Imported Upstream version 2.6.4 67/225867/2 upstream/2.6.4
authorBowon Ryu <bowon.ryu@samsung.com>
Tue, 25 Feb 2020 05:54:08 +0000 (14:54 +0900)
committerBowon Ryu <bowon.ryu@samsung.com>
Tue, 25 Feb 2020 06:18:49 +0000 (15:18 +0900)
Change-Id: Icb2ce380590ccf605416ee6165effa40d790cd6e

696 files changed:
AUTHORS
CMakeLists.txt
CONFIG.md [new file with mode: 0644]
COPYING
ChangeLog
Makefile.am
Makefile.in
NEWS
README
README.md [new file with mode: 0644]
README.mingw.md [new file with mode: 0644]
README.python.md
README.wine.md [deleted file]
RELEASING.md
TESTING.md [new file with mode: 0644]
THANKS
aclocal.m4
config.h.in
config.sub
configure
configure.ac
docs/Makefile.am
docs/Makefile.in
docs/harfbuzz-docs.xml
docs/harfbuzz-sections.txt
docs/harfbuzz.types [new file with mode: 0644]
docs/html/aat-shaping.html
docs/html/adding-text-to-the-buffer.html
docs/html/api-index-full.html
docs/html/buffers-language-script-and-direction.html
docs/html/building.html
docs/html/ch09.html [deleted file]
docs/html/ch10.html [deleted file]
docs/html/ch11.html
docs/html/ch12.html
docs/html/ch13.html [new file with mode: 0644]
docs/html/ch14.html [new file with mode: 0644]
docs/html/clusters.html
docs/html/customizing-unicode-functions.html
docs/html/fonts-and-faces-custom-functions.html [new file with mode: 0644]
docs/html/fonts-and-faces-native-opentype.html [new file with mode: 0644]
docs/html/fonts-and-faces-variable.html [new file with mode: 0644]
docs/html/fonts-and-faces.html
docs/html/harfbuzz-hb-aat-layout.html
docs/html/harfbuzz-hb-blob.html
docs/html/harfbuzz-hb-buffer.html
docs/html/harfbuzz-hb-common.html
docs/html/harfbuzz-hb-coretext.html
docs/html/harfbuzz-hb-deprecated.html
docs/html/harfbuzz-hb-face.html
docs/html/harfbuzz-hb-font.html
docs/html/harfbuzz-hb-ft.html
docs/html/harfbuzz-hb-glib.html
docs/html/harfbuzz-hb-gobject.html
docs/html/harfbuzz-hb-graphite2.html
docs/html/harfbuzz-hb-icu.html
docs/html/harfbuzz-hb-map.html
docs/html/harfbuzz-hb-ot-color.html
docs/html/harfbuzz-hb-ot-font.html
docs/html/harfbuzz-hb-ot-layout.html
docs/html/harfbuzz-hb-ot-math.html
docs/html/harfbuzz-hb-ot-name.html
docs/html/harfbuzz-hb-ot-shape.html
docs/html/harfbuzz-hb-ot-var.html
docs/html/harfbuzz-hb-set.html
docs/html/harfbuzz-hb-shape-plan.html
docs/html/harfbuzz-hb-shape.html
docs/html/harfbuzz-hb-unicode.html
docs/html/harfbuzz-hb-uniscribe.html
docs/html/harfbuzz-hb-version.html
docs/html/harfbuzz.devhelp2
docs/html/index.html
docs/html/level-2.html
docs/html/object-model-blobs.html [new file with mode: 0644]
docs/html/object-model-lifecycle.html [new file with mode: 0644]
docs/html/object-model-object-types.html [new file with mode: 0644]
docs/html/object-model-user-data.html [new file with mode: 0644]
docs/html/object-model.html [new file with mode: 0644]
docs/html/plans-and-caching.html [deleted file]
docs/html/pt01.html
docs/html/pt02.html
docs/html/setting-buffer-properties.html
docs/html/shaping-and-shape-plans.html
docs/html/shaping-opentype-features.html [new file with mode: 0644]
docs/html/shaping-plans-and-caching.html [new file with mode: 0644]
docs/html/shaping-shaper-selection.html [new file with mode: 0644]
docs/html/using-harfbuzzs-native-opentype-implementation.html [deleted file]
docs/html/using-your-own-font-functions.html [deleted file]
docs/html/utilities-common-types-apis.html [new file with mode: 0644]
docs/html/utilities-ucdn.html [new file with mode: 0644]
docs/html/utilities.html [new file with mode: 0644]
docs/html/what-about-the-other-scripts.html [deleted file]
docs/html/why-do-i-need-a-shaping-engine.html
docs/html/working-with-harfbuzz-clusters.html
docs/usermanual-buffers-language-script-and-direction.xml
docs/usermanual-clusters.xml
docs/usermanual-fonts-and-faces.xml
docs/usermanual-install-harfbuzz.xml
docs/usermanual-object-model.xml [new file with mode: 0644]
docs/usermanual-opentype-features.xml
docs/usermanual-utilities.xml [new file with mode: 0644]
docs/usermanual-what-is-harfbuzz.xml
docs/version.xml
ltmain.sh
m4/ax_cxx_compile_stdcxx.m4 [new file with mode: 0644]
m4/libtool.m4
m4/ltoptions.m4
m4/ltsugar.m4
m4/ltversion.m4
m4/lt~obsolete.m4
mingw-configure.sh [new file with mode: 0755]
mingw-ldd.py [new file with mode: 0755]
mingw32.sh [new file with mode: 0755]
mingw64.sh [new file with mode: 0755]
src/Makefile.am
src/Makefile.in
src/Makefile.sources
src/check-symbols.sh
src/gen-emoji-table.py
src/gen-indic-table.py
src/gen-os2-unicode-ranges.py [changed mode: 0644->0755]
src/gen-tag-table.py
src/gen-ucd-table.py [new file with mode: 0755]
src/gen-use-table.py
src/gen-vowel-constraints.py
src/harfbuzz.cc [new file with mode: 0644]
src/hb-aat-fdsc-table.hh
src/hb-aat-layout-ankr-table.hh
src/hb-aat-layout-bsln-table.hh
src/hb-aat-layout-common.hh
src/hb-aat-layout-feat-table.hh
src/hb-aat-layout-just-table.hh
src/hb-aat-layout-kerx-table.hh
src/hb-aat-layout-lcar-table.hh
src/hb-aat-layout-morx-table.hh
src/hb-aat-layout-opbd-table.hh [new file with mode: 0644]
src/hb-aat-layout-trak-table.hh
src/hb-aat-layout.cc
src/hb-aat-layout.h
src/hb-aat-layout.hh
src/hb-aat-ltag-table.hh
src/hb-aat-map.cc
src/hb-aat-map.hh
src/hb-algs.hh [new file with mode: 0644]
src/hb-array.hh
src/hb-atomic.hh
src/hb-bimap.hh [new file with mode: 0644]
src/hb-blob.cc
src/hb-blob.h
src/hb-blob.hh
src/hb-buffer-serialize.cc
src/hb-buffer.cc
src/hb-buffer.h
src/hb-buffer.hh
src/hb-cff-interp-common.hh
src/hb-cff-interp-cs-common.hh
src/hb-cff-interp-dict-common.hh
src/hb-cff1-interp-cs.hh
src/hb-cff2-interp-cs.hh
src/hb-common.cc
src/hb-common.h
src/hb-config.hh [new file with mode: 0644]
src/hb-coretext.cc
src/hb-debug.hh
src/hb-deprecated.h
src/hb-directwrite.cc
src/hb-directwrite.h
src/hb-dispatch.hh [new file with mode: 0644]
src/hb-dsalgs.hh [deleted file]
src/hb-face.cc
src/hb-fallback-shape.cc
src/hb-font.cc
src/hb-font.h
src/hb-font.hh
src/hb-ft.cc
src/hb-gdi.cc [new file with mode: 0644]
src/hb-gdi.h [new file with mode: 0644]
src/hb-glib.cc
src/hb-gobject-enums.cc.tmpl
src/hb-gobject-structs.cc
src/hb-graphite2.cc
src/hb-icu.cc
src/hb-iter.hh
src/hb-kern.hh
src/hb-machinery.hh
src/hb-map.hh
src/hb-meta.hh [new file with mode: 0644]
src/hb-mutex.hh
src/hb-null.hh
src/hb-number-parser.hh [new file with mode: 0644]
src/hb-number-parser.rl [new file with mode: 0644]
src/hb-number.cc [new file with mode: 0644]
src/hb-number.hh [moved from src/hb-warning.cc with 69% similarity]
src/hb-object.hh
src/hb-open-file.hh
src/hb-open-type.hh
src/hb-ot-cff-common.hh
src/hb-ot-cff1-table.cc
src/hb-ot-cff1-table.hh
src/hb-ot-cff2-table.cc
src/hb-ot-cff2-table.hh
src/hb-ot-cmap-table.hh
src/hb-ot-color-cbdt-table.hh
src/hb-ot-color-colr-table.hh
src/hb-ot-color-cpal-table.hh
src/hb-ot-color-sbix-table.hh
src/hb-ot-color-svg-table.hh
src/hb-ot-color.cc
src/hb-ot-color.h
src/hb-ot-deprecated.h
src/hb-ot-face-table-list.hh [new file with mode: 0644]
src/hb-ot-face.cc
src/hb-ot-face.hh
src/hb-ot-font.cc
src/hb-ot-glyf-table.hh
src/hb-ot-hdmx-table.hh
src/hb-ot-hhea-table.hh
src/hb-ot-hmtx-table.hh
src/hb-ot-kern-table.hh
src/hb-ot-layout-base-table.hh
src/hb-ot-layout-common.hh
src/hb-ot-layout-gdef-table.hh
src/hb-ot-layout-gpos-table.hh
src/hb-ot-layout-gsub-table.hh
src/hb-ot-layout-gsubgpos.hh
src/hb-ot-layout-jstf-table.hh
src/hb-ot-layout.cc
src/hb-ot-layout.h
src/hb-ot-layout.hh
src/hb-ot-map.cc
src/hb-ot-map.hh
src/hb-ot-math-table.hh
src/hb-ot-math.cc
src/hb-ot-math.h
src/hb-ot-maxp-table.hh
src/hb-ot-meta-table.hh [new file with mode: 0644]
src/hb-ot-meta.cc [new file with mode: 0644]
src/hb-ot-meta.h [new file with mode: 0644]
src/hb-ot-metrics.cc [new file with mode: 0644]
src/hb-ot-metrics.h [new file with mode: 0644]
src/hb-ot-metrics.hh [moved from src/hb-subset-glyf.hh with 73% similarity]
src/hb-ot-name-language-static.hh [moved from src/hb-ot-name-language.cc with 98% similarity]
src/hb-ot-name-table.hh
src/hb-ot-name.cc
src/hb-ot-os2-table.hh
src/hb-ot-post-table.hh
src/hb-ot-shape-complex-arabic-fallback.hh
src/hb-ot-shape-complex-arabic.cc
src/hb-ot-shape-complex-default.cc
src/hb-ot-shape-complex-hangul.cc
src/hb-ot-shape-complex-hebrew.cc
src/hb-ot-shape-complex-indic-machine.hh
src/hb-ot-shape-complex-indic-machine.rl
src/hb-ot-shape-complex-indic-table.cc
src/hb-ot-shape-complex-indic.cc
src/hb-ot-shape-complex-indic.hh
src/hb-ot-shape-complex-khmer-machine.hh
src/hb-ot-shape-complex-khmer-machine.rl
src/hb-ot-shape-complex-khmer.cc
src/hb-ot-shape-complex-khmer.hh
src/hb-ot-shape-complex-myanmar-machine.hh
src/hb-ot-shape-complex-myanmar-machine.rl
src/hb-ot-shape-complex-myanmar.cc
src/hb-ot-shape-complex-myanmar.hh
src/hb-ot-shape-complex-thai.cc
src/hb-ot-shape-complex-use-machine.hh
src/hb-ot-shape-complex-use-machine.rl
src/hb-ot-shape-complex-use-table.cc
src/hb-ot-shape-complex-use.cc
src/hb-ot-shape-complex-use.hh
src/hb-ot-shape-complex-vowel-constraints.cc
src/hb-ot-shape-fallback.cc
src/hb-ot-shape-normalize.cc
src/hb-ot-shape.cc
src/hb-ot-shape.hh
src/hb-ot-stat-table.hh
src/hb-ot-tag-table.hh
src/hb-ot-tag.cc
src/hb-ot-var-avar-table.hh
src/hb-ot-var-fvar-table.hh
src/hb-ot-var-gvar-table.hh [new file with mode: 0644]
src/hb-ot-var-hvar-table.hh
src/hb-ot-var-mvar-table.hh
src/hb-ot-var.cc
src/hb-ot-var.h
src/hb-ot-vorg-table.hh
src/hb-ot.h
src/hb-pool.hh [new file with mode: 0644]
src/hb-sanitize.hh [new file with mode: 0644]
src/hb-serialize.hh [new file with mode: 0644]
src/hb-set.cc
src/hb-set.hh
src/hb-shape-plan.cc
src/hb-shape-plan.hh
src/hb-shape.cc
src/hb-shaper-list.hh
src/hb-shaper.cc
src/hb-static.cc
src/hb-string-array.hh
src/hb-subset-cff-common.cc
src/hb-subset-cff-common.hh
src/hb-subset-cff1.cc
src/hb-subset-cff2.cc
src/hb-subset-glyf.cc [deleted file]
src/hb-subset-input.cc
src/hb-subset-input.hh
src/hb-subset-plan.cc
src/hb-subset-plan.hh
src/hb-subset.cc
src/hb-subset.h
src/hb-subset.hh
src/hb-ucd-table.hh [new file with mode: 0644]
src/hb-ucd.cc [new file with mode: 0644]
src/hb-ucdn.cc [deleted file]
src/hb-ucdn/COPYING [deleted file]
src/hb-ucdn/Makefile.am [deleted file]
src/hb-ucdn/Makefile.in [deleted file]
src/hb-ucdn/Makefile.sources [deleted file]
src/hb-ucdn/README [deleted file]
src/hb-ucdn/ucdn.c [deleted file]
src/hb-ucdn/ucdn.h [deleted file]
src/hb-ucdn/ucdn_db.h [deleted file]
src/hb-unicode-emoji-table.hh
src/hb-unicode.cc
src/hb-unicode.h
src/hb-unicode.hh
src/hb-uniscribe.cc
src/hb-utf.hh
src/hb-vector.hh
src/hb-version.h
src/hb.hh
src/main.cc
src/test-algs.cc [new file with mode: 0644]
src/test-bimap.cc [new file with mode: 0644]
src/test-buffer-serialize.cc
src/test-gpos-size-params.cc [moved from src/test-size-params.cc with 86% similarity]
src/test-gsub-would-substitute.cc [moved from src/test-would-substitute.cc with 96% similarity]
src/test-iter.cc
src/test-meta.cc [new file with mode: 0644]
src/test-number.cc [new file with mode: 0644]
src/test-ot-color.cc
src/test-ot-meta.cc [new file with mode: 0644]
src/test-ot-name.cc [moved from src/test-name-table.cc with 93% similarity]
src/test-unicode-ranges.cc
src/test.cc
test/Makefile.in
test/api/Makefile.am
test/api/Makefile.in
test/api/fonts/Roboto-Regular.D7,D8,D9,DA,DE.ttf
test/api/fonts/Roboto-Regular.a.retaingids.ttf [new file with mode: 0644]
test/api/fonts/Roboto-Regular.abc.ttf
test/api/fonts/Roboto-Regular.ac.ttf
test/api/fonts/SourceHanSans-Regular.41,4C2E.retaingids.otf
test/api/fonts/SourceSansVariable-Roman-nohvar-41,C1.ttf [new file with mode: 0644]
test/api/fonts/SourceSansVariable-Roman.anchor.ttf [new file with mode: 0644]
test/api/fonts/SourceSansVariable-Roman.modcomp.ttf [new file with mode: 0644]
test/api/fonts/SourceSerifVariable-Roman-VVAR.abc.ttf [new file with mode: 0644]
test/api/fonts/TestCFF2VF.otf [new file with mode: 0644]
test/api/fonts/cmunrm.otf [new file with mode: 0644]
test/api/fonts/meta.ttf [new file with mode: 0644]
test/api/fonts/nameID.dup.expected.ttf [new file with mode: 0644]
test/api/fonts/nameID.dup.origin.ttf [new file with mode: 0644]
test/api/fonts/nameID.expected.ttf [new file with mode: 0644]
test/api/fonts/nameID.origin.ttf [new file with mode: 0644]
test/api/hb-subset-test.h
test/api/hb-test.h
test/api/test-aat-layout.c
test/api/test-baseline.c
test/api/test-buffer.c
test/api/test-collect-unicodes.c
test/api/test-font.c
test/api/test-object.c
test/api/test-ot-color.c
test/api/test-ot-extents-cff.c
test/api/test-ot-face.c
test/api/test-ot-math.c
test/api/test-ot-meta.c [new file with mode: 0644]
test/api/test-ot-metrics-tt-var.c [new file with mode: 0644]
test/api/test-ot-metrics.c [new file with mode: 0644]
test/api/test-ot-tag.c
test/api/test-shape.c
test/api/test-subset-drop-tables.c [new file with mode: 0644]
test/api/test-subset-glyf.c
test/api/test-subset-hdmx.c
test/api/test-subset-nameids.c [new file with mode: 0644]
test/api/test-unicode.c
test/fuzzing/Makefile.am
test/fuzzing/Makefile.in
test/fuzzing/fonts/clusterfuzz-testcase-hb-subset-fuzzer-5717414645334016 [new file with mode: 0644]
test/fuzzing/fonts/clusterfuzz-testcase-minimized-harfbuzz_fuzzer-5093685255077888 [new file with mode: 0644]
test/fuzzing/fonts/clusterfuzz-testcase-minimized-harfbuzz_fuzzer-5702671124791296 [new file with mode: 0644]
test/fuzzing/fonts/clusterfuzz-testcase-minimized-harfbuzz_fuzzer-6252118652092416 [new file with mode: 0644]
test/fuzzing/fonts/clusterfuzz-testcase-minimized-hb-subset-fuzzer-5077547978588160 [new file with mode: 0644]
test/fuzzing/fonts/clusterfuzz-testcase-minimized-hb-subset-fuzzer-5634197349203968 [new file with mode: 0644]
test/fuzzing/fonts/clusterfuzz-testcase-minimized-hb-subset-fuzzer-5643107869917184 [new file with mode: 0644]
test/fuzzing/fonts/clusterfuzz-testcase-minimized-hb-subset-fuzzer-5659903036751872 [new file with mode: 0644]
test/fuzzing/fonts/clusterfuzz-testcase-minimized-hb-subset-fuzzer-5667673584697344 [new file with mode: 0644]
test/fuzzing/fonts/clusterfuzz-testcase-minimized-hb-subset-fuzzer-5675720390475776 [new file with mode: 0644]
test/fuzzing/fonts/clusterfuzz-testcase-minimized-hb-subset-fuzzer-5676773460672512 [new file with mode: 0644]
test/fuzzing/fonts/clusterfuzz-testcase-minimized-hb-subset-fuzzer-5677906231033856 [new file with mode: 0644]
test/fuzzing/fonts/clusterfuzz-testcase-minimized-hb-subset-fuzzer-5680398559870976 [new file with mode: 0644]
test/fuzzing/fonts/clusterfuzz-testcase-minimized-hb-subset-fuzzer-5696825891225600 [new file with mode: 0644]
test/fuzzing/fonts/clusterfuzz-testcase-minimized-hb-subset-fuzzer-5716947896893440 [new file with mode: 0644]
test/fuzzing/fonts/clusterfuzz-testcase-minimized-hb-subset-fuzzer-5721073428987904 [new file with mode: 0644]
test/fuzzing/fonts/clusterfuzz-testcase-minimized-hb-subset-fuzzer-5728664968232960 [new file with mode: 0644]
test/fuzzing/fonts/clusterfuzz-testcase-minimized-hb-subset-fuzzer-5738978499624960 [new file with mode: 0644]
test/fuzzing/fonts/clusterfuzz-testcase-minimized-hb-subset-fuzzer-5754526379802624 [new file with mode: 0644]
test/fuzzing/fonts/clusterfuzz-testcase-minimized-hb-subset-fuzzer-5761434614497280 [new file with mode: 0644]
test/fuzzing/fonts/clusterfuzz-testcase-minimized-hb-subset-fuzzer-5763024094232576 [new file with mode: 0644]
test/fuzzing/fonts/clusterfuzz-testcase-minimized-hb-subset-fuzzer-5923632099885056 [new file with mode: 0644]
test/fuzzing/hb-shape-fuzzer.cc
test/fuzzing/hb-subset-fuzzer.cc
test/fuzzing/main.cc
test/fuzzing/run-shape-fuzzer-tests.py
test/fuzzing/run-subset-fuzzer-tests.py
test/shaping/Makefile.in
test/shaping/data/Makefile.in
test/shaping/data/aots/Makefile.in
test/shaping/data/in-house/Makefile.in
test/shaping/data/in-house/Makefile.sources
test/shaping/data/in-house/fonts/3cc01fede4debd4b7794ccb1b16cdb9987ea7571.ttf [new file with mode: 0644]
test/shaping/data/in-house/fonts/53a91c20e33a596f2be17fb68b382d6b7eb85d5c.ttf [new file with mode: 0644]
test/shaping/data/in-house/fonts/ea3f63620511b2097200d23774ffef197e829e69.ttf [new file with mode: 0644]
test/shaping/data/in-house/fonts/f79eb71df4e4c9c273b67b89a06e5ff9e3c1f834.ttf [new file with mode: 0644]
test/shaping/data/in-house/fonts/fcbaa518d3cce441ed37ae3b1fed6a19e9b54efd.ttf [new file with mode: 0644]
test/shaping/data/in-house/tests/aat-trak.tests
test/shaping/data/in-house/tests/color-fonts.tests
test/shaping/data/in-house/tests/macos.tests
test/shaping/data/in-house/tests/positioning-features.tests [new file with mode: 0644]
test/shaping/data/in-house/tests/use-syllable.tests
test/shaping/data/text-rendering-tests/Makefile.in
test/shaping/record-test.sh
test/subset/Makefile.am
test/subset/Makefile.in
test/subset/data/Makefile.am
test/subset/data/Makefile.in
test/subset/data/Makefile.sources
test/subset/data/expected/basics/Comfortaa-Regular-new.default.61,62,63.ttf [new file with mode: 0644]
test/subset/data/expected/basics/Comfortaa-Regular-new.default.61,63.ttf [new file with mode: 0644]
test/subset/data/expected/basics/Comfortaa-Regular-new.default.61.ttf [new file with mode: 0644]
test/subset/data/expected/basics/Comfortaa-Regular-new.default.62.ttf [new file with mode: 0644]
test/subset/data/expected/basics/Comfortaa-Regular-new.default.63.ttf [new file with mode: 0644]
test/subset/data/expected/basics/Comfortaa-Regular-new.default.retain-all-codepoint.ttf [new file with mode: 0644]
test/subset/data/expected/basics/Comfortaa-Regular-new.drop-hints-retain-gids.61,62,63.ttf [new file with mode: 0644]
test/subset/data/expected/basics/Comfortaa-Regular-new.drop-hints-retain-gids.61,63.ttf [new file with mode: 0644]
test/subset/data/expected/basics/Comfortaa-Regular-new.drop-hints-retain-gids.61.ttf [new file with mode: 0644]
test/subset/data/expected/basics/Comfortaa-Regular-new.drop-hints-retain-gids.62.ttf [new file with mode: 0644]
test/subset/data/expected/basics/Comfortaa-Regular-new.drop-hints-retain-gids.63.ttf [new file with mode: 0644]
test/subset/data/expected/basics/Comfortaa-Regular-new.drop-hints-retain-gids.retain-all-codepoint.ttf [new file with mode: 0644]
test/subset/data/expected/basics/Comfortaa-Regular-new.drop-hints.61,62,63.ttf [new file with mode: 0644]
test/subset/data/expected/basics/Comfortaa-Regular-new.drop-hints.61,63.ttf [new file with mode: 0644]
test/subset/data/expected/basics/Comfortaa-Regular-new.drop-hints.61.ttf [new file with mode: 0644]
test/subset/data/expected/basics/Comfortaa-Regular-new.drop-hints.62.ttf [new file with mode: 0644]
test/subset/data/expected/basics/Comfortaa-Regular-new.drop-hints.63.ttf [new file with mode: 0644]
test/subset/data/expected/basics/Comfortaa-Regular-new.drop-hints.retain-all-codepoint.ttf [new file with mode: 0644]
test/subset/data/expected/basics/Comfortaa-Regular-new.name-ids.61,62,63.ttf [new file with mode: 0644]
test/subset/data/expected/basics/Comfortaa-Regular-new.name-ids.61,63.ttf [new file with mode: 0644]
test/subset/data/expected/basics/Comfortaa-Regular-new.name-ids.61.ttf [new file with mode: 0644]
test/subset/data/expected/basics/Comfortaa-Regular-new.name-ids.62.ttf [new file with mode: 0644]
test/subset/data/expected/basics/Comfortaa-Regular-new.name-ids.63.ttf [new file with mode: 0644]
test/subset/data/expected/basics/Comfortaa-Regular-new.name-ids.retain-all-codepoint.ttf [new file with mode: 0644]
test/subset/data/expected/basics/Comfortaa-Regular-new.retain-gids.61,62,63.ttf [new file with mode: 0644]
test/subset/data/expected/basics/Comfortaa-Regular-new.retain-gids.61,63.ttf [new file with mode: 0644]
test/subset/data/expected/basics/Comfortaa-Regular-new.retain-gids.61.ttf [new file with mode: 0644]
test/subset/data/expected/basics/Comfortaa-Regular-new.retain-gids.62.ttf [new file with mode: 0644]
test/subset/data/expected/basics/Comfortaa-Regular-new.retain-gids.63.ttf [new file with mode: 0644]
test/subset/data/expected/basics/Comfortaa-Regular-new.retain-gids.retain-all-codepoint.ttf [new file with mode: 0644]
test/subset/data/expected/basics/Roboto-Regular.abc.default.retain-all-codepoint.ttf [new file with mode: 0644]
test/subset/data/expected/basics/Roboto-Regular.abc.drop-hints-retain-gids.61.ttf
test/subset/data/expected/basics/Roboto-Regular.abc.drop-hints-retain-gids.62.ttf
test/subset/data/expected/basics/Roboto-Regular.abc.drop-hints-retain-gids.retain-all-codepoint.ttf [new file with mode: 0644]
test/subset/data/expected/basics/Roboto-Regular.abc.drop-hints.retain-all-codepoint.ttf [new file with mode: 0644]
test/subset/data/expected/basics/Roboto-Regular.abc.name-ids.61,62,63.ttf [new file with mode: 0644]
test/subset/data/expected/basics/Roboto-Regular.abc.name-ids.61,63.ttf [new file with mode: 0644]
test/subset/data/expected/basics/Roboto-Regular.abc.name-ids.61.ttf [new file with mode: 0644]
test/subset/data/expected/basics/Roboto-Regular.abc.name-ids.62.ttf [new file with mode: 0644]
test/subset/data/expected/basics/Roboto-Regular.abc.name-ids.63.ttf [new file with mode: 0644]
test/subset/data/expected/basics/Roboto-Regular.abc.name-ids.retain-all-codepoint.ttf [new file with mode: 0644]
test/subset/data/expected/basics/Roboto-Regular.abc.retain-gids.61.ttf
test/subset/data/expected/basics/Roboto-Regular.abc.retain-gids.62.ttf
test/subset/data/expected/basics/Roboto-Regular.abc.retain-gids.retain-all-codepoint.ttf [new file with mode: 0644]
test/subset/data/expected/cff-full-font/SourceSansPro-Regular.default.1FC,21,41,20,62,63.otf [new file with mode: 0644]
test/subset/data/expected/cff-full-font/SourceSansPro-Regular.default.61,62,63.otf [new file with mode: 0644]
test/subset/data/expected/cff-full-font/SourceSansPro-Regular.default.D7,D8,D9,DA,DE.otf [new file with mode: 0644]
test/subset/data/expected/cff-full-font/SourceSansPro-Regular.desubroutinize-retain-gids.1FC,21,41,20,62,63.otf [new file with mode: 0644]
test/subset/data/expected/cff-full-font/SourceSansPro-Regular.desubroutinize-retain-gids.61,62,63.otf [new file with mode: 0644]
test/subset/data/expected/cff-full-font/SourceSansPro-Regular.desubroutinize-retain-gids.D7,D8,D9,DA,DE.otf [new file with mode: 0644]
test/subset/data/expected/cff-full-font/SourceSansPro-Regular.desubroutinize.1FC,21,41,20,62,63.otf [new file with mode: 0644]
test/subset/data/expected/cff-full-font/SourceSansPro-Regular.desubroutinize.61,62,63.otf [new file with mode: 0644]
test/subset/data/expected/cff-full-font/SourceSansPro-Regular.desubroutinize.D7,D8,D9,DA,DE.otf [new file with mode: 0644]
test/subset/data/expected/cff-full-font/SourceSansPro-Regular.drop-hints-desubroutinize-retain-gids.1FC,21,41,20,62,63.otf [new file with mode: 0644]
test/subset/data/expected/cff-full-font/SourceSansPro-Regular.drop-hints-desubroutinize-retain-gids.61,62,63.otf [new file with mode: 0644]
test/subset/data/expected/cff-full-font/SourceSansPro-Regular.drop-hints-desubroutinize-retain-gids.D7,D8,D9,DA,DE.otf [new file with mode: 0644]
test/subset/data/expected/cff-full-font/SourceSansPro-Regular.drop-hints-desubroutinize.1FC,21,41,20,62,63.otf [new file with mode: 0644]
test/subset/data/expected/cff-full-font/SourceSansPro-Regular.drop-hints-desubroutinize.61,62,63.otf [new file with mode: 0644]
test/subset/data/expected/cff-full-font/SourceSansPro-Regular.drop-hints-desubroutinize.D7,D8,D9,DA,DE.otf [new file with mode: 0644]
test/subset/data/expected/cff-full-font/SourceSansPro-Regular.drop-hints-retain-gids.1FC,21,41,20,62,63.otf [new file with mode: 0644]
test/subset/data/expected/cff-full-font/SourceSansPro-Regular.drop-hints-retain-gids.61,62,63.otf [new file with mode: 0644]
test/subset/data/expected/cff-full-font/SourceSansPro-Regular.drop-hints-retain-gids.D7,D8,D9,DA,DE.otf [new file with mode: 0644]
test/subset/data/expected/cff-full-font/SourceSansPro-Regular.drop-hints.1FC,21,41,20,62,63.otf [new file with mode: 0644]
test/subset/data/expected/cff-full-font/SourceSansPro-Regular.drop-hints.61,62,63.otf [new file with mode: 0644]
test/subset/data/expected/cff-full-font/SourceSansPro-Regular.drop-hints.D7,D8,D9,DA,DE.otf [new file with mode: 0644]
test/subset/data/expected/cff-full-font/SourceSansPro-Regular.retain-gids.1FC,21,41,20,62,63.otf [new file with mode: 0644]
test/subset/data/expected/cff-full-font/SourceSansPro-Regular.retain-gids.61,62,63.otf [new file with mode: 0644]
test/subset/data/expected/cff-full-font/SourceSansPro-Regular.retain-gids.D7,D8,D9,DA,DE.otf [new file with mode: 0644]
test/subset/data/expected/cff-japanese/SourceHanSans-Regular_subset.default.3042,3044,3046,3048,304A,304B.otf [new file with mode: 0644]
test/subset/data/expected/cff-japanese/SourceHanSans-Regular_subset.default.3042,3044,3046,73E0,5EA6,8F38.otf [new file with mode: 0644]
test/subset/data/expected/cff-japanese/SourceHanSans-Regular_subset.default.61,63,65,6B.otf [new file with mode: 0644]
test/subset/data/expected/cff-japanese/SourceHanSans-Regular_subset.default.660E,6975,73E0,5EA6,8F38,6E05.otf [new file with mode: 0644]
test/subset/data/expected/cff-japanese/SourceHanSans-Regular_subset.default.660E.otf [new file with mode: 0644]
test/subset/data/expected/cff-japanese/SourceHanSans-Regular_subset.desubroutinize-retain-gids.3042,3044,3046,3048,304A,304B.otf [new file with mode: 0644]
test/subset/data/expected/cff-japanese/SourceHanSans-Regular_subset.desubroutinize-retain-gids.3042,3044,3046,73E0,5EA6,8F38.otf [new file with mode: 0644]
test/subset/data/expected/cff-japanese/SourceHanSans-Regular_subset.desubroutinize-retain-gids.61,63,65,6B.otf [new file with mode: 0644]
test/subset/data/expected/cff-japanese/SourceHanSans-Regular_subset.desubroutinize-retain-gids.660E,6975,73E0,5EA6,8F38,6E05.otf [new file with mode: 0644]
test/subset/data/expected/cff-japanese/SourceHanSans-Regular_subset.desubroutinize-retain-gids.660E.otf [new file with mode: 0644]
test/subset/data/expected/cff-japanese/SourceHanSans-Regular_subset.desubroutinize.3042,3044,3046,3048,304A,304B.otf [new file with mode: 0644]
test/subset/data/expected/cff-japanese/SourceHanSans-Regular_subset.desubroutinize.3042,3044,3046,73E0,5EA6,8F38.otf [new file with mode: 0644]
test/subset/data/expected/cff-japanese/SourceHanSans-Regular_subset.desubroutinize.61,63,65,6B.otf [new file with mode: 0644]
test/subset/data/expected/cff-japanese/SourceHanSans-Regular_subset.desubroutinize.660E,6975,73E0,5EA6,8F38,6E05.otf [new file with mode: 0644]
test/subset/data/expected/cff-japanese/SourceHanSans-Regular_subset.desubroutinize.660E.otf [new file with mode: 0644]
test/subset/data/expected/cff-japanese/SourceHanSans-Regular_subset.drop-hints-desubroutinize-retain-gids.3042,3044,3046,3048,304A,304B.otf [new file with mode: 0644]
test/subset/data/expected/cff-japanese/SourceHanSans-Regular_subset.drop-hints-desubroutinize-retain-gids.3042,3044,3046,73E0,5EA6,8F38.otf [new file with mode: 0644]
test/subset/data/expected/cff-japanese/SourceHanSans-Regular_subset.drop-hints-desubroutinize-retain-gids.61,63,65,6B.otf [new file with mode: 0644]
test/subset/data/expected/cff-japanese/SourceHanSans-Regular_subset.drop-hints-desubroutinize-retain-gids.660E,6975,73E0,5EA6,8F38,6E05.otf [new file with mode: 0644]
test/subset/data/expected/cff-japanese/SourceHanSans-Regular_subset.drop-hints-desubroutinize-retain-gids.660E.otf [new file with mode: 0644]
test/subset/data/expected/cff-japanese/SourceHanSans-Regular_subset.drop-hints-desubroutinize.3042,3044,3046,3048,304A,304B.otf [new file with mode: 0644]
test/subset/data/expected/cff-japanese/SourceHanSans-Regular_subset.drop-hints-desubroutinize.3042,3044,3046,73E0,5EA6,8F38.otf [new file with mode: 0644]
test/subset/data/expected/cff-japanese/SourceHanSans-Regular_subset.drop-hints-desubroutinize.61,63,65,6B.otf [new file with mode: 0644]
test/subset/data/expected/cff-japanese/SourceHanSans-Regular_subset.drop-hints-desubroutinize.660E,6975,73E0,5EA6,8F38,6E05.otf [new file with mode: 0644]
test/subset/data/expected/cff-japanese/SourceHanSans-Regular_subset.drop-hints-desubroutinize.660E.otf [new file with mode: 0644]
test/subset/data/expected/cff-japanese/SourceHanSans-Regular_subset.drop-hints-retain-gids.3042,3044,3046,3048,304A,304B.otf [new file with mode: 0644]
test/subset/data/expected/cff-japanese/SourceHanSans-Regular_subset.drop-hints-retain-gids.3042,3044,3046,73E0,5EA6,8F38.otf [new file with mode: 0644]
test/subset/data/expected/cff-japanese/SourceHanSans-Regular_subset.drop-hints-retain-gids.61,63,65,6B.otf [new file with mode: 0644]
test/subset/data/expected/cff-japanese/SourceHanSans-Regular_subset.drop-hints-retain-gids.660E,6975,73E0,5EA6,8F38,6E05.otf [new file with mode: 0644]
test/subset/data/expected/cff-japanese/SourceHanSans-Regular_subset.drop-hints-retain-gids.660E.otf [new file with mode: 0644]
test/subset/data/expected/cff-japanese/SourceHanSans-Regular_subset.drop-hints.3042,3044,3046,3048,304A,304B.otf [new file with mode: 0644]
test/subset/data/expected/cff-japanese/SourceHanSans-Regular_subset.drop-hints.3042,3044,3046,73E0,5EA6,8F38.otf [new file with mode: 0644]
test/subset/data/expected/cff-japanese/SourceHanSans-Regular_subset.drop-hints.61,63,65,6B.otf [new file with mode: 0644]
test/subset/data/expected/cff-japanese/SourceHanSans-Regular_subset.drop-hints.660E,6975,73E0,5EA6,8F38,6E05.otf [new file with mode: 0644]
test/subset/data/expected/cff-japanese/SourceHanSans-Regular_subset.drop-hints.660E.otf [new file with mode: 0644]
test/subset/data/expected/cff-japanese/SourceHanSans-Regular_subset.retain-gids.3042,3044,3046,3048,304A,304B.otf [new file with mode: 0644]
test/subset/data/expected/cff-japanese/SourceHanSans-Regular_subset.retain-gids.3042,3044,3046,73E0,5EA6,8F38.otf [new file with mode: 0644]
test/subset/data/expected/cff-japanese/SourceHanSans-Regular_subset.retain-gids.61,63,65,6B.otf [new file with mode: 0644]
test/subset/data/expected/cff-japanese/SourceHanSans-Regular_subset.retain-gids.660E,6975,73E0,5EA6,8F38,6E05.otf [new file with mode: 0644]
test/subset/data/expected/cff-japanese/SourceHanSans-Regular_subset.retain-gids.660E.otf [new file with mode: 0644]
test/subset/data/expected/cmap14/cmap14_font1.default.4E00,4E02,4E03.otf [new file with mode: 0644]
test/subset/data/expected/cmap14/cmap14_font1.default.4E00,4E03.otf [new file with mode: 0644]
test/subset/data/expected/cmap14/cmap14_font1.default.4E00,4E05,4E07.otf [new file with mode: 0644]
test/subset/data/expected/cmap14/cmap14_font1.default.4E02,4E03,4E08.otf [new file with mode: 0644]
test/subset/data/expected/cmap14/cmap14_font1.default.4E02.otf [new file with mode: 0644]
test/subset/data/expected/cmap14/cmap14_font1.default.4E03.otf [new file with mode: 0644]
test/subset/data/expected/cmap14/cmap14_font1.default.4E05,4E07,4E08,4E09.otf [new file with mode: 0644]
test/subset/data/expected/cmap14/cmap14_font1.default.4E08,4E09.otf [new file with mode: 0644]
test/subset/data/expected/cmap14/cmap14_font1.default.4E08.otf [new file with mode: 0644]
test/subset/data/expected/cmap14/cmap14_font1.default.retain-all-codepoint.otf [new file with mode: 0644]
test/subset/data/expected/cmap14/cmap14_font1.drop-hints-retain-gids.4E00,4E02,4E03.otf [new file with mode: 0644]
test/subset/data/expected/cmap14/cmap14_font1.drop-hints-retain-gids.4E00,4E03.otf [new file with mode: 0644]
test/subset/data/expected/cmap14/cmap14_font1.drop-hints-retain-gids.4E00,4E05,4E07.otf [new file with mode: 0644]
test/subset/data/expected/cmap14/cmap14_font1.drop-hints-retain-gids.4E02,4E03,4E08.otf [new file with mode: 0644]
test/subset/data/expected/cmap14/cmap14_font1.drop-hints-retain-gids.4E02.otf [new file with mode: 0644]
test/subset/data/expected/cmap14/cmap14_font1.drop-hints-retain-gids.4E03.otf [new file with mode: 0644]
test/subset/data/expected/cmap14/cmap14_font1.drop-hints-retain-gids.4E05,4E07,4E08,4E09.otf [new file with mode: 0644]
test/subset/data/expected/cmap14/cmap14_font1.drop-hints-retain-gids.4E08,4E09.otf [new file with mode: 0644]
test/subset/data/expected/cmap14/cmap14_font1.drop-hints-retain-gids.4E08.otf [new file with mode: 0644]
test/subset/data/expected/cmap14/cmap14_font1.drop-hints-retain-gids.retain-all-codepoint.otf [new file with mode: 0644]
test/subset/data/expected/cmap14/cmap14_font1.drop-hints.4E00,4E02,4E03.otf [new file with mode: 0644]
test/subset/data/expected/cmap14/cmap14_font1.drop-hints.4E00,4E03.otf [new file with mode: 0644]
test/subset/data/expected/cmap14/cmap14_font1.drop-hints.4E00,4E05,4E07.otf [new file with mode: 0644]
test/subset/data/expected/cmap14/cmap14_font1.drop-hints.4E02,4E03,4E08.otf [new file with mode: 0644]
test/subset/data/expected/cmap14/cmap14_font1.drop-hints.4E02.otf [new file with mode: 0644]
test/subset/data/expected/cmap14/cmap14_font1.drop-hints.4E03.otf [new file with mode: 0644]
test/subset/data/expected/cmap14/cmap14_font1.drop-hints.4E05,4E07,4E08,4E09.otf [new file with mode: 0644]
test/subset/data/expected/cmap14/cmap14_font1.drop-hints.4E08,4E09.otf [new file with mode: 0644]
test/subset/data/expected/cmap14/cmap14_font1.drop-hints.4E08.otf [new file with mode: 0644]
test/subset/data/expected/cmap14/cmap14_font1.drop-hints.retain-all-codepoint.otf [new file with mode: 0644]
test/subset/data/expected/cmap14/cmap14_font1.name-ids.4E00,4E02,4E03.otf [new file with mode: 0644]
test/subset/data/expected/cmap14/cmap14_font1.name-ids.4E00,4E03.otf [new file with mode: 0644]
test/subset/data/expected/cmap14/cmap14_font1.name-ids.4E00,4E05,4E07.otf [new file with mode: 0644]
test/subset/data/expected/cmap14/cmap14_font1.name-ids.4E02,4E03,4E08.otf [new file with mode: 0644]
test/subset/data/expected/cmap14/cmap14_font1.name-ids.4E02.otf [new file with mode: 0644]
test/subset/data/expected/cmap14/cmap14_font1.name-ids.4E03.otf [new file with mode: 0644]
test/subset/data/expected/cmap14/cmap14_font1.name-ids.4E05,4E07,4E08,4E09.otf [new file with mode: 0644]
test/subset/data/expected/cmap14/cmap14_font1.name-ids.4E08,4E09.otf [new file with mode: 0644]
test/subset/data/expected/cmap14/cmap14_font1.name-ids.4E08.otf [new file with mode: 0644]
test/subset/data/expected/cmap14/cmap14_font1.name-ids.retain-all-codepoint.otf [new file with mode: 0644]
test/subset/data/expected/cmap14/cmap14_font1.retain-gids.4E00,4E02,4E03.otf [new file with mode: 0644]
test/subset/data/expected/cmap14/cmap14_font1.retain-gids.4E00,4E03.otf [new file with mode: 0644]
test/subset/data/expected/cmap14/cmap14_font1.retain-gids.4E00,4E05,4E07.otf [new file with mode: 0644]
test/subset/data/expected/cmap14/cmap14_font1.retain-gids.4E02,4E03,4E08.otf [new file with mode: 0644]
test/subset/data/expected/cmap14/cmap14_font1.retain-gids.4E02.otf [new file with mode: 0644]
test/subset/data/expected/cmap14/cmap14_font1.retain-gids.4E03.otf [new file with mode: 0644]
test/subset/data/expected/cmap14/cmap14_font1.retain-gids.4E05,4E07,4E08,4E09.otf [new file with mode: 0644]
test/subset/data/expected/cmap14/cmap14_font1.retain-gids.4E08,4E09.otf [new file with mode: 0644]
test/subset/data/expected/cmap14/cmap14_font1.retain-gids.4E08.otf [new file with mode: 0644]
test/subset/data/expected/cmap14/cmap14_font1.retain-gids.retain-all-codepoint.otf [new file with mode: 0644]
test/subset/data/expected/full-font/Roboto-Regular.default.1FC,21,41,20,62,63.ttf
test/subset/data/expected/full-font/Roboto-Regular.default.61,62,63.ttf
test/subset/data/expected/full-font/Roboto-Regular.default.D7,D8,D9,DA,DE.ttf
test/subset/data/expected/full-font/Roboto-Regular.drop-hints.1FC,21,41,20,62,63.ttf
test/subset/data/expected/full-font/Roboto-Regular.drop-hints.61,62,63.ttf
test/subset/data/expected/full-font/Roboto-Regular.drop-hints.D7,D8,D9,DA,DE.ttf
test/subset/data/expected/japanese/Mplus1p-Regular.default.3042,3044,3046,3048,304A,304B.ttf
test/subset/data/expected/japanese/Mplus1p-Regular.default.3042,3044,3046,73E0,5EA6,8F38.ttf
test/subset/data/expected/japanese/Mplus1p-Regular.default.61,63,65,6B.ttf
test/subset/data/expected/japanese/Mplus1p-Regular.default.660E,6975,73E0,5EA6,8F38,6E05.ttf
test/subset/data/expected/japanese/Mplus1p-Regular.default.660E.ttf
test/subset/data/expected/japanese/Mplus1p-Regular.drop-hints.3042,3044,3046,3048,304A,304B.ttf
test/subset/data/expected/japanese/Mplus1p-Regular.drop-hints.3042,3044,3046,73E0,5EA6,8F38.ttf
test/subset/data/expected/japanese/Mplus1p-Regular.drop-hints.61,63,65,6B.ttf
test/subset/data/expected/japanese/Mplus1p-Regular.drop-hints.660E,6975,73E0,5EA6,8F38,6E05.ttf
test/subset/data/expected/japanese/Mplus1p-Regular.drop-hints.660E.ttf
test/subset/data/expected/layout.gpos/gpos1_2_font.keep-layout-retain-gids.41,43.otf [new file with mode: 0644]
test/subset/data/expected/layout.gpos/gpos1_2_font.keep-layout-retain-gids.41,46.otf [new file with mode: 0644]
test/subset/data/expected/layout.gpos/gpos1_2_font.keep-layout-retain-gids.43,46.otf [new file with mode: 0644]
test/subset/data/expected/layout.gpos/gpos1_2_font.keep-layout-retain-gids.retain-all-codepoint.otf [new file with mode: 0644]
test/subset/data/expected/layout.gpos2/gpos2_1_font7.keep-layout-retain-gids.21,23,25.otf [new file with mode: 0644]
test/subset/data/expected/layout.gpos2/gpos2_1_font7.keep-layout-retain-gids.21,23.otf [new file with mode: 0644]
test/subset/data/expected/layout.gpos2/gpos2_1_font7.keep-layout-retain-gids.retain-all-codepoint.otf [new file with mode: 0644]
test/subset/data/expected/layout.gpos2/gpos2_1_font7.keep-layout.21,23,25.otf [new file with mode: 0644]
test/subset/data/expected/layout.gpos2/gpos2_1_font7.keep-layout.21,23.otf [new file with mode: 0644]
test/subset/data/expected/layout.gpos2/gpos2_1_font7.keep-layout.retain-all-codepoint.otf [new file with mode: 0644]
test/subset/data/expected/layout.gpos2/gpos2_2_font5.keep-layout-retain-gids.21,23,25.otf [new file with mode: 0644]
test/subset/data/expected/layout.gpos2/gpos2_2_font5.keep-layout-retain-gids.21,23.otf [new file with mode: 0644]
test/subset/data/expected/layout.gpos2/gpos2_2_font5.keep-layout-retain-gids.retain-all-codepoint.otf [new file with mode: 0644]
test/subset/data/expected/layout.gpos2/gpos2_2_font5.keep-layout.21,23,25.otf [new file with mode: 0644]
test/subset/data/expected/layout.gpos2/gpos2_2_font5.keep-layout.21,23.otf [new file with mode: 0644]
test/subset/data/expected/layout.gpos2/gpos2_2_font5.keep-layout.retain-all-codepoint.otf [new file with mode: 0644]
test/subset/data/expected/layout.gpos3/gpos3_font3.keep-layout-retain-gids.28,29.otf [new file with mode: 0644]
test/subset/data/expected/layout.gpos3/gpos3_font3.keep-layout-retain-gids.28,2B.otf [new file with mode: 0644]
test/subset/data/expected/layout.gpos3/gpos3_font3.keep-layout-retain-gids.29,2B.otf [new file with mode: 0644]
test/subset/data/expected/layout.gpos3/gpos3_font3.keep-layout-retain-gids.retain-all-codepoint.otf [new file with mode: 0644]
test/subset/data/expected/layout.gpos3/gpos3_font3.keep-layout.28,29.otf [new file with mode: 0644]
test/subset/data/expected/layout.gpos3/gpos3_font3.keep-layout.28,2B.otf [new file with mode: 0644]
test/subset/data/expected/layout.gpos3/gpos3_font3.keep-layout.29,2B.otf [new file with mode: 0644]
test/subset/data/expected/layout.gpos3/gpos3_font3.keep-layout.retain-all-codepoint.otf [new file with mode: 0644]
test/subset/data/expected/layout.gsub6/gsub_chaining1_multiple_subrules_f1.keep-layout-retain-gids.30,31,32,33.otf [new file with mode: 0644]
test/subset/data/expected/layout.gsub6/gsub_chaining1_multiple_subrules_f1.keep-layout-retain-gids.retain-all-codepoint.otf [new file with mode: 0644]
test/subset/data/expected/layout.gsub6/gsub_chaining1_multiple_subrules_f1.keep-layout.30,31,32,33.otf [new file with mode: 0644]
test/subset/data/expected/layout.gsub6/gsub_chaining1_multiple_subrules_f1.keep-layout.retain-all-codepoint.otf [new file with mode: 0644]
test/subset/data/expected/layout.gsub6/gsub_chaining2_multiple_subrules_f1.keep-layout-retain-gids.30,31,32,33.otf [new file with mode: 0644]
test/subset/data/expected/layout.gsub6/gsub_chaining2_multiple_subrules_f1.keep-layout-retain-gids.retain-all-codepoint.otf [new file with mode: 0644]
test/subset/data/expected/layout.gsub6/gsub_chaining2_multiple_subrules_f1.keep-layout.30,31,32,33.otf [new file with mode: 0644]
test/subset/data/expected/layout.gsub6/gsub_chaining2_multiple_subrules_f1.keep-layout.retain-all-codepoint.otf [new file with mode: 0644]
test/subset/data/expected/layout.gsub6/gsub_chaining3_simple_f2.keep-layout-retain-gids.30,31,32,33.otf [new file with mode: 0644]
test/subset/data/expected/layout.gsub6/gsub_chaining3_simple_f2.keep-layout-retain-gids.retain-all-codepoint.otf [new file with mode: 0644]
test/subset/data/expected/layout.gsub6/gsub_chaining3_simple_f2.keep-layout.30,31,32,33.otf [new file with mode: 0644]
test/subset/data/expected/layout.gsub6/gsub_chaining3_simple_f2.keep-layout.retain-all-codepoint.otf [new file with mode: 0644]
test/subset/data/expected/layout/Roboto-Regular.smallcaps.keep-layout-retain-gids.41,42,43.ttf [new file with mode: 0644]
test/subset/data/expected/layout/Roboto-Regular.smallcaps.keep-layout-retain-gids.41,43.ttf [new file with mode: 0644]
test/subset/data/expected/layout/Roboto-Regular.smallcaps.keep-layout-retain-gids.41.ttf [new file with mode: 0644]
test/subset/data/expected/layout/Roboto-Regular.smallcaps.keep-layout-retain-gids.43.ttf [new file with mode: 0644]
test/subset/data/expected/layout/Roboto-Regular.smallcaps.keep-layout-retain-gids.CA,CB.ttf [new file with mode: 0644]
test/subset/data/expected/layout/Roboto-Regular.smallcaps.keep-layout.41,42,43.ttf [new file with mode: 0644]
test/subset/data/expected/layout/Roboto-Regular.smallcaps.keep-layout.41,43.ttf [new file with mode: 0644]
test/subset/data/expected/layout/Roboto-Regular.smallcaps.keep-layout.41.ttf [new file with mode: 0644]
test/subset/data/expected/layout/Roboto-Regular.smallcaps.keep-layout.43.ttf [new file with mode: 0644]
test/subset/data/expected/layout/Roboto-Regular.smallcaps.keep-layout.CA,CB.ttf [new file with mode: 0644]
test/subset/data/fonts/Comfortaa-Regular-new.ttf [new file with mode: 0644]
test/subset/data/fonts/Roboto-Regular.smallcaps.ttf [new file with mode: 0644]
test/subset/data/fonts/SourceHanSans-Regular.otf [deleted file]
test/subset/data/fonts/SourceHanSans-Regular_subset.otf [new file with mode: 0644]
test/subset/data/fonts/cmap14_font1.otf [new file with mode: 0644]
test/subset/data/fonts/gpos1_2_font.otf [new file with mode: 0644]
test/subset/data/fonts/gpos2_1_font7.otf [new file with mode: 0644]
test/subset/data/fonts/gpos2_2_font5.otf [new file with mode: 0644]
test/subset/data/fonts/gpos3_font3.otf [new file with mode: 0644]
test/subset/data/fonts/gsub_chaining1_multiple_subrules_f1.otf [new file with mode: 0644]
test/subset/data/fonts/gsub_chaining2_multiple_subrules_f1.otf [new file with mode: 0644]
test/subset/data/fonts/gsub_chaining3_simple_f2.otf [new file with mode: 0644]
test/subset/data/profiles/keep-layout-retain-gids.txt [new file with mode: 0644]
test/subset/data/profiles/keep-layout.txt [new file with mode: 0644]
test/subset/data/profiles/name-ids.txt [new file with mode: 0644]
test/subset/data/tests/basics.tests
test/subset/data/tests/cff-full-font.tests [new file with mode: 0644]
test/subset/data/tests/cff-japanese.tests [new file with mode: 0644]
test/subset/data/tests/cmap14.tests [new file with mode: 0644]
test/subset/data/tests/full-font.tests
test/subset/data/tests/layout.gpos.tests [new file with mode: 0644]
test/subset/data/tests/layout.gpos2.tests [new file with mode: 0644]
test/subset/data/tests/layout.gpos3.tests [new file with mode: 0644]
test/subset/data/tests/layout.gsub6.tests [new file with mode: 0644]
test/subset/data/tests/layout.tests [new file with mode: 0644]
test/subset/run-tests.py
test/subset/subset_test_suite.py
util/Makefile.am
util/Makefile.in
util/Makefile.sources
util/ansi-print.cc
util/hb-ot-shape-closure.cc
util/hb-shape.cc
util/hb-subset.cc
util/helper-cairo-ansi.cc
util/helper-cairo.cc
util/options-subset.cc [new file with mode: 0644]
util/options.cc
util/options.hh

diff --git a/AUTHORS b/AUTHORS
index 0763761..83c0c66 100644 (file)
--- a/AUTHORS
+++ b/AUTHORS
@@ -1,11 +1,14 @@
 Behdad Esfahbod
+David Corbett
 David Turner
 Ebrahim Byagowi
+Garret Rieger
 Jonathan Kew
 Khaled Hosny
 Lars Knoll
 Martin Hosken
 Owen Taylor
+Roderick Sheeter
 Roozbeh Pournader
 Simon Hausmann
 Werner Lemberg
index f64f96d..2a8fd8b 100644 (file)
@@ -35,7 +35,6 @@ endif ()
 ## HarfBuzz build configurations
 option(HB_HAVE_FREETYPE "Enable freetype interop helpers" OFF)
 option(HB_HAVE_GRAPHITE2 "Enable Graphite2 complementary shaper" OFF)
-option(HB_BUILTIN_UCDN "Use HarfBuzz provided UCDN" ON)
 option(HB_HAVE_GLIB "Enable glib unicode functions" OFF)
 option(HB_HAVE_ICU "Enable icu unicode functions" OFF)
 if (APPLE)
@@ -44,6 +43,7 @@ if (APPLE)
 endif ()
 if (WIN32)
   option(HB_HAVE_UNISCRIBE "Enable Uniscribe shaper backend on Windows" OFF)
+  option(HB_HAVE_GDI "Enable GDI integration helpers on Windows" OFF)
   option(HB_HAVE_DIRECTWRITE "Enable DirectWrite shaper backend on Windows" OFF)
 endif ()
 option(HB_BUILD_UTILS "Build harfbuzz utils, needs cairo, freetype, and glib properly be installed" OFF)
@@ -70,7 +70,6 @@ option(HB_CHECK OFF "Do a configuration suitable for testing (shared library and
 if (HB_CHECK)
   set (BUILD_SHARED_LIBS ON)
   set (HB_BUILD_UTILS ON)
-  set (HB_BUILTIN_UCDN ON)
   set (HB_HAVE_ICU)
   set (HB_HAVE_GLIB ON)
   #set (HB_HAVE_GOBJECT ON)
@@ -79,6 +78,7 @@ if (HB_CHECK)
   set (HB_HAVE_GRAPHITE2 ON)
   if (WIN32)
     set (HB_HAVE_UNISCRIBE ON)
+    set (HB_HAVE_GDI ON)
     set (HB_HAVE_DIRECTWRITE ON)
   elseif (APPLE)
     set (HB_HAVE_CORETEXT ON)
@@ -90,8 +90,6 @@ include_directories(AFTER
   ${PROJECT_BINARY_DIR}/src
 )
 
-add_definitions(-DHAVE_FALLBACK)
-
 # We need PYTHON_EXECUTABLE to be set for running the tests...
 include (FindPythonInterp)
 
@@ -110,7 +108,7 @@ endmacro ()
 if (UNIX)
   list(APPEND CMAKE_REQUIRED_LIBRARIES m)
 endif ()
-check_funcs(atexit mprotect sysconf getpagesize mmap isatty newlocale strtod_l round)
+check_funcs(atexit mprotect sysconf getpagesize mmap isatty newlocale strtod_l roundf)
 check_include_file(unistd.h HAVE_UNISTD_H)
 if (${HAVE_UNISTD_H})
   add_definitions(-DHAVE_UNISTD_H)
@@ -144,8 +142,8 @@ endif ()
 
 ## Extract variables from Makefile files
 function (extract_make_variable variable makefile_source)
-  string(REGEX MATCH "${variable} = ([^$]+)\\$" temp ${makefile_source})
-  string(REGEX MATCHALL "[^ \n\t\\]+" listVar ${CMAKE_MATCH_1})
+  string(REGEX MATCH "${variable} = ([^$]+)\\$" temp "${makefile_source}")
+  string(REGEX MATCHALL "[^ \n\t\\]+" listVar "${CMAKE_MATCH_1}")
   set (${variable} ${listVar} PARENT_SCOPE)
 endfunction ()
 
@@ -160,14 +158,9 @@ endfunction ()
 
 file(READ ${PROJECT_SOURCE_DIR}/src/Makefile.sources SRCSOURCES)
 file(READ ${PROJECT_SOURCE_DIR}/util/Makefile.sources UTILSOURCES)
-file(READ ${PROJECT_SOURCE_DIR}/src/hb-ucdn/Makefile.sources UCDNSOURCES)
 
-extract_make_variable(HB_BASE_sources ${SRCSOURCES})
-add_prefix_to_list(HB_BASE_sources "${PROJECT_SOURCE_DIR}/src/")
 extract_make_variable(HB_BASE_headers ${SRCSOURCES})
 add_prefix_to_list(HB_BASE_headers "${PROJECT_SOURCE_DIR}/src/")
-extract_make_variable(HB_FALLBACK_sources ${SRCSOURCES})
-add_prefix_to_list(HB_FALLBACK_sources "${PROJECT_SOURCE_DIR}/src/")
 
 extract_make_variable(HB_SUBSET_sources ${SRCSOURCES})
 add_prefix_to_list(HB_SUBSET_sources "${PROJECT_SOURCE_DIR}/src/")
@@ -191,9 +184,6 @@ add_prefix_to_list(HB_SUBSET_CLI_sources "${PROJECT_SOURCE_DIR}/util/")
 extract_make_variable(HB_OT_SHAPE_CLOSURE_sources ${UTILSOURCES})
 add_prefix_to_list(HB_OT_SHAPE_CLOSURE_sources "${PROJECT_SOURCE_DIR}/util/")
 
-extract_make_variable(LIBHB_UCDN_sources ${UCDNSOURCES})
-add_prefix_to_list(LIBHB_UCDN_sources "${PROJECT_SOURCE_DIR}/src/hb-ucdn/")
-
 
 file(READ configure.ac CONFIGUREAC)
 string(REGEX MATCH "\\[(([0-9]+)\\.([0-9]+)\\.([0-9]+))\\]" HB_VERSION_MATCH ${CONFIGUREAC})
@@ -202,61 +192,12 @@ set (HB_VERSION_MAJOR ${CMAKE_MATCH_2})
 set (HB_VERSION_MINOR ${CMAKE_MATCH_3})
 set (HB_VERSION_MICRO ${CMAKE_MATCH_4})
 
-
-## Define ragel tasks
-# if (NOT IN_HB_DIST)
-#  foreach (ragel_output IN ITEMS ${HB_BASE_RAGEL_GENERATED_sources})
-#    string(REGEX MATCH "([^/]+)\\.hh" temp ${ragel_output})
-#    set (target_name ${CMAKE_MATCH_1})
-#    add_custom_command(OUTPUT ${ragel_output}
-#      COMMAND ${RAGEL} -G2 -o ${ragel_output} ${PROJECT_SOURCE_DIR}/src/${target_name}.rl -I ${PROJECT_SOURCE_DIR} ${ARGN}
-#      DEPENDS ${PROJECT_SOURCE_DIR}/src/${target_name}.rl
-#    )
-#    add_custom_target(harfbuzz_${target_name} DEPENDS ${PROJECT_BINARY_DIR}/src/${target_name})
-#  endforeach ()
-
-#  mark_as_advanced(RAGEL)
-# endif ()
-
-
-## Generate hb-version.h
-# if (NOT IN_HB_DIST)
-#  set (HB_VERSION_H_IN "${PROJECT_SOURCE_DIR}/src/hb-version.h.in")
-#  set (HB_VERSION_H "${PROJECT_BINARY_DIR}/src/hb-version.h")
-#  set_source_files_properties("${HB_VERSION_H}" PROPERTIES GENERATED true)
-#  configure_file("${HB_VERSION_H_IN}" "${HB_VERSION_H}.tmp" @ONLY)
-#  execute_process(COMMAND "${CMAKE_COMMAND}" -E copy_if_different
-#    "${HB_VERSION_H}.tmp"
-#    "${HB_VERSION_H}"
-#  )
-#  file(REMOVE "${HB_VERSION_H}.tmp")
-# endif ()
-
-
 ## Define sources and headers of the project
-set (project_sources
-  ${HB_BASE_sources}
-  ${HB_BASE_RAGEL_GENERATED_sources}
-
-  ${HB_FALLBACK_sources}
-)
-
-set (subset_project_sources
-  ${HB_SUBSET_sources}
-)
-
+set (project_sources ${PROJECT_SOURCE_DIR}/src/harfbuzz.cc) # use amalgam source
+set (subset_project_sources ${HB_SUBSET_sources})
 set (project_extra_sources)
-
-set (project_headers
-  #${HB_VERSION_H}
-
-  ${HB_BASE_headers}
-)
-
-set (subset_project_headers
-  ${HB_SUBSET_headers}
-)
-
+set (project_headers ${HB_BASE_headers})
+set (subset_project_headers ${HB_SUBSET_headers})
 
 ## Find and include needed header folders and libraries
 if (HB_HAVE_FREETYPE)
@@ -269,7 +210,6 @@ if (HB_HAVE_FREETYPE)
   include_directories(AFTER ${FREETYPE_INCLUDE_DIRS})
   add_definitions(-DHAVE_FREETYPE=1)
 
-  list(APPEND project_sources ${PROJECT_SOURCE_DIR}/src/hb-ft.cc)
   list(APPEND project_headers ${PROJECT_SOURCE_DIR}/src/hb-ft.h)
 
   # So check_funcs can find its headers
@@ -287,7 +227,6 @@ if (HB_HAVE_GRAPHITE2)
 
   include_directories(${GRAPHITE2_INCLUDE_DIR})
 
-  list(APPEND project_sources ${PROJECT_SOURCE_DIR}/src/hb-graphite2.cc)
   list(APPEND project_headers ${PROJECT_SOURCE_DIR}/src/hb-graphite2.h)
 
   list(APPEND THIRD_PARTY_LIBS ${GRAPHITE2_LIBRARY})
@@ -295,14 +234,6 @@ if (HB_HAVE_GRAPHITE2)
   mark_as_advanced(GRAPHITE2_INCLUDE_DIR GRAPHITE2_LIBRARY)
 endif ()
 
-if (HB_BUILTIN_UCDN)
-  include_directories(src/hb-ucdn)
-  add_definitions(-DHAVE_UCDN)
-
-  list(APPEND project_sources ${PROJECT_SOURCE_DIR}/src/hb-ucdn.cc)
-  list(APPEND project_extra_sources ${LIBHB_UCDN_sources})
-endif ()
-
 if (HB_HAVE_GLIB)
   add_definitions(-DHAVE_GLIB)
 
@@ -316,7 +247,6 @@ if (HB_HAVE_GLIB)
 
   include_directories(${GLIBCONFIG_INCLUDE_DIR} ${GLIB_INCLUDE_DIR})
 
-  list(APPEND project_sources ${PROJECT_SOURCE_DIR}/src/hb-glib.cc)
   list(APPEND project_headers ${PROJECT_SOURCE_DIR}/src/hb-glib.h)
 
   list(APPEND THIRD_PARTY_LIBS ${GLIB_LIBRARIES})
@@ -336,7 +266,6 @@ if (HB_HAVE_ICU)
 
   include_directories(${ICU_INCLUDE_DIR})
 
-  list(APPEND project_sources ${PROJECT_SOURCE_DIR}/src/hb-icu.cc)
   list(APPEND project_headers ${PROJECT_SOURCE_DIR}/src/hb-icu.h)
 
   list(APPEND THIRD_PARTY_LIBS ${ICU_LIBRARY})
@@ -348,7 +277,6 @@ if (APPLE AND HB_HAVE_CORETEXT)
   # Apple Advanced Typography
   add_definitions(-DHAVE_CORETEXT)
 
-  list(APPEND project_sources ${PROJECT_SOURCE_DIR}/src/hb-coretext.cc)
   list(APPEND project_headers ${PROJECT_SOURCE_DIR}/src/hb-coretext.h)
 
   if (HB_IOS)
@@ -379,21 +307,21 @@ if (APPLE AND HB_HAVE_CORETEXT)
   endif ()
 endif ()
 
+if (WIN32 AND HB_HAVE_GDI)
+  add_definitions(-DHAVE_GDI)
+  list(APPEND project_headers ${PROJECT_SOURCE_DIR}/src/hb-gdi.h)
+  list(APPEND THIRD_PARTY_LIBS gdi32)
+endif ()
+
 if (WIN32 AND HB_HAVE_UNISCRIBE)
   add_definitions(-DHAVE_UNISCRIBE)
-
-  list(APPEND project_sources ${PROJECT_SOURCE_DIR}/src/hb-uniscribe.cc)
   list(APPEND project_headers ${PROJECT_SOURCE_DIR}/src/hb-uniscribe.h)
-
   list(APPEND THIRD_PARTY_LIBS usp10 gdi32 rpcrt4)
 endif ()
 
 if (WIN32 AND HB_HAVE_DIRECTWRITE)
   add_definitions(-DHAVE_DIRECTWRITE)
-
-  list(APPEND project_sources ${PROJECT_SOURCE_DIR}/src/hb-directwrite.cc)
   list(APPEND project_headers ${PROJECT_SOURCE_DIR}/src/hb-directwrite.h)
-
   list(APPEND THIRD_PARTY_LIBS dwrite rpcrt4)
 endif ()
 
@@ -501,7 +429,6 @@ if (HB_HAVE_GOBJECT)
   )
 endif ()
 
-
 ## Atomic ops availability detection
 file(WRITE "${PROJECT_BINARY_DIR}/try_compile_intel_atomic_primitives.c"
 "              void memory_barrier (void) { __sync_synchronize (); }
@@ -610,7 +537,6 @@ if (WIN32)
 endif ()
 
 if (HB_HAVE_INTROSPECTION)
-
   find_package(PkgConfig)
   pkg_check_modules(PC_GI QUIET gobject-introspection-1.0)
 
@@ -844,7 +770,7 @@ endif ()
 
 if (HB_BUILD_TESTS)
   ## src/ executables
-  foreach (prog main test test-would-substitute test-size-params test-buffer-serialize hb-ot-tag test-unicode-ranges)
+  foreach (prog main test test-gsub-would-substitute test-gpos-size-params test-buffer-serialize test-unicode-ranges) # hb-ot-tag
     set (prog_name ${prog})
     if (${prog_name} STREQUAL "test")
       # test can not be used as a valid executable name on cmake, lets special case it
@@ -853,7 +779,7 @@ if (HB_BUILD_TESTS)
     add_executable(${prog_name} ${PROJECT_SOURCE_DIR}/src/${prog}.cc)
     target_link_libraries(${prog_name} harfbuzz ${THIRD_PARTY_LIBS})
   endforeach ()
-  set_target_properties(hb-ot-tag PROPERTIES COMPILE_FLAGS "-DMAIN")
+  set_target_properties(hb-ot-tag PROPERTIES COMPILE_FLAGS "-DMAIN")
 
   ## Tests
   if (UNIX OR MINGW)
diff --git a/CONFIG.md b/CONFIG.md
new file mode 100644 (file)
index 0000000..46971b0
--- /dev/null
+++ b/CONFIG.md
@@ -0,0 +1,151 @@
+# Configuring HarfBuzz
+
+Most of the time you will not need any custom configuration.  The configuration
+options provided by `configure` or `cmake` should be enough.  In particular,
+if you just want HarfBuzz library plus hb-shape / hb-view utilities, make sure
+FreeType and Cairo are available and found during configuration.
+
+If you are building for distribution, you should more carefully consider whether
+you need Glib, ICU, Graphite2, as well as CoreText / Uniscribe / DWrite.  Make
+sure the relevant ones are enabled.
+
+If you are building for custom environment (embedded, downloadable app, etc)
+where you mostly just want to call `hb_shape()` and the binary size of the
+resulting library is very important to you, the rest of this file guides you
+through your options to disable features you may not need, in exchange for
+binary size savings.
+
+## Compiler Options
+
+Make sure you build with your compiler's "optimize for size" option.  On `gcc`
+this is `-Os`, and can be enabled by passing `CXXFLAGS=-Os` either to `configure`
+(sticky) or to `make` (non-sticky).  On clang there is an even more extreme flag,
+`-Oz`.
+
+HarfBuzz heavily uses inline functions and the optimize-size flag can make the
+library smaller by 20% or more.  Moreover, sometimes, based on the target CPU,
+the optimize-size builds perform *faster* as well, thanks to lower code
+footprint and caching effects.  So, definitely try that even if size is not
+extremely tight but you have a huge application.  For example, Chrome does
+that.  Note that this configuration also automatically enables certain internal
+optimizations.  Search for `HB_OPTIMIZE_SIZE` for details, if you are using
+other compilers, or continue reading.
+
+Another compiler option to consider is "link-time optimization", also known as
+'lto'.  To enable that, with `gcc` or `clang`, add `-flto` to both `CXXFLAGS`
+and `LDFLAGS`, either on `configure` invocation (sticky) or on `make` (non-sticky).
+This, also, can have a huge impact on the final size, 20% or more.
+
+Finally, if you are making a static library build or otherwise linking the
+library into your app, make sure your linker removes unused functions.  This
+can be tricky and differ from environment to environment, but you definitely
+want to make sure this happens.  Otherwise, every unused public function will
+be adding unneeded bytes to your binary.  The following pointers might come
+handy:
+
+ * https://lwn.net/Articles/741494/ (all of the four-part series)
+ * https://elinux.org/images/2/2d/ELC2010-gc-sections_Denys_Vlasenko.pdf
+
+Combining the above three build options should already shrink your library a lot.
+The rest of this file shows you ways to shrink the library even further at the
+expense of removing functionality (that may not be needed).  The remaining
+options are all enabled by defining pre-processor macros, which can be done
+via `CXXFLAGS` or `CPPFLAGS` similarly.
+
+
+## Unicode-functions
+
+Access to Unicode data can be configured at compile time as well as run-time.
+By default, HarfBuzz ships with its own compact subset of properties from
+Unicode Character Database that it needs.  This is a highly-optimized
+implementation that depending on compile settings (optimize-size or not)
+takes around ~40kb or ~60kb.  Using this implementation (default) is highly
+recommended, as HarfBuzz always ships with data from latest version of Unicode.
+This implementation can be disabled by defining `HB_NO_UCD`.
+
+For example, if you are enabling ICU as a built-in option, or GLib, those
+can provide Unicode data as well, so defining `HB_NO_UCD` might save you
+space without reducing functionality (to the extent that the Unicode version
+of those implementations is recent.)
+
+If, however, you provide your own Unicode data to HarfBuzz at run-time by
+calling `hb_buffer_set_unicode_funcs` on every buffer you create, and you do
+not rely on `hb_unicode_funcs_get_default()` results, you can disable the
+internal implementation by defining both `HB_NO_UCD` and `HB_NO_UNICODE_FUNCS`.
+The latter is needed to guard against accidentally building a library without
+any default Unicode implementations.
+
+
+## Font-functions
+
+Access to certain font functionalities can also be configured at run-time.  By
+default, HarfBuzz uses an efficient internal implementation of OpenType
+functionality for this.  This internal implementation is called `hb-ot-font`.
+All newly-created `hb_font_t` objects by default use `hb-ot-font`.  Using this
+is highly recommended, and is what fonts use by default when they are created.
+
+Most embedded uses will probably use HarfBuzz with FreeType using `hb-ft.h`.
+In that case, or if you otherwise provide those functions by calling
+`hb_font_set_funcs()` on every font you create, you can disable `hb-ot-font`
+without loss of functionality by defining `HB_NO_OT_FONT`.
+
+
+## Shapers
+
+Most HarfBuzz clients use it for the main shaper, called "ot".  However, it
+is legitimate to want to compile HarfBuzz with only another backend, eg.
+CoreText, for example for an iOS app.  For that, you want `HB_NO_OT_SHAPE`.
+If you are going down that route, check if you want `HB_NO_OT`.
+
+This is very rarely what you need.  Make sure you understand exactly what you
+are doing.
+
+Defining `HB_NO_FALLBACK_SHAPE` however is pretty harmless.  That removes the
+(unused) "fallback" shaper.
+
+
+## Thread-safety
+
+By default HarfBuzz builds as a thread-safe library.  The exception is that
+the `HB_TINY` predefined configuring (more below) disables thread-safety.
+
+If you do /not/ need thread-safety in the library (eg. you always call into
+HarfBuzz from the same thread), you can disable thread-safety by defining
+`HB_NO_MT`.  As noted already, this is enabled by `HB_TINY`.
+
+
+## Pre-defined configurations
+
+The [`hb-config.hh`](src/hb-config.hh) internal header supports three
+pre-defined configurations as well grouping of various configuration options.
+The pre-defined configurations are:
+
+  * `HB_MINI`: Disables shaping of AAT as well as legacy fonts.  Ie. it produces
+    a capable OpenType shaper only.
+
+  * `HB_LEAN`: Disables various non-shaping functionality in the library, as well
+    as esoteric or rarely-used shaping features.  See the definition for details.
+
+  * `HB_TINY`: Enables both `HB_MINI` and `HB_LEAN` configurations, as well as
+    disabling thread-safety and debugging, and use even more size-optimized data
+    tables.
+
+
+## Tailoring configuration
+
+Most of the time, one of the pre-defined configuration is exactly what one needs.
+Sometimes, however, the pre-defined configuration cuts out features that might
+be desired in the library.  Unfortunately there is no quick way to undo those
+configurations from the command-line.  But one can add a header file called
+`config-override.h` to undefine certain `HB_NO_*` symbols as desired.  Then
+define `HAVE_CONFIG_OVERRIDE_H` to make `hb-config.hh` include your configuration
+overrides at the end.
+
+
+## Notes
+
+Note that the config option `HB_NO_CFF`, which is enabled by `HB_LEAN` and
+`HB_TINY` does /not/ mean that the resulting library won't work with CFF fonts.
+The library can shape valid CFF fonts just fine, with or without this option.
+This option disables (among other things) the code to calculate glyph exntents
+for CFF fonts.
diff --git a/COPYING b/COPYING
index 9d1056f..0278e60 100644 (file)
--- a/COPYING
+++ b/COPYING
@@ -2,7 +2,8 @@ HarfBuzz is licensed under the so-called "Old MIT" license.  Details follow.
 For parts of HarfBuzz that are licensed under different licenses see individual
 files names COPYING in subdirectories where applicable.
 
-Copyright © 2010,2011,2012  Google, Inc.
+Copyright © 2010,2011,2012,2013,2014,2015,2016,2017,2018,2019  Google, Inc.
+Copyright © 2019  Facebook, Inc.
 Copyright © 2012  Mozilla Foundation
 Copyright © 2011  Codethink Limited
 Copyright © 2008,2010  Nokia Corporation and/or its subsidiary(-ies)
index 1ee02dd..ec56461 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
-commit d6fc1d49aa099104a889c96bc9087c21d8fc0960
+commit 3a74ee528255cc027d84b204a87b5c25e47bff79
 Author: Behdad Esfahbod <behdad@behdad.org>
-Date:   Thu Mar 28 21:21:26 2019 -0700
+Date:   Tue Oct 29 12:27:03 2019 -0700
 
-    2.4.0
+    2.6.4
 
- NEWS             | 11 +++++++++++
- configure.ac     |  2 +-
- src/hb-buffer.h  |  2 +-
- src/hb-version.h |  6 +++---
- 4 files changed, 16 insertions(+), 5 deletions(-)
+ NEWS             | 7 +++++++
+ configure.ac     | 2 +-
+ src/hb-version.h | 4 ++--
+ 3 files changed, 10 insertions(+), 3 deletions(-)
 
-commit d2db71fdc4764eecf8320cf465ee0e4254146b6e
-Author: Behdad Esfahbod <behdad@behdad.org>
-Date:   Thu Mar 28 21:00:58 2019 -0700
+commit 3958f6fb2378d83dd5107d62a8464187c93707b0
+Author: Ebrahim Byagowi <ebrahim@gnu.org>
+Date:   Tue Oct 29 22:36:50 2019 +0330
 
-    Use internal bsearch() for language tags
-    
-    Fixes https://github.com/harfbuzz/harfbuzz/pull/1639
+    Add in_range in hb_bytes_t to merge range_checker_t with it
 
- src/hb-ot-tag.cc | 46 ++++++++++++++++++++++------------------------
- 1 file changed, 22 insertions(+), 24 deletions(-)
+ src/hb-array.hh             |  9 +++++++++
+ src/hb-ot-glyf-table.hh     | 28 ++++++++++++--------------
+ src/hb-ot-var-gvar-table.hh | 49 +++++++++++++++------------------------------
+ 3 files changed, 38 insertions(+), 48 deletions(-)
 
-commit 21bb80ebf2e20025a196386cee8fd92dd1eb4597
-Author: Behdad Esfahbod <behdad@behdad.org>
-Date:   Thu Mar 28 20:50:04 2019 -0700
+commit 7915c5d6fa3efac99df08a54d4437eca0b780033
+Author: Ebrahim Byagowi <ebrahim@gnu.org>
+Date:   Tue Oct 29 22:55:34 2019 +0330
 
-    [indic] Add back medial-consonant to grammar
-    
-    Fixes https://github.com/harfbuzz/harfbuzz/issues/1592
+    [ci] Check the recipt introduce in 7152ac3
 
- src/hb-ot-shape-complex-indic-machine.hh           | 1244 +++++++++++---------
- src/hb-ot-shape-complex-indic-machine.rl           |    5 +-
- src/hb-ot-shape-complex-indic.cc                   |    2 +-
- src/hb-ot-shape-complex-indic.hh                   |    6 +-
- .../f75c4b05a0a4d67c1a808081ae3d74a9c66509e8.ttf   |  Bin 0 -> 1924 bytes
- .../data/in-house/tests/indic-syllable.tests       |    2 +
- 6 files changed, 672 insertions(+), 587 deletions(-)
+ .circleci/config.yml | 1 +
+ 1 file changed, 1 insertion(+)
 
-commit 5ab6de7a6fbad4c4a954c2c81d216486a5a14f72
-Author: Behdad Esfahbod <behdad@behdad.org>
-Date:   Thu Mar 28 20:23:12 2019 -0700
+commit aa3831e295540083350c640d4a630f53e70d822f
+Author: Ebrahim Byagowi <ebrahim@gnu.org>
+Date:   Tue Oct 29 21:37:07 2019 +0330
 
-    [khmer] Add trailing Coeng to syllable grammar
-    
-    Fixes https://github.com/harfbuzz/harfbuzz/issues/1541
+    [glyf] Use contour_bounds_t::empty to simplify get_extents logic
 
- src/hb-ot-shape-complex-khmer-machine.hh           | 248 ++++++++++-----------
- src/hb-ot-shape-complex-khmer-machine.rl           |   2 +-
- .../ad01ab2ea1cb1a4d3a2783e2675112ef11ae6404.ttf   | Bin 0 -> 1500 bytes
- test/shaping/data/in-house/tests/khmer-misc.tests  |   1 +
- 4 files changed, 122 insertions(+), 129 deletions(-)
+ src/hb-ot-glyf-table.hh | 20 ++++++--------------
+ 1 file changed, 6 insertions(+), 14 deletions(-)
 
-commit 7360265e69a8cdaa9f993c36def2860a79cca49f
+commit d59ae5836d1349b885db980cbb741da33caebfde
 Author: Ebrahim Byagowi <ebrahim@gnu.org>
-Date:   Thu Mar 28 16:57:56 2019 -0700
+Date:   Tue Oct 29 21:30:04 2019 +0330
 
-    [ci] Tweak macos and psvita bots (#1638)
-    
-    * Add --with-graphite2 to macOS
-    * Add a dummy ragel script for psvita
+    [glyf] Refactor contour_bounds_t use to make its fields protected
 
.circleci/config.yml | 6 +++---
- 1 file changed, 3 insertions(+), 3 deletions(-)
src/hb-ot-glyf-table.hh | 47 ++++++++++++++++++++++++++---------------------
+ 1 file changed, 26 insertions(+), 21 deletions(-)
 
-commit a548d1da78b506cc6460fdde3715f6ef13ccad48
+commit 773ee8041e8905bfb06c1a71d2b4fc99110b3dc6
+Merge: 47b4074d 0efbda7a
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Tue Oct 29 10:58:56 2019 -0700
+
+    Merge pull request #2038 from ebraminio/glyf-contour
+    
+    Remove contour_point_t so we won't need to zero its unused var
+
+commit 0efbda7a40742cbdf30d5a85061ffb6a0a55bcc0
 Author: Ebrahim Byagowi <ebrahim@gnu.org>
-Date:   Thu Mar 28 15:42:45 2019 -0700
+Date:   Tue Oct 29 21:03:26 2019 +0330
 
-    [ci] Use only CircleCI for macOS (#1637)
+    Remove contour_point_t so we won't need to zero its unused var
 
- .circleci/config.yml |  5 +++--
- .travis.yml          | 18 ------------------
- 2 files changed, 3 insertions(+), 20 deletions(-)
+ src/hb-ot-glyf-table.hh | 27 +++++++++++++--------------
+ 1 file changed, 13 insertions(+), 14 deletions(-)
 
-commit 160b4a2b01e925812fbf0e7db5bc9dcb90dc81cc
+commit 47b4074d5f98d71d2983470602eff9b93f102af4
+Merge: dd8a8460 dd288840
 Author: Behdad Esfahbod <behdad@behdad.org>
-Date:   Thu Mar 28 13:44:38 2019 -0700
+Date:   Tue Oct 29 03:16:34 2019 -0700
 
-    Fix shell syntax error
+    Merge pull request #2034 from khaledhosny/cmap-notdef
     
-    Fixes https://github.com/harfbuzz/harfbuzz/issues/1612
+    [cmap] Check GID before adding ranges in format 4 & 12
 
- src/check-symbols.sh | 2 +-
+commit dd8a8460377ca54207877ea9da96931175dbb15f
+Author: jfkthame <jfkthame@gmail.com>
+Date:   Tue Oct 29 09:20:41 2019 +0000
+
+    Use proper y-scale factor for height value
+
+ src/hb-ot-cff1-table.cc | 2 +-
  1 file changed, 1 insertion(+), 1 deletion(-)
 
-commit 8665b9b0a24e4d46e486057d72c0486b9da16523
+commit 7152ac3fcfe8a599aa0d20f8d02ef38c69111231
 Author: Behdad Esfahbod <behdad@behdad.org>
-Date:   Thu Mar 28 11:11:52 2019 -0700
+Date:   Mon Oct 28 17:12:55 2019 -0700
 
-    Comment
+    Fix build
+    
+    $ make CPPFLAGS="-DHB_TINY -DHB_NO_OT_FONT" libharfbuzz-subset.la
 
- src/hb.hh | 1 +
- 1 file changed, 1 insertion(+)
+ src/hb-subset-plan.cc | 5 ++++-
+ 1 file changed, 4 insertions(+), 1 deletion(-)
 
-commit a7eed7e41dba8e583a9c740a4ca7ddf53e77de63
-Author: punchcutter <zarijoscha@gmail.com>
-Date:   Wed Mar 27 23:12:58 2019 -0700
+commit dd288840d6f87acd13b99b71408dcdb35a2be9cb
+Author: Khaled Hosny <khaledhosny@eglug.org>
+Date:   Tue Oct 29 01:45:49 2019 +0200
 
-    Override USE category for Grantha and Tirhuta visargas to allow marks
+    [cmap] Check GID before adding ranges in format 4 & 12
+    
+    Fixes https://github.com/harfbuzz/harfbuzz/issues/2031
 
- src/gen-use-table.py                 | 3 ++-
- src/hb-ot-shape-complex-use-table.cc | 4 ++--
- 2 files changed, 4 insertions(+), 3 deletions(-)
+ src/hb-ot-cmap-table.hh          |  32 ++++++++++++++++++++++++--------
+ test/api/fonts/cmunrm.otf        | Bin 0 -> 330492 bytes
+ test/api/test-collect-unicodes.c |  22 ++++++++++++++++++++++
+ 3 files changed, 46 insertions(+), 8 deletions(-)
 
-commit cf040c0fef4a049a75a5ec7972f518b9034bdc76
-Author: Egor Pugin <egor.pugin@gmail.com>
-Date:   Thu Mar 28 19:06:12 2019 +0300
+commit fd71c045b46380281ba8a7e351fac7248938c74c
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Mon Oct 28 17:06:53 2019 -0700
 
-    Disable unwanted C++ definitions for MSVC.
-    
-    MSVC does not set __cplusplus to the latest standard and also it does not like redefining some keywords.
+    Hopefully fix up previous commit and bots
 
  src/hb.hh | 2 +-
  1 file changed, 1 insertion(+), 1 deletion(-)
 
-commit 717181c5943c13a682c719dce10bfc3d9cc47e6b
-Author: Ebrahim Byagowi <ebrahim@gnu.org>
-Date:   Wed Mar 27 16:38:39 2019 +0430
+commit e832dc4c642f604d2cbb8e6b2f0b8d37151936f1
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Mon Oct 28 17:02:40 2019 -0700
 
-    [ci] remove ragel from psvita compile bot
+    [config] Make HB_NO_ERRNO work with systems defining errno as a macro
 
.circleci/config.yml | 1 -
- 1 file changed, 1 deletion(-)
src/hb.hh | 8 +++++---
+ 1 file changed, 5 insertions(+), 3 deletions(-)
 
-commit 08e36c5d8be22b3a7e31f33af9452372dafeacc0
-Author: Ebrahim Byagowi <ebrahim@gnu.org>
-Date:   Wed Mar 27 16:21:47 2019 +0430
+commit ce11df1b5b8e49712bef249de19bc4768f3a691c
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Mon Oct 28 14:45:31 2019 -0700
 
-    [ci] Don't install ragel on cmake build bot images
-    
-    It is not needed anyway
+    2.6.3
 
- .circleci/config.yml | 5 -----
- 1 file changed, 5 deletions(-)
+ NEWS             | 8 ++++++++
+ configure.ac     | 2 +-
+ src/hb-font.cc   | 2 +-
+ src/hb-version.h | 4 ++--
+ 4 files changed, 12 insertions(+), 4 deletions(-)
 
-commit ec2a5dc859b03ceb92518aa992e4e9c053b30534
-Author: Behdad Esfahbod <behdad@fb.com>
-Date:   Tue Mar 26 16:18:03 2019 -0700
+commit 5a59de2b983ed7a1c639ea3e4d23c341134cd6d5
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Mon Oct 28 14:02:47 2019 -0700
 
-    Use class templates for Null objects
+    Actually add +hb_font_get_nominal_glyphs()
     
-    This allows partial-instantiating custom Null object for template Lookup<T>.
-    Before, this had to be handcoded per instantiation.  Apparently I missed
-    adding one for AAT::ankr.lookupTable, so it was getting the wrong (generic)
-    null for Lookup object, which is wrong and unsafe.
-    
-    Fixes https://bugs.chromium.org/p/chromium/issues/detail?id=944346
+    New API:
+    +hb_font_get_nominal_glyphs()
 
- src/hb-aat-layout-common.hh                        |  14 ++++------
- src/hb-null.hh                                     |  31 +++++++++++++--------
- ...case-minimized-harfbuzz_fuzzer-5748102301614080 | Bin 0 -> 213 bytes
- 3 files changed, 24 insertions(+), 21 deletions(-)
+ src/hb-font.cc | 23 +++++++++++++++++++++++
+ src/hb-font.h  |  8 ++++++++
+ 2 files changed, 31 insertions(+)
 
-commit 96f12377942dbe1c6b1d0ffa7d626d99cb265443
-Author: Behdad Esfahbod <behdad@fb.com>
-Date:   Tue Mar 26 16:17:45 2019 -0700
+commit 03028a5fe512978a8f8e2396001cf8e425b44f72
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Mon Oct 28 13:46:56 2019 -0700
 
-    [aat] Add missing check to ankr table
+    Revert "Don't include codepoint 0 in the results of collect_unicodes."
     
-    Isn't absolutely needed.  But helps.
-
- src/hb-aat-layout-ankr-table.hh | 1 +
- 1 file changed, 1 insertion(+)
+    This reverts commit 14ad96ffbf77c33d8d33d2686d17c2375381989e.
+    
+    This was wrong.  My bad!
+    
+    https://github.com/harfbuzz/harfbuzz/issues/2031
 
-commit e5dfffb1ef610a982ed9878fbf3f9ee49cbc3a97
-Author: Behdad Esfahbod <behdad@fb.com>
-Date:   Mon Mar 25 15:15:37 2019 -0700
+ src/hb-ot-cmap-table.hh | 8 +-------
+ 1 file changed, 1 insertion(+), 7 deletions(-)
 
-    [docs] Update
+commit 2714dc31b8d0ffe3c043935dd7619be0dd7b7635
+Merge: aca63902 14ad96ff
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Mon Oct 28 13:01:34 2019 -0700
 
- docs/harfbuzz-docs.xml | 1 +
- 1 file changed, 1 insertion(+)
+    Merge pull request #2032 from googlefonts/collect_unicodes
+    
+    Don't include codepoint 0 in the results of collect_unicodes.
 
-commit 0dd3fdf9d227f9bd79f395078f8e58dcfc32d1bf
-Author: Behdad Esfahbod <behdad@fb.com>
-Date:   Mon Mar 25 15:08:14 2019 -0700
+commit 14ad96ffbf77c33d8d33d2686d17c2375381989e
+Author: Garret Rieger <grieger@google.com>
+Date:   Mon Oct 28 12:56:04 2019 -0700
 
-    Update ChangeLog generation
-    
-    Let's see if I can make a release on Mac...
+    Don't include codepoint 0 in the results of collect_unicodes.
+    It is always assumed to be the notdef glyph.
 
Makefile.am | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
src/hb-ot-cmap-table.hh | 8 +++++++-
+ 1 file changed, 7 insertions(+), 1 deletion(-)
 
-commit 2d9034491eca0a63db82d3801f05c067a5241b7d
-Author: Qunxin Liu <qxliu@google.com>
-Date:   Tue Mar 26 10:37:24 2019 -0700
+commit aca63902814748b36bf6939421cfa95eed3a1ca7
+Author: Ebrahim Byagowi <ebrahim@gnu.org>
+Date:   Tue Oct 22 00:06:46 2019 +0330
 
-    completely remove lines that are commented out
+    [gpos] Don't move pointer when match_glyph_data is not set
 
- src/hb-subset-plan.cc | 6 ------
- src/hb-subset-plan.hh | 3 ---
- 2 files changed, 9 deletions(-)
+ src/hb-ot-layout-gsubgpos.hh | 16 ++++++++--------
+ 1 file changed, 8 insertions(+), 8 deletions(-)
 
-commit 3147133b6173487c26813a2a406aebd067b53fbf
+commit defe9b6da018bc85750c999454c51fde0cadb9b2
 Author: Qunxin Liu <qxliu@google.com>
-Date:   Tue Mar 26 09:15:56 2019 -0700
+Date:   Fri Oct 25 10:07:26 2019 -0700
 
-    update arguments in_populate_gids_to_retain() and _create_old_gid_to_new_gid_map()
-    so they don't use deprecated variable
+    crash fix : Heap-buffer-overflow READ 2
+    https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=18513
 
- src/hb-subset-plan.cc | 36 ++++++++++++++++++------------------
- 1 file changed, 18 insertions(+), 18 deletions(-)
+ src/hb-ot-layout-gpos-table.hh                            |  12 ++++++------
+ ...z-testcase-minimized-hb-subset-fuzzer-5677906231033856 | Bin 0 -> 938 bytes
+ 2 files changed, 6 insertions(+), 6 deletions(-)
 
-commit 79a6c258497e80be15245a7b576e34443d9f7bff
+commit b2fcca6e14afc8085cc1c2491b2d7c780dad1450
 Author: Qunxin Liu <qxliu@google.com>
-Date:   Mon Mar 25 19:59:37 2019 -0700
+Date:   Thu Oct 24 15:15:26 2019 -0700
 
-    try to remove deprecated variable from struct definition
+     fuzzer crash fix
+     https://oss-fuzz.com/testcase-detail/5643107869917184
 
- src/hb-subset-plan.cc | 9 +++++----
- src/hb-subset-plan.hh | 2 +-
- 2 files changed, 6 insertions(+), 5 deletions(-)
+ src/hb-ot-layout-gsubgpos.hh                             |  11 +++++++----
+ ...-testcase-minimized-hb-subset-fuzzer-5643107869917184 | Bin 0 -> 3232 bytes
+ 2 files changed, 7 insertions(+), 4 deletions(-)
 
-commit bcb4e505d6ffe33e3268a06698e75d6be0e64957
-Author: Michiharu Ariza <ariza@adobe.com>
-Date:   Fri Mar 15 13:46:25 2019 -0700
+commit 9815ca0338b47c6ea4e82f2fbd39d70e3456aca1
+Author: Ebrahim Byagowi <ebrahim@gnu.org>
+Date:   Thu Oct 24 21:05:38 2019 +0330
 
-    cff2 subset fuzzer issues (#1619)
-    
-    * add check to FDArray::serialize
-    
-    * add test files
-    
-    * fix off by one
+    [ci] Use custom subset fuzzer timeout for failing sanitizer bots
 
- src/hb-ot-cff-common.hh                                   |   1 +
- ...z-testcase-minimized-hb-subset-fuzzer-5739000398086144 | Bin 0 -> 620 bytes
- ...z-testcase-minimized-hb-subset-fuzzer-5760768497156096 | Bin 0 -> 210 bytes
- ...z-testcase-minimized-hb-subset-fuzzer-5764268627066880 | Bin 0 -> 687 bytes
- 4 files changed, 1 insertion(+)
+ .circleci/config.yml                    | 8 ++++----
+ test/fuzzing/run-shape-fuzzer-tests.py  | 3 ++-
+ test/fuzzing/run-subset-fuzzer-tests.py | 3 ++-
+ 3 files changed, 8 insertions(+), 6 deletions(-)
 
-commit 8aaab78efcac81a05ec919be13792c98741ea1b5
+commit b03b62cb304279195569180061cde745e0c9880a
 Author: Ebrahim Byagowi <ebrahim@gnu.org>
-Date:   Thu Mar 14 16:49:42 2019 -0700
+Date:   Wed Oct 23 12:18:21 2019 +0330
 
-    Allow zero length ranges in sanitization (#1617)
-    
-    Fixes fvar table sanitization where there are no named instance
-    by allowing zero length ranges starting from Null() address.
-    
-    Fixes #1607
+    [ci] Add HB_NO_MT on non HB_TINY no-build-system builds
 
- src/hb-machinery.hh      |  30 ++++++++++++++++--------------
- test/api/fonts/Zycon.ttf | Bin 0 -> 21036 bytes
- test/api/test-ot-face.c  |   9 +++++++++
- 3 files changed, 25 insertions(+), 14 deletions(-)
+ .circleci/config.yml | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
 
-commit b1dfb8c850f36d4065190a779a6e3342a5fbb593
-Author: Khaled Hosny <khaledhosny@eglug.org>
-Date:   Thu Mar 14 21:41:25 2019 +0200
+commit 5e489670e15329f5eced16e5a76145c6149a265f
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Tue Oct 22 15:03:47 2019 -0700
 
-    [ci] Cache FreeType build on Travis
+    Remove hb-warning.cc
+    
+    Fixes https://github.com/harfbuzz/harfbuzz/issues/2005
 
- .ci/build-freetype.sh | 17 +++++++++++++++++
- .travis.yml           | 18 ++++++++++++------
- 2 files changed, 29 insertions(+), 6 deletions(-)
+ src/Makefile.sources |  1 -
+ src/harfbuzz.cc      |  1 -
+ src/hb-atomic.hh     | 16 +++++-----------
+ src/hb-mutex.hh      | 25 ++++++-------------------
+ src/hb-warning.cc    | 37 -------------------------------------
+ 5 files changed, 11 insertions(+), 69 deletions(-)
 
-commit 7de9f92ee9ced6f4c176459cf25f4ca931ca5ceb
-Author: David Corbett <corbett.dav@husky.neu.edu>
-Date:   Tue Mar 12 19:30:47 2019 -0400
+commit 05bcdb39d8648c49f7984c404aee096f2ad1d655
+Author: Garret Rieger <grieger@google.com>
+Date:   Mon Oct 21 16:10:06 2019 -0700
 
-    Categorize U+09FC as Consonant_Placeholder
+    Add a specialization of array_t:hash for hb_bytes_t and hb_ubytes_t.
 
- src/hb-ot-shape-complex-indic.hh | 1 +
- 1 file changed, 1 insertion(+)
+ src/hb-array.hh              | 34 ++++++++++++++++++++++++----------
+ src/hb-ot-layout-gsubgpos.hh |  2 --
+ 2 files changed, 24 insertions(+), 12 deletions(-)
 
-commit 8b1eaecd9485fe504af364db1537bb04852b265c
-Author: Khaled Hosny <khaledhosny@eglug.org>
-Date:   Wed Mar 13 13:21:12 2019 +0200
+commit 95ab110cd9a6083a854e538211618b2733aba643
+Author: Garret Rieger <grieger@google.com>
+Date:   Mon Oct 21 13:15:46 2019 -0700
 
-    [ci] Simplify and fix Travis CI macOS build
+    Optimize intersects_array to fix fuzzer timeout.
 
- .travis.yml | 16 +++++++++-------
- 1 file changed, 9 insertions(+), 7 deletions(-)
+ src/hb-ot-layout-gsubgpos.hh                           |  10 +++++-----
+ ...estcase-minimized-hb-subset-fuzzer-5763024094232576 | Bin 0 -> 125681 bytes
+ 2 files changed, 5 insertions(+), 5 deletions(-)
 
-commit e52ec3fc23c2d5a881849f047885e0423bd74740
-Author: Behdad Esfahbod <behdad@fb.com>
-Date:   Mon Mar 11 18:09:51 2019 -0700
+commit be5cdcdfa21a2d956fc8c445452a78e77ede95fb
+Author: Garret Rieger <grieger@google.com>
+Date:   Tue Oct 22 11:55:04 2019 -0700
 
-    Remove redundant hb_ot_layout_lookup_would_substitute_fast
+    Store the hash value of a key in item_t in hb_map to reduce the number of hash computations.
 
- src/hb-ot-layout.cc              | 13 -------------
- src/hb-ot-layout.hh              |  7 -------
- src/hb-ot-shape-complex-indic.cc |  2 +-
- src/hb-ot-shape-complex-khmer.cc |  2 +-
- 4 files changed, 2 insertions(+), 22 deletions(-)
+ src/hb-map.hh | 70 ++++++++++++++++++++++++++++++++++-------------------------
+ 1 file changed, 40 insertions(+), 30 deletions(-)
 
-commit c2442c90d6ecfaee987ed8ac6f93a9ac6b07c642
-Author: Khaled Hosny <khaledhosny@eglug.org>
-Date:   Tue Mar 12 01:09:27 2019 +0200
+commit b33a0d628e5e76992fdd02fd4178906137e6153c
+Author: Qunxin Liu <qxliu@google.com>
+Date:   Mon Oct 21 13:24:52 2019 -0700
 
-    [doc] Add placeholder since version for new flag
+    fuzzer crash fix: Null-dereference WRITE
+    https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=18363
 
- src/hb-buffer.h | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
+ src/hb-ot-layout-common.hh                                |   4 +++-
+ ...z-testcase-minimized-hb-subset-fuzzer-5659903036751872 | Bin 0 -> 781 bytes
+ 2 files changed, 3 insertions(+), 1 deletion(-)
 
-commit 8c42f03215097d7c1bae74db7e98315263d3e8a4
-Author: David Corbett <corbett.dav@husky.neu.edu>
-Date:   Fri Mar 8 09:46:48 2019 -0500
+commit cf414e361a99decd9c1710f1012236bffd067878
+Author: Garret Rieger <grieger@google.com>
+Date:   Fri Sep 27 09:55:17 2019 -0700
 
-    Remove obsolete overrides from Indic/USE scripts
+    Added profiling instructions to TESTING.md
 
- src/gen-indic-table.py               |  4 ----
- src/gen-use-table.py                 | 30 +++++++-----------------------
- src/hb-ot-shape-complex-use-table.cc |  2 +-
- 3 files changed, 8 insertions(+), 28 deletions(-)
+ TESTING.md | 11 +++++++++++
+ 1 file changed, 11 insertions(+)
 
-commit b38bab86229bc40d9cdf4819d6dc6aab444d0291
-Author: Eric Muller <emuller@amazon.com>
-Date:   Tue Feb 12 11:41:16 2019 -0800
+commit 1f0a9d9be979de01527c05f4dbe6fbc62799597c
+Author: Qunxin Liu <qxliu@google.com>
+Date:   Tue Sep 17 11:10:08 2019 -0700
+
+    [subset] GPOS Lookup Type 2: PairPos
+
+ src/hb-ot-layout-gpos-table.hh                     | 131 ++++++++++++++++++++-
+ test/subset/data/Makefile.am                       |   1 +
+ test/subset/data/Makefile.sources                  |   1 +
+ ...s2_1_font7.keep-layout-retain-gids.21,23,25.otf | Bin 0 -> 1764 bytes
+ ...gpos2_1_font7.keep-layout-retain-gids.21,23.otf | Bin 0 -> 1632 bytes
+ ...eep-layout-retain-gids.retain-all-codepoint.otf | Bin 0 -> 3688 bytes
+ .../gpos2_1_font7.keep-layout.21,23,25.otf         | Bin 0 -> 1428 bytes
+ .../gpos2_1_font7.keep-layout.21,23.otf            | Bin 0 -> 1308 bytes
+ ...s2_1_font7.keep-layout.retain-all-codepoint.otf | Bin 0 -> 3688 bytes
+ ...s2_2_font5.keep-layout-retain-gids.21,23,25.otf | Bin 0 -> 1776 bytes
+ ...gpos2_2_font5.keep-layout-retain-gids.21,23.otf | Bin 0 -> 1644 bytes
+ ...eep-layout-retain-gids.retain-all-codepoint.otf | Bin 0 -> 3684 bytes
+ .../gpos2_2_font5.keep-layout.21,23,25.otf         | Bin 0 -> 1440 bytes
+ .../gpos2_2_font5.keep-layout.21,23.otf            | Bin 0 -> 1320 bytes
+ ...s2_2_font5.keep-layout.retain-all-codepoint.otf | Bin 0 -> 3684 bytes
+ test/subset/data/fonts/gpos2_1_font7.otf           | Bin 0 -> 4584 bytes
+ test/subset/data/fonts/gpos2_2_font5.otf           | Bin 0 -> 4580 bytes
+ test/subset/data/tests/layout.gpos2.tests          |  12 ++
+ 18 files changed, 139 insertions(+), 6 deletions(-)
+
+commit e766783152b91fb20baf0c657586628fd7959b1b
+Author: Ebrahim Byagowi <ebrahim@gnu.org>
+Date:   Mon Oct 21 22:17:06 2019 +0330
 
-    Update generation code for hb-ot-shape-complex-vowel-constraints.cc. Remove 'unlikely'
+    [fuzz] Add https://crbug.com/oss-fuzz/17898 testcase
 
- src/gen-vowel-constraints.py                 | 3 +++
- src/hb-ot-shape-complex-vowel-constraints.cc | 2 +-
- 2 files changed, 4 insertions(+), 1 deletion(-)
+ ...sterfuzz-testcase-hb-subset-fuzzer-5717414645334016 | Bin 0 -> 310324 bytes
+ 1 file changed, 0 insertions(+), 0 deletions(-)
 
-commit 44a67ddeb878f7639b30d1884e38b1525aab4f4a
-Author: Eric Muller <emuller@amazon.com>
-Date:   Sun Feb 10 04:31:41 2019 -0800
+commit b66094ada0ae7e69d5d08ee8423554629eabccaf
+Author: Qunxin Liu <qxliu@google.com>
+Date:   Mon Sep 30 16:19:18 2019 -0700
+
+    [subset] GSUB Lookup Type 6: ChainContextSubst
+
+ src/hb-ot-layout-common.hh                         | 260 ++++++++++++++-------
+ src/hb-ot-layout-gsubgpos.hh                       | 218 ++++++++++++++++-
+ test/subset/data/Makefile.am                       |   1 +
+ test/subset/data/Makefile.sources                  |   1 +
+ ...ules_f1.keep-layout-retain-gids.30,31,32,33.otf | Bin 0 -> 2380 bytes
+ ...eep-layout-retain-gids.retain-all-codepoint.otf | Bin 0 -> 3748 bytes
+ ...ultiple_subrules_f1.keep-layout.30,31,32,33.otf | Bin 0 -> 1916 bytes
+ ...ubrules_f1.keep-layout.retain-all-codepoint.otf | Bin 0 -> 3748 bytes
+ ...ules_f1.keep-layout-retain-gids.30,31,32,33.otf | Bin 0 -> 2408 bytes
+ ...eep-layout-retain-gids.retain-all-codepoint.otf | Bin 0 -> 3780 bytes
+ ...ultiple_subrules_f1.keep-layout.30,31,32,33.otf | Bin 0 -> 1944 bytes
+ ...ubrules_f1.keep-layout.retain-all-codepoint.otf | Bin 0 -> 3780 bytes
+ ...mple_f2.keep-layout-retain-gids.30,31,32,33.otf | Bin 0 -> 2368 bytes
+ ...eep-layout-retain-gids.retain-all-codepoint.otf | Bin 0 -> 3716 bytes
+ ...chaining3_simple_f2.keep-layout.30,31,32,33.otf | Bin 0 -> 1904 bytes
+ ..._simple_f2.keep-layout.retain-all-codepoint.otf | Bin 0 -> 3716 bytes
+ .../fonts/gsub_chaining1_multiple_subrules_f1.otf  | Bin 0 -> 4700 bytes
+ .../fonts/gsub_chaining2_multiple_subrules_f1.otf  | Bin 0 -> 4780 bytes
+ .../subset/data/fonts/gsub_chaining3_simple_f2.otf | Bin 0 -> 4668 bytes
+ test/subset/data/tests/layout.gsub6.tests          |  12 +
+ 20 files changed, 405 insertions(+), 87 deletions(-)
+
+commit eff91bbb4b1e6f4cc8401b1915d5ddad64e053bb
+Author: Garret Rieger <grieger@google.com>
+Date:   Wed Oct 16 16:58:57 2019 -0700
 
-    Fix coding style.
+    Add missing pop() for the failure case of script subsetting.
 
- src/hb-ot-shape-complex-hangul.cc | 4 ++--
- 1 file changed, 2 insertions(+), 2 deletions(-)
+ src/hb-ot-layout-common.hh | 6 ++++--
+ 1 file changed, 4 insertions(+), 2 deletions(-)
 
-commit 30d7c40f8ce9f47d733b1f43a93f20739772859e
-Author: Eric Muller <emuller@amazon.com>
-Date:   Sat Feb 9 02:55:27 2019 -0800
+commit eab191fd9c851cb7881163ddd5e11a2ebc58cef4
+Author: Garret Rieger <grieger@google.com>
+Date:   Wed Oct 2 14:28:53 2019 -0700
 
-    Add a flag to hb_buffer_t to prevent the insertion of dotted circles on incorrect character sequences.
+    Rewrite hash and == function for hb_array_t as a plain loop.
     
-    Current behavior unchanged if this flag is not set (and it isn't by default).
+    Profling showed that the current implementation were accounting for nearly all processing time in some cases. These implementations look to be about 10x faster.
 
- src/hb-buffer.h                              | 7 ++++++-
- src/hb-ot-shape-complex-hangul.cc            | 3 ++-
- src/hb-ot-shape-complex-indic.cc             | 3 +++
- src/hb-ot-shape-complex-khmer.cc             | 3 +++
- src/hb-ot-shape-complex-myanmar.cc           | 3 +++
- src/hb-ot-shape-complex-use.cc               | 3 +++
- src/hb-ot-shape-complex-vowel-constraints.cc | 3 +++
- src/hb-ot-shape.cc                           | 3 +++
- 8 files changed, 26 insertions(+), 2 deletions(-)
+ src/hb-array.hh | 21 +++++++++++----------
+ 1 file changed, 11 insertions(+), 10 deletions(-)
 
-commit 8b6eb6cf465032d0ca747f4b75f6e9155082bc45
-Author: Ebrahim Byagowi <ebrahim@gnu.org>
-Date:   Fri Mar 8 01:33:41 2019 +0330
+commit 831daf4c76aed87d229b1edfb59a0a37caa8e581
+Author: Garret Rieger <grieger@google.com>
+Date:   Tue Oct 1 17:46:27 2019 -0700
 
-    Add a macOS 10.14.3 fonts tests (#1608)
+    Enforce HB_MAX_LANGSYS limit during layout subsetting.
 
- .circleci/config.yml                         | 11 +++++++++++
- test/shaping/data/in-house/tests/macos.tests | 19 +++++++++++++++++++
- 2 files changed, 30 insertions(+)
+ src/hb-ot-layout-common.hh                         |  68 +++++++++++++--------
+ ...ase-minimized-hb-subset-fuzzer-5721073428987904 | Bin 0 -> 349561 bytes
+ 2 files changed, 41 insertions(+), 27 deletions(-)
 
-commit e723c04de1b3dcd96e6a70baf09e3ae2ddbbc0bf
-Author: David Corbett <corbett.dav@husky.neu.edu>
-Date:   Wed Mar 6 12:37:25 2019 -0500
+commit 9871461bce9a1557807f69615300e5df4f6ae322
+Author: Garret Rieger <grieger@google.com>
+Date:   Tue Oct 1 16:29:24 2019 -0700
 
-    Update to Unicode 12.0.0
+    Enforce HB_MAX_SCRIPTS during subsetting of the script table.
 
- src/gen-use-table.py                         |    1 -
- src/gen-vowel-constraints.py                 |    1 +
- src/hb-common.h                              |    8 +
- src/hb-ot-shape-complex-arabic-table.hh      |   14 +-
- src/hb-ot-shape-complex-indic-table.cc       |   56 +-
- src/hb-ot-shape-complex-use-table.cc         |   49 +-
- src/hb-ot-shape-complex-vowel-constraints.cc |    4 +-
- src/hb-ot-shape-complex.hh                   |    3 +
- src/hb-ot-tag-table.hh                       |   12 +-
- src/hb-ucdn.cc                               |    4 +
- src/hb-ucdn/ucdn.h                           |   11 +
- src/hb-ucdn/ucdn_db.h                        | 2998 +++++++++++++-------------
- src/hb-unicode-emoji-table.hh                |    6 +-
- 13 files changed, 1631 insertions(+), 1536 deletions(-)
+ src/hb-ot-layout-common.hh | 46 +++++++++++++++++++++++++++++++++++++++++-----
+ 1 file changed, 41 insertions(+), 5 deletions(-)
 
-commit 2f125b0fa763c3be7d8d74489c027f7155607756
-Author: Adrian Wong <adrianwjw@gmail.com>
-Date:   Wed Feb 13 21:04:46 2019 +1100
+commit 029775bcbd0a25ee1cdb6c0653a2ce189774490a
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Wed Oct 9 11:00:09 2019 +0700
 
-    [indic] Remove superfluous ZWNJ check in final reorder of pre-base matras
+    [buffer] Minor; improve HB_NO_BUFFER_MESSAGE
 
- src/hb-ot-shape-complex-indic.cc | 11 ++++++++---
- 1 file changed, 8 insertions(+), 3 deletions(-)
+ src/hb-buffer.cc | 2 ++
+ src/hb-buffer.hh | 2 +-
+ 2 files changed, 3 insertions(+), 1 deletion(-)
 
-commit d936ad4582a0017cf88406372d7c08b9896beed6
-Author: Stephan Bergmann <sbergman@redhat.com>
-Date:   Tue Mar 5 17:18:57 2019 +0100
+commit 9a68e6b901967da14a5da5acb535c944794627b8
+Author: Ebrahim Byagowi <ebrahim@gnu.org>
+Date:   Wed Oct 16 13:28:15 2019 +0330
 
-    Fix hb_atomic_* variants based on C++11 atomics
-    
-    I stumbled over this when trying to upgrade the version of HarfBuzz used by
-    LibreOffice to 3.2.1 (see <https://gerrit.libreoffice.org/plugins/gitiles/core/
-    +/b7ddc514bff9bdf682abae537f990aa01dc2c0fb%5E!/> "Upgrade to latest
-    HarfBuzz 2.3.1"), where building with MSVC 2017 failed like
-    
-    > c:\cygwin\home\tdf\lode\jenkins\workspace\gerrit_windows\workdir\unpackedtarball\harfbuzz\src\hb-atomic.hh(272): error C2440: 'reinterpret_cast': cannot convert from 'const int *' to 'std::atomic<int> *'
-    > c:\cygwin\home\tdf\lode\jenkins\workspace\gerrit_windows\workdir\unpackedtarball\harfbuzz\src\hb-atomic.hh(272): note: Conversion loses qualifiers
-    > c:\cygwin\home\tdf\lode\jenkins\workspace\gerrit_windows\workdir\unpackedtarball\harfbuzz\src\hb-atomic.hh(272): error C2227: left of '->load' must point to class/struct/union/generic type
-    
-    (see <https://ci.libreoffice.org/job/gerrit_windows/29916/>).
+    [doc] minor
     
-    I added all the necessary "const" to make building of HarfBuzz 2.3.1 with
-    MSVC 2017 succeed for me.  There may be more missing at least conceptually.
+    Addresses https://github.com/harfbuzz/harfbuzz/pull/2013/files#r335196908
 
- src/hb-atomic.hh | 6 +++---
- 1 file changed, 3 insertions(+), 3 deletions(-)
+ src/hb-common.h | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
 
-commit 731b13e4e9190a45e51f855f19e88869a7718d43
-Author: Martin Hosken <martin_hosken@sil.org>
-Date:   Mon Mar 4 11:12:21 2019 +0700
+commit b0b8551afc2ff86d027fdb380210601cb465af41
+Author: Ebrahim Byagowi <ebrahim@gnu.org>
+Date:   Sat Oct 12 21:12:19 2019 +0330
 
-    Fix offset drift in graphite integration
+    [glyf] Use range_checker_t in composite_iter_t
 
- src/hb-graphite2.cc | 35 +++++++++++++++++++----------------
- 1 file changed, 19 insertions(+), 16 deletions(-)
+ src/hb-ot-glyf-table.hh     | 12 +++++++-----
+ src/hb-ot-var-gvar-table.hh | 19 +++++++++----------
+ 2 files changed, 16 insertions(+), 15 deletions(-)
 
-commit 8a25868e6a41a3d82782aadb3c7b744ad87d20ff
+commit 06e35ce052388e7ce079c0250db62428ae0c5bc8
 Author: Ebrahim Byagowi <ebrahim@gnu.org>
-Date:   Sat Mar 2 03:24:49 2019 +0330
+Date:   Sat Oct 12 15:16:31 2019 +0330
 
-    Minor, remove .editorconfig hack
-    
-    As vscode is going to support it soon
+    [glyf] minor
 
.editorconfig | 7 ++-----
- 1 file changed, 2 insertions(+), 5 deletions(-)
src/hb-ot-glyf-table.hh | 128 +++++++++++++++++++++++++-----------------------
+ 1 file changed, 67 insertions(+), 61 deletions(-)
 
-commit 4f37ab63de9705d7bf74ee75364747e41b7c06a1
-Author: Garret Rieger <grieger@google.com>
-Date:   Thu Feb 28 17:25:05 2019 -0800
+commit d13bb4bd94a6ba8cdd4a03d40d8089a8f8b3a7ec
+Author: Ebrahim Byagowi <ebrahim@gnu.org>
+Date:   Sat Oct 12 12:13:57 2019 +0330
 
-    Make hb_subset_input_glyph_set () actually do something.
+    [glyf] other cleanups
 
- src/hb-subset-plan.cc       |  3 +++
- test/api/hb-subset-test.h   | 11 ++++++++++-
- test/api/test-subset-glyf.c | 24 ++++++++++++++++++++++++
- 3 files changed, 37 insertions(+), 1 deletion(-)
+ src/hb-ot-glyf-table.hh | 338 +++++++++++++++++++++++-------------------------
+ 1 file changed, 160 insertions(+), 178 deletions(-)
 
-commit 45149eb34f9735b5d690a2a7956adb42b938c8d9
+commit e7aa8c5d22b034f3d7bcf187a63cdec27732fa8a
 Author: Ebrahim Byagowi <ebrahim@gnu.org>
-Date:   Fri Feb 22 13:13:42 2019 +0330
+Date:   Sat Oct 12 11:25:32 2019 +0330
 
-    [dwrite] hb_directwrite_face_create, a new API
-    
-    It makes a hb_face_t from IDWriteFontFace, useful when using
-    DirectWrite facilities for font selection, loading and rendering
-    but using harfbuzz for shaping.
+    [glyf] Introduce glyf::Glyph, a hb_bytes_t/GlyphHeader pair
 
- src/hb-directwrite.cc | 70 +++++++++++++++++++++++++++++++++++++++++++++++----
- src/hb-directwrite.h  |  5 +++-
- 2 files changed, 69 insertions(+), 6 deletions(-)
+ src/hb-ot-glyf-table.hh | 177 +++++++++++++++++++++++++-----------------------
+ 1 file changed, 91 insertions(+), 86 deletions(-)
 
-commit 45adc185260f0fa1fa86472aafb7f91f942c567e
-Author: David Corbett <corbett.dav@husky.neu.edu>
-Date:   Mon Feb 18 22:30:40 2019 -0500
+commit 546ffc9faf869b4971765e9a4fd232cfe0eecaea
+Author: Ebrahim Byagowi <ebrahim@gnu.org>
+Date:   Sat Oct 12 09:51:57 2019 +0330
 
-    Fix or document unsupported font-feature-settings
+    [glyf] minor
 
- src/hb-common.cc | 18 ++++++++++++------
- util/options.cc  |  3 ++-
- 2 files changed, 14 insertions(+), 7 deletions(-)
+ src/hb-ot-glyf-table.hh | 5 +++--
+ 1 file changed, 3 insertions(+), 2 deletions(-)
 
-commit d66f7e14a0097d8ca54ad9824f7aa7daee6c7f72
-Author: Joël R. Langlois <joel.r.langlois@gmail.com>
-Date:   Mon Feb 25 15:26:58 2019 -0500
+commit 4299ea266e03b64db4e8a132983fed9fd0a967ee
+Author: Ebrahim Byagowi <ebrahim@gnu.org>
+Date:   Sat Oct 12 09:51:27 2019 +0330
 
-    Remove Forcing Diagnostic Colours from CMakeLists.txt (#1597)
-    
-    Fixes https://github.com/harfbuzz/harfbuzz/issues/1596
+    [glyf] Move get_contour_points to GlyphHeader
 
CMakeLists.txt | 12 ------------
- 1 file changed, 12 deletions(-)
src/hb-ot-glyf-table.hh | 260 ++++++++++++++++++++++++++----------------------
+ 1 file changed, 141 insertions(+), 119 deletions(-)
 
-commit 93739242e1aab9b745d0ba3c22c33b4acaf9526c
-Author: Michiharu Ariza <ariza@adobe.com>
-Date:   Wed Feb 20 13:23:12 2019 -0800
+commit b918cd8c76a6333e43b9be23178afc9e74e17024
+Author: Ben Wagner <bungeman@chromium.org>
+Date:   Thu Oct 10 15:30:48 2019 -0400
 
-    minor edit
+    Document hb_feature_t.
+    
+    This documents hb_feature_t. This is motivated mostly by the ambiguity
+    of the units for 'start' and 'end' (clusters) and whether they are
+    inclusive or exclusive. This also documents that for lookup type 3 the
+    value is the one based index into the alternates and that in a list of
+    features later feature values override previous feature values with the
+    same tag.
 
- src/hb-map.hh | 3 +--
- 1 file changed, 1 insertion(+), 2 deletions(-)
+ src/hb-common.h | 15 +++++++++++++++
+ src/hb-shape.cc |  4 +++-
+ 2 files changed, 18 insertions(+), 1 deletion(-)
 
-commit eebc21c8de08d58c806fcd3d0f3a5aedee867776
-Author: Michiharu Ariza <ariza@adobe.com>
-Date:   Wed Feb 20 12:43:18 2019 -0800
+commit e637a4b3de2fb8bdbc1b82e822f4a6cc579e794b
+Merge: 670fec23 e4464f44
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Fri Oct 11 10:28:58 2019 +0700
 
-    fix crash in hb_map_t::clear()
+    Merge pull request #2012 from harfbuzz/lepcha-oo
     
-    in case called immediately after init()
+    Reorder U+1C29 LEPCHA VOWEL SIGN OO
 
- src/hb-map.hh | 3 ++-
- 1 file changed, 2 insertions(+), 1 deletion(-)
+commit 670fec231d31bf7417de590efd3485f337a7330f
+Author: Ebrahim Byagowi <ebrahim@gnu.org>
+Date:   Thu Oct 10 09:21:08 2019 +0330
 
-commit a17ed8459ee1e01caf4761f682bcda821bc8e656
-Author: Khaled Hosny <khaledhosny@eglug.org>
-Date:   Tue Feb 19 21:14:11 2019 +0200
+    Minor, add a zero length tolerant memset, hb_memset
 
-    [doc] Move hb_variation_t to hb-common section
+ src/hb-algs.hh   | 10 +++++++++-
+ src/hb-buffer.cc |  3 +--
+ 2 files changed, 10 insertions(+), 3 deletions(-)
 
- docs/harfbuzz-sections.txt | 6 +++---
- 1 file changed, 3 insertions(+), 3 deletions(-)
+commit e4464f4484009b4efe7144570384d836cb6bbac8
+Author: David Corbett <corbett.dav@husky.neu.edu>
+Date:   Wed Oct 9 20:55:52 2019 -0400
 
-commit 9caabc9cf898e1d66921f88890d5b7d46494dc90
-Author: Khaled Hosny <khaledhosny@eglug.org>
-Date:   Tue Feb 19 19:27:28 2019 +0200
+    Reorder U+1C29 LEPCHA VOWEL SIGN OO
 
-    [doc] Move feature_t and its function to hb-common
-    
-    It is rather confusing to have script, language etc, in hb-common section
-    while feature is in hb-shape section. I keep looking for it in hb-common
-    section then using the API index because I can’t find it there.
+ src/gen-use-table.py                 | 3 +++
+ src/hb-ot-shape-complex-use-table.cc | 2 +-
+ 2 files changed, 4 insertions(+), 1 deletion(-)
 
- docs/harfbuzz-sections.txt | 10 +++++-----
- 1 file changed, 5 insertions(+), 5 deletions(-)
+commit e17e7443007fc0debc4a26e5cf37d5d76c747fbf
+Author: Garret Rieger <grieger@google.com>
+Date:   Wed Oct 9 11:45:42 2019 -0700
 
-commit d29c8424c8bfa47c910d0e270f05b5c0a1f803a2
-Author: Evgeniy Reizner <razrfalcon@gmail.com>
-Date:   Tue Feb 19 18:35:00 2019 +0200
+    Convert existing uses of serialize_append in gsub subsetting to use subset_offset_array.
 
-    Typo (#1588)
-    
-    Fixed a small typo.
-    [skip ci]
+ src/hb-ot-layout-gsub-table.hh | 44 +++---------------------------------------
+ 1 file changed, 3 insertions(+), 41 deletions(-)
 
- src/hb-ot-font.cc | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
+commit 36f18cecbbaf8635a2179a827242ca99d5283666
+Author: Garret Rieger <grieger@google.com>
+Date:   Mon Oct 7 14:02:31 2019 -0700
 
-commit 6bd4c082e49143d0631881645b81f999347257f8
-Author: Khaled Hosny <khaledhosny@eglug.org>
-Date:   Tue Feb 19 02:23:58 2019 +0200
+    Add subset_offset_array helper function which simplifies subsetting offset arrays during stream operations.
 
-    [doc] Document hb_feature_from_string() syntax
-    
-    Copied and edited from the util option documentation. The docbook table
-    syntax is too verbose, but that is the best I can come up with.
+ src/hb-ot-layout-common.hh     | 54 ++++++++++++++++++++++++++++++++++++++++++
+ src/hb-ot-layout-gsub-table.hh | 15 +-----------
+ 2 files changed, 55 insertions(+), 14 deletions(-)
 
- src/hb-common.cc | 35 ++++++++++++++++++++++++++++++++++-
- 1 file changed, 34 insertions(+), 1 deletion(-)
+commit dc45f225212da7b8eca0ddcb3c9cd66e65983605
+Author: Ebrahim Byagowi <ebrahim@gnu.org>
+Date:   Tue Oct 8 23:27:37 2019 +0330
 
-commit 3da79dd5b92b89fbf062cbe591e6b1ba83083aec
-Merge: 50005501 d8a68728
-Author: Behdad Esfahbod <behdad@behdad.org>
-Date:   Fri Feb 15 15:54:51 2019 -0800
+    [ot-metrics] Don't use mixed scaled and not scaled for generating extents
 
-    Merge pull request #1557 from harfbuzz/cff-more-arrayof-fixes
-    
-    CFF more arrayof fixes
+ src/hb-ot-cff1-table.cc        | 4 ++--
+ src/hb-ot-cff2-table.cc        | 4 ++--
+ src/hb-ot-color-sbix-table.hh  | 7 +++++++
+ src/hb-ot-glyf-table.hh        | 6 +++---
+ test/api/test-ot-extents-cff.c | 6 +++---
+ 5 files changed, 17 insertions(+), 10 deletions(-)
 
-commit 5000550183022db8c9cfef63a9ed90eb9f37764d
-Merge: 5c2bb1de 90c8bbf9
-Author: Behdad Esfahbod <behdad@behdad.org>
-Date:   Fri Feb 15 15:54:13 2019 -0800
+commit b068e25f8f89d9b07963dddd5d5e14f61539556f
+Author: Ebrahim Byagowi <ebrahim@gnu.org>
+Date:   Tue Oct 8 16:29:15 2019 +0330
 
-    Merge pull request #1583 from harfbuzz/cff-retain-gids
+    [glyf] Address Behdad's reviews
     
-    [subset] Implement --retain-gids with CFF/CFF2
+    Addresses https://github.com/harfbuzz/harfbuzz/pull/1999#issuecomment-539298559
+    * Don't check against Null pool
+    * Remove cryptic _tt suffix
 
-commit d8a68728a077a8c5fc8ceae19f2866cdc8b70baf
-Merge: 1cb1d5d7 5c2bb1de
-Author: Michiharu Ariza <ariza@adobe.com>
-Date:   Fri Feb 15 14:48:10 2019 -0800
+ src/hb-ot-font.cc       |  4 ++--
+ src/hb-ot-hmtx-table.hh | 16 ++++++++--------
+ 2 files changed, 10 insertions(+), 10 deletions(-)
 
-    Merge branch 'master' into cff-more-arrayof-fixes
+commit 6961766db2c53ea813079c61e4d996234ae8be4f
+Author: Ebrahim Byagowi <ebrahim@gnu.org>
+Date:   Tue Oct 8 16:26:48 2019 +0330
 
-commit 90c8bbf98747eb29687471da892b4a34a9236242
-Merge: 6f1dfd08 5c2bb1de
-Author: Michiharu Ariza <ariza@adobe.com>
-Date:   Fri Feb 15 14:47:38 2019 -0800
+    [glyf] fix scaling direction
 
-    Merge branch 'master' into cff-retain-gids
+ src/hb-ot-glyf-table.hh | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
 
-commit 5c2bb1de8de31fecf0dae2ef905b896e42d39f1d
-Author: Martin <44297768+TheRealMDoerr@users.noreply.github.com>
-Date:   Fri Feb 15 19:23:46 2019 +0100
+commit 0527fda4c75e4354198df79275526d4726a3aacc
+Author: Ebrahim Byagowi <ebrahim@gnu.org>
+Date:   Tue Oct 8 16:19:39 2019 +0330
 
-    Support xlclang++ on AIX. (#1584)
+    minor
 
- src/hb-atomic.hh | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
+ src/hb-subset-cff-common.cc | 3 +--
+ 1 file changed, 1 insertion(+), 2 deletions(-)
 
-commit 28f77361322886360743fdbffd388c9482cf4257
-Author: Behdad Esfahbod <behdad@fb.com>
-Date:   Thu Feb 14 11:34:28 2019 -0800
+commit b2628f1a3e3a6875dcdf7cb89f5b10a4ae76e6f9
+Author: Ebrahim Byagowi <ebrahim@gnu.org>
+Date:   Tue Oct 8 15:09:09 2019 +0330
 
-    [CI] Install more packages
+    [glyf] Move glyph bytes drop hints logic to GlyphHeader
+
+ src/hb-ot-glyf-table.hh | 92 ++++++++++++++++++++-----------------------------
+ 1 file changed, 37 insertions(+), 55 deletions(-)
+
+commit 1fb9c3b6463fdee9eb4dac697beab4d3d7a5fdcf
+Author: Ebrahim Byagowi <ebrahim@gnu.org>
+Date:   Tue Oct 8 13:50:16 2019 +0330
+
+    [glyf] Implement depth limit for add_gid_and_children
+
+ src/hb-ot-glyf-table.hh | 8 +++++---
+ 1 file changed, 5 insertions(+), 3 deletions(-)
+
+commit be0eddd41896824cb093024c2b4929b612ee1fae
+Author: Ebrahim Byagowi <ebrahim@gnu.org>
+Date:   Tue Oct 8 13:46:55 2019 +0330
+
+    [glyf] Move add_gid_and_children to glyf table
+
+ src/hb-ot-glyf-table.hh | 14 ++++++++++++++
+ src/hb-subset-plan.cc   | 19 +------------------
+ 2 files changed, 15 insertions(+), 18 deletions(-)
+
+commit c7621cf21115aa563ee4fb9d2fcb601984848494
+Author: Ebrahim Byagowi <ebrahim@gnu.org>
+Date:   Tue Oct 8 13:24:26 2019 +0330
+
+    Minor, replace hb_set_add with private API
+
+ src/hb-ot-map.cc            |  2 +-
+ src/hb-subset-cff-common.hh |  2 +-
+ src/hb-subset-cff1.cc       |  2 +-
+ src/hb-subset-cff2.cc       |  2 +-
+ src/hb-subset-plan.cc       | 10 +++++-----
+ 5 files changed, 9 insertions(+), 9 deletions(-)
+
+commit ad86806dcb702b25fac6a3364cf0f85e1b8f4b2a
+Author: Ebrahim Byagowi <ebrahim@gnu.org>
+Date:   Tue Oct 8 12:14:14 2019 +0330
+
+    [glyf] Move subset related methods inside GlyphHeader
+
+ src/hb-ot-glyf-table.hh | 428 ++++++++++++++++++++++++------------------------
+ src/hb-subset-plan.cc   |   4 +-
+ 2 files changed, 214 insertions(+), 218 deletions(-)
+
+commit 7839e23558344f206175b5a798149e0f04f38266
+Author: Ebrahim Byagowi <ebrahim@gnu.org>
+Date:   Mon Oct 7 11:14:26 2019 +0330
+
+    [glyf] minor
+
+ src/hb-ot-glyf-table.hh | 38 +++++++++++++++-----------------------
+ 1 file changed, 15 insertions(+), 23 deletions(-)
+
+commit cbefbb2439c1a2f4c20877e611f8986b3933234e
+Author: Ebrahim Byagowi <ebrahim@gnu.org>
+Date:   Mon Oct 7 10:15:18 2019 +0330
+
+    [glyf] Move padding removal logic to GlyphHeader
+
+ src/hb-ot-glyf-table.hh | 219 +++++++++++++++++++++++-------------------------
+ 1 file changed, 105 insertions(+), 114 deletions(-)
+
+commit 1ab8f9aa7a182fa078f6c6a5a78ef95686b1ac54
+Author: Ebrahim Byagowi <ebrahim@gnu.org>
+Date:   Mon Oct 7 08:24:12 2019 +0330
+
+    [glyf] minor
+
+ src/hb-ot-glyf-table.hh | 15 +++++++++------
+ 1 file changed, 9 insertions(+), 6 deletions(-)
+
+commit 13fb5612ad545b419ca217f031864dde1b71c43f
+Author: Ebrahim Byagowi <ebrahim@gnu.org>
+Date:   Sun Oct 6 23:24:06 2019 +0330
+
+    [glyf] Aggregate get_offsets uses
+
+ src/hb-ot-glyf-table.hh | 29 +++++++----------------------
+ 1 file changed, 7 insertions(+), 22 deletions(-)
+
+commit 5179b96958f2db71c315c1d8c224bab87e2f4ae8
+Author: Ebrahim Byagowi <ebrahim@gnu.org>
+Date:   Tue Oct 8 11:09:12 2019 +0330
+
+    [cff] minor on number_t
+
+ src/hb-cff-interp-common.hh | 11 ++++-------
+ 1 file changed, 4 insertions(+), 7 deletions(-)
+
+commit d73cdcf3612ae6114a0f828e0f667d447ed1a964
+Author: Ebrahim Byagowi <ebrahim@gnu.org>
+Date:   Sun Oct 6 18:09:14 2019 +0330
+
+    [ot-font] Apply font scaling before turning to int
+
+ src/hb-ot-cff1-table.cc        | 12 ++++-----
+ src/hb-ot-cff1-table.hh        |  2 +-
+ src/hb-ot-cff2-table.cc        |  8 +++---
+ src/hb-ot-color-cbdt-table.hh  | 14 +++++-----
+ src/hb-ot-color-sbix-table.hh  |  8 +++---
+ src/hb-ot-font.cc              | 12 +++------
+ src/hb-ot-glyf-table.hh        | 58 ++++++++++++++++++++----------------------
+ src/hb-ot-hmtx-table.hh        |  2 +-
+ src/hb-ot-var-hvar-table.hh    |  5 ++--
+ test/api/test-ot-extents-cff.c | 20 +++++++--------
+ 10 files changed, 66 insertions(+), 75 deletions(-)
+
+commit f2339964b713815c8e0e33699bf34ee24db12215
+Author: Ebrahim Byagowi <ebrahim@gnu.org>
+Date:   Sun Oct 6 16:41:52 2019 +0330
+
+    [glyf] minor, remove GlyphHeader::simple_* helpers
+
+ src/hb-ot-glyf-table.hh | 16 +++-------------
+ 1 file changed, 3 insertions(+), 13 deletions(-)
+
+commit 2d7ca6a76a754a42ec09a66319ac3e4ab5efc618
+Author: Ebrahim Byagowi <ebrahim@gnu.org>
+Date:   Sun Oct 6 16:31:29 2019 +0330
+
+    [glyf] Move get_instruction_length inside GlyphHeader struct
+
+ src/hb-ot-glyf-table.hh | 153 ++++++++++++++++++++++++++----------------------
+ 1 file changed, 84 insertions(+), 69 deletions(-)
+
+commit 50aef4d7f80b6c8a19481ad3d0fa89c7c7f222c2
+Author: Ebrahim Byagowi <ebrahim@gnu.org>
+Date:   Sun Oct 6 14:00:07 2019 +0330
+
+    [glyf] cleanup
+
+ src/hb-ot-glyf-table.hh | 128 +++++++++++++++++++++---------------------------
+ 1 file changed, 55 insertions(+), 73 deletions(-)
+
+commit ee3f4630d70099c42fd9c84796b29a236f6135b6
+Author: Ebrahim Byagowi <ebrahim@gnu.org>
+Date:   Sun Oct 6 13:56:35 2019 +0330
+
+    [glyf] Remove get_composite_iter and refactor bytes_for_glyph for shape uses
+
+ src/hb-ot-glyf-table.hh | 42 ++++++++++++++++--------------------------
+ src/hb-subset-plan.cc   |  2 +-
+ 2 files changed, 17 insertions(+), 27 deletions(-)
+
+commit 8378ab96e28fa34f154583850ff1c2c672a4310d
+Author: Ebrahim Byagowi <ebrahim@gnu.org>
+Date:   Sun Oct 6 13:49:45 2019 +0330
+
+    [glyf] Rewrite composite iterator to new iterators convention
+
+ src/hb-ot-glyf-table.hh | 201 ++++++++++++++++++++----------------------------
+ src/hb-subset-plan.cc   |  10 +--
+ 2 files changed, 85 insertions(+), 126 deletions(-)
+
+commit b7684fa9f42dffa6bd81acfade163123b30800b8
+Merge: 79ec65ae 21c80d95
+Author: Ebrahim Byagowi <ebrahim@gnu.org>
+Date:   Sun Oct 6 09:00:48 2019 +0330
+
+    Merge pull request #1999 from ebraminio/glyf-var
     
-    Wish there was a way to streamline this :(.
+    Implement gvar table and variable glyf
 
- .circleci/config.yml | 6 +++---
- 1 file changed, 3 insertions(+), 3 deletions(-)
+commit 21c80d955f69c1242c77e0ec7ccd852360dd54dd
+Author: Ebrahim Byagowi <ebrahim@gnu.org>
+Date:   Sat Oct 5 23:58:52 2019 +0330
 
-commit 1cb1d5d7fb74e9f42dc8361dcdf669ed479d595d
-Merge: 8a568a88 d5287e1b
-Author: Michiharu Ariza <ariza@adobe.com>
-Date:   Thu Feb 14 10:09:19 2019 -0800
+    [gvar] minor
 
-    Merge branch 'master' into cff-more-arrayof-fixes
+ src/hb-ot-var-gvar-table.hh | 43 +++++++++++++++++++++----------------------
+ 1 file changed, 21 insertions(+), 22 deletions(-)
 
-commit 6f1dfd082cf79488ae6773e7d99172f13575668c
-Merge: b1dbc77f d5287e1b
-Author: Michiharu Ariza <ariza@adobe.com>
-Date:   Thu Feb 14 10:08:16 2019 -0800
+commit 5752863640cf4292dec313edebb57aecd47496f3
+Author: Ebrahim Byagowi <ebrahim@gnu.org>
+Date:   Sat Oct 5 23:51:50 2019 +0330
 
-    Merge branch 'master' into cff-retain-gids
+    [glyf][gvar] Make HB_NO_VAR buildable
 
-commit d5287e1ba40638be5d48178ce3d64557b622b01f
-Author: Behdad Esfahbod <behdad@fb.com>
-Date:   Wed Feb 13 23:46:17 2019 -0800
+ src/hb-ot-font.cc       | 2 ++
+ src/hb-ot-glyf-table.hh | 6 ++++++
+ src/hb-ot-hmtx-table.hh | 8 ++++++++
+ 3 files changed, 16 insertions(+)
 
-    [CI] Install wget on clang-O3-O0 bot
+commit 8e33510343d151afe49730f3a0b263a2853822b8
+Author: Ebrahim Byagowi <ebrahim@gnu.org>
+Date:   Fri Oct 4 01:11:03 2019 +0330
 
- .circleci/config.yml | 2 +-
+    [gvar] minor
+
+ src/hb-ot-var-gvar-table.hh | 132 ++++++++++++++++++++++----------------------
+ 1 file changed, 66 insertions(+), 66 deletions(-)
+
+commit b3afa8164460d63031a80d399200bcaa769c0fa1
+Author: Ebrahim Byagowi <ebrahim@gnu.org>
+Date:   Fri Oct 4 00:32:04 2019 +0330
+
+    [glyf] Use common convention of other tables access, format
+
+ src/hb-ot-face-table-list.hh |  1 +
+ src/hb-ot-glyf-table.hh      | 65 +++++++++++++++++++-------------------------
+ 2 files changed, 29 insertions(+), 37 deletions(-)
+
+commit 88bd342c0ff686daad88bb6b4f2968bbd8b01a24
+Author: Ebrahim Byagowi <ebrahim@gnu.org>
+Date:   Thu Oct 3 22:45:37 2019 +0330
+
+    [glyf] minor
+
+ src/hb-ot-glyf-table.hh     | 247 +++++++++++++++++++++++---------------------
+ src/hb-ot-var-gvar-table.hh |  54 +++++-----
+ 2 files changed, 155 insertions(+), 146 deletions(-)
+
+commit ee7610181cee5bbc0b5dc291228fbe032097bde4
+Author: Ebrahim Byagowi <ebrahim@gnu.org>
+Date:   Thu Oct 3 15:59:45 2019 +0330
+
+    [hmtx] Use more conventional internal API style
+
+ src/Makefile.sources    |  1 -
+ src/harfbuzz.cc         |  1 -
+ src/hb-ot-font.cc       | 12 ++++++++++++
+ src/hb-ot-hmtx-table.cc | 42 ------------------------------------------
+ src/hb-ot-hmtx-table.hh | 18 ++++++++++--------
+ 5 files changed, 22 insertions(+), 52 deletions(-)
+
+commit c9577a630fd5bd08482ee7b94bc03c91fcf366c7
+Author: Ebrahim Byagowi <ebrahim@gnu.org>
+Date:   Thu Oct 3 15:48:35 2019 +0330
+
+    [hmtx] Use more optimal way to access glyf table
+
+ src/hb-ot-hmtx-table.cc | 20 ++++----------------
+ src/hb-ot-hmtx-table.hh |  4 ++--
+ 2 files changed, 6 insertions(+), 18 deletions(-)
+
+commit b9ff43c162e8f61cff8e48d3dcbf7c1fe263d625
+Author: Michiharu Ariza <ariza@typekit.com>
+Date:   Tue Oct 1 16:13:40 2019 +0330
+
+    Implement gvar table and variable glyf
+    
+    Split from Ariza's "[subset] TrueType/CFF2 variable font" work on #1594
+
+ src/Makefile.sources                               |   2 +
+ src/harfbuzz.cc                                    |   1 +
+ src/hb-ot-font.cc                                  |   4 +-
+ src/hb-ot-glyf-table.hh                            | 618 ++++++++++++++---
+ src/hb-ot-hmtx-table.cc                            |  54 ++
+ src/hb-ot-hmtx-table.hh                            |  33 +-
+ src/hb-ot-var-gvar-table.hh                        | 734 +++++++++++++++++++++
+ test/api/Makefile.am                               |   1 +
+ .../SourceSansVariable-Roman-nohvar-41,C1.ttf      | Bin 0 -> 4696 bytes
+ test/api/fonts/SourceSansVariable-Roman.anchor.ttf | Bin 0 -> 4708 bytes
+ .../api/fonts/SourceSansVariable-Roman.modcomp.ttf | Bin 0 -> 3252 bytes
+ .../fonts/SourceSerifVariable-Roman-VVAR.abc.ttf   | Bin 0 -> 5632 bytes
+ test/api/test-ot-metrics-tt-var.c                  | 250 +++++++
+ 13 files changed, 1588 insertions(+), 109 deletions(-)
+
+commit 79ec65ae10f959aeddaa1e39eba5226c604a8c87
+Author: Ebrahim Byagowi <ebrahim@gnu.org>
+Date:   Thu Oct 3 14:27:51 2019 +0330
+
+    [ot-font] Use var vmtx side bearing in calculating v-origin
+
+ src/hb-ot-font.cc | 2 +-
  1 file changed, 1 insertion(+), 1 deletion(-)
 
-commit 890d0ee77fecd6aa4f19b663bb2897735a0d4c0b
+commit 3fd555be543a3e9bf9fee509327dbbc9a7b51cdb
 Author: Ebrahim Byagowi <ebrahim@gnu.org>
-Date:   Thu Feb 14 00:27:01 2019 +0330
+Date:   Thu Oct 3 13:02:41 2019 +0330
 
-    Minor, use a meaningful naming in template parameter (#1582)
+    [hmtx] Prepare to fix and minor fixes
 
- src/hb-ot-layout.hh | 6 +++---
- 1 file changed, 3 insertions(+), 3 deletions(-)
+ src/hb-ot-hmtx-table.hh     | 41 ++++++++++++++++-------------------------
+ src/hb-ot-var-hvar-table.hh |  9 +++++----
+ 2 files changed, 21 insertions(+), 29 deletions(-)
 
-commit 8a568a8858b44a81ca43a82761a70bf8d53e7c26
-Merge: c83412e4 1e1d0e63
-Author: Michiharu Ariza <ariza@adobe.com>
-Date:   Wed Feb 13 11:25:00 2019 -0800
+commit 6d09b5a8a0f6ed7a2a92d91ac3d027bd54c452be
+Author: Michiharu Ariza <ariza@typekit.com>
+Date:   Thu Oct 3 12:01:39 2019 +0330
 
-    Merge branch 'master' into cff-more-arrayof-fixes
+    Implement hmtx/vmtx metrics read from hvar/vvar
 
-commit b1dbc77fa62a99047df539663cfd1e8778d2c907
-Merge: c3a3536c 1e1d0e63
-Author: Michiharu Ariza <ariza@adobe.com>
-Date:   Wed Feb 13 11:24:38 2019 -0800
+ src/hb-ot-hmtx-table.hh     | 46 ++++++++++++++++++++++++++++++++++++++++-----
+ src/hb-ot-var-hvar-table.hh | 19 +++++++++++++------
+ 2 files changed, 54 insertions(+), 11 deletions(-)
 
-    Merge branch 'master' into cff-retain-gids
+commit cfafee52e4ff0441a33530847533f1b1f6019006
+Author: Ebrahim Byagowi <ebrahim@gnu.org>
+Date:   Wed Oct 2 09:22:46 2019 +0330
 
-commit 1e1d0e63df405730ed542ae1d729928623addf08
+    Add Repology badges by @luzpaz
+    
+    fixes #2002
+    to track downstream packaging of harfbuzz
+
+ README.md | 9 +++++++++
+ 1 file changed, 9 insertions(+)
+
+commit 2d7221a0e3552b1d902629d4ab6c0ce22db983a6
 Author: Ebrahim Byagowi <ebrahim@gnu.org>
-Date:   Wed Feb 13 12:58:01 2019 +0330
+Date:   Tue Oct 1 15:05:02 2019 +0330
 
-    Fix djgpp complains by tweaking templates (#1579)
+    [cff] minor
+
+ src/hb-ot-cff-common.hh | 10 +++++-----
+ 1 file changed, 5 insertions(+), 5 deletions(-)
+
+commit 0558413f27e9a18188c0e3d55f5ee57ea42b1548
+Author: Ebrahim Byagowi <ebrahim@gnu.org>
+Date:   Tue Oct 1 13:49:55 2019 +0330
+
+    Minor, tweak spaces
+
+ src/hb-aat-layout-kerx-table.hh    |  4 ++--
+ src/hb-array.hh                    |  4 ++--
+ src/hb-buffer.hh                   |  3 +--
+ src/hb-font.h                      |  4 ++--
+ src/hb-font.hh                     |  8 ++++----
+ src/hb-open-file.hh                |  2 +-
+ src/hb-open-type.hh                | 10 +++++-----
+ src/hb-ot-cff-common.hh            |  4 ++--
+ src/hb-ot-cff1-table.cc            | 11 +++++------
+ src/hb-ot-cff1-table.hh            | 24 ++++++++++++------------
+ src/hb-ot-cff2-table.cc            |  4 ++--
+ src/hb-ot-cmap-table.hh            |  6 ++----
+ src/hb-ot-color-cbdt-table.hh      |  2 +-
+ src/hb-ot-color-cpal-table.hh      |  2 +-
+ src/hb-ot-kern-table.hh            | 12 ++++++------
+ src/hb-ot-layout-common.hh         |  2 +-
+ src/hb-ot-layout-gpos-table.hh     | 14 +++++++-------
+ src/hb-ot-os2-table.hh             |  4 ++--
+ src/hb-ot-shape-complex-myanmar.cc |  4 ++--
+ src/hb-subset-cff-common.hh        |  2 +-
+ src/hb-unicode.cc                  |  8 ++++----
+ src/hb-unicode.h                   | 20 ++++++++++----------
+ src/hb-vector.hh                   |  4 ++--
+ src/main.cc                        | 37 +++++++++++++++++++++++--------------
+ src/test-iter.cc                   |  2 +-
+ 25 files changed, 101 insertions(+), 96 deletions(-)
+
+commit 51b720f686adf45bc1b6db3aa76b7d2e62ad1304
+Author: Ebrahim Byagowi <ebrahim@gnu.org>
+Date:   Tue Oct 1 12:06:22 2019 +0330
+
+    Fix -Wsizeof-array-div clang warning
+
+ src/hb-ot-shape-complex-arabic-fallback.hh | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+commit faace9437ea09d89ef5f5f9c9fc3ce0dbc672142
+Merge: e48ef080 f0dd724c
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Mon Sep 30 13:34:05 2019 -0700
+
+    Merge pull request #1807 from harfbuzz/subset-varstore
     
-    For some reasons djgpp doesn't understand "unsigned int" can be same
-    with one of uint*_t anyway so lets do that for it explicitly.
+    VariationStore serializer
+
+commit e48ef0804ad7e4abd35ff3646fa6ed10ad32f1ef
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Mon Sep 30 12:39:06 2019 -0700
+
+    2.6.2
+
+ NEWS             | 6 ++++++
+ configure.ac     | 2 +-
+ src/hb-version.h | 4 ++--
+ 3 files changed, 9 insertions(+), 3 deletions(-)
+
+commit d6ad613159aabce42fc21d57f6f1a4762c5617bf
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Tue Sep 10 15:31:44 2019 -0700
+
+    [docs] Misc fixes
+
+ docs/harfbuzz-sections.txt | 4 ++--
+ src/hb-gdi.cc              | 2 +-
+ src/hb-ot-layout.cc        | 2 +-
+ 3 files changed, 4 insertions(+), 4 deletions(-)
+
+commit 2dce85ed06a8cc7ca20900c65662af659c53e717
+Author: Ebrahim Byagowi <ebrahim@gnu.org>
+Date:   Thu Sep 26 21:15:59 2019 +0330
+
+    [icu] Remove HB_ICU_STMT (#1993)
     
-    Just to note, our CI's djgpp is based GCC 7.2.0 and isn't old.
+    And ignore extra semicolon error to ICU versions < 65
 
- src/hb-ot-layout.hh               | 4 ++--
- src/hb-ot-shape-complex-arabic.cc | 6 +++---
- 2 files changed, 5 insertions(+), 5 deletions(-)
+ src/hb-icu.cc | 43 ++++++++++++++++++++++++-------------------
+ 1 file changed, 24 insertions(+), 19 deletions(-)
 
-commit c3a3536c9a00a989ebd83d52e67d06525ed669bc
-Merge: bc33c617 85a6d312
-Author: Michiharu Ariza <ariza@adobe.com>
-Date:   Tue Feb 12 15:10:59 2019 -0800
+commit d6a83abd6a0c684bd9a27f593d5be388819022b7
+Author: Iceflower <iceflower@gmx.de>
+Date:   Thu Sep 26 11:42:11 2019 +0200
 
-    Merge branch 'cff-retain-gids' of https://github.com/harfbuzz/harfbuzz into cff-retain-gids
+    Define HB_UNUSED for clang
 
-commit bc33c617b85988f4d81312e62a75f92601852c76
-Merge: c6af8461 fdfa3d29
-Author: Michiharu Ariza <ariza@adobe.com>
-Date:   Tue Feb 12 15:10:50 2019 -0800
+ src/hb.hh | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
 
-    Merge branch 'master' into cff-retain-gids
+commit c4567968cd175dc367ab951c9e3141ab5c03c2d6
+Author: Iceflower <iceflower@gmx.de>
+Date:   Thu Sep 26 11:35:27 2019 +0200
 
-commit c6af846178bba10af318bcea1e9ac5165ec2aea6
-Author: Michiharu Ariza <ariza@adobe.com>
-Date:   Tue Feb 12 15:10:43 2019 -0800
+    [dwrite] Fix extra semicolon issue
 
-    tweaked --desubroutinize to remove hintmask only subrs
+ src/hb-directwrite.cc | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
 
- src/hb-subset-cff-common.hh | 26 ++++++++++++++++++++++++--
- 1 file changed, 24 insertions(+), 2 deletions(-)
+commit b0c3eb06b64dcfcfee09a25dde8250804484f77d
+Author: Qunxin Liu <qxliu@google.com>
+Date:   Wed Sep 18 16:11:44 2019 -0700
+
+    [subset] GPOS Lookup Type 3: CursivePos
+
+ src/hb-ot-layout-common.hh                         |  33 ++++++++
+ src/hb-ot-layout-gpos-table.hh                     |  87 ++++++++++++++++++++-
+ test/subset/data/Makefile.am                       |   1 +
+ test/subset/data/Makefile.sources                  |   1 +
+ .../gpos3_font3.keep-layout-retain-gids.28,29.otf  | Bin 0 -> 1712 bytes
+ .../gpos3_font3.keep-layout-retain-gids.28,2B.otf  | Bin 0 -> 1860 bytes
+ .../gpos3_font3.keep-layout-retain-gids.29,2B.otf  | Bin 0 -> 1772 bytes
+ ...eep-layout-retain-gids.retain-all-codepoint.otf | Bin 0 -> 3692 bytes
+ .../layout.gpos3/gpos3_font3.keep-layout.28,29.otf | Bin 0 -> 1328 bytes
+ .../layout.gpos3/gpos3_font3.keep-layout.28,2B.otf | Bin 0 -> 1456 bytes
+ .../layout.gpos3/gpos3_font3.keep-layout.29,2B.otf | Bin 0 -> 1368 bytes
+ ...pos3_font3.keep-layout.retain-all-codepoint.otf | Bin 0 -> 3692 bytes
+ test/subset/data/fonts/gpos3_font3.otf             | Bin 0 -> 4624 bytes
+ test/subset/data/tests/layout.gpos3.tests          |  12 +++
+ 14 files changed, 132 insertions(+), 2 deletions(-)
+
+commit 68d39ea4866a9d2bae60107619aad25dac6da241
+Author: Ebrahim Byagowi <ebrahim@gnu.org>
+Date:   Tue Sep 24 13:52:46 2019 +0330
 
-commit 85a6d3121a26c9bcbec60d37b64643ff8dc97a0a
-Merge: d9ded069 fdfa3d29
-Author: Michiharu Ariza <ariza@adobe.com>
-Date:   Mon Feb 11 14:25:21 2019 -0800
+    Revert previous change and fix -Wrange-loop-analysis complains
 
-    Merge branch 'master' into cff-retain-gids
+ src/hb-ot-layout-gpos-table.hh | 6 +++---
+ src/hb-ot-vorg-table.hh        | 2 +-
+ 2 files changed, 4 insertions(+), 4 deletions(-)
 
-commit c83412e4cec10f6f6f6ac38f202b3ce373da5daf
-Merge: 1239b6b2 fdfa3d29
-Author: Michiharu Ariza <ariza@adobe.com>
-Date:   Mon Feb 11 14:16:25 2019 -0800
+commit cbc0646a6cfc0f6a04804d6888636f12130cd51b
+Author: Ebrahim Byagowi <ebrahim@gnu.org>
+Date:   Tue Sep 24 12:08:12 2019 +0330
 
-    Merge branch 'master' into cff-more-arrayof-fixes
+    Minor, normalize for each calls
 
-commit fdfa3d29b7c347b5038f4f9148428c80dde462ae
-Author: Ken <21211439+kencu@users.noreply.github.com>
-Date:   Sun Feb 10 23:46:05 2019 -0800
+ src/hb-ot-glyf-table.hh        |  5 +----
+ src/hb-ot-layout-gpos-table.hh | 10 +++++-----
+ src/hb-ot-name-table.hh        |  3 +--
+ src/hb-ot-vorg-table.hh        |  3 +--
+ 4 files changed, 8 insertions(+), 13 deletions(-)
 
-    hb-coretext.cc: remove TARGET_OS_MAC from test (#1578)
+commit 22b6c6a5c7b9bebe123822c702b9661e144ebd6b
+Author: Ebrahim Byagowi <ebrahim@gnu.org>
+Date:   Tue Sep 24 12:06:28 2019 +0330
+
+    [serialize] use for each as #resolve_links, format
+
+ src/hb-serialize.hh | 22 +++++++---------------
+ 1 file changed, 7 insertions(+), 15 deletions(-)
+
+commit 512551f27600adac875de3381533b52d78f6b22d
+Author: Qunxin Liu <48925186+qxliu76@users.noreply.github.com>
+Date:   Mon Sep 23 17:28:16 2019 -0700
+
+    memory leak fix in serializer (#1988)
+
+ src/hb-serialize.hh | 1 +
+ 1 file changed, 1 insertion(+)
+
+commit f0a7677993e51ba4076a0f9a0e7d032d99917d34
+Author: Ebrahim Byagowi <ebrahim@gnu.org>
+Date:   Mon Sep 23 21:09:39 2019 +0330
+
+    [gpos] minor
+
+ src/hb-ot-layout-gpos-table.hh | 8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+commit 035ec3d1b46b8e60bea3aa8dcf29cf47a5a42d57
+Author: Ebrahim Byagowi <ebrahim@gnu.org>
+Date:   Mon Sep 23 20:51:43 2019 +0330
+
+    [cmap] remove has_format14, minor format
     
-    it is always true when building on APPLE systems
-    and this file only builds on APPLE systems
+    fixes #1986
 
- src/hb-coretext.cc | 10 +++++-----
- 1 file changed, 5 insertions(+), 5 deletions(-)
+ src/hb-ot-cmap-table.hh | 9 ++++-----
+ 1 file changed, 4 insertions(+), 5 deletions(-)
 
-commit f55e7bf5835c59e478d6a448327d53027c4e9f4a
+commit c1a585fab0c17fe47b0728cf67920791c2173019
 Author: Ebrahim Byagowi <ebrahim@gnu.org>
-Date:   Sun Feb 10 01:08:05 2019 +0330
+Date:   Sat Sep 21 23:30:52 2019 +0430
 
-    [ci] Install 'base-devel' on ArchLinux CI bot
+    [gpos] minor
 
.circleci/config.yml | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
src/hb-ot-layout-gpos-table.hh | 22 +++++++---------------
+ 1 file changed, 7 insertions(+), 15 deletions(-)
 
-commit 8f4eb919bd0498e997852aa39656adc4c65b3f0e
+commit d87d38998a4ff7bec3d8fb658dc9299f144a2fcb
 Author: Ebrahim Byagowi <ebrahim@gnu.org>
-Date:   Sat Feb 9 16:58:02 2019 +0330
+Date:   Sat Sep 21 17:27:39 2019 +0430
 
-    [ci] Install 'which' in ArchLinux bot
+    Fix clang -Wrange-loop-analysis complains
+    
+    ./hb-ot-layout-gpos-table.hh:674:43: error: loop variable '_' is always a copy because the range of type 'hb_zip_iter_t<hb_iter_type<hb_array_t<const OT::IntType<unsigned short, 2> > &>, hb_iter_type<hb_array_t<const OT::IntType<unsigned short, 2> > &> >' (aka 'hb_zip_iter_t<hb_array_t<const OT::IntType<unsigned short, 2> >, hb_array_t<const OT::IntType<unsigned short, 2> > >') does not return a reference [-Werror,-Wrange-loop-analysis]
+          for (const hb_pair_t<Value, Value>& _ : hb_zip (val_iter, first_val_iter))
+                                              ^
+    ./hb-ot-layout-gpos-table.hh:674:12: note: use non-reference type 'hb_pair_t<OT::Value, OT::Value>' (aka 'hb_pair_t<IntType<unsigned short, 2>, IntType<unsigned short, 2> >')
+          for (const hb_pair_t<Value, Value>& _ : hb_zip (val_iter, first_val_iter))
+    
+    and
+    
+    In file included from hb-subset.cc:44:
+    ./hb-ot-vorg-table.hh:87:34: error: loop variable '_' is always a copy because the range of type 'hb_map_iter_t<hb_filter_iter_t<hb_sorted_array_t<const OT::VertOriginMetric>, const hb_set_t *, OT::HBGlyphID OT::VertOriginMetric::*, nullptr>, (lambda at ./hb-ot-vorg-table.hh:100:15), hb_function_sortedness_t::NOT_SORTED, nullptr>' does not return a reference [-Werror,-Wrange-loop-analysis]
+        for (const VertOriginMetric& _ : it)
+                                     ^
+    ./hb-ot-vorg-table.hh:113:17: note: in instantiation of function template specialization 'OT::VORG::serialize<hb_map_iter_t<hb_filter_iter_t<hb_sorted_array_t<const OT::VertOriginMetric>, const hb_set_t *, OT::HBGlyphID OT::VertOriginMetric::*, nullptr>, (lambda at ./hb-ot-vorg-table.hh:100:15), hb_function_sortedness_t::NOT_SORTED, nullptr>, nullptr>' requested here
+        vorg_prime->serialize (c->serializer, it, defaultVertOriginY);
+                    ^
+    ./hb-ot-vorg-table.hh:87:10: note: use non-reference type 'OT::VertOriginMetric'
+        for (const VertOriginMetric& _ : it)
+             ^~~~~~~~~~~~~~~~~~~~~~~~~~~
 
- .circleci/config.yml | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
+ src/hb-ot-layout-gpos-table.hh | 2 +-
+ src/hb-ot-vorg-table.hh        | 2 +-
+ 2 files changed, 2 insertions(+), 2 deletions(-)
 
-commit 02294349618037f59b32834b49880ca75ed96261
+commit 6e42a418c8fe4231c3cc080bc771455578b0cce0
 Author: Ebrahim Byagowi <ebrahim@gnu.org>
-Date:   Sat Feb 9 16:33:28 2019 +0330
+Date:   Sat Sep 21 16:25:54 2019 +0430
 
-    [ci] Speculative fix for Alpine and ArchLinux bots
+    Minor, turn more of hb_apply to for each
+
+ src/hb-ot-glyf-table.hh        |  5 ++---
+ src/hb-ot-layout-gpos-table.hh | 42 ++++++++++++++----------------------------
+ src/hb-ot-name-table.hh        |  5 ++---
+ src/hb-ot-vorg-table.hh        |  5 ++---
+ 4 files changed, 20 insertions(+), 37 deletions(-)
+
+commit 0665dce1163317390adbed9394cce2b1325ddb6c
+Author: Ebrahim Byagowi <ebrahim@gnu.org>
+Date:   Sat Sep 21 17:22:02 2019 +0430
+
+    [fuzzer] Don't process output in debug mode as it causes timeout
+
+ test/fuzzing/run-shape-fuzzer-tests.py  | 7 ++++++-
+ test/fuzzing/run-subset-fuzzer-tests.py | 7 ++++++-
+ 2 files changed, 12 insertions(+), 2 deletions(-)
+
+commit dc886f6638f50e45e73d01e49db77b4bcefc85e1
+Author: Ebrahim Byagowi <ebrahim@gnu.org>
+Date:   Sat Sep 14 11:18:47 2019 +0430
+
+    [ci] Re-enable debug builds on fedora bot
 
  .circleci/config.yml | 4 ++--
  1 file changed, 2 insertions(+), 2 deletions(-)
 
-commit d9ded069926bf46a5d8e5edbf5201c98044db78e
-Merge: a5e933eb 84694af7
-Author: Michiharu Ariza <ariza@adobe.com>
-Date:   Fri Feb 8 14:44:20 2019 -0800
+commit 70228f68ac413ee19281861e3039a82d90c17f2a
+Author: Ebrahim Byagowi <ebrahim@gnu.org>
+Date:   Sat Sep 21 16:24:41 2019 +0430
 
-    Merge branch 'master' into cff-retain-gids
+    [ci] Enable HB_WITH_WIN1256 on -Weverything bot
+    
+    To catch its compile warnings, #1969 related
 
-commit a5e933eba08ff50ac3beb1055ae952ccc26d0af7
-Author: Michiharu Ariza <ariza@adobe.com>
-Date:   Fri Feb 8 14:44:13 2019 -0800
+ .circleci/config.yml | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
 
-    Updated expected/cff-japanese fonts with retained FDs
+commit 385741d565de1cc90de23664f8e66fc77c31efae
+Author: Ebrahim Byagowi <ebrahim@gnu.org>
+Date:   Sat Sep 21 15:26:14 2019 +0430
 
- ...gular.default.3042,3044,3046,3048,304A,304B.otf |    Bin 6324 -> 6356 bytes
- ...gular.default.3042,3044,3046,73E0,5EA6,8F38.otf |    Bin 6568 -> 6564 bytes
- .../SourceHanSans-Regular.default.61,63,65,6B.otf  |    Bin 5500 -> 5532 bytes
- ...gular.default.660E,6975,73E0,5EA6,8F38,6E05.otf |    Bin 6780 -> 6780 bytes
- .../SourceHanSans-Regular.default.660E.otf         |    Bin 5248 -> 5248 bytes
- ...e-retain-gids.3042,3044,3046,3048,304A,304B.otf |    Bin 536352 -> 537992 bytes
- ...e-retain-gids.3042,3044,3046,73E0,5EA6,8F38.otf |    Bin 690752 -> 692312 bytes
- ...ular.desubroutinize-retain-gids.61,63,65,6B.otf |    Bin 530004 -> 531624 bytes
- ...e-retain-gids.660E,6975,73E0,5EA6,8F38,6E05.otf |    Bin 690868 -> 692496 bytes
- ...ans-Regular.desubroutinize-retain-gids.660E.otf |    Bin 612212 -> 613836 bytes
- ...esubroutinize.3042,3044,3046,3048,304A,304B.otf |    Bin 6248 -> 6272 bytes
- ...esubroutinize.3042,3044,3046,73E0,5EA6,8F38.otf |    Bin 6432 -> 6456 bytes
- ...eHanSans-Regular.desubroutinize.61,63,65,6B.otf |    Bin 5428 -> 5460 bytes
- ...esubroutinize.660E,6975,73E0,5EA6,8F38,6E05.otf |    Bin 6552 -> 6572 bytes
- .../SourceHanSans-Regular.desubroutinize.660E.otf  |    Bin 5196 -> 5224 bytes
- ...e-retain-gids.3042,3044,3046,3048,304A,304B.otf |    Bin 536176 -> 537424 bytes
- ...e-retain-gids.3042,3044,3046,73E0,5EA6,8F38.otf |    Bin 690500 -> 691692 bytes
- ...ints-desubroutinize-retain-gids.61,63,65,6B.otf |    Bin 529888 -> 531124 bytes
- ...e-retain-gids.660E,6975,73E0,5EA6,8F38,6E05.otf |    Bin 690564 -> 691808 bytes
- ....drop-hints-desubroutinize-retain-gids.660E.otf |    Bin 612108 -> 613348 bytes
- ...s-retain-gids.3042,3044,3046,3048,304A,304B.otf |    Bin 536244 -> 537492 bytes
- ...s-retain-gids.3042,3044,3046,73E0,5EA6,8F38.otf |    Bin 690596 -> 691788 bytes
- ...-Regular.drop-hints-retain-gids.61,63,65,6B.otf |    Bin 529928 -> 531164 bytes
- ...-Regular.drop-hints-retain-gids.61,63,65,6B.ttx | 393879 ++++++++++++++++++
- ...s-retain-gids.660E,6975,73E0,5EA6,8F38,6E05.otf |    Bin 690768 -> 692008 bytes
- ...HanSans-Regular.drop-hints-retain-gids.660E.otf |    Bin 612128 -> 613368 bytes
- ...ar.drop-hints.3042,3044,3046,3048,304A,304B.otf |    Bin 6132 -> 6164 bytes
- ...ar.drop-hints.3042,3044,3046,73E0,5EA6,8F38.otf |    Bin 6304 -> 6300 bytes
- ...ourceHanSans-Regular.drop-hints.61,63,65,6B.otf |    Bin 5344 -> 5376 bytes
- ...ar.drop-hints.660E,6975,73E0,5EA6,8F38,6E05.otf |    Bin 6472 -> 6472 bytes
- .../SourceHanSans-Regular.drop-hints.660E.otf      |    Bin 5140 -> 5140 bytes
- ...r.retain-gids.3042,3044,3046,3048,304A,304B.otf |    Bin 536436 -> 538076 bytes
- ...r.retain-gids.3042,3044,3046,73E0,5EA6,8F38.otf |    Bin 690860 -> 692420 bytes
- ...urceHanSans-Regular.retain-gids.61,63,65,6B.otf |    Bin 530084 -> 531704 bytes
- ...r.retain-gids.660E,6975,73E0,5EA6,8F38,6E05.otf |    Bin 691076 -> 692700 bytes
- .../SourceHanSans-Regular.retain-gids.660E.otf     |    Bin 612236 -> 613860 bytes
- 36 files changed, 393879 insertions(+)
+    [cmap] Turn hb_apply into foreach where possible
 
-commit 84694af723bde07cf3231ed2d2e193123f5f73ed
+ src/hb-ot-cmap-table.hh | 151 +++++++++++++++++++-----------------------------
+ 1 file changed, 61 insertions(+), 90 deletions(-)
+
+commit 1023c2cc6de0f33602df8709134bef8cdb66ba0c
 Author: Ebrahim Byagowi <ebrahim@gnu.org>
-Date:   Fri Feb 8 15:30:17 2019 +0330
+Date:   Sat Sep 21 14:33:43 2019 +0430
 
-    [ci] Disable the just added bot
+    [cmap] minor
+
+ src/hb-ot-cmap-table.hh | 62 ++++++++++++++++++-------------------------------
+ 1 file changed, 22 insertions(+), 40 deletions(-)
+
+commit ead46eefe3bf2bea61c86689f4c5a1da9b7e446b
+Author: Ebrahim Byagowi <ebrahim@gnu.org>
+Date:   Sat Sep 21 14:25:11 2019 +0430
+
+    minor, use internal API instead public hb_set_has
+
+ src/hb-ot-cmap-table.hh | 4 ++--
+ src/hb-subset-plan.cc   | 2 +-
+ 2 files changed, 3 insertions(+), 3 deletions(-)
+
+commit d8af4e7701fe63d63f6669706ce7a5bb3a15a19d
+Author: Ebrahim Byagowi <ebrahim@gnu.org>
+Date:   Sat Sep 21 14:19:14 2019 +0430
+
+    [cmap] minor, turn 8 spaces to tab
+
+ src/hb-ot-cmap-table.hh | 228 ++++++++++++++++++++++++------------------------
+ src/hb-subset-plan.cc   |   6 +-
+ 2 files changed, 117 insertions(+), 117 deletions(-)
+
+commit 4315666283a7d1b175d1c3ed43b5ac85fdc84a50
+Author: Qunxin Liu <qxliu@google.com>
+Date:   Thu Aug 29 11:17:20 2019 -0700
+
+    [subset] updates according to review comments
+
+ src/hb-ot-cmap-table.hh | 95 ++++++++++++++++++++++++-------------------------
+ 1 file changed, 47 insertions(+), 48 deletions(-)
+
+commit bf66d1bf589b6af2ceb30c18619f210b718c9db9
+Author: Qunxin Liu <qxliu@google.com>
+Date:   Wed Aug 21 14:24:33 2019 -0700
+
+    [subset] Add integration tests for cmap14
+
+ test/subset/data/Makefile.am                       |   1 +
+ test/subset/data/Makefile.sources                  |   1 +
+ .../cmap14/cmap14_font1.default.4E00,4E02,4E03.otf | Bin 0 -> 1360 bytes
+ .../cmap14/cmap14_font1.default.4E00,4E03.otf      | Bin 0 -> 1236 bytes
+ .../cmap14/cmap14_font1.default.4E00,4E05,4E07.otf | Bin 0 -> 1328 bytes
+ .../cmap14/cmap14_font1.default.4E02,4E03,4E08.otf | Bin 0 -> 1576 bytes
+ .../expected/cmap14/cmap14_font1.default.4E02.otf  | Bin 0 -> 996 bytes
+ .../expected/cmap14/cmap14_font1.default.4E03.otf  | Bin 0 -> 1080 bytes
+ .../cmap14_font1.default.4E05,4E07,4E08,4E09.otf   | Bin 0 -> 1848 bytes
+ .../cmap14/cmap14_font1.default.4E08,4E09.otf      | Bin 0 -> 1720 bytes
+ .../expected/cmap14/cmap14_font1.default.4E08.otf  | Bin 0 -> 1384 bytes
+ .../cmap14_font1.default.retain-all-codepoint.otf  | Bin 0 -> 2348 bytes
+ ...font1.drop-hints-retain-gids.4E00,4E02,4E03.otf | Bin 0 -> 1388 bytes
+ ...ap14_font1.drop-hints-retain-gids.4E00,4E03.otf | Bin 0 -> 1272 bytes
+ ...font1.drop-hints-retain-gids.4E00,4E05,4E07.otf | Bin 0 -> 1396 bytes
+ ...font1.drop-hints-retain-gids.4E02,4E03,4E08.otf | Bin 0 -> 1720 bytes
+ .../cmap14_font1.drop-hints-retain-gids.4E02.otf   | Bin 0 -> 1028 bytes
+ .../cmap14_font1.drop-hints-retain-gids.4E03.otf   | Bin 0 -> 1124 bytes
+ ....drop-hints-retain-gids.4E05,4E07,4E08,4E09.otf | Bin 0 -> 1984 bytes
+ ...ap14_font1.drop-hints-retain-gids.4E08,4E09.otf | Bin 0 -> 1872 bytes
+ .../cmap14_font1.drop-hints-retain-gids.4E08.otf   | Bin 0 -> 1544 bytes
+ ...drop-hints-retain-gids.retain-all-codepoint.otf | Bin 0 -> 2436 bytes
+ .../cmap14_font1.drop-hints.4E00,4E02,4E03.otf     | Bin 0 -> 1292 bytes
+ .../cmap14/cmap14_font1.drop-hints.4E00,4E03.otf   | Bin 0 -> 1168 bytes
+ .../cmap14_font1.drop-hints.4E00,4E05,4E07.otf     | Bin 0 -> 1260 bytes
+ .../cmap14_font1.drop-hints.4E02,4E03,4E08.otf     | Bin 0 -> 1512 bytes
+ .../cmap14/cmap14_font1.drop-hints.4E02.otf        | Bin 0 -> 928 bytes
+ .../cmap14/cmap14_font1.drop-hints.4E03.otf        | Bin 0 -> 1012 bytes
+ ...cmap14_font1.drop-hints.4E05,4E07,4E08,4E09.otf | Bin 0 -> 1780 bytes
+ .../cmap14/cmap14_font1.drop-hints.4E08,4E09.otf   | Bin 0 -> 1652 bytes
+ .../cmap14/cmap14_font1.drop-hints.4E08.otf        | Bin 0 -> 1316 bytes
+ ...map14_font1.drop-hints.retain-all-codepoint.otf | Bin 0 -> 2280 bytes
+ .../cmap14_font1.name-ids.4E00,4E02,4E03.otf       | Bin 0 -> 1292 bytes
+ .../cmap14/cmap14_font1.name-ids.4E00,4E03.otf     | Bin 0 -> 1168 bytes
+ .../cmap14_font1.name-ids.4E00,4E05,4E07.otf       | Bin 0 -> 1260 bytes
+ .../cmap14_font1.name-ids.4E02,4E03,4E08.otf       | Bin 0 -> 1508 bytes
+ .../expected/cmap14/cmap14_font1.name-ids.4E02.otf | Bin 0 -> 928 bytes
+ .../expected/cmap14/cmap14_font1.name-ids.4E03.otf | Bin 0 -> 1012 bytes
+ .../cmap14_font1.name-ids.4E05,4E07,4E08,4E09.otf  | Bin 0 -> 1780 bytes
+ .../cmap14/cmap14_font1.name-ids.4E08,4E09.otf     | Bin 0 -> 1652 bytes
+ .../expected/cmap14/cmap14_font1.name-ids.4E08.otf | Bin 0 -> 1316 bytes
+ .../cmap14_font1.name-ids.retain-all-codepoint.otf | Bin 0 -> 2280 bytes
+ .../cmap14_font1.retain-gids.4E00,4E02,4E03.otf    | Bin 0 -> 1452 bytes
+ .../cmap14/cmap14_font1.retain-gids.4E00,4E03.otf  | Bin 0 -> 1340 bytes
+ .../cmap14_font1.retain-gids.4E00,4E05,4E07.otf    | Bin 0 -> 1464 bytes
+ .../cmap14_font1.retain-gids.4E02,4E03,4E08.otf    | Bin 0 -> 1788 bytes
+ .../cmap14/cmap14_font1.retain-gids.4E02.otf       | Bin 0 -> 1096 bytes
+ .../cmap14/cmap14_font1.retain-gids.4E03.otf       | Bin 0 -> 1192 bytes
+ ...map14_font1.retain-gids.4E05,4E07,4E08,4E09.otf | Bin 0 -> 2048 bytes
+ .../cmap14/cmap14_font1.retain-gids.4E08,4E09.otf  | Bin 0 -> 1940 bytes
+ .../cmap14/cmap14_font1.retain-gids.4E08.otf       | Bin 0 -> 1608 bytes
+ ...ap14_font1.retain-gids.retain-all-codepoint.otf | Bin 0 -> 2500 bytes
+ test/subset/data/fonts/cmap14_font1.otf            | Bin 0 -> 4484 bytes
+ test/subset/data/tests/cmap14.tests                |  21 +++++++++++++++++++++
+ 54 files changed, 23 insertions(+)
+
+commit 2583afa0eb90134274ddd92864ea5270eeebc52e
+Author: Qunxin Liu <qxliu@google.com>
+Date:   Fri Aug 16 13:54:24 2019 -0700
+
+    [subset] subsetting cmap14
+
+ src/hb-ot-cmap-table.hh | 295 +++++++++++++++++++++++++++++++++++++++++++-----
+ 1 file changed, 265 insertions(+), 30 deletions(-)
+
+commit 078ddbd0f6ad660e740809b7f4c067e02309b98d
+Author: Qunxin Liu <qxliu@google.com>
+Date:   Wed Aug 7 13:17:26 2019 -0700
+
+    [subset] glyph closure for CMAP14
+
+ src/hb-ot-cmap-table.hh | 34 +++++++++++++++++++++++++++++++++-
+ src/hb-subset-plan.cc   | 10 ++++++++++
+ 2 files changed, 43 insertions(+), 1 deletion(-)
+
+commit bbe878006d347893fc70e282c2aaafef5dd622b4
+Author: Ebrahim Byagowi <ebrahim@gnu.org>
+Date:   Wed Sep 18 22:22:01 2019 +0430
+
+    Avoid bitwise negate of enum value
+    
+    Fixes this -fno-sanitize-recover=undefined fail,
+    
+    hb-ot-map.hh:188:1: runtime error: load of value 4294967294, which is not a valid value for type 'hb_ot_map_feature_flags_t'
+        #0 0x7f62bfa9b227 in operator&=(hb_ot_map_feature_flags_t&, hb_ot_map_feature_flags_t) /home/ebrahim/Desktop/harfbuzz/src/./hb-ot-map.hh:188:1
+        #1 0x7f62bfa9b227 in hb_ot_map_builder_t::compile(hb_ot_map_t&, hb_ot_shape_plan_key_t const&) /home/ebrahim/Desktop/harfbuzz/src/hb-ot-map.cc:194
+        #2 0x7f62bface650 in hb_ot_shape_planner_t::compile(hb_ot_shape_plan_t&, hb_ot_shape_plan_key_t const&) /home/ebrahim/Desktop/harfbuzz/src/hb-ot-shape.cc:108:7
+        #3 0x7f62bfacec1e in hb_ot_shape_plan_t::init0(hb_face_t*, hb_shape_plan_key_t const*) /home/ebrahim/Desktop/harfbuzz/src/hb-ot-shape.cc:225:11
+        #4 0x7f62bfae1318 in hb_shape_plan_create2 /home/ebrahim/Desktop/harfbuzz/src/hb-shape-plan.cc:232:7
+        #5 0x7f62bfae1d2a in hb_shape_plan_create_cached2 /home/ebrahim/Desktop/harfbuzz/src/hb-shape-plan.cc:489:33
+        #6 0x7f62bfae2527 in hb_shape_full /home/ebrahim/Desktop/harfbuzz/src/hb-shape.cc:135:33
+        #7 0x55ed360b6588 in shape_options_t::shape(hb_font_t*, hb_buffer_t*, char const**) /home/ebrahim/Desktop/harfbuzz/util/./options.hh:242:10
+        #8 0x55ed360b5d9c in shape_consumer_t<output_buffer_t>::consume_line(char const*, unsigned int, char const*, char const*) /home/ebrahim/Desktop/harfbuzz/util/./shape-consumer.hh:67:19
+        #9 0x55ed360b549f in main_font_text_t<shape_consumer_t<output_buffer_t>, 2147483647, 0>::main(int, char**) /home/ebrahim/Desktop/harfbuzz/util/./main-font-text.hh:81:16
+        #10 0x55ed360b4e23 in main /home/ebrahim/Desktop/harfbuzz/util/hb-shape.cc:189:17
+        #11 0x7f62bf104ee2 in __libc_start_main (/usr/lib/libc.so.6+0x26ee2)
+        #12 0x55ed3608f7ad in _start (/home/ebrahim/Desktop/harfbuzz/util/.libs/lt-hb-shape+0xd7ad)
+
+ src/hb-ot-map.cc | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+commit e6909ee58d0f7b954f3bb227c2f90ca4cfd0c858
+Author: Ebrahim Byagowi <ebrahim@gnu.org>
+Date:   Wed Sep 18 22:12:25 2019 +0430
+
+    minor
+
+ src/hb-buffer.cc | 2 +-
+ src/hb-common.cc | 2 +-
+ 2 files changed, 2 insertions(+), 2 deletions(-)
+
+commit bb41b74fd1fb42b08e9069c22ee046daeee98e6b
+Author: Ebrahim Byagowi <ebrahim@gnu.org>
+Date:   Wed Sep 18 00:55:24 2019 +0430
+
+    Don't rely on undefined left shift of negative value behavior
     
-    Doesn't play well with CircleCI apparently
+    Fixes this -fno-sanitize-recover=undefined check,
     
-    https://circleci.com/gh/harfbuzz/harfbuzz/74289
+    hb-ft.cc:869:27: runtime error: left shift of negative value -16384
+        #0 0x7ff8f47da843 in hb_ft_font_set_funcs /home/ebrahim/Desktop/harfbuzz/src/hb-ft.cc:869:27
+        #1 0x55f20a66c7d6 in font_options_t::get_font() const /home/ebrahim/Desktop/harfbuzz/util/options.cc:731:3
+        #2 0x55f20a668c1f in shape_consumer_t<output_buffer_t>::init(hb_buffer_t*, font_options_t const*) /home/ebrahim/Desktop/harfbuzz/util/./shape-consumer.hh:47:42
+        #3 0x55f20a668441 in main_font_text_t<shape_consumer_t<output_buffer_t>, 2147483647, 0>::main(int, char**) /home/ebrahim/Desktop/harfbuzz/util/./main-font-text.hh:75:14
+        #4 0x55f20a667f91 in main /home/ebrahim/Desktop/harfbuzz/util/hb-shape.cc:180:21
+        #5 0x7ff8f3df7ee2 in __libc_start_main (/usr/lib/libc.so.6+0x26ee2)
+        #6 0x55f20a6427ad in _start (/home/ebrahim/Desktop/harfbuzz/util/.libs/lt-hb-shape+0xd7ad)
 
.circleci/config.yml | 19 ++++++++++---------
- 1 file changed, 10 insertions(+), 9 deletions(-)
src/hb-ft.cc | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
 
-commit 81ae4974e35aa8ca408abd6238eb768f5c948287
+commit b73313ade75130bf86ad1efbd312ce4106166089
 Author: Ebrahim Byagowi <ebrahim@gnu.org>
-Date:   Fri Feb 8 15:18:26 2019 +0330
+Date:   Wed Sep 18 00:50:32 2019 +0430
+
+    Don't seek of out-of-bound value even if the result is not used
+    
+    Fixes this -fno-sanitize-recover=undefined fail,
+    
+    /set/iter: hb-algs.hh:1016:60: runtime error: index 4294967295 out of bounds for type 'unsigned long long const[8]'
+        #0 0x4d1e09 in hb_vector_size_t<unsigned long long, 64u>::operator[](unsigned int) const /home/user/code/harfbuzz/src/./hb-algs.hh:1016:60
+        #1 0x4d8b5f in hb_set_t::page_t::previous(unsigned int*) const /home/user/code/harfbuzz/src/./hb-set.hh:139:53
+        #2 0x4d0ada in hb_set_t::previous(unsigned int*) const /home/user/code/harfbuzz/src/./hb-set.hh:602:36
+        #3 0x4cd76f in hb_set_previous /home/user/code/harfbuzz/src/hb-set.cc:494:15
+        #4 0x4ca8af in test_set_iter /home/user/code/harfbuzz/test/api/test-set.c:310:3
+        #5 0x7f3a4f3e0f49  (/usr/lib/x86_64-linux-gnu/libglib-2.0.so.0+0x72f49)
+        #6 0x7f3a4f3e0e7a  (/usr/lib/x86_64-linux-gnu/libglib-2.0.so.0+0x72e7a)
+        #7 0x7f3a4f3e1121 in g_test_run_suite (/usr/lib/x86_64-linux-gnu/libglib-2.0.so.0+0x73121)
+        #8 0x7f3a4f3e1140 in g_test_run (/usr/lib/x86_64-linux-gnu/libglib-2.0.so.0+0x73140)
+        #9 0x4c8894 in hb_test_run /home/user/code/harfbuzz/test/api/./hb-test.h:88:10
+        #10 0x4c8894 in main /home/user/code/harfbuzz/test/api/test-set.c:408:10
+        #11 0x7f3a4e3d2b96 in __libc_start_main /build/glibc-OTsEL5/glibc-2.27/csu/../csu/libc-start.c:310
+        #12 0x41e7d9 in _start (/home/user/code/harfbuzz/test/api/test-set+0x41e7d9)
+
+ src/hb-set.hh | 7 ++++++-
+ 1 file changed, 6 insertions(+), 1 deletion(-)
 
-    [ci] Add a Void Linux bot
+commit d8af9ee017ed1018343d30272f55b90dd03a3559
+Author: Ebrahim Byagowi <ebrahim@gnu.org>
+Date:   Wed Sep 18 00:47:55 2019 +0430
+
+    Don't rely on nullptr deref recovery
     
-    https://voidlinux.org/ is yet another and different distro written from scratch, thus completely eligible to have a bot here!
+    Fixes this -fno-sanitize-recover=undefined fail,
     
-    Seriously however not that useful yet however but I will try to overload it other tasks later, like our other bots.
+    /types/language: hb-common.cc:385:20: runtime error: member access within null pointer of type 'const struct hb_language_impl_t'
+        #0 0x4caa34 in hb_language_to_string /home/user/code/harfbuzz/src/hb-common.cc:385:20
+        #1 0x4c9be8 in test_types_language /home/user/code/harfbuzz/test/api/test-common.c:205:3
+        #2 0x7f9557e72f49  (/usr/lib/x86_64-linux-gnu/libglib-2.0.so.0+0x72f49)
+        #3 0x7f9557e72e7a  (/usr/lib/x86_64-linux-gnu/libglib-2.0.so.0+0x72e7a)
+        #4 0x7f9557e73121 in g_test_run_suite (/usr/lib/x86_64-linux-gnu/libglib-2.0.so.0+0x73121)
+        #5 0x7f9557e73140 in g_test_run (/usr/lib/x86_64-linux-gnu/libglib-2.0.so.0+0x73140)
+        #6 0x4c88a3 in hb_test_run /home/user/code/harfbuzz/test/api/./hb-test.h:88:10
+        #7 0x4c88a3 in main /home/user/code/harfbuzz/test/api/test-common.c:224:10
+        #8 0x7f9556e64b96 in __libc_start_main /build/glibc-OTsEL5/glibc-2.27/csu/../csu/libc-start.c:310
+        #9 0x41e7d9 in _start (/home/user/code/harfbuzz/test/api/test-common+0x41e7d9)
+
+ src/hb-common.cc | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+commit bfb155a5f19b26f9dcff667a76a24cd5c3b83234
+Author: Ebrahim Byagowi <ebrahim@gnu.org>
+Date:   Wed Sep 18 00:44:52 2019 +0430
+
+    Don't call memset when length is zero
     
-    No test yet also, couldn't install cairo-devel, will try to fix that later.
+    Fixes this -fno-sanitize-recover=undefined check,
     
-    Their harfbuzz package source: https://github.com/void-linux/void-packages/blob/master/srcpkgs/harfbuzz/template
+    /buffer/positions/empty: hb-buffer.cc:327:11: runtime error: null pointer passed as argument 1, which is declared to never be null
+    
+    /usr/include/string.h:60:62: note: nonnull attribute specified here
+        #0 0x4cf31c in hb_buffer_t::clear_positions() /home/user/code/harfbuzz/src/hb-buffer.cc:327:3
+        #1 0x4d4dd4 in hb_buffer_get_glyph_positions /home/user/code/harfbuzz/src/hb-buffer.cc:1418:13
+        #2 0x4cb553 in test_buffer_positions /home/user/code/harfbuzz/test/api/test-buffer.c:305:3
+        #3 0x7f324187bf49  (/usr/lib/x86_64-linux-gnu/libglib-2.0.so.0+0x72f49)
+        #4 0x7f324187be7a  (/usr/lib/x86_64-linux-gnu/libglib-2.0.so.0+0x72e7a)
+        #5 0x7f324187be7a  (/usr/lib/x86_64-linux-gnu/libglib-2.0.so.0+0x72e7a)
+        #6 0x7f324187c121 in g_test_run_suite (/usr/lib/x86_64-linux-gnu/libglib-2.0.so.0+0x73121)
+        #7 0x7f324187c140 in g_test_run (/usr/lib/x86_64-linux-gnu/libglib-2.0.so.0+0x73140)
+        #8 0x4c8bd3 in hb_test_run /home/user/code/harfbuzz/test/api/./hb-test.h:88:10
+        #9 0x4c8bd3 in main /home/user/code/harfbuzz/test/api/test-buffer.c:884:10
+        #10 0x7f324086db96 in __libc_start_main /build/glibc-OTsEL5/glibc-2.27/csu/../csu/libc-start.c:310
+        #11 0x41e919 in _start (/home/user/code/harfbuzz/test/api/test-buffer+0x41e919)
 
.circleci/config.yml | 11 ++++++++++-
- 1 file changed, 10 insertions(+), 1 deletion(-)
src/hb-buffer.cc | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
 
-commit e2856c2d85eb0f6ce0c780d1889dc9bb05cdc433
-Author: Michiharu Ariza <ariza@adobe.com>
-Date:   Thu Feb 7 15:32:32 2019 -0800
+commit 5a1cc199ab7b619935af04584ecc650216a83d66
+Author: Ebrahim Byagowi <ebrahim@gnu.org>
+Date:   Wed Sep 18 00:43:44 2019 +0430
 
-    retain FDSelect & FDArray with --retain-gids
-    
-    so in sync with fonttools behavior
+    [ci] Run -fno-sanitize-recover=undefined checks
 
- src/hb-subset-cff-common.cc                           |  12 ++++--------
- .../SourceHanSans-Regular.41,4C2E.retaingids.otf      | Bin 2604 -> 2736 bytes
- 2 files changed, 4 insertions(+), 8 deletions(-)
+ .circleci/config.yml | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
 
-commit 1239b6b2b4430658aea78216a1dcc885724a7ab4
-Merge: 9f80eb01 126abca9
-Author: Michiharu Ariza <ariza@adobe.com>
-Date:   Thu Feb 7 10:29:40 2019 -0800
+commit c930ae2bd8b6f626ddec0628ae6b38e3134e3c97
+Author: Ebrahim Byagowi <ebrahim@gnu.org>
+Date:   Mon Sep 16 14:04:34 2019 +0430
 
-    Merge branch 'master' into cff-more-arrayof-fixes
+    Avoid stdint.h in Kernel module compiles
 
-commit a5fa76977b5bdf3bd40ede3cdd0da9c5546557a6
-Merge: 214d0b02 126abca9
-Author: Michiharu Ariza <ariza@adobe.com>
-Date:   Thu Feb 7 10:28:13 2019 -0800
+ src/hb-common.h | 2 ++
+ 1 file changed, 2 insertions(+)
 
-    Merge branch 'master' into cff-retain-gids
+commit 412d6cac3a46d710159ed4b3cc3bb59fd5876d5f
+Author: Ebrahim Byagowi <ebrahim@gnu.org>
+Date:   Mon Sep 16 13:50:11 2019 +0430
 
-commit 214d0b024b49edd51974ff2c051535ae06de0709
-Author: Michiharu Ariza <ariza@adobe.com>
-Date:   Thu Feb 7 10:27:43 2019 -0800
+    Extract an avoid errno compile flag
 
-    minor change
+ src/hb-blob.cc   | 1 -
+ src/hb-config.hh | 1 +
+ src/hb.hh        | 9 +++++++--
+ 3 files changed, 8 insertions(+), 3 deletions(-)
 
- src/hb-subset-cff-common.cc | 4 ++--
+commit 8a16d6f1c13388e6d9ca844a309632ec583ee1a2
+Author: Ebrahim Byagowi <ebrahim@gnu.org>
+Date:   Sun Sep 15 20:43:33 2019 +0430
+
+    [doc] fix minor typo
+
+ src/hb-ot-layout.cc | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit aab279b33dda45ae0e45c887f2fad6381b5138dc
+Author: Ebrahim Byagowi <ebrahim@gnu.org>
+Date:   Sat Sep 14 11:20:09 2019 +0430
+
+    [ci] Install cmake on macOS cmake/amalgam tester
+
+ .circleci/config.yml | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit f3214df6f63919ebe73c713b1e80bba1097a0cea
+Author: Ebrahim Byagowi <ebrahim@gnu.org>
+Date:   Sat Sep 14 10:56:00 2019 +0430
+
+    [coretext] Fix double promotion warnings by making casts explicit
+
+ src/hb-coretext.cc | 4 ++--
  1 file changed, 2 insertions(+), 2 deletions(-)
 
-commit 126abca98a954f7ec3374d0593fee25f78dc10f3
-Merge: 1e062821 7859decd
+commit cbbb6fa45519a8670870c784841d7b9e1ab71dd1
+Author: Ebrahim Byagowi <ebrahim@gnu.org>
+Date:   Sat Sep 14 10:53:12 2019 +0430
+
+    [ci] Don't build cmake tests in macOS bot
+
+ .circleci/config.yml | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 6e4736a3c5acc0eea1b16c79b95d1a3082baa320
+Author: Ebrahim Byagowi <ebrahim@gnu.org>
+Date:   Sat Sep 14 10:38:52 2019 +0430
+
+    [name] Undef entry_{index,score} to avoid collision in amalgam builds
+
+ src/hb-ot-name-table.hh | 3 +++
+ 1 file changed, 3 insertions(+)
+
+commit d512087e4dfb5d9483b78eaf8443b4fa8724b8e1
+Author: Ebrahim Byagowi <ebrahim@gnu.org>
+Date:   Sat Sep 14 10:36:29 2019 +0430
+
+    Rename GlyphID to HBGlyphID
+    
+    Avoid collision with macOS's ATSUnicodeTypes.h GlyphID
+
+ src/hb-aat-layout-bsln-table.hh            |  4 +-
+ src/hb-aat-layout-common.hh                | 16 +++----
+ src/hb-aat-layout-just-table.hh            |  8 ++--
+ src/hb-aat-layout-kerx-table.hh            |  4 +-
+ src/hb-aat-layout-morx-table.hh            | 32 ++++++-------
+ src/hb-open-type.hh                        |  4 +-
+ src/hb-ot-cmap-table.hh                    |  4 +-
+ src/hb-ot-color-cbdt-table.hh              |  8 ++--
+ src/hb-ot-color-colr-table.hh              |  4 +-
+ src/hb-ot-glyf-table.hh                    |  2 +-
+ src/hb-ot-layout-base-table.hh             |  2 +-
+ src/hb-ot-layout-common.hh                 | 22 ++++-----
+ src/hb-ot-layout-gpos-table.hh             |  2 +-
+ src/hb-ot-layout-gsub-table.hh             | 72 +++++++++++++++---------------
+ src/hb-ot-layout-jstf-table.hh             |  2 +-
+ src/hb-ot-math-table.hh                    |  4 +-
+ src/hb-ot-shape-complex-arabic-fallback.hh | 14 +++---
+ src/hb-ot-vorg-table.hh                    |  2 +-
+ 18 files changed, 103 insertions(+), 103 deletions(-)
+
+commit bf08611044d83b6f5d6dec443f5216db259b4085
+Author: Ebrahim Byagowi <ebrahim@gnu.org>
+Date:   Sat Sep 14 10:35:08 2019 +0430
+
+    [ci] Update and compile cmake/amalgam on macOS bot
+
+ .circleci/config.yml | 7 ++++---
+ 1 file changed, 4 insertions(+), 3 deletions(-)
+
+commit 229ef1d29d5c7a370ebb10a1131c04719f34dc81
 Author: Behdad Esfahbod <behdad@behdad.org>
-Date:   Wed Feb 6 13:36:52 2019 -0800
+Date:   Tue Sep 10 10:31:07 2019 -0700
 
-    Merge pull request #1571 from kencu/cleanostests
+    Rename Fixed to HBFixed
     
-    hb-coretext.cc: clean up macosx test
+    Fixes(!!) https://github.com/harfbuzz/harfbuzz/issues/1966
 
-commit 7859decdd02f65dfb3da07bd95742b14b4697638
-Author: Ken Cunningham <kencu@macports.org>
-Date:   Tue Feb 5 20:26:49 2019 -0800
+ src/hb-aat-fdsc-table.hh        |  4 ++--
+ src/hb-aat-layout-just-table.hh | 20 ++++++++++----------
+ src/hb-aat-layout-trak-table.hh |  8 ++++----
+ src/hb-open-type.hh             |  4 ++--
+ src/hb-ot-post-table.hh         |  2 +-
+ src/hb-ot-stat-table.hh         | 14 +++++++-------
+ src/hb-ot-var-fvar-table.hh     | 16 ++++++++--------
+ 7 files changed, 34 insertions(+), 34 deletions(-)
 
-    hb-coretext.cc: clean up macosx test
-    
-    TARGET_OS_OSX was introduced only in late OS versions
-    so always returns as "0" on older systems.
-    
-    if !TARGET_OS_IPHONE can work, as it returns as !0 on older
-    systems where TARGET_OS_IPHONE is not defined, but is not
-    specific
-    
-    if TARGET_OS_MAC && !(defined(TARGET_OS_IPHONE) && TARGET_OS_IPHONE)
-    is both specific and accurate on all systems.
+commit 170b5dd856b1ba8f26e79863fe0c64a52eb68951
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Sun Sep 8 16:34:11 2019 -0400
 
- src/hb-coretext.cc | 10 +++++-----
- 1 file changed, 5 insertions(+), 5 deletions(-)
+    [aat] Minor
 
-commit 9328354a83252a8d8d74fe424ab3894d398b0bd0
-Author: Michiharu Ariza <ariza@adobe.com>
-Date:   Mon Feb 4 11:28:15 2019 -0800
+ src/hb-aat-layout-morx-table.hh | 14 +++++---------
+ 1 file changed, 5 insertions(+), 9 deletions(-)
 
-    separate CFF from TrueType in full font tests
+commit a0695687eb03bcf80c4dec19917127cdd8d8797d
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Sun Sep 8 16:32:12 2019 -0400
 
- ...eSansPro-Regular.default.1FC,21,41,20,62,63.otf | Bin
- .../SourceSansPro-Regular.default.61,62,63.otf     | Bin
- ...ourceSansPro-Regular.default.D7,D8,D9,DA,DE.otf | Bin
- ...subroutinize-retain-gids.1FC,21,41,20,62,63.otf | Bin
- ...Regular.desubroutinize-retain-gids.61,62,63.otf | Bin
- ...r.desubroutinize-retain-gids.D7,D8,D9,DA,DE.otf | Bin
- ...o-Regular.desubroutinize.1FC,21,41,20,62,63.otf | Bin
+    [aat] Minor
+
+ src/hb-aat-layout-morx-table.hh | 2 --
+ 1 file changed, 2 deletions(-)
+
+commit 4905a2198b4c47c12c6356f72ae0d2b178630d25
+Author: Ebrahim Byagowi <ebrahim@gnu.org>
+Date:   Mon Sep 9 12:36:12 2019 +0430
+
+    [number] Add static to hb-number-parser.hh functions
+
+ src/hb-number-parser.hh | 4 ++--
+ src/hb-number-parser.rl | 4 ++--
+ 2 files changed, 4 insertions(+), 4 deletions(-)
+
+commit 30e5cdfbf1ce2aadadf29ccfd0733355ced2d065
+Author: Ebrahim Byagowi <ebrahim@gnu.org>
+Date:   Mon Sep 9 00:28:16 2019 +0430
+
+    [number] Optimize _pow10 constants (#1963)
+
+ src/hb-number-parser.hh | 43 +++++++++++++++++++------------------------
+ src/hb-number-parser.rl | 31 +++++++++++++------------------
+ 2 files changed, 32 insertions(+), 42 deletions(-)
+
+commit 3f2cdf07a417f81aeeb1e296db493b6e02d76ba8
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Sun Sep 8 15:08:02 2019 -0400
+
+    Change HB_VAR_ARRAY to 1 again
+    
+    To fix MSVC bots, while I work on changing this to 0 permanently.
+
+ src/hb.hh | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 39cf8e21be2bf69717cf60a339b3ad26c6f7985b
+Author: Ebrahim Byagowi <ebrahim@gnu.org>
+Date:   Sat Sep 7 15:27:30 2019 +0430
+
+    [number] Add overflow checks used to be done in parse_bcd
+    
+    Which were removed in 1083df8
+
+ src/hb-number-parser.hh | 60 +++++++++++++++++++++++++++++++++----------------
+ src/hb-number-parser.rl | 38 ++++++++++++++++++++++++-------
+ 2 files changed, 71 insertions(+), 27 deletions(-)
+
+commit 47d82713a144e06e00a486b3aa7d3934d62d68fd
+Author: Ebrahim Byagowi <ebrahim@gnu.org>
+Date:   Fri Sep 6 20:33:10 2019 +0430
+
+    Replace strtod with a ragel implementation
+    
+    Use a ragel based number parser when strtod_l couldn't be found
+    as libc's strtod may is locale sensetivity which we need to not.
+
+ src/Makefile.sources    |   2 +
+ src/hb-number-parser.hh | 223 ++++++++++++++++++++++++++++++++++++++++++++++++
+ src/hb-number-parser.rl | 122 ++++++++++++++++++++++++++
+ src/hb-number.cc        |   3 +-
+ src/test-number.cc      |  30 +++++++
+ 5 files changed, 379 insertions(+), 1 deletion(-)
+
+commit 80613e5b9ee31125f4390012719e6f39970118d3
+Author: Ebrahim Byagowi <ebrahim@gnu.org>
+Date:   Sat Sep 7 14:25:54 2019 +0430
+
+    Minor, remove unused header
+
+ src/hb-common.cc | 3 ---
+ 1 file changed, 3 deletions(-)
+
+commit 5902198cee9b9939ae310f459f9f18f5f1b07424
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Fri Sep 6 21:36:31 2019 -0400
+
+    [kerx] Fix offset issue in kern format 2
+    
+    Fixes tests with HB_VAR_ARRAY != 1, as done in previous commit.
+
+ src/hb-aat-layout-common.hh     | 2 +-
+ src/hb-aat-layout-kerx-table.hh | 2 +-
+ 2 files changed, 2 insertions(+), 2 deletions(-)
+
+commit 861547d5315be4cb22f3a1e7cd59696d8657ca49
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Fri Sep 6 16:55:00 2019 -0400
+
+    Change HB_VAR_ARRAY from 1 to 0
+    
+    Going to see which compilers it breaks and special-case those...
+
+ src/hb.hh | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+commit 0e294c455e7f2e50172f65463ab016f1372d4c59
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Fri Sep 6 16:54:27 2019 -0400
+
+    Rename VAR to HB_VAR_ARRAY
+
+ src/hb-machinery.hh        | 2 +-
+ src/hb-open-type.hh        | 8 ++++----
+ src/hb-ot-cff-common.hh    | 6 +++---
+ src/hb-ot-cff1-table.hh    | 4 ++--
+ src/hb-ot-layout-common.hh | 2 +-
+ src/hb-ot-maxp-table.hh    | 2 +-
+ src/hb-string-array.hh     | 2 +-
+ src/hb.hh                  | 2 +-
+ 8 files changed, 14 insertions(+), 14 deletions(-)
+
+commit c379faed2bcca1cc1a81b0de132fc3c4f7f7a080
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Fri Sep 6 16:41:12 2019 -0400
+
+    Fix a few struct size declarations
+    
+    Was wrong.  As excercised by defining VAR to other than 1 in hb.hh.
+
+ src/hb-aat-layout-feat-table.hh | 2 +-
+ src/hb-ot-cff-common.hh         | 2 +-
+ src/hb-ot-color-sbix-table.hh   | 2 +-
+ src/hb-ot-layout-common.hh      | 2 +-
+ 4 files changed, 4 insertions(+), 4 deletions(-)
+
+commit 7d4da8b86242d5a541e501937ddf321716b43f07
+Author: Evgeniy Reizner <razrfalcon@gmail.com>
+Date:   Fri Sep 6 19:24:32 2019 +0300
+
+    Remove duplicated tests from test-ot-tag (#1958)
+
+ test/api/test-ot-tag.c | 3 ---
+ 1 file changed, 3 deletions(-)
+
+commit 3aceee2527ad921e0d589e42a1fe451e0fc67ee0
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Fri Sep 6 12:17:18 2019 -0400
+
+    Revert "[null] Silence undefined-behavior complaints with too-small null bytes"
+    
+    This reverts commit 911c76abcdfe89770b252eb0d4eb621c0db00ad5.
+    
+    Broke tests.  I'm not sure I understand why.  At any rate, this was a
+    bad way to fix.  I'll look into understanding as well as better fix.
+
+ src/hb-null.hh | 6 ------
+ 1 file changed, 6 deletions(-)
+
+commit 911c76abcdfe89770b252eb0d4eb621c0db00ad5
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Fri Sep 6 11:53:11 2019 -0400
+
+    [null] Silence undefined-behavior complaints with too-small null bytes
+    
+    Fixes https://bugzilla.mozilla.org/show_bug.cgi?id=1577584
+
+ src/hb-null.hh | 6 ++++++
+ 1 file changed, 6 insertions(+)
+
+commit 3c81246f66585edd8ee4515d226b133c290e9d7c
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Sun Sep 1 19:25:50 2019 -0500
+
+    [subset] Use newer iter tools in SinglePosFormat1
+
+ src/hb-ot-layout-gpos-table.hh | 8 ++------
+ 1 file changed, 2 insertions(+), 6 deletions(-)
+
+commit 9510e918f72d2496f5e2ec84c58e79af944c8a0b
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Sun Sep 1 16:25:33 2019 -0500
+
+    [iter] Partialize hb_zip()
+
+ src/hb-iter.hh | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 52d19ba4591e822708e52a8fc96d9821fe2668f4
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Sun Sep 1 19:42:08 2019 -0500
+
+    Minor
+
+ test/subset/Makefile.am | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+commit cad698568a36ea6c929b4c888bd5e8aafe8d39e3
+Author: Ebrahim Byagowi <ebrahim@gnu.org>
+Date:   Wed Sep 4 10:59:19 2019 +0430
+
+    Use roundf to fix cast to int difference of msys2 w64
+
+ src/test-number.cc | 14 +++++++-------
+ 1 file changed, 7 insertions(+), 7 deletions(-)
+
+commit 88c73359da3f7078d02f27087790c7109ab4d248
+Author: Ebrahim Byagowi <ebrahim@gnu.org>
+Date:   Wed Sep 4 11:16:18 2019 +0430
+
+    Check roundf availibity in autotools
+    
+    Hmm, not sure how I missed it.
+
+ configure.ac | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 1083df8b80b08aa1a4f2dabfe414aaa4a0ec8aa1
+Author: Ebrahim Byagowi <ebrahim@gnu.org>
+Date:   Wed Sep 4 01:22:21 2019 +0430
+
+    Use hb_parse_double in CFF::dict_opset_t::parse_bcd
+
+ src/Makefile.sources             |   2 +
+ src/hb-cff-interp-dict-common.hh | 136 +++++++++------------------------------
+ 2 files changed, 31 insertions(+), 107 deletions(-)
+
+commit 57f88e11d4c48f40a2e56625a54bdfed4aae601a
+Author: Ebrahim Byagowi <ebrahim@gnu.org>
+Date:   Wed Sep 4 01:20:50 2019 +0430
+
+    [number] Turn hb_parse_float into hb_parse_double
+
+ src/hb-common.cc   |  6 +++++-
+ src/hb-number.cc   | 16 ++++++++--------
+ src/hb-number.hh   |  4 ++--
+ src/test-number.cc | 44 ++++++++++++++++++++++----------------------
+ 4 files changed, 37 insertions(+), 33 deletions(-)
+
+commit 65690b5a4bf1186a072e8e918c5e01464f918d46
+Author: Ebrahim Byagowi <ebrahim@gnu.org>
+Date:   Tue Sep 3 23:09:47 2019 +0430
+
+    [number] Add whole buffer check and test it
+
+ src/hb-algs.hh             |  6 ++----
+ src/hb-buffer-serialize.cc | 12 ++++--------
+ src/hb-number.cc           | 39 ++++++++++++++++++++++++---------------
+ src/hb-number.hh           |  9 ++++++---
+ src/test-number.cc         | 19 ++++++++++++++++---
+ 5 files changed, 52 insertions(+), 33 deletions(-)
+
+commit 3661eb6105a33a763736d8dc4a2cd95c01aa4332
+Author: Ebrahim Byagowi <ebrahim@gnu.org>
+Date:   Tue Sep 3 19:43:14 2019 +0430
+
+    Don't check null terminaion of source in hb_codepoint_parse
+    
+    This isn't what intended originally, just checking if consumed
+    all the buffer is enough.
+
+ src/hb-algs.hh     |  4 ++--
+ src/test-number.cc | 32 +++++++++++++++++++++++++++++++-
+ 2 files changed, 33 insertions(+), 3 deletions(-)
+
+commit 3a162727501ad0c56d5d6561cace115d858eacb7
+Author: Ebrahim Byagowi <ebrahim@gnu.org>
+Date:   Tue Sep 3 17:19:33 2019 +0430
+
+    [test] resolve msvc complain on signedness comparing
+
+ src/test-number.cc | 14 +++++++-------
+ 1 file changed, 7 insertions(+), 7 deletions(-)
+
+commit 005389beb5a28e2a94b40d0bb8229e9598b84b1d
+Author: Ebrahim Byagowi <ebrahim@gnu.org>
+Date:   Tue Sep 3 17:00:46 2019 +0430
+
+    Use hb_parse_uint in deserializer token parser
+
+ src/hb-buffer-serialize.cc | 9 ++++++---
+ 1 file changed, 6 insertions(+), 3 deletions(-)
+
+commit 3d5b1df7ab689871db37ec9a2f5b1ff1665fdb20
+Author: Ebrahim Byagowi <ebrahim@gnu.org>
+Date:   Tue Sep 3 16:58:16 2019 +0430
+
+    [number] Add test
+
+ src/Makefile.am    |   6 +-
+ src/test-number.cc | 180 +++++++++++++++++++++++++++++++++++++++++++++++++++++
+ 2 files changed, 185 insertions(+), 1 deletion(-)
+
+commit b5e6805ee777347ae13ba0133ca0d64252ef9d55
+Author: Ebrahim Byagowi <ebrahim@gnu.org>
+Date:   Tue Sep 3 15:23:40 2019 +0430
+
+    [number] Minor tweak on parser related codes
+
+ src/hb-algs.hh             |  6 +++---
+ src/hb-buffer-serialize.cc |  6 ++----
+ src/hb-common.cc           | 14 ++++++--------
+ src/hb-number.cc           |  6 ++----
+ 4 files changed, 13 insertions(+), 19 deletions(-)
+
+commit e2cecf1f34fe1cc62fd8260172f9bd694a17fac5
+Author: Ebrahim Byagowi <ebrahim@gnu.org>
+Date:   Tue Sep 3 15:14:21 2019 +0430
+
+    [number] Remove parsing code duplication of the calls using lambda
+
+ src/hb-number.cc | 57 +++++++++++++++++++-------------------------------------
+ 1 file changed, 19 insertions(+), 38 deletions(-)
+
+commit a77bb7eb41d34b19a672bb4ede038cc1b19a3945
+Author: Ebrahim Byagowi <ebrahim@gnu.org>
+Date:   Tue Sep 3 14:49:14 2019 +0430
+
+    Move hb_codepoint_parse to hb_parse_uint
+
+ src/hb-algs.hh             | 20 +++++++++-----------
+ src/hb-buffer-serialize.cc |  1 -
+ src/hb-common.cc           |  1 -
+ src/hb-number.cc           | 26 +++++++++++++++++++++++---
+ src/hb-number.hh           |  3 +++
+ src/hb.hh                  |  3 ++-
+ 6 files changed, 37 insertions(+), 17 deletions(-)
+
+commit 43372fbb5afe31ea1e66d450f29de718b6190828
+Author: Ebrahim Byagowi <ebrahim@gnu.org>
+Date:   Tue Sep 3 01:02:40 2019 +0430
+
+    Merge and aggregate number parsing logics to form hb-number
+
+ src/Makefile.sources       |   2 +
+ src/harfbuzz.cc            |   1 +
+ src/hb-buffer-serialize.cc |  41 +++++---------
+ src/hb-common.cc           | 121 +++------------------------------------
+ src/hb-number.cc           | 138 +++++++++++++++++++++++++++++++++++++++++++++
+ src/hb-number.hh           |  35 ++++++++++++
+ 6 files changed, 197 insertions(+), 141 deletions(-)
+
+commit d50d2fcbc7233f0473493e17ab3fb243d8d30edd
+Author: Ebrahim Byagowi <ebrahim@gnu.org>
+Date:   Tue Sep 3 05:02:06 2019 +0430
+
+    Fallback if roundf didn't exist, like in dietlibc (#1953)
+
+ CMakeLists.txt | 2 +-
+ src/hb.hh      | 9 +++++++++
+ 2 files changed, 10 insertions(+), 1 deletion(-)
+
+commit d3b984d3790d61931d4427ad7c0ae6547f8f1076
+Author: Ebrahim Byagowi <ebrahim@gnu.org>
+Date:   Mon Sep 2 18:18:25 2019 +0430
+
+    Revert in-house pow10 (d80a3ea) and fix oss-fuzz/16922
+    
+    Probably can be fixed but merging it was wrong so let's revert.
+
+ src/hb-cff-interp-dict-common.hh                   |  37 ++-------------------
+ ...ase-minimized-hb-subset-fuzzer-5728664968232960 | Bin 0 -> 28 bytes
+ 2 files changed, 3 insertions(+), 34 deletions(-)
+
+commit 41d6e95b0d47c874b73b314cd147e6ea8ec5ddfb
+Author: Ebrahim Byagowi <ebrahim@gnu.org>
+Date:   Mon Sep 2 01:41:48 2019 +0430
+
+    [subset] Use internal API of hb_set_t
+
+ src/hb-subset.cc | 7 +++----
+ 1 file changed, 3 insertions(+), 4 deletions(-)
+
+commit 8ccf328d548a51140e22fe61ba6fdae3f7194aa2
+Author: Ebrahim Byagowi <ebrahim@gnu.org>
+Date:   Mon Sep 2 00:02:06 2019 +0430
+
+    [subset] Run once for a tag
+
+ src/hb-subset.cc | 5 ++++-
+ 1 file changed, 4 insertions(+), 1 deletion(-)
+
+commit 0954c8f7a003b4130cfdc1b3f29db8c57953a78f
+Author: Khaled Hosny <khaledhosny@eglug.org>
+Date:   Sun Sep 1 17:09:08 2019 +0200
+
+    [ft] Prefer symbol cmap subtable if found (#1948)
+    
+    Similar to commit d304d60e4d49df14ed85d6646680085f27bafbf2 for ot-font.
+
+ src/hb-ft.cc | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+commit 4375858792f3e3cc2fae72c3ae3327f52884f780
+Author: Ebrahim Byagowi <ebrahim@gnu.org>
+Date:   Sun Sep 1 15:13:05 2019 +0430
+
+    [editorconfig] Treat Ragel files also as C sources
+
+ .editorconfig | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit d80a3ea983534e291aee273dba5b1c6e889dadfa
+Author: Ebrahim Byagowi <ebrahim@gnu.org>
+Date:   Sun Sep 1 14:05:16 2019 +0430
+
+    [cff] Implement in-house power of 10
+    
+    A minimal power only for natural numbers exponents of ten, for portability.
+    
+    Found the idea in Tcl/Tk but wrote it myself after weeks and it turned out
+    being a different implementation, reverse direction, constexpr, etc.
+
+ src/hb-cff-interp-dict-common.hh | 37 ++++++++++++++++++++++++++++++++++---
+ 1 file changed, 34 insertions(+), 3 deletions(-)
+
+commit f441a7c00837fbe7843df6faedd5f6383c2258c3
+Author: Ebrahim Byagowi <ebrahim@gnu.org>
+Date:   Sun Sep 1 02:18:09 2019 +0430
+
+    Don't allow reference blob be accessed using empty tag in hb_face_reference_table (#1947)
+
+ src/hb-face.cc   | 3 +++
+ src/hb-subset.cc | 5 -----
+ 2 files changed, 3 insertions(+), 5 deletions(-)
+
+commit c9eb913f4cf3d9d4a28059c7ecf7145ad3c49c65
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Sat Aug 31 15:21:02 2019 -0500
+
+    [iter] Simplify hb_chop()
+
+ src/hb-iter.hh | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+commit 67ec9fa9e48714f595ab17bb8a673b5ee7c73aa8
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Sat Aug 31 14:51:49 2019 -0500
+
+    [iter] Add hb_chop()
+
+ src/hb-iter.hh   | 14 ++++++++++++++
+ src/test-iter.cc |  2 +-
+ 2 files changed, 15 insertions(+), 1 deletion(-)
+
+commit 5828d8e83c023547f0add77b6413967056c2a13c
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Sat Aug 31 14:36:44 2019 -0500
+
+    [iter] Add hb_take() specialization for arrays
+
+ src/hb-iter.hh | 11 +++++++++++
+ 1 file changed, 11 insertions(+)
+
+commit 398b296f3b205daa8964de1a63957efeb59f6bdf
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Sat Aug 31 12:44:24 2019 -0500
+
+    [iter] Add hb_len()
+
+ src/hb-iter.hh   | 8 ++++++++
+ src/test-iter.cc | 2 +-
+ 2 files changed, 9 insertions(+), 1 deletion(-)
+
+commit 875131d47854c162c1d0a39a5c0f8f8d0c5f24e0
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Sat Aug 31 12:42:52 2019 -0500
+
+    [iter] Add hb_take()
+
+ src/hb-iter.hh   | 12 ++++++++++--
+ src/test-iter.cc |  1 +
+ 2 files changed, 11 insertions(+), 2 deletions(-)
+
+commit 1f88dae9f54d18cd740f149d020b2bb435dc9378
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Sat Aug 31 12:24:42 2019 -0500
+
+    [iter] Make iota() accept invokable for increasing to next item
+
+ src/hb-iter.hh   | 21 ++++++++++++++++-----
+ src/test-iter.cc |  1 +
+ 2 files changed, 17 insertions(+), 5 deletions(-)
+
+commit 3bc86fb237b668e738a78397be04c603e7cf083b
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Fri Aug 30 16:39:52 2019 -0500
+
+    [algs] Fix hb_inc/dec signature
+
+ src/hb-algs.hh   | 5 +++--
+ src/test-algs.cc | 4 ++++
+ 2 files changed, 7 insertions(+), 2 deletions(-)
+
+commit b1378d8a217a53e17562abebee22276e09528f8c
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Fri Aug 30 12:10:45 2019 -0500
+
+    [iter] Add hb_repeat()
+
+ src/hb-iter.hh   | 37 +++++++++++++++++++++++++++++++++----
+ src/test-iter.cc |  3 +++
+ 2 files changed, 36 insertions(+), 4 deletions(-)
+
+commit 966a18b92a8b95d8024ae67bc237eeffe5019711
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Fri Aug 30 12:07:17 2019 -0500
+
+    [iter] Remove some &&
+
+ src/hb-iter.hh | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+commit de45775c37873dd5818058dfe316cc0e98590334
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Fri Aug 30 12:02:46 2019 -0500
+
+    [iter] Use hb_ridentity instead of lazy +
+
+ src/hb-iter.hh | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+commit ce4d63beec08995aaa6b8b45f7986f074a73f295
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Fri Aug 30 11:59:50 2019 -0500
+
+    [iter] Separate hb_iota implementation from hb_range
+
+ src/hb-iter.hh | 29 +++++++++++++++++++++++++++--
+ 1 file changed, 27 insertions(+), 2 deletions(-)
+
+commit 814dc3cbe5a5e51b48cb962a6f7053797bbb8e0d
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Fri Aug 30 10:20:30 2019 -0500
+
+    [iter] Rename
+    
+    Moving towards making iota useful for non-integers.
+
+ src/hb-iter.hh | 35 ++++++++++++++++++-----------------
+ 1 file changed, 18 insertions(+), 17 deletions(-)
+
+commit 2d5643aed4a5a4bc3ea129d4af3dcbe7af7b9995
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Fri Aug 30 09:51:22 2019 -0500
+
+    [algs] Add hb_inc() and hb_dec())
+
+ src/hb-algs.hh | 12 ++++++++++++
+ 1 file changed, 12 insertions(+)
+
+commit 7eafe94705bb818aac71fbc142158a22da622d19
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Fri Aug 30 09:40:40 2019 -0500
+
+    Revert "[array] Add chop()"
+    
+    This reverts commit 545fe9d9f0870568c40c17591f3f224c228feba6.
+    
+    Breaks gcc 4.8 and MSVC all versions.
+    
+    Will add hb_chop() that works on all iterators instead.
+
+ src/hb-array.hh | 14 --------------
+ 1 file changed, 14 deletions(-)
+
+commit 28c8dcb53f0af0dd3f4e7909285e67865a10b67b
+Author: Ebrahim Byagowi <ebrahim@gnu.org>
+Date:   Sat Aug 31 12:27:14 2019 +0430
+
+    [subset] minor
+
+ src/hb-subset.cc | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 545fe9d9f0870568c40c17591f3f224c228feba6
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Thu Aug 29 15:48:21 2019 -0700
+
+    [array] Add chop()
+    
+    Takes n, and returns iterator of iterators that contain up to
+    n items each.  Basically cuts the array into subarrays of size n.
+    The last sub-array might contain fewer.
+    
+    Ideally this should become a generic iter tool, not array-specific,
+    so we can use it in GPOS to chop a value matrix into rows and elements.
+
+ src/hb-array.hh | 14 ++++++++++++++
+ 1 file changed, 14 insertions(+)
+
+commit c72589f13f24ca24a0613f7d9bc28b7fe1ef25c0
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Thu Aug 29 15:45:21 2019 -0700
+
+    [iter] Change item_size to get_item_size()
+    
+    By moving access to hb_static_size(Type) into a function instead of
+    a class-const, we can refer to iter types of incomplete types, which
+    come handy when a method of hb_array_t wants to return iterator
+    of hb_array_t.  That kind of stuff.   Next commit needs this to
+    build on clang...
+
+ src/hb-array.hh | 8 ++++----
+ src/hb-iter.hh  | 4 ++--
+ 2 files changed, 6 insertions(+), 6 deletions(-)
+
+commit d58e248df62457bdc8a5bab743e5de26c6fc57be
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Thu Aug 29 15:23:48 2019 -0700
+
+    [array] Add truncate() method
+
+ src/hb-array.hh | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+commit a06edf1430ba73d24104fce5406f2bc787ce5f11
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Thu Aug 29 15:21:18 2019 -0700
+
+    [array] Use injected class name more
+
+ src/hb-array.hh | 24 ++++++++++++------------
+ 1 file changed, 12 insertions(+), 12 deletions(-)
+
+commit e0e0c8c10948212e97426e987b6f296dc4270c43
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Thu Aug 29 14:58:16 2019 -0700
+
+    Minor
+
+ src/hb-ot-layout-gpos-table.hh | 6 ++++--
+ 1 file changed, 4 insertions(+), 2 deletions(-)
+
+commit 0313ef86e32a217e14950d46a3c3b98362a53dee
+Author: qxliu76 <48925186+qxliu76@users.noreply.github.com>
+Date:   Thu Aug 29 14:09:05 2019 -0700
+
+    bug fix in optimizing coverage table format (#1942)
+    
+    We are comparing number of shorts, NOT number of bytes.
+
+ src/hb-ot-layout-common.hh | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 38f95baf6b7a74547906e8e813c826ee8f8c272f
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Thu Aug 29 13:40:46 2019 -0700
+
+    [subset] in SingleSubst subsetting, check for substitute in glyphset
+    
+    That matches what fonttools does and allows for specifying exact
+    glyphset for subset.
+
+ src/hb-ot-layout-gsub-table.hh | 8 ++++++--
+ 1 file changed, 6 insertions(+), 2 deletions(-)
+
+commit 499029644f35be7feedca7edf4610b2594855f01
+Author: Ebrahim Byagowi <ebrahim@gnu.org>
+Date:   Thu Aug 29 15:09:39 2019 +0430
+
+    [gsub] Fix clang's semicolon complains
+
+ src/hb-ot-layout-gsub-table.hh | 8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+commit 28620310b8a86092074d5a1c40c87fdc9a91ba61
+Author: Ebrahim Byagowi <ebrahim@gnu.org>
+Date:   Thu Aug 29 14:55:54 2019 +0430
+
+    [test] Avoid alloca use as clang complain
+    
+    Fixes https://circleci.com/gh/harfbuzz/harfbuzz/108171 complain
+
+ test/api/test-ot-color.c | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+commit 875985cd481f1609d10ad0472f1e77af075c93bc
+Author: Ebrahim Byagowi <ebrahim@gnu.org>
+Date:   Thu Aug 29 14:51:22 2019 +0430
+
+    [subset] Don't allow malicious fonts to insert unlimited table headers
+    
+    Fixes https://crbug.com/oss-fuzz/16810
+
+ src/hb-subset.cc                                       |   5 +++++
+ ...estcase-minimized-hb-subset-fuzzer-5675720390475776 | Bin 0 -> 299037 bytes
+ 2 files changed, 5 insertions(+)
+
+commit dc9222b1dd197ba50f7b63eb97f3fe0891a7b7b5
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Wed Aug 28 15:38:46 2019 -0700
+
+    [subset] Implement AlternateSubst subsetting
+
+ src/hb-ot-layout-gsub-table.hh | 61 +++++++++++++++++++++++++++++++++++++-----
+ 1 file changed, 55 insertions(+), 6 deletions(-)
+
+commit 23681b6da4368895fc049beda5a79af58aad8d69
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Wed Aug 28 15:30:37 2019 -0700
+
+    Minor
+
+ src/hb-ot-layout-gsub-table.hh | 21 ++++++++-------------
+ 1 file changed, 8 insertions(+), 13 deletions(-)
+
+commit 33c8e2303c23e8dfacb79ac15d8a0e6c7f866c89
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Wed Aug 28 15:25:55 2019 -0700
+
+    [subset] Implement MultipleSubst subsetting
+
+ src/hb-ot-layout-gsub-table.hh | 50 ++++++++++++++++++++++++++++++++++++++++--
+ 1 file changed, 48 insertions(+), 2 deletions(-)
+
+commit 5c43a7ba7e4cac229593f9cbe1017d3c55b111ac
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Wed Aug 28 15:09:58 2019 -0700
+
+    [GSUB] Use dagger in Ligature::intersects()
+
+ src/hb-ot-layout-gsub-table.hh | 8 +-------
+ 1 file changed, 1 insertion(+), 7 deletions(-)
+
+commit b8c642c1f597fb28ef323ac3cd78541eb462a2f7
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Wed Aug 28 15:06:45 2019 -0700
+
+    Minor
+
+ src/hb-ot-layout-gsub-table.hh | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit dc2c9aa0c398ac068e1385fffe1fb2b28c80d099
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Wed Aug 28 15:05:49 2019 -0700
+
+    Rename
+
+ src/hb-open-type.hh | 10 +++++-----
+ 1 file changed, 5 insertions(+), 5 deletions(-)
+
+commit bc5ef765a874ecd9fc0634dccf0848d1ee839c9a
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Wed Aug 28 14:51:28 2019 -0700
+
+    [subset] Subset ligature substitutes!
+    
+    Test with:
+    
+    $ ./hb-subset -o out.ttf NotoSansArabic-Regular.ttf --drop-tables=  سلام && ./hb-view out.ttf سلام
+
+ src/hb-ot-layout-gsub-table.hh | 79 ++++++++++++++++++++++++++++++++++++++++--
+ 1 file changed, 76 insertions(+), 3 deletions(-)
+
+commit 42d887bd221879f57ef939838d4f72bf38268943
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Wed Aug 28 14:47:14 2019 -0700
+
+    Beef up HeadlessArrayOf<>
+    
+    Should be merged with ArrayOf...
+    https://github.com/harfbuzz/harfbuzz/issues/1937
+
+ src/hb-open-type.hh | 37 ++++++++++++++++++++++++++++++-------
+ 1 file changed, 30 insertions(+), 7 deletions(-)
+
+commit 3ca809e3623e59b9a99bc0b9e5d10b02238bba3c
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Wed Aug 28 13:49:35 2019 -0700
+
+    Add ArrayOf::pop()
+
+ src/hb-open-type.hh | 2 ++
+ 1 file changed, 2 insertions(+)
+
+commit 307bd6d79f11eb175f06c08c321947a447496291
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Wed Aug 28 13:49:17 2019 -0700
+
+    Add arithmetic operators to IntType<>
+
+ src/hb-open-type.hh | 8 ++++++++
+ 1 file changed, 8 insertions(+)
+
+commit 2e1d00c85bba98f08a728c4f6f8112d5a25d8062
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Wed Aug 28 13:49:04 2019 -0700
+
+    [debug] Minor
+
+ src/hb-debug.hh | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+commit 062cad5e28574f9f004f917afa7d010fa68fdad0
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Wed Aug 28 13:33:08 2019 -0700
+
+    Add ArrayOf::serialize_append
+
+ src/hb-open-type.hh | 12 ++++++++++++
+ 1 file changed, 12 insertions(+)
+
+commit b66076812d067f893a5a422af2656916ff479d8f
+Author: Adrian Wong <adrianwjw@gmail.com>
+Date:   Wed Aug 28 21:31:27 2019 +1000
+
+    Adjustments to the generated Indic table output (#1936)
+    
+    * Add empty parentheses after print call
+    
+    * Minor: newlines. Move #pragma pop down one; #endif up one
+    
+    * Adjust #define ISC/IMC output
+    
+    * Regenerate Indic table
+
+ src/gen-indic-table.py                 |  21 ++++---
+ src/hb-ot-shape-complex-indic-table.cc | 109 +++++++++++++++++----------------
+ 2 files changed, 70 insertions(+), 60 deletions(-)
+
+commit 4ef08dbce1a9acd7e941168245c96e010248ecb6
+Author: Ebrahim Byagowi <ebrahim@gnu.org>
+Date:   Tue Aug 27 14:49:46 2019 +0430
+
+    Use hb_bytes_t as<T> in hb_blob_t
+
+ src/hb-blob.hh | 8 ++------
+ 1 file changed, 2 insertions(+), 6 deletions(-)
+
+commit dce42cef2b769379a0690053da0e7467ff086195
+Author: Ebrahim Byagowi <ebrahim@gnu.org>
+Date:   Tue Aug 27 14:32:05 2019 +0430
+
+    [glyf] Move GlyphHeader::from_bytes to hb_bytes_t, introduce .as<T> ()
+
+ src/hb-array.hh         |  6 ++++++
+ src/hb-ot-glyf-table.hh | 24 +++++++++---------------
+ 2 files changed, 15 insertions(+), 15 deletions(-)
+
+commit 6e82d59b4f72e8f2ff1830fb384907dcba95962a
+Author: Ebrahim Byagowi <ebrahim@gnu.org>
+Date:   Tue Aug 27 12:33:42 2019 +0430
+
+    [glyf] Revert the way indexToLocFormat is set
+
+ src/hb-ot-glyf-table.hh | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 88e9db19d29480fadcd4f49f0f4d9029ac64b429
+Author: Ebrahim Byagowi <ebrahim@gnu.org>
+Date:   Tue Aug 27 02:44:26 2019 +0430
+
+    [subset] Remove subset table size assertion
+    
+    As https://github.com/harfbuzz/harfbuzz/pull/1930#issuecomment-525036802
+
+ src/hb-subset.cc | 1 -
+ 1 file changed, 1 deletion(-)
+
+commit a0b4ac4dce392326284138fc47cf3741e2798e21
+Author: Ebrahim Byagowi <ebrahim@gnu.org>
+Date:   Sat Aug 24 17:57:14 2019 +0430
+
+    Turn 8 spaces to tab across the project
+    
+    According to the current code style of the project
+
+ src/hb-aat-layout-kerx-table.hh    |  12 +-
+ src/hb-aat-layout-morx-table.hh    |  16 +--
+ src/hb-aat-layout-trak-table.hh    |   6 +-
+ src/hb-array.hh                    |   4 +-
+ src/hb-blob.cc                     |   4 +-
+ src/hb-buffer-serialize.cc         |   2 +-
+ src/hb-buffer.cc                   |  22 ++--
+ src/hb-buffer.h                    |   4 +-
+ src/hb-common.cc                   |   4 +-
+ src/hb-coretext.cc                 |  50 ++++----
+ src/hb-dispatch.hh                 |   2 +-
+ src/hb-font.cc                     |  16 +--
+ src/hb-ft.cc                       |   2 +-
+ src/hb-graphite2.cc                |  10 +-
+ src/hb-iter.hh                     |   4 +-
+ src/hb-kern.hh                     |   6 +-
+ src/hb-machinery.hh                |   2 +-
+ src/hb-object.hh                   |   2 +-
+ src/hb-open-file.hh                |   4 +-
+ src/hb-open-type.hh                |   2 +-
+ src/hb-ot-cmap-table.hh            | 252 ++++++++++++++++++-------------------
+ src/hb-ot-color-cbdt-table.hh      |   2 +-
+ src/hb-ot-color-cpal-table.hh      |   2 +-
+ src/hb-ot-color-sbix-table.hh      |   8 +-
+ src/hb-ot-font.cc                  |  16 +--
+ src/hb-ot-hmtx-table.hh            |  62 ++++-----
+ src/hb-ot-layout-common.hh         |  16 +--
+ src/hb-ot-layout-gdef-table.hh     |   4 +-
+ src/hb-ot-layout-gpos-table.hh     |  74 +++++------
+ src/hb-ot-layout.cc                |  26 ++--
+ src/hb-ot-layout.h                 |  18 +--
+ src/hb-ot-map.cc                   |   2 +-
+ src/hb-ot-maxp-table.hh            |   2 +-
+ src/hb-ot-name-table.hh            |   8 +-
+ src/hb-ot-name.cc                  |   2 +-
+ src/hb-ot-shape-complex-arabic.cc  |  14 +--
+ src/hb-ot-shape-complex-hangul.cc  |  12 +-
+ src/hb-ot-shape-complex-indic.cc   |  34 ++---
+ src/hb-ot-shape-complex-khmer.cc   |   2 +-
+ src/hb-ot-shape-complex-myanmar.cc |   2 +-
+ src/hb-ot-shape-complex-use.cc     |   2 +-
+ src/hb-ot-shape-fallback.cc        |  46 +++----
+ src/hb-ot-shape-normalize.cc       |   4 +-
+ src/hb-ot-shape.cc                 |  16 +--
+ src/hb-ot-stat-table.hh            |   4 +-
+ src/hb-ot-var-avar-table.hh        |   2 +-
+ src/hb-ot-var-fvar-table.hh        |   6 +-
+ src/hb-ot-vorg-table.hh            |  28 ++---
+ src/hb-pool.hh                     |   2 +-
+ src/hb-sanitize.hh                 |   6 +-
+ src/hb-set.hh                      |  36 +++---
+ src/hb-shape-plan.cc               |  50 ++++----
+ src/hb-subset-cff2.cc              |  18 +--
+ src/hb-subset-input.cc             |   2 +-
+ src/hb-subset-plan.cc              |  34 ++---
+ src/hb-subset-plan.hh              |   8 +-
+ src/hb-subset.h                    |   2 +-
+ src/hb-uniscribe.cc                |   8 +-
+ src/hb-utf.hh                      |   8 +-
+ src/hb-vector.hh                   |   2 +-
+ src/hb.hh                          |  12 +-
+ src/test-ot-color.cc               |   4 +-
+ src/test-unicode-ranges.cc         |   6 +-
+ test/api/hb-subset-test.h          |   6 +-
+ test/api/test-buffer.c             |   2 +-
+ test/api/test-object.c             |   2 +-
+ test/api/test-ot-math.c            | 132 +++++++++----------
+ test/api/test-unicode.c            |  16 +--
+ util/ansi-print.cc                 |  26 ++--
+ util/hb-fc-list.c                  |   2 +-
+ util/hb-fc.cc                      |   4 +-
+ util/hb-shape.cc                   |   2 +-
+ util/hb-subset.cc                  |  10 +-
+ util/helper-cairo-ansi.cc          |   4 +-
+ util/helper-cairo.cc               |   2 +-
+ util/options-subset.cc             |  26 ++--
+ util/options.cc                    |  50 ++++----
+ util/options.hh                    |   8 +-
+ 78 files changed, 662 insertions(+), 668 deletions(-)
+
+commit 269a120f137ca69ca83b6fa00bb6a0ff1a87ae3e
+Author: Ebrahim Byagowi <ebrahim@gnu.org>
+Date:   Sun Aug 25 20:37:00 2019 +0430
+
+    [subset] Raise the bar in new vs old table size
+    
+    https://crbug.com/oss-fuzz/16740
+    
+    This is actually an interesting thing that {h,v}mtx allocates as
+    much as a font pretends to have glyphs but the solution is not
+    that obvious as regular fonts can have less than actually containing
+    metrics in their {h,v}mtx. This change raises the bar to consider this
+    hmtx 4 byte for every glyph case.
+    
+    Initially we wanted to just find things allocating crazy amount of
+    memory but having the assert has led to interesting findings also
+    so let's don't remove the assert and see what we can find elsewhere.
+
+ src/hb-subset.cc                                          |   2 +-
+ ...z-testcase-minimized-hb-subset-fuzzer-5667673584697344 | Bin 0 -> 178 bytes
+ 2 files changed, 1 insertion(+), 1 deletion(-)
+
+commit 2f8e823331aca2c73b940f057f4b149a89af0502
+Author: Ebrahim Byagowi <ebrahim@gnu.org>
+Date:   Sun Aug 25 12:37:40 2019 +0430
+
+    [glyf] minor
+
+ src/hb-ot-glyf-table.hh | 5 ++---
+ 1 file changed, 2 insertions(+), 3 deletions(-)
+
+commit 07e467a30e2bab9731900d72dbf926dbe6fc6e1d
+Author: Ebrahim Byagowi <ebrahim@gnu.org>
+Date:   Sun Aug 25 00:36:58 2019 +0430
+
+    [glyf] Move GlyphHeader size checking to a static method
+
+ src/hb-ot-glyf-table.hh | 69 ++++++++++++++++++++++++++-----------------------
+ 1 file changed, 36 insertions(+), 33 deletions(-)
+
+commit 139d14dc899250cf06a8d03b70504687184d5c7f
+Author: Ebrahim Byagowi <ebrahim@gnu.org>
+Date:   Sat Aug 24 17:23:16 2019 +0430
+
+    [glyf] Move GlyphHeader related logics to its, making its fields protected
+
+ src/hb-ot-glyf-table.hh | 73 +++++++++++++++++++++++++------------------------
+ 1 file changed, 38 insertions(+), 35 deletions(-)
+
+commit d57819cbdbab18ccf20caa25cb72cd66efe30848
+Author: Ebrahim Byagowi <ebrahim@gnu.org>
+Date:   Sat Aug 24 16:26:42 2019 +0430
+
+    [glyf] format source
+
+ src/hb-ot-glyf-table.hh | 282 ++++++++++++++++++++++++++----------------------
+ 1 file changed, 154 insertions(+), 128 deletions(-)
+
+commit 2aef3013f3e6d71eacd0123f4faa63445034c32b
+Author: Ebrahim Byagowi <ebrahim@gnu.org>
+Date:   Sat Aug 24 02:59:18 2019 +0430
+
+    [subset] Consider instruction length place itself
+    
+    Now fixes https://crbug.com/oss-fuzz/16639 completely
+
+ src/hb-ot-glyf-table.hh | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+commit 922898c814b328712fac6c3259740804679dae11
+Author: Ebrahim Byagowi <ebrahim@gnu.org>
+Date:   Fri Aug 23 22:04:14 2019 +0430
+
+    [subset] Fail on table grow more than 16x+4096
+
+ src/hb-subset.cc | 1 +
+ 1 file changed, 1 insertion(+)
+
+commit 28aba780c4035cc85a31b778db0f5553c896dd6a
+Author: Ebrahim Byagowi <ebrahim@gnu.org>
+Date:   Fri Aug 23 16:47:15 2019 +0430
+
+    [subset] Fix blob leak of _subset2 when returns early
+    
+    Fixes https://crbug.com/oss-fuzz/16639
+
+ src/hb-subset.cc                                          |   2 ++
+ ...z-testcase-minimized-hb-subset-fuzzer-5754526379802624 | Bin 0 -> 288 bytes
+ 2 files changed, 2 insertions(+)
+
+commit 541f3c2d7dcae47eb55650082e372286369d4a55
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Fri Aug 23 12:25:58 2019 -0700
+
+    [debug] Fix extra semicolon issue
+    
+    https://github.com/harfbuzz/harfbuzz/issues/1923
+
+ src/hb-debug.hh | 8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+commit 4dcaca84115bf8de130fc2c9e03bd7e63fcf9607
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Fri Aug 23 12:24:15 2019 -0700
+
+    Whitespace
+
+ src/hb-debug.hh | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+commit 569426d861ac9336f4083e55f98284b4c647c795
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Fri Aug 23 11:54:20 2019 -0700
+
+    [debug] Fix build with HB_DEBUG
+    
+    Fixes https://github.com/harfbuzz/harfbuzz/issues/1923
+
+ src/hb-debug.hh | 5 +++--
+ 1 file changed, 3 insertions(+), 2 deletions(-)
+
+commit f233e6c8014cde9b2396c5350c29a3277cd3a657
+Author: Khaled Hosny <khaledhosny@eglug.org>
+Date:   Fri Aug 23 13:15:37 2019 +0200
+
+    [doc] Update list of default features in the manual
+    
+    Fixes https://github.com/harfbuzz/harfbuzz/issues/1921
+
+ docs/usermanual-opentype-features.xml | 8 +++++---
+ 1 file changed, 5 insertions(+), 3 deletions(-)
+
+commit be97e9d678017d4ec66625fa2b17ef3485552cad
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Thu Aug 22 15:52:24 2019 -0700
+
+    2.6.1
+
+ NEWS             | 11 +++++++++++
+ configure.ac     |  2 +-
+ src/hb-version.h |  4 ++--
+ 3 files changed, 14 insertions(+), 3 deletions(-)
+
+commit d304d60e4d49df14ed85d6646680085f27bafbf2
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Wed Aug 21 12:30:22 2019 -0700
+
+    [ot-font] Prefer symbol cmap subtable if found
+    
+    Fixes https://github.com/harfbuzz/harfbuzz/issues/1918
+    
+    Hopefully doesn't break anyone...
+
+ src/hb-ot-cmap-table.hh | 16 +++++++++-------
+ 1 file changed, 9 insertions(+), 7 deletions(-)
+
+commit 2a3d4987a75fb2cd51ccf4c1d08baba383ceda7b
+Author: Ebrahim Byagowi <ebrahim@gnu.org>
+Date:   Wed Aug 21 03:02:01 2019 +0430
+
+    Remove hb_directwrite_shape_experimental_width public API
+    
+    I had specially exposed the API as I didn't know how to embed harfbuzz
+    easily elsewhere but now with harfbuzz.cc it has become very easy
+    and I don't like to see its use anywhere as it has a bad naming and
+    its Kashida adding is bogus and only useful to check where it should
+    be added, not visually useful however.
+
+ src/hb-directwrite.cc | 29 ++++++-----------------------
+ src/hb-directwrite.h  |  5 -----
+ 2 files changed, 6 insertions(+), 28 deletions(-)
+
+commit 163a66dc737645852d7515381304d69706688e16
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Tue Aug 20 14:22:57 2019 -0700
+
+    [test] Add test for aaa85931f3542639cd9d0dfb92fd6baab5b0298d
+
+ test/api/test-shape.c | 48 ++++++++++++++++++++++++++++++------------------
+ 1 file changed, 30 insertions(+), 18 deletions(-)
+
+commit aaa85931f3542639cd9d0dfb92fd6baab5b0298d
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Tue Aug 20 13:06:10 2019 -0700
+
+    [font] Update multipliers when creating sub_font
+    
+    Fixes https://github.com/harfbuzz/harfbuzz/issues/1910
+
+ src/hb-font.cc | 1 +
+ 1 file changed, 1 insertion(+)
+
+commit bbad1b8298125d78c159ed7fdd7bde6a3f3fff56
+Author: Ebrahim Byagowi <ebrahim@gnu.org>
+Date:   Tue Aug 20 14:46:48 2019 +0430
+
+    [trak] minor, use roundf instead round to normalize the use
+    
+    The change to `round` wasn't intended
+
+ src/hb-aat-layout-trak-table.hh | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+commit e67cb500e9c5f6717d0d1cd152de84d88ec7370e
+Author: Ebrahim Byagowi <ebrahim@gnu.org>
+Date:   Tue Aug 20 13:30:34 2019 +0430
+
+    [readme] add oss-fuzz badge
+    
+    Related:
+    https://github.com/google/oss-fuzz/pull/2513
+    https://github.com/systemd/systemd/commit/ce2098b7e9443cd6f31fb70af7f72308cd2962a3
+
+ README.md | 1 +
+ 1 file changed, 1 insertion(+)
+
+commit d59d89b28128cf644d76098c709b9309b834eb09
+Author: Ebrahim Byagowi <ebrahim@gnu.org>
+Date:   Tue Aug 20 13:07:17 2019 +0430
+
+    [test] Rebase 10.14 trak related test
+
+ test/shaping/data/in-house/tests/macos.tests | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 20b1a27c8a319d43a582c3efa8233b9f2c3cc73e
+Merge: 5ee1e451 37de38ad
+Author: Ebrahim Byagowi <ebrahim@gnu.org>
+Date:   Tue Aug 20 13:04:51 2019 +0430
+
+    Merge remove-coretext-96dpi-assumption, @drott
+    
+    Remove assumption about Core Text working in 96 DPI
+
+commit 37de38adeae48e1855c2431a39639db873a74554
+Merge: f401f85a 5ee1e451
+Author: Ebrahim Byagowi <ebrahim@gnu.org>
+Date:   Tue Aug 20 12:59:33 2019 +0430
+
+    Merge branch 'master' into remove-coretext-96dpi-assumption
+
+commit 5ee1e451cfc75dc6ddbc3ae300ba7394a0cd560e
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Mon Aug 19 14:23:17 2019 -0700
+
+    Minor touch-up for recent change
+
+ src/hb-ot-var-avar-table.hh | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+commit 33489928444b94bdd2cc523dac14707eb29d667e
+Author: Ebrahim Byagowi <ebrahim@gnu.org>
+Date:   Wed Aug 7 20:07:58 2019 +0430
+
+    [avar] Implement inverse map, unmap
+
+ src/hb-ot-var-avar-table.hh | 30 ++++++++++++++++++++++++------
+ 1 file changed, 24 insertions(+), 6 deletions(-)
+
+commit 981f5a54c3cbc1de45ba941fdf5315c62d86b6f3
+Author: Ebrahim Byagowi <ebrahim@gnu.org>
+Date:   Wed Aug 7 18:45:39 2019 +0430
+
+    [fvar] Implement inverse normalize, unnormalize
+
+ src/hb-ot-var-fvar-table.hh | 14 ++++++++++++++
+ 1 file changed, 14 insertions(+)
+
+commit dcb4cd400fb44172872a20ba54baa011d748b61d
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Mon Aug 19 11:35:37 2019 -0700
+
+    Minor
+
+ src/hb-font.cc | 4 +---
+ 1 file changed, 1 insertion(+), 3 deletions(-)
+
+commit ca54440324745afc388edac40ad1047e92567fdb
+Author: Ebrahim Byagowi <ebrahim@gnu.org>
+Date:   Sun Aug 18 11:58:04 2019 +0430
+
+    Remove continuous development helper script
+    
+    Not have used it personally for a long time, lets remove it
+
+ src/dev-run.sh | 99 ----------------------------------------------------------
+ 1 file changed, 99 deletions(-)
+
+commit 40aef1b473f63701ab901880d764e33682f13414
+Author: Khaled Hosny <khaledhosny@eglug.org>
+Date:   Fri Aug 16 01:00:30 2019 +0200
+
+    [ot-shape] Keep horizontal_features array sorted
+
+ src/hb-ot-shape.cc | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit da5118da77898ae4778af1ace4af52334b210dd6
+Author: Khaled Hosny <khaledhosny@eglug.org>
+Date:   Fri Aug 16 00:48:26 2019 +0200
+
+    [ot-shape] Enable abvm/blwm features by default
+    
+    Core Text seems to apply them to Latin text, but Uniscribe doesn’t.
+    
+    See https://github.com/harfbuzz/harfbuzz/pull/1908#issuecomment-521819343
+
+ src/hb-ot-shape-complex-indic.cc                   |   9 ---------
+ src/hb-ot-shape-complex-khmer.cc                   |   9 ---------
+ src/hb-ot-shape-complex-myanmar.cc                 |  21 ---------------------
+ src/hb-ot-shape-complex-use.cc                     |  14 --------------
+ src/hb-ot-shape.cc                                 |   2 ++
+ test/shaping/data/in-house/Makefile.sources        |   2 +-
+ .../ea3f63620511b2097200d23774ffef197e829e69.ttf   | Bin 0 -> 1804 bytes
+ .../f79eb71df4e4c9c273b67b89a06e5ff9e3c1f834.ttf   | Bin 0 -> 1860 bytes
+ test/shaping/data/in-house/tests/dist.tests        |   1 -
+ .../data/in-house/tests/positioning-features.tests |   3 +++
+ 10 files changed, 6 insertions(+), 55 deletions(-)
+
+commit 2164bd6f29df265acdc04b84f5f94cf63b2cea8a
+Author: Khaled Hosny <khaledhosny@eglug.org>
+Date:   Fri Aug 16 00:28:41 2019 +0200
+
+    [ot-shape] Enable dist feature by default (#1908)
+    
+    Fixes https://github.com/harfbuzz/harfbuzz/issues/1907
+
+ src/hb-ot-shape-complex-indic.cc                         |   2 --
+ src/hb-ot-shape-complex-khmer.cc                         |   2 --
+ src/hb-ot-shape-complex-myanmar.cc                       |   1 -
+ src/hb-ot-shape-complex-use.cc                           |   1 -
+ src/hb-ot-shape.cc                                       |   1 +
+ test/shaping/data/in-house/Makefile.sources              |   1 +
+ .../fonts/53a91c20e33a596f2be17fb68b382d6b7eb85d5c.ttf   | Bin 0 -> 2020 bytes
+ test/shaping/data/in-house/tests/dist.tests              |   1 +
+ 8 files changed, 3 insertions(+), 6 deletions(-)
+
+commit bc27f86ffef537835f6c9dbbecbc2ee6792cb127
+Author: Ebrahim Byagowi <ebrahim@gnu.org>
+Date:   Wed Aug 14 22:37:00 2019 +0430
+
+    Move HB_NO_VAR to a better place in hb-font.cc
+    
+    Needed for other works
+
+ src/hb-font.cc | 5 ++---
+ 1 file changed, 2 insertions(+), 3 deletions(-)
+
+commit 1cc844da66ab527991ff96efdf10d97f6b626bfe
+Author: Ebrahim Byagowi <ebrahim@gnu.org>
+Date:   Wed Aug 14 19:10:02 2019 +0430
+
+    minor
+    
+    Use hb_font_t coords directly
+
+ src/hb-ot-cff2-table.cc | 4 +---
+ 1 file changed, 1 insertion(+), 3 deletions(-)
+
+commit 6a194b6876db12f083ae5391ca01972168d4e68a
+Author: Ebrahim Byagowi <ebrahim@gnu.org>
+Date:   Wed Aug 14 18:49:57 2019 +0430
+
+    Minor, remove trailing spaces in hb-font.{cc,h} as .editorconfig
+
+ src/hb-font.cc | 338 ++++++++++++++++++++++++++++-----------------------------
+ src/hb-font.h  |  26 ++---
+ 2 files changed, 182 insertions(+), 182 deletions(-)
+
+commit 3ae44645d60fe8271ad18b004434d475eaeb7ad6
+Author: Ebrahim Byagowi <ebrahim@gnu.org>
+Date:   Wed Aug 14 14:34:55 2019 +0430
+
+    Fix caret_count value when AAT is disabled
+    
+    Set caret_count to zero as that is what we want to happen inside lcar when
+    there is no result.
+
+ src/hb-ot-layout.cc | 6 +++++-
+ 1 file changed, 5 insertions(+), 1 deletion(-)
+
+commit a5aa67b9f288687e21ca7a9887483f7fe1cbce54
+Author: Ebrahim Byagowi <ebrahim@gnu.org>
+Date:   Wed Aug 14 14:29:01 2019 +0430
+
+    [lcar] Use multiformat convention
+
+ src/hb-aat-layout-lcar-table.hh | 115 +++++++++++++++++++++++++++++++---------
+ 1 file changed, 90 insertions(+), 25 deletions(-)
+
+commit bfffe85dd7d7557e10ec9f9886b86fe0d8b4a7a2
+Author: Ebrahim Byagowi <ebrahim@gnu.org>
+Date:   Wed Aug 14 13:55:49 2019 +0430
+
+    [opbd] Use multiformat convention on the table
+
+ src/hb-aat-layout-opbd-table.hh | 116 ++++++++++++++++++++++++++++++----------
+ 1 file changed, 89 insertions(+), 27 deletions(-)
+
+commit d6206dbcc4e4ef8c034ee714e74d3a76c5333a12
+Author: Ebrahim Byagowi <ebrahim@gnu.org>
+Date:   Wed Aug 14 11:24:06 2019 +0430
+
+    [opbd] Turn OpticalBounds fields to FWORD
+
+ src/hb-aat-layout-opbd-table.hh | 8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+commit 6461143b44f81a4190d3f1cb02238750536f08e4
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Tue Aug 13 22:20:54 2019 -0700
+
+    2.6.0
+
+ NEWS                   | 23 +++++++++++++++++++++++
+ configure.ac           |  2 +-
+ docs/harfbuzz-docs.xml |  4 ++++
+ src/hb-font.cc         |  2 +-
+ src/hb-gdi.cc          |  2 +-
+ src/hb-ot-layout.cc    |  2 ++
+ src/hb-ot-layout.h     |  2 +-
+ src/hb-ot-meta.cc      |  4 ++--
+ src/hb-ot-meta.h       |  2 +-
+ src/hb-ot-metrics.cc   |  8 ++++----
+ src/hb-ot-metrics.h    |  2 +-
+ src/hb-version.h       |  6 +++---
+ 12 files changed, 44 insertions(+), 15 deletions(-)
+
+commit e56d4ff43b97ca35a8324be2acf1c8644f3b0a24
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Tue Aug 13 21:02:47 2019 -0700
+
+    Rename hb_ot_meta_get_entries() to +hb_ot_meta_get_entry_tags()
+
+ docs/harfbuzz-sections.txt | 2 +-
+ src/hb-ot-meta.cc          | 8 ++++----
+ src/hb-ot-meta.h           | 8 ++++----
+ src/test-ot-meta.cc        | 4 ++--
+ test/api/test-ot-face.c    | 2 +-
+ test/api/test-ot-meta.c    | 6 +++---
+ 6 files changed, 15 insertions(+), 15 deletions(-)
+
+commit aade9b70aabd8a97dd8a28cda2cf4d0694dd7350
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Tue Aug 13 16:09:20 2019 -0700
+
+    [pool] Fix alignment assertion
+    
+    I *think* it should fix https://github.com/harfbuzz/harfbuzz/issues/1901
+    
+    Ie. if on a system, alignof(void*) < sizeof(void*)...
+
+ src/hb-pool.hh | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit b31d627f151c8eeeb12ed84c3282392d6adbc5b4
+Author: Ebrahim Byagowi <ebrahim@gnu.org>
+Date:   Sun Aug 11 23:34:48 2019 +0430
+
+    Increase subset fuzzer timeout to 16s
+    
+    To satisfy -valgrind and -tsan bots, very ugly
+
+ test/fuzzing/run-subset-fuzzer-tests.py | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 5b9cf191fe1fb13bd4bf914e0f4c03c3b2795a73
+Author: Ebrahim Byagowi <ebrahim@gnu.org>
+Date:   Sun Aug 11 23:07:29 2019 +0430
+
+    [ci] Disable vcpkg thus running the test suit in Windows
+    
+    vcpkg apparently doesn't like to work the same way used to anymore, lets disable it
+
+ appveyor.yml | 20 ++++++++++----------
+ 1 file changed, 10 insertions(+), 10 deletions(-)
+
+commit 60d9f0097580a339c7ffe582cc0657698e315cea
+Author: Ebrahim Byagowi <ebrahim@gnu.org>
+Date:   Sun Aug 11 16:15:19 2019 +0430
+
+    Implement opbd table parsing
+    
+    https://developer.apple.com/fonts/TrueType-Reference-Manual/RM06/Chap6opbd.html
+
+ src/Makefile.sources            |   1 +
+ src/hb-aat-layout-opbd-table.hh | 111 ++++++++++++++++++++++++++++++++++++++++
+ src/hb-ot-face-table-list.hh    |   1 +
+ src/hb-ot-layout.cc             |   1 +
+ 4 files changed, 114 insertions(+)
+
+commit 8762676e34cef13f4b263b377b485b199b66d4d1
+Author: Ebrahim Byagowi <ebrahim@gnu.org>
+Date:   Sat Aug 10 01:26:55 2019 +0430
+
+    [os2] Replace null pool addr compare by checking vital fields (#1896)
+
+ src/hb-ot-os2-table.hh | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+commit 1f926fb2b642094a15e686be6a910e709b15ebd0
+Author: Ebrahim Byagowi <ebrahim@gnu.org>
+Date:   Wed Aug 7 20:22:20 2019 +0430
+
+    [fvar] Use roundf instead hardcoding round logic
+
+ src/hb-ot-var-fvar-table.hh | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 60485ab0473630c585bb96fcdc14dbe415edf4f2
+Author: Ebrahim Byagowi <ebrahim@gnu.org>
+Date:   Wed Aug 7 23:23:06 2019 +0430
+
+    [os2] Get defined lower/upper optical size
+
+ src/hb-ot-os2-table.hh | 17 +++++++++++++++++
+ 1 file changed, 17 insertions(+)
+
+commit 321d5588d4fa96bcc4aa558d2f982430031f242e
+Author: Qunxin Liu <qxliu@google.com>
+Date:   Tue Jul 2 16:30:57 2019 -0700
+
+    [subset] Add subsetting for GPOS Lookup Type 1: Single Adjustment Positioning Subtable
+
+ src/hb-ot-layout-gpos-table.hh                     | 157 ++++++++++++++++++++-
+ test/subset/data/Makefile.am                       |   1 +
+ test/subset/data/Makefile.sources                  |   1 +
+ .../gpos1_2_font.keep-layout-retain-gids.41,43.otf | Bin 0 -> 2068 bytes
+ .../gpos1_2_font.keep-layout-retain-gids.41,46.otf | Bin 0 -> 2232 bytes
+ .../gpos1_2_font.keep-layout-retain-gids.43,46.otf | Bin 0 -> 2096 bytes
+ ...eep-layout-retain-gids.retain-all-codepoint.otf | Bin 0 -> 3668 bytes
+ test/subset/data/fonts/gpos1_2_font.otf            | Bin 0 -> 4564 bytes
+ test/subset/data/tests/layout.gpos.tests           |  11 ++
+ 9 files changed, 166 insertions(+), 4 deletions(-)
+
+commit 37572882e7a685d804384eaf11f0f3e53af38341
+Author: Qunxin Liu <qxliu@google.com>
+Date:   Tue Jun 25 13:17:30 2019 -0700
+
+    [subset] cmap table to use _subset2 and new iterator frameworks
+
+ src/hb-ot-cmap-table.hh                          | 670 +++++++++++------------
+ src/hb-subset.cc                                 |   2 +-
+ test/api/fonts/Roboto-Regular.D7,D8,D9,DA,DE.ttf | Bin 2816 -> 2532 bytes
+ test/api/fonts/Roboto-Regular.abc.ttf            | Bin 2460 -> 2168 bytes
+ test/api/fonts/Roboto-Regular.ac.ttf             | Bin 2268 -> 1988 bytes
+ 5 files changed, 320 insertions(+), 352 deletions(-)
+
+commit 06596cf90700ff76f23297141c656dfc317eece6
+Author: Khaled Hosny <khaledhosny@eglug.org>
+Date:   Sat Aug 3 13:55:34 2019 +0200
+
+    Some styling
+
+ README.python.md | 12 ++++++------
+ 1 file changed, 6 insertions(+), 6 deletions(-)
+
+commit 5848c890cf2f8a14c9d9e329c4f8283feac1f0c3
+Author: Ebrahim Byagowi <ebrahim@gnu.org>
+Date:   Sat Aug 3 14:19:28 2019 +0430
+
+    [metrics] Add metrics tags documentation
+
+ src/hb-ot-metrics.h | 28 ++++++++++++++++++++++++++++
+ 1 file changed, 28 insertions(+)
+
+commit 4d1872b8e019659a92a59b1d7cba6fd81ed3607d
+Author: Ebrahim Byagowi <ebrahim@gnu.org>
+Date:   Sat Aug 3 14:06:46 2019 +0430
+
+    [base] Add documentation for baseline tags from ot spec
+
+ src/hb-ot-layout.h | 19 ++++++++++++++++++-
+ 1 file changed, 18 insertions(+), 1 deletion(-)
+
+commit bbeee84a7f048633b0aaa95aa6129871a3a22164
+Author: Ebrahim Byagowi <ebrahim@gnu.org>
+Date:   Sat Aug 3 13:47:55 2019 +0430
+
+    [meta] Add metadata tags documentation from ot spec
+
+ src/hb-ot-meta.h | 8 +++++++-
+ 1 file changed, 7 insertions(+), 1 deletion(-)
+
+commit 521c7013abab84a0994fda3977ccd1ba3d496242
+Author: Ebrahim Byagowi <ebrahim@gnu.org>
+Date:   Tue Jul 30 18:10:40 2019 +0430
+
+    [cpal] revert port to dagger
+    
+    It has a different semantic, maybe we should just do a zero memset,
+    letting Behdad to decide.
+
+ src/hb-ot-color-cpal-table.hh | 5 ++---
+ 1 file changed, 2 insertions(+), 3 deletions(-)
+
+commit 8014ce198a09d20cb947e4a465c7d893a84c55be
+Author: Ebrahim Byagowi <ebrahim@gnu.org>
+Date:   Tue Jul 30 17:31:34 2019 +0430
+
+    [cpal] port to dagger (#1887)
+
+ src/hb-ot-color-cpal-table.hh | 5 +++--
+ 1 file changed, 3 insertions(+), 2 deletions(-)
+
+commit d67201da5a2142cb9d039a8cb2cb713556d945af
+Author: Ebrahim Byagowi <ebrahim@gnu.org>
+Date:   Tue Jul 30 17:20:18 2019 +0430
+
+    [colr] minor
+
+ src/hb-ot-color-colr-table.hh | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 8c0a2e68ad91e55a11162da0cddb355810a4c8a0
+Author: Ebrahim Byagowi <ebrahim@gnu.org>
+Date:   Tue Jul 30 13:16:15 2019 +0430
+
+    [fuzz] Add dummy call of the added APIs (#1886)
+
+ test/api/test-ot-face.c | 10 ++++++++++
+ 1 file changed, 10 insertions(+)
+
+commit e5cf9718c07c8bf1fc20cd573cef2d125c28281f
+Author: Ebrahim Byagowi <ebrahim@gnu.org>
+Date:   Tue Jul 30 04:44:23 2019 +0430
+
+    [colr][feat][meta] Port sub_array iteration to dagger (#1868)
+
+ src/hb-aat-layout-feat-table.hh | 37 ++++++++++++++++++-------------------
+ src/hb-ot-color-colr-table.hh   | 14 ++++++--------
+ src/hb-ot-meta-table.hh         |  8 +++++---
+ 3 files changed, 29 insertions(+), 30 deletions(-)
+
+commit 9f2b4956b484b802eb37f36974c11785c90493ce
+Author: Ebrahim Byagowi <ebrahim@gnu.org>
+Date:   Tue Jul 30 04:42:51 2019 +0430
+
+    [base] Add hb_ot_layout_get_baseline API
+
+ docs/harfbuzz-sections.txt   |  2 +
+ src/hb-ot-face-table-list.hh |  6 ++-
+ src/hb-ot-layout.cc          | 87 ++++++++++++--------------------------------
+ src/hb-ot-layout.h           | 32 ++++++++++++++++
+ test/api/test-baseline.c     |  4 +-
+ 5 files changed, 63 insertions(+), 68 deletions(-)
+
+commit 40a4b6ddbdc84a25f76bd4d7ff41b1322fe95b83
+Author: Ebrahim Byagowi <ebrahim@gnu.org>
+Date:   Sat Jul 27 13:33:46 2019 +0430
+
+    [var] Add a new API, hb_font_set_var_named_instance
+
+ docs/harfbuzz-sections.txt     |  1 +
+ src/hb-font.cc                 | 28 ++++++++++++++++++++++++++++
+ src/hb-font.h                  |  4 ++++
+ test/api/test-ot-extents-cff.c | 32 ++++++++++++++++++++++++++++++++
+ 4 files changed, 65 insertions(+)
+
+commit b6a2281f1a2d29cc5797f4f266800f7141591585
+Author: Ebrahim Byagowi <ebrahim@gnu.org>
+Date:   Tue Jul 30 03:45:45 2019 +0430
+
+    [meta] Make values match their enum type naming
+
+ src/hb-ot-meta.h        | 10 +++++-----
+ test/api/test-ot-meta.c |  4 ++--
+ 2 files changed, 7 insertions(+), 7 deletions(-)
+
+commit 20072a2eca8943a82e36cbb603ad31481cfc56cd
+Author: Ebrahim Byagowi <ebrahim@gnu.org>
+Date:   Tue Jul 30 03:43:15 2019 +0430
+
+    [metrics] Make values match their enum type naming
+
+ src/hb-ot-font.cc          |  12 +++---
+ src/hb-ot-metrics.cc       | 100 ++++++++++++++++++++++-----------------------
+ src/hb-ot-metrics.h        |  58 +++++++++++++-------------
+ test/api/test-ot-metrics.c |  26 ++++++------
+ 4 files changed, 98 insertions(+), 98 deletions(-)
+
+commit ed2965a8527ee89994c8eecf451bf71846b3ca86
+Author: Ebrahim Byagowi <ebrahim@gnu.org>
+Date:   Tue Jul 30 03:34:10 2019 +0430
+
+    [base] Don't use enum inside the table
+
+ src/hb-ot-layout-base-table.hh | 31 ++++++++++++++-----------------
+ 1 file changed, 14 insertions(+), 17 deletions(-)
+
+commit 388fa9b32611a8726b9bbfe7ccf8cdbcd818fd70
+Author: Ebrahim Byagowi <ebrahim@gnu.org>
+Date:   Sat Jul 27 14:56:18 2019 +0430
+
+    [lcar] flip for and switch position
+
+ src/hb-aat-layout-lcar-table.hh | 16 ++++++++++------
+ 1 file changed, 10 insertions(+), 6 deletions(-)
+
+commit f0dd724c1e091f42f289efbebd2c50e830e59c6e
+Merge: 68ac767e 4e1da6bb
+Author: blueshade7 <ariza@typekit.com>
+Date:   Mon Jul 29 14:21:05 2019 -0700
+
+    Merge branch 'master' into subset-varstore
+
+commit 4e1da6bb612b0c6386ab143dbb4ca19ff25bc2ba
+Author: Ebrahim Byagowi <ebrahim@gnu.org>
+Date:   Mon Jul 29 22:03:56 2019 +0430
+
+    [metrics] Rename hb_ot_metrics_t to hb_ot_metrics_tag_t
+
+ src/hb-ot-metrics.cc | 22 +++++++++++-----------
+ src/hb-ot-metrics.h  | 16 ++++++++--------
+ src/hb-ot-metrics.hh |  6 +++---
+ 3 files changed, 22 insertions(+), 22 deletions(-)
+
+commit 2c2a2b97dbe24ae2e09018f435559c97a460bdcb
+Author: Ebrahim Byagowi <ebrahim@gnu.org>
+Date:   Mon Jul 29 22:01:13 2019 +0430
+
+    [meta] Rename hb_ot_meta_t to hb_ot_meta_tag_t
+
+ src/hb-ot-meta-table.hh | 10 +++++-----
+ src/hb-ot-meta.cc       | 10 +++++-----
+ src/hb-ot-meta.h        | 14 +++++++-------
+ src/test-ot-meta.cc     |  4 ++--
+ test/api/test-ot-meta.c |  6 +++---
+ 5 files changed, 22 insertions(+), 22 deletions(-)
+
+commit 7bcc5dfa97a43d9c5f6dfdb87b4f0d5a589ecd48
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Sun Jul 28 20:55:50 2019 -0700
+
+    [iter] Fix accumulate to accept const types
+
+ src/hb-iter.hh | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit e21bdf500d4ecc3a5fd6f79aabf6232f3967035e
+Author: Ebrahim Byagowi <ebrahim@gnu.org>
+Date:   Sun Jul 28 22:59:09 2019 +0430
+
+    Increase subset fuzzer timeout to 8s
+    
+    Probably we should just remove timeout when running tsan and vaglrind here, the flaky bots
+
+ test/fuzzing/run-subset-fuzzer-tests.py | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 87454c447d705327a26c1f879e0a4f3002ae2667
+Author: Ebrahim Byagowi <ebrahim@gnu.org>
+Date:   Sun Jul 28 20:46:47 2019 +0430
+
+    [base] fix logic
+
+ src/hb-ot-layout-base-table.hh | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+commit 69655d5bc3c7b240424545bdef197d9d7251e509
+Author: Ebrahim Byagowi <ebrahim@gnu.org>
+Date:   Sun Jul 28 20:39:20 2019 +0430
+
+    [base] minor
+
+ src/hb-ot-layout-base-table.hh | 5 ++---
+ 1 file changed, 2 insertions(+), 3 deletions(-)
+
+commit d9c44e7239daf59e283fecd4166c984b43d48e24
+Author: Ebrahim Byagowi <ebrahim@gnu.org>
+Date:   Sun Jul 28 20:35:32 2019 +0430
+
+    [base] Check if the returned base_coord is valid
+
+ src/hb-ot-layout-base-table.hh | 13 ++++++++-----
+ 1 file changed, 8 insertions(+), 5 deletions(-)
+
+commit 53853c044a6382ece51393dfc3a4fe6a5f8a5a23
+Author: Ebrahim Byagowi <ebrahim@gnu.org>
+Date:   Sun Jul 28 20:23:48 2019 +0430
+
+    [meta] minor
+
+ src/hb-ot-meta-table.hh | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit ed126d8c37c45d8d60eb0368143c6776d1fcfbff
+Author: Ebrahim Byagowi <ebrahim@gnu.org>
+Date:   Sun Jul 28 20:21:59 2019 +0430
+
+    [base] fix build
+
+ src/hb-ot-layout-base-table.hh | 3 +++
+ 1 file changed, 3 insertions(+)
+
+commit c7b22b96cc64c81248362a70f2d60d93ee520f2d
+Author: Ebrahim Byagowi <ebrahim@gnu.org>
+Date:   Sun Jul 28 19:46:57 2019 +0430
+
+    [base] minor
+
+ src/hb-ot-layout-base-table.hh | 4 +---
+ 1 file changed, 1 insertion(+), 3 deletions(-)
+
+commit a157342fce2616141ee62d68ad8e3fb93e52187e
+Author: Ebrahim Byagowi <ebrahim@gnu.org>
+Date:   Sun Jul 28 18:54:13 2019 +0430
+
+    [base] Fix use of bsearch
+
+ src/hb-ot-layout-base-table.hh | 94 ++++++++++++++----------------------------
+ 1 file changed, 31 insertions(+), 63 deletions(-)
+
+commit eddd45653282ffff8ef002ad2163bcf8bf4f3df1
+Author: Ebrahim Byagowi <ebrahim@gnu.org>
+Date:   Sun Jul 28 02:21:54 2019 +0430
+
+    [base] minor spacing
+
+ src/hb-ot-layout-base-table.hh | 10 +++++-----
+ 1 file changed, 5 insertions(+), 5 deletions(-)
+
+commit 0a18efd766b3b6cc987ee18785f7858fe2bd1c67
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Fri Jul 26 14:34:26 2019 -0700
+
+    Minor
+
+ src/hb-ot-layout-gsub-table.hh | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 60d0fe2eda9c0eb67f50d61e905b584b8edc3e95
+Merge: 6d53cda1 658424b2
+Author: Ebrahim Byagowi <ebrahim@gnu.org>
+Date:   Sat Jul 27 01:20:55 2019 +0430
+
+    Merge pull request #1872 from darktohka/cmake-regex-fix
+    
+    [cmake] Fix CMake build on newer CMake versions
+
+commit 658424b29efbc758541a790193c42171bb7fa965
+Author: Derzsi Dániel <daniel@tohka.us>
+Date:   Fri Jul 26 22:52:03 2019 +0300
+
+    [cmake] Fix CMake build on newer CMake versions
+    
+    Unfortunately, newer CMake versions die during regex variable extraction, causing the build to fail.
+    
+    This is caused by the lack of escaping used around variables in the extract_make_variable function, causing these variables to be automatically unwrapped into empty strings.
+
+ CMakeLists.txt | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+commit 6d53cda1baf130853e5725fe8fea1d1c5f766a79
+Author: Zero King <l2dy@icloud.com>
+Date:   Fri Jul 26 15:43:51 2019 +0000
+
+    [util] Fix memory leak
+
+ util/options.cc | 1 +
+ 1 file changed, 1 insertion(+)
+
+commit d3d99f8bb6ad77d1ac73901885acfffd3bb3e7f7
+Author: Ebrahim Byagowi <ebrahim@gnu.org>
+Date:   Fri Jul 26 16:46:04 2019 +0430
+
+    [metrics] Expose raw OS2/HHEA asc/dsc values using private tags (#1867)
+
+ src/hb-ot-metrics.cc | 16 ++++++++++++++++
+ 1 file changed, 16 insertions(+)
+
+commit aaffe41094f8ddefad6f33e86cbd04a24dd9bfff
+Author: Ebrahim Byagowi <ebrahim@gnu.org>
+Date:   Fri Jul 26 01:14:37 2019 +0430
+
+    [meta] minor, simplify iterator
+
+ src/hb-ot-meta-table.hh | 8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+commit 62932c14bd256f10031380047ededd93a2aacd88
+Author: Ebrahim Byagowi <ebrahim@gnu.org>
+Date:   Fri Jul 26 00:30:29 2019 +0430
+
+    [meta] Rename ot-metadata to ot-meta per review
+
+ docs/harfbuzz-sections.txt                      |  7 +++---
+ src/Makefile.am                                 |  8 +++----
+ src/Makefile.sources                            |  4 ++--
+ src/harfbuzz.cc                                 |  2 +-
+ src/hb-ot-meta-table.hh                         |  8 +++----
+ src/{hb-ot-metadata.cc => hb-ot-meta.cc}        | 22 +++++++++---------
+ src/{hb-ot-metadata.h => hb-ot-meta.h}          | 30 ++++++++++++-------------
+ src/hb-ot.h                                     |  2 +-
+ src/{test-ot-metadata.cc => test-ot-meta.cc}    | 10 ++++-----
+ test/api/Makefile.am                            |  2 +-
+ test/api/{test-ot-metadata.c => test-ot-meta.c} | 26 ++++++++++-----------
+ 11 files changed, 61 insertions(+), 60 deletions(-)
+
+commit 821d9e9034c57c5c593741284b134c76cc3c7c0f
+Author: Ebrahim Byagowi <ebrahim@gnu.org>
+Date:   Fri Jul 26 00:08:58 2019 +0430
+
+    Use .sub_array for DataMap tags iteration
+
+ src/hb-ot-meta-table.hh | 8 +++-----
+ 1 file changed, 3 insertions(+), 5 deletions(-)
+
+commit a250af98ae74c94ac3aa069e6e5958a937586bfc
+Author: Ebrahim Byagowi <ebrahim@gnu.org>
+Date:   Wed Jul 24 03:10:41 2019 +0430
+
+    [meta] Add max value to hb_ot_metadata_t
+
+ src/hb-ot-metadata.h | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+commit 80e246a1f2b3c4e3c25a4a3ec042e7610944abd4
+Author: Ebrahim Byagowi <ebrahim@gnu.org>
+Date:   Wed Jul 24 03:08:34 2019 +0430
+
+    [meta] Add a test program for metadata
+
+ src/Makefile.am         |  5 ++++
+ src/test-ot-metadata.cc | 70 +++++++++++++++++++++++++++++++++++++++++++++++++
+ 2 files changed, 75 insertions(+)
+
+commit bc65ebbce765545bc4455d8ae5ba4a6a99201e41
+Author: Ebrahim Byagowi <ebrahim@gnu.org>
+Date:   Wed Jul 24 02:28:09 2019 +0430
+
+    [meta] hb_ot_metadata_get_entries, tags iteration API
+
+ src/hb-ot-meta-table.hh     | 17 +++++++++++++++++
+ src/hb-ot-metadata.cc       | 28 ++++++++++++++++++++++++----
+ src/hb-ot-metadata.h        |  8 +++++++-
+ test/api/test-ot-metadata.c | 26 ++++++++++++++++++++++++++
+ 4 files changed, 74 insertions(+), 5 deletions(-)
+
+commit 3ac03bd67cb9f4a72e636bf56bc4a79e04bcba62
+Author: Ebrahim Byagowi <ebrahim@gnu.org>
+Date:   Mon Jul 22 23:35:08 2019 +0430
+
+    [meta] New API, hb_ot_metadata_reference_entry for fetching meta entries
+
+ docs/harfbuzz-sections.txt   |   6 +++++
+ src/Makefile.sources         |   2 ++
+ src/harfbuzz.cc              |   1 +
+ src/hb-config.hh             |   1 +
+ src/hb-ot-face-table-list.hh |   4 ++-
+ src/hb-ot-face.cc            |   1 +
+ src/hb-ot-layout.cc          |   1 -
+ src/hb-ot-meta-table.hh      |  20 +++++++++++++++
+ src/hb-ot-metadata.cc        |  57 ++++++++++++++++++++++++++++++++++++++++++
+ src/hb-ot-metadata.h         |  57 ++++++++++++++++++++++++++++++++++++++++++
+ src/hb-ot.h                  |   1 +
+ test/api/Makefile.am         |   1 +
+ test/api/fonts/meta.ttf      | Bin 0 -> 320 bytes
+ test/api/test-ot-metadata.c  |  58 +++++++++++++++++++++++++++++++++++++++++++
+ 14 files changed, 208 insertions(+), 2 deletions(-)
+
+commit aab8e084873eb098c55ed2569c15bb308c59e436
+Author: Ebrahim Byagowi <ebrahim@gnu.org>
+Date:   Fri Jul 26 02:19:22 2019 +0430
+
+    minor spacing fix (#1869)
+
+ src/hb-open-type.hh     | 16 ++++++++--------
+ src/hb-ot-vorg-table.hh |  2 +-
+ src/hb-vector.hh        |  8 ++++----
+ 3 files changed, 13 insertions(+), 13 deletions(-)
+
+commit d791446a930f8e2009c5ab5ea389da98d1ed9b95
+Author: Ebrahim Byagowi <ebrahim@gnu.org>
+Date:   Fri Jul 26 02:12:06 2019 +0430
+
+    [feat] minor
+
+ src/hb-aat-layout-feat-table.hh | 4 +---
+ 1 file changed, 1 insertion(+), 3 deletions(-)
+
+commit 356b68a00afaf972908cb2a478170e3933eaf974
+Author: Ebrahim Byagowi <ebrahim@gnu.org>
+Date:   Thu Jul 25 23:22:00 2019 +0430
+
+    [metrics] Add a test that actually practices variation (#1858)
+
+ test/api/fonts/TestCFF2VF.otf | Bin 0 -> 3636 bytes
+ test/api/test-ot-metrics.c    |  28 ++++++++++++++++++++++++++--
+ 2 files changed, 26 insertions(+), 2 deletions(-)
+
+commit a744fdc6c8217d0d4bfce30e638ed2e5200cf380
+Author: Ebrahim Byagowi <ebrahim@gnu.org>
+Date:   Thu Jul 25 14:49:02 2019 +0430
+
+    Add _MAX_VALUE to hb_ot_metrics_t (#1861)
+
+ src/hb-ot-metrics.cc | 4 ++--
+ src/hb-ot-metrics.h  | 4 +++-
+ 2 files changed, 5 insertions(+), 3 deletions(-)
+
+commit 069872c51b31fe1a618e3ca5c3b0ab8ccba0cf81
+Author: Ebrahim Byagowi <ebrahim@gnu.org>
+Date:   Thu Jul 25 14:27:43 2019 +0430
+
+    minor
+
+ src/hb-ot-layout.cc | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 737eb85a4ec8861791157d83dd170ac48fa2cfc7
+Author: Ebrahim Byagowi <ebrahim@gnu.org>
+Date:   Thu Jul 25 14:26:30 2019 +0430
+
+    Add _MAX_VALUE to disabled baseline types enum
+
+ src/hb-ot-layout.cc | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+commit dd9a0ed3f0c0a8a94e107689318463d62414cf60
+Author: Ebrahim Byagowi <ebrahim@gnu.org>
+Date:   Wed Jul 24 00:47:19 2019 +0430
+
+    Replace 0x7FFFFFFFu in enums with HB_TAG_MAX_SIGNED
+
+ src/hb-aat-layout.h | 4 ++--
+ src/hb-ot-var.h     | 2 +-
+ 2 files changed, 3 insertions(+), 3 deletions(-)
+
+commit 636ae422372ed7f17b695e78c9c9015188b204e8
+Author: Ebrahim Byagowi <ebrahim@gnu.org>
+Date:   Mon Jul 22 22:50:21 2019 +0430
+
+    minor, comment out meta table in list till its use
+
+ src/hb-ot-face-table-list.hh | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 04c11a19b75663af35d16c827e295aa2e555d110
+Merge: 41ab56e0 c9796d15
+Author: Khaled Hosny <khaledhosny@eglug.org>
+Date:   Mon Jul 22 16:44:47 2019 +0200
+
+    Merge pull request #1851 from khaledhosny/fix-sbix-extents
+    
+    Fix sbix glyph extents
+
+commit 41ab56e09586b675b1c5de745cf5f520a808bba1
+Author: Ebrahim Byagowi <ebrahim@gnu.org>
+Date:   Mon Jul 22 18:46:52 2019 +0430
+
+    Implement meta table parsing
+
+ src/Makefile.sources         |  1 +
+ src/hb-ot-face-table-list.hh |  1 +
+ src/hb-ot-layout.cc          | 15 ++++----
+ src/hb-ot-meta-table.hh      | 89 ++++++++++++++++++++++++++++++++++++++++++++
+ 4 files changed, 99 insertions(+), 7 deletions(-)
+
+commit a51aa951b5ad8da4ac7effc891437345e012a0ac
+Author: Ebrahim Byagowi <ebrahim@gnu.org>
+Date:   Mon Jul 22 18:35:55 2019 +0430
+
+    [metrics] Fix _get_variation API to works with actual coord values
+
+ src/hb-ot-metrics.cc       | 16 ++++++++--------
+ src/hb-ot-metrics.h        |  2 +-
+ test/api/test-ot-metrics.c |  2 +-
+ 3 files changed, 10 insertions(+), 10 deletions(-)
+
+commit 77141dff7d73fa6290f51c9e1ca56ce51a5deec0
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Mon Jul 22 07:48:32 2019 -0400
+
+    [metrics] _-prefix internal symbol
+
+ src/hb-ot-font.cc    | 12 ++++++------
+ src/hb-ot-metrics.cc |  8 ++++----
+ src/hb-ot-metrics.hh |  6 +++---
+ 3 files changed, 13 insertions(+), 13 deletions(-)
+
+commit 89228ccb9a81b728bc9955082c17c68c848c50c4
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Mon Jul 22 07:07:37 2019 -0400
+
+    Fix warning on IBM compilers
+    
+    Fixes https://github.com/harfbuzz/harfbuzz/issues/1852
+
+ src/hb.hh | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+commit c9796d15e1ec5f8939f8b1ae368cb3352b6a9cb9
+Author: Khaled Hosny <khaledhosny@eglug.org>
+Date:   Mon Jul 22 03:57:24 2019 +0200
+
+    Fix sbix glyph extents
+    
+    * The ‘height’ needs to be negated since the API returns “distance from
+      top to bottom side”.
+    * Similarly, the ‘y_offset‘ needs to be added to the height to get the
+      ‘y_bearing’, since sbix’s offset is “the point in the glyph relative
+      to its lower-left corner which corresponds to the origin” while
+      ‘y_bearing’ is the “top side of glyph from origin”.
+    
+    With these changes the sbix glyph metrics return values similar to other
+    tables, as they were otherwise unusable.
+
+ src/hb-ot-color-sbix-table.hh                            |   4 ++--
+ test/api/test-ot-color.c                                 |   4 ++--
+ .../fonts/fcbaa518d3cce441ed37ae3b1fed6a19e9b54efd.ttf   | Bin 0 -> 3128 bytes
+ test/shaping/data/in-house/tests/color-fonts.tests       |   1 +
+ 4 files changed, 5 insertions(+), 4 deletions(-)
+
+commit 759f3bd486c99bb09fb9fa5f42e621ec21399df8
+Author: Ebrahim Byagowi <ebrahim@gnu.org>
+Date:   Mon Jul 22 02:06:07 2019 +0430
+
+    [metrics] Don't use metrics API in _common
+    
+    As it is exposed with a different condition
+
+ src/hb-ot-metrics.cc | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit eb8bd2f7eccde483d33406f102c69260fde6fe23
+Author: Ebrahim Byagowi <ebrahim@gnu.org>
+Date:   Tue Jul 16 22:27:01 2019 +0430
+
+    Add hb_gdi_face_create API
+    
+    Based on Konstantin Ritt work posted on mailing list
+
+ CMakeLists.txt             |  8 +++++
+ appveyor.yml               |  2 +-
+ configure.ac               | 23 +++++++++++++++
+ docs/harfbuzz-sections.txt |  5 ++++
+ src/Makefile.am            |  8 +++++
+ src/Makefile.sources       |  3 ++
+ src/harfbuzz.cc            |  1 +
+ src/hb-directwrite.cc      |  9 ++----
+ src/hb-gdi.cc              | 73 ++++++++++++++++++++++++++++++++++++++++++++++
+ src/hb-gdi.h               | 39 +++++++++++++++++++++++++
+ src/hb-uniscribe.cc        |  7 -----
+ src/hb.hh                  |  5 ++++
+ 12 files changed, 168 insertions(+), 15 deletions(-)
+
+commit 3d03bb84d44bc9ef8a77e974d0e937a3385ffb92
+Author: Ebrahim Byagowi <ebrahim@gnu.org>
+Date:   Sun Jul 21 12:38:04 2019 +0430
+
+    [metrics] minor, tweak comment
+
+ src/hb-ot-metrics.cc | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+commit e540d402f6120e8761ff655bdbffb07d91a5f643
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Fri Jul 19 11:19:31 2019 -0700
+
+    [docs] Minor
+
+ docs/harfbuzz-sections.txt | 2 ++
+ src/hb-ot-math.h           | 2 +-
+ 2 files changed, 3 insertions(+), 1 deletion(-)
+
+commit 00e13985fbc5291850b8ea3d021e5f83c8a297e3
+Author: Ebrahim Byagowi <ebrahim@gnu.org>
+Date:   Sat Jul 20 23:03:51 2019 +0430
+
+    Revert hhea fallback to OS/2 to its reverse way
+    
+    As searching number of hhea having fonts beats the number of OS/2
+    having ones in macOS 10.14.2
+
+ src/hb-ot-metrics.cc | 12 ++++++------
+ 1 file changed, 6 insertions(+), 6 deletions(-)
+
+commit c13ef9cc64a447e74abfed75f4f418bf644be88d
+Author: Ebrahim Byagowi <ebrahim@gnu.org>
+Date:   Sat Jul 20 15:01:37 2019 +0430
+
+    Bring back asc/desc abs logic used to be in hmtx table
+
+ src/hb-ot-metrics.cc | 21 ++++++++++++++++++---
+ 1 file changed, 18 insertions(+), 3 deletions(-)
+
+commit 772e62688cd72c02910f623653d2ec8ef6990928
+Author: Ebrahim Byagowi <ebrahim@gnu.org>
+Date:   Sat Jul 20 14:50:31 2019 +0430
+
+    Make HB_TINY builds work again by separating the always needed part
+
+ src/hb-ot-font.cc    | 12 +++++-----
+ src/hb-ot-metrics.cc | 62 ++++++++++++++++++++++++++++++++++++++++------------
+ src/hb-ot-metrics.hh |  5 +++++
+ 3 files changed, 59 insertions(+), 20 deletions(-)
+
+commit cb704337407ae9ccb57ae7631567002028b93c84
+Author: Ebrahim Byagowi <ebrahim@gnu.org>
+Date:   Sat Jul 20 14:33:57 2019 +0430
+
+    Merge _get_position_internal into _get_position
+
+ src/hb-ot-metrics.cc | 143 ++++++++++++++++++---------------------------------
+ src/hb-ot-metrics.hh |   5 --
+ 2 files changed, 49 insertions(+), 99 deletions(-)
+
+commit ac3518af58464b33f1b16b34b8846c302b935208
+Author: Ebrahim Byagowi <ebrahim@gnu.org>
+Date:   Sat Jul 20 14:03:36 2019 +0430
+
+    Define post table only when used
+
+ src/hb-ot-face-table-list.hh | 2 ++
+ 1 file changed, 2 insertions(+)
+
+commit 471f798ace08b4551f0c9ead6855a4e49b72ba25
+Author: Ebrahim Byagowi <ebrahim@gnu.org>
+Date:   Sat Jul 20 14:00:20 2019 +0430
+
+    Merge ot-metrics-internal.cc with ot-metrics now that isn't needed in subset
+
+ src/Makefile.sources          |   3 --
+ src/harfbuzz.cc               |   1 -
+ src/hb-ot-metrics-internal.cc | 100 ------------------------------------------
+ src/hb-ot-metrics.cc          |  71 +++++++++++++++++++++++++++++-
+ 4 files changed, 70 insertions(+), 105 deletions(-)
+
+commit 29444d7e9fd5007bf39efa2cf57a0117aabfc770
+Author: Ebrahim Byagowi <ebrahim@gnu.org>
+Date:   Sat Jul 20 13:52:21 2019 +0430
+
+    Don't cache ascender/descender metrics
+
+ src/hb-ot-font.cc       | 24 ++++++++----------------
+ src/hb-ot-hmtx-table.hh | 20 --------------------
+ 2 files changed, 8 insertions(+), 36 deletions(-)
+
+commit 5e28c2654d030655d7b93ec0d6213d2b9fb2956e
+Author: Ebrahim Byagowi <ebrahim@gnu.org>
+Date:   Sat Jul 20 14:08:11 2019 +0430
+
+    [doc] minor, improve hb-ot-metrics doc a bit
+
+ src/hb-ot-metrics.cc | 11 ++++++-----
+ 1 file changed, 6 insertions(+), 5 deletions(-)
+
+commit ac8b6e330a443a66c3e0fb83af9794310688d848
+Merge: ec8dde81 08b48e89
+Author: Ebrahim Byagowi <ebrahim@gnu.org>
+Date:   Sat Jul 20 13:16:16 2019 +0430
+
+    Merge pull request #1844 from ebraminio/hhea
+    
+    Fallback hhea's ascender/descender to OS2
+
+commit 08b48e89d3c1bafe252badc7c65a9fc2f166a693
+Author: Ebrahim Byagowi <ebrahim@gnu.org>
+Date:   Sat Jul 20 12:53:40 2019 +0430
+
+    [os2] minor spacing tweaks
+
+ src/hb-ot-os2-table.hh | 11 +++++------
+ 1 file changed, 5 insertions(+), 6 deletions(-)
+
+commit 54b9ab704dbf62e2916f1d5276ffef2543bcc2a7
+Author: Ebrahim Byagowi <ebrahim@gnu.org>
+Date:   Sat Jul 20 12:51:38 2019 +0430
+
+    Fallback hhea's ascender/descender to OS2
+
+ src/hb-ot-metrics-internal.cc | 12 ++++++------
+ 1 file changed, 6 insertions(+), 6 deletions(-)
+
+commit ec8dde8142fbf9e5bc0aee9318a7c4e73d61c758
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Fri Jul 19 11:13:50 2019 -0700
+
+    [metrics] Fall back to hhea if OS2 metrics are empty
+    
+    Reinstates previous logic, even if it might be unnecessary.
+
+ src/hb-ot-metrics-internal.cc | 12 ++++++------
+ 1 file changed, 6 insertions(+), 6 deletions(-)
+
+commit 2e5b49d11d1dbfd44d8c640cb9ce5de7d26ca873
+Author: Ebrahim Byagowi <ebrahim@gnu.org>
+Date:   Fri Jul 19 11:41:07 2019 +0430
+
+    Add HB_NO_METRICS and fix HB_TINY build (#1839)
+
+ src/hb-config.hh              | 1 +
+ src/hb-ot-face-table-list.hh  | 2 --
+ src/hb-ot-metrics-internal.cc | 8 +++++++-
+ src/hb-ot-metrics.cc          | 6 ++++++
+ 4 files changed, 14 insertions(+), 3 deletions(-)
+
+commit bdfdac0f26aafb3e9ff2db123116f0406fa49efc
+Author: Ebrahim Byagowi <ebrahim@gnu.org>
+Date:   Fri Jul 19 10:33:00 2019 +0430
+
+    [ci][fuzzer] print valgrind failure if an error happened
+
+ test/fuzzing/run-shape-fuzzer-tests.py | 34 +++++++++++++++++-----------------
+ 1 file changed, 17 insertions(+), 17 deletions(-)
+
+commit 2bd953ff4f656f042dba2845f0479a7fe7c439a6
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Thu Jul 18 14:25:45 2019 -0700
+
+    [metrics] Fix weird use of xor
+    
+    I believe that was a try to use one approach as fallback to other.  But
+    felt wrong.  Just believe what's in OS/2 table to be correct.
+
+ src/hb-ot-metrics-internal.cc | 12 ++++++------
+ src/hb-ot-os2-table.hh        |  2 +-
+ 2 files changed, 7 insertions(+), 7 deletions(-)
+
+commit 9675a067bf1cc0e5d4707c1345736fda4be75b82
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Thu Jul 18 14:15:08 2019 -0700
+
+    [ot-metrics] Touch up
+
+ src/harfbuzz.cc         |  2 ++
+ src/hb-ot-hmtx-table.hh | 19 +++++++++----------
+ 2 files changed, 11 insertions(+), 10 deletions(-)
+
+commit 87e628436e32786635796fbb07ed200f8c0da68f
+Author: Ebrahim Byagowi <ebrahim@gnu.org>
+Date:   Tue Nov 20 23:26:46 2018 +0330
+
+    Implement a simple API for fetching opentype metrics
+    
+    Fixes https://github.com/harfbuzz/harfbuzz/pull/1432
+
+ docs/harfbuzz-sections.txt    |   9 +++
+ src/Makefile.sources          |   6 ++
+ src/hb-ot-face-table-list.hh  |   2 +
+ src/hb-ot-hhea-table.hh       |   2 +
+ src/hb-ot-hmtx-table.hh       |  62 +++++++++----------
+ src/hb-ot-layout.cc           |   1 -
+ src/hb-ot-metrics-internal.cc |  94 +++++++++++++++++++++++++++++
+ src/hb-ot-metrics.cc          | 135 ++++++++++++++++++++++++++++++++++++++++++
+ src/hb-ot-metrics.h           |  92 ++++++++++++++++++++++++++++
+ src/hb-ot-metrics.hh          |  35 +++++++++++
+ src/hb-ot-os2-table.hh        |   4 ++
+ src/hb-ot-post-table.hh       |   5 +-
+ src/hb-ot.h                   |   1 +
+ test/api/Makefile.am          |   1 +
+ test/api/test-ot-metrics.c    |  54 +++++++++++++++++
+ 15 files changed, 467 insertions(+), 36 deletions(-)
+
+commit ed67efcc8c3638c625b2904833af3f27ef51db14
+Author: David Corbett <corbett.dav@husky.neu.edu>
+Date:   Mon Jun 17 10:16:24 2019 -0400
+
+    Revert "[Myanmar] Prevent reordering between Asat and Dot below"
+    
+    This reverts commit 1c8654ead41ca746d577549c92d2a41c594ab639.
+
+ src/hb-unicode.hh | 3 ---
+ 1 file changed, 3 deletions(-)
+
+commit 504bb17287c978d60a4a515555852465319f74ed
+Author: Ebrahim Byagowi <ebrahim@gnu.org>
+Date:   Wed Jul 17 22:57:46 2019 +0430
+
+    [ci] Bring back -linux-arm64 bot
+    
+    Let's see if 576065b has fixed it
+
+ .circleci/config.yml | 16 ++++++++--------
+ 1 file changed, 8 insertions(+), 8 deletions(-)
+
+commit 6157bbe5127bbcbd17348622601976cffcd11c63
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Wed Jul 17 11:20:08 2019 -0700
+
+    Revert "Revert previous change"
+    
+    This reverts commit b8e90ca1a10fbd472eda1aa8cc3797011da52356.
+    
+    Works now.
+
+ src/hb-subset-plan.cc | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 576065b4429109359c3af491b34b9ab0c6b149ee
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Wed Jul 17 11:19:34 2019 -0700
+
+    [iter] Fix reduce type deduction
+
+ src/hb-iter.hh | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 4552864c82c876da738ec3bf772cc089216f2fd2
+Author: Ebrahim Byagowi <ebrahim@gnu.org>
+Date:   Wed Jul 17 22:08:39 2019 +0430
+
+    [ci] Disable -linux-arm64 bot
+    
+    This is its failure https://circleci.com/gh/harfbuzz/harfbuzz/99864
+    
+    Trying to fix like ee05627, interestingly, makes the bot and the
+    others to fail like this https://circleci.com/gh/harfbuzz/harfbuzz/99841
+
+ .circleci/config.yml | 16 ++++++++--------
+ 1 file changed, 8 insertions(+), 8 deletions(-)
+
+commit b8e90ca1a10fbd472eda1aa8cc3797011da52356
+Author: Ebrahim Byagowi <ebrahim@gnu.org>
+Date:   Wed Jul 17 21:38:19 2019 +0430
+
+    Revert previous change
+    
+    Interestingly all of the bots disagreed with the change and the complain is... weird.
+
+ src/hb-subset-plan.cc | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit ee05627aff2993c51ed8a4bff3170450c000a28a
+Author: Ebrahim Byagowi <ebrahim@gnu.org>
+Date:   Wed Jul 17 21:28:25 2019 +0430
+
+    Improve syntax to make out linux-arm64 a little happy
+    
+    Decided to apply is we did the same on other places however this won't
+    fix all of its complains
+
+ src/hb-subset-plan.cc | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 6a6bf7b7bc4a0b375fcf04ff7c674bf76e6d51aa
+Author: Ebrahim Byagowi <ebrahim@gnu.org>
+Date:   Wed Jul 17 21:22:38 2019 +0430
+
+    Downgrade -Wdeprecated-declarations to warning
+    
+    Fixes #1834 at least till fix of #1829
+
+ src/hb.hh | 1 +
+ 1 file changed, 1 insertion(+)
+
+commit 25e2562fdff6c14a9cb70999a1ad71ee1bdff494
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Wed Jul 17 09:35:56 2019 -0700
+
+    [amalgam] Fix redundant-declaration warning/error
+
+ src/hb-unicode.cc | 8 ++++++--
+ 1 file changed, 6 insertions(+), 2 deletions(-)
+
+commit c184180228540c23405aaa03b6b571bb41103b45
+Author: Ali Javadi <ali.djavadi@gmail.com>
+Date:   Tue Jul 16 22:10:24 2019 +0430
+
+    Fix C++20 compile warning on implicit capture of this with '=' default capture (#1833)
+    
+    Happens when compiled with -std=c++2a, the fix just makes the captures explicit to resolve the issue. Just adding this in addition to = doesn't work in C++11.
+    
+    src/hb-ot-layout-gpos-table.hh:737:18: warning: implicit capture of 'this' with a capture default of '=' is deprecated [-Wdeprecated-this-capture]
+                  { return (this+_).intersects (glyphs, valueFormat); })
+                            ^
+    src/hb-ot-layout-gpos-table.hh:736:16: note: add an explicit capture of 'this' to capture '*this' by reference
+        | hb_map ([=] (const OffsetTo<PairSet> &_)
+                   ^
+                    , this
+
+ src/hb-ot-layout-gpos-table.hh | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 1f94388516befe137d265c261f687a47ce6f8e69
+Author: Ebrahim Byagowi <ebrahim@gnu.org>
+Date:   Tue Jul 16 11:24:29 2019 +0430
+
+    [usp] define atfree callback only if used
+
+ src/hb-uniscribe.cc | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+commit 1da1b4dc94c500e4c9c833ab74fced07364d13fb
+Author: Qunxin Liu <qxliu@google.com>
+Date:   Wed Jun 26 13:23:24 2019 -0700
+
+    [subset] For option "--unicodes",  add support for "*" to retain all code points
+
+ ...aa-Regular-new.default.retain-all-codepoint.ttf | Bin 0 -> 97204 bytes
+ ...drop-hints-retain-gids.retain-all-codepoint.ttf | Bin 0 -> 65976 bytes
+ ...Regular-new.drop-hints.retain-all-codepoint.ttf | Bin 0 -> 65936 bytes
+ ...a-Regular-new.name-ids.retain-all-codepoint.ttf | Bin 0 -> 96948 bytes
+ ...egular-new.retain-gids.retain-all-codepoint.ttf | Bin 0 -> 97244 bytes
+ ...to-Regular.abc.default.retain-all-codepoint.ttf | Bin 0 -> 2168 bytes
+ ...drop-hints-retain-gids.retain-all-codepoint.ttf | Bin 0 -> 924 bytes
+ ...Regular.abc.drop-hints.retain-all-codepoint.ttf | Bin 0 -> 924 bytes
+ ...o-Regular.abc.name-ids.retain-all-codepoint.ttf | Bin 0 -> 2168 bytes
+ ...egular.abc.retain-gids.retain-all-codepoint.ttf | Bin 0 -> 2168 bytes
+ test/subset/data/tests/basics.tests                |   1 +
+ test/subset/subset_test_suite.py                   |  20 +++++++---
+ util/hb-subset.cc                                  |   7 ++++
+ util/options.cc                                    |  44 ++++++++++++---------
+ 14 files changed, 48 insertions(+), 24 deletions(-)
+
+commit 68ac767e430c4dfe4c556b2c4f962cc3dfc5d3e4
+Author: blueshade7 <ariza@typekit.com>
+Date:   Fri Jul 12 23:02:29 2019 -0700
+
+    added skip(), get_next_value() to inc_bimap to subset VarStore with retain-gids
+
+ src/hb-bimap.hh            | 25 ++++++++++++++++++++++++-
+ src/hb-ot-layout-common.hh | 14 +++++++-------
+ 2 files changed, 31 insertions(+), 8 deletions(-)
+
+commit 4730b350b7ee90338caf3e962343af42412ce3df
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Fri Jul 12 15:38:35 2019 -0700
+
+    Revert "Update Graphite API to latest (#1215)"
+    
+    This reverts commit e4e74c2751ac24178086cce2811d34d8019b6f85.
+    
+    See https://github.com/harfbuzz/harfbuzz/issues/1829
+
+ src/hb-graphite2.cc | 28 +---------------------------
+ 1 file changed, 1 insertion(+), 27 deletions(-)
+
+commit f8242b61ab01002e9f7374daa8755e92c6a92eb4
+Author: Ebrahim Byagowi <ebrahim@gnu.org>
+Date:   Thu Jul 11 15:10:36 2019 +0430
+
+    [fuzz] Increase subset runner timeout for tsan bot
+    
+    Now is flaky let's just increase and maybe investigate later
+
+ test/fuzzing/run-subset-fuzzer-tests.py | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit b65bad18aa527684af999b5808a9087404c0759a
+Author: Ebrahim Byagowi <ebrahim@gnu.org>
+Date:   Thu Jul 11 14:31:55 2019 +0430
+
+    [fuzz] Don't fail when blob is empty
+    
+    And enable more tests able to trig the issue.
+
+ ...zz-testcase-minimized-hb-subset-fuzzer-5738978499624960 | Bin 0 -> 28 bytes
+ test/fuzzing/hb-subset-fuzzer.cc                           |   2 +-
+ test/fuzzing/run-subset-fuzzer-tests.py                    |   9 +++++----
+ 3 files changed, 6 insertions(+), 5 deletions(-)
+
+commit 7a9d643c297990f9889a2f7b4a470ef933bac131
+Author: Ebrahim Byagowi <ebrahim@gnu.org>
+Date:   Thu Jul 11 01:35:06 2019 +0430
+
+    Fix unintialized memory read in cmap subset (#1826)
+
+ src/hb-ot-cmap-table.hh | 10 +++++++++-
+ 1 file changed, 9 insertions(+), 1 deletion(-)
+
+commit a6065d05cf38620c06b6dd10b8a841ed236f76c2
+Author: Ebrahim Byagowi <ebrahim@gnu.org>
+Date:   Wed Jul 10 16:41:40 2019 +0430
+
+    Don't call memcpy when a table is empty
+
+ src/hb-open-file.hh | 7 ++++---
+ 1 file changed, 4 insertions(+), 3 deletions(-)
+
+commit c85f624b519df1db141bf55d9452bc2837ef35c4
+Author: Ebrahim Byagowi <ebrahim@gnu.org>
+Date:   Wed Jul 10 14:28:06 2019 +0430
+
+    Force blob generation and memory check in hb-subset-fuzzer
+
+ test/fuzzing/hb-subset-fuzzer.cc | 14 ++++++++++++++
+ 1 file changed, 14 insertions(+)
+
+commit 2e7021da7d1726a37822e6a001b9218f82255bc8
+Author: Dominik Röttsches <drott@chromium.org>
+Date:   Mon Jul 8 10:19:49 2019 +0300
+
+    Revert "Minor" - revert moving extern "C" definitions in-function
+    
+    This reverts commit 62e60322cb9e18b3ee75f1b4a2a6d3069f587407 since it
+    breaks building HarfBuzz as part of Chromium.
+    
+    Fixes https://github.com/harfbuzz/harfbuzz/issues/1821.
+
+ src/hb-unicode.cc | 5 +++--
+ 1 file changed, 3 insertions(+), 2 deletions(-)
+
+commit f18ea1dd3a9961661a383b2966de57ea68a267e7
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Fri Jul 5 13:56:45 2019 -0700
+
+    [font] Remove division when scaling
+    
+    Yoohoo.  This seems to be precise enough!  Let's see if it sticks.
+    I'm asking Dominik to run this in Chrome test suite and report.
+    
+    Fixes https://github.com/harfbuzz/harfbuzz/issues/1801
+
+ src/hb-font.hh          | 23 +++++++++--------------
+ src/hb-ot-math-table.hh | 16 ++++++++--------
+ 2 files changed, 17 insertions(+), 22 deletions(-)
+
+commit b847769292aca13345fd1facae35aaf999198ad4
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Fri Jul 5 13:52:09 2019 -0700
+
+    [font] Keep font-space to user-space multiplier
+    
+    Part of https://github.com/harfbuzz/harfbuzz/issues/1801
+
+ src/hb-font.cc |  5 +++++
+ src/hb-font.hh | 13 +++++++++++--
+ 2 files changed, 16 insertions(+), 2 deletions(-)
+
+commit df6edcd44ceb63d01d9c0d6d2aa06b6c6cbb914d
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Fri Jul 5 13:45:15 2019 -0700
+
+    Make face immutable in hb_font_set_face()
+
+ src/hb-font.cc | 1 +
+ 1 file changed, 1 insertion(+)
+
+commit 0d425e1eeaea97bf5e4fc9ce40e549332bc0cea1
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Fri Jul 5 13:18:05 2019 -0700
+
+    [ot-font] Optimize rounding
+    
+    Part of https://github.com/harfbuzz/harfbuzz/issues/1801
+    
+    The assumption that compiler optimizes "upem/2" to a shift only
+    works if upem is unsigned...  Anyway, spoon-feed the compiler.
+
+ src/hb-font.hh | 6 ++++--
+ 1 file changed, 4 insertions(+), 2 deletions(-)
+
+commit 144326e215671a42fb3ac9f00ddef779ba354345
+Author: Simon Sapin <simon.sapin@exyr.org>
+Date:   Fri Jul 5 19:05:11 2019 +0200
+
+    Clusters are reversed based on the direction, not script
+    
+    Fixes https://github.com/harfbuzz/harfbuzz/issues/1818
+
+ docs/usermanual-clusters.xml | 6 ++++--
+ 1 file changed, 4 insertions(+), 2 deletions(-)
+
+commit cf1a782a5ca82a880906cae3d4cb76b10ec2aad2
+Author: Simon Sapin <simon.sapin@exyr.org>
+Date:   Thu Jul 4 21:06:59 2019 +0200
+
+    Docs: fix a typo in function name
+
+ docs/usermanual-fonts-and-faces.xml | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit ffa736f151f27adb76fb0bf91e18e1ec5cb8fe8d
+Author: Simon Sapin <simon.sapin@exyr.org>
+Date:   Thu Jul 4 23:05:50 2019 +0200
+
+    hb_set_previous_range docs: fix presumed copy/paste error
+
+ src/hb-set.cc | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 641f33738089ef7ccbedce09886309edcd2e1718
+Author: Simon Sapin <simon.sapin@exyr.org>
+Date:   Thu Jul 4 23:03:45 2019 +0200
+
+    Docs typo fix: slower → lower
+
+ src/hb-set.cc | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 9fea6b4dd41bfe2b85f788523162658a7ab9bd49
+Author: Ebrahim Byagowi <ebrahim@gnu.org>
+Date:   Fri Jul 5 18:46:41 2019 +0430
+
+    [amalgam] Use it in cmake port and fix conflicts (#1812)
+
+ .circleci/config.yml           |  8 ++---
+ CMakeLists.txt                 | 74 ++++--------------------------------------
+ src/Makefile.am                |  2 ++
+ src/hb-cff-interp-common.hh    |  6 ++--
+ src/hb-cff-interp-cs-common.hh |  2 +-
+ src/hb-coretext.cc             |  4 +--
+ src/hb-directwrite.cc          | 14 ++++----
+ src/hb-ft.cc                   |  4 +--
+ 8 files changed, 27 insertions(+), 87 deletions(-)
+
+commit b240d701fd98efa59a7f772ff39654fc95b8fc8f
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Wed Jul 3 12:17:57 2019 -0700
+
+    [amalgam] Include integration source files as well
+    
+    Just for those that are normally built into libharfbuzz itself.
+    
+    Part of https://github.com/harfbuzz/harfbuzz/issues/1809
+
+ src/Makefile.am | 12 ++++++++++--
+ src/harfbuzz.cc |  6 ++++++
+ 2 files changed, 16 insertions(+), 2 deletions(-)
+
+commit d51524204528b36907ab0f48bf2a48ec124c93d9
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Wed Jul 3 12:10:03 2019 -0700
+
+    [amalgam] Rename hb.cc to harfbuzz.cc
+    
+    Part of https://github.com/harfbuzz/harfbuzz/issues/1809
+
+ src/Makefile.am            | 8 ++++----
+ src/{hb.cc => harfbuzz.cc} | 0
+ 2 files changed, 4 insertions(+), 4 deletions(-)
+
+commit 4cb180d227c1adc32e921c241a93cd1f50a98d33
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Tue Jul 2 19:44:18 2019 -0700
+
+    Revert "Use constexpr to replace passthru_ bools"
+    
+    This reverts commit c4aa10ebc8dc28b1f9c90af2ca2092a7535f8395.
+    
+    Broke several compilers... Sigh.  The version without constexpr
+    didn't fully optimize out the unreachable code on clang.
+    So, revert it is...
+
+ src/hb-algs.hh |  8 ++++++++
+ src/hb-set.hh  | 18 ++++++++----------
+ 2 files changed, 16 insertions(+), 10 deletions(-)
+
+commit c4aa10ebc8dc28b1f9c90af2ca2092a7535f8395
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Tue Jul 2 19:15:03 2019 -0700
+
+    Use constexpr to replace passthru_ bools
+
+ src/hb-algs.hh |  8 --------
+ src/hb-set.hh  | 18 ++++++++++--------
+ 2 files changed, 10 insertions(+), 16 deletions(-)
+
+commit 2e48fd077954410f59156b3100c16bf56a507948
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Tue Jul 2 17:55:58 2019 -0700
+
+    Sprinkle constexpr around
+    
+    Being conservative.  Also not sure it makes any real difference
+    in our codebase.
+
+ src/hb-algs.hh | 48 ++++++++++++++++++++++++------------------------
+ src/hb-meta.hh | 18 +++++++++---------
+ 2 files changed, 33 insertions(+), 33 deletions(-)
+
+commit df4448064e370a410404708a15ce819daf1d9386
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Tue Jul 2 17:11:09 2019 -0700
+
+    Remove unused 'inline' specifier
+
+ src/hb-ot-map.hh     |  4 ++--
+ src/hb-shape-plan.hh | 18 +++++++++---------
+ 2 files changed, 11 insertions(+), 11 deletions(-)
+
+commit 04a4957040380bba58880ff51d529c5cccf1d2c7
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Tue Jul 2 16:19:18 2019 -0700
+
+    [amalgam] Add hb.cc to git
+    
+    Part of https://github.com/harfbuzz/harfbuzz/issues/1809
+
+ src/Makefile.am |  1 +
+ src/hb.cc       | 44 ++++++++++++++++++++++++++++++++++++++++++++
+ 2 files changed, 45 insertions(+)
+
+commit 62e60322cb9e18b3ee75f1b4a2a6d3069f587407
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Tue Jul 2 16:07:03 2019 -0700
+
+    Minor
+
+ src/hb-unicode.cc | 5 ++---
+ 1 file changed, 2 insertions(+), 3 deletions(-)
+
+commit ceb4c212dc91a277f646c4a5354e4362f548a9f6
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Tue Jul 2 16:02:13 2019 -0700
+
+    [amalgam] Fix UCD issue
+    
+    This actually makes it build now!
+    
+    Part https://github.com/harfbuzz/harfbuzz/issues/1809
+    
+    Keeping open to add tests, CI, etc.
+
+ src/hb-ucd.cc     | 5 +----
+ src/hb-unicode.cc | 2 --
+ src/hb-unicode.hh | 3 +++
+ 3 files changed, 4 insertions(+), 6 deletions(-)
+
+commit 7ca54811f471a28163de6b3c561990c85aa39880
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Tue Jul 2 16:00:58 2019 -0700
+
+    [amalgam] Fix CFF
+    
+    Part of https://github.com/harfbuzz/harfbuzz/issues/1809
+
+ src/hb-ot-cff1-table.cc | 18 +++++++++---------
+ src/hb-ot-cff2-table.cc | 16 ++++++++--------
+ 2 files changed, 17 insertions(+), 17 deletions(-)
+
+commit 3724f13ba0292055197efdbfcacfe3d7b067175c
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Tue Jul 2 15:23:00 2019 -0700
+
+    [amalgam] Finish fixing Indic-like shapers
+    
+    Part of https://github.com/harfbuzz/harfbuzz/issues/1809
+
+ src/hb-ot-shape-complex-indic.cc   | 34 +++++++++++++++++-----------------
+ src/hb-ot-shape-complex-indic.hh   |  9 ++++++++-
+ src/hb-ot-shape-complex-khmer.cc   | 18 +++++++++---------
+ src/hb-ot-shape-complex-khmer.hh   | 17 ++++++++---------
+ src/hb-ot-shape-complex-myanmar.cc |  8 ++++----
+ src/hb-ot-shape-complex-myanmar.hh | 16 ++++++++--------
+ src/hb-ot-shape-complex-use.cc     | 14 +++++++-------
+ 7 files changed, 61 insertions(+), 55 deletions(-)
+
+commit eb37bc9d93b3abebee24390708940510fe37477a
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Tue Jul 2 15:19:39 2019 -0700
+
+    [use] Remove Syriac features
+    
+    This was non-standard, and unused anyway.
+
+ src/hb-ot-shape-complex-use.cc | 7 +------
+ 1 file changed, 1 insertion(+), 6 deletions(-)
+
+commit dc480fc4717937d53cf38860a5c5d48211e8cbc8
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Tue Jul 2 15:17:56 2019 -0700
+
+    [amalgam] More Indic-like issues
+    
+    Part of https://github.com/harfbuzz/harfbuzz/issues/1809
+
+ src/hb-ot-shape-complex-indic.cc | 76 +++++++++++++++++++++-------------------
+ src/hb-ot-shape-complex-khmer.cc | 36 ++++++++++---------
+ src/hb-ot-shape-complex-use.cc   | 32 ++++++++---------
+ 3 files changed, 74 insertions(+), 70 deletions(-)
+
+commit d8b5353e07650cf243ba182dbf52e7f198719762
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Tue Jul 2 15:09:26 2019 -0700
+
+    [amalgam] More
+    
+    Part of https://github.com/harfbuzz/harfbuzz/issues/1809
+
+ src/hb-ot-shape-complex-myanmar.cc | 28 ++++++++++++++--------------
+ src/hb-ot-shape-complex-use.cc     | 28 ++++++++++++++--------------
+ 2 files changed, 28 insertions(+), 28 deletions(-)
+
+commit d115a9e022c0b687fb402cfd2b90d516beded5c0
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Tue Jul 2 14:42:45 2019 -0700
+
+    [amalgam] Fix most duplicate-id instances in Indic-like shapers
+    
+    Part of https://github.com/harfbuzz/harfbuzz/issues/1809
+
+ src/hb-ot-layout.hh                        |  22 +++++
+ src/hb-ot-shape-complex-indic-machine.hh   |   6 +-
+ src/hb-ot-shape-complex-indic-machine.rl   |   6 +-
+ src/hb-ot-shape-complex-indic.cc           | 130 +++++++++----------------
+ src/hb-ot-shape-complex-indic.hh           |  26 +++++
+ src/hb-ot-shape-complex-khmer-machine.hh   |   6 +-
+ src/hb-ot-shape-complex-khmer-machine.rl   |   6 +-
+ src/hb-ot-shape-complex-khmer.cc           |  97 ++++++-------------
+ src/hb-ot-shape-complex-myanmar-machine.hh |   4 +-
+ src/hb-ot-shape-complex-myanmar-machine.rl |   4 +-
+ src/hb-ot-shape-complex-myanmar.cc         |  69 ++++++--------
+ src/hb-ot-shape-complex-use-machine.hh     |   4 +-
+ src/hb-ot-shape-complex-use-machine.rl     |   4 +-
+ src/hb-ot-shape-complex-use.cc             | 148 ++++++++++++-----------------
+ 14 files changed, 230 insertions(+), 302 deletions(-)
+
+commit c073233f45da6ad8131dd38cb43b125f48c17432
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Tue Jul 2 14:26:45 2019 -0700
+
+    Add make rule to build hb.cc
+    
+    Part of https://github.com/harfbuzz/harfbuzz/issues/1809
+
+ src/Makefile.am | 6 ++++++
+ 1 file changed, 6 insertions(+)
+
+commit f1d20d9b4dcbeead3757650b9286393918b4be8a
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Tue Jul 2 14:18:38 2019 -0700
+
+    Add ucd-table make target
+
+ src/Makefile.am      | 23 +++++++++++++++--------
+ src/gen-ucd-table.py |  8 +++++---
+ 2 files changed, 20 insertions(+), 11 deletions(-)
+
+commit 634390ecaf600176245e3354edd8dfdcb7f64cc5
+Author: blueshade7 <ariza@typekit.com>
+Date:   Mon Jul 1 18:52:57 2019 -0700
+
+    added VariationStore serializer to be used by HVAR/VVAR subsetters
+
+ src/hb-ot-layout-common.hh | 165 ++++++++++++++++++++++++++++++++++++++++++++-
+ 1 file changed, 163 insertions(+), 2 deletions(-)
+
+commit 040b261deeed8924edcb087e27a61392d1f85023
+Author: Michiharu Ariza <ariza@typekit.com>
+Date:   Sun Jun 30 16:13:07 2019 -0700
+
+    add bimap test along with bug fix/tweaks
+
+ src/Makefile.am   |  6 ++++-
+ src/hb-bimap.hh   |  4 +++
+ src/test-bimap.cc | 76 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
+ 3 files changed, 85 insertions(+), 1 deletion(-)
+
+commit 9c93f5cc2de5c60d5464a65890fc7d8c25aa9702
+Merge: ad341d5f 4ab2d1d6
+Author: Ebrahim Byagowi <ebrahim@gnu.org>
+Date:   Mon Jul 1 20:08:22 2019 +0430
+
+    Merge pull request #1806 from carlo-bramini/master
+    
+    Make harfbuzz working on all existing versions of Windows
+
+commit 4ab2d1d6767568c45495be515e016805cce0c69a
+Author: Ebrahim Byagowi <ebrahim@gnu.org>
+Date:   Mon Jul 1 19:30:21 2019 +0430
+
+    [dwrite] Apply minor style improves
+
+ src/hb-directwrite.cc | 16 ++++++++--------
+ 1 file changed, 8 insertions(+), 8 deletions(-)
+
+commit 5ebd265e66cbcd167469837dcf8647484310dfb5
+Author: Carlo Bramini <30959007+carlo-bramini@users.noreply.github.com>
+Date:   Mon Jul 1 16:06:43 2019 +0200
+
+    Fix error rised by GCC8+
+
+ src/hb-directwrite.cc | 10 ++++++++++
+ 1 file changed, 10 insertions(+)
+
+commit 693dacbb1c0bc805e3e6aedaca5a57f04eb6ec9c
+Author: Carlo Bramini <30959007+carlo-bramini@users.noreply.github.com>
+Date:   Mon Jul 1 13:31:26 2019 +0200
+
+    Use lower case file name with #include
+    
+    I tried to cross compile harfbuzz for Windows and an error was generated because `DWrite_1.h` was not found.
+    This happened because the filesystem is case sensitive and for this reason that include file was not found.
+    The right name of the file to be used is `dwrite_1.h`, with all letters not capitalized:
+    https://docs.microsoft.com/en-us/windows/desktop/api/dwrite_1/
+    I also verified in the installation of VS2017 with Windows Kit v10 and in that place it was also lower case.
+    So, in my opinion it should be better to change this.
+
+ src/hb-directwrite.cc | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit a4543d408b31376c38bab878b2f72d4323abc564
+Author: Carlo Bramini <30959007+carlo-bramini@users.noreply.github.com>
+Date:   Sun Jun 30 15:06:30 2019 +0200
+
+    Empty DIRECTWRITE_LIBS
+    
+    Not used anymore since DWRITE is loaded dynamically.
+
+ configure.ac | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 601b6825b05f67354b48dd3629b95e0d8bf68a14
+Author: Carlo Bramini <30959007+carlo-bramini@users.noreply.github.com>
+Date:   Sun Jun 30 15:03:44 2019 +0200
+
+    Dynamically load DWRITE
+    
+    Also checks if DWriteCreateFactory() has been executed successfully.
+
+ src/hb-directwrite.cc | 41 +++++++++++++++++++++++++++++++++--------
+ 1 file changed, 33 insertions(+), 8 deletions(-)
+
+commit ad341d5f1624f4e30b2d0eb2a171054a973053b5
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Fri Jun 28 16:00:37 2019 -0700
+
+    [config] Fix CoreText build with NO_AAT
+
+ src/hb-aat-layout.cc | 8 +++++---
+ 1 file changed, 5 insertions(+), 3 deletions(-)
+
+commit 3f806673fbeacdbe1b31399394ccc26c773a794b
+Author: Ebrahim Byagowi <ebrahim@gnu.org>
+Date:   Sat Jun 29 00:00:00 2019 +0430
+
+    Apply some minor improves on CFFIndex
+
+ src/hb-ot-cff-common.hh | 38 +++++++++++++-------------------------
+ 1 file changed, 13 insertions(+), 25 deletions(-)
+
+commit ddd29e5594ccc9d0281e6da7373a1f115f6f6f3a
+Author: Ebrahim Byagowi <ebrahim@gnu.org>
+Date:   Fri Jun 28 23:44:14 2019 +0430
+
+    minor, reuse StructAtOffset logic in StructAtOffsetOrNull
+
+ src/hb-ot-cff-common.hh | 12 ++++++------
+ 1 file changed, 6 insertions(+), 6 deletions(-)
+
+commit 9db7ce73d7ac6566837cdd70d38c45f3aefd7769
+Author: Ebrahim Byagowi <ebrahim@gnu.org>
+Date:   Fri Jun 28 23:11:52 2019 +0430
+
+    minor style improve in hb-cff-interp-common.hh
+
+ src/hb-cff-interp-common.hh | 91 +++++++++++++++------------------------------
+ 1 file changed, 30 insertions(+), 61 deletions(-)
+
+commit 9a7b7bd9fc5bde7796ffdd997ee65cb33cbf6b29
+Author: Ebrahim Byagowi <ebrahim@gnu.org>
+Date:   Fri Jun 28 22:53:51 2019 +0430
+
+    style fix for pylint complain
+
+ src/gen-emoji-table.py | 20 ++++++++++----------
+ 1 file changed, 10 insertions(+), 10 deletions(-)
+
+commit 8d36ef50c8712be476572514d73b7bddf43e5951
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Thu Jun 27 14:48:10 2019 -0700
+
+    [config] Add links
+
+ CONFIG.md | 6 +++++-
+ 1 file changed, 5 insertions(+), 1 deletion(-)
+
+commit f53590971c5326dd15f4296764bfd1255ec0506a
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Thu Jun 27 13:42:51 2019 -0700
+
+    [test] Make Unicode tests strict against internal UCD
+    
+    https://github.com/harfbuzz/harfbuzz/pull/1799
+
+ test/api/test-unicode.c | 30 ++++++++++++++++++++++--------
+ 1 file changed, 22 insertions(+), 8 deletions(-)
+
+commit d42264f151a61a4a77e5d5712e535fc6e2daf338
+Author: David Corbett <corbett.dav@husky.neu.edu>
+Date:   Wed Jun 26 21:10:11 2019 -0400
+
+    Test at least one character per Unicode version
+
+ test/api/test-unicode.c | 142 ++++++++++++++++++++++++++++++++++++++++++++++--
+ 1 file changed, 138 insertions(+), 4 deletions(-)
+
+commit 7185bd6ffb4dd8c0efebdab5b930e62c5695e3ab
+Merge: cd65305b 8341c0b3
+Author: Ebrahim Byagowi <ebrahim@gnu.org>
+Date:   Thu Jun 27 22:09:28 2019 +0430
+
+    Merge pull request #1800 from harfbuzz/harfbuzz/cffnull_fix2
+    
+    [CFF] fix for Subrs null ptr access
+
+commit 8341c0b304ee3bb0b7d150bcfb42a8b9e6448687
+Author: Michiharu Ariza <ariza@typekit.com>
+Date:   Thu Jun 27 08:43:31 2019 -0700
+
+    add test case file
+
+ ...z-testcase-minimized-harfbuzz_fuzzer-5093685255077888 | Bin 0 -> 1160 bytes
+ 1 file changed, 0 insertions(+), 0 deletions(-)
+
+commit 01832fd16b605971466fc3b174cb932787ef4bfb
+Author: Michiharu Ariza <ariza@typekit.com>
+Date:   Wed Jun 26 15:58:38 2019 -0700
+
+    alternate fix for https://crbug.com/971933
+
+ src/hb-cff-interp-cs-common.hh | 6 +++---
+ src/hb-cff1-interp-cs.hh       | 2 +-
+ src/hb-cff2-interp-cs.hh       | 2 +-
+ 3 files changed, 5 insertions(+), 5 deletions(-)
+
+commit cd65305b059e7495f4f993d25cfda4d88781589b
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Wed Jun 26 14:57:48 2019 -0700
+
+    [config] Don't disable emoji sequences in HB_TINY
+    
+    It makes sense to disable this code these if editing is not needed.
+    However, this is also necessary to correctly display emoji sequences
+    in right-to-left direction.  For that reason, don't auto-disable it.
+
+ src/hb-config.hh   | 1 -
+ src/hb-ot-shape.cc | 2 +-
+ src/hb-unicode.cc  | 2 +-
+ 3 files changed, 2 insertions(+), 3 deletions(-)
+
+commit 7298716a3cfbdabedd15960404623317a64db3ae
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Wed Jun 26 14:51:17 2019 -0700
+
+    [config] Compile out modified combining-class if HB_NO_OT_SHAPE
+    
+    Part of https://github.com/harfbuzz/harfbuzz/issues/1652
+
+ src/hb-unicode.cc | 2 ++
+ 1 file changed, 2 insertions(+)
+
+commit 1cdd0fa60d9a6aaddc20e646d294d642e2db9be4
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Wed Jun 26 14:49:15 2019 -0700
+
+    [emoji] Port generator to packtab
+
+ src/gen-emoji-table.py        |  18 ++++--
+ src/hb-unicode-emoji-table.hh | 126 ++++++++++++++++--------------------------
+ src/hb-unicode.cc             |   5 +-
+ 3 files changed, 60 insertions(+), 89 deletions(-)
+
+commit 5130c90ac0173c542b550049c93738ab5de84bb9
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Wed Jun 26 14:29:39 2019 -0700
+
+    [config] Add HB_NO_EMOJI
+    
+    Part of https://github.com/harfbuzz/harfbuzz/issues/1652
+
+ src/hb-config.hh   | 1 +
+ src/hb-ot-shape.cc | 2 ++
+ src/hb-unicode.cc  | 2 ++
+ 3 files changed, 5 insertions(+)
+
+commit 9d5b5348c7ca1e39faa9e197fdebfb8f5d3aeece
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Wed Jun 26 13:58:40 2019 -0700
+
+    [config] Add HB_NO_SHAPER
+    
+    Don't know who would want when why.  But makes sense to have.
+
+ src/hb-shaper-list.hh | 6 ++++++
+ src/hb-shaper.cc      | 2 ++
+ 2 files changed, 8 insertions(+)
+
+commit 8fe15485cbc2f56adb29d4d5f0c3957869bd0e1a
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Wed Jun 26 13:49:42 2019 -0700
+
+    [config] Add HB_NO_OT_TAG
+    
+    Part of https://github.com/harfbuzz/harfbuzz/issues/1652
+
+ src/hb-config.hh    | 1 +
+ src/hb-ot-layout.cc | 4 ++++
+ src/hb-ot-tag.cc    | 5 +++++
+ src/hb-uniscribe.cc | 4 ++++
+ 4 files changed, 14 insertions(+)
+
+commit 7dcf8e126ecf52c67f59745e04d21df68b1a6992
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Wed Jun 26 13:44:10 2019 -0700
+
+    [config] Fix build with HB_NO_OT_LAYOUT
+
+ src/hb-ot-face-table-list.hh   | 2 ++
+ src/hb-ot-layout-gpos-table.hh | 3 ++-
+ src/hb-ot-layout-gsub-table.hh | 5 +++--
+ src/hb-ot-layout-gsubgpos.hh   | 8 +++++++-
+ 4 files changed, 14 insertions(+), 4 deletions(-)
+
+commit 2804790bceb9398cc9b668ca63f5aa9ffe29beeb
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Wed Jun 26 13:38:14 2019 -0700
+
+    [config] Add dependency
+
+ src/hb-ot-shape.cc | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+commit b0fd16eec62dea29d984bab879064ae9d91afdfc
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Wed Jun 26 13:31:51 2019 -0700
+
+    [config] Add dependency
+
+ src/hb-config.hh | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+commit 12092a46d8826eec5dcf69e7817921380e4bc507
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Wed Jun 26 13:31:01 2019 -0700
+
+    [config] Rename HB_NO_SHAPE_AAT to HB_NO_AAT_SHAPE
+
+ src/hb-aat-map.cc       |  2 +-
+ src/hb-config.hh        |  2 +-
+ src/hb-ot-kern-table.hh | 14 +++++++-------
+ src/hb-ot-layout.cc     |  2 +-
+ src/hb-ot-shape.cc      | 36 ++++++++++++++++++------------------
+ src/hb-ot-shape.hh      |  8 ++++----
+ 6 files changed, 32 insertions(+), 32 deletions(-)
+
+commit bb4bbe617d3878ca7e5e359ada493c68ec7f0a90
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Wed Jun 26 13:29:58 2019 -0700
+
+    [config] Add HB_NO_OT_LAYOUT
+    
+    Part of https://github.com/harfbuzz/harfbuzz/issues/1652
+
+ src/hb-config.hh    | 1 +
+ src/hb-ot-layout.cc | 7 +++++++
+ src/hb-ot-map.cc    | 7 +++++++
+ 3 files changed, 15 insertions(+)
+
+commit ab40a2feecf53d2ef787b7785132bf57e5bdcff9
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Wed Jun 26 13:25:02 2019 -0700
+
+    [config] Enable HB_NO_OT_FONT in HB_NO_OT
+
+ CONFIG.md        | 4 ++--
+ src/hb-config.hh | 1 +
+ 2 files changed, 3 insertions(+), 2 deletions(-)
+
+commit 7aad53657eb23264f658711a71da3e50f2264455
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Wed Jun 26 13:21:03 2019 -0700
+
+    [config] Add HB_NO_OT_SHAPE / HB_NO_OT
+    
+    Part of https://github.com/harfbuzz/harfbuzz/issues/1652
+
+ CONFIG.md                                    | 14 ++++++++++++++
+ src/gen-indic-table.py                       |  6 ++++++
+ src/gen-use-table.py                         |  6 ++++++
+ src/gen-vowel-constraints.py                 |  7 +++++++
+ src/hb-config.hh                             |  4 ++++
+ src/hb-ot-shape-complex-arabic.cc            |  6 ++++++
+ src/hb-ot-shape-complex-default.cc           |  7 +++++++
+ src/hb-ot-shape-complex-hangul.cc            |  7 +++++++
+ src/hb-ot-shape-complex-hebrew.cc            |  7 +++++++
+ src/hb-ot-shape-complex-indic-table.cc       |  6 ++++++
+ src/hb-ot-shape-complex-indic.cc             |  7 +++++++
+ src/hb-ot-shape-complex-khmer.cc             |  7 +++++++
+ src/hb-ot-shape-complex-myanmar.cc           |  7 +++++++
+ src/hb-ot-shape-complex-thai.cc              |  7 +++++++
+ src/hb-ot-shape-complex-use-table.cc         |  6 ++++++
+ src/hb-ot-shape-complex-use.cc               |  7 +++++++
+ src/hb-ot-shape-complex-vowel-constraints.cc |  6 ++++++
+ src/hb-ot-shape-fallback.cc                  |  7 +++++++
+ src/hb-ot-shape-normalize.cc                 |  7 +++++++
+ src/hb-ot-shape.cc                           |  7 +++++++
+ src/hb-shape-plan.cc                         | 10 ++++++++++
+ src/hb-shape-plan.hh                         |  4 ++++
+ src/hb-shaper-list.hh                        |  2 ++
+ 23 files changed, 154 insertions(+)
+
+commit cee9f6e044278b590694f4dff6f22eaad9371385
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Wed Jun 26 13:01:58 2019 -0700
+
+    Fail compile if no shapers enabled
+
+ src/hb-shaper.cc | 1 +
+ 1 file changed, 1 insertion(+)
+
+commit 8786820a5a7406be95bc4a6b6e2aca736126420c
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Wed Jun 26 12:53:57 2019 -0700
+
+    [src] Add make targets "tiny" and "tinyz"
+
+ src/Makefile.am | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+commit b14e413fae8f14b75c5956e9b38e413c878ded0c
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Wed Jun 26 10:44:10 2019 -0700
+
+    2.5.3
+
+ NEWS             | 7 +++++++
+ configure.ac     | 2 +-
+ src/hb-version.h | 4 ++--
+ 3 files changed, 10 insertions(+), 3 deletions(-)
+
+commit 3bfa878c98cceeaae074d81c14329e358bea8912
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Tue Jun 25 19:07:07 2019 -0700
+
+    [gen-ucd] Protect against accidents like previous commit
+    
+    https://github.com/harfbuzz/harfbuzz/pull/1796
+
+ src/gen-ucd-table.py | 24 +++++++++++-------------
+ 1 file changed, 11 insertions(+), 13 deletions(-)
+
+commit f4ea1a9afb4849e7cfb7a5eb9e81e4f656c3f89e
+Author: David Corbett <corbett.dav@husky.neu.edu>
+Date:   Tue Jun 25 21:08:14 2019 -0400
+
+    [ucd] Include scripts added in Unicode 10 or later
+
+ src/gen-ucd-table.py |   2 +-
+ src/hb-ucd-table.hh  | 970 +++++++++++++++++++++++++++------------------------
+ 2 files changed, 511 insertions(+), 461 deletions(-)
+
+commit 10bd6b8d913a57260b35c1ef830db37c06eebd18
+Author: Michiharu Ariza <ariza@typekit.com>
+Date:   Thu Jun 20 16:22:08 2019 -0700
+
+    minor
+
+ src/hb-bimap.hh | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit f3ee2bd020f8ca313fae783cc49a374f1377e877
+Author: Michiharu Ariza <ariza@typekit.com>
+Date:   Thu Jun 20 14:33:09 2019 -0700
+
+    add ops & methods to hb_bimap_t making it more like hb_map_t
+    moved has () to hb_bimap_t from hb_inc_bimap_t
+    moved identity () to hb_inc_bimap_t
+    removed forward()
+
+ src/hb-bimap.hh             | 38 ++++++++++++++++++++++++--------------
+ src/hb-ot-cff-common.hh     |  2 +-
+ src/hb-ot-cff1-table.hh     |  4 ++--
+ src/hb-subset-cff-common.cc |  2 +-
+ src/hb-subset-cff-common.hh |  4 ++--
+ src/hb-subset-cff1.cc       |  4 ++--
+ src/hb-subset-cff2.cc       |  2 +-
+ 7 files changed, 33 insertions(+), 23 deletions(-)
+
+commit 094966959f96d9a41fb612fd0b870f5ae8f5a954
+Author: Michiharu Ariza <ariza@adobe.com>
+Date:   Mon Jun 17 22:12:40 2019 -0700
+
+    add hb_bimap_t, subclass hb_inc_bimap_t replacing CFF::remap_t
+
+ src/Makefile.sources        |   1 +
+ src/hb-bimap.hh             | 129 ++++++++++++++++++++++++++++++++++++++++++++
+ src/hb-ot-cff-common.hh     |  64 +++-------------------
+ src/hb-ot-cff1-table.hh     |  16 +++---
+ src/hb-subset-cff-common.cc |  12 ++---
+ src/hb-subset-cff-common.hh |  40 ++++++--------
+ src/hb-subset-cff1.cc       |  26 ++++-----
+ src/hb-subset-cff2.cc       |  31 +++++------
+ 8 files changed, 191 insertions(+), 128 deletions(-)
+
+commit 0660175dc82d82bbb38c45b9cb53190e06f55750
+Author: David Corbett <corbett.dav@husky.neu.edu>
+Date:   Tue Jun 25 10:14:03 2019 -0400
+
+    Categorize U+1133B for use in Tamil
+
+ src/hb-ot-shape-complex-indic.hh | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit fb0df17b2701c1c5623198440aa88a676985bd4f
+Author: David Corbett <corbett.dav@husky.neu.edu>
+Date:   Mon Jun 24 21:54:26 2019 -0400
+
+    Correct "nonunihan" to "nounihan"
+
+ src/gen-ucd-table.py | 4 ++--
+ src/hb-ucd-table.hh  | 2 +-
+ 2 files changed, 3 insertions(+), 3 deletions(-)
+
+commit bb4cdf8e0bcc98a036c22cfd44242502b107fb32
+Author: Ebrahim Byagowi <ebrahim@gnu.org>
+Date:   Tue Jun 25 01:42:42 2019 +0430
+
+    Replace create_from_file with empty blob if HB_NO_OPEN is defined
+
+ src/main.cc                       | 4 ++++
+ src/test-buffer-serialize.cc      | 4 ++++
+ src/test-gpos-size-params.cc      | 4 ++++
+ src/test-gsub-would-substitute.cc | 4 ++++
+ src/test-ot-color.cc              | 4 ++++
+ src/test-ot-name.cc               | 4 ++++
+ src/test.cc                       | 4 ++++
+ 7 files changed, 28 insertions(+)
+
+commit ccf1448238c91da3cba8370ee527229013f6d362
+Author: GaryQian <garyq@google.com>
+Date:   Mon Jun 24 12:57:13 2019 -0700
+
+    Cast long->size_t to ensure comparison of similar types
+
+ src/hb-common.cc | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit ec8e635e0c1a8e5c631a90820be68cf07c52c1a0
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Mon Jun 24 12:37:23 2019 -0700
+
+    [ucd] Use custom encoding to shrink composition data
+    
+    Saves another 2.5kb.
+    
+    Part of https://github.com/harfbuzz/harfbuzz/issues/1652
+
+ src/gen-ucd-table.py |  22 +-
+ src/hb-algs.hh       |   5 +
+ src/hb-ucd-table.hh  | 963 ++++++++++++++++++++++++++++++++++-----------------
+ src/hb-ucd.cc        |  49 ++-
+ 4 files changed, 704 insertions(+), 335 deletions(-)
+
+commit 9c933acaa443889bc2484dbe3ef3e990b299cd52
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Sun Jun 23 17:14:27 2019 -0700
+
+    [ucd] Save a few more bytes
+    
+    Part of https://github.com/harfbuzz/harfbuzz/issues/1652
+
+ src/gen-ucd-table.py | 11 ++++++-----
+ src/hb-ucd-table.hh  | 34 +++++++++++++++++-----------------
+ src/hb-ucd.cc        | 12 ++++++------
+ 3 files changed, 29 insertions(+), 28 deletions(-)
+
+commit 9bd8d66c2ba97aec57597ff85e059a7618260a1c
+Author: Qunxin Liu <qxliu@google.com>
+Date:   Wed Jun 12 11:02:48 2019 -0700
+
+    [subset] VORG table to use _subset2 method and new iterator frameworks
+
+ src/hb-ot-vorg-table.hh | 128 ++++++++++++++----------------------------------
+ src/hb-subset.cc        |   2 +-
+ 2 files changed, 39 insertions(+), 91 deletions(-)
+
+commit 8062979990d348671b465c877e4dd672e1337665
+Merge: ad97ec95 c2d7dfc6
+Author: Ebrahim Byagowi <ebrahim@gnu.org>
+Date:   Sun Jun 23 11:19:48 2019 +0430
+
+    Merge pull request #1788 from jameshilliard/configure-svg
+    
+    Add missing cairo-svg dependency to test-ot-color
+
+commit c2d7dfc68ffcb389c9f73b5ef94da7b270bdcf9e
+Author: James Hilliard <james.hilliard1@gmail.com>
+Date:   Sat Jun 22 19:38:48 2019 -0600
+
+    Add missing cairo-svg dependency to test-ot-color
+
+ src/test-ot-color.cc | 5 +++--
+ 1 file changed, 3 insertions(+), 2 deletions(-)
+
+commit ad97ec95019b1e5170d00953d4dfe392cfb4abb0
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Fri Jun 21 00:44:29 2019 -0700
+
+    [config/ucd] Add HB_NO_UNICODE_UNASSIGNED and activate in HB_TINY
+    
+    Saves another 12kb:
+    
+    $ python ./gen-ucd-table.py ucd.nounihan.grouped.zip > hb-ucd-table.hh && make -j5 CPPFLAGS='-Os -DHB_TINY' -C ~/hb/build/src/  && size ~/hb/build/src/.libs/libharfbuzz_la-hb-ucd.o
+    INFO: Loading UCDXML...
+    INFO: Preparing data tables...
+    INFO: Generating output...
+    INFO:   Compression=1:
+    INFO:       Dataset=gc       FullCost=18612
+    INFO:       Dataset=ccc      FullCost=3550
+    INFO:       Dataset=bmg      FullCost=1548
+    INFO:       Dataset=sc       FullCost=17765
+    INFO:       Dataset=dm       FullCost=13325
+    INFO:   Compression=3:
+    INFO:       Dataset=gc       FullCost=10726
+    INFO:       Dataset=ccc      FullCost=2389
+    INFO:       Dataset=bmg      FullCost=1052
+    INFO:       Dataset=sc       FullCost=13669
+    INFO:       Dataset=dm       FullCost=7780
+    INFO:   Compression=5:
+    INFO:       Dataset=gc       FullCost=8274
+    INFO:       Dataset=ccc      FullCost=2055
+    INFO:       Dataset=bmg      FullCost=908
+    INFO:       Dataset=sc       FullCost=4073
+    INFO:       Dataset=dm       FullCost=7780
+    INFO: Done.
+    
+    Part of https://github.com/harfbuzz/harfbuzz/issues/1652
+
+ CONFIG.md            |    3 +-
+ src/gen-ucd-table.py |   27 +-
+ src/hb-config.hh     |    1 +
+ src/hb-ucd-table.hh  | 1161 +++++++++++++++++++++++++++++++++++++++++++++++++-
+ 4 files changed, 1185 insertions(+), 7 deletions(-)
+
+commit ccea7fa119d139b6a3a429b3b81fac8448f3bab1
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Fri Jun 21 00:42:06 2019 -0700
+
+    [config] Make test build under HB_TINY
+
+ src/test-gpos-size-params.cc | 9 +++++++--
+ 1 file changed, 7 insertions(+), 2 deletions(-)
+
+commit 12cec6c12ec1856e483097e702126214dd25a34a
+Author: Ebrahim Byagowi <ebrahim@gnu.org>
+Date:   Fri Jun 21 22:39:42 2019 +0430
+
+    Don't define hb_blob_create_from_file if HB_NO_OPEN is defined
+
+ src/hb-blob.cc | 6 ++----
+ 1 file changed, 2 insertions(+), 4 deletions(-)
+
+commit 7f3b409e85897ff267f1b6a5ce1b5cdafbfe7afe
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Thu Jun 20 14:24:43 2019 -0700
+
+    Fix build with -O0
+    
+    message_impl was not defined.  That causes trouble if compiler didn't
+    optimize the unreachable call out...
+
+ src/hb-buffer.cc | 1 -
+ src/hb-buffer.hh | 4 ++++
+ 2 files changed, 4 insertions(+), 1 deletion(-)
+
+commit 6b44bf85382146b355a5a3cbbfde48166721ce52
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Thu Jun 20 11:57:19 2019 -0700
+
+    2.5.2
+
+ NEWS             | 12 ++++++++++++
+ configure.ac     |  2 +-
+ src/hb-version.h |  4 ++--
+ 3 files changed, 15 insertions(+), 3 deletions(-)
+
+commit e9f7b338ef599b9cbffa125fe594a9939b8517cb
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Thu Jun 20 11:48:44 2019 -0700
+
+    [config] Adjust description of HB_LEAN
+    
+    https://github.com/harfbuzz/harfbuzz/commit/d84932ba50482b3b47e393714eb77b19173d1f14
+
+ CONFIG.md | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+commit fce3bf8127321bb53b14eb8a5528a2347cd9be8a
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Wed Jun 19 20:34:29 2019 -0700
+
+    [config] Add HB_NO_LAYOUT_COLLECT_GLYPHS
+    
+    Part of
+
+ src/hb-config.hh    | 1 +
+ src/hb-ot-layout.cc | 2 ++
+ 2 files changed, 3 insertions(+)
+
+commit 6c725c7799bf4870fb8b4f896a537a2c0f7a1ccc
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Wed Jun 19 20:12:25 2019 -0700
+
+    [config] Add HB_NO_LAYOUT_FEATURE_PARAMS
+    
+    Part of https://github.com/harfbuzz/harfbuzz/issues/1652
+
+ src/hb-config.hh           | 1 +
+ src/hb-ot-layout-common.hh | 7 +++++--
+ src/hb-ot-layout.cc        | 6 ++----
+ 3 files changed, 8 insertions(+), 6 deletions(-)
+
+commit 27de7c44fe80e69c527578c99c26280ba9f26c15
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Wed Jun 19 20:07:02 2019 -0700
+
+    [config] Add HB_NO_FACE_COLLECT_UNICODES
+    
+    Part of https://github.com/harfbuzz/harfbuzz/issues/1652
+
+ src/hb-config.hh             | 1 +
+ src/hb-face.cc               | 5 ++---
+ src/hb-ot-face-table-list.hh | 2 ++
+ 3 files changed, 5 insertions(+), 3 deletions(-)
+
+commit 3caa32d737e7c2b4fe6ccd10950760998524f573
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Wed Jun 19 19:50:54 2019 -0700
+
+    [config] Add HB_NO_CMAP_LEGACY_SUBTABLES
+    
+    Part of https://vimeo.com/331852453/06eec89c65
+
+ src/hb-config.hh        |  1 +
+ src/hb-ot-cmap-table.hh | 16 ++++++++++++----
+ 2 files changed, 13 insertions(+), 4 deletions(-)
+
+commit 8e3cde67dfa4aa17c0f1156b4a4acd0c95bdbe6f
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Wed Jun 19 19:58:24 2019 -0700
+
+    Fix MSVC build
+    
+    MSVC warning:
+    
+    c:\projects\harfbuzz\src\hb-ot-layout-gsubgpos.hh(2732): error C2121: '#': invalid character: possibly the result of a macro expansion [C:\projects\harfbuzz\build\harfbuzz.vcxproj]
+    
+    Clang warning for it:
+    
+    ./hb-ot-layout-gsubgpos.hh:2729:2: error: embedding a directive within macro arguments has undefined behavior [-Werror,-Wembedded-directive]
+
+ src/hb-ot-layout-gsubgpos.hh | 18 +++++++++++-------
+ src/hb.hh                    |  1 +
+ 2 files changed, 12 insertions(+), 7 deletions(-)
+
+commit c8f529a07eca06acf2216935921377e7cad8436f
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Wed Jun 19 19:33:15 2019 -0700
+
+    [config] Add HB_NO_HINTING, enabled by HB_TINY
+    
+    Disables HintingDevice tables and Anchors addressing contour points.
+    
+    Part of https://github.com/harfbuzz/harfbuzz/issues/1652
+
+ src/hb-config.hh               | 3 ++-
+ src/hb-ot-layout-common.hh     | 6 ++++++
+ src/hb-ot-layout-gpos-table.hh | 7 +++++++
+ 3 files changed, 15 insertions(+), 1 deletion(-)
+
+commit a849873124efea6577b4938b23501d9e4f4af2f4
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Wed Jun 19 19:26:22 2019 -0700
+
+    [config] Add HB_NO_VAR to disable variations support, enabled by HB_TINY
+    
+    Part of https://github.com/harfbuzz/harfbuzz/issues/1652
+
+ src/hb-config.hh             |  1 +
+ src/hb-font.cc               |  3 ++-
+ src/hb-ot-face-table-list.hh |  2 ++
+ src/hb-ot-layout-common.hh   | 34 ++++++++++++++++++++++++++++------
+ src/hb-ot-layout-gsubgpos.hh | 18 +++++++++++++++---
+ src/hb-ot-var.cc             |  7 ++++++-
+ src/hb-subset-plan.cc        |  2 ++
+ 7 files changed, 56 insertions(+), 11 deletions(-)
+
+commit 230adf2c417bbb6b5f367eb857dd6f98bea3ef26
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Wed Jun 19 18:49:52 2019 -0700
+
+    [config] Add HB_NO_OT_FONT_GLYPH_NAMES
+    
+    Part of https://github.com/harfbuzz/harfbuzz/issues/1652
+
+ src/hb-config.hh             | 1 +
+ src/hb-ot-face-table-list.hh | 4 +++-
+ src/hb-ot-font.cc            | 5 ++++-
+ 3 files changed, 8 insertions(+), 2 deletions(-)
+
+commit b0debc32f6cedfa76a4851aa391f88ed1860955d
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Wed Jun 19 18:42:39 2019 -0700
+
+    [subset] Simplify collect_name_ids
+
+ src/hb-subset-plan.cc | 19 ++-----------------
+ 1 file changed, 2 insertions(+), 17 deletions(-)
+
+commit a5897463d4d0b83cb1bfe4ae1477dac4e3851252
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Wed Jun 19 18:36:35 2019 -0700
+
+    [config] Add HB_NO_STAT
+    
+    Part of https://github.com/harfbuzz/harfbuzz/issues/1652
+
+ src/hb-config.hh             | 1 +
+ src/hb-ot-face-table-list.hh | 2 ++
+ src/hb-subset-plan.cc        | 2 ++
+ 3 files changed, 5 insertions(+)
+
+commit ffc2b8d56e5d35b4dc19499c830d8fc4b643213a
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Wed Jun 19 18:33:29 2019 -0700
+
+    [config] Don't include name table in face if HB_NO_NAME
+    
+    Part of https://github.com/harfbuzz/harfbuzz/issues/1652
+
+ src/hb-ot-face-table-list.hh | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+commit 1432df102ebf206592f92677f48bb950871675b3
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Wed Jun 19 18:32:40 2019 -0700
+
+    [config] Disable hb-ot-font code if HB_NO_OT_FONT
+    
+    Part of https://github.com/harfbuzz/harfbuzz/issues/1652
+
+ src/hb-ot-font.cc | 5 +++++
+ 1 file changed, 5 insertions(+)
+
+commit b1a2384a5244ea3ea63ca94eb095c4add2cd451d
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Wed Jun 19 17:34:12 2019 -0700
+
+    [ucd] Print out table sizes
+
+ src/gen-ucd-table.py | 27 +++++++++++++++++++--------
+ src/hb-ucd-table.hh  |  1 -
+ 2 files changed, 19 insertions(+), 9 deletions(-)
+
+commit f4de0c775408e34474a688361fa319251e1a9c18
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Wed Jun 19 17:08:26 2019 -0700
+
+    [config] Disable AAT map
+    
+    Part of https://github.com/harfbuzz/harfbuzz/issues/1652
+
+ src/hb-aat-map.cc  | 15 +++++++--------
+ src/hb-ot-shape.cc |  6 ++++++
+ 2 files changed, 13 insertions(+), 8 deletions(-)
+
+commit d8bf6723a1176ca26e97e8015044c8829ec77c36
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Wed Jun 19 17:04:16 2019 -0700
+
+    [config] Disable more legacy kerning
+    
+    Part of https://github.com/harfbuzz/harfbuzz/issues/1652
+
+ src/hb-ot-shape.cc | 4 +++-
+ src/hb-ot-shape.hh | 8 ++++++++
+ 2 files changed, 11 insertions(+), 1 deletion(-)
+
+commit 43d7048d59b1a0af62b80bd914805bdec74a29d2
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Wed Jun 19 17:02:32 2019 -0700
+
+    [config] More trak disabling
+    
+    Part of https://github.com/harfbuzz/harfbuzz/issues/1652
+
+ src/hb-ot-shape.cc | 4 +++-
+ src/hb-ot-shape.hh | 8 ++++++++
+ 2 files changed, 11 insertions(+), 1 deletion(-)
+
+commit d84932ba50482b3b47e393714eb77b19173d1f14
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Wed Jun 19 16:57:48 2019 -0700
+
+    [config] add HB_NO_OT_SHAPE_FRACTIONS, enabled in HB_LEAN
+    
+    Part of https://github.com/harfbuzz/harfbuzz/issues/1652
+
+ src/hb-config.hh   |  1 +
+ src/hb-ot-shape.cc |  9 +++++++++
+ src/hb-ot-shape.hh | 10 ++++++++++
+ 3 files changed, 20 insertions(+)
+
+commit eaf4a7364c28663720a9da57bf4d576b6009e17d
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Wed Jun 19 16:51:13 2019 -0700
+
+    [config] Minor trak disable
+    
+    Part of https://github.com/harfbuzz/harfbuzz/issues/1652
+
+ src/hb-ot-shape.cc | 2 ++
+ 1 file changed, 2 insertions(+)
+
+commit 971330c0588307bcd73934e44c6343db55b1f5b6
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Wed Jun 19 16:37:35 2019 -0700
+
+    [config] Add HB_NO_LANGUAGE_PRIVATE_SUBTAG
+    
+    Part of https://github.com/harfbuzz/harfbuzz/issues/1652
+
+ src/hb-config.hh | 1 +
+ src/hb-ot-tag.cc | 4 ++++
+ 2 files changed, 5 insertions(+)
+
+commit f642a5fa6c42b145574593a0e18815dc74d3c617
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Wed Jun 19 16:36:09 2019 -0700
+
+    Restructure code
+
+ src/hb-ot-tag.cc | 44 ++++++++++++++++++++------------------------
+ 1 file changed, 20 insertions(+), 24 deletions(-)
+
+commit d2ff73b256599a655e4ddedbe1ca75abdf837d23
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Wed Jun 19 16:28:08 2019 -0700
+
+    [config] Remove remaining AAT context bits if HB_NO_OT_KERN
+    
+    Part of https://github.com/harfbuzz/harfbuzz/issues/1652
+
+ src/hb-aat-layout.cc | 6 ++++--
+ 1 file changed, 4 insertions(+), 2 deletions(-)
+
+commit 588697afd0ddf411e8201866ade1f593ccb61aab
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Wed Jun 19 16:24:51 2019 -0700
+
+    [config] Add HB_NO_OT_KERN, enabled by HB_MINI / HB_NO_LEGACY
+    
+    Part of https://github.com/harfbuzz/harfbuzz/issues/1652
+
+ src/hb-config.hh             |  1 +
+ src/hb-ot-face-table-list.hh |  6 +++++-
+ src/hb-ot-layout.cc          |  4 ++--
+ src/hb-ot-shape.cc           | 16 ++++++++++++++--
+ src/hb-ot-shape.hh           |  4 ++++
+ 5 files changed, 26 insertions(+), 5 deletions(-)
+
+commit 2e3e929d2b0fa6026c55eb92f91de0498fb22646
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Wed Jun 19 15:50:13 2019 -0700
+
+    Fix build
+
+ src/hb-ot-face-table-list.hh | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+commit 631da9d816da381c5fd4b3cc640c41fda736a96f
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Wed Jun 19 15:36:14 2019 -0700
+
+    [config] Remove tables from hb_face_t for disabled features
+    
+    Part of https://github.com/harfbuzz/harfbuzz/issues/1652
+
+ src/Makefile.sources         |   1 +
+ src/hb-ot-face-table-list.hh | 112 +++++++++++++++++++++++++++++++++++++++++++
+ src/hb-ot-face.cc            |   8 +---
+ src/hb-ot-face.hh            |  52 ++------------------
+ src/hb-ot-layout.cc          |   2 +
+ 5 files changed, 120 insertions(+), 55 deletions(-)
+
+commit e710888188ff3285a162c25c89d886d9535d9f02
+Author: Misty De Meo <mistydemeo@gmail.com>
+Date:   Tue Jun 18 15:20:38 2019 -0700
+
+    coretext: remove trailing macro from SCRATCH_RESTORE
+
+ src/hb-coretext.cc | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 10bac21bb5b25cf20c2198934e99e444625dfd97
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Tue Jun 18 15:15:06 2019 -0700
+
+    [coretext/uniscribe/directwrite] Remove extra semicolons
+    
+    Fixes https://github.com/harfbuzz/harfbuzz/pull/1783
+
+ src/hb-coretext.cc    | 2 +-
+ src/hb-directwrite.cc | 2 +-
+ src/hb-uniscribe.cc   | 2 +-
+ 3 files changed, 3 insertions(+), 3 deletions(-)
+
+commit f0b0fd4e78e94315c9d01b9232ebfb09bbfef556
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Tue Jun 18 14:40:24 2019 -0700
+
+    Remove dead code
+
+ src/hb-ot-layout.cc | 10 ++--------
+ 1 file changed, 2 insertions(+), 8 deletions(-)
+
+commit d7e27cd65a085a76c85cddd93cea48ce4b7be03f
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Tue Jun 18 14:38:05 2019 -0700
+
+    [config] Don't use VORG table if HB_NO_OT_FONT_CFF
+    
+    Part of https://github.com/harfbuzz/harfbuzz/issues/1652
+
+ src/hb-ot-font.cc | 2 ++
+ 1 file changed, 2 insertions(+)
+
+commit 37f8ebff5f1973423c7e4ed9dea88881d0642b61
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Tue Jun 18 14:33:49 2019 -0700
+
+    [config] Fixup for AAT ltag table access
+    
+    Part of https://github.com/harfbuzz/harfbuzz/issues/1652
+
+ src/hb-aat-layout.hh    | 8 --------
+ src/hb-ot-name-table.hh | 2 +-
+ 2 files changed, 1 insertion(+), 9 deletions(-)
+
+commit f08066ce9a41469e2a7396f0accd61e1c02e5649
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Tue Jun 18 14:29:27 2019 -0700
+
+    [config] One more morx disabling
+    
+    Part of https://github.com/harfbuzz/harfbuzz/issues/1652
+
+ src/hb-ot-layout.cc | 3 +++
+ 1 file changed, 3 insertions(+)
+
+commit 231d0257883ec9e8904afae1adfd73f3c225f177
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Tue Jun 18 14:25:52 2019 -0700
+
+    [config] Don't compile AAT API if HB_NO_AAT
+    
+    Part of https://github.com/harfbuzz/harfbuzz/issues/1652
+
+ src/hb-aat-layout.cc | 131 ++++++++++++++++-----------------------------------
+ src/hb-ot-shape.cc   |  19 ++++++--
+ 2 files changed, 56 insertions(+), 94 deletions(-)
+
+commit bf9424a9a198b99d49c005536a10f27387630064
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Tue Jun 18 13:31:35 2019 -0700
+
+    [config] Don't compile unused layout API if HB_NO_LAYOUT_UNUSED
+    
+    Part of https://github.com/harfbuzz/harfbuzz/issues/1652
+
+ src/hb-ot-layout.cc | 16 ++--------------
+ 1 file changed, 2 insertions(+), 14 deletions(-)
+
+commit eb9798ef733da53e69966054b67752cd8937eb7b
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Tue Jun 18 13:29:55 2019 -0700
+
+    [config] Dont' compile buffer message API if HB_NO_BUFFER_MESSAGE
+    
+    Part of https://github.com/harfbuzz/harfbuzz/issues/1652
+
+ src/hb-buffer.cc | 2 ++
+ src/hb-buffer.hh | 5 ++++-
+ 2 files changed, 6 insertions(+), 1 deletion(-)
+
+commit be1c0ab2186a728eabdf6666632a9f759474f901
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Tue Jun 18 13:26:03 2019 -0700
+
+    [config] Don't compile buffer serialize API if HB_NO_BUFFER_SERIALIZE
+    
+    Part of https://github.com/harfbuzz/harfbuzz/issues/1652
+
+ src/hb-buffer-serialize.cc   | 19 +++++++------------
+ src/test-buffer-serialize.cc |  7 ++++++-
+ 2 files changed, 13 insertions(+), 13 deletions(-)
+
+commit bdbabd110cfdb4c59cf24bd500ce63073a5213e4
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Tue Jun 18 13:21:25 2019 -0700
+
+    Minor header include cleanup
+
+ src/hb-aat-layout.cc | 1 -
+ src/hb-ot-math.cc    | 3 ---
+ src/hb-ot-name.cc    | 1 -
+ src/hb-ot-var.cc     | 4 ++--
+ 4 files changed, 2 insertions(+), 7 deletions(-)
+
+commit 83de3a60ab7383cf3ee25c1f8c33a45a7778d003
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Tue Jun 18 13:18:15 2019 -0700
+
+    [config] Don't compile color API if HB_NO_COLOR
+    
+    Part of https://github.com/harfbuzz/harfbuzz/issues/1652
+
+ src/hb-ot-color.cc   | 55 +++++++++-------------------------------------------
+ src/test-ot-color.cc |  9 ++++++++-
+ 2 files changed, 17 insertions(+), 47 deletions(-)
+
+commit 350f98ea47aaf0fe008065b92c8b6fe2bc519fa7
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Tue Jun 18 13:11:41 2019 -0700
+
+    [config] Don't compile name table API if HB_NO_NAME
+    
+    Part of https://github.com/harfbuzz/harfbuzz/issues/1652
+
+ src/hb-ot-name.cc   | 25 +++++--------------------
+ src/test-ot-name.cc |  5 ++++-
+ 2 files changed, 9 insertions(+), 21 deletions(-)
+
+commit da51a2cb0efae664d4ee83c6036f29a21621e993
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Tue Jun 18 13:09:22 2019 -0700
+
+    [config] Don't compile math API if HB_NO_MATH
+    
+    Part of https://github.com/harfbuzz/harfbuzz/issues/1652
+
+ src/hb-ot-math.cc | 47 +++++++----------------------------------------
+ 1 file changed, 7 insertions(+), 40 deletions(-)
+
+commit 737436d3f8aacfd0bd586cd54d7034bae3afc4e1
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Tue Jun 18 13:07:44 2019 -0700
+
+    Streamline HB_NO_CFF
+
+ src/hb-ot-cff1-table.cc     | 7 +++++--
+ src/hb-ot-cff2-table.cc     | 7 +++++--
+ src/hb-subset-cff-common.cc | 7 +++++++
+ src/hb-subset-cff1.cc       | 7 +++++--
+ src/hb-subset-cff2.cc       | 7 +++++--
+ 5 files changed, 27 insertions(+), 8 deletions(-)
+
+commit 60653a7adbbd8143d187b3edf33cb7a2dddadf74
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Tue Jun 18 13:01:11 2019 -0700
+
+    Remove HB_VECTOR_SIZE
+    
+    It was cumbersome to get it to work reliably, for dubious performance
+    gain, mostly in the subsetter maybe...
+    
+    Life is easier without.  It was disabled forever anyway.
+
+ src/hb-algs.hh   | 36 +++++++++---------------------------
+ src/hb-null.hh   |  4 ++--
+ src/hb-static.cc |  4 ++--
+ src/hb.hh        | 32 --------------------------------
+ 4 files changed, 13 insertions(+), 63 deletions(-)
+
+commit 24060d3aa77f1e1a18960cc61c3d1ac241875507
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Tue Jun 18 12:50:42 2019 -0700
+
+    Add hb_bitwise_neg
+
+ src/hb-algs.hh | 33 +++++++++++++++++++++------------
+ 1 file changed, 21 insertions(+), 12 deletions(-)
+
+commit 7cf9169078f35299ec0633a7b212256acdd71661
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Tue Jun 18 12:44:03 2019 -0700
+
+    Remove accidentally left cruft
+
+ src/hb-algs.hh | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 6172ec5d879653c536d7cb3d3b3760fbb6d0f3f3
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Tue Jun 18 12:41:56 2019 -0700
+
+    Remove (unused) posix_memalign fallback
+    
+    Was wrong.  The returned pointer couldn't be passed to free().  Ouch!
+
+ configure.ac |  2 +-
+ src/hb.hh    | 34 ----------------------------------
+ 2 files changed, 1 insertion(+), 35 deletions(-)
+
+commit eb28d6e48b02a8c49875cfcd084a16c1c66c367e
+Author: Ebrahim Byagowi <ebrahim@gnu.org>
+Date:   Tue Jun 18 12:14:10 2019 +0430
+
+    [ci] Test no build system builds
+    
+    Introduced in aa3450c, let's preserve it
+
+ .circleci/config.yml | 5 +++--
+ 1 file changed, 3 insertions(+), 2 deletions(-)
+
+commit efef672911dd6c3b80e53294f3fcd59dbb64597a
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Mon Jun 17 22:57:51 2019 -0700
+
+    Fix cmake build
+    
+    Hopefullly.
+
+ CMakeLists.txt | 4 ----
+ 1 file changed, 4 deletions(-)
+
+commit aa3450cac148280f747fb88864b6fcc4ec70cc51
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Mon Jun 17 22:41:49 2019 -0700
+
+    [config] Don't compile disabled features
+    
+    This makes it possible to include all .cc files into build, even if not
+    building CoreText, Uniscribe, etc.
+    
+    This was mostly to help custom builders.  But also means that we can
+    include all files in our own build system.  Not sure if we should.
+    Definitely simplifies things, but slightly only.
+
+ src/Makefile.am              | 1 +
+ src/hb-coretext.cc           | 6 ++++++
+ src/hb-directwrite.cc        | 6 ++++++
+ src/hb-ft.cc                 | 5 +++++
+ src/hb-glib.cc               | 5 +++++
+ src/hb-gobject-enums.cc.tmpl | 7 +++++++
+ src/hb-gobject-structs.cc    | 5 +++++
+ src/hb-graphite2.cc          | 7 +++++++
+ src/hb-icu.cc                | 5 +++++
+ src/hb-uniscribe.cc          | 4 ++++
+ 10 files changed, 51 insertions(+)
+
+commit 33d8b76e74579a27b06fa788d0bf696a9dd44cc4
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Mon Jun 17 21:54:20 2019 -0700
+
+    [config] Flesh out CONFIG.md
+    
+    Part of https://github.com/harfbuzz/harfbuzz/issues/1652
+
+ CONFIG.md | 87 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++---
+ 1 file changed, 84 insertions(+), 3 deletions(-)
+
+commit 23ccd00a3d5033b812f2bebcc5b793a4415b252b
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Mon Jun 17 20:35:04 2019 -0700
+
+    Minor
+
+ src/hb-config.hh | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+commit 23768a99e08cbe691772b7514c023d3184989ff8
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Mon Jun 17 20:29:29 2019 -0700
+
+    [config] Replace HAVE_FALLBACK with HB_NO_FALLBACK_SHAPE
+    
+    This disables fallback shaper in tiny builds.  Projects that don't
+    use our build system and want to disable fallback shaper (eg. Firefox)
+    should define HB_NO_FALLBACK_SHAPE now.
+    
+    Part of https://github.com/harfbuzz/harfbuzz/issues/1652
+
+ CMakeLists.txt           | 2 --
+ configure.ac             | 8 --------
+ src/Makefile.am          | 4 ----
+ src/Makefile.sources     | 5 +----
+ src/hb-config.hh         | 1 +
+ src/hb-fallback-shape.cc | 3 +++
+ src/hb-shaper-list.hh    | 2 +-
+ 7 files changed, 6 insertions(+), 19 deletions(-)
+
+commit 3a9394635ffd663d8acd0715236dd01d9f22f3b8
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Mon Jun 17 20:10:36 2019 -0700
+
+    Add CONFIG.md
+    
+    https://github.com/harfbuzz/harfbuzz/issues/1652
+
+ CONFIG.md   | 51 +++++++++++++++++++++++++++++++++++++++++++++++++++
+ Makefile.am |  1 +
+ README.md   |  2 ++
+ 3 files changed, 54 insertions(+)
+
+commit 1c56b5d1d8307efd12519556e41fc50c5371f136
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Mon Jun 17 14:23:04 2019 -0700
+
+    [serialize] Fix copy() calling operator=
+    
+    https://github.com/googlefonts/harfbuzz/commit/9f610ae239a11e86f94621e26bc15849b65ce41b#commitcomment-33944686
+
+ src/hb-serialize.hh | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 6492b2345cd913223b0eb931e9e11f7e5ad33049
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Mon Jun 17 14:19:13 2019 -0700
+
+    Minor
+
+ src/hb-open-type.hh | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 8938dd23c64f80dbd31f87133d9df88cd0c98c1a
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Mon Jun 17 14:12:11 2019 -0700
+
+    Use injected class name
+
+ src/hb-open-type.hh | 8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+commit bfb5569d530a2b65dafd0d9be45d594af9e742ce
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Mon Jun 17 14:06:04 2019 -0700
+
+    Disable non-OpenType kerning with hb-ft in HB_TINY
+
+ src/hb-ft.cc | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+commit 0819f3ca863af520fe546e6ef0596300e9e28b01
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Mon Jun 17 14:02:47 2019 -0700
+
+    Deprecate v_kerning callback again
+    
+    Part of https://github.com/harfbuzz/harfbuzz/issues/1682
+
+ docs/harfbuzz-sections.txt |  6 +++---
+ src/hb-deprecated.h        | 23 +++++++++++++++++++++++
+ src/hb-font.cc             |  7 +++----
+ src/hb-font.h              | 20 --------------------
+ src/hb-font.hh             |  2 +-
+ 5 files changed, 30 insertions(+), 28 deletions(-)
+
+commit eb2825c7f140185f41922a371434873a0114ef67
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Mon Jun 17 13:42:53 2019 -0700
+
+    Minor
+
+ src/hb-ot-font.cc | 1 -
+ 1 file changed, 1 deletion(-)
+
+commit 896416bd4c6ac486eb4e1926eaa09d5a9b693763
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Mon Jun 17 13:39:49 2019 -0700
+
+    Partially revert "[ft/ot] Remove implementation of deprecated kerning funcs"
+    
+    This reverts commit 47030b1855f04c0d75899ffb6f5021fea3c19b90.
+    
+    Reverts only the hb-ft part, to reinstate non-OpenType kerning with
+    FreeType.
+    
+    Fixes https://github.com/harfbuzz/harfbuzz/issues/1682
+
+ src/hb-ft.cc | 19 +++++++++++++++++++
+ 1 file changed, 19 insertions(+)
+
+commit 2682efb02df72fb254c819cb76fc23592c30fc45
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Mon Jun 17 13:38:08 2019 -0700
+
+    Revert "Deprecate font kern API"
+    
+    This reverts commit d219f899f4b2fb4b39ebc1dff9fb648fc5d6d112.
+    
+    API change: Un-deprecate font kern API.
+    
+    Part of https://github.com/harfbuzz/harfbuzz/issues/1682
+    
+    We should document that this API is only necessary to hook up
+    non-OpenType kerning.  hb-ot-font will continue to NOT implement them.
+
+ docs/harfbuzz-sections.txt | 16 +++++++-------
+ src/hb-deprecated.h        | 54 ----------------------------------------------
+ src/hb-font.cc             |  3 ---
+ src/hb-font.h              | 51 +++++++++++++++++++++++++++++++++++++++++++
+ 4 files changed, 59 insertions(+), 65 deletions(-)
+
+commit d6cb244f7d63338e0cbfa774c2a32e6e7e06f15b
+Author: David Corbett <corbett.dav@husky.neu.edu>
+Date:   Sat Jun 15 21:38:27 2019 -0400
+
+    Canonically reorder U+0C55 and U+0C56
+
+ src/hb-unicode.hh | 8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+commit 82d4bfb8f3ac30fecce41f8abe59f58ad64ba98a
+Author: Michiharu Ariza <ariza@adobe.com>
+Date:   Fri Jun 14 10:49:42 2019 -0700
+
+    enable cff subset tests
+    
+    add Unicode UCS-4 cmap
+    fix Unicode bits in OS/2
+    add Unicode cmap sub-table in SourceHanSans-Regular_subset.otf
+    regenerate cff subset test expected results
+
+ src/hb-ot-cmap-table.hh                            |  73 +++++++++++++++++----
+ src/hb-ot-os2-table.hh                             |  10 ++-
+ test/subset/data/Makefile.am                       |   2 +
+ test/subset/data/Makefile.sources                  |   2 +
+ ...subroutinize-retain-gids.1FC,21,41,20,62,63.otf | Bin 32124 -> 20000 bytes
+ ...Regular.desubroutinize-retain-gids.61,62,63.otf | Bin 29688 -> 2196 bytes
+ ...r.desubroutinize-retain-gids.D7,D8,D9,DA,DE.otf | Bin 33316 -> 30412 bytes
+ ...subroutinize-retain-gids.1FC,21,41,20,62,63.otf | Bin 31960 -> 19840 bytes
+ ...p-hints-desubroutinize-retain-gids.61,62,63.otf | Bin 29564 -> 2072 bytes
+ ...s-desubroutinize-retain-gids.D7,D8,D9,DA,DE.otf | Bin 33168 -> 30264 bytes
+ ...r.drop-hints-retain-gids.1FC,21,41,20,62,63.otf | Bin 32052 -> 19932 bytes
+ ...Pro-Regular.drop-hints-retain-gids.61,62,63.otf | Bin 29632 -> 2108 bytes
+ ...gular.drop-hints-retain-gids.D7,D8,D9,DA,DE.otf | Bin 33180 -> 30276 bytes
+ ...sPro-Regular.retain-gids.1FC,21,41,20,62,63.otf | Bin 32276 -> 20152 bytes
+ .../SourceSansPro-Regular.retain-gids.61,62,63.otf | Bin 29788 -> 2264 bytes
+ ...eSansPro-Regular.retain-gids.D7,D8,D9,DA,DE.otf | Bin 33332 -> 30428 bytes
+ ...ubset.default.3042,3044,3046,3048,304A,304B.otf | Bin 3028 -> 3036 bytes
+ ...ubset.default.3042,3044,3046,73E0,5EA6,8F38.otf | Bin 3240 -> 3248 bytes
+ ...eHanSans-Regular_subset.default.61,63,65,6B.otf | Bin 2200 -> 2208 bytes
+ ...ubset.default.660E,6975,73E0,5EA6,8F38,6E05.otf | Bin 3460 -> 3468 bytes
+ .../SourceHanSans-Regular_subset.default.660E.otf  | Bin 1920 -> 1928 bytes
+ ...e-retain-gids.3042,3044,3046,3048,304A,304B.otf | Bin 90956 -> 8932 bytes
+ ...e-retain-gids.3042,3044,3046,73E0,5EA6,8F38.otf | Bin 125820 -> 116080 bytes
+ ...bset.desubroutinize-retain-gids.61,63,65,6B.otf | Bin 88392 -> 3016 bytes
+ ...e-retain-gids.660E,6975,73E0,5EA6,8F38,6E05.otf | Bin 126004 -> 116264 bytes
+ ...ular_subset.desubroutinize-retain-gids.660E.otf | Bin 103780 -> 50224 bytes
+ ...esubroutinize.3042,3044,3046,3048,304A,304B.otf | Bin 2952 -> 2960 bytes
+ ...esubroutinize.3042,3044,3046,73E0,5EA6,8F38.otf | Bin 3136 -> 3144 bytes
+ ...s-Regular_subset.desubroutinize.61,63,65,6B.otf | Bin 2132 -> 2140 bytes
+ ...esubroutinize.660E,6975,73E0,5EA6,8F38,6E05.otf | Bin 3256 -> 3264 bytes
+ ...eHanSans-Regular_subset.desubroutinize.660E.otf | Bin 1896 -> 1904 bytes
+ ...e-retain-gids.3042,3044,3046,3048,304A,304B.otf | Bin 90656 -> 8672 bytes
+ ...e-retain-gids.3042,3044,3046,73E0,5EA6,8F38.otf | Bin 125468 -> 115768 bytes
+ ...ints-desubroutinize-retain-gids.61,63,65,6B.otf | Bin 88156 -> 2892 bytes
+ ...e-retain-gids.660E,6975,73E0,5EA6,8F38,6E05.otf | Bin 125584 -> 115884 bytes
+ ....drop-hints-desubroutinize-retain-gids.660E.otf | Bin 103556 -> 50040 bytes
+ ...esubroutinize.3042,3044,3046,3048,304A,304B.otf | Bin 2792 -> 2800 bytes
+ ...esubroutinize.3042,3044,3046,73E0,5EA6,8F38.otf | Bin 2896 -> 2904 bytes
+ ...ubset.drop-hints-desubroutinize.61,63,65,6B.otf | Bin 2028 -> 2036 bytes
+ ...esubroutinize.660E,6975,73E0,5EA6,8F38,6E05.otf | Bin 2964 -> 2972 bytes
+ ...gular_subset.drop-hints-desubroutinize.660E.otf | Bin 1804 -> 1812 bytes
+ ...s-retain-gids.3042,3044,3046,3048,304A,304B.otf | Bin 90724 -> 8740 bytes
+ ...s-retain-gids.3042,3044,3046,73E0,5EA6,8F38.otf | Bin 125560 -> 115864 bytes
+ ...r_subset.drop-hints-retain-gids.61,63,65,6B.otf | Bin 88196 -> 2852 bytes
+ ...s-retain-gids.660E,6975,73E0,5EA6,8F38,6E05.otf | Bin 125780 -> 116084 bytes
+ ...-Regular_subset.drop-hints-retain-gids.660E.otf | Bin 103572 -> 50060 bytes
+ ...et.drop-hints.3042,3044,3046,3048,304A,304B.otf | Bin 2848 -> 2856 bytes
+ ...et.drop-hints.3042,3044,3046,73E0,5EA6,8F38.otf | Bin 2988 -> 2996 bytes
+ ...nSans-Regular_subset.drop-hints.61,63,65,6B.otf | Bin 2060 -> 2068 bytes
+ ...et.drop-hints.660E,6975,73E0,5EA6,8F38,6E05.otf | Bin 3164 -> 3172 bytes
+ ...ourceHanSans-Regular_subset.drop-hints.660E.otf | Bin 1824 -> 1832 bytes
+ ...t.retain-gids.3042,3044,3046,3048,304A,304B.otf | Bin 91040 -> 9016 bytes
+ ...t.retain-gids.3042,3044,3046,73E0,5EA6,8F38.otf | Bin 125924 -> 116184 bytes
+ ...Sans-Regular_subset.retain-gids.61,63,65,6B.otf | Bin 88468 -> 3012 bytes
+ ...t.retain-gids.660E,6975,73E0,5EA6,8F38,6E05.otf | Bin 126208 -> 116468 bytes
+ ...urceHanSans-Regular_subset.retain-gids.660E.otf | Bin 103800 -> 50244 bytes
+ .../data/fonts/SourceHanSans-Regular_subset.otf    | Bin 2707728 -> 2707736 bytes
+ 57 files changed, 70 insertions(+), 17 deletions(-)
+
+commit 6bcbe495bff221169f8c0769dde1b4b2c165a211
+Author: Ebrahim Byagowi <ebrahim@gnu.org>
+Date:   Thu Jun 13 15:04:51 2019 +0430
+
+    [cff] minor format (#1774)
+
+ src/hb-subset-cff-common.cc | 104 ++++++++++++++++++++------------------------
+ 1 file changed, 48 insertions(+), 56 deletions(-)
+
+commit 4f37c0db9bf4e3d536a50126d17b36009b12f9cb
+Author: David Corbett <corbett.dav@husky.neu.edu>
+Date:   Tue Jun 11 17:55:31 2019 -0400
+
+    Remove 'mym3'
+
+ src/hb-ot-tag.cc       | 4 +++-
+ test/api/test-ot-tag.c | 2 +-
+ 2 files changed, 4 insertions(+), 2 deletions(-)
+
+commit 90872a29ee5d0bef6df1c2900f7001c11106c4da
+Author: Michiharu Ariza <ariza@adobe.com>
+Date:   Tue Jun 11 12:28:30 2019 -0700
+
+    change assert(false) to failure
+
+ src/hb-subset-cff-common.cc                               |   2 +-
+ ...z-testcase-minimized-hb-subset-fuzzer-5680398559870976 | Bin 0 -> 145 bytes
+ 2 files changed, 1 insertion(+), 1 deletion(-)
+
+commit 0c5da57d1aab91d7677a5c6517a3da254d53267f
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Mon Jun 10 14:06:25 2019 -0700
+
+    Fix typo :)
+
+ src/hb-blob.cc   | 3 ++-
+ src/hb-config.hh | 2 +-
+ 2 files changed, 3 insertions(+), 2 deletions(-)
+
+commit 19b8eb08e5457cd643aee5f9b9ad1c80b2243895
+Author: Ebrahim Byagowi <ebrahim@gnu.org>
+Date:   Tue Jun 11 01:33:30 2019 +0430
+
+    Move HB_NO_SETLOCALE to closer place to its to unbreak HB_TINY build (#1768)
+
+ src/hb-common.cc | 3 +++
+ src/hb.hh        | 4 ----
+ 2 files changed, 3 insertions(+), 4 deletions(-)
+
+commit b4a5a69ad8625e3b90eb907a1b70e3ed24d4ff97
+Author: Ebrahim Byagowi <ebrahim@gnu.org>
+Date:   Tue Jun 11 01:33:09 2019 +0430
+
+    Add HB_NO_OEPN (#1767)
+
+ src/hb-blob.cc   | 3 +++
+ src/hb-config.hh | 2 ++
+ 2 files changed, 5 insertions(+)
+
+commit a36ff941710b5a5f7e464e6d72aff36cf5549a91
+Author: Ebrahim Byagowi <ebrahim@gnu.org>
+Date:   Mon Jun 10 15:48:28 2019 +0430
+
+    Add HB_NO_SETLOCALE
+
+ src/hb-config.hh | 1 +
+ src/hb.hh        | 6 +++++-
+ 2 files changed, 6 insertions(+), 1 deletion(-)
+
+commit c4cae81a26a816979f3206418c47856b5ed2d8bb
+Author: Ebrahim Byagowi <ebrahim@gnu.org>
+Date:   Mon Jun 10 15:32:54 2019 +0430
+
+    Remove round polyfill
+    
+    Added in 01dff1e and 19256bef, this was targeted at older
+    msvc versions that don't support C99 but now as we require
+    C++11 we don't target places those envs thus removing this.
+
+ CMakeLists.txt |  2 +-
+ configure.ac   |  6 ------
+ src/hb.hh      | 14 --------------
+ 3 files changed, 1 insertion(+), 21 deletions(-)
+
+commit ff9b9b1c89d5529fafc74ce84c0acb71b5d6031b
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Mon Jun 10 12:48:25 2019 -0700
+
+    Simplify HB_PARTIALIZE impl
+    
+    +this works on gcc 4.8 as well as default code path.
+
+ src/hb-algs.hh | 17 +++++------------
+ 1 file changed, 5 insertions(+), 12 deletions(-)
+
+commit 451edbd4d063a4b43c1ca3d2b60c7392602ae7b7
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Mon Jun 10 12:46:54 2019 -0700
+
+    Revert "Test new solution for HB_PARTIALIZE"
+    
+    This reverts commit a0c4900799c26e4ff34180842a5ff21048fe31a0.
+
+ src/hb-algs.hh | 18 +++++++++++++++++-
+ 1 file changed, 17 insertions(+), 1 deletion(-)
+
+commit a0c4900799c26e4ff34180842a5ff21048fe31a0
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Mon Jun 10 12:33:23 2019 -0700
+
+    Test new solution for HB_PARTIALIZE
+    
+    Just testing bots.  Will finish based on results.
+
+ src/hb-algs.hh | 18 +-----------------
+ 1 file changed, 1 insertion(+), 17 deletions(-)
+
+commit 4a2b58555f173b692b767c933d280a51142926dd
+Author: Ebrahim Byagowi <ebrahim@gnu.org>
+Date:   Mon Jun 10 08:16:51 2019 -0700
+
+    [ci] Use HB_OPTIMIZE_SIZE instead of __OPTIMIZE_SIZE__
+
+ .circleci/config.yml | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit a228bb5f1d471a334bc9727f5d4f5b59dbe829ff
+Author: Ebrahim Byagowi <ebrahim@gnu.org>
+Date:   Mon Jun 10 15:56:36 2019 +0430
+
+    [ci] Test -Os and optimize size in Alpine bot
+    
+    __OPTIMIZE_SIZE__ should be defined whenever -Os but some Internet thread
+    indicate may not so lets do that ourselves as that is the main intention
+
+ .circleci/config.yml | 8 ++++++--
+ 1 file changed, 6 insertions(+), 2 deletions(-)
+
+commit 9407ef8d4bb96346b1f8b07757d79d3f8cc61cf7
+Author: Ebrahim Byagowi <ebrahim@gnu.org>
+Date:   Mon Jun 10 15:17:43 2019 +0430
+
+    minor, add HB_USE_INTERNAL_QSORT
+    
+    The only thing I need for a working wasm in a minimum libc,
+    otherwise I have to provide the very same qsort inside that libc
+
+ src/hb-algs.hh | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+commit 801d93fc58aa13082dea86fb2c3821bc6362f593
+Author: Ebrahim Byagowi <ebrahim@gnu.org>
+Date:   Mon Jun 10 14:53:14 2019 +0430
+
+    [ci] remove wine from fedora bot
+    
+    We are not testing Windows exes in fedora mingw bot, we don't have to as
+    probably won't go that smoothly and we have real Windows bots anyway
+    and as wine installation itself is time taking let's remove it
+
+ .circleci/config.yml | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 7dcfc5357df879491f847bd7d2941645e58f268c
+Author: Ebrahim Byagowi <ebrahim@gnu.org>
+Date:   Sun Jun 9 11:58:08 2019 +0430
+
+    [stat] minor format
+
+ src/hb-ot-stat-table.hh | 72 ++++++++++++++++++++++++-------------------------
+ 1 file changed, 36 insertions(+), 36 deletions(-)
+
+commit 2646c7149ce49d3b6cf90e354658df35254bcce0
+Author: Ebrahim Byagowi <ebrahim@gnu.org>
+Date:   Sun Jun 9 11:51:58 2019 +0430
+
+    [stat] minor
+
+ src/hb-ot-stat-table.hh | 8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+commit c4669fda7890bc741ef934ebc360e366eba94866
+Author: Ebrahim Byagowi <ebrahim@gnu.org>
+Date:   Sun Jun 9 11:50:36 2019 +0430
+
+    [algs] minor
+
+ src/hb-algs.hh | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+commit 9b853f755dd05ccef3429d3d3d0d561a99cc4c2d
+Author: Ebrahim Byagowi <ebrahim@gnu.org>
+Date:   Sun Jun 9 11:49:25 2019 +0430
+
+    [cff] Use switch on multi-format structs (#1762)
+
+ src/hb-cff-interp-cs-common.hh   |   4 +-
+ src/hb-cff-interp-dict-common.hh |  12 +--
+ src/hb-ot-cff-common.hh          | 135 ++++++++++++------------
+ src/hb-ot-cff1-table.hh          | 215 ++++++++++++++++++++++-----------------
+ src/hb-ot-cff2-table.hh          |  68 +++++++------
+ src/hb-subset-cff1.cc            |   2 +-
+ src/hb-subset-cff2.cc            |   2 +-
+ 7 files changed, 233 insertions(+), 205 deletions(-)
+
+commit eff579f743a91c0b1c543f4b69ab33580cae6392
+Author: Ebrahim Byagowi <ebrahim@gnu.org>
+Date:   Fri Jun 7 12:58:09 2019 +0430
+
+    Update and use internal qsort everywhere
+
+ src/hb-algs.hh          | 210 +++++++++++++++++++++++++++++++++++-------------
+ src/hb-array.hh         |   6 +-
+ src/hb-ot-post-table.hh |   2 +-
+ 3 files changed, 158 insertions(+), 60 deletions(-)
+
+commit 5074d665a8b0980f202a5986bda52808674cfb54
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Fri Jun 7 14:20:45 2019 -0700
+
+    [ucd] Save another 1.5kb
+    
+    https://github.com/harfbuzz/harfbuzz/issues/1652
+
+ src/gen-ucd-table.py |  8 +++++---
+ src/hb-ucd-table.hh  | 37 +++++++++++++++++++++----------------
+ src/hb-ucd.cc        | 12 +++++++++---
+ 3 files changed, 35 insertions(+), 22 deletions(-)
+
+commit 6d58b45782833f8c6c8efd9426e2785c78e6462a
+Author: Ebrahim Byagowi <ebrahim@gnu.org>
+Date:   Sat Jun 8 00:40:18 2019 +0430
+
+    [ci] use trusty for its gcc 4.8 again
+
+ .travis.yml | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 973699c49b905e142ecc5cefd1f4fa15aad8e309
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Fri Jun 7 12:49:06 2019 -0700
+
+    Disable clang gcc impersonator
+
+ src/hb-algs.hh | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit e4e518f33d933a02058bad86a6aae714e59814db
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Fri Jun 7 12:41:09 2019 -0700
+
+    Fix build on gcc 4.8
+    
+    Fixes https://github.com/harfbuzz/harfbuzz/issues/1724
+
+ src/hb-algs.hh | 29 +++++++++++++++++++++++++++--
+ 1 file changed, 27 insertions(+), 2 deletions(-)
+
+commit 3c240bd3dc0aaca38154da555d0aef350da62ee6
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Fri Jun 7 10:56:24 2019 -0700
+
+    Downgrade double-promotion from error to warning
+    
+    https://github.com/harfbuzz/harfbuzz/issues/1740
+
+ src/hb.hh | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 385e436692e94588fc4cb3a7afbeb862035db09b
+Author: Ebrahim Byagowi <ebrahim@gnu.org>
+Date:   Fri Jun 7 10:44:53 2019 -0700
+
+    Minor, fix gcc maybe-uninitialized complain
+    
+    I guess all of its field will be initialized anyway here but lets make it more defensive
+
+ src/hb-ot-glyf-table.hh | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 1bada656a86e9cb27d4a6b9fcc50748f0bd9c1d9
+Author: Ebrahim Byagowi <ebrahim@gnu.org>
+Date:   Fri Jun 7 02:01:27 2019 +0430
+
+    Minor, remove unnecessary semicolon
+    
+    Causing -Wextra-semi-stmt build error when no primitive has chosen
+    Interesting that nobody has noticed it yet.
+
+ src/hb-mutex.hh | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit f9b1ae73360054d9f121a2d36820377909888b35
+Author: Garret Rieger <grieger@google.com>
+Date:   Wed Jun 5 17:40:59 2019 -0700
+
+    [subset] Move OS/2 to subset2.
+
+ src/hb-ot-os2-table.hh | 32 ++++++++++++++++----------------
+ src/hb-subset.cc       |  2 +-
+ 2 files changed, 17 insertions(+), 17 deletions(-)
+
+commit 93d592e0e181f436ea47038fef419134007208aa
+Author: Qunxin Liu <qxliu@google.com>
+Date:   Wed Jun 5 16:51:31 2019 -0700
+
+    [subset] post table to use _subset2
+
+ src/hb-ot-post-table.hh | 31 +++++++++++++++----------------
+ src/hb-subset.cc        |  2 +-
+ 2 files changed, 16 insertions(+), 17 deletions(-)
+
+commit db938479d7b1e3ec35a39a9ad31c945e09e6d5e5
+Author: Qunxin Liu <qxliu@google.com>
+Date:   Tue Jun 4 10:30:53 2019 -0700
+
+    [subset] maxp table to use _subset2
+
+ src/hb-ot-maxp-table.hh | 48 ++++++++++++++++++++++--------------------------
+ src/hb-subset.cc        |  2 +-
+ 2 files changed, 23 insertions(+), 27 deletions(-)
+
+commit d5e5f378329b6ce21944b79b568369ea7bc36cf3
+Author: Eli Zaretskii <eliz@gnu.org>
+Date:   Wed Jun 5 22:20:03 2019 +0300
+
+    This makes minor changes to allow building HarfBuzz with
+    mingw.org's MinGW.
+    
+    src/hb-algs.hh: Don't compile _BitScanForward and _BitScanReverse
+    for GCC >= 4.  mingw.org's MinGW doesn't have these functions.
+    
+    src/hb-atomic.hh: MemoryBarrier does exist in mingw.org's MinGW,
+    but it is not a macro, it is an inline function.  __MINGW32_VERSION
+    is a macro that exists only in mingw.org's MinGW, so conditioning
+    on it should not affect MinGW64, where MemoryBarrier is a macro.
+    
+    src/hb-uniscribe.cc: Define E_NOT_SUFFICIENT_BUFFER if it is not
+    defined (mingw.org's MinGW doesn't).
+    
+    src/hb.hh: Don't include intrin.h for mingw.org's MinGW, since that
+    header is not available; instead, include windows.h.  Conditioned
+    on __MINGW32_VERSION to avoid affecting MinGW64.
+
+ src/hb-algs.hh      | 4 ++--
+ src/hb-atomic.hh    | 2 +-
+ src/hb-uniscribe.cc | 4 ++++
+ src/hb.hh           | 7 +++++++
+ 4 files changed, 14 insertions(+), 3 deletions(-)
+
+commit c7439d4e3a76d596845aad4e4bc860bd61ee47e3
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Wed Jun 5 12:13:49 2019 -0700
+
+    Slightly massage buffer-messaging commit
+    
+    Saves a few bytes.
+
+ src/hb-buffer.cc | 3 ---
+ src/hb-buffer.hh | 8 +++++++-
+ 2 files changed, 7 insertions(+), 4 deletions(-)
+
+commit 4b1b0bf2f51f806d3285a7e7dec378b9eab9333e
+Merge: 659eeddb 815f002b
+Author: Ebrahim Byagowi <ebrahim@gnu.org>
+Date:   Wed Jun 5 12:57:28 2019 +0430
+
+    Merge pull request #1755 from ebraminio/slim
+    
+    Don't use vsnprintf when HB_NO_BUFFER_MESSAGE is defined
+
+commit 815f002bb9230a52768a165383497cc98c58eadb
+Author: Ebrahim Byagowi <ebrahim@gnu.org>
+Date:   Wed Jun 5 10:38:06 2019 +0430
+
+    Don't use vsnprintf when HB_NO_BUFFER_MESSAGE is defined
+
+ src/hb-buffer.cc | 5 ++++-
+ src/hb-config.hh | 1 +
+ 2 files changed, 5 insertions(+), 1 deletion(-)
+
+commit 659eeddb2df5b97cc01bd39e106381f65c9f41f1
+Author: Bruce Mitchener <bruce.mitchener@gmail.com>
+Date:   Mon Jun 3 22:31:50 2019 +0700
+
+    Use C++11 override keyword.
+
+ util/hb-ot-shape-closure.cc |  2 +-
+ util/options.hh             | 30 +++++++++++++++---------------
+ 2 files changed, 16 insertions(+), 16 deletions(-)
+
+commit 2e16593b70688dfcee1788f38c6af03c5a589f6e
+Author: David Corbett <corbett.dav@husky.neu.edu>
+Date:   Sat Jun 1 20:54:46 2019 -0400
+
+    [myanmar] Make medial_group match the OT spec
+    
+    Sometime between [July 2018] and [January 2019], the OpenType Myanmar
+    grammar changed: one asat is now allowed after a medial ya, before any
+    other medial consonant.
+    
+    [July 2018]: http://web.archive.org/web/20180711011550/https://docs.microsoft.com/en-us/typography/script-development/myanmar
+    [January 2019]: http://web.archive.org/web/20190115044451/https://docs.microsoft.com/en-us/typography/script-development/myanmar
+    
+    This also reverts commit 439b05867c0856a81fa8f9bea3a7465b4b4bdd91, which
+    allowed an asat immediately after a medial ra.
+
+ src/hb-ot-shape-complex-myanmar-machine.hh | 249 +++++++++++++++--------------
+ src/hb-ot-shape-complex-myanmar-machine.rl |   2 +-
+ 2 files changed, 129 insertions(+), 122 deletions(-)
+
+commit 209491fc37c46281e063c3e6707d686d5f2b2ba4
+Author: Qunxin Liu <qxliu@google.com>
+Date:   Wed May 29 14:03:17 2019 -0700
+
+    [subset] Hmtx/vmtx tables to use subset2 and new iterator frameworks
+
+ src/hb-ot-hmtx-table.hh | 115 +++++++++++++++++++++++-------------------------
+ src/hb-subset.cc        |   6 +--
+ 2 files changed, 59 insertions(+), 62 deletions(-)
+
+commit 89a7a880a1d5cd5e585d43fdde6d44c6dba559cf
+Merge: 760eb1bf 12febd68
+Author: Ebrahim Byagowi <ebrahim@gnu.org>
+Date:   Tue Jun 4 10:52:16 2019 +0430
+
+    Merge pull request #1747 from harfbuzz/cff2-fdselect-fix
+    
+    fixed faulty FDSelect::sanitize
+
+commit 12febd68d694cc1bae44b0b672d88bf9fbe8568d
+Author: Michiharu Ariza <ariza@adobe.com>
+Date:   Mon Jun 3 16:40:03 2019 -0700
+
+    added parentheses to FDSelect::sanitize as well
+
+ src/hb-ot-cff-common.hh | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+commit 65e66a2d371f42d018b1a22f31a6428d19a90284
+Author: Michiharu Ariza <ariza@adobe.com>
+Date:   Mon Jun 3 16:31:41 2019 -0700
+
+    added test data
+
+ ...zz-testcase-minimized-harfbuzz_fuzzer-6252118652092416 | Bin 0 -> 126 bytes
+ 1 file changed, 0 insertions(+), 0 deletions(-)
+
+commit be82a2fc0c7ad3553f2e6dc8082a3255cb6c917c
+Author: Michiharu Ariza <ariza@adobe.com>
+Date:   Mon Jun 3 15:52:23 2019 -0700
+
+    parenthesized cond-exp in CFF2FDSelect::sanitize
+
+ src/hb-ot-cff2-table.hh | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+commit 760eb1bf9398bd37103ca879e825fad9bef4bfdd
+Author: Ebrahim Byagowi <ebrahim@gnu.org>
+Date:   Mon Jun 3 05:48:04 2019 -0700
+
+    Reapply possible bsearch overflow fix
+    
+    Originally introduced in 21ede86 (#1314) but as it wasn't applied to hb_bsearch
+    accidentally removed while merging hb_bsearch_r to it.
+
+ src/hb-algs.hh | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 5846884f86cae61c1b0c369c81427712fb97ed83
+Author: Bruce Mitchener <bruce.mitchener@gmail.com>
+Date:   Mon Jun 3 15:00:25 2019 +0700
+
+    test: Use nullptr in C++ code. (#1744)
+
+ src/test-ot-color.cc             | 8 ++++----
+ test/fuzzing/hb-shape-fuzzer.cc  | 6 +++---
+ test/fuzzing/hb-subset-fuzzer.cc | 2 +-
+ util/options-subset.cc           | 2 +-
+ 4 files changed, 9 insertions(+), 9 deletions(-)
+
+commit 7c14b9014587e1423ef7481058e48dae84a65fce
+Author: Ebrahim Byagowi <ebrahim@gnu.org>
+Date:   Sun Jun 2 13:51:26 2019 +0430
+
+    [ci] revert to xenial
+    
+    It should've done in a branch
+
+ .travis.yml | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 8278ff7dce41e6694eba15a7c94a0c0eb3bca427
+Author: Ebrahim Byagowi <ebrahim@gnu.org>
+Date:   Sun Jun 2 00:36:30 2019 +0430
+
+    minor
+
+ src/hb-algs.hh | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+commit 33d38e793e2e4882337e5f42fbbae7d00d343940
+Author: Ebrahim Byagowi <ebrahim@gnu.org>
+Date:   Sun Jun 2 00:19:57 2019 +0430
+
+    Use a unified bsearch (#1741)
+    
+    A part of #593
+
+ src/hb-aat-layout.cc        | 10 +++++-----
+ src/hb-algs.hh              | 29 ++++-------------------------
+ src/hb-ot-post-table.hh     |  4 ++--
+ src/hb-ot-var-mvar-table.hh |  6 +++---
+ 4 files changed, 14 insertions(+), 35 deletions(-)
+
+commit 97b92685775983a280f335423263a6a8d82c3941
+Author: Ebrahim Byagowi <ebrahim@gnu.org>
+Date:   Sat Jun 1 21:25:09 2019 +0430
+
+    [ci] Downgrade Travis distribution upon Behdad request
+
+ .travis.yml | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit faf69e03f5ab9f3926442525f6c6e30fbc7a93d5
+Author: Ebrahim Byagowi <ebrahim@gnu.org>
+Date:   Sat Jun 1 11:02:25 2019 +0430
+
+    [ci] Install ragel on appveyor mingw bots
+    
+    Hopefully autotools timestamps issues will go
+
+ appveyor.yml | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit c91f3fa3eaf77fa255292c779f88da4feaaae8a0
+Author: Ebrahim Byagowi <ebrahim@gnu.org>
+Date:   Sat Jun 1 10:55:37 2019 +0430
+
+    [dwrite] Replace REPLACEME with release version the symbol had
+
+ src/hb-directwrite.cc | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 93c455567fe3d92a7efe65bf0e9ac2af794e2c4f
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Fri May 31 22:53:27 2019 -0700
+
+    2.5.1
+
+ NEWS             | 11 +++++++++++
+ configure.ac     |  2 +-
+ src/hb-version.h |  4 ++--
+ 3 files changed, 14 insertions(+), 3 deletions(-)
+
+commit 10e3cb9246ab3d288af4effe484f4d8beb2243d6
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Fri May 31 22:56:37 2019 -0700
+
+    [docs] Fix dist
+
+ docs/Makefile.am | 1 +
+ 1 file changed, 1 insertion(+)
+
+commit 619f5f1eb9e5e2a4f326f89c9e3e05b01f9c042f
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Fri May 31 22:31:35 2019 -0700
+
+    Fourth try at building VS bots
+    
+    Based on https://github.com/harfbuzz/harfbuzz/issues/1730#issuecomment-497151210
+
+ src/hb-algs.hh | 16 +++++++++++-----
+ 1 file changed, 11 insertions(+), 5 deletions(-)
+
+commit f387a09742bd8e4a7a8da6db954339609839a113
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Fri May 31 22:12:23 2019 -0700
+
+    [ci] Disable VS 2013
+    
+    That one doesn't even understand constexpr.
+
+ appveyor.yml | 12 ++++++------
+ 1 file changed, 6 insertions(+), 6 deletions(-)
+
+commit aba3888d933474a874d2f3ff02397b523846466c
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Fri May 31 22:11:27 2019 -0700
+
+    Third try at fixing VS build
+    
+    https://github.com/harfbuzz/harfbuzz/issues/1730
+
+ src/hb-algs.hh | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 8aaecbb5832568135f6149254ed9e17ac4310341
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Fri May 31 21:41:40 2019 -0700
+
+    Second VS fix try
+    
+    https://github.com/harfbuzz/harfbuzz/issues/1730
+
+ src/hb-algs.hh | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+commit 5a1b5c0a8b91a2291e7327e84acba2406a14414e
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Fri May 31 21:08:39 2019 -0700
+
+    Try fixing VS builds
+    
+    Hopefully fixes https://github.com/harfbuzz/harfbuzz/issues/1730
+
+ src/hb-algs.hh | 7 ++++++-
+ 1 file changed, 6 insertions(+), 1 deletion(-)
+
+commit 66381fb73f21e8e3c1c14b196e64d1004be303c7
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Fri May 31 20:20:43 2019 -0700
+
+    [ci] Enable other versions of Visual Studio
+    
+    https://github.com/harfbuzz/harfbuzz/issues/1730
+
+ appveyor.yml | 44 ++++++++++++++++++++++++--------------------
+ 1 file changed, 24 insertions(+), 20 deletions(-)
+
+commit 92fde3dea282d308fad2b8e93cd638aa813c6f2a
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Fri May 31 20:16:25 2019 -0700
+
+    Whitespace
+
+ src/hb-algs.hh | 8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+commit 49879adbfc57c3173a25bbc55afc0796ee71b6da
+Author: rsheeter <rsheeter@google.com>
+Date:   Fri May 31 15:14:44 2019 -0700
+
+    [subset] Correct calculation of max offset; fixes bug where loca would erroneously be short
+
+ src/hb-ot-glyf-table.hh | 5 ++++-
+ 1 file changed, 4 insertions(+), 1 deletion(-)
+
+commit 2ad4ba7bc04fbbd886a2da6fbc55a4e13468d878
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Fri May 31 15:48:54 2019 -0700
+
+    [gsub] Minor
+
+ src/hb-ot-layout-gsub-table.hh | 40 +++++++++++++++++++++-------------------
+ 1 file changed, 21 insertions(+), 19 deletions(-)
+
+commit 2dbdec66a17af94fffc50949e4712465aada9a68
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Fri May 31 15:38:11 2019 -0700
+
+    [gsub] Porting serialize to iterators
+
+ src/hb-ot-layout-gsub-table.hh | 15 ++++++++++-----
+ 1 file changed, 10 insertions(+), 5 deletions(-)
+
+commit 1834cf86d40abfbb536db1edb366c90318ba49fc
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Fri May 31 14:39:32 2019 -0700
+
+    [serialize] Pass offset to serialize_subset()
+
+ src/hb-open-type.hh            | 14 +++++++++-----
+ src/hb-ot-layout-common.hh     |  4 ++--
+ src/hb-ot-layout-gdef-table.hh | 12 ++++++------
+ src/hb-ot-layout-gsubgpos.hh   |  7 ++++---
+ 4 files changed, 21 insertions(+), 16 deletions(-)
+
+commit 926044162472aeca8f5032b11b544d38be587110
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Fri May 31 14:34:34 2019 -0700
+
+    [serialize] Pass offset to serialize_copy()
+
+ src/hb-open-type.hh          | 12 ++++++++----
+ src/hb-ot-layout-common.hh   |  4 ++--
+ src/hb-ot-layout-gsubgpos.hh |  2 +-
+ src/hb-ot-name-table.hh      |  2 +-
+ 4 files changed, 12 insertions(+), 8 deletions(-)
+
+commit 87dd4bff1c42f1845fb3d11477e5de210121d48e
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Thu May 30 11:26:17 2019 -0400
+
+    [math] Rename HB_MATH_GLYPH_PART_FLAG_EXTENDER
+    
+    To HB_OT_MATH_GLYPH_PART_FLAG_EXTENDER.  Added a deprecated macro.
+    
+    Fixes https://github.com/harfbuzz/harfbuzz/issues/1734
+
+ src/hb-ot-deprecated.h  |  4 ++++
+ src/hb-ot-math-table.hh |  2 +-
+ src/hb-ot-math.h        |  2 +-
+ test/api/test-ot-math.c | 16 ++++++++--------
+ 4 files changed, 14 insertions(+), 10 deletions(-)
+
+commit 88f9dab366491af144da316384991e74af443226
+Author: Ebrahim Byagowi <ebrahim@gnu.org>
+Date:   Wed May 29 01:55:31 2019 +0430
+
+    [ci] Clean up and add disabled bots of other msvc versions (#1733)
+
+ appveyor.yml | 41 ++++++++++++++++++++++++++++++-----------
+ 1 file changed, 30 insertions(+), 11 deletions(-)
+
+commit da9d43171ba4ae0a78c92e9de83498fd2f513c8b
+Author: Bruce Mitchener <bruce.mitchener@gmail.com>
+Date:   Tue May 28 21:50:17 2019 +0700
+
+    Fix some typos.
+
+ docs/usermanual-clusters.xml        | 4 ++--
+ docs/usermanual-fonts-and-faces.xml | 2 +-
+ src/hb-ot-math.h                    | 2 +-
+ 3 files changed, 4 insertions(+), 4 deletions(-)
+
+commit 8a133718472d152fa1f69ec52862b019b71b371f
+Author: Ebrahim Byagowi <ebrahim@gnu.org>
+Date:   Tue May 28 13:54:45 2019 +0430
+
+    [test] minor, fix copyright
+    
+    nothing important, fixing a copy paste error inconsistency
+
+ test/api/test-aat-layout.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 13316ac5d435f11c2c65fd2d762841a819afb639
+Author: Ebrahim Byagowi <ebrahim@gnu.org>
+Date:   Tue May 28 13:48:39 2019 +0430
+
+    [test] minor style improve
+
+ test/subset/run-tests.py | 38 +++++++++++++++++++-------------------
+ 1 file changed, 19 insertions(+), 19 deletions(-)
+
+commit d64fb9db520d77eb7bb40ceda4e20be5e602bf91
+Author: David Corbett <corbett.dav@husky.neu.edu>
+Date:   Sun May 26 11:05:54 2019 -0400
+
+    [use] Allow U+1A60 TAI THAM SIGN SAKOT after vowel
+
+ src/gen-use-table.py                               |   7 +-
+ src/hb-ot-shape-complex-use-machine.hh             | 609 +++++++++++----------
+ src/hb-ot-shape-complex-use-machine.rl             |  20 +-
+ src/hb-ot-shape-complex-use-table.cc               |   4 +-
+ src/hb-ot-shape-complex-use.cc                     |   3 +
+ src/hb-ot-shape-complex-use.hh                     |   2 +
+ .../3cc01fede4debd4b7794ccb1b16cdb9987ea7571.ttf   | Bin 0 -> 1144 bytes
+ .../fd565cabd5208d345d0ed4fda7ae742917d846a5.ttf   | Bin 1056 -> 0 bytes
+ .../shaping/data/in-house/tests/use-syllable.tests |   5 +-
+ 9 files changed, 351 insertions(+), 299 deletions(-)
+
+commit 179570d4cae9aefcd91d540b8865a81d569b3358
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Mon May 27 13:08:07 2019 -0400
+
+    [atomic] Fix warning, second time
+    
+    Fixes https://bugzilla.mozilla.org/show_bug.cgi?id=1554306
+
+ src/hb-atomic.hh | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit ad17a8bdd571c7b275f9735e3602a8068f12934f
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Sat May 25 16:33:21 2019 -0400
+
+    [ucd] Update for latest packTab
+
+ src/gen-ucd-table.py | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+commit 771712b3ca97035ba5690e65bd7e63a852286159
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Sat May 25 15:58:45 2019 -0400
+
+    [ucd] Update for recent packTab
+    
+    No need for separate youseedy package.
+
+ src/gen-ucd-table.py | 8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+commit 52aa6c57c5a4b18807a1329549dface90b148f22
+Author: Ebrahim Byagowi <ebrahim@gnu.org>
+Date:   Sat May 25 22:55:06 2019 +0430
+
+    [ci] minor
+
+ .circleci/config.yml | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+commit 9b75da4299adb5487519ddf96e99949b1dad2d5c
+Author: Ebrahim Byagowi <ebrahim@gnu.org>
+Date:   Sat May 25 22:46:10 2019 +0430
+
+    [ci] minor
+
+ .circleci/config.yml | 2 ++
+ 1 file changed, 2 insertions(+)
+
+commit 9158cab3f9f9e1a4941c1dbf0aa71455ceb00da6
+Author: Ebrahim Byagowi <ebrahim@gnu.org>
+Date:   Sat May 25 22:33:02 2019 +0430
+
+    [ci] Store dist-win result instead
+
+ .circleci/config.yml | 11 +++++------
+ 1 file changed, 5 insertions(+), 6 deletions(-)
+
+commit 85b68a42af541bc91f2851389ac09b012a6d3aa1
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Sat May 25 12:59:01 2019 -0400
+
+    [atomic] Fix warnings
+    
+    https://bugzilla.mozilla.org/show_bug.cgi?id=1554306
+
+ src/hb-atomic.hh | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 941c1b6d711b8528d0f5faa5655b09ea74f7dfb4
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Sat May 25 12:52:16 2019 -0400
+
+    [mingw] Update instructions
+    
+    https://github.com/harfbuzz/harfbuzz/issues/1728
+
+ RELEASING.md | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 210f93c143d0fa2a7b293a6ffd138b3e01cab7c0
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Sat May 25 12:49:20 2019 -0400
+
+    [mutex] Prefer pthread over windows
+    
+    https://github.com/harfbuzz/harfbuzz/issues/1728
+
+ src/hb-mutex.hh | 22 +++++++++++-----------
+ 1 file changed, 11 insertions(+), 11 deletions(-)
+
+commit a5d1b0bdaa0183e2bd310640f5867426096e0b18
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Sat May 25 12:45:40 2019 -0400
+
+    Look for pthread even if win32
+    
+    https://github.com/harfbuzz/harfbuzz/issues/1728
+
+ configure.ac | 4 +---
+ 1 file changed, 1 insertion(+), 3 deletions(-)
+
+commit f3b132187fc734cbb3705b405361c8bad9a72582
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Sat May 25 12:42:38 2019 -0400
+
+    [mingw] Some more tweaks
+    
+    It now survives ./config.status --recheck as well.
+    
+    https://github.com/harfbuzz/harfbuzz/issues/1728
+
+ mingw-configure.sh | 37 ++++++++++++++++++-------------------
+ mingw32.sh         |  2 +-
+ mingw64.sh         |  2 +-
+ 3 files changed, 20 insertions(+), 21 deletions(-)
+
+commit c41ed54b169c16fb9862e88ddf127ae68c1561e9
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Sat May 25 12:35:09 2019 -0400
+
+    [mingw] Add "make dist-win" to toplevel Makefile
+
+ Makefile.am | 16 +++++++++++++---
+ 1 file changed, 13 insertions(+), 3 deletions(-)
+
+commit a0a75a7c701932f4533b104eeb3c6087d01aa2ae
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Sat May 25 12:16:28 2019 -0400
+
+    [mingw] More
+
+ Makefile.am        |  8 +++++++-
+ mingw-configure.sh | 29 +++++++++++++++++++++++++++++
+ mingw32.sh         | 25 ++-----------------------
+ mingw64.sh         | 25 ++-----------------------
+ 4 files changed, 40 insertions(+), 47 deletions(-)
+
+commit 309a9d8ffb499f89738864acef596685ca495150
+Author: Ebrahim Byagowi <ebrahim@gnu.org>
+Date:   Sat May 25 20:40:03 2019 +0430
+
+    [ci] Remove --without-icu now that we have it in ./mingw{32,64} scripts
+
+ .circleci/config.yml | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+commit ccfe642c0cdc9fbc8280669e3e8b01dc5eb682d8
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Sat May 25 12:08:05 2019 -0400
+
+    [mingw] Force off ICU
+    
+    If cross-compiled ICU is not available, we might end up finding the
+    native ICU via icu-config.  That's distracting.
+
+ mingw32.sh | 2 +-
+ mingw64.sh | 2 +-
+ 2 files changed, 2 insertions(+), 2 deletions(-)
+
+commit 0e6b7f7cd51d7376f21a422881cb4eb542360b0b
+Author: Ebrahim Byagowi <ebrahim@gnu.org>
+Date:   Sat May 25 20:27:29 2019 +0430
+
+    [ci] Build mingw on Fedora and store .exe outputs
+
+ .circleci/config.yml | 16 ++++++++++++----
+ 1 file changed, 12 insertions(+), 4 deletions(-)
+
+commit 7b716cbbe6de2902ca6b1f67024b3f8cdb41340c
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Sat May 25 11:37:23 2019 -0400
+
+    [ming2] Update instructions
+    
+    Part of https://github.com/harfbuzz/harfbuzz/issues/1728
+    
+    Only left to write how to create a win32 bundle.
+
+ README.mingw.md | 44 ++++++++++++++++++++++++++------------------
+ RELEASING.md    | 54 ++++++------------------------------------------------
+ 2 files changed, 32 insertions(+), 66 deletions(-)
+
+commit 77a1b6b7c3bd5490ffa5bb48a8b52d9c4c18e669
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Sat May 25 11:18:40 2019 -0400
+
+    [mingw] Rename README.wine
+
+ Makefile.am                       | 2 +-
+ README.wine.md => README.mingw.md | 0
+ 2 files changed, 1 insertion(+), 1 deletion(-)
+
+commit c68b4264880c0f99bcb579345e51ce54e799655b
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Sat May 25 11:17:56 2019 -0400
+
+    [mingw] Update for recent change
+
+ README.wine.md | 2 +-
+ RELEASING.md   | 4 ++--
+ 2 files changed, 3 insertions(+), 3 deletions(-)
+
+commit 5cf2e648a67e1af20a23e010c86e8812a74ff7a4
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Sat May 25 11:15:15 2019 -0400
+
+    [mingw] Update for Fedora mingw installation location
+    
+    Also adds --with-uniscribe by default.
+    
+    Part of https://github.com/harfbuzz/harfbuzz/issues/1728
+
+ mingw32.sh | 9 +++++----
+ mingw64.sh | 9 +++++----
+ 2 files changed, 10 insertions(+), 8 deletions(-)
+
+commit e7ed85de95d3ccdb674ec5a30ae66d53cea74b3a
+Merge: f93a5e6a 97ba206b
+Author: n8willis <n8willis@users.noreply.github.com>
+Date:   Sat May 25 16:05:07 2019 +0100
+
+    Merge pull request #1691 from n8willis/usermanual-shaping
+    
+    Usermanual: Add new chapters.
+
+commit 97ba206bed341dc7c915a86531512b1e0617303d
+Author: Nathan Willis <nwillis@glyphography.com>
+Date:   Sat May 25 12:26:50 2019 +0100
+
+    Usermanual; minor.
+
+ ...usermanual-buffers-language-script-and-direction.xml |  2 +-
+ docs/usermanual-opentype-features.xml                   | 17 ++++++++++-------
+ 2 files changed, 11 insertions(+), 8 deletions(-)
+
+commit f93a5e6a7dad4fde2bf61c241bf32da678525c8b
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Fri May 24 17:02:38 2019 -0400
+
+    [win] Add mingw-ldd.py
+    
+    Part of https://github.com/harfbuzz/harfbuzz/issues/1728
+
+ mingw-ldd.py | 58 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+ 1 file changed, 58 insertions(+)
+
+commit 5fd3ece5237ac6a4ee95b2665b5e20102ed176bb
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Fri May 24 15:56:15 2019 -0400
+
+    2.5.0
+
+ Makefile.am      |  2 +-
+ NEWS             | 14 ++++++++++++++
+ configure.ac     |  2 +-
+ src/hb-version.h |  4 ++--
+ 4 files changed, 18 insertions(+), 4 deletions(-)
+
+commit 1da089179b9bd06f071f967d128819e85998b809
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Fri May 24 15:41:34 2019 -0400
+
+    Put back Since: tags for hb_color_get_*
+
+ src/hb-common.cc | 8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+commit dd5ad6b6b5aed3db62bc03b89acf90c68795edb4
+Author: Nathan Willis <nwillis@glyphography.com>
+Date:   Fri May 24 20:30:22 2019 +0100
+
+    Usermanual-buffers-chapter: trim out fallback-of-ufuncs talk and just mention that stuff exists if you care to go find it.
+
+ docs/usermanual-buffers-language-script-and-direction.xml | 13 +++++++------
+ 1 file changed, 7 insertions(+), 6 deletions(-)
+
+commit e1a5ce6aa661251e998df7b3612a1d5d39e28827
+Author: Qunxin Liu <qxliu@google.com>
+Date:   Fri May 24 10:58:52 2019 -0700
+
+    Fix fuzzer crash testcase
+    
+    Add a check for stringOffSet(uint16) overflow,
+    return early if overflow happens
+
+ src/hb-ot-name-table.hh                                |   2 +-
+ ...estcase-minimized-hb-subset-fuzzer-5077547978588160 | Bin 0 -> 339602 bytes
+ ...estcase-minimized-hb-subset-fuzzer-5761434614497280 | Bin 0 -> 532 bytes
+ 3 files changed, 1 insertion(+), 1 deletion(-)
+
+commit 240540ff9a463cf386ae5755471a5621b94290df
+Author: Nathan Willis <nwillis@glyphography.com>
+Date:   Fri May 24 20:13:35 2019 +0100
+
+    Usermanual-buffers-chapter: explain ICU fallback for Ufuncs.
+
+ docs/usermanual-buffers-language-script-and-direction.xml | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+commit d100ccad02b038719472b2cc733940ffb0374cd1
+Author: David Corbett <corbett.dav@husky.neu.edu>
+Date:   Sun May 19 10:01:20 2019 -0400
+
+    [use] Allow multiple FMs in a cluster
+
+ src/gen-use-table.py                   |  12 +-
+ src/hb-ot-shape-complex-use-machine.hh | 567 ++++++++++++++++-----------------
+ src/hb-ot-shape-complex-use-machine.rl |  14 +-
+ src/hb-ot-shape-complex-use-table.cc   |  38 ++-
+ src/hb-ot-shape-complex-use.hh         |  11 +-
+ 5 files changed, 315 insertions(+), 327 deletions(-)
+
+commit 487879e013758aef2c7f824033a40cd56361d240
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Fri May 24 12:37:53 2019 -0400
+
+    Don't compile in UCD if HB_NO_UCD defined
+
+ src/hb-ucd.cc | 3 +++
+ 1 file changed, 3 insertions(+)
+
+commit 1fffe51a295b6106a442bed8107d305c325bef05
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Fri May 24 10:52:09 2019 -0400
+
+    [blob] Shuffle
+
+ src/hb-blob.h | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+commit 96de94768b08287325be8947255917502368c337
+Merge: c96c6b28 1197bef2
+Author: rsheeter <rsheeter@google.com>
+Date:   Fri May 24 11:22:41 2019 -0700
+
+    Merge pull request #1722 from googlefonts/glyf
+    
+    [subset] Use iterators in glyf/loca subsetting
+
+commit 1197bef26c63ee896bea3fab5788635cb0fc9d18
+Author: Rod Sheeter <rsheeter@google.com>
+Date:   Fri May 24 10:52:49 2019 -0700
+
+    [subset] Per code review, use hb_array to avoid duplicated type name
+
+ src/hb-ot-glyf-table.hh | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+commit e66253283385aa67eb9c5ab627139a56f9ae5a71
+Author: Rod Sheeter <rsheeter@google.com>
+Date:   Fri May 24 10:39:56 2019 -0700
+
+    [subset] Cppcheck complaints
+
+ test/api/hb-test.h | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+commit 13b3cd307e7dedea3b419fb06d81a008e49ccff6
+Author: Rod Sheeter <rsheeter@google.com>
+Date:   Fri May 24 10:10:12 2019 -0700
+
+    [subset] Address @behdad review feedback
+
+ src/hb-ot-glyf-table.hh | 18 ++++++++----------
+ 1 file changed, 8 insertions(+), 10 deletions(-)
+
+commit c96c6b287ff1d96da6a50a8cb3f641fe8705e5f7
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Thu May 23 21:37:17 2019 -0400
+
+    One more
+
+ .circleci/config.yml | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit b567d4ea14cc6ec0e8efc64a4993a9b0461adb20
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Thu May 23 21:36:42 2019 -0400
+
+    Fix build after UCDN -> UCD
+
+ CMakeLists.txt                       | 14 --------------
+ configure.ac                         | 18 +-----------------
+ docs/usermanual-install-harfbuzz.xml | 34 ++++++++--------------------------
+ 3 files changed, 9 insertions(+), 57 deletions(-)
+
+commit 226ab06ec110f4cbd56b39ce0d05d349dfec35b9
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Thu May 23 20:39:04 2019 -0400
+
+    [ucd] Add URL to dependencies
+
+ src/gen-ucd-table.py | 3 +++
+ 1 file changed, 3 insertions(+)
+
+commit 65392b734e38668b870b1ffcbfb4b42ec289ef58
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Wed May 22 16:21:21 2019 -0400
+
+    [ucdn] Replace UCDN with a new UCD implementation
+    
+    UCDN was ~120kb of data.  New implementatoin is 69kb in default builds,
+    and 49kb if built with HB_OPTIMIZE_SIZE or __OPTIMIZE_SIZE__.  The
+    latter automatically enabled if built with -Os or -Oz.
+    
+    There's room to shave off another 10kb or 20kb.  That will follow later.
+    
+    Fixes https://github.com/harfbuzz/harfbuzz/issues/1652
+
+ src/Makefile.am              |   11 -
+ src/Makefile.sources         |    5 +-
+ src/gen-ucd-table.py         |   11 +-
+ src/hb-algs.hh               |    8 +
+ src/hb-ot-layout.cc          |   76 +-
+ src/hb-ucd-table.hh          | 5160 +++++++++++++++++++++++++++++++++++++
+ src/hb-ucd.cc                |  209 ++
+ src/hb-ucdn.cc               |  272 --
+ src/hb-ucdn/COPYING          |   13 -
+ src/hb-ucdn/Makefile.am      |   16 -
+ src/hb-ucdn/Makefile.sources |    7 -
+ src/hb-ucdn/README           |   40 -
+ src/hb-ucdn/ucdn.c           |  361 ---
+ src/hb-ucdn/ucdn.h           |  472 ----
+ src/hb-ucdn/ucdn_db.h        | 5790 ------------------------------------------
+ src/hb-unicode.cc            |    8 +-
+ 16 files changed, 5427 insertions(+), 7032 deletions(-)
+
+commit 12c59f6c40401c8221facc5d0aed63f510a77dd7
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Thu May 23 13:33:21 2019 -0400
+
+    [deprecated] Minor
+
+ src/hb-deprecated.h | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 36dee9221f8de3a2a6a23f0548460aab4982b594
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Wed May 22 15:51:53 2019 -0400
+
+    [gen-ucd] Rename
+
+ src/Makefile.am                      | 1 +
+ src/{gen-ucd.py => gen-ucd-table.py} | 0
+ 2 files changed, 1 insertion(+)
+
+commit 831c213501fc38229755be7958b2952fe0cdff0e
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Wed May 22 15:46:19 2019 -0400
+
+    [gen-ucd] Minor
+
+ src/gen-ucd.py | 30 +++++++++++++++++++++++++++---
+ 1 file changed, 27 insertions(+), 3 deletions(-)
+
+commit 15a9e32b566fbf6f4a2c6fd488d8cc3865234b17
+Merge: 993d81b9 ff7fc6d4
+Author: Ebrahim Byagowi <ebrahim@gnu.org>
+Date:   Thu May 23 11:02:15 2019 +0430
+
+    Merge pull request #1723 from googlefonts/drop_tables
+    
+    [subset] Add morx, mort, kern, and kernx to the default layout tables…
+
+commit ff7fc6d488f37e3faaca4986cde35836f013b03f
+Author: Garret Rieger <grieger@google.com>
+Date:   Wed May 22 17:36:16 2019 -0700
+
+    [subset] Add morx, mort, kern, and kernx to the default layout tables drop list.
+
+ src/hb-subset-input.cc | 4 ++++
+ src/hb-subset.cc       | 4 ++++
+ 2 files changed, 8 insertions(+)
+
+commit 993d81b9c57f2e27d80d276953b0430821129425
+Author: Qunxin Liu <qxliu@google.com>
+Date:   Tue May 14 13:55:11 2019 -0700
+
+    [subset] Add one ttf file with fvar/STAT tables to integration test
+    Ignore gvar/MVAR/HVAR table
+    add support for --nameIDs=* option
+
+ src/hb-ot-cmap-table.hh                            |  27 +++++++++++++++++----
+ src/hb-ot-stat-table.hh                            |   2 +-
+ src/hb-subset-input.cc                             |   1 +
+ src/hb-subset-plan.cc                              |   6 +----
+ test/api/hb-subset-test.h                          |   2 +-
+ .../Comfortaa-Regular-new.default.61,62,63.ttf     | Bin 0 -> 6492 bytes
+ .../basics/Comfortaa-Regular-new.default.61,63.ttf | Bin 0 -> 6316 bytes
+ .../basics/Comfortaa-Regular-new.default.61.ttf    | Bin 0 -> 6148 bytes
+ .../basics/Comfortaa-Regular-new.default.62.ttf    | Bin 0 -> 6088 bytes
+ .../basics/Comfortaa-Regular-new.default.63.ttf    | Bin 0 -> 6068 bytes
+ ...Regular-new.drop-hints-retain-gids.61,62,63.ttf | Bin 0 -> 3284 bytes
+ ...aa-Regular-new.drop-hints-retain-gids.61,63.ttf | Bin 0 -> 3164 bytes
+ ...ortaa-Regular-new.drop-hints-retain-gids.61.ttf | Bin 0 -> 2868 bytes
+ ...ortaa-Regular-new.drop-hints-retain-gids.62.ttf | Bin 0 -> 3020 bytes
+ ...ortaa-Regular-new.drop-hints-retain-gids.63.ttf | Bin 0 -> 3024 bytes
+ .../Comfortaa-Regular-new.drop-hints.61,62,63.ttf  | Bin 0 -> 1952 bytes
+ .../Comfortaa-Regular-new.drop-hints.61,63.ttf     | Bin 0 -> 1832 bytes
+ .../basics/Comfortaa-Regular-new.drop-hints.61.ttf | Bin 0 -> 1704 bytes
+ .../basics/Comfortaa-Regular-new.drop-hints.62.ttf | Bin 0 -> 1688 bytes
+ .../basics/Comfortaa-Regular-new.drop-hints.63.ttf | Bin 0 -> 1688 bytes
+ .../Comfortaa-Regular-new.name-ids.61,62,63.ttf    | Bin 0 -> 6236 bytes
+ .../Comfortaa-Regular-new.name-ids.61,63.ttf       | Bin 0 -> 6060 bytes
+ .../basics/Comfortaa-Regular-new.name-ids.61.ttf   | Bin 0 -> 5892 bytes
+ .../basics/Comfortaa-Regular-new.name-ids.62.ttf   | Bin 0 -> 5832 bytes
+ .../basics/Comfortaa-Regular-new.name-ids.63.ttf   | Bin 0 -> 5812 bytes
+ .../Comfortaa-Regular-new.retain-gids.61,62,63.ttf | Bin 0 -> 7824 bytes
+ .../Comfortaa-Regular-new.retain-gids.61,63.ttf    | Bin 0 -> 7648 bytes
+ .../Comfortaa-Regular-new.retain-gids.61.ttf       | Bin 0 -> 7312 bytes
+ .../Comfortaa-Regular-new.retain-gids.62.ttf       | Bin 0 -> 7420 bytes
+ .../Comfortaa-Regular-new.retain-gids.63.ttf       | Bin 0 -> 7404 bytes
+ ...eSansPro-Regular.default.1FC,21,41,20,62,63.otf | Bin 3784 -> 2384 bytes
+ .../SourceSansPro-Regular.default.61,62,63.otf     | Bin 3496 -> 2096 bytes
+ ...ourceSansPro-Regular.default.D7,D8,D9,DA,DE.otf | Bin 3612 -> 2212 bytes
+ ...subroutinize-retain-gids.1FC,21,41,20,62,63.otf | Bin 33516 -> 32124 bytes
+ ...Regular.desubroutinize-retain-gids.61,62,63.otf | Bin 31080 -> 29688 bytes
+ ...r.desubroutinize-retain-gids.D7,D8,D9,DA,DE.otf | Bin 34708 -> 33316 bytes
+ ...o-Regular.desubroutinize.1FC,21,41,20,62,63.otf | Bin 3640 -> 2240 bytes
+ ...urceSansPro-Regular.desubroutinize.61,62,63.otf | Bin 3400 -> 2000 bytes
+ ...nsPro-Regular.desubroutinize.D7,D8,D9,DA,DE.otf | Bin 3596 -> 2196 bytes
+ ...subroutinize-retain-gids.1FC,21,41,20,62,63.otf | Bin 33352 -> 31960 bytes
+ ...p-hints-desubroutinize-retain-gids.61,62,63.otf | Bin 30956 -> 29564 bytes
+ ...s-desubroutinize-retain-gids.D7,D8,D9,DA,DE.otf | Bin 34560 -> 33168 bytes
+ ...rop-hints-desubroutinize.1FC,21,41,20,62,63.otf | Bin 3480 -> 2080 bytes
+ ...-Regular.drop-hints-desubroutinize.61,62,63.otf | Bin 3288 -> 1876 bytes
+ ...ar.drop-hints-desubroutinize.D7,D8,D9,DA,DE.otf | Bin 3448 -> 2048 bytes
+ ...r.drop-hints-retain-gids.1FC,21,41,20,62,63.otf | Bin 33448 -> 32052 bytes
+ ...Pro-Regular.drop-hints-retain-gids.61,62,63.otf | Bin 31028 -> 29632 bytes
+ ...gular.drop-hints-retain-gids.D7,D8,D9,DA,DE.otf | Bin 34576 -> 33180 bytes
+ ...nsPro-Regular.drop-hints.1FC,21,41,20,62,63.otf | Bin 3564 -> 2164 bytes
+ .../SourceSansPro-Regular.drop-hints.61,62,63.otf  | Bin 3340 -> 1940 bytes
+ ...ceSansPro-Regular.drop-hints.D7,D8,D9,DA,DE.otf | Bin 3464 -> 2064 bytes
+ ...sPro-Regular.retain-gids.1FC,21,41,20,62,63.otf | Bin 33668 -> 32276 bytes
+ .../SourceSansPro-Regular.retain-gids.61,62,63.otf | Bin 31180 -> 29788 bytes
+ ...eSansPro-Regular.retain-gids.D7,D8,D9,DA,DE.otf | Bin 34724 -> 33332 bytes
+ .../Roboto-Regular.default.1FC,21,41,20,62,63.ttf  | Bin 3772 -> 3164 bytes
+ .../full-font/Roboto-Regular.default.61,62,63.ttf  | Bin 3368 -> 2760 bytes
+ .../Roboto-Regular.default.D7,D8,D9,DA,DE.ttf      | Bin 3732 -> 3124 bytes
+ ...oboto-Regular.drop-hints.1FC,21,41,20,62,63.ttf | Bin 2224 -> 1616 bytes
+ .../Roboto-Regular.drop-hints.61,62,63.ttf         | Bin 2016 -> 1408 bytes
+ .../Roboto-Regular.drop-hints.D7,D8,D9,DA,DE.ttf   | Bin 2252 -> 1644 bytes
+ ...gular.default.3042,3044,3046,3048,304A,304B.ttf | Bin 3112 -> 2684 bytes
+ ...gular.default.3042,3044,3046,73E0,5EA6,8F38.ttf | Bin 3356 -> 2928 bytes
+ .../Mplus1p-Regular.default.61,63,65,6B.ttf        | Bin 2656 -> 2228 bytes
+ ...gular.default.660E,6975,73E0,5EA6,8F38,6E05.ttf | Bin 3652 -> 3224 bytes
+ .../japanese/Mplus1p-Regular.default.660E.ttf      | Bin 2396 -> 1968 bytes
+ ...ar.drop-hints.3042,3044,3046,3048,304A,304B.ttf | Bin 2384 -> 1956 bytes
+ ...ar.drop-hints.3042,3044,3046,73E0,5EA6,8F38.ttf | Bin 2628 -> 2200 bytes
+ .../Mplus1p-Regular.drop-hints.61,63,65,6B.ttf     | Bin 1928 -> 1500 bytes
+ ...ar.drop-hints.660E,6975,73E0,5EA6,8F38,6E05.ttf | Bin 2924 -> 2496 bytes
+ .../japanese/Mplus1p-Regular.drop-hints.660E.ttf   | Bin 1668 -> 1240 bytes
+ test/subset/data/fonts/Comfortaa-Regular-new.ttf   | Bin 0 -> 230316 bytes
+ test/subset/data/tests/basics.tests                |   1 +
+ test/subset/generate-expected-outputs.py           |   3 +--
+ test/subset/run-tests.py                           |   3 ++-
+ util/options-subset.cc                             |  23 +++++++++++++++---
+ 75 files changed, 50 insertions(+), 18 deletions(-)
+
+commit 58ce477ac170969430310750b78dcb5f9e3b06a3
+Author: Rod Sheeter <rsheeter@google.com>
+Date:   Tue May 21 20:22:40 2019 -0700
+
+    [subset] Report failure more often
+
+ src/hb-ot-glyf-table.hh | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+commit 51a0129f7322e97825455df4eb6eecfea14980f5
+Author: Rod Sheeter <rsheeter@google.com>
+Date:   Tue May 21 20:12:19 2019 -0700
+
+    [subset] Thar be comparison of integers of different signs
+
+ test/api/hb-test.h | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 14e3b0cf41d9657c39f1f921f7e09a1418fa3278
+Author: Rod Sheeter <rsheeter@google.com>
+Date:   Tue May 21 20:09:36 2019 -0700
+
+    [subset] Code review feedback
+
+ src/hb-ot-glyf-table.hh | 53 +++++++++++++++++++++++++------------------------
+ 1 file changed, 27 insertions(+), 26 deletions(-)
+
+commit a03ed95e7d50b9dd947e8982c7730de969795b05
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Tue May 21 16:43:14 2019 -0400
+
+    [gen-ucd] Generate decomposition tables
+    
+    Code is ugly.  Ugh.
+
+ src/gen-ucd.py | 40 ++++++++++++++++++++--------------------
+ 1 file changed, 20 insertions(+), 20 deletions(-)
+
+commit 8a48c88fa9fe047a83ba4a45dbd6399412ca3302
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Tue May 21 13:02:54 2019 -0400
+
+    [gen-ucd] Comment
+
+ src/gen-ucd.py | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+commit b71d353cee89a6654810f75e7a1d7fd156b76faa
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Mon May 20 17:33:55 2019 -0400
+
+    [gen-ucd] Remove some code
+
+ src/gen-ucd.py | 7 -------
+ 1 file changed, 7 deletions(-)
+
+commit 4ea44112b5163591ce0b086e0d13ec368f4f6ddc
+Author: Rod Sheeter <rsheeter@google.com>
+Date:   Tue May 21 13:07:43 2019 -0700
+
+    [subset] Remove missed reference to hb-subset-glyf, was deleted
+
+ src/Makefile.sources | 1 -
+ 1 file changed, 1 deletion(-)
+
+commit b928de91a755788fd0fad9fa0f5f03c5670ac6a3
+Author: Garret Rieger <grieger@google.com>
+Date:   Tue May 21 11:23:26 2019 -0700
+
+    [subset] Add test/subset/data/expected/layout to dist list.
+
+ test/subset/data/Makefile.am | 1 +
+ 1 file changed, 1 insertion(+)
+
+commit 0af9de13b78ddd35f58ee02ce8ffeffd99509ec5
+Author: Garret Rieger <grieger@google.com>
+Date:   Mon May 20 15:04:20 2019 -0700
+
+    [subset] For gsub subsetting only consider glyphs reachable via gsub closure.
+
+ src/hb-ot-layout-gsub-table.hh |  4 +--
+ src/hb-subset-plan.cc          | 55 ++++++++++++++++++++----------------------
+ src/hb-subset-plan.hh          | 10 ++++++++
+ 3 files changed, 38 insertions(+), 31 deletions(-)
+
+commit c740c8636b48b1790bba42445a301e8e1cf8f749
+Author: Garret Rieger <grieger@google.com>
+Date:   Thu May 16 10:57:33 2019 -0700
+
+    [subset] Add integration tests for SingleSubst.
+
+ test/subset/data/Makefile.sources                      |   1 +
+ ...ular.smallcaps.keep-layout-retain-gids.41,42,43.ttf | Bin 0 -> 6780 bytes
+ ...Regular.smallcaps.keep-layout-retain-gids.41,43.ttf | Bin 0 -> 6396 bytes
+ ...to-Regular.smallcaps.keep-layout-retain-gids.41.ttf | Bin 0 -> 6032 bytes
+ ...to-Regular.smallcaps.keep-layout-retain-gids.43.ttf | Bin 0 -> 6088 bytes
+ ...Regular.smallcaps.keep-layout-retain-gids.CA,CB.ttf | Bin 0 -> 7932 bytes
+ .../Roboto-Regular.smallcaps.keep-layout.41,42,43.ttf  | Bin 0 -> 2972 bytes
+ .../Roboto-Regular.smallcaps.keep-layout.41,43.ttf     | Bin 0 -> 2572 bytes
+ .../layout/Roboto-Regular.smallcaps.keep-layout.41.ttf | Bin 0 -> 2196 bytes
+ .../layout/Roboto-Regular.smallcaps.keep-layout.43.ttf | Bin 0 -> 2268 bytes
+ .../Roboto-Regular.smallcaps.keep-layout.CA,CB.ttf     | Bin 0 -> 2612 bytes
+ test/subset/data/fonts/Roboto-Regular.smallcaps.ttf    | Bin 0 -> 131632 bytes
+ test/subset/data/profiles/keep-layout-retain-gids.txt  |   2 ++
+ test/subset/data/profiles/keep-layout.txt              |   1 +
+ test/subset/data/tests/full-font.tests                 |   1 -
+ test/subset/data/tests/layout.tests                    |  13 +++++++++++++
+ test/subset/generate-expected-outputs.py               |   3 ++-
+ 17 files changed, 19 insertions(+), 2 deletions(-)
+
+commit 349d692b0ee45330220fd3ec9267979d73acd149
+Author: Rod Sheeter <rsheeter@google.com>
+Date:   Tue May 21 12:38:53 2019 -0700
+
+    [subset] Iter in and out for loca
+
+ src/hb-ot-glyf-table.hh | 31 ++++++++++++++++---------------
+ test/api/hb-test.h      |  7 ++-----
+ 2 files changed, 18 insertions(+), 20 deletions(-)
+
+commit 95445d79be0a79e6e2d384d46819730146d397d8
+Author: Rod Sheeter <rsheeter@google.com>
+Date:   Tue May 21 11:14:31 2019 -0700
+
+    [subset] Write loca using more idiomatic harfbuzzese
+
+ src/hb-ot-glyf-table.hh | 35 +++++++++++++++++++----------------
+ 1 file changed, 19 insertions(+), 16 deletions(-)
+
+commit d1b12a546561a78ae3c3e9d6bffa057caf82dbee
+Merge: 3a43603e f49a5bec
+Author: Rod Sheeter <rsheeter@google.com>
+Date:   Mon May 20 21:29:54 2019 -0700
+
+    Merge branch 'master' of https://github.com/harfbuzz/harfbuzz into glyf
+
+commit 3a43603ecea2c349f58396e103a52948776681e0
+Author: Rod Sheeter <rsheeter@google.com>
+Date:   Mon May 20 20:40:55 2019 -0700
+
+    [subset] Fix memory leak caused by failure to cleanup glyf accelerator
+
+ src/hb-ot-glyf-table.hh | 42 ++++++++++++++++++++++++++----------------
+ 1 file changed, 26 insertions(+), 16 deletions(-)
+
+commit 5cedda5e4a3f726168b87d357aee723e6fd919cd
+Author: Rod Sheeter <rsheeter@google.com>
+Date:   Thu May 16 19:16:52 2019 -0700
+
+    [subset] Fix null pointer deref, tidy up a bit
+
+ src/hb-ot-glyf-table.hh     | 282 +++++++++++++++++++++++++-------------------
+ test/api/test-subset-glyf.c |  18 +--
+ 2 files changed, 167 insertions(+), 133 deletions(-)
+
+commit 8a84b540c7b850c1fb30d5bc1ffdeb43033be173
+Author: Rod Sheeter <rsheeter@google.com>
+Date:   Thu May 16 19:14:16 2019 -0700
+
+    [subset] Tests passing using iterator based glyf
+
+ src/hb-ot-glyf-table.hh     | 117 +++++++++++++++++++++++++++++++-------------
+ test/api/test-subset-glyf.c |   4 +-
+ 2 files changed, 86 insertions(+), 35 deletions(-)
+
+commit 82bbec306376d61b6700461c4038c6789e60a998
+Merge: 9d09ac13 b7be5931
+Author: Rod Sheeter <rsheeter@google.com>
+Date:   Thu May 16 15:14:01 2019 -0700
+
+    Merge branch 'master' of https://github.com/harfbuzz/harfbuzz into glyf
+
+commit 9d09ac13a114967576284d0b006a0ac7965d928a
+Author: rsheeter <rsheeter@google.com>
+Date:   Sat May 11 23:16:40 2019 -0700
+
+    [subset] Tweak hint stripping
+
+ src/hb-ot-glyf-table.hh | 46 +++++++++++++++++++++++++++++++++-------------
+ 1 file changed, 33 insertions(+), 13 deletions(-)
+
+commit 3a4c928fcfce5a8c7a56907b9945e87b0ce8e327
+Author: rsheeter <rsheeter@google.com>
+Date:   Sat May 11 22:06:46 2019 -0700
+
+    [subset] Fix glyf tests except hint stripping & local test asan
+
+ src/hb-ot-glyf-table.hh     | 93 +++++++++++++++++++++++++++++++++------------
+ test/api/hb-subset-test.h   |  2 +-
+ test/api/hb-test.h          | 13 +++++++
+ test/api/test-subset-glyf.c |  8 ++--
+ 4 files changed, 86 insertions(+), 30 deletions(-)
+
+commit b77dde8f138442935e5ca99460a520a4117d6dd2
+Author: Rod Sheeter <rsheeter@google.com>
+Date:   Fri May 10 16:52:19 2019 -0700
+
+    [subset] Destroy blob
+
+ src/hb-ot-glyf-table.hh | 2 ++
+ 1 file changed, 2 insertions(+)
+
+commit 14db6512f8dca80a575f468708949346b005834a
+Author: Rod Sheeter <rsheeter@google.com>
+Date:   Fri May 10 09:32:43 2019 -0700
+
+    [subset] Correct flipped use short computation
+
+ src/hb-ot-glyf-table.hh | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+commit ab3fe5de2bbe10fdc13711537f824b62d091f995
+Author: Rod Sheeter <rsheeter@google.com>
+Date:   Thu May 9 22:12:20 2019 -0700
+
+    [subset] Glyf by iter now runs but fails tests
+
+ src/hb-ot-glyf-table.hh | 88 +++++++++++++++++++++++++++++++++----------------
+ 1 file changed, 59 insertions(+), 29 deletions(-)
+
+commit f8de063b48c243d551c8892bdd2a799606fda3f4
+Merge: 0d7fef2d 8f174870
+Author: Rod Sheeter <rsheeter@google.com>
+Date:   Thu May 9 20:02:38 2019 -0700
+
+    Merge branch 'glyf' of github.com:googlefonts/harfbuzz into glyf
+
+commit 0d7fef2d50bba714815c0c13f3b3dd6464710a1d
+Author: rsheeter <rsheeter@google.com>
+Date:   Wed May 8 16:52:00 2019 -0700
+
+    [subset] Dinner time, checkpoint
+
+ src/hb-ot-glyf-table.hh | 97 +++++++++++++++++++++++++++++--------------------
+ 1 file changed, 58 insertions(+), 39 deletions(-)
+
+commit 240bc86e3a0b177ee84ec9c60723304a0cf4c405
+Author: rsheeter <rsheeter@google.com>
+Date:   Wed May 8 14:59:03 2019 -0700
+
+    [subset] Remove subset-glyf; want everything to point to new iter-based edition. Some of the code will resurface as impl builds out.
+
+ src/Makefile.sources    |   2 -
+ src/hb-ot-glyf-table.hh |   9 +-
+ src/hb-subset-glyf.cc   | 346 ------------------------------------------------
+ src/hb-subset-glyf.hh   |  40 ------
+ src/hb-subset.cc        |   1 -
+ 5 files changed, 6 insertions(+), 392 deletions(-)
+
+commit 02d4d4f3e67dcc37915bc386d506bb272455ff1e
+Author: rsheeter <rsheeter@google.com>
+Date:   Wed May 8 14:43:18 2019 -0700
+
+    [subset] Starting to sketch glyf as iter
+
+ src/hb-ot-glyf-table.hh | 60 ++++++++++++++++++++++++++++++++++++-------------
+ src/hb-subset-plan.hh   |  2 ++
+ src/hb-subset.cc        |  2 +-
+ 3 files changed, 47 insertions(+), 17 deletions(-)
+
+commit 8f174870e9eed4c47463fdb0d4fe3e22a6f5fdc8
+Author: rsheeter <rsheeter@google.com>
+Date:   Wed May 8 16:52:00 2019 -0700
+
+    [subset] Dinner time, checkpoint
+
+ src/hb-ot-glyf-table.hh | 97 +++++++++++++++++++++++++++++--------------------
+ 1 file changed, 58 insertions(+), 39 deletions(-)
+
+commit 723d054dcb6ad44e9eab4dc8cc55f8d480d2ff16
+Merge: ed727d4b e2a51ff7
+Author: rsheeter <rsheeter@google.com>
+Date:   Wed May 8 16:45:35 2019 -0700
+
+    Merge branch 'master' of https://github.com/harfbuzz/harfbuzz into glyf
+
+commit ed727d4bb74860c126675e94f87f65ff7874dbb6
+Merge: fb9bff95 e8b45c19
+Author: rsheeter <rsheeter@google.com>
+Date:   Wed May 8 16:39:45 2019 -0700
+
+    Merge branch 'master' of https://github.com/harfbuzz/harfbuzz into glyf
+
+commit fb9bff955a9356b053c5c9bcd7aa9101edb55767
+Author: rsheeter <rsheeter@google.com>
+Date:   Wed May 8 14:59:03 2019 -0700
+
+    [subset] Remove subset-glyf; want everything to point to new iter-based edition. Some of the code will resurface as impl builds out.
+
+ src/Makefile.sources    |   2 -
+ src/hb-ot-glyf-table.hh |   9 +-
+ src/hb-subset-glyf.cc   | 346 ------------------------------------------------
+ src/hb-subset-glyf.hh   |  40 ------
+ src/hb-subset.cc        |   1 -
+ 5 files changed, 6 insertions(+), 392 deletions(-)
+
+commit f9b089b695edc89023e3d62700ae68d5648f8494
+Author: rsheeter <rsheeter@google.com>
+Date:   Wed May 8 14:43:18 2019 -0700
+
+    [subset] Starting to sketch glyf as iter
+
+ src/hb-ot-glyf-table.hh | 60 ++++++++++++++++++++++++++++++++++++-------------
+ src/hb-subset-plan.hh   |  2 ++
+ src/hb-subset.cc        |  2 +-
+ 3 files changed, 47 insertions(+), 17 deletions(-)
+
+commit f49a5bec9fc241c098be5a49233aa83cd5dc098e
+Author: rsheeter <rsheeter@google.com>
+Date:   Mon May 20 20:45:11 2019 -0700
+
+    [docs] Tweak fuzzer doc
+
+ TESTING.md | 6 ++++++
+ 1 file changed, 6 insertions(+)
+
+commit 1aadd1449c65c50d5f35191f43136841c64ad399
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Mon May 20 17:29:13 2019 -0400
+
+    [gen-ucd] Generate script order table
+
+ src/gen-ucd.py | 7 ++++++-
+ 1 file changed, 6 insertions(+), 1 deletion(-)
+
+commit be8de188671c04ddd8ec4d7af38b313322189136
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Mon May 20 17:17:38 2019 -0400
+
+    [gen-ucd] Start adding script-order
+
+ src/gen-ucd.py | 14 +++++++++++++-
+ 1 file changed, 13 insertions(+), 1 deletion(-)
+
+commit 4a0eb066fdceb0cab48107f17670d6943ec0d61e
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Mon May 20 16:57:04 2019 -0400
+
+    [gen-ucd] Add gc order
+
+ src/gen-ucd.py | 7 ++++++-
+ 1 file changed, 6 insertions(+), 1 deletion(-)
+
+commit d1f9b2f961c71e5218ee359e8fb20cfbdb894c7e
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Mon May 20 15:47:49 2019 -0400
+
+    [gen-ucd] Flesh out a bit more
+
+ src/gen-ucd.py | 52 ++++++++++++++++++++++++++++++++++++++++------------
+ 1 file changed, 40 insertions(+), 12 deletions(-)
+
+commit d6de4659aa7edb991507f8838dc566874e5b6a61
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Mon May 20 15:33:23 2019 -0400
+
+    Add HB_OPTIMIZE_SIZE
+    
+    Part of https://github.com/harfbuzz/harfbuzz/issues/1652
+
+ src/hb-config.hh | 8 ++++++++
+ 1 file changed, 8 insertions(+)
+
+commit 0ff3618c2d841d16cce9ba2d73321048e7ca6a2d
+Author: Garret Rieger <grieger@google.com>
+Date:   Fri May 17 15:30:01 2019 -0700
+
+    [subset] Use hb_subset_input_t inside of subset_options_t so that input defaults are shared between the library and cli.
+
+ src/hb-subset-input.cc           |  42 ++++++++-----
+ src/hb-subset-input.hh           |   7 +--
+ src/hb-subset-plan.cc            |   3 +-
+ src/hb-subset-plan.hh            |   1 -
+ src/hb-subset.cc                 |  23 +------
+ src/hb-subset.h                  |   6 --
+ test/api/test-subset-glyf.c      |   8 ++-
+ test/fuzzing/hb-subset-fuzzer.cc |   8 ++-
+ util/Makefile.am                 |   5 +-
+ util/Makefile.sources            |   1 +
+ util/hb-subset.cc                |   9 +--
+ util/options-subset.cc           | 127 +++++++++++++++++++++++++++++++++++++++
+ util/options.cc                  | 101 -------------------------------
+ util/options.hh                  |  20 ++----
+ 14 files changed, 182 insertions(+), 179 deletions(-)
+
+commit 67064294a0c521550f5277b51b8c7e5d6bb27e68
+Author: Garret Rieger <grieger@google.com>
+Date:   Thu May 16 15:13:39 2019 -0700
+
+    [subset] Add drop-tables option to hb-subset util.
+
+ util/hb-subset.cc |  1 +
+ util/options.cc   | 45 ++++++++++++++++++++++++++++++++++++++++++---
+ util/options.hh   |  3 +++
+ 3 files changed, 46 insertions(+), 3 deletions(-)
+
+commit 3be0ffe45d1ba32ddd8d3af25ff2c420be85da76
+Author: Garret Rieger <grieger@google.com>
+Date:   Thu May 16 11:29:15 2019 -0700
+
+    [subset] Add drop tables to subset input.
+
+ src/hb-subset-input.cc             |  8 +++++
+ src/hb-subset-input.hh             |  1 +
+ src/hb-subset-plan.cc              |  3 ++
+ src/hb-subset-plan.hh              |  5 ++-
+ src/hb-subset.cc                   |  3 ++
+ src/hb-subset.h                    |  3 ++
+ test/api/Makefile.am               |  2 ++
+ test/api/test-subset-drop-tables.c | 71 ++++++++++++++++++++++++++++++++++++++
+ 8 files changed, 95 insertions(+), 1 deletion(-)
+
+commit 0ca7ad4352eff357cbb5cc1dfe62aa15b440de84
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Mon May 20 11:39:07 2019 -0400
+
+    [cff] Fix unlikely invocations
+
+ src/hb-ot-cff-common.hh | 8 ++++----
+ src/hb-ot-cff1-table.hh | 2 +-
+ 2 files changed, 5 insertions(+), 5 deletions(-)
+
+commit 9ef241cd409b7ad4eeb8259cbf1a7a01358a766e
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Mon May 20 11:38:02 2019 -0400
+
+    [test] Add one more
+
+ ...-testcase-minimized-hb-subset-fuzzer-5634197349203968 | Bin 0 -> 5791 bytes
+ 1 file changed, 0 insertions(+), 0 deletions(-)
+
+commit 3efb7af7e28061f8cd138eb2ed5261bf521abc63
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Mon May 20 11:37:16 2019 -0400
+
+    [STAT] Fix sanitize condition
+    
+    Oops!
+    
+    Fixes https://oss-fuzz.com/testcase-detail/5696825891225600
+
+ src/hb-ot-stat-table.hh                                    |   2 +-
+ ...zz-testcase-minimized-hb-subset-fuzzer-5696825891225600 | Bin 0 -> 69 bytes
+ 2 files changed, 1 insertion(+), 1 deletion(-)
+
+commit e66eb21a46b2374bfb51f86ed9f5eec35ba87a61
+Author: Ebrahim Byagowi <ebrahim@gnu.org>
+Date:   Sat May 18 07:44:48 2019 -0700
+
+    Don't set _POSIX_C_SOURCE in NetBSD
+    
+    According to a harfbuzz package patch on NetBSD project
+    https://github.com/NetBSD/pkgsrc/blob/trunk/fonts/harfbuzz/patches/patch-src_hb-blob.cc
+
+ src/hb-blob.cc | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 08c3648c6e18a0969a64284337dbd5b435d40f37
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Fri May 17 16:21:34 2019 -0700
+
+    Oops, fix include
+
+ src/hb-set.hh | 1 +
+ 1 file changed, 1 insertion(+)
+
+commit 24958b8868a8003936e872d8fda873c52d528bcf
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Fri May 17 16:20:36 2019 -0700
+
+    [set] Use StructAtOffsetUnaligned
+
+ src/hb-set.hh | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit a0febbac439ac4cc58af674f676e473d2f6d726f
+Author: rsheeter <rsheeter@google.com>
+Date:   Thu May 16 15:58:49 2019 -0700
+
+    Update TESTING.md
+
+ TESTING.md | 5 +++++
+ 1 file changed, 5 insertions(+)
+
+commit b7be59311f27112791e9b9c6356464e1c3ff92c1
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Thu May 16 13:32:56 2019 -0700
+
+    Fix msan issue
+    
+    The fact that HB_AUTO_RETURN will return rvalue-references for rvalues
+    is very disturbing.
+    
+    Even apart from that, I'm totally lost re any hb_move needs or
+    hb_forward'ing to functions/templates where the type is fixed by
+    explicitly specifying template parameters.
+    
+    ==1==ERROR: AddressSanitizer: stack-use-after-return on address 0x7f6ad65e51e0 at pc 0x0000005da240 bp 0x7ffc104ab670 sp 0x7ffc104ab668
+    READ of size 4 at 0x7f6ad65e51e0 thread T0
+    SCARINESS: 55 (4-byte-read-stack-use-after-return)
+         #0 0x5da23f in bool OT::Coverage::serialize<hb_map_iter_t<hb_map_iter_t<hb_filter_iter_t<OT::Coverage::iter_t, hb_set_t const&, $_7&, (void*)0>, OT::SingleSubstFormat1::subset(hb_subset_context_t*) const::'lambda'(unsigned int), (hb_function_sortedness_t)1, (void*)0>, $_20&, (hb_function_sortedness_t)1, (void*)0>, (void*)0>(hb_serialize_context_t*, hb_map_iter_t<hb_map_iter_t<hb_filter_iter_t<OT::Coverage::iter_t, hb_set_t const&, $_7&, (void*)0>, OT::SingleSubstFormat1::subset(hb_subset_context_t*) const::'lambda'(unsigned int), (hb_function_sortedness_t)1, (void*)0>, $_20&, (hb_function_sortedness_t)1, (void*)0>) harfbuzz/src/hb-ot-layout-common.hh:1055:16
+         #1 0x5d88f9 in bool OT::SingleSubstFormat1::serialize<hb_map_iter_t<hb_map_iter_t<hb_filter_iter_t<OT::Coverage::iter_t, hb_set_t const&, $_7&, (void*)0>, OT::SingleSubstFormat1::subset(hb_subset_context_t*) const::'lambda'(unsigned int), (hb_function_sortedness_t)1, (void*)0>, $_20&, (hb_function_sortedness_t)1, (void*)0>, (void*)0>(hb_serialize_context_t*, hb_map_iter_t<hb_map_iter_t<hb_filter_iter_t<OT::Coverage::iter_t, hb_set_t const&, $_7&, (void*)0>, OT::SingleSubstFormat1::subset(hb_subset_context_t*) const::'lambda'(unsigned int), (hb_function_sortedness_t)1, (void*)0>, $_20&, (hb_function_sortedness_t)1, (void*)0>, unsigned int) harfbuzz/src/hb-ot-layout-gsub-table.hh:98:9
+
+ src/hb-algs.hh | 8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+commit bcd3ffc948f63f59a709923a3ba6dc9d591aae6b
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Thu May 16 13:22:09 2019 -0700
+
+    Whitespace
+
+ src/hb-ot-layout-gsub-table.hh | 24 ++++++++++++------------
+ 1 file changed, 12 insertions(+), 12 deletions(-)
+
+commit 05bc5f96fb0818531404174b71c6ff497d5e2738
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Thu May 16 13:05:58 2019 -0700
+
+    [subset] Remove extra iteration
+
+ src/hb-ot-layout-gsub-table.hh | 6 ++++--
+ 1 file changed, 4 insertions(+), 2 deletions(-)
+
+commit 6555f209586886a4b2562412363cf152d7837d5c
+Author: Garret Rieger <grieger@google.com>
+Date:   Wed May 15 09:42:38 2019 -0700
+
+    [subset] Truncate empty gids at the end in retain-gids mode.
+
+ src/hb-subset-plan.cc                              |   8 ++++---
+ test/api/fonts/Roboto-Regular.a.retaingids.ttf     | Bin 0 -> 2068 bytes
+ .../SourceHanSans-Regular.41,4C2E.retaingids.otf   | Bin 2736 -> 2656 bytes
+ test/api/test-subset-glyf.c                        |  25 +++++++++++++++++++++
+ ...oboto-Regular.abc.drop-hints-retain-gids.61.ttf | Bin 744 -> 732 bytes
+ ...oboto-Regular.abc.drop-hints-retain-gids.62.ttf | Bin 712 -> 704 bytes
+ .../basics/Roboto-Regular.abc.retain-gids.61.ttf   | Bin 1808 -> 1792 bytes
+ .../basics/Roboto-Regular.abc.retain-gids.62.ttf   | Bin 1756 -> 1748 bytes
+ 8 files changed, 30 insertions(+), 3 deletions(-)
+
+commit 2376867649f97d25e4319f45845525ec207887f7
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Wed May 15 21:57:26 2019 -0700
+
+    Use hb_map(hb_add(this)) to dereference OffsetTo<>'s
+
+ src/hb-ot-layout-gsub-table.hh | 30 ++++++++++++++-------
+ src/hb-ot-layout-gsubgpos.hh   | 60 ++++++++++++++++++++++++++++--------------
+ src/hb-ot-stat-table.hh        |  2 +-
+ 3 files changed, 61 insertions(+), 31 deletions(-)
+
+commit 6f51e5552477125480f764a6af763dad9f8e3e1b
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Wed May 15 21:41:12 2019 -0700
+
+    [algs] Rename hb_bind to hb_partial
+    
+    Since our API is the invers of what std::bind is, and closer to Python
+    functools.partial().
+
+ src/hb-algs.hh   | 12 ++++++------
+ src/test-algs.cc |  6 +++---
+ 2 files changed, 9 insertions(+), 9 deletions(-)
+
+commit 0888e7bc86454020db45f78ee1136d6f3a1b9527
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Wed May 15 21:36:42 2019 -0700
+
+    [algs] Change hb_bind parameter number to be from one
+    
+    To match std:;bind, even though our interfaces are very different.
+
+ src/hb-algs.hh   | 24 +++++++++++++-----------
+ src/test-algs.cc |  6 +++---
+ 2 files changed, 16 insertions(+), 14 deletions(-)
+
+commit dfa5e4297147b52f0ed2f569c9b90a0c68c003c4
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Wed May 15 21:18:14 2019 -0700
+
+    Add back symmetric OffsetTo<>::friend operator+
+    
+    Finally seems to be working now.
+
+ src/hb-open-type.hh | 6 ++++++
+ 1 file changed, 6 insertions(+)
+
+commit a06a236891611da9db601ddbc2b1513380ad12e6
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Wed May 15 21:12:22 2019 -0700
+
+    [algs] Partialize all operators
+
+ src/hb-algs.hh   | 66 +++++++++++++++++++++++++++++++++++---------------------
+ src/test-algs.cc |  4 ++--
+ 2 files changed, 44 insertions(+), 26 deletions(-)
+
+commit edc69ec935511d1993240fb68b54b2cfd6afa888
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Wed May 15 21:09:56 2019 -0700
+
+    [algs] Rewrite bind API
+    
+    And add a partialization API use example to hb_add()
+
+ src/hb-algs.hh   | 45 ++++++++++++++++++++-------------------------
+ src/test-algs.cc |  9 ++++++---
+ 2 files changed, 26 insertions(+), 28 deletions(-)
+
+commit 16a3540ea4257a19b9bfd9d5300a280e18b423a1
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Wed May 15 20:48:20 2019 -0700
+
+    [algs] Add hb_bind0 and hb_bind1
+
+ src/hb-algs.hh   | 54 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
+ src/test-algs.cc |  7 +++++++
+ 2 files changed, 61 insertions(+)
+
+commit d214b07883a626f3ecebb027797e8bb994e174a4
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Wed May 15 19:07:39 2019 -0700
+
+    Fix clang build
+    
+    Ugh.
+    
+    In file included from hb-ot-face.cc:41:
+    ./hb-ot-layout-gsub-table.hh:293:7: error: template parameter redefines default argument
+             hb_requires (hb_is_sorted_source_of (Iterator,
+             ^
+    ./hb-meta.hh:59:27: note: expanded from macro 'hb_requires'
+     define hb_requires(Cond) hb_enable_if((Cond))
+                              ^
+    ./hb-meta.hh:57:67: note: expanded from macro 'hb_enable_if'
+     define hb_enable_if(Cond) typename hb_enable_if<(Cond)>::type* = nullptr
+                                                                      ^
+    ./hb-ot-layout-gsub-table.hh:40:5: note: previous default template argument defined here
+        hb_requires (hb_is_sorted_source_of (Iterator,
+        ^
+    ./hb-meta.hh:59:27: note: expanded from macro 'hb_requires'
+     define hb_requires(Cond) hb_enable_if((Cond))
+                              ^
+    ./hb-meta.hh:57:67: note: expanded from macro 'hb_enable_if'
+     define hb_enable_if(Cond) typename hb_enable_if<(Cond)>::type* = nullptr
+                                                                      ^
+
+ src/hb-ot-layout-gsub-table.hh | 4 +---
+ 1 file changed, 1 insertion(+), 3 deletions(-)
+
+commit 371b55c7a0c718fcaca0330edfeacf610797cf7a
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Wed May 15 18:54:07 2019 -0700
+
+    Fix clang build
+    
+    In file included from hb-ot-face.cc:41:
+    ./hb-ot-layout-gsub-table.hh:293:7: error: template parameter redefines default argument
+             hb_requires (hb_is_sorted_source_of (Iterator,
+             ^
+    ./hb-meta.hh:59:27: note: expanded from macro 'hb_requires'
+     define hb_requires(Cond) hb_enable_if((Cond))
+                              ^
+    ./hb-meta.hh:57:67: note: expanded from macro 'hb_enable_if'
+     define hb_enable_if(Cond) typename hb_enable_if<(Cond)>::type* = nullptr
+                                                                      ^
+    ./hb-ot-layout-gsub-table.hh:40:5: note: previous default template argument defined here
+        hb_requires (hb_is_sorted_source_of (Iterator,
+        ^
+    ./hb-meta.hh:59:27: note: expanded from macro 'hb_requires'
+     define hb_requires(Cond) hb_enable_if((Cond))
+                              ^
+    ./hb-meta.hh:57:67: note: expanded from macro 'hb_enable_if'
+     define hb_enable_if(Cond) typename hb_enable_if<(Cond)>::type* = nullptr
+                                                                      ^
+    1 error generated.
+
+ src/hb-ot-layout-gsub-table.hh | 4 +---
+ 1 file changed, 1 insertion(+), 3 deletions(-)
+
+commit 243a5a6af2565937705d6bc20e65a62b686bb664
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Wed May 15 19:03:59 2019 -0700
+
+    [algs] Remove pair copy constructor
+    
+    Use default.
+
+ src/hb-algs.hh   | 1 -
+ src/test-algs.cc | 1 +
+ 2 files changed, 1 insertion(+), 1 deletion(-)
+
+commit f92d188d7703184d04e8f205ae46ca3081d3e048
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Wed May 15 18:52:57 2019 -0700
+
+    Whitespace
+
+ src/hb-ot-layout-gsub-table.hh | 16 ++++++++--------
+ 1 file changed, 8 insertions(+), 8 deletions(-)
+
+commit 962f95cf802404dafadf2f999772d3f9fc949d63
+Author: Garret Rieger <grieger@google.com>
+Date:   Thu May 9 13:04:11 2019 -0700
+
+    [subset] Switch SingleSubst to use iterators in serialize.
+
+ src/hb-ot-layout-common.hh     |  6 +--
+ src/hb-ot-layout-gsub-table.hh | 97 +++++++++++++++++++++++++-----------------
+ 2 files changed, 62 insertions(+), 41 deletions(-)
+
+commit 78d35f0e780dd811ae103c96f3b1060d49046a7a
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Wed May 15 18:15:05 2019 -0700
+
+    Reduce captures of lambdas
+
+ src/hb-ot-hdmx-table.hh        |  4 ++--
+ src/hb-ot-layout-gpos-table.hh |  2 +-
+ src/hb-ot-layout-gsub-table.hh | 29 +++++++++++++++--------------
+ src/hb-ot-layout-gsubgpos.hh   | 12 ++++++------
+ src/hb-ot-name-table.hh        |  2 +-
+ src/hb-ot-stat-table.hh        |  2 +-
+ src/hb-ot-var-fvar-table.hh    |  4 ++--
+ src/hb-subset-plan.cc          |  2 +-
+ src/test-iter.cc               |  4 ++--
+ 9 files changed, 31 insertions(+), 30 deletions(-)
+
+commit 5266ca86b633b84850492b7982334fb63271ccbc
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Wed May 15 17:59:00 2019 -0700
+
+    Fix tests
+    
+    Oops.
+
+ src/test-algs.cc | 8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+commit 5da8a3a90db5e5ccaaf68de2ac312108af911821
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Wed May 15 17:11:18 2019 -0700
+
+    Remove variadic form of hb_min/hb_max
+    
+    Unused, and why here and not in other functions...
+
+ src/hb-algs.hh | 22 ++--------------------
+ 1 file changed, 2 insertions(+), 20 deletions(-)
+
+commit e5cfe9d582d86281eda2bcb85d3d1cbd4afbb5bb
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Wed May 15 16:59:36 2019 -0700
+
+    Add arithmetic operators
+
+ src/hb-algs.hh | 44 ++++++++++++++++++++++++++++++--------------
+ 1 file changed, 30 insertions(+), 14 deletions(-)
+
+commit f7a458510d9c34d1c52579985ded5082ad0f3458
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Wed May 15 16:49:35 2019 -0700
+
+    Add hb_bitwise_* ops
+
+ src/hb-algs.hh | 56 +++++++++++++++++++++++++++++++++++---------------------
+ src/hb-set.hh  | 14 +++++++-------
+ 2 files changed, 42 insertions(+), 28 deletions(-)
+
+commit d822e0a16f914ec6a7e629d21ed972d009a88561
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Wed May 15 16:30:08 2019 -0700
+
+    [array] Adjust operator!=
+    
+    See comments.
+
+ src/hb-array.hh  | 7 ++++++-
+ src/hb-vector.hh | 1 +
+ 2 files changed, 7 insertions(+), 1 deletion(-)
+
+commit 203ea58bf67b3df3e376f94cdfb37382dd3858a0
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Wed May 15 16:14:40 2019 -0700
+
+    More adjustment to OffsetTo<>::friend opeator+
+    
+    Let's see if I break any bots.  But yeah, it wasn't accepting a
+    non-const pointer.  It just happens that we don't use that in the
+    code it seems.
+
+ src/hb-open-type.hh | 10 ++++++----
+ 1 file changed, 6 insertions(+), 4 deletions(-)
+
+commit ebf47a95f29dd959319feb7f8728f7c0162a181e
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Wed May 15 15:14:26 2019 -0700
+
+    [iter] Simplify operator!= of iterator filters
+    
+    Both to save ops, and also because lambdas don't implement operator!=,
+    so this was failing in range-based for loop if a lambda was passed to
+    hb_map() or hb_filter().  Just check end-condition assuming that we
+    are comparing to .end() or iterators that are otherwise derived from
+    current iterator.  Ie. don't compare things that are expected to be
+    in common.
+
+ src/hb-iter.hh | 8 +++++---
+ 1 file changed, 5 insertions(+), 3 deletions(-)
+
+commit d3e1d5044f23a2dc910f4253c3f4976bf08f93ab
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Wed May 15 14:25:54 2019 -0700
+
+    Add all pair_t comparison operators
+
+ src/hb-algs.hh | 5 +++++
+ 1 file changed, 5 insertions(+)
+
+commit f244224dbb5ee8929af109a0c4e23d2d993c8df8
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Wed May 15 14:19:20 2019 -0700
+
+    [iter] Use default operators instead of redefining empty ones
+
+ src/hb-iter.hh | 26 +++++++++++++++-----------
+ 1 file changed, 15 insertions(+), 11 deletions(-)
+
+commit 125c45ed368ae61a74e2c558b9c884cfde6295e1
+Author: David Corbett <corbett.dav@husky.neu.edu>
+Date:   Wed May 15 17:02:32 2019 -0400
+
+    Convert Consonant_Initial_Postfixed to CONS_MED
+
+ src/gen-use-table.py                                     |   6 +++---
+ src/hb-ot-shape-complex-use-table.cc                     |   2 +-
+ .../fonts/fd565cabd5208d345d0ed4fda7ae742917d846a5.ttf   | Bin 0 -> 1056 bytes
+ test/shaping/data/in-house/tests/use-syllable.tests      |   1 +
+ 4 files changed, 5 insertions(+), 4 deletions(-)
+
+commit 99ca956c131563b57d490b1ec3c8de920645e53f
+Author: David Corbett <corbett.dav@husky.neu.edu>
+Date:   Wed May 15 16:29:51 2019 -0400
+
+    Fix record-test.sh on machines without sha1sum
+
+ test/shaping/record-test.sh | 13 ++++++++++++-
+ 1 file changed, 12 insertions(+), 1 deletion(-)
+
+commit e2767e438c56b8ee0bc2f2040c10b13b34d37f95
+Author: Ebrahim Byagowi <ebrahim@gnu.org>
+Date:   Wed May 15 13:14:09 2019 +0430
+
+    [ci][test] Ignore other gcov symbols also
+    
+    To fix https://travis-ci.org/harfbuzz/harfbuzz/jobs/532693197
+
+ src/check-symbols.sh | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 397cbbd5ff25c9796ecd56b8270e83de1eb322ac
+Author: Ebrahim Byagowi <ebrahim@gnu.org>
+Date:   Wed May 15 13:03:28 2019 +0430
+
+    [ci][travis] Update its distribution
+    
+    It may break things, lets see
+
+ .travis.yml | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 763ea4224bf612f3efb80d5744d1e8852682683e
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Wed May 15 01:15:11 2019 -0700
+
+    Another try
+
+ src/hb-open-type.hh | 10 +++++-----
+ 1 file changed, 5 insertions(+), 5 deletions(-)
+
+commit e1b2edb04af7bd2b4eecb59392f75abcc72cd8a6
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Wed May 15 01:12:04 2019 -0700
+
+    Completely revert the thing back
+
+ src/hb-open-type.hh | 14 +++++---------
+ 1 file changed, 5 insertions(+), 9 deletions(-)
+
+commit c58eeb5fb35ec6a8d0a4394fd83cb2571cd5af4f
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Wed May 15 01:10:31 2019 -0700
+
+    Another try at fix
+    
+    Fails locally.  Trying to understand.  Sigh
+
+ src/hb-open-type.hh | 18 +++++++++---------
+ 1 file changed, 9 insertions(+), 9 deletions(-)
+
+commit 004edf3bdac77564d39516b51b0666de60e65ece
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Wed May 15 01:02:50 2019 -0700
+
+    Ugh.  How was the Travis bot happy before, but isn't now?! :(
+
+ src/hb-open-type.hh | 8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+commit e01c7b1648dbbb76966b3bd4437bcf7699e77c35
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Wed May 15 00:52:17 2019 -0700
+
+    Move OffsetTo operator+ back out of class
+    
+    Apparently there's different overload resolution rules that apply, at
+    least with some (older?) version of gcc.
+    
+    hb-ot-name-table.hh: In member function ‘void OT::name::accelerator_t::init(hb_face_t*)’:
+    hb-ot-name-table.hh:244:62: error: ambiguous overload for ‘operator+’ (operand types are ‘hb_blob_ptr_t<OT::name>’ and ‘OT::NNOffsetTo<OT::UnsizedArrayOf<OT::IntType<unsigned char, 1u> > > {aka const OT::OffsetTo<OT::UnsizedArrayOf<OT::IntType<unsigned char, 1u> >, OT::IntType<short unsigned int, 2u>, false>}’)
+           this->pool = (const char *) (const void *) (this->table+this->table->stringOffset);
+                                                                  ^
+    hb-ot-name-table.hh:244:62: note: candidates are:
+    hb-ot-name-table.hh:244:62: note: operator+(const C*, long int) <built-in>
+    hb-ot-name-table.hh:244:62: note: operator+(const char*, long int) <built-in>
+
+ src/hb-open-type.hh | 18 +++++++++---------
+ 1 file changed, 9 insertions(+), 9 deletions(-)
+
+commit b213042f87dd736bad7a852fe98269f84cbff493
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Wed May 15 00:50:48 2019 -0700
+
+    Revert "Revert symmetric OffsetTo overloads"
+    
+    This reverts commit 01912efb74fc554a81c8cfe572145ce45b8fa58b.
+    
+    Actually this didn't break things.  Fixing
+
+ src/hb-open-type.hh | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+commit 01912efb74fc554a81c8cfe572145ce45b8fa58b
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Wed May 15 00:42:47 2019 -0700
+
+    Revert symmetric OffsetTo overloads
+    
+    Reverts 57f65ae9355004044325dd6441cde761bca5e0a3
+    
+    Caused ambiguous-overload on some gcc...
+
+ src/hb-open-type.hh | 4 ----
+ 1 file changed, 4 deletions(-)
+
+commit d0df996cdc249a245c9dad1fa6503213c84dbcd2
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Wed May 15 00:32:41 2019 -0700
+
+    Use implicit lambda return type
+
+ src/hb-array.hh                |  4 ++--
+ src/hb-ot-layout-gsub-table.hh |  8 ++++----
+ src/hb-ot-layout-gsubgpos.hh   | 18 +++++++++---------
+ src/hb-ot-stat-table.hh        |  2 +-
+ src/hb-ot-var-fvar-table.hh    |  4 ++--
+ src/test-iter.cc               |  8 ++++----
+ src/test-meta.cc               |  1 -
+ 7 files changed, 22 insertions(+), 23 deletions(-)
+
+commit 57f65ae9355004044325dd6441cde761bca5e0a3
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Tue May 14 22:52:59 2019 -0700
+
+    Add symmetric friend operator+ for OffsetTo
+
+ src/hb-open-type.hh | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+commit 71208e5047c71108dec7361fd7c3e594c8b6c2d8
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Tue May 14 22:51:59 2019 -0700
+
+    Move OffsetTo<> deref operators in-class as friends
+
+ src/hb-open-type.hh | 10 +++++-----
+ 1 file changed, 5 insertions(+), 5 deletions(-)
+
+commit e6d6f4b96dd5517406265093cd57834c00850d41
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Tue May 14 22:45:03 2019 -0700
+
+    Whitespace
+
+ src/hb-ot-stat-table.hh     | 2 +-
+ src/hb-ot-var-fvar-table.hh | 4 ++--
+ 2 files changed, 3 insertions(+), 3 deletions(-)
+
+commit 889dc1eb06a80ea9be4223a19011e47a52abebdd
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Tue May 14 22:28:07 2019 -0700
+
+    [iter] Remove sort categorization
+    
+    See comments.
+
+ src/hb-array.hh            |  2 +-
+ src/hb-iter.hh             | 48 ++++++++++++++++++++++++++++++----------------
+ src/hb-ot-layout-common.hh |  2 +-
+ src/hb-set.hh              |  2 +-
+ 4 files changed, 35 insertions(+), 19 deletions(-)
+
+commit b4eff38397c2a4e475f426df38e040dddf94a4fa
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Tue May 14 09:07:20 2019 -0700
+
+    Start of gen-ucd.py, to replace UCDN
+
+ src/gen-ucd.py | 46 ++++++++++++++++++++++++++++++++++++++++++++++
+ 1 file changed, 46 insertions(+)
+
+commit 02e5e5d939be36d8f108029601a1ce1f533e5ccb
+Author: Qunxin Liu <qxliu@google.com>
+Date:   Mon May 13 09:38:42 2019 -0700
+
+    [subset] retian nameids from STAT and fvar tables
+
+ src/hb-ot-stat-table.hh     | 76 +++++++++++++++++++++++++++++++++++++++++----
+ src/hb-ot-var-fvar-table.hh | 21 +++++++++++++
+ src/hb-subset-plan.cc       | 26 ++++++++++++++++
+ 3 files changed, 117 insertions(+), 6 deletions(-)
+
+commit ff7995200e706f3161b9fc5c27bb950e3d87e8e2
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Tue May 14 07:44:03 2019 -0700
+
+    Hopefully last warning fix
+
+ src/hb-subset-cff2.cc | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+commit d1baf99697d215584b2ecb8d2d38ba5b9045955c
+Author: Ebrahim Byagowi <ebrahim@gnu.org>
+Date:   Tue May 14 16:16:46 2019 +0430
+
+    [ci] add HB_TINY to asmjs builder
+
+ .circleci/config.yml | 28 ++++++++++++++--------------
+ 1 file changed, 14 insertions(+), 14 deletions(-)
+
+commit 9e7c9c3adb33b06610951be38f3c820342333092
+Author: Ebrahim Byagowi <ebrahim@gnu.org>
+Date:   Tue May 14 15:58:51 2019 +0430
+
+    Fix -Wunused-function on HB_NO_SHAPE_AAT
+    
+    We should add a bot for it
+    Part of #1652
+
+ src/hb-ot-shape.cc | 2 ++
+ 1 file changed, 2 insertions(+)
+
+commit c73d7ba75d4556d9b8e05b10d6572f74f4814f7a
+Author: Dominik Röttsches <drott@chromium.org>
+Date:   Tue May 14 13:26:18 2019 +0300
+
+    Fix building with HB_NO_SUBSET_LAYOUT
+    
+    Fixes an unused function warning when building with HB_NO_SUBSET_LAYOUT
+    as part of the Chrome build.
+
+ src/hb-subset-plan.cc | 2 ++
+ 1 file changed, 2 insertions(+)
+
+commit f39934983f459c992e27075cd2c45ac0025183d0
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Tue May 14 00:13:21 2019 -0700
+
+    [ucdn] Fix Hangul composition
+    
+    https://github.com/grigorig/ucdn/issues/23
+
+ src/hb-ucdn/ucdn.c      | 3 ++-
+ test/api/test-unicode.c | 4 ++++
+ 2 files changed, 6 insertions(+), 1 deletion(-)
+
+commit b2ab15a78c219016e20389582716e0ac0ee8aeb5
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Mon May 13 23:47:28 2019 -0700
+
+    Fix more warnings
+
+ src/hb-ot-cff1-table.hh | 8 ++++----
+ src/hb-subset-cff1.cc   | 4 ++--
+ 2 files changed, 6 insertions(+), 6 deletions(-)
+
+commit 42ae468a8a76e1e4e6a8121eec5dc118f52086ee
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Mon May 13 23:43:45 2019 -0700
+
+    [config] Add NDEBUG and HB_NDEBUG
+    
+    Part of https://github.com/harfbuzz/harfbuzz/issues/1652
+
+ src/hb-config.hh | 10 ++++++++++
+ src/hb.hh        | 10 ----------
+ 2 files changed, 10 insertions(+), 10 deletions(-)
+
+commit 0a01deb76fa582afa83da70a09478299d8080827
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Mon May 13 18:04:09 2019 -0700
+
+    One more warning fix
+    
+    No idea where these appear from...
+
+ src/hb-ot-cff-common.hh | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+commit f76e9f2ede76a189d48ddd4f2275442d8e849815
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Mon May 13 17:39:46 2019 -0700
+
+    [icu] Comment
+
+ src/hb-icu.cc | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+commit 70fe9e73555f3354238f7cda5ff0f0c0b75e1d62
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Mon May 13 17:35:02 2019 -0700
+
+    Fix moreeeeeeeeeee
+
+ src/hb-icu.cc         | 28 +++++++++++++++-------------
+ src/hb-subset-plan.cc |  2 +-
+ 2 files changed, 16 insertions(+), 14 deletions(-)
+
+commit 68e12e68f813bfd22dda040463d042cc06b958ec
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Mon May 13 17:28:59 2019 -0700
+
+    Fix more semi-colon issues
+
+ src/hb-coretext.cc    | 4 ++--
+ src/hb-directwrite.cc | 4 ++--
+ src/hb-graphite2.cc   | 4 ++--
+ src/hb-uniscribe.cc   | 4 ++--
+ 4 files changed, 8 insertions(+), 8 deletions(-)
+
+commit 4d3cf2adb669c345cc43832d11689271995e160a
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Mon May 13 17:25:07 2019 -0700
+
+    [iter] Fix zip iterator sortedness classification logic
+
+ src/hb-iter.hh | 9 ++-------
+ 1 file changed, 2 insertions(+), 7 deletions(-)
+
+commit c572732f29787d1cf7ff39b8160b3935d4b13ba4
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Mon May 13 15:41:09 2019 -0700
+
+    Fix more excess semi-colon errors
+
+ src/hb-common.cc                 | 2 +-
+ src/hb-ot-name.cc                | 4 ++--
+ src/hb-ot-shape-complex-indic.hh | 2 +-
+ src/hb-ot-shape-complex-khmer.hh | 2 +-
+ 4 files changed, 5 insertions(+), 5 deletions(-)
+
+commit 513762849a683914fc266a17ddf38f133cccf072
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Mon May 13 15:36:14 2019 -0700
+
+    [iter] Track strictly-sorted iterators
+    
+    This make output of hb_enumerate() sorted regardless of input iterator.
+
+ src/hb-array.hh            |  2 +-
+ src/hb-iter.hh             | 30 +++++++++++++++++++++---------
+ src/hb-ot-layout-common.hh |  2 +-
+ src/hb-set.hh              |  2 +-
+ 4 files changed, 24 insertions(+), 12 deletions(-)
+
+commit 7e02063f3202712b4e5fbddac0354adadb924f72
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Mon May 13 15:26:00 2019 -0700
+
+    [iter] Minor
+
+ src/hb-iter.hh | 21 +++++++++++----------
+ 1 file changed, 11 insertions(+), 10 deletions(-)
+
+commit a5fb44a8cbbaad194ddf6d02a6b6c98b0b637149
+Author: Garret Rieger <grieger@google.com>
+Date:   Mon May 13 14:57:40 2019 -0700
+
+    [subset] Fix shadowed 'groups' param in cmap.
+
+ src/hb-ot-cmap-table.hh | 18 +++++++++---------
+ 1 file changed, 9 insertions(+), 9 deletions(-)
+
+commit 73943bdf21a96f4e12cb9efd8458a2711de0d870
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Mon May 13 14:48:31 2019 -0700
+
+    Adjust uniscribe_bug_compatible mode
+    
+    More correct behavior.  We were commenting out some legit conditions
+    before.
+    
+    Part of https://github.com/harfbuzz/harfbuzz/issues/1652
+
+ src/hb-ot-shape-complex-indic.cc | 10 ++--------
+ 1 file changed, 2 insertions(+), 8 deletions(-)
+
+commit 809c58708359bcc22bb1273069886f2cbf68be65
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Mon May 13 14:45:51 2019 -0700
+
+    [config] Better compile away morx/kerx/trak
+    
+    Part of https://github.com/harfbuzz/harfbuzz/issues/1652
+
+ src/hb-ot-shape.cc | 38 ++++++++++++++------------------------
+ src/hb-ot-shape.hh | 12 +++++++++++-
+ 2 files changed, 25 insertions(+), 25 deletions(-)
+
+commit b1d3e54bd3c881794b05831e811b1a77a7d427c5
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Mon May 13 14:35:04 2019 -0700
+
+    [indic] Don't constrain how many C, M, ... occur
+    
+    Fixes https://github.com/harfbuzz/harfbuzz/issues/1709
+    
+    Part of https://github.com/harfbuzz/harfbuzz/issues/1652
+
+ src/hb-ot-shape-complex-indic-machine.hh | 1225 ++++++++----------------------
+ src/hb-ot-shape-complex-indic-machine.rl |    8 +-
+ 2 files changed, 305 insertions(+), 928 deletions(-)
+
+commit 148d88368013ba9bf70a7dd275b1a0f9c64fd45c
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Mon May 13 14:33:06 2019 -0700
+
+    [test] Don't call deprecated API
+
+ test/api/test-font.c  |  3 ---
+ test/api/test-shape.c | 16 ++--------------
+ 2 files changed, 2 insertions(+), 17 deletions(-)
+
+commit a487fc33248ea2f934ff4cb857cb556065c11841
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Mon May 13 14:16:33 2019 -0700
+
+    Another extra semi-colon
+
+ src/hb-ot-layout-common.hh | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 8461ade7832110d28001dc641342d3f9461e03b0
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Mon May 13 14:10:48 2019 -0700
+
+    Revert "[ragel] Regenerate ragel-generated files using ragel 7.0.0.11 May 2018"
+    
+    This reverts commit 9b05db33b54e6e5f0b4658f4c06e7fe563f8923b.
+    
+    Fixes https://github.com/harfbuzz/harfbuzz/issues/1708
+
+ src/hb-buffer-deserialize-json.hh          | 1051 ++++++-----
+ src/hb-buffer-deserialize-text.hh          | 1009 ++++++-----
+ src/hb-ot-shape-complex-indic-machine.hh   | 2678 ++++++++++++----------------
+ src/hb-ot-shape-complex-khmer-machine.hh   |  709 ++++----
+ src/hb-ot-shape-complex-myanmar-machine.hh |  820 ++++-----
+ src/hb-ot-shape-complex-use-machine.hh     | 1144 ++++++------
+ 6 files changed, 3452 insertions(+), 3959 deletions(-)
+
+commit 52c15b053aec06d351404a4c15609384946b26e1
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Mon May 13 14:10:28 2019 -0700
+
+    Revert "[ragel] Switch to -T1 output instead of -F1"
+    
+    This reverts commit ae8719eb596485ebff07dd5016256015cd0cf86b.
+    
+    Part of https://github.com/harfbuzz/harfbuzz/issues/1708
+
+ src/Makefile.am                            |    2 +-
+ src/hb-buffer-deserialize-json.hh          |  381 ++-
+ src/hb-buffer-deserialize-text.hh          |  308 +--
+ src/hb-ot-shape-complex-indic-machine.hh   | 3527 +++++++---------------------
+ src/hb-ot-shape-complex-khmer-machine.hh   |  396 +---
+ src/hb-ot-shape-complex-myanmar-machine.hh |  742 ++----
+ src/hb-ot-shape-complex-use-machine.hh     | 1011 ++------
+ 7 files changed, 1658 insertions(+), 4709 deletions(-)
+
+commit e98f0ddd6373f64ef4b542daa36b5841399170af
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Mon May 13 13:53:06 2019 -0700
+
+    Fix extra semi-colon
+
+ src/hb-iter.hh | 2 +-
+ src/hb.hh      | 1 +
+ 2 files changed, 2 insertions(+), 1 deletion(-)
+
+commit ae8719eb596485ebff07dd5016256015cd0cf86b
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Mon May 13 12:27:10 2019 -0700
+
+    [ragel] Switch to -T1 output instead of -F1
+    
+    Fedora upgraded to ragel 7, which is buggy if char is signed.
+    Switching to -G2 output fails with sign-compare error:
+    
+    ../../src/hb-buffer-deserialize-json.hh:107:12: error: comparison of integer expressions of different signedness: ‘unsigned int’ and ‘const char’ [-Werror=sign-compare]
+        if ( 9u <= ( (*( p))) && ( (*( p))) <= 13u ) {
+             ~~~^~~~~~~~~~~~~
+    
+    Switching to -T1 for now.  It actually results in smaller code,
+    at the expense of some binary searching instead of flat tables.
+    In the not distant future, we might actually generate two different
+    outputs and choose between depending on size-optimize options.
+    
+    Fixes https://github.com/harfbuzz/harfbuzz/issues/1708
+
+ src/Makefile.am                            |    2 +-
+ src/hb-buffer-deserialize-json.hh          |  381 ++--
+ src/hb-buffer-deserialize-text.hh          |  308 ++-
+ src/hb-ot-shape-complex-indic-machine.hh   | 3401 +++++++++++++++++++++-------
+ src/hb-ot-shape-complex-khmer-machine.hh   |  396 +++-
+ src/hb-ot-shape-complex-myanmar-machine.hh |  742 ++++--
+ src/hb-ot-shape-complex-use-machine.hh     | 1011 ++++++---
+ 7 files changed, 4646 insertions(+), 1595 deletions(-)
+
+commit df3f36f0bb7aeed0554843f24f6542852e40f6cc
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Sun May 12 20:56:36 2019 -0700
+
+    Minor
+
+ src/gen-os2-unicode-ranges.py | 2 ++
+ 1 file changed, 2 insertions(+)
+
+commit ccc88e98f34453100830d6408fdabfe90e6b47b8
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Sun May 12 16:12:06 2019 -0700
+
+    Fix MSVC build
+
+ src/hb-ot-shape-complex-indic.cc | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit f8f9cb93b7166b0d8c816610596da486443c7391
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Sun May 12 15:56:25 2019 -0700
+
+    [config] Define HB_NO_SUBSET_LAYOUT in HB_LEAN
+    
+    Assumning subsetter would be used for printing-like uses in that case,
+    which don't need GSUB/GPOS.
+
+ src/hb-config.hh | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+commit a1394a28fc4b3d15ef45481f3147f0685d343acb
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Sun May 12 15:47:46 2019 -0700
+
+    [config] Add HB_NO_UNISCRIBE_BUG_COMPATIBLE
+    
+    Part of https://github.com/harfbuzz/harfbuzz/issues/1652
+
+ src/hb-config.hh                 |  4 ++++
+ src/hb-ot-shape-complex-indic.cc | 24 ++++++++++++++++++------
+ 2 files changed, 22 insertions(+), 6 deletions(-)
+
+commit dba1ac1b0e8f5f96974fc1119b318ae6127daa82
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Sun May 12 15:33:31 2019 -0700
+
+    [config] Disable buffer serialize routines in HB_TINY
+    
+    Part of https://github.com/harfbuzz/harfbuzz/issues/1652
+
+ src/hb-buffer-serialize.cc | 14 +++++++++++++-
+ src/hb-config.hh           |  1 +
+ 2 files changed, 14 insertions(+), 1 deletion(-)
+
+commit 3d9be2ad5036aaf02b69095faaf9c18705c2c5bc
+Merge: a20db496 1a850abd
+Author: n8willis <n8willis@users.noreply.github.com>
+Date:   Sun May 12 20:03:29 2019 +0100
+
+    Merge pull request #1665 from n8willis/docs-gtkdoc-colormath
+    
+    [Docs] Add gtk-doc comments for OT color and OT math
+
+commit a20db496f090abc5b937857b7c5f077161b6ffe4
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Sun May 12 11:08:45 2019 -0700
+
+    Fix builds
+
+ src/hb-subset-plan.cc | 2 ++
+ 1 file changed, 2 insertions(+)
+
+commit 8694d6082901661e90e2ffcf732e9985a215063f
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Sun May 12 11:05:24 2019 -0700
+
+    [config] Enable HB_NO_MT in HB_TINY
+    
+    Now that user can override it if needed...
+    
+    Part of https://github.com/harfbuzz/harfbuzz/issues/1652
+
+ src/hb-config.hh | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 7f6fca4ef78cf3c9384bf835def14219b2ce8791
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Sun May 12 10:29:47 2019 -0700
+
+    Force-disable CFF code under disabling conditions
+    
+    Subsetter size goes down from 190kb to 119kb.  Main library about 7kb.
+    
+    Part of https://github.com/harfbuzz/harfbuzz/issues/1652
+
+ src/hb-ot-cff1-table.cc | 4 ++++
+ src/hb-ot-cff2-table.cc | 4 ++++
+ src/hb-subset-cff1.cc   | 4 ++++
+ src/hb-subset-cff2.cc   | 4 ++++
+ 4 files changed, 16 insertions(+)
+
+commit 5249eee43748db32b40ad2602b3243d2491642b3
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Sat May 11 16:12:07 2019 -0700
+
+    [config] Allow overriding chosen config
+
+ src/hb-config.hh | 6 ++++++
+ 1 file changed, 6 insertions(+)
+
+commit 30c059a978c91fcd38d47f1ac4a03295f887a7da
+Author: Ebrahim Byagowi <ebrahim@gnu.org>
+Date:   Sat May 11 18:48:41 2019 -0400
+
+    [test] minor, fix -Weverything bot
+
+ test/fuzzing/main.cc | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+commit a29b1de55abca2e90733caff7423e5251d72e03c
+Author: Nathan Willis <nwillis@glyphography.com>
+Date:   Sat May 11 20:56:55 2019 +0100
+
+    Usermanual, fix up userfeatures example code in OpenType features section of shaping chapter.
+
+ docs/usermanual-opentype-features.xml | 15 +++++++++++----
+ 1 file changed, 11 insertions(+), 4 deletions(-)
+
+commit 78fcb14db9041af0e0d5ea209cf0cb1977f6dcc3
+Author: Nathan Willis <nwillis@glyphography.com>
+Date:   Sat May 11 20:56:02 2019 +0100
+
+    Usermanual, minor: flesh out invisible-glyph discussion in buffers chapter.
+
+ ...ermanual-buffers-language-script-and-direction.xml | 19 +++++++++++++++----
+ 1 file changed, 15 insertions(+), 4 deletions(-)
+
+commit 25531a30394c451a7a2aee77928e0a550015b803
+Author: Ebrahim Byagowi <ebrahim@gnu.org>
+Date:   Sat May 11 19:50:42 2019 +0000
+
+    [test] minor
+    
+    style fix and add return statement
+
+ test/fuzzing/main.cc | 10 +++++++---
+ 1 file changed, 7 insertions(+), 3 deletions(-)
+
+commit 1a850abd66999707b6f4795050e748fc879b92ef
+Merge: 8a544171 a6048e4c
+Author: n8willis <n8willis@users.noreply.github.com>
+Date:   Sat May 11 20:16:57 2019 +0100
+
+    Merge branch 'master' into docs-gtkdoc-colormath
+
+commit 8a544171d15bb36c15ca7bf679643b2b14f94b45
+Author: Nathan Willis <nwillis@glyphography.com>
+Date:   Sat May 11 20:11:49 2019 +0100
+
+    Corrections to OT Color gtk-doc comments.
+
+ src/hb-ot-color.cc | 14 +++++++-------
+ 1 file changed, 7 insertions(+), 7 deletions(-)
+
+commit 301f5091f6663cc8a1fff848bf5285aa15cc0598
+Author: Nathan Willis <nwillis@glyphography.com>
+Date:   Sat May 11 20:11:36 2019 +0100
+
+    Corrections to OT Math gtk-doc comments.
+
+ src/hb-ot-math.cc | 33 +++++++++++++++++++++++----------
+ 1 file changed, 23 insertions(+), 10 deletions(-)
+
+commit a6048e4cd013987ecb846e0683a7cf6f0caa65f9
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Sat May 11 12:11:22 2019 -0700
+
+    Fix build
+
+ src/hb-ot-font.cc | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 32d3c06b61f2f4252f4403b55c6ba07fbb572149
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Sat May 11 11:59:18 2019 -0700
+
+    Disable sbix if no-color or no-ot-font-bitmap
+    
+    Part of https://github.com/harfbuzz/harfbuzz/issues/1652
+
+ src/hb-ot-font.cc | 21 +++++++++++----------
+ 1 file changed, 11 insertions(+), 10 deletions(-)
+
+commit 606841b07017ac80dea2fc5ada25b5976f2f9192
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Sat May 11 11:54:30 2019 -0700
+
+    [iter] Check for more before forwarding/rewinding past ends
+
+ src/hb-iter.hh   | 4 ++--
+ src/test-iter.cc | 6 ++----
+ 2 files changed, 4 insertions(+), 6 deletions(-)
+
+commit c1c122e7b3f60dc7b5a224c68d2acb106fda8b49
+Author: David Corbett <corbett.dav@husky.neu.edu>
+Date:   Sat May 11 11:38:06 2019 -0400
+
+    [iter] Fix filter rewinding
+
+ src/hb-iter.hh | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit b854d4ff46602104343201361919f30169144cf1
+Author: David Corbett <corbett.dav@husky.neu.edu>
+Date:   Fri May 10 22:51:49 2019 -0400
+
+    [array] Fix rewinding
+
+ src/hb-array.hh | 22 +++++++++++++---------
+ 1 file changed, 13 insertions(+), 9 deletions(-)
+
+commit 76e80c5ca5e820e955438e4c727929ddd99e695e
+Author: n8willis <n8willis@users.noreply.github.com>
+Date:   Sat May 11 19:51:24 2019 +0100
+
+    Update src/hb-ot-color.cc
+    
+    Co-Authored-By: Khaled Hosny <khaledhosny@eglug.org>
+
+ src/hb-ot-color.cc | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 79126df3070f00193fe3caefe9deb62c4520e048
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Sat May 11 11:23:31 2019 -0700
+
+    [iter] Add hb_map_sorted() and hb_map_retains_sorting()
+
+ src/hb-iter.hh | 38 +++++++++++++++++++++++++++++++-------
+ 1 file changed, 31 insertions(+), 7 deletions(-)
+
+commit bcd81932f0bcb2258276ae313709780e90e9b0f6
+Author: n8willis <n8willis@users.noreply.github.com>
+Date:   Sat May 11 14:10:32 2019 +0100
+
+    Update src/hb-ot-math.cc
+    
+    Co-Authored-By: Khaled Hosny <khaledhosny@eglug.org>
+
+ src/hb-ot-math.cc | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit ddc6dd42f753a20204898e41cc711b0100638330
+Author: n8willis <n8willis@users.noreply.github.com>
+Date:   Sat May 11 14:10:11 2019 +0100
+
+    Update src/hb-ot-math.cc
+    
+    Co-Authored-By: Khaled Hosny <khaledhosny@eglug.org>
+
+ src/hb-ot-math.cc | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 46e05ecca16e561a0ff4ca60bb064f480374590a
+Author: n8willis <n8willis@users.noreply.github.com>
+Date:   Sat May 11 14:09:52 2019 +0100
+
+    Update src/hb-ot-color.cc
+    
+    Co-Authored-By: Khaled Hosny <khaledhosny@eglug.org>
+
+ src/hb-ot-color.cc | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 6d9870b4799f20a6c58a2c071713e56aa93b0221
+Author: n8willis <n8willis@users.noreply.github.com>
+Date:   Sat May 11 14:09:26 2019 +0100
+
+    Update src/hb-ot-color.cc
+    
+    Co-Authored-By: Khaled Hosny <khaledhosny@eglug.org>
+
+ src/hb-ot-color.cc | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 12ea4a24c40c7ac28d058e9721479347951e3482
+Author: n8willis <n8willis@users.noreply.github.com>
+Date:   Sat May 11 14:08:40 2019 +0100
+
+    Update src/hb-ot-color.cc
+    
+    Co-Authored-By: Khaled Hosny <khaledhosny@eglug.org>
+
+ src/hb-ot-color.cc | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 3535f2d31efe1ebe44ba63f980882ba23cdcde3b
+Author: n8willis <n8willis@users.noreply.github.com>
+Date:   Sat May 11 14:07:38 2019 +0100
+
+    Update src/hb-ot-color.cc
+    
+    Co-Authored-By: Khaled Hosny <khaledhosny@eglug.org>
+
+ src/hb-ot-color.cc | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 12d2c472fe8ec3268a4b39a57603dcc734ab7b88
+Author: n8willis <n8willis@users.noreply.github.com>
+Date:   Sat May 11 14:06:56 2019 +0100
+
+    Update src/hb-ot-color.cc
+    
+    Co-Authored-By: Khaled Hosny <khaledhosny@eglug.org>
+
+ src/hb-ot-color.cc | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 7f45ce42dbf11366e904f48db45cf5405e4e94df
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Sat May 11 01:28:31 2019 -0700
+
+    [config] Rename
+
+ src/hb-config.hh    | 2 +-
+ src/hb-ot-layout.cc | 4 ++--
+ 2 files changed, 3 insertions(+), 3 deletions(-)
+
+commit 0e78d4ddaec5f29d6652cc4185cbcca98c3a2927
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Sat May 11 01:27:50 2019 -0700
+
+    [config] Add HB_NO_NAME
+    
+    Part of https://github.com/harfbuzz/harfbuzz/issues/1652
+
+ src/hb-config.hh  |  6 +++++-
+ src/hb-ot-name.cc | 20 ++++++++++++++++++++
+ 2 files changed, 25 insertions(+), 1 deletion(-)
+
+commit 1fc077211771c752768f63f178116d2b8f2f7d03
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Sat May 11 01:24:23 2019 -0700
+
+    [config] HB_NO_OT_NAME_LANGUAGE AAT
+
+ src/hb-config.hh                  | 4 ++--
+ src/hb-ot-name-language-static.hh | 3 +++
+ src/hb-ot-name-table.hh           | 4 +++-
+ 3 files changed, 8 insertions(+), 3 deletions(-)
+
+commit 4381bb2de7a554a148302836b86a5d73264abeae
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Sat May 11 01:14:04 2019 -0700
+
+    [config] Comment
+
+ src/hb-config.hh | 1 +
+ 1 file changed, 1 insertion(+)
+
+commit 9c921e6c32ab5ac4c524f554b7a7841eeeb0908f
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Sat May 11 01:08:51 2019 -0700
+
+    [config] Enable HB_NO_NAME_TABLE_AAT
+    
+    Part of https://github.com/harfbuzz/harfbuzz/issues/1652
+
+ src/hb-config.hh | 2 ++
+ 1 file changed, 2 insertions(+)
+
+commit 81b79dfc397599182f43d63bf9346eee28e2d220
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Sat May 11 00:53:52 2019 -0700
+
+    [config] Add HB_NO_COLOR to HB_LEAN
+    
+    Part of https://github.com/harfbuzz/harfbuzz/issues/1652
+
+ src/hb-config.hh   |  1 +
+ src/hb-ot-color.cc | 49 +++++++++++++++++++++++++++++++++++++++++++++----
+ src/hb-ot-color.h  |  2 +-
+ src/hb-ot-layout.h |  2 +-
+ 4 files changed, 48 insertions(+), 6 deletions(-)
+
+commit b63a8e173cbc5a81f2ca4a0a82f20b9dafaedb30
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Sat May 11 00:47:20 2019 -0700
+
+    [config Add HB_NO_OT_SHAPE_COMPLEX_VOWEL_CONSTRAINTS to LEAN
+    
+    Already I don't like the inflexibility of this approach :(.
+    
+    Part of https://github.com/harfbuzz/harfbuzz/issues/1652
+
+ src/hb-config.hh | 1 +
+ 1 file changed, 1 insertion(+)
+
+commit 42a21284778f3203d96133f74b0f846cd1567958
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Sat May 11 00:44:22 2019 -0700
+
+    [config] Disbale getenv() and atexit() if HB_LEAN
+    
+    Part of https://github.com/harfbuzz/harfbuzz/issues/1652
+
+ src/hb-config.hh | 2 ++
+ 1 file changed, 2 insertions(+)
+
+commit fca27860417812d51e40f040de97c10177b1250e
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Sat May 11 00:37:01 2019 -0700
+
+    [config] Make HB_DISABLE_DEPRECATED actually compile
+    
+    Part of https://github.com/harfbuzz/harfbuzz/issues/1652
+
+ src/hb-config.hh            |  7 +++++++
+ src/hb-font.cc              |  8 ++++++++
+ src/hb-font.hh              | 12 ++++++++++--
+ src/hb-graphite2.cc         |  2 ++
+ src/hb-icu.cc               |  2 +-
+ src/hb-ot-layout.cc         |  7 ++++++-
+ src/hb-ot-shape-fallback.cc |  4 ++++
+ src/hb-ot-tag.cc            |  4 ++++
+ src/hb-ot-var-fvar-table.hh |  6 ++++++
+ src/hb-ot-var.cc            |  2 ++
+ src/hb-set.cc               |  2 ++
+ src/hb-unicode.cc           |  6 ++++++
+ src/hb-unicode.hh           | 10 +++++++---
+ 13 files changed, 65 insertions(+), 7 deletions(-)
+
+commit 5a48611ccd045de5782ad2fd5f6718357fe232a2
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Sat May 11 00:19:03 2019 -0700
+
+    [config] Add HB_NO_OT_LAYOUT_UNUSED
+    
+    Part of https://github.com/harfbuzz/harfbuzz/issues/1652
+
+ src/hb-config.hh    |  1 +
+ src/hb-ot-layout.cc | 12 ++++++++++++
+ 2 files changed, 13 insertions(+)
+
+commit 771f1b21d1d7128440d6b4488705456d43dbc0e7
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Sat May 11 00:16:18 2019 -0700
+
+    [config] Adjust
+
+ src/hb-config.hh | 12 +++++++-----
+ 1 file changed, 7 insertions(+), 5 deletions(-)
+
+commit 484f6e8215038006a945da67d245f14db3eeeb2e
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Sat May 11 00:13:35 2019 -0700
+
+    [config] Add HB_LEAN
+    
+    Part of https://github.com/harfbuzz/harfbuzz/issues/1652
+
+ src/hb-config.hh  |  5 +++++
+ src/hb-ot-math.cc | 40 ++++++++++++++++++++++++++++++++++++++++
+ 2 files changed, 45 insertions(+)
+
+commit 0bfd14c0ed2f95f00d0b94d396c777399afa4d68
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Sat May 11 00:06:57 2019 -0700
+
+    [config] Fix tests
+
+ src/hb-config.hh | 3 +++
+ 1 file changed, 3 insertions(+)
+
+commit 784df8eba1aaf20d2db464f8b3ea0984f7ea1308
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Sat May 11 00:04:59 2019 -0700
+
+    [config] Flesh out more
+    
+    Part of https://github.com/harfbuzz/harfbuzz/issues/1652
+
+ src/hb-config.hh | 17 +++++++++++++++++
+ 1 file changed, 17 insertions(+)
+
+commit 799c6a5081e5058260199eeeb2091ee2c1dfefff
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Fri May 10 23:55:22 2019 -0700
+
+    [config] Add some
+
+ src/hb-aat-layout.cc    | 26 +++++++++++++-------------
+ src/hb-aat-map.cc       |  4 ++--
+ src/hb-config.hh        | 18 ++++++++++++++++++
+ src/hb-ot-kern-table.hh | 14 +++++++-------
+ src/hb-ot-shape.cc      | 22 +++++++++++-----------
+ 5 files changed, 51 insertions(+), 33 deletions(-)
+
+commit e6582de12f1af9ab5e3122d762a3e12438a66b6b
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Fri May 10 23:53:38 2019 -0700
+
+    Add hb-config.hh
+
+ src/Makefile.sources |  1 +
+ src/hb-config.hh     | 36 ++++++++++++++++++++++++++++++++++++
+ src/hb.hh            |  7 ++++---
+ 3 files changed, 41 insertions(+), 3 deletions(-)
+
+commit d43af339e7a7f5dab1690703a78d2690baefbd59
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Fri May 10 23:46:22 2019 -0700
+
+    [subset] More HB_NO_SUBSET_LAYOUT
+    
+    Part of https://github.com/harfbuzz/harfbuzz/issues/1652
+
+ src/hb-subset-plan.cc | 13 ++++++++-----
+ 1 file changed, 8 insertions(+), 5 deletions(-)
+
+commit 31c591d69f6a7605088883db59149e83c80d019c
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Fri May 10 23:39:53 2019 -0700
+
+    [cff] Prune more code if HB_NO_OT_FONT_CFF
+    
+    Part of https://github.com/harfbuzz/harfbuzz/issues/1652
+
+ src/hb-ot-cff1-table.cc | 5 +++++
+ src/hb-ot-cff2-table.cc | 5 +++++
+ 2 files changed, 10 insertions(+)
+
+commit 5ea8ad5c48f9baabc4ccf81dce4aee1067c401f6
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Fri May 10 23:36:42 2019 -0700
+
+    [subset] Add HB_NO_SUBSET_CFF
+    
+    Doesn't fully prune all the relevant code.  To be fixed later.
+    
+    Part of https://github.com/harfbuzz/harfbuzz/issues/1652
+
+ src/hb-subset.cc | 3 +++
+ 1 file changed, 3 insertions(+)
+
+commit 2c93f0dee31b2277567ccbee041539732b9bd26d
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Fri May 10 23:31:05 2019 -0700
+
+    Add HB_NO_AAT
+    
+    Part of https://github.com/harfbuzz/harfbuzz/issues/1652
+
+ src/hb-aat-layout.cc    | 58 +++++++++++++++++++++++++++++++++++++++++++++++++
+ src/hb-aat-map.cc       |  8 +++++++
+ src/hb-ot-kern-table.hh | 14 ++++++++++++
+ src/hb-ot-shape.cc      | 28 +++++++++++++++++++++++-
+ 4 files changed, 107 insertions(+), 1 deletion(-)
+
+commit 62dfe7aea23c95f4550543085071990e20ee4d54
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Fri May 10 23:17:15 2019 -0700
+
+    [cff] Minor
+
+ src/hb-subset-cff1.cc | 2 +-
+ src/hb-subset-cff2.cc | 2 +-
+ 2 files changed, 2 insertions(+), 2 deletions(-)
+
+commit 227d85e138d4c785c2d658e225ed35f5acd1235f
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Fri May 10 23:15:58 2019 -0700
+
+    Minor
+
+ src/hb-atomic.hh                             |  2 +-
+ src/hb-debug.hh                              |  2 +-
+ src/hb-font.cc                               |  2 +-
+ src/hb-ot-font.cc                            |  4 ++--
+ src/hb-ot-layout.cc                          |  6 +++---
+ src/hb-ot-name-table.hh                      |  2 +-
+ src/hb-ot-shape-complex-arabic.cc            |  2 +-
+ src/hb-ot-shape-complex-hebrew.cc            |  2 +-
+ src/hb-ot-shape-complex-thai.cc              |  2 +-
+ src/hb-ot-shape-complex-vowel-constraints.cc |  2 +-
+ src/hb-ot-shape-fallback.cc                  |  6 +++---
+ src/hb-subset.cc                             |  4 ++--
+ src/hb-warning.cc                            |  4 ++--
+ src/hb.hh                                    | 10 +++++-----
+ 14 files changed, 25 insertions(+), 25 deletions(-)
+
+commit 9bfe22af6113ee8cd24cb9ee091f0841c27bbf98
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Fri May 10 22:44:19 2019 -0700
+
+    [sanitize] Fix previous commit
+
+ src/hb-open-type.hh | 8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+commit 4dcf65328f04a11594fc190fd7e976afa54455e9
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Fri May 10 22:23:24 2019 -0700
+
+    [sanitize] Simplify
+
+ src/hb-open-type.hh | 45 ++++++++++-----------------------------------
+ 1 file changed, 10 insertions(+), 35 deletions(-)
+
+commit 23168c3981f7c80883663fa69c608caee98d3d99
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Fri May 10 22:11:51 2019 -0700
+
+    [sanitize] Use hb_is_trivially_copyable()
+
+ src/hb-open-type.hh | 64 +++++++----------------------------------------------
+ 1 file changed, 8 insertions(+), 56 deletions(-)
+
+commit 0ff7954f9f09f80654ac91c16712154744a0dd2d
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Fri May 10 22:04:40 2019 -0700
+
+    [meta] Add hb_is_trivial
+
+ src/hb-meta.hh   | 7 +++++++
+ src/test-meta.cc | 4 ++++
+ 2 files changed, 11 insertions(+)
+
+commit 7162a97bca6e0dde3d277701a3bf15688deef61d
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Fri May 10 22:03:03 2019 -0700
+
+    [meta] Add hb_is_trivially_copyable()
+
+ src/hb-meta.hh   | 11 +++++++++++
+ src/test-meta.cc |  4 ++++
+ 2 files changed, 15 insertions(+)
+
+commit f2398f34c019a55d4f0e1a7031961714afadf2b3
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Fri May 10 21:59:57 2019 -0700
+
+    [meta] Add is_trivially_destructible
+
+ src/hb-meta.hh   | 6 +++---
+ src/test-meta.cc | 7 +++++--
+ 2 files changed, 8 insertions(+), 5 deletions(-)
+
+commit 72cb5b8e52b7103c18adcb82cbcd4b91a2c85474
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Fri May 10 21:50:15 2019 -0700
+
+    Remove accidentally included include
+
+ src/test-meta.cc | 3 ---
+ 1 file changed, 3 deletions(-)
+
+commit 086772e409759e8f1edd0e34f6f25374e51e9e10
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Fri May 10 21:49:25 2019 -0700
+
+    [meta] Add is_destructible
+
+ src/hb-meta.hh | 14 ++++++++++++++
+ 1 file changed, 14 insertions(+)
+
+commit b14745278ad16fe7f4e838b685029e3fdda516ca
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Fri May 10 21:42:59 2019 -0700
+
+    [met]a Add is_constructible, ...
+
+ src/hb-meta.hh   | 73 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+ src/test-meta.cc | 23 ++++++++++++++++++
+ 2 files changed, 96 insertions(+)
+
+commit 19e08a146712dacd11359370c91a7bad55bc6f62
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Fri May 10 21:25:07 2019 -0700
+
+    [iter] Adjust source_of/sink_of
+
+ src/hb-iter.hh | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+commit c0485e32a320e17dd0634b2cc8b4dd8c4fdc65e0
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Fri May 10 21:03:14 2019 -0700
+
+    Use hb_void_t<> the way it's supposed to be used
+
+ src/hb-null.hh | 12 ++++++------
+ 1 file changed, 6 insertions(+), 6 deletions(-)
+
+commit 40fb36a39de5dd3ee9a4c84f1f76205b6bb68660
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Fri May 10 21:01:19 2019 -0700
+
+    [meta] Minor
+
+ src/hb-meta.hh | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+commit f9a96a0a97f59a0b31ee0f901d1c21dde6b3cfaf
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Fri May 10 20:56:16 2019 -0700
+
+    [meta] More rewrites
+
+ src/hb-meta.hh | 18 +++++++++---------
+ 1 file changed, 9 insertions(+), 9 deletions(-)
+
+commit 5252677e53ff4473701172bbbd4e953ac6b08e6f
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Fri May 10 20:49:52 2019 -0700
+
+    [meta] Rewrite hb_int_min/max
+
+ src/hb-meta.hh | 44 ++++++++++++++++++++++----------------------
+ 1 file changed, 22 insertions(+), 22 deletions(-)
+
+commit caa3f92e91062ff78b657aec23569b099de48640
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Fri May 10 20:43:51 2019 -0700
+
+    [meta] void_tt -> void_t
+
+ src/hb-meta.hh | 9 ++++-----
+ 1 file changed, 4 insertions(+), 5 deletions(-)
+
+commit 7df3ecfb4069d275cd277c71165962bb5769364a
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Fri May 10 20:43:26 2019 -0700
+
+    [meta] hb_void_t -> hb_empty_t
+
+ src/hb-debug.hh                |  6 +++---
+ src/hb-meta.hh                 |  2 +-
+ src/hb-ot-layout-gsub-table.hh |  2 +-
+ src/hb-ot-layout-gsubgpos.hh   | 18 +++++++++---------
+ 4 files changed, 14 insertions(+), 14 deletions(-)
+
+commit 149c3db8a2d41894b5d65f4c4b7c20757f6de6dd
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Fri May 10 20:34:52 2019 -0700
+
+    [meta] Minor
+
+ src/hb-meta.hh | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 707ff5b59d3903b60312a028f2ba5d74c18db101
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Fri May 10 20:31:20 2019 -0700
+
+    Minor
+
+ src/hb-meta.hh      | 5 -----
+ src/hb-open-type.hh | 2 +-
+ 2 files changed, 1 insertion(+), 6 deletions(-)
+
+commit ce300f4fb68a25d46d165e8b0a4825482c83a966
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Fri May 10 20:26:29 2019 -0700
+
+    [meta] Rewrite is_signed, add is_unsigned
+
+ src/hb-meta.hh | 29 ++++++++++++-----------------
+ 1 file changed, 12 insertions(+), 17 deletions(-)
+
+commit e939d88bd72e0db0ebe357649b7a0fa3447c0bf4
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Fri May 10 20:20:51 2019 -0700
+
+    [meta] Rewrite is_integral / is_floating_point, add is_arithmetic
+
+ src/hb-meta.hh | 49 +++++++++++++++++++++++++++++++------------------
+ 1 file changed, 31 insertions(+), 18 deletions(-)
+
+commit c3a456a26e8e5f8bc483b326f1928e9c603a7216
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Fri May 10 20:17:30 2019 -0700
+
+    [meta] Rewrite is_cr_convertible
+
+ src/hb-meta.hh | 13 +++++--------
+ 1 file changed, 5 insertions(+), 8 deletions(-)
+
+commit b4ad6af9c4ec30c462078bd93ae12653619c5fea
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Fri May 10 20:15:03 2019 -0700
+
+    [meta] Rewrite is_base_of
+
+ src/hb-meta.hh | 5 +----
+ 1 file changed, 1 insertion(+), 4 deletions(-)
+
+commit 5a171ed3a69313e10df6e42a03affb5e8bfe8e95
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Fri May 10 20:11:29 2019 -0700
+
+    [null] Modernize template work
+
+ src/hb-null.hh | 19 ++++++-------------
+ 1 file changed, 6 insertions(+), 13 deletions(-)
+
+commit 61d150c916d181cc3f333d0378108e08210370ad
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Fri May 10 20:06:31 2019 -0700
+
+    [meta] Add integral_constant, true_t -> true_type, false_t -> false_type
+
+ src/hb-iter.hh | 20 ++++++++++----------
+ src/hb-meta.hh | 17 ++++++++---------
+ src/hb-null.hh |  4 ++--
+ 3 files changed, 20 insertions(+), 21 deletions(-)
+
+commit 38e3a8bd531ef3d35ca0fbcfad09db3f83345038
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Fri May 10 20:03:14 2019 -0700
+
+    [meta] bool_tt -> bool_constant
+
+ src/hb-meta.hh | 6 +++---
+ src/hb-null.hh | 4 ++--
+ 2 files changed, 5 insertions(+), 5 deletions(-)
+
+commit 3919ca41b5e657764c7f75dfdc21cf8ca20bd66f
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Fri May 10 19:56:36 2019 -0700
+
+    [meta] Add is_floating_point
+
+ src/hb-meta.hh | 33 +++++++++++++++++++--------------
+ 1 file changed, 19 insertions(+), 14 deletions(-)
+
+commit 25bb7e005d96c367731fd8d129d764d101b1200f
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Fri May 10 19:49:26 2019 -0700
+
+    [meta] Add is_signed for floating point types
+
+ src/hb-meta.hh | 3 +++
+ 1 file changed, 3 insertions(+)
+
+commit e0315b4aadb3fbc6b618de56d643471e8d1f7859
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Fri May 10 19:48:02 2019 -0700
+
+    [meta] is_integer -> is_integral
+
+ src/hb-algs.hh |  2 +-
+ src/hb-map.hh  |  4 ++--
+ src/hb-meta.hh | 26 +++++++++++++-------------
+ 3 files changed, 16 insertions(+), 16 deletions(-)
+
+commit 9574de7a3e763b9c5eacf65b4b8c148724c00b82
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Fri May 10 19:29:32 2019 -0700
+
+    [meta] Add add_const, add_pointer, add_lvalue_reference, add_rvalue_reference
+
+ src/hb-meta.hh | 11 +++++++++++
+ 1 file changed, 11 insertions(+)
+
+commit 2fb3a8327ab35248a0c7877c48422718cfbe375d
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Fri May 10 18:40:29 2019 -0700
+
+    [vector] Simplify arrayZ
+    
+    Was turned into function when we had static ones and wanted to be
+    move-safe...  Not the case anymore.
+
+ src/hb-coretext.cc      |  2 +-
+ src/hb-ot-cff-common.hh |  2 +-
+ src/hb-uniscribe.cc     | 10 +++----
+ src/hb-vector.hh        | 71 ++++++++++++++++++++++---------------------------
+ 4 files changed, 39 insertions(+), 46 deletions(-)
+
+commit 4d67743ffd99ed9f2278ab21adfac7eb314c0df0
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Fri May 10 16:35:31 2019 -0700
+
+    [subset] Use more auto typing
+
+ src/hb-ot-layout-common.hh     | 8 ++++----
+ src/hb-ot-layout-gdef-table.hh | 2 +-
+ src/hb-ot-layout-gsubgpos.hh   | 4 ++--
+ 3 files changed, 7 insertions(+), 7 deletions(-)
+
+commit a27a31b9ee2601a05575cb581dc227caa73742c4
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Fri May 10 16:26:19 2019 -0700
+
+    Minor
+
+ src/hb-ot-layout-common.hh | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 2ade0086286963ae2c65d44b94e63cb3836ce36b
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Fri May 10 16:21:03 2019 -0700
+
+    [serialize] More rewrite
+
+ src/hb-ot-layout-common.hh | 42 ++++++++++++++++++++++++------------------
+ 1 file changed, 24 insertions(+), 18 deletions(-)
+
+commit 99ed6e29d86bbf391c12ee1f980b8af9dc35615e
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Fri May 10 16:07:51 2019 -0700
+
+    [serialize] Fix a TODO
+
+ src/hb-ot-layout-common.hh | 16 ++++++++++------
+ 1 file changed, 10 insertions(+), 6 deletions(-)
+
+commit d8a49b53e3676ad742bdb8edf0ec3ca6f7a7cac9
+Author: rsheeter <rsheeter@google.com>
+Date:   Fri May 10 16:52:43 2019 -0700
+
+    Update TESTING.md
+
+ TESTING.md | 9 ++++++++-
+ 1 file changed, 8 insertions(+), 1 deletion(-)
+
+commit 25a5b287f220802728cd3312692f368c45d22862
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Fri May 10 16:01:39 2019 -0700
+
+    Fix sanitize fail of extension sublookups
+    
+    Fixes https://bugs.chromium.org/p/chromium/issues/detail?id=960331
+
+ src/hb-ot-layout-common.hh                                 |  10 ++++++++--
+ src/hb-sanitize.hh                                         |   2 ++
+ ...uzz-testcase-minimized-harfbuzz_fuzzer-5702671124791296 | Bin 0 -> 94 bytes
+ 3 files changed, 10 insertions(+), 2 deletions(-)
+
+commit 9c0c3589f31106d1898f8922cc9a2e18cb054989
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Fri May 10 13:56:50 2019 -0700
+
+    Minor
+
+ src/hb-ot-layout-common.hh | 14 ++++++++------
+ 1 file changed, 8 insertions(+), 6 deletions(-)
+
+commit 5d773ec60029e1a6edec45c27ea918d9be4ea806
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Fri May 10 13:53:15 2019 -0700
+
+    Minor
+
+ src/hb-ot-layout-gsubgpos.hh | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit ac737f8c9e7cbc81cdb5a0542a2494671f236895
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Fri May 10 13:51:12 2019 -0700
+
+    Minor again
+
+ src/hb-ot-layout-gsubgpos.hh | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 5d4437fad0f99508ebd5c026a3d927f5d649615e
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Fri May 10 13:43:29 2019 -0700
+
+    Minor
+
+ src/hb-ot-layout-common.hh | 1 -
+ 1 file changed, 1 deletion(-)
+
+commit cd9bc732a75c716121a86e39ab588d2e0af58eba
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Fri May 10 13:17:41 2019 -0700
+
+    [gsubgpos] Minor
+
+ src/hb-ot-layout-gsubgpos.hh | 9 ++-------
+ 1 file changed, 2 insertions(+), 7 deletions(-)
+
+commit 6d63e27ca41b12ba2e8fb22fd6bc44417651c518
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Fri May 10 11:53:02 2019 -0700
+
+    Generate tarball in .xz instead of .bz2
+    
+    Fixes https://github.com/harfbuzz/harfbuzz/issues/1662
+
+ configure.ac | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 1d870cce68f7033f6d3967ce4e9ba622a6fafe79
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Fri May 10 11:32:59 2019 -0700
+
+    Fix bot
+    
+    Any way to catch these?
+
+ src/test-meta.cc | 26 +++++++++++++-------------
+ 1 file changed, 13 insertions(+), 13 deletions(-)
+
+commit 30e4ae6bd19bf297b029205b5f86c1a0ae14943d
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Fri May 10 11:26:39 2019 -0700
+
+    [meta] Add hb_is_base_of
+
+ src/hb-meta.hh   |  7 +++++++
+ src/test-meta.cc | 16 ++++++++++++++++
+ 2 files changed, 23 insertions(+)
+
+commit 98974ac16f5caf282c9c7cf0c417b494efd6af1d
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Fri May 10 11:18:52 2019 -0700
+
+    [iter] Adjust is_source_of / is_sink_of
+    
+    There are two cases that we accept.  Encode both.
+
+ src/hb-iter.hh | 8 +++++++-
+ 1 file changed, 7 insertions(+), 1 deletion(-)
+
+commit 1b58bf22ca70908bb578910757795ee32d48b65a
+Author: rsheeter <rsheeter@google.com>
+Date:   Thu May 9 20:06:29 2019 -0700
+
+    Update TESTING.md
+
+ TESTING.md | 18 +++++++++---------
+ 1 file changed, 9 insertions(+), 9 deletions(-)
+
+commit ed972d5d73ba0592e1ba92426adf2a8f67acf9c9
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Thu May 9 16:58:28 2019 -0700
+
+    [iter] Rewrite test functions
+    
+    Notably, add hb_is_source_of(,) and hb_is_sink_of(,) to replace most
+    uses of hb_is_iterator_of(,).
+
+ src/hb-iter.hh             | 65 +++++++++++++++++++++++++++++-----------------
+ src/hb-open-type.hh        |  7 +++--
+ src/hb-ot-layout-common.hh |  6 ++---
+ src/hb-ot-name-table.hh    |  2 +-
+ src/test-iter.cc           |  2 +-
+ 5 files changed, 49 insertions(+), 33 deletions(-)
+
+commit 42901d7af91b4c5cffee9752f653447e4f4bd4f7
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Thu May 9 16:22:08 2019 -0700
+
+    Minor
+
+ src/hb-meta.hh | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 322627ae1daa16f62f7a91c3c3ed02eb5b708ca5
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Thu May 9 16:08:10 2019 -0700
+
+    Whitespace
+
+ src/hb-array.hh | 6 ++++--
+ 1 file changed, 4 insertions(+), 2 deletions(-)
+
+commit 489f3c35bddb22cfe40c45d3a5c1cb6d88ccaf1f
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Thu May 9 15:39:32 2019 -0700
+
+    Fix bot
+
+ src/test-meta.cc | 70 ++++++++++++++++++++++++++++----------------------------
+ 1 file changed, 35 insertions(+), 35 deletions(-)
+
+commit 790315e0dbc0ce796f0081a60953f74bd3fbdb63
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Thu May 9 15:31:24 2019 -0700
+
+    [algs] Implement implicit casting between compatible pair types
+
+ src/hb-algs.hh   | 5 +++++
+ src/test-algs.cc | 3 +++
+ 2 files changed, 8 insertions(+)
+
+commit 69d9114b5372c1fcea5f20e75a187158c31c52f8
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Thu May 9 15:24:14 2019 -0700
+
+    [meta] Rewrite hb_is_cr_converitble
+
+ src/hb-meta.hh | 22 ++++++++++------------
+ 1 file changed, 10 insertions(+), 12 deletions(-)
+
+commit ceda1f03b7b06248ffd056eb7b2400088bb4a121
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Thu May 9 15:19:42 2019 -0700
+
+    Fix compile
+    
+    NameRecord is not copy-constructible, so should be iterator of
+    const-reference.
+
+ src/hb-meta.hh          |  2 --
+ src/hb-ot-name-table.hh |  2 +-
+ src/test-meta.cc        | 12 ++++++++++++
+ 3 files changed, 13 insertions(+), 3 deletions(-)
+
+commit 3686c3b65c017cf8689b67db440b4cddd399538b
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Thu May 9 15:09:07 2019 -0700
+
+    Adjust is_cr_convertible
+    
+    If To is const& then From doesn't need to be &.
+
+ src/hb-meta.hh | 14 ++++++++++----
+ 1 file changed, 10 insertions(+), 4 deletions(-)
+
+commit 726002a6a615e2d213186d402cca4e8d7e7a7f58
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Thu May 9 14:53:02 2019 -0700
+
+    [iter] Make hb_is_iterator_of() check is_convertible
+    
+    Instead of is_cr_convertible.
+
+ src/hb-array.hh | 8 ++++----
+ src/hb-iter.hh  | 2 +-
+ src/hb-meta.hh  | 8 ++++----
+ 3 files changed, 9 insertions(+), 9 deletions(-)
+
+commit 70a49f2e4a9ab05fe04d1949bbf7a128d14a1284
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Thu May 9 14:35:15 2019 -0700
+
+    [meta] Add hb_conditional<> and hb_is_convertible()
+
+ src/Makefile.am  |  6 ++++-
+ src/hb-meta.hh   | 56 +++++++++++++++++++++++++++++++++++++--------
+ src/test-meta.cc | 70 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+ 3 files changed, 121 insertions(+), 11 deletions(-)
+
+commit 5e3cbed048b19ee579277ab4c56167a15d13104e
+Author: Garret Rieger <grieger@google.com>
+Date:   Wed May 8 16:33:03 2019 -0700
+
+    [subset] Switch building of glyph maps in subset plan to use iterators.
+
+ src/hb-algs.hh        |  4 +---
+ src/hb-subset-plan.cc | 52 +++++++++++++++++++++++++--------------------------
+ 2 files changed, 27 insertions(+), 29 deletions(-)
+
+commit 971020eca7c5d576816b93431607f1e63e9584a4
+Author: Garret Rieger <grieger@google.com>
+Date:   Wed May 8 16:31:52 2019 -0700
+
+    Add sink support for hb_hashmap_t and a reverse call to hb_pair_t.
+
+ src/hb-algs.hh | 5 +++++
+ src/hb-map.hh  | 4 ++++
+ 2 files changed, 9 insertions(+)
+
+commit 98eec3dd5f527cc562d98784429db0c7269e82a8
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Thu May 9 13:15:36 2019 -0700
+
+    Add hb_pair_t(,) macro as alternative to hb_pair_t<,>
+    
+    Just so it's easier to use it in other macros.
+
+ src/hb-algs.hh | 1 +
+ 1 file changed, 1 insertion(+)
+
+commit c9b287a867d6130a0cc745d7fd3ccfa4dcb4c32e
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Thu May 9 12:43:57 2019 -0700
+
+    Add hb_lidentity(), and rename hb_rvalue() to hb_ridentity()
+
+ src/hb-algs.hh   | 13 ++++++++++++-
+ src/hb-map.hh    |  4 ++--
+ src/test-iter.cc |  2 +-
+ 3 files changed, 15 insertions(+), 4 deletions(-)
+
+commit 00195a22ce5198345cb39825a45863cef7d8f7fc
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Thu May 9 12:14:36 2019 -0700
+
+    [hdmx] Adjust to hb_iota() behavior change
+    
+    Use hb_range() instead.
+
+ src/hb-ot-hdmx-table.hh | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+commit 4f2ad75a839708de71e7341f23c2d4b72059fc58
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Thu May 9 12:07:45 2019 -0700
+
+    [enumerate] Fix hb_enumerate() len for step=0
+
+ src/hb-iter.hh | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 5da3c9c33f02010a3fc57cf0e1d07955af681e7c
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Thu May 9 11:30:31 2019 -0700
+
+    [iter] Fix hb_zip() end condition
+    
+    We should compare-equal to end if either iterator's end reaches,
+    not if both reach at the same time.  Fixes infinite-loop in test
+    which was happening after hb_enumerate() switched to using hb_zip().
+
+ src/hb-iter.hh | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 57a5256fbcef6e5d29fc40cf019cc4b2c29c9dcf
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Thu May 9 11:30:27 2019 -0700
+
+    [iter] Minor
+
+ src/hb-iter.hh | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+commit 12dd56f8573cb86169580d5ac31b986208805c03
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Thu May 9 11:25:02 2019 -0700
+
+    [iter] Minor
+
+ src/hb-iter.hh | 6 ++++--
+ 1 file changed, 4 insertions(+), 2 deletions(-)
+
+commit 57d545932f539d06c52862310ecdfe79c143bb6b
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Thu May 9 11:23:41 2019 -0700
+
+    [test-iter] Don't walk past end
+    
+    That's not legal.
+
+ src/test-iter.cc | 6 ++++--
+ 1 file changed, 4 insertions(+), 2 deletions(-)
+
+commit 46837910e628248edc09e45e212532a3493905da
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Thu May 9 11:20:41 2019 -0700
+
+    [iter] Allow negative step in hb_iota()
+
+ src/hb-iter.hh | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 087327af1eac8c3a16115904557cbf3ab0f28072
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Thu May 9 11:14:06 2019 -0700
+
+    [iter] Minor
+
+ src/hb-iter.hh | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 64f0899a9f5e5aff65c5a78fa796ceae6f35c008
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Thu May 9 11:10:31 2019 -0700
+
+    [iter] Bug fix
+
+ src/hb-iter.hh | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 5d263556b95047bced88e4a6252178d2fc0f9a19
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Thu May 9 11:08:25 2019 -0700
+
+    [iter] Fix
+
+ src/hb-iter.hh | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 2c24ea37b1ef63f79fcc24752dd180ce53540eda
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Thu May 9 11:07:38 2019 -0700
+
+    [iter] Take start value in hb_enumerate()
+    
+    Also rewrite it via composition.
+
+ src/hb-iter.hh   | 61 ++++++++++++--------------------------------------------
+ src/test-iter.cc |  1 +
+ 2 files changed, 14 insertions(+), 48 deletions(-)
+
+commit 7675d0d3a6cc13ade1a2047019ef7fac8c373a3c
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Thu May 9 11:02:56 2019 -0700
+
+    [iter] Add hb_range()
+    
+    hb_range() is like Python range.  hb_iota() has slightly different API.
+    Ie. it takes a start, instead of end.
+
+ src/hb-iter.hh   | 29 ++++++++++++++++++-----------
+ src/test-iter.cc | 19 +++++++++++--------
+ 2 files changed, 29 insertions(+), 19 deletions(-)
+
+commit 05867d9f5315c7e4f49e5873a5aba6bba7121f04
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Thu May 9 11:00:43 2019 -0700
+
+    [meta] Add hb_int_max()
+
+ src/hb-meta.hh | 91 ++++++++++++++++++++++++++++++++++++----------------------
+ 1 file changed, 56 insertions(+), 35 deletions(-)
+
+commit 71537f93e0ce27121012bf1e81270b6b03b22224
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Thu May 9 10:46:49 2019 -0700
+
+    [iota] end -> end_ to not shadow
+
+ src/hb-iter.hh | 22 +++++++++++-----------
+ 1 file changed, 11 insertions(+), 11 deletions(-)
+
+commit 6bc82579100992e3f04c11f36b9c2f0014d880f2
+Merge: 34764454 6d9a86ae
+Author: n8willis <n8willis@users.noreply.github.com>
+Date:   Thu May 9 14:39:05 2019 +0100
+
+    Merge pull request #1680 from n8willis/usermanual-obj
+    
+    Usermanual: object-model chapter
+
+commit 3476445420d0e6432c09710b6667205453799129
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Wed May 8 21:14:01 2019 -0700
+
+    Remove unnecessary template keyword
+    
+    Should fix MSVC.
+
+ src/hb-array.hh | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit e2a51ff7264940312197184318f5ad4ec971492f
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Wed May 8 16:41:39 2019 -0700
+
+    Remove unused var
+
+ src/hb-open-type.hh | 1 -
+ 1 file changed, 1 deletion(-)
+
+commit e8b45c19330d8718cd6d7aef0ca2db0539a53294
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Wed May 8 16:37:38 2019 -0700
+
+    [array] Add .copy()
+
+ src/hb-array.hh     | 11 +++++++++++
+ src/hb-open-type.hh | 10 ++++------
+ src/hb-serialize.hh |  2 +-
+ 3 files changed, 16 insertions(+), 7 deletions(-)
+
+commit afb013f350b0022ae6c05f140aeba23d5de34101
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Wed May 8 16:16:43 2019 -0700
+
+    Fix msan issue
+    
+    hb_identity returns rvalue-reference if input is rvalue.  That, can leak
+    the reference and cause in bad access to temporaries after they are
+    destructed.  This is unfortunately unfixable given the desired
+    transparency of hb_identity :(.  Just don't use it with hb_map().
+
+ src/test-iter.cc | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 4c94bc63d914fac7e11940eb165b6cf1039ba5a1
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Wed May 8 15:57:33 2019 -0700
+
+    Move hb_invoke() back to hb-algs.hh
+
+ src/hb-algs.hh | 32 ++++++++++++++++++++++++++++++++
+ src/hb-meta.hh | 32 --------------------------------
+ 2 files changed, 32 insertions(+), 32 deletions(-)
+
+commit b710176ce28e863a01797987d7ce37d19aaf2fd3
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Wed May 8 15:46:51 2019 -0700
+
+    [hdmx] Touch up
+
+ src/hb-ot-hdmx-table.hh | 24 ++++++++++++++----------
+ 1 file changed, 14 insertions(+), 10 deletions(-)
+
+commit e8ef0e627c493af700e254bdd2767f8955f2d03f
+Author: Garret Rieger <grieger@google.com>
+Date:   Tue May 7 17:23:02 2019 -0700
+
+    [subset] WIP convert hdmx subsetting to use iterators.
+
+ src/hb-ot-hdmx-table.hh     | 121 +++++++++++++++++++-------------------------
+ test/api/test-subset-hdmx.c |  23 ---------
+ 2 files changed, 51 insertions(+), 93 deletions(-)
+
+commit d5decf9bf77db914b67ffc446379df621516e362
+Author: Garret Rieger <grieger@google.com>
+Date:   Tue May 7 15:47:38 2019 -0700
+
+    [subset] Move hdmx to subset2.
+
+ src/hb-ot-hdmx-table.hh | 36 ++++++------------------------------
+ src/hb-subset.cc        |  2 +-
+ 2 files changed, 7 insertions(+), 31 deletions(-)
+
+commit 27b2093009745b6c30663605f45ac95deb1562cc
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Wed May 8 15:32:57 2019 -0700
+
+    [map] Return rvalues from keys()/values()
+
+ src/hb-algs.hh | 7 +++++++
+ src/hb-map.hh  | 2 ++
+ 2 files changed, 9 insertions(+)
+
+commit 372c5b97bfa3b744de1d017cf662607eb8a2fa6e
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Wed May 8 15:28:39 2019 -0700
+
+    [map] Fix bots
+    
+    Older compilers don't like calling iter() from return-type decltype()
+    
+    ../src/hb-map.hh:226:12: error: cannot call member function 'decltype ((((+ hb_array(((const hb_hashmap_t<K, V, kINVALID, vINVALID>*)this)->hb_hashmap_t<K, V, kINVALID, vINVALID>::items, (((const hb_hashmap_t<K, V, kINVALID, vINVALID>*)this)->hb_hashmap_t<K, V, kINVALID, vINVALID>::mask ? (((const hb_hashmap_t<K, V, kINVALID, vINVALID>*)this)->hb_hashmap_t<K, V, kINVALID, vINVALID>::mask + 1) : 0))) | hb_filter((& hb_hashmap_t<K, V, kINVALID, vINVALID>::item_t:: is_real))) | hb_map((& hb_hashmap_t<K, V, kINVALID, vINVALID>::item_t:: get_pair)))) hb_hashmap_t<K, V, kINVALID, vINVALID>::iter() const [with K = const hb_serialize_context_t::object_t*; V = unsigned int; K kINVALID = 0u; V vINVALID = 0u; decltype ((((+ hb_array(((const hb_hashmap_t<K, V, kINVALID, vINVALID>*)this)->hb_hashmap_t<K, V, kINVALID, vINVALID>::items, (((const hb_hashmap_t<K, V, kINVALID, vINVALID>*)this)->hb_hashmap_t<K, V, kINVALID, vINVALID>::mask ? (((const hb_hashmap_t<K, V, kINVALID, vINVALID>*)this)->hb_hashmap_t<K, V, kINVALID, vINVALID>::mask + 1) : 0))) | hb_filter((& hb_hashmap_t<K, V, kINVALID, vINVALID>::item_t:: is_real))) | hb_map((& hb_hashmap_t<K, V, kINVALID, vINVALID>::item_t:: get_pair)))) = hb_map_iter_t<hb_filter_iter_t<hb_array_t<hb_hashmap_t<const hb_serialize_context_t::object_t*, unsigned int, 0u, 0u>::item_t>, bool (hb_hashmap_t<const hb_serialize_context_t::object_t*, unsigned int, 0u, 0u>::item_t::*)() const, const<anonymous struct>&, 0u>, hb_pair_t<const hb_serialize_context_t::object_t*, unsigned int> (hb_hashmap_t<const hb_serialize_context_t::object_t*, unsigned int, 0u, 0u>::item_t::*)() const, 0u>]' without object
+         + iter()
+                ^
+    ../src/hb-meta.hh:58:41: note: in definition of macro 'HB_AUTO_RETURN'
+     #define HB_AUTO_RETURN(E) -> decltype ((E)) { return (E); }
+                                             ^
+
+ src/hb-map.hh | 10 ++++++----
+ 1 file changed, 6 insertions(+), 4 deletions(-)
+
+commit a30482718491e3455365167e1c85981c8c0f542b
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Wed May 8 15:08:10 2019 -0700
+
+    [map] Add .values() iterator
+
+ src/hb-map.hh    | 6 +++++-
+ src/test-iter.cc | 8 ++++++++
+ 2 files changed, 13 insertions(+), 1 deletion(-)
+
+commit 3c69505b3a7850b68a931849a2badb84b6b36d51
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Wed May 8 15:05:10 2019 -0700
+
+    [map] Fix iter
+
+ src/hb-map.hh | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 5ceaafa5de8dff51fe91f7008a12ec9c304a1376
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Wed May 8 14:59:25 2019 -0700
+
+    [algs] Fix identity return type
+
+ src/hb-algs.hh | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+commit f5705d7656817cbfdbc4479b1cb0be3af6f4abdf
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Wed May 8 14:46:55 2019 -0700
+
+    Whitespace
+
+ src/hb-map.hh    | 10 +++++-----
+ src/test-iter.cc | 11 +++++++----
+ 2 files changed, 12 insertions(+), 9 deletions(-)
+
+commit a17f0fa3a10a25959561582ae63ef2e5208647e2
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Wed May 8 14:44:11 2019 -0700
+
+    [meta] Capture rvalue-references in is_reference / remove_reference
+
+ src/hb-meta.hh | 1 +
+ 1 file changed, 1 insertion(+)
+
+commit 7166bd563447a64eda05c66668bd4a178292bd79
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Wed May 8 14:24:57 2019 -0700
+
+    Minor
+
+ src/hb-open-type.hh | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+commit b827181ba1f539c990e1bd8fdd3559f1589c8d28
+Author: rsheeter <rsheeter@google.com>
+Date:   Wed May 8 13:51:11 2019 -0700
+
+    [map] tweak test-iter.cc
+
+ src/hb-map.hh    | 1 -
+ src/test-iter.cc | 2 +-
+ 2 files changed, 1 insertion(+), 2 deletions(-)
+
+commit 492af0f1bf1d7198b474fda2faca451908af267f
+Author: rsheeter <rsheeter@google.com>
+Date:   Wed May 8 12:47:18 2019 -0700
+
+    [map] add keys()
+
+ src/hb-map.hh    | 9 ++++++++-
+ src/test-iter.cc | 4 ++++
+ 2 files changed, 12 insertions(+), 1 deletion(-)
+
+commit ba60512813caafc2006b26214e95bbfe1c0e460a
+Author: rsheeter <rsheeter@google.com>
+Date:   Wed May 8 12:09:10 2019 -0700
+
+    [map] add a test for iteration
+
+ src/hb-map.hh    | 2 +-
+ src/test-iter.cc | 4 ++++
+ 2 files changed, 5 insertions(+), 1 deletion(-)
+
+commit 183b8094b577dcb7f40b7fcd64b60d405845897a
+Author: rsheeter <rsheeter@google.com>
+Date:   Wed May 8 11:40:31 2019 -0700
+
+    [map] add iteration
+
+ src/hb-map.hh | 11 +++++++++++
+ 1 file changed, 11 insertions(+)
+
+commit df237d2fe78086ad16bdbd2cc60639ae9ce909d6
+Author: Ebrahim Byagowi <ebrahim@gnu.org>
+Date:   Wed May 8 14:17:14 2019 -0700
+
+    [test] Add https://crbug.com/oss-fuzz/14641 testcase
+    
+    As 503748d fix
+
+ ...-testcase-minimized-hb-subset-fuzzer-5676773460672512 | Bin 0 -> 2172 bytes
+ 1 file changed, 0 insertions(+), 0 deletions(-)
+
+commit 02ae2591d930563cec8c3c63086afb0a3a12c4aa
+Author: Michiharu Ariza <ariza@adobe.com>
+Date:   Wed May 8 13:44:03 2019 -0700
+
+    initialize return param subr_num in popSubrNum
+    
+    also snake_cased popSubrtNum and other surrounding function names
+
+ src/hb-cff-interp-cs-common.hh | 15 ++++++++-------
+ src/hb-subset-cff1.cc          |  4 ++--
+ src/hb-subset-cff2.cc          |  4 ++--
+ 3 files changed, 12 insertions(+), 11 deletions(-)
+
+commit 503748d8a80dd5db450c8c4dc109f2b97049d989
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Wed May 8 12:45:02 2019 -0700
+
+    [name] Sanitize records for reals
+    
+    Fixes https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=14641
+
+ src/hb-ot-name-table.hh | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+commit 5875d775e1253c0e14b900539c28c2de881da7aa
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Wed May 8 12:25:34 2019 -0700
+
+    [iter] Rename hb_iter_t() to hb_iter_type<> and add hb_item_type<>
+
+ src/hb-iter.hh | 18 ++++++++++--------
+ 1 file changed, 10 insertions(+), 8 deletions(-)
+
+commit bad16066392e4dbdd8490a4b1c70d1dcddcc8ec8
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Wed May 8 12:11:52 2019 -0700
+
+    [map] Make .has() optionally return value
+
+ src/hb-map.hh | 7 ++++++-
+ 1 file changed, 6 insertions(+), 1 deletion(-)
+
+commit 750d5af48e38627c3c84a2f3857a7ee602221e24
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Wed May 8 12:01:55 2019 -0700
+
+    Make compiler happy with -Og
+
+ src/hb-cff-interp-cs-common.hh | 2 +-
+ src/hb-ot-cmap-table.hh        | 6 +++---
+ src/hb-ot-glyf-table.hh        | 2 +-
+ src/hb-subset-glyf.cc          | 4 ++--
+ 4 files changed, 7 insertions(+), 7 deletions(-)
+
+commit cdb61eb0431d426f7152f975e89ee3ba4431083f
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Wed May 8 11:00:18 2019 -0700
+
+    [iter] Accept pointer in hb_iter() and hb_iter_t()
+
+ src/hb-iter.hh   | 4 ++--
+ src/test-iter.cc | 3 +++
+ 2 files changed, 5 insertions(+), 2 deletions(-)
+
+commit c93eeba9b21cb8f8ba64ebaf284bf9c8a8544886
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Wed May 8 10:56:09 2019 -0700
+
+    [iter] Accept pointer in hb_map()
+
+ src/hb-iter.hh   | 4 ++--
+ src/test-iter.cc | 7 ++++++-
+ 2 files changed, 8 insertions(+), 3 deletions(-)
+
+commit 4c9e0c37a34e8355d752af39507b310f473bffa5
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Wed May 8 10:40:39 2019 -0700
+
+    [serialize] LangSys subset->copy
+
+ src/hb-ot-layout-common.hh | 10 +++++-----
+ 1 file changed, 5 insertions(+), 5 deletions(-)
+
+commit 50dc3e7d9f4f290c7353313c5e5f888cb7c4846d
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Wed May 8 10:35:02 2019 -0700
+
+    Add hb_iota()
+
+ src/hb-iter.hh   | 51 +++++++++++++++++++++++++++++++++++++++++++++++++++
+ src/test-iter.cc | 10 ++++++++++
+ 2 files changed, 61 insertions(+)
+
+commit aa4ac13f0be34bba66b00d04fd7806c474ff59c0
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Wed May 8 10:02:30 2019 -0700
+
+    [iter] Actually fix previous commit
+    
+    The iter objects shouldn't not be const.  D'oh.
+
+ src/hb-iter.hh | 16 ++++++++--------
+ 1 file changed, 8 insertions(+), 8 deletions(-)
+
+commit a66598e0306fe80063c5d6a678bbca4a931bc4d4
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Wed May 8 09:56:29 2019 -0700
+
+    [iter] For ref-qualified variants
+
+ src/hb-iter.hh | 14 ++++++++++----
+ 1 file changed, 10 insertions(+), 4 deletions(-)
+
+commit fa576ce1874fd886688bf3f16b714d86aebb07ec
+Author: rsheeter <rsheeter@google.com>
+Date:   Wed May 8 09:53:58 2019 -0700
+
+    Update README.md
+
+ README.md | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+commit d109c9e767ff3198d51e23a7ac8931d0bc4d5d72
+Author: rsheeter <rsheeter@google.com>
+Date:   Wed May 8 09:53:29 2019 -0700
+
+    Update README.md
+
+ README.md | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+commit 4063181791d6b3efb35e7c748dee12273e64ebd4
+Author: rsheeter <rsheeter@google.com>
+Date:   Wed May 8 09:47:34 2019 -0700
+
+    [docs] add fuzzer instructions (courtesy of Garret)
+
+ TESTING.md | 10 ++++++++++
+ 1 file changed, 10 insertions(+)
+
+commit 00946ca3aa45f109c455871ce89c5872fd243624
+Author: Roderick Sheeter <rsheeter@rsheeter-macbookpro2.roam.corp.google.com>
+Date:   Wed May 8 09:42:35 2019 -0700
+
+    [docs] add sample commands for test exec
+
+ README.md  |  4 ++++
+ TESTING.md | 47 +++++++++++++++++++++++++++++++++++++++++++++++
+ 2 files changed, 51 insertions(+)
+
+commit 8479eb5955c93cbc8951d0319b2fe43ff19cc403
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Wed May 8 09:48:55 2019 -0700
+
+    [iter] Fix hb_sink() to accept rvalue
+
+ src/hb-iter.hh   | 2 +-
+ src/test-iter.cc | 4 ++++
+ 2 files changed, 5 insertions(+), 1 deletion(-)
+
+commit 710d459acac88fd784d4ead0ba75b9aa623c48d4
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Wed May 8 09:33:09 2019 -0700
+
+    [iter] Default predicates to hb_identity instead of hb_bool
+    
+    The bool conversion happens after predicate is called automatically.
+
+ src/hb-iter.hh | 16 ++++++++--------
+ 1 file changed, 8 insertions(+), 8 deletions(-)
+
+commit fe14a4000a58528878bcc75fde0972de2b779316
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Wed May 8 09:32:19 2019 -0700
+
+    Adjust hb_all/any/none
+
+ src/hb-iter.hh   | 18 +++++++++---------
+ src/test-iter.cc | 10 ++++++----
+ 2 files changed, 15 insertions(+), 13 deletions(-)
+
+commit 4a101d8ffccd6f907f16ef190125ded5e27e0d8b
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Wed May 8 09:16:33 2019 -0700
+
+    Add hb_match
+
+ src/hb-algs.hh | 30 +++++++++++++++++++++++++++++-
+ 1 file changed, 29 insertions(+), 1 deletion(-)
+
+commit 26adefd9eaf4bc1d80b1ffececf0d86f3308f9ee
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Wed May 8 09:14:44 2019 -0700
+
+    [algs] Try f[v] in hb_get() as last resort
+
+ src/hb-algs.hh | 10 ++++++++--
+ 1 file changed, 8 insertions(+), 2 deletions(-)
+
+commit 0601a19d38b2b0fc5dd36fd821af634a49322ebf
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Wed May 8 07:47:36 2019 -0700
+
+    Fix a few more double-pomotion errors
+
+ src/hb-coretext.cc | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+commit 2ba984fcbbef4561d35c3a2c502610c38b26f4fb
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Tue May 7 23:28:22 2019 -0700
+
+    Fix signed comparison on 32bit
+
+ src/hb-sanitize.hh | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit dfc57802450360f06026668b7b61495aaa2d1943
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Tue May 7 23:26:09 2019 -0700
+
+    Fix more double-promotion errors
+    
+    WHy do only some of the clang bots catch this I have no idea :(.
+
+ src/hb-aat-layout-trak-table.hh |  4 ++--
+ src/hb-font.hh                  |  2 +-
+ src/hb-open-type.hh             |  4 ++--
+ src/hb-ot-color-cbdt-table.hh   | 12 ++++++------
+ src/hb-ot-color-sbix-table.hh   | 10 +++++-----
+ src/hb-ot-layout-gpos-table.hh  | 20 ++++++++++----------
+ 6 files changed, 26 insertions(+), 26 deletions(-)
+
+commit c2c9d204fa5c2189e369726276a1c0e92e09a9ce
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Tue May 7 23:13:38 2019 -0700
+
+    Fix double-promotion warnings
+    
+    Make it an error.
+
+ src/hb-ot-var-fvar-table.hh | 12 ++++++------
+ src/hb.hh                   |  1 +
+ 2 files changed, 7 insertions(+), 6 deletions(-)
+
+commit 2c7093ed01f417828d5521d983eae63042363197
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Tue May 7 23:10:59 2019 -0700
+
+    More tests
+
+ src/test-algs.cc | 3 +++
+ 1 file changed, 3 insertions(+)
+
+commit 56d2d0294b836ea1e2dea9e242ae72c99387d00a
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Tue May 7 23:08:49 2019 -0700
+
+    [algs] Sprinkle hb_min/max with hb-forward salad
+    
+    Let's see if fixes MSVC fail.  Though, the error doesn't make sense to me.
+    
+      hb-blob.cc
+    c:\projects\harfbuzz\src\hb-algs.hh(166): error C2440: 'return': cannot convert from 'unsigned int' to 'unsigned int &&' [C:\projects\harfbuzz\build\harfbuzz.vcxproj]
+      c:\projects\harfbuzz\src\hb-algs.hh(166): note: You cannot bind an lvalue to an rvalue reference
+      c:\projects\harfbuzz\src\hb-algs.hh(174): note: see reference to function template instantiation 'T &&<unnamed-type-hb_min>::impl<T,unsigned int&>(T &&,T2) const' being compiled
+              with
+              [
+                  T=unsigned int,
+                  T2=unsigned int &
+              ]
+
+ src/hb-algs.hh | 10 ++++++----
+ 1 file changed, 6 insertions(+), 4 deletions(-)
+
+commit bdbfdc92b58d5c9f8654e430075dab543d1ba394
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Tue May 7 22:52:43 2019 -0700
+
+    [iter] Add value and projection to hb_all/any/none
+    
+    Allows for eg, checking all values equal 2: hb_all (it, 2).
+
+ src/hb-iter.hh   | 24 ++++++++++++++++++------
+ src/test-iter.cc | 10 +++++++++-
+ 2 files changed, 27 insertions(+), 7 deletions(-)
+
+commit cf61acb9eaa2bb3fe479a9050116b4b96934e3ed
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Tue May 7 22:45:01 2019 -0700
+
+    [iter] Accept rvalues to hb_enumerate()
+
+ src/hb-iter.hh   | 2 +-
+ src/test-iter.cc | 2 ++
+ 2 files changed, 3 insertions(+), 1 deletion(-)
+
+commit e8bd5fc3fa2cc5c5f8f254629553902aed3496ba
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Tue May 7 22:29:40 2019 -0700
+
+    [meta] Move hb_invoke from algs to meta
+
+ src/hb-algs.hh | 31 -------------------------------
+ src/hb-meta.hh | 32 ++++++++++++++++++++++++++++++++
+ 2 files changed, 32 insertions(+), 31 deletions(-)
+
+commit af571dbffc12e6bb7a3146762d12bb4ac3f19bdc
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Tue May 7 21:39:20 2019 -0700
+
+    [meta] Replace most hb_enable_if with hb_requires
+    
+    They do absolutely same thing.  hb_requires is to encode constraints,
+    whereas hb_enable_if is for more conditional enabling.
+
+ src/hb-iter.hh             | 63 +++++++++++++++++++++-------------------------
+ src/hb-open-type.hh        |  6 ++---
+ src/hb-ot-layout-common.hh |  6 ++---
+ src/test-iter.cc           |  6 ++---
+ 4 files changed, 37 insertions(+), 44 deletions(-)
+
+commit 6fa1f38070e710b2f80a836bd633b6ab33e1bc80
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Tue May 7 21:33:26 2019 -0700
+
+    [algs] Accept varargs in hb_min/max
+
+ src/hb-algs.hh   | 24 +++++++++++++++++++++---
+ src/test-algs.cc |  8 ++++++++
+ 2 files changed, 29 insertions(+), 3 deletions(-)
+
+commit 1ad07080c3ea7f6a1b3cb247529ec0c78575a6d3
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Tue May 7 21:00:23 2019 -0700
+
+    Rename
+
+ src/hb-algs.hh | 24 ++++++++++++------------
+ 1 file changed, 12 insertions(+), 12 deletions(-)
+
+commit 83e3eabd84e2b53c696768d1357a6a259bcd3576
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Tue May 7 20:58:43 2019 -0700
+
+    Whitespace
+
+ src/hb-aat-layout-common.hh     |  2 +-
+ src/hb-aat-layout-kerx-table.hh |  2 +-
+ src/hb-aat-layout-morx-table.hh |  2 +-
+ src/hb-algs.hh                  |  6 +++---
+ src/hb-dispatch.hh              |  2 +-
+ src/hb-open-type.hh             | 18 +++++++++---------
+ src/hb-ot-kern-table.hh         |  4 ++--
+ src/hb-ot-layout-common.hh      |  2 +-
+ src/hb-ot-layout-gpos-table.hh  | 16 ++++++++--------
+ src/hb-ot-layout-gsub-table.hh  | 14 +++++++-------
+ src/hb-ot-layout-gsubgpos.hh    |  8 ++++----
+ src/hb-sanitize.hh              |  6 +++---
+ src/hb-serialize.hh             | 12 ++++++------
+ src/hb-subset.hh                |  6 +++---
+ 14 files changed, 50 insertions(+), 50 deletions(-)
+
+commit 2b9402a86a4e37e6386f8028bdf3789ae262a4c4
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Tue May 7 20:55:33 2019 -0700
+
+    Use universal references in hb_min/max
+
+ src/hb-algs.hh | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+commit 41248cce0e32653227a83eb4e42ccf793f040fc2
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Tue May 7 20:54:31 2019 -0700
+
+    Remove MIN/MAX in favor of hb_min/hb_max
+
+ src/hb-aat-layout-common.hh      |  8 ++++----
+ src/hb-aat-layout-feat-table.hh  |  2 +-
+ src/hb-aat-layout-kerx-table.hh  |  2 +-
+ src/hb-aat-layout-morx-table.hh  | 18 +++++++++---------
+ src/hb-algs.hh                   | 14 +++++---------
+ src/hb-array.hh                  |  4 ++--
+ src/hb-blob.cc                   |  2 +-
+ src/hb-buffer-serialize.cc       | 32 ++++++++++++++++----------------
+ src/hb-buffer.cc                 |  4 ++--
+ src/hb-buffer.hh                 |  2 +-
+ src/hb-common.cc                 | 20 ++++++++++----------
+ src/hb-coretext.cc               |  6 +++---
+ src/hb-debug.hh                  |  2 +-
+ src/hb-directwrite.cc            |  2 +-
+ src/hb-ft.cc                     |  2 +-
+ src/hb-iter.hh                   |  2 +-
+ src/hb-open-file.hh              |  2 +-
+ src/hb-open-type.hh              |  2 +-
+ src/hb-ot-cmap-table.hh          |  8 ++++----
+ src/hb-ot-color-cbdt-table.hh    |  6 +++---
+ src/hb-ot-color-cpal-table.hh    |  2 +-
+ src/hb-ot-color-sbix-table.hh    |  2 +-
+ src/hb-ot-glyf-table.hh          | 14 +++++++-------
+ src/hb-ot-hmtx-table.hh          |  2 +-
+ src/hb-ot-layout-gpos-table.hh   |  2 +-
+ src/hb-ot-layout-gsub-table.hh   |  4 ++--
+ src/hb-ot-layout-gsubgpos.hh     |  6 +++---
+ src/hb-ot-layout.cc              |  2 +-
+ src/hb-ot-map.cc                 |  8 ++++----
+ src/hb-ot-post-table.hh          |  2 +-
+ src/hb-ot-shape-complex-indic.cc |  8 ++++----
+ src/hb-ot-shape-complex-use.cc   |  2 +-
+ src/hb-ot-shape.cc               |  4 ++--
+ src/hb-ot-tag.cc                 |  2 +-
+ src/hb-ot-var-avar-table.hh      |  2 +-
+ src/hb-ot-var-fvar-table.hh      | 18 +++++++++---------
+ src/hb-sanitize.hh               |  4 ++--
+ src/hb-uniscribe.cc              |  2 +-
+ 38 files changed, 111 insertions(+), 115 deletions(-)
+
+commit 5c0f62adc969696b46c1ceb57cd3c2fa408eb94f
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Tue May 7 17:23:46 2019 -0700
+
+    [serializer] Accept pointer & reference in more methods
+
+ src/hb-serialize.hh | 39 ++++++++++++++++++++++++---------------
+ 1 file changed, 24 insertions(+), 15 deletions(-)
+
+commit 839618de3b3da285e8753b6ca6d767e9a483bfde
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Tue May 7 17:21:27 2019 -0700
+
+    [serializer] Minor
+
+ src/hb-serialize.hh | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 035b818e34bbd2d5c1f65328c9847c845d74d919
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Tue May 7 17:21:18 2019 -0700
+
+    [meta] Fix addressof()
+
+ src/hb-meta.hh | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 7654ebe3a51c98b4d3bf6fb11779024f1c770962
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Tue May 7 16:53:03 2019 -0700
+
+    Whitespace
+
+ src/hb-algs.hh | 30 ++++++++++++++++++++----------
+ src/hb-iter.hh | 39 ++++++++++++++++++++++++++-------------
+ src/hb-meta.hh | 11 ++++++-----
+ 3 files changed, 52 insertions(+), 28 deletions(-)
+
+commit 95426ea983bde01fadf4681926cb77e3b3c0d40a
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Tue May 7 15:56:51 2019 -0700
+
+    Add comment
+
+ src/hb-open-type.hh | 1 +
+ 1 file changed, 1 insertion(+)
+
+commit e33ad252222481a6078a8bb423505e713b081313
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Tue May 7 15:46:24 2019 -0700
+
+    [serialize] FeatureVariations subset->copy
+
+ src/hb-ot-layout-common.hh   | 6 +++---
+ src/hb-ot-layout-gsubgpos.hh | 2 +-
+ 2 files changed, 4 insertions(+), 4 deletions(-)
+
+commit fa8c4ba81175f671c3f39f1586d0a1d9067d9f89
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Tue May 7 14:26:03 2019 -0700
+
+    Minor
+
+ src/hb-serialize.hh | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit c09d6c58e99dba50f29a569e4c53916b5b507ef1
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Tue May 7 14:09:00 2019 -0700
+
+    [iter] Require lvalue in operators that return reference
+
+ src/hb-iter.hh | 16 ++++++++--------
+ 1 file changed, 8 insertions(+), 8 deletions(-)
+
+commit 52f6c04c1e0eab2aaa0c7d817b212c01ba993fe9
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Tue May 7 13:45:48 2019 -0700
+
+    Minor
+
+ src/hb-serialize.hh | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+commit 7c037bd2be2e794dfd882b806f684ad74c56dbb8
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Tue May 7 13:37:43 2019 -0700
+
+    [name] Clean up some more
+
+ src/hb-meta.hh          |  2 ++
+ src/hb-ot-name-table.hh | 30 ++++++++++++++----------------
+ 2 files changed, 16 insertions(+), 16 deletions(-)
+
+commit f982b9d9f8d6b61efd2a3e89cc3d34923c1914b0
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Tue May 7 13:29:01 2019 -0700
+
+    [name] Clean up serialize() API
+
+ src/hb-ot-name-table.hh | 8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+commit 59ee61fddc76cd18f19f351bca7dd293eb610333
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Tue May 7 13:26:15 2019 -0700
+
+    [name] Use iterators more
+
+ src/hb-ot-name-table.hh | 46 +++++++++++++++-------------------------------
+ src/hb-subset-plan.cc   |  3 +++
+ 2 files changed, 18 insertions(+), 31 deletions(-)
+
+commit 2eb7e0e0e923d096d2598133cacd6e5ee04a6a04
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Tue May 7 12:45:38 2019 -0700
+
+    [serialize] Minor
+
+ src/hb-serialize.hh | 5 ++++-
+ 1 file changed, 4 insertions(+), 1 deletion(-)
+
+commit 1c81cff2d3f9df2c18ffbdfff02ed418560480c1
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Tue May 7 11:51:10 2019 -0700
+
+    Fix signed-comparison error on 32bit
+
+ src/hb-serialize.hh | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 938de315756e08bd2b5fa816c7951640e5835b2e
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Tue May 7 11:47:02 2019 -0700
+
+    Comment
+
+ src/hb-subset-glyf.cc | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 159fe962e90dd3b758ad10046b9d75cf87c1d4f3
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Tue May 7 11:46:11 2019 -0700
+
+    [doc] Make header search more resilient
+    
+    How stupid to scan all files... Sigh.
+
+ docs/Makefile.am | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 9b05db33b54e6e5f0b4658f4c06e7fe563f8923b
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Tue May 7 11:39:44 2019 -0700
+
+    [ragel] Regenerate ragel-generated files using ragel 7.0.0.11 May 2018
+
+ src/hb-buffer-deserialize-json.hh          | 1051 +++++------
+ src/hb-buffer-deserialize-text.hh          | 1009 +++++------
+ src/hb-ot-shape-complex-indic-machine.hh   | 2678 ++++++++++++++++------------
+ src/hb-ot-shape-complex-khmer-machine.hh   |  709 ++++----
+ src/hb-ot-shape-complex-myanmar-machine.hh |  820 +++++----
+ src/hb-ot-shape-complex-use-machine.hh     | 1144 ++++++------
+ 6 files changed, 3959 insertions(+), 3452 deletions(-)
+
+commit 521262b236dacf7b2b64e0a1d3c79d6a10b07063
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Tue May 7 11:08:08 2019 -0700
+
+    [subset] Add TODO
+
+ src/hb-subset.cc | 2 ++
+ 1 file changed, 2 insertions(+)
+
+commit e6a622b5b202533d64f83e71d7ff8a8104d46e26
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Tue May 7 11:06:43 2019 -0700
+
+    [serialize] Enable bias assertion
+
+ src/hb-serialize.hh | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 530ddbbc320bd24b4902ee6d49bf80242a591794
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Tue May 7 11:05:51 2019 -0700
+
+    [serialize] Use range-based loop
+
+ src/hb-serialize.hh | 15 ++++++---------
+ 1 file changed, 6 insertions(+), 9 deletions(-)
+
+commit 0987c4204fae66f80224c6f01d9c5dc3abe809e0
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Tue May 7 11:01:02 2019 -0700
+
+    [name] Remove dead code
+
+ src/hb-ot-name-table.hh | 88 +------------------------------------------------
+ 1 file changed, 1 insertion(+), 87 deletions(-)
+
+commit 5ac4ab686809be9352e91bc3213e1edf3ba66a93
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Thu May 2 16:29:07 2019 -0700
+
+    [subset] fix for name table serializing with new serializer machinery
+
+ src/hb-ot-name-table.hh            |   8 ++++++--
+ test/api/fonts/nameID.expected.ttf | Bin 170696 -> 2388 bytes
+ 2 files changed, 6 insertions(+), 2 deletions(-)
+
+commit c548fcedc404c03442c042059a71194d97d23bb6
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Thu May 2 16:29:07 2019 -0700
+
+    [WIP] [name] Port to fancy serializer machinery
+
+ src/hb-ot-name-table.hh | 18 +++++++++++-------
+ 1 file changed, 11 insertions(+), 7 deletions(-)
+
+commit fa2d97161f8b7de3d7a70e06d41b6f7e154012ad
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Tue May 7 00:34:50 2019 -0700
+
+    Remove use of deprecated implicit copy/move assignment operators
+    
+    By removing custom copy constructor.
+
+ src/hb-meta.hh | 2 --
+ 1 file changed, 2 deletions(-)
+
+commit 45f5e56236912359d0ac72310dcdba9259cfee66
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Tue May 7 00:33:32 2019 -0700
+
+    Warn on -Wdeprecated
+
+ src/hb.hh | 1 +
+ 1 file changed, 1 insertion(+)
+
+commit c3e0eafc80481f8c16516fdae1841c563e7253d4
+Author: Ebrahim Byagowi <ebrahim@gnu.org>
+Date:   Tue May 7 12:04:00 2019 +0430
+
+    [ci] Upgrade Ubuntu 17.10 bots to 19.04
+
+ .circleci/config.yml | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+commit 8903040fcd09e7d7ad5112ac2a583718bb85795d
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Tue May 7 00:13:11 2019 -0700
+
+    Actually make it work
+
+ src/hb-iter.hh | 2 ++
+ src/hb-meta.hh | 6 ++++--
+ 2 files changed, 6 insertions(+), 2 deletions(-)
+
+commit 025eaa3c81214cdb20f2f588bab665512d21507c
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Tue May 7 00:05:37 2019 -0700
+
+    [iter] Make filter/map copyable
+
+ src/hb-iter.hh   | 18 +++++++++---------
+ src/test-iter.cc |  4 ++--
+ 2 files changed, 11 insertions(+), 11 deletions(-)
+
+commit 03a68165d8296ed5cc0eb2434500381419409e79
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Tue May 7 00:03:35 2019 -0700
+
+    [meta] Add hb_reference_wrapper<>
+    
+    Functionality kinda superset of std:: counterpart.
+
+ src/hb-meta.hh | 21 +++++++++++++++++++++
+ 1 file changed, 21 insertions(+)
+
+commit 0bf86d9c5dcb0de206b38c3cf1824d2254376f37
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Mon May 6 23:39:26 2019 -0700
+
+    Whitespace
+
+ src/hb-meta.hh | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+commit 72eb91deb9eb7a08e38e100a3234518651fe4cb8
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Mon May 6 23:39:13 2019 -0700
+
+    Add hb_ref()
+    
+    Unused.
+
+ src/hb-meta.hh | 10 ++++++++++
+ 1 file changed, 10 insertions(+)
+
+commit 240f57e58d3b0161feb90621d5db9e2fc4d99b27
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Mon May 6 23:17:39 2019 -0700
+
+    Rename hb_deref_pointer() to hb_deref()
+
+ src/hb-algs.hh      | 12 ++++++------
+ src/hb-map.hh       |  2 +-
+ src/hb-meta.hh      |  2 +-
+ src/hb-serialize.hh |  2 +-
+ 4 files changed, 9 insertions(+), 9 deletions(-)
+
+commit 0b1ca5a13b6921cb4d00f8651bb99fc7c7037ec2
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Mon May 6 23:04:32 2019 -0700
+
+    [iter] Adjust hb_filter
+
+ src/hb-iter.hh | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 4c2fd05ca5fa34303b986c34948b512d770ab8fe
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Mon May 6 19:57:15 2019 -0700
+
+    [iter] Implement range-based for loops
+    
+    Part of https://github.com/harfbuzz/harfbuzz/issues/1648
+
+ src/hb-array.hh            |  6 ++++
+ src/hb-iter.hh             | 74 ++++++++++++++++++++++++++++++++++++++++++++--
+ src/hb-ot-layout-common.hh | 14 +++++++++
+ src/hb-set.hh              |  3 ++
+ src/test-iter.cc           | 28 ++++++++++++++----
+ 5 files changed, 118 insertions(+), 7 deletions(-)
+
+commit e261dc3a4043230ae1b4f56e2cc7d3133b7da4ca
+Author: Ebrahim Byagowi <ebrahim@gnu.org>
+Date:   Tue May 7 01:24:55 2019 +0430
+
+    Ignore -Wc++11-compat as we require C++11 actually
+    
+    pollutes gcc bots logs https://circleci.com/gh/harfbuzz/harfbuzz/85395
+
+ src/hb.hh | 1 +
+ 1 file changed, 1 insertion(+)
+
+commit 9f9890e9e82c620e733d123f421f7c63d91ce8e1
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Mon May 6 12:16:51 2019 -0700
+
+    Remove HB_NO_OPTIONS in favor of HB_NO_GETENV
+    
+    Part of https://github.com/harfbuzz/harfbuzz/issues/1652
+
+ src/hb-debug.hh | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 36bb24f7b4dbbe171b945639bac749c46785e17c
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Sun May 5 10:14:17 2019 -0700
+
+    [dispatch] Forward arguments in all dispatch multiplexers
+
+ src/hb-aat-layout-kerx-table.hh | 14 ++++-----
+ src/hb-aat-layout-morx-table.hh | 14 ++++-----
+ src/hb-ot-kern-table.hh         | 16 +++++-----
+ src/hb-ot-layout-common.hh      |  6 ++--
+ src/hb-ot-layout-gpos-table.hh  | 68 ++++++++++++++++++++---------------------
+ src/hb-ot-layout-gsub-table.hh  | 58 +++++++++++++++++------------------
+ src/hb-ot-layout-gsubgpos.hh    | 32 +++++++++----------
+ 7 files changed, 104 insertions(+), 104 deletions(-)
+
+commit c14efb8e68e31fb7537bcfe5eea779c0830a0b0c
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Sun May 5 09:54:58 2019 -0700
+
+    Fix previous commit
+    
+    Priority should be given to specific over dispatch.  Broke sanitize before.
+    This fixes it, by moving prioritization to the context implementation, since
+    the correct priority cannot be done in the dispatch implementation.  Done
+    for subset and sanitize only, which need it.
+
+ src/hb-aat-layout-common.hh  |  2 +-
+ src/hb-dispatch.hh           | 10 +---------
+ src/hb-ot-layout-gsubgpos.hh | 14 +++++++-------
+ src/hb-sanitize.hh           | 16 +++++++++++++---
+ src/hb-subset.hh             | 15 ++++++++++++---
+ 5 files changed, 34 insertions(+), 23 deletions(-)
+
+commit b10f65933a77434bf8d68058793037f38a8ed5a6
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Sun May 5 09:23:35 2019 -0700
+
+    [dispatch] Use functionality from previous commit
+    
+    To remove a couple of unwanted wrapper methods
+
+ src/hb-dispatch.hh             | 15 +++++++++------
+ src/hb-open-type.hh            | 10 +++++-----
+ src/hb-ot-layout-gpos-table.hh |  6 ------
+ src/hb-ot-layout-gsub-table.hh |  6 ------
+ src/hb-sanitize.hh             |  5 +++--
+ src/hb-subset.hh               |  5 +++--
+ 6 files changed, 20 insertions(+), 27 deletions(-)
+
+commit ac350c92fd6b04845c6240a5f3b77ceaf29e51d0
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Sun May 5 09:10:46 2019 -0700
+
+    [dispatch] Try obj.dispatch(c) before trying c->dispatch(obj)
+
+ src/hb-aat-layout-common.hh  |  2 +-
+ src/hb-dispatch.hh           | 13 +++++++++++++
+ src/hb-ot-layout-gsubgpos.hh | 14 +++++++-------
+ src/hb-sanitize.hh           |  2 +-
+ src/hb-subset.hh             |  4 ++--
+ 5 files changed, 24 insertions(+), 11 deletions(-)
+
+commit 0d5fd168f8e3c1202358a82161a28e407149b1b4
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Fri May 3 10:37:32 2019 -0700
+
+    Revert "[WIP] [name] Port to fancy serializer machinery"
+    
+    This reverts commit c7f366fbbb208d0a9103ac4ee4ac00ff726c31e4.
+    
+    Don't know how it got to master!
+
+ src/hb-ot-name-table.hh | 18 +++++++-----------
+ 1 file changed, 7 insertions(+), 11 deletions(-)
+
+commit 72e3eba8f87e2a8b145a4f98e24499f0aafe099b
+Author: Cody Planteen <planteen@gmail.com>
+Date:   Thu May 2 13:03:15 2019 -0600
+
+    Add configuration option HB_NO_GETENV to disable use of getenv()
+
+ src/hb.hh | 12 ++++++++++--
+ 1 file changed, 10 insertions(+), 2 deletions(-)
+
+commit c7f366fbbb208d0a9103ac4ee4ac00ff726c31e4
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Thu May 2 16:29:07 2019 -0700
+
+    [WIP] [name] Port to fancy serializer machinery
+
+ src/hb-ot-name-table.hh | 18 +++++++++++-------
+ 1 file changed, 11 insertions(+), 7 deletions(-)
+
+commit 8855af38a8497d7788924d368baa9eeae4916940
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Thu May 2 16:26:06 2019 -0700
+
+    [name] Add NameRecord::copy()
+
+ src/hb-ot-name-table.hh | 10 ++++++++++
+ 1 file changed, 10 insertions(+)
+
+commit 097bb3f0af391dbb5d498df548b769f165f35c8a
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Thu May 2 16:25:00 2019 -0700
+
+    [name] Minor changes
+
+ src/hb-ot-name-table.hh | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+commit 431b6e1c449582619169722e16b472e872b02d58
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Thu May 2 16:22:32 2019 -0700
+
+    [serialize] Disable assertion for now
+
+ src/hb-serialize.hh | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 8a32c9eecbdc907415195eca9ebad47c8acf2df5
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Thu May 2 16:20:18 2019 -0700
+
+    [serialize] Misc getting copy() to work
+
+ src/hb-open-type.hh | 16 +++++++++-------
+ src/hb-serialize.hh | 26 ++++++++++++++++----------
+ 2 files changed, 25 insertions(+), 17 deletions(-)
+
+commit 7d497a3a92973d4cec14888b932091f49de1d190
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Thu May 2 16:20:03 2019 -0700
+
+    [debug] Allow return_trace() to return any type
+
+ src/hb-debug.hh | 14 ++++++++------
+ 1 file changed, 8 insertions(+), 6 deletions(-)
+
+commit 49b1c763a0459d586b7f0aa86eadd13d21b24867
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Thu May 2 16:19:34 2019 -0700
+
+    [test] Run "fonttools ttx" instead of "ttx"
+
+ test/subset/run-tests.py | 10 +++++-----
+ 1 file changed, 5 insertions(+), 5 deletions(-)
+
+commit 91176d5b778b44172591e82ba84127e5eff1372d
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Thu May 2 15:12:07 2019 -0700
+
+    [serialize] Check offset base is within (possibly end of) object
+
+ src/hb-serialize.hh | 1 +
+ 1 file changed, 1 insertion(+)
+
+commit 0f1a6ce8268b197732aab40069bbda57eddac2e0
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Thu May 2 15:03:41 2019 -0700
+
+    [name] Fix format of susbetted table to 0
+
+ src/hb-ot-name-table.hh | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 87810fc958e28d0c5e05097b1b3fe78d962fdc62
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Thu May 2 14:45:57 2019 -0700
+
+    [name] Use variable forwarding to simplify sanitize()
+
+ src/hb-ot-name-table.hh | 7 ++-----
+ 1 file changed, 2 insertions(+), 5 deletions(-)
+
+commit bf91b418b0e988619c230156f5f062c5d2802dd8
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Thu May 2 14:42:37 2019 -0700
+
+    [name]
+
+ src/hb-ot-name-table.hh | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+commit 998b0b68ac2eafd1d5bca51b3723fa753e4db7c4
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Thu May 2 14:39:52 2019 -0700
+
+    [serializer] Add copy() to (Unsized)ArrayOf
+
+ src/hb-open-type.hh | 41 +++++++++++++++++++++++++++++++++++++++++
+ src/hb-serialize.hh |  4 ++--
+ 2 files changed, 43 insertions(+), 2 deletions(-)
+
+commit 88a41472404a8e7754e1099ca4a5b2146dae5298
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Thu May 2 14:22:31 2019 -0700
+
+    [serializer] Accept exact type in serialize_subset/copy()
+
+ src/hb-open-type.hh            | 12 ++++++------
+ src/hb-ot-layout-common.hh     | 33 ++-------------------------------
+ src/hb-ot-layout-gpos-table.hh |  6 ++++++
+ src/hb-ot-layout-gsub-table.hh |  6 ++++++
+ 4 files changed, 20 insertions(+), 37 deletions(-)
+
+commit 88fdeeecc0ef57e41219d92c90f35f13cbd3a35e
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Thu May 2 14:14:33 2019 -0700
+
+    [serialize] Take arguments in copy()
+
+ src/hb-open-type.hh |  6 +++---
+ src/hb-serialize.hh | 10 ++++++----
+ 2 files changed, 9 insertions(+), 7 deletions(-)
+
+commit 273ed6127bd9471fd11b3c1c7f232638f1ff1dba
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Thu May 2 14:04:51 2019 -0700
+
+    [serializer] Add serialize_copy()
+
+ src/hb-open-type.hh | 14 ++++++++++++++
+ 1 file changed, 14 insertions(+)
+
+commit bf22338f49fb1711f7cbcad2d9949d7962cdc0bc
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Thu May 2 13:51:52 2019 -0700
+
+    Remove dead code
+
+ src/hb-algs.hh | 3 ---
+ 1 file changed, 3 deletions(-)
+
+commit 14e1fabc41a9a5ead3d91d560773050469982f54
+Author: David Corbett <corbett.dav@husky.neu.edu>
+Date:   Wed May 1 21:29:06 2019 -0400
+
+    Sync gen-vowel-constraints.py with current output
+
+ src/gen-vowel-constraints.py | 3 +++
+ 1 file changed, 3 insertions(+)
+
+commit 026ab825c8e41980e286be911cc6fbb958dd7cd3
+Author: David Corbett <corbett.dav@husky.neu.edu>
+Date:   Wed May 1 16:15:58 2019 -0400
+
+    Add dotted circles to more broken clusters
+
+ src/gen-use-table.py                       |   9 +
+ src/hb-ot-shape-complex-myanmar-machine.hh | 196 +++++-----
+ src/hb-ot-shape-complex-myanmar-machine.rl |   4 +-
+ src/hb-ot-shape-complex-use-machine.hh     | 602 +++++++++++++++--------------
+ src/hb-ot-shape-complex-use-machine.rl     |  11 +-
+ src/hb-ot-shape-complex-use-table.cc       |   2 +-
+ 6 files changed, 433 insertions(+), 391 deletions(-)
+
+commit 92588782d7a45e0c023c5f48cbd19b11cfa8f0d2
+Author: Ebrahim Byagowi <ebrahim@gnu.org>
+Date:   Tue Apr 30 13:05:10 2019 -0700
+
+    Remove space between right angle brackets now that we have C++11 (#1689)
+
+ src/hb-aat-layout-ankr-table.hh |  2 +-
+ src/hb-aat-layout-common.hh     | 14 +++----
+ src/hb-aat-layout-just-table.hh |  4 +-
+ src/hb-aat-layout-kerx-table.hh | 14 +++----
+ src/hb-aat-layout-lcar-table.hh |  2 +-
+ src/hb-aat-layout-morx-table.hh | 14 +++----
+ src/hb-aat-layout-trak-table.hh |  2 +-
+ src/hb-aat-ltag-table.hh        |  2 +-
+ src/hb-cff-interp-cs-common.hh  |  2 +-
+ src/hb-cff1-interp-cs.hh        |  2 +-
+ src/hb-cff2-interp-cs.hh        |  2 +-
+ src/hb-iter.hh                  |  4 +-
+ src/hb-null.hh                  |  8 ++--
+ src/hb-open-file.hh             |  8 ++--
+ src/hb-open-type.hh             |  8 ++--
+ src/hb-ot-color-cbdt-table.hh   |  2 +-
+ src/hb-ot-color-colr-table.hh   |  4 +-
+ src/hb-ot-color-cpal-table.hh   |  8 ++--
+ src/hb-ot-color-sbix-table.hh   |  2 +-
+ src/hb-ot-color-svg-table.hh    |  4 +-
+ src/hb-ot-kern-table.hh         |  6 +--
+ src/hb-ot-layout-base-table.hh  |  2 +-
+ src/hb-ot-layout-common.hh      | 10 ++---
+ src/hb-ot-layout-gdef-table.hh  |  4 +-
+ src/hb-ot-layout-gpos-table.hh  |  6 +--
+ src/hb-ot-layout-gsub-table.hh  | 18 ++++-----
+ src/hb-ot-layout-gsubgpos.hh    | 86 ++++++++++++++++++++---------------------
+ src/hb-ot-math-table.hh         |  2 +-
+ src/hb-ot-name-table.hh         | 10 ++---
+ src/hb-ot-stat-table.hh         |  4 +-
+ src/hb-subset-cff1.cc           |  2 +-
+ src/test-iter.cc                | 10 ++---
+ 32 files changed, 134 insertions(+), 134 deletions(-)
+
+commit f27fdca4aa438ec366ee17370fbc9fdeb962c397
+Author: Ebrahim Byagowi <ebrahim@gnu.org>
+Date:   Tue Apr 30 13:01:04 2019 -0700
+
+    [doc] Add documentation to hb_color_get_* and hb_directwrite_face_* (#1690)
+
+ src/hb-common.cc      | 12 ++++++++----
+ src/hb-directwrite.cc |  8 ++++++--
+ 2 files changed, 14 insertions(+), 6 deletions(-)
+
+commit fe4a0ac707802b5bb36787723f8d55a58c2946a5
+Author: David Corbett <corbett.dav@husky.neu.edu>
+Date:   Tue Apr 30 13:35:50 2019 -0400
+
+    Fix some dead links
+
+ src/gen-os2-unicode-ranges.py      | 2 +-
+ src/gen-use-table.py               | 6 +++---
+ src/hb-ot-shape-complex-myanmar.hh | 2 +-
+ 3 files changed, 5 insertions(+), 5 deletions(-)
+
+commit 68749e996aedbae9b1c4553f5672f74e1727b850
+Author: Nathan Willis <nwillis@glyphography.com>
+Date:   Tue Apr 30 17:23:55 2019 +0100
+
+    [Docs] Usermanual; update XML manifest for new chapters.
+
+ docs/Makefile.am       | 4 ++--
+ docs/harfbuzz-docs.xml | 4 ++--
+ 2 files changed, 4 insertions(+), 4 deletions(-)
+
+commit 30d7d1064ee339ca216699851030f9bae8c07c68
+Author: Nathan Willis <nwillis@glyphography.com>
+Date:   Tue Apr 30 17:23:19 2019 +0100
+
+    [Docs] Usermanual; add Utilities chapter.
+
+ docs/usermanual-utilities.xml | 244 ++++++++++++++++++++++++++++++++++++++++++
+ 1 file changed, 244 insertions(+)
+
+commit d0f5a05aef73293fe21ddb022084166a7a095862
+Author: Nathan Willis <nwillis@glyphography.com>
+Date:   Tue Apr 30 17:22:54 2019 +0100
+
+    [Docs] Usermanual; add Shaping, Features, and Plans.
+
+ docs/usermanual-opentype-features.xml | 279 +++++++++++++++++++++++++++++++++-
+ 1 file changed, 277 insertions(+), 2 deletions(-)
+
+commit 8354c99fbee2887cb71440f4e25ad1e6f46b2592
+Author: Nathan Willis <nwillis@glyphography.com>
+Date:   Tue Apr 30 17:22:08 2019 +0100
+
+    [Docs] Usermanual; add Fonts And Faces chapter.
+
+ docs/usermanual-fonts-and-faces.xml | 445 +++++++++++++++++++++++++++++++++++-
+ 1 file changed, 437 insertions(+), 8 deletions(-)
+
+commit 3b301c5ac6b15728f858cb6f5de8dfc6a77209fa
+Author: Nathan Willis <nwillis@glyphography.com>
+Date:   Tue Apr 30 17:21:33 2019 +0100
+
+    [Docs] Usermanual; fill out Buffers chapter.
+
+ ...anual-buffers-language-script-and-direction.xml | 358 +++++++++++++++++++--
+ 1 file changed, 335 insertions(+), 23 deletions(-)
+
+commit 6d9a86ae7535ea8e3c108a49c6da877a78cdac26
+Author: Nathan Willis <nwillis@glyphography.com>
+Date:   Tue Apr 30 16:09:01 2019 +0100
+
+    [Docs] Usermanual; fixes to Object Model chapter
+
+ docs/usermanual-object-model.xml | 35 ++++++++++++++++++++++-------------
+ 1 file changed, 22 insertions(+), 13 deletions(-)
+
+commit 9542bdd0ed2d581cdb4bd950ac3cd7e3bf899478
+Author: Ebrahim Byagowi <ebrahim@gnu.org>
+Date:   Mon Apr 29 14:52:28 2019 -0700
+
+    Add color channels getters ABI (#1513)
+    
+    So can be used with language wrappers
+
+ src/hb-common.cc | 53 +++++++++++++++++++++++++++++++++++++++++++++++++++++
+ src/hb-common.h  | 40 +++++++++++-----------------------------
+ 2 files changed, 64 insertions(+), 29 deletions(-)
+
+commit e200d165a4e8a5f901165c705d617b6e457ec595
+Author: Ebrahim Byagowi <ebrahim@gnu.org>
+Date:   Tue Apr 30 02:10:50 2019 +0430
+
+    [ci] Remove crosscompile-notest-freebsd9 bot
+    
+    It was testing an old version of freebsd and now it's image is gone.
+    We really like to test the environment.
+
+ .circleci/config.yml | 10 ----------
+ 1 file changed, 10 deletions(-)
+
+commit 4aa546b70ad7b11154b901e67f98c1ec6bc5c364
+Author: David Corbett <corbett.dav@husky.neu.edu>
+Date:   Mon Apr 29 14:16:51 2019 -0400
+
+    Allow some Balinese Po & So as aksara modre bases
+
+ src/gen-use-table.py                 | 10 ++++++++--
+ src/hb-ot-shape-complex-use-table.cc |  4 ++--
+ 2 files changed, 10 insertions(+), 4 deletions(-)
+
+commit 6d6edc8b25395c87477181a647a8e6d02f2cad4f
+Author: Ebrahim Byagowi <ebrahim@gnu.org>
+Date:   Sun Apr 28 11:54:07 2019 -0700
+
+    [valgrind] Use libtool and support run-subset-fuzzer-tests (#1668)
+
+ test/fuzzing/Makefile.am                |  4 +-
+ test/fuzzing/run-shape-fuzzer-tests.py  | 28 ++++++------
+ test/fuzzing/run-subset-fuzzer-tests.py | 75 ++++++++++++++++++++++++++++++---
+ 3 files changed, 85 insertions(+), 22 deletions(-)
+
+commit 62c6e170728303f4225aaa25523675fc260ae1ab
+Author: Ebrahim Byagowi <ebrahim@gnu.org>
+Date:   Sun Apr 28 10:55:07 2019 -0700
+
+    [test] Add crbug.com/oss-fuzz/14474 testcase
+    
+    Fixed at 6977a95f
+
+ ...testcase-minimized-hb-subset-fuzzer-5716947896893440 | Bin 0 -> 65833 bytes
+ 1 file changed, 0 insertions(+), 0 deletions(-)
+
+commit 6977a95fed8a35d6e915ed3fc3a3ea8709f3d4a4
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Sat Apr 27 10:05:25 2019 -0700
+
+    [subset] Don't crash if subsetting GSUB/GPOS fails
+    
+    Fixes fuzzer issue.
+
+ src/hb-subset.cc | 27 ++++++++++++++-------------
+ 1 file changed, 14 insertions(+), 13 deletions(-)
+
+commit 2b051e7aa147c78cfbf953b6f0eb18c25b732eb2
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Sat Apr 27 10:01:11 2019 -0700
+
+    [subset] Check error after calling serializer end
+
+ src/hb-subset.cc | 5 ++---
+ 1 file changed, 2 insertions(+), 3 deletions(-)
+
+commit 750b65e9a980efc13e50ea5d0388ecf06e7a93b1
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Fri Apr 26 17:14:25 2019 -0700
+
+    [meta] Add hb_type_identity<>
+    
+    To block template argument deduction.
+
+ src/hb-meta.hh | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+commit 8c8922a019eb1ceb8beffc05ca638ee0ca25b565
+Author: Qunxin Liu <qxliu@google.com>
+Date:   Thu Apr 25 09:17:58 2019 -0700
+
+    [subset] Updates due to changes in resolve_links() on master branch
+
+ src/Makefile.sources    | 1 +
+ src/hb-ot-name-table.hh | 7 +++++--
+ src/hb-static.cc        | 3 +--
+ 3 files changed, 7 insertions(+), 4 deletions(-)
+
+commit 2f6ec35344db08d0c892152bc7a7eaa67e7c03f0
+Author: Garret Rieger <grieger@google.com>
+Date:   Wed Apr 24 15:15:36 2019 -0700
+
+    Move implementations of hb-ot-name-language.cc into a hb-static.cc
+
+ src/hb-aat-layout.hh              |   1 -
+ src/hb-ot-name-language-static.hh | 462 ++++++++++++++++++++++++++++++++++++++
+ src/hb-ot-name-language.hh        | 432 +----------------------------------
+ src/hb-static.cc                  |   2 +
+ 4 files changed, 468 insertions(+), 429 deletions(-)
+
+commit 19afd25004487cfaa7b487b1768b4dae1ab37296
+Author: Qunxin Liu <qxliu@google.com>
+Date:   Wed Apr 24 14:02:29 2019 -0700
+
+    [subset] Update to use _subset2() for name table
+
+ src/hb-ot-name-table.hh | 47 ++++++++++-------------------------------------
+ src/hb-subset.cc        |  4 ++--
+ 2 files changed, 12 insertions(+), 39 deletions(-)
+
+commit 1ca4b5c77012ed586413f39e730b03bf965e1305
+Author: Qunxin Liu <qxliu@google.com>
+Date:   Mon Apr 22 11:31:23 2019 -0700
+
+    [subset] Add unit test for str de-dup
+    Also move the implementation of some methods from the .cc to the .hh
+
+ src/Makefile.sources                   |   1 -
+ src/hb-aat-layout.cc                   |   8 -
+ src/hb-aat-layout.hh                   |   9 +-
+ src/hb-ot-name-language.cc             | 457 ---------------------------------
+ src/hb-ot-name-language.hh             | 432 ++++++++++++++++++++++++++++++-
+ test/api/fonts/nameID.dup.expected.ttf | Bin 0 -> 2340 bytes
+ test/api/fonts/nameID.dup.origin.ttf   | Bin 0 -> 170680 bytes
+ test/api/test-subset-nameids.c         |  21 ++
+ 8 files changed, 456 insertions(+), 472 deletions(-)
+
+commit 9ad14f56b6cf2a345104b3a897b52a1f4c0f33a5
+Author: Qunxin Liu <qxliu@google.com>
+Date:   Tue Apr 16 11:20:58 2019 -0700
+
+    [subset] update name table subsetting with new serializer
+
+ src/hb-ot-name-table.hh | 126 ++++++++++++++++++++++++++++--------------------
+ 1 file changed, 75 insertions(+), 51 deletions(-)
+
+commit 6faac8df83bb59f08e5d329e76435ba438b2ea54
+Author: Qunxin Liu <qxliu@google.com>
+Date:   Wed Apr 10 16:38:35 2019 -0700
+
+    [subset] Subsetting Name Table Step 4
+    Add unit test and integration test
+
+ test/api/Makefile.am                               |   2 +
+ test/api/fonts/nameID.expected.ttf                 | Bin 0 -> 170696 bytes
+ test/api/fonts/nameID.origin.ttf                   | Bin 0 -> 170976 bytes
+ test/api/hb-subset-test.h                          |   9 ++++
+ test/api/test-subset-nameids.c                     |  58 +++++++++++++++++++++
+ .../Roboto-Regular.abc.name-ids.61,62,63.ttf       | Bin 0 -> 2168 bytes
+ .../basics/Roboto-Regular.abc.name-ids.61,63.ttf   | Bin 0 -> 1988 bytes
+ .../basics/Roboto-Regular.abc.name-ids.61.ttf      | Bin 0 -> 1792 bytes
+ .../basics/Roboto-Regular.abc.name-ids.62.ttf      | Bin 0 -> 1740 bytes
+ .../basics/Roboto-Regular.abc.name-ids.63.ttf      | Bin 0 -> 1716 bytes
+ test/subset/data/profiles/name-ids.txt             |   1 +
+ test/subset/data/tests/basics.tests                |   1 +
+ 12 files changed, 71 insertions(+)
+
+commit e501ea143d1e63974903cdb41932c50f4222ff4e
+Author: Qunxin Liu <qxliu@google.com>
+Date:   Fri Apr 5 10:05:55 2019 -0700
+
+    [subset] Subset name table step 3, add --nameids option to guide the
+    selection of which name records to keep in the subset method.
+
+ src/hb-ot-name-table.hh | 28 ++++++++++++++++------------
+ src/hb-subset-input.cc  |  8 ++++++++
+ src/hb-subset-input.hh  |  3 ++-
+ src/hb-subset-plan.cc   | 10 ++++++----
+ src/hb-subset-plan.hh   |  3 +++
+ src/hb-subset.h         |  3 +++
+ util/hb-subset.cc       |  1 +
+ util/options.cc         | 45 +++++++++++++++++++++++++++++++++++++++++++++
+ util/options.hh         |  8 ++++++++
+ 9 files changed, 92 insertions(+), 17 deletions(-)
+
+commit 2637a81615c80443911a603cbd161ade525c79f1
+Author: Qunxin Liu <qxliu@google.com>
+Date:   Tue Apr 2 13:38:27 2019 -0700
+
+    [subset] subset name table step 2, add implementation for collecting subset
+    elements and serialize method
+
+ src/hb-ot-name-table.hh | 131 ++++++++++++++++++++++++++++++++++++++++--------
+ 1 file changed, 109 insertions(+), 22 deletions(-)
+
+commit 408c1daeb4ff86d2204ed1bdd059513357ada392
+Author: Qunxin Liu <qxliu@google.com>
+Date:   Fri Mar 29 10:34:32 2019 -0700
+
+    [subset] subset name table step 1,  write out table unmodified, use accelerator to access
+    string
+
+ src/hb-ot-name-table.hh | 53 +++++++++++++++++++++++++++++++++++++++++++++++++
+ src/hb-subset.cc        |  4 ++++
+ 2 files changed, 57 insertions(+)
+
+commit 3a7f5bdd18314676425ec811199767a5f8e65a40
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Fri Apr 26 14:40:01 2019 -0700
+
+    Rewrite hb_is_signed()
+
+ src/hb-meta.hh | 20 +++++++++++---------
+ 1 file changed, 11 insertions(+), 9 deletions(-)
+
+commit 73c82f2301a52cf2111296b34691bc898a7a6363
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Fri Apr 26 13:16:48 2019 -0700
+
+    [iter] Fix hb_is_iterator_of() to actually check item type
+
+ src/hb-iter.hh | 20 +++++++++-----------
+ 1 file changed, 9 insertions(+), 11 deletions(-)
+
+commit c51f15ddfcae8578483693b761b81ceaebf05f2a
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Fri Apr 26 13:03:41 2019 -0700
+
+    [array] Adjust hb_sorted_array_t copy constructor/assignment to match hb_array_t
+
+ src/hb-array.hh | 13 ++++++++++---
+ 1 file changed, 10 insertions(+), 3 deletions(-)
+
+commit b2758c360cc08d7a0334aae11845d0c5d50c46af
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Fri Apr 26 12:58:06 2019 -0700
+
+    [array] Use hb_is_cr_convertible_to()
+
+ src/hb-array.hh | 14 ++------------
+ 1 file changed, 2 insertions(+), 12 deletions(-)
+
+commit 8ecae793aa79056a312d3c8518106cfeca42390e
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Fri Apr 26 12:57:56 2019 -0700
+
+    [meta] Add hb_is_cr_convertible_to()
+
+ src/hb-meta.hh | 5 +++++
+ 1 file changed, 5 insertions(+)
+
+commit 52bb0346d319c322f117567a096fafa1bc804e26
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Fri Apr 26 12:52:28 2019 -0700
+
+    [meta] Add hb_decay<>
+
+ src/hb-meta.hh | 2 ++
+ 1 file changed, 2 insertions(+)
+
+commit 474f3587cd18fdaf86b2068647fa03b107557d8c
+Author: Michiharu Ariza <ariza@adobe.com>
+Date:   Fri Apr 26 10:12:38 2019 -0700
+
+    copy retain_gids from input to plan
+
+ src/hb-subset-plan.cc | 1 +
+ src/hb-subset-plan.hh | 1 +
+ 2 files changed, 2 insertions(+)
+
+commit 3fc066314ac19005ea8157a6541412cfd24abbc2
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Wed Apr 24 16:41:57 2019 -0700
+
+    Another try at fixing cmake build
+
+ CMakeLists.txt | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit c69f02784ac53a7fd13eee559559b38d8224ef59
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Wed Apr 24 16:31:37 2019 -0700
+
+    Fix sign-compare error on 32-bit systems
+
+ src/hb-open-type.hh | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit f2d20dd9d3b52f434f5fe9dbef82bd95eb499edf
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Wed Apr 24 15:08:27 2019 -0700
+
+    [THANKS] Add Ivan Kuckir <https://photopea.com/>
+    
+    https://github.com/harfbuzz/harfbuzz/issues/1633#issuecomment-485764140
+
+ THANKS | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 0ca358f21a2a6e86a3d5c145a70bb84ab6e2db32
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Wed Apr 24 16:36:29 2019 -0400
+
+    Try fixing cmake build
+
+ CMakeLists.txt | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 59a8fa53533b10b9c25458d9ba2d68b7b01c3ff0
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Wed Apr 24 12:19:13 2019 -0400
+
+    [iter] Add tests for casting to hb_iter_t<> base class for hb_sorted_array_t<>
+    
+    Something's phishy about hb_sorted_array_t<>.  Can't get it work nicely with
+    change I'm making.  Ugh..
+
+ src/test-iter.cc | 7 ++++++-
+ 1 file changed, 6 insertions(+), 1 deletion(-)
+
+commit 714307cc437f375f128e17e5ab01eba0c57aaf01
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Wed Apr 24 10:56:12 2019 -0400
+
+    [iter] Remove fixed TODO
+
+ src/hb-iter.hh | 3 ---
+ 1 file changed, 3 deletions(-)
+
+commit 22da12318a3e9fd9955f24fd0092de1a4a1a940d
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Wed Apr 24 10:53:16 2019 -0400
+
+    [map] Fix TODO
+
+ src/hb-map.hh           | 6 ++----
+ src/hb-meta.hh          | 6 ++++++
+ src/hb-ot-cff1-table.cc | 1 -
+ src/hb-ot-cff2-table.cc | 1 -
+ src/hb.hh               | 3 +--
+ 5 files changed, 9 insertions(+), 8 deletions(-)
+
+commit 4c6136e976af4f7332f703f5a7625505ffc296b6
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Wed Apr 24 10:44:24 2019 -0400
+
+    [mutex] Remove TODO
+
+ src/hb-mutex.hh | 2 --
+ 1 file changed, 2 deletions(-)
+
+commit 0268db11965d022883d5ef2ef828c0635165b7bd
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Wed Apr 24 10:43:40 2019 -0400
+
+    [map] Use hb_invoke() with pointer-to-method
+
+ src/hb-algs.hh   | 5 ++++-
+ src/hb-map.hh    | 4 ++--
+ src/test-algs.cc | 8 ++++++++
+ 3 files changed, 14 insertions(+), 3 deletions(-)
+
+commit 8f79a5750e8982f9ab73c0dc6a8534dffef74610
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Wed Apr 24 10:32:49 2019 -0400
+
+    [algs] Add more hb_forward<>()'s
+
+ src/hb-algs.hh | 10 +++++-----
+ 1 file changed, 5 insertions(+), 5 deletions(-)
+
+commit 42526d1697e2449fa23741f84721dcf2ce688af7
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Wed Apr 24 10:24:33 2019 -0400
+
+    [serialize] Fix SingleSubstFormat1 failure
+
+ src/hb-ot-layout-gsub-table.hh | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+commit 6cc9707c9c0885a3133b7844f615cdcdaeccec18
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Wed Apr 24 10:22:06 2019 -0400
+
+    [serialize] Rename
+
+ src/hb-serialize.hh | 8 +++-----
+ 1 file changed, 3 insertions(+), 5 deletions(-)
+
+commit 085793d6cd35a1590a66712f39260030367490db
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Wed Apr 24 10:15:59 2019 -0400
+
+    Remove wrong TODOs
+
+ src/hb-ot-layout-gsubgpos.hh       | 2 +-
+ src/hb-ot-shape-complex-indic.cc   | 1 -
+ src/hb-ot-shape-complex-khmer.cc   | 4 ++--
+ src/hb-ot-shape-complex-myanmar.cc | 3 ++-
+ src/hb-ot-shape-complex-use.cc     | 4 ++--
+ 5 files changed, 7 insertions(+), 7 deletions(-)
+
+commit 915b9ea5f48d56df21419761477b2d4ba2843b54
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Wed Apr 24 10:07:19 2019 -0400
+
+    [serialize] Add c->check_assign()
+    
+    To check for assignment overflows.
+
+ src/hb-open-type.hh            |  7 +++----
+ src/hb-ot-layout-gsub-table.hh |  2 +-
+ src/hb-serialize.hh            | 20 +++++++++++++-------
+ 3 files changed, 17 insertions(+), 12 deletions(-)
+
+commit 00a00bc1f23c681d64fbd4df33582ec0165e337a
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Wed Apr 24 10:01:30 2019 -0400
+
+    Fix two TODOs
+
+ src/hb-ot-layout-gsub-table.hh | 11 +++++------
+ 1 file changed, 5 insertions(+), 6 deletions(-)
+
+commit 11ab889a8d743304c8ec17920e209a514f46739d
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Wed Apr 24 09:55:24 2019 -0400
+
+    Rename a few test programs
+
+ src/Makefile.am                                    | 24 +++++++++++-----------
+ ...est-size-params.cc => test-gpos-size-params.cc} |  0
+ ...substitute.cc => test-gsub-would-substitute.cc} |  0
+ src/{test-name-table.cc => test-ot-name.cc}        |  0
+ 4 files changed, 12 insertions(+), 12 deletions(-)
+
+commit 12017db0bfe62e7777e1ab6ba5b14729dcd4c351
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Wed Apr 24 09:24:38 2019 -0400
+
+    Move test code around
+
+ src/test-algs.cc | 8 ++++++++
+ src/test-iter.cc | 9 ---------
+ 2 files changed, 8 insertions(+), 9 deletions(-)
+
+commit 27377a7e287dd39e3f7caad5c1e0691ae381ccf8
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Wed Apr 24 09:22:14 2019 -0400
+
+    Rely on variadic parameter pack more
+
+ src/hb-open-type.hh | 16 ++++++++--------
+ 1 file changed, 8 insertions(+), 8 deletions(-)
+
+commit 3ad20c38ade76aca8aed024014977ecb5f2b636e
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Wed Apr 24 09:09:00 2019 -0400
+
+    [serialize] Fix a few overflow TODO items
+
+ src/hb-open-type.hh | 7 ++++---
+ 1 file changed, 4 insertions(+), 3 deletions(-)
+
+commit 175bdad8bff5b0e9732ab1fb97617a9293680fd4
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Tue Apr 23 23:57:11 2019 -0400
+
+    One more variadic parameter pack use
+
+ src/hb-aat-layout-common.hh | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+commit 441cca235477a5399af214c9ac85320d4de69f0b
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Tue Apr 23 23:49:21 2019 -0400
+
+    Use hb_forward() when forwarding parameter pack
+
+ src/hb-open-type.hh | 32 ++++++++++++++++----------------
+ src/hb-serialize.hh |  3 ++-
+ 2 files changed, 18 insertions(+), 17 deletions(-)
+
+commit 20f3134789f65b10f301c4635c9f80c2dda0fb97
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Tue Apr 23 12:58:52 2019 -0400
+
+    Use variadic templates in OffsetTo<> and various ArrayOf<>s
+
+ src/hb-open-type.hh | 145 ++++++++++++++++++----------------------------------
+ 1 file changed, 49 insertions(+), 96 deletions(-)
+
+commit aa6692cb0079bbe1e003f211a321e8fe6a18ea94
+Author: Nathan Willis <nwillis@glyphography.com>
+Date:   Tue Apr 23 17:56:44 2019 +0100
+
+    Usermanual: update Makefile SGML list. Again.
+
+ docs/Makefile.am | 1 +
+ 1 file changed, 1 insertion(+)
+
+commit 98c54cdef8b0615a95382bdba4ecd008789f8c9e
+Author: Nathan Willis <nwillis@glyphography.com>
+Date:   Tue Apr 23 17:48:42 2019 +0100
+
+    Usermanual: add chapter on object model.
+
+ docs/harfbuzz-docs.xml           |   1 +
+ docs/usermanual-object-model.xml | 249 +++++++++++++++++++++++++++++++++++++++
+ 2 files changed, 250 insertions(+)
+
+commit 64ca2ffa4c88b961dcbd9d06be8ac7dd80ad8182
+Author: Ebrahim Byagowi <ebrahim@gnu.org>
+Date:   Tue Apr 23 01:10:46 2019 -0700
+
+    Fix clang's -Wmain complain (#1678)
+
+ src/test-iter.cc | 8 +++++++-
+ 1 file changed, 7 insertions(+), 1 deletion(-)
+
+commit 7c218351ab45c41e48147b2196393357f7b551d4
+Author: Ebrahim Byagowi <ebrahim@gnu.org>
+Date:   Tue Apr 23 12:40:29 2019 +0430
+
+    .editorconfig, minor
+    
+    still doesn't work with vscode
+
+ .editorconfig | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 25dd88efc6521b972babe1067c0de1b9d4f5dbe5
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Mon Apr 22 17:45:23 2019 -0400
+
+    Err, fix hb_invoke() variadic
+
+ src/hb-algs.hh   | 6 +++---
+ src/test-iter.cc | 5 ++++-
+ 2 files changed, 7 insertions(+), 4 deletions(-)
+
+commit c862a532df0bc3ce0b47f3fde9bf1dd300ff8bee
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Mon Apr 22 17:32:19 2019 -0400
+
+    Add variadic arguments to hb_invoke()
+
+ src/hb-algs.hh | 22 +++++++++++-----------
+ 1 file changed, 11 insertions(+), 11 deletions(-)
+
+commit 9c724e48a2f5d61c31c79f0b4660f08e5d07db10
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Mon Apr 22 15:37:10 2019 -0400
+
+    [serializer] Add err_propagaged_error()
+
+ src/hb-serialize.hh | 5 ++++-
+ 1 file changed, 4 insertions(+), 1 deletion(-)
+
+commit ae8da4b61b4cc3b55242b85fe7c63393d65bd6cf
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Mon Apr 22 15:25:11 2019 -0400
+
+    Minor
+
+ src/hb-iter.hh | 9 ++++++---
+ 1 file changed, 6 insertions(+), 3 deletions(-)
+
+commit 24da1d08603a7fe262ae88d687986efc0343956f
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Mon Apr 22 15:20:25 2019 -0400
+
+    Use variadic template args for propagate_error()
+    
+    Let's see if bots happy.
+    
+    Not sure where else we can use these.  Mm.  Maybe in hb_invoke().
+
+ src/hb-serialize.hh | 7 ++-----
+ 1 file changed, 2 insertions(+), 5 deletions(-)
+
+commit 9bab398462fa598047f34fd6d23e07a91305b1b3
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Mon Apr 22 15:16:35 2019 -0400
+
+    Simplify propagate_error()
+
+ src/hb-serialize.hh | 12 ++++++------
+ 1 file changed, 6 insertions(+), 6 deletions(-)
+
+commit ecac94ca763e80d217ba5db429745e8882b38464
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Sun Apr 21 12:27:32 2019 -0400
+
+    [docs] Remove fdo repo
+    
+    Has not been updated.
+
+ docs/harfbuzz-docs.xml | 6 +-----
+ 1 file changed, 1 insertion(+), 5 deletions(-)
+
+commit 8ed7655be89c658219ab702e34a79734ba0efb73
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Sun Apr 21 12:25:19 2019 -0400
+
+    Update AUTHORS / COPYING
+
+ AUTHORS | 3 +++
+ COPYING | 3 ++-
+ 2 files changed, 5 insertions(+), 1 deletion(-)
+
+commit a464cbeecea73aeaa03c262f49fed8584057d9bb
+Author: Ebrahim Byagowi <ebrahim@gnu.org>
+Date:   Fri Apr 19 12:14:09 2019 -0700
+
+    Revert "Add harfbuzzjs build configuration (#1636)" (#1675)
+    
+    This reverts commit 694cb1beeefe1c54b2e613d2d566a21e248a2c9c.
+
+ CMakeLists.txt | 35 -----------------------------------
+ 1 file changed, 35 deletions(-)
+
+commit 694cb1beeefe1c54b2e613d2d566a21e248a2c9c
+Author: Ebrahim Byagowi <ebrahim@gnu.org>
+Date:   Fri Apr 19 07:51:04 2019 -0700
+
+    Add harfbuzzjs build configuration (#1636)
+
+ CMakeLists.txt | 35 +++++++++++++++++++++++++++++++++++
+ 1 file changed, 35 insertions(+)
+
+commit 42f4bd6b801f96fc33a365db8ab6390e74cef05a
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Thu Apr 18 19:04:59 2019 -0400
+
+    Minor warning fix again
+
+ src/hb-ot-map.cc        | 20 ++++++++++----------
+ test/api/test-ot-face.c |  2 +-
+ 2 files changed, 11 insertions(+), 11 deletions(-)
+
+commit 267fb9c7163e61c9cdbafbb16005bc659ec5a4a2
+Author: Michiharu Ariza <ariza@adobe.com>
+Date:   Thu Apr 18 15:17:10 2019 -0700
+
+    add spaces
+
+ src/hb-ot-cff1-table.hh | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+commit ba0386060d92dffcde2d14f9e523a46ea8713de2
+Author: Michiharu Ariza <ariza@adobe.com>
+Date:   Thu Apr 18 14:53:35 2019 -0700
+
+    fix oss-fuzz issue 14345
+
+ src/hb-ot-cff1-table.hh                                 |   3 ++-
+ ...testcase-minimized-hb-subset-fuzzer-5923632099885056 | Bin 0 -> 25847 bytes
+ 2 files changed, 2 insertions(+), 1 deletion(-)
+
+commit 63a2108480cca2d9c1a2f61d6642d70496f1a5e3
+Author: Michiharu Ariza <ariza@adobe.com>
+Date:   Thu Apr 18 13:54:58 2019 -0700
+
+    silence MVC warnings 3rd attempt
+
+ src/hb-ot-cff1-table.cc | 5 +++--
+ src/hb-ot-cff2-table.cc | 9 +++++----
+ 2 files changed, 8 insertions(+), 6 deletions(-)
+
+commit 705dde57fe7bd5aafe93f284db2aa809aad932dc
+Author: Michiharu Ariza <ariza@adobe.com>
+Date:   Thu Apr 18 11:32:10 2019 -0700
+
+    silence MVC warnings 2nd attempt
+
+ src/hb-ot-cff1-table.cc | 4 ++--
+ src/hb-ot-cff2-table.cc | 8 ++++----
+ 2 files changed, 6 insertions(+), 6 deletions(-)
+
+commit dd4c37529bcecee33d43015a852a3fcf9e978b7f
+Author: Michiharu Ariza <ariza@adobe.com>
+Date:   Thu Apr 18 10:38:57 2019 -0700
+
+    silence MVC warnings
+
+ src/hb-cff-interp-common.hh | 2 +-
+ src/hb-ot-cff1-table.cc     | 4 ++--
+ src/hb-ot-cff2-table.cc     | 8 ++++----
+ 3 files changed, 7 insertions(+), 7 deletions(-)
+
+commit 518e6e07f29d9bb7e532313fb0af6177d8022ea5
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Thu Apr 18 12:21:25 2019 -0400
+
+    Minor
+
+ src/hb-ot-map.cc | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 91d958acc08cb99ddd3b656922e13497b9d1595d
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Thu Apr 18 10:04:10 2019 -0400
+
+    [array] Simplify copy assignment/constructor
+    
+    To fix bogus MSVC warnings:
+    
+      c:\projects\harfbuzz\src\hb-array.hh(189): warning C4521: 'hb_array_t<Type>': multiple copy constructors specified [C:\projects\harfbuzz\build\harfbuzz.vcxproj]
+      c:\projects\harfbuzz\src\hb-array.hh(189): warning C4522: 'hb_array_t<Type>': multiple assignment operators specified [C:\projects\harfbuzz\build\harfbuzz.vcxproj]
+
+ src/hb-array.hh | 29 +++++++++++++++++++----------
+ 1 file changed, 19 insertions(+), 10 deletions(-)
+
+commit 693d91cd49fda3e728b59e6885bea8d7b01958ef
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Wed Apr 17 17:59:39 2019 -0400
+
+    [serialize] Fix offset calculation
+
+ src/hb-serialize.hh | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit db0c9a1485ae6ca7ca9af38a43504f1ae4ea09c8
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Wed Apr 17 17:58:13 2019 -0400
+
+    [subset] Assert offsets are zero during relocation
+    
+    If they're not, it's a bug in our subsetting logic somewhere.  So check.
+
+ src/hb-serialize.hh | 2 ++
+ 1 file changed, 2 insertions(+)
+
+commit efbba7ad26dda5930f5d1bd5292304835432f504
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Wed Apr 17 11:00:08 2019 -0400
+
+    [serializer] Add copy()
+    
+    Calls obj.copy() or obj.operator=() in that order.
+
+ src/hb-serialize.hh | 18 ++++++++++++++++++
+ 1 file changed, 18 insertions(+)
+
+commit c67a0d581fcc50df5563c23060b4fcd9dac4c87c
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Wed Apr 17 10:20:02 2019 -0400
+
+    Add HB_RETURN
+
+ src/hb-algs.hh | 13 ++++++-------
+ src/hb-meta.hh | 34 ++++++++++++++++++++--------------
+ 2 files changed, 26 insertions(+), 21 deletions(-)
+
+commit 6745a600bfec13b3f5468b3d31bab7d82b1e61ce
+Author: David Corbett <corbett.dav@husky.neu.edu>
+Date:   Tue Apr 16 17:29:34 2019 -0400
+
+    Comment out ot_languages where fallback suffices
+
+ src/gen-tag-table.py   |  15 +-
+ src/hb-ot-tag-table.hh | 443 +++++++++++++++++++++++++------------------------
+ src/hb-ot-tag.cc       |  19 ++-
+ test/api/test-ot-tag.c |   5 +-
+ 4 files changed, 255 insertions(+), 227 deletions(-)
+
+commit 5daeff3e68e4e202effb152f52702a044c09f386
+Author: David Corbett <corbett.dav@husky.neu.edu>
+Date:   Wed Apr 17 09:11:44 2019 -0400
+
+    Fix "hb_script_" doc typo
+
+ src/hb-common.cc | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 6916b77863cd5ce492a274eb85f196f2152fbb96
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Tue Apr 16 18:33:51 2019 -0400
+
+    One more auto return type
+
+ src/hb-iter.hh | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+commit 5b33427f2c4d596a12f05ffebebfd68655fd63eb
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Tue Apr 16 18:28:17 2019 -0400
+
+    Rename HB_AUTO_RETURN_EXPR to HB_AUTO_RETURN
+
+ src/hb-algs.hh | 34 +++++++++++++++++-----------------
+ src/hb-meta.hh |  8 ++++----
+ 2 files changed, 21 insertions(+), 21 deletions(-)
+
+commit da293b0e59a0d6c47e9b3a7807115a168a0a5c94
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Tue Apr 16 18:27:25 2019 -0400
+
+    Use HB_AUTO_RETURN_EXPR in hb_min/max
+
+ src/hb-algs.hh | 8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+commit 0241a40f2aff43aba045fb7de4a2c3e5f1e9626a
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Tue Apr 16 18:26:30 2019 -0400
+
+    Use auto return type for hb_first/hb_second
+
+ src/hb-algs.hh | 8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+commit fe30fcd228ff95be1f169f580b30184c8511d1c3
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Tue Apr 16 17:34:06 2019 -0400
+
+    Use hb_deref_pointer() to reduce number of overloads
+
+ src/hb-algs.hh | 27 ++++++++++-----------------
+ src/hb-meta.hh | 36 +++++++++++++++++++-----------------
+ 2 files changed, 29 insertions(+), 34 deletions(-)
+
+commit c918a6706fa759696569ad6dcaae03fed76306bc
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Tue Apr 16 17:28:18 2019 -0400
+
+    Properly prioritize hb_hash()
+
+ src/hb-algs.hh | 46 +++++++++++++++++++++++-----------------------
+ 1 file changed, 23 insertions(+), 23 deletions(-)
+
+commit 75fd845a4abccc2596f0e1fe2294f936199e61f3
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Tue Apr 16 17:22:29 2019 -0400
+
+    Move around
+
+ src/hb-algs.hh | 25 ++++++++++++-------------
+ 1 file changed, 12 insertions(+), 13 deletions(-)
+
+commit 973717175d46d62471772318bb0b607070c53ec7
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Tue Apr 16 16:50:07 2019 -0400
+
+    Fix priorities
+
+ src/hb-algs.hh | 10 +++++-----
+ 1 file changed, 5 insertions(+), 5 deletions(-)
+
+commit 54ece299bcb3436763cc4f3b6b0ca11de8133b28
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Tue Apr 16 16:45:53 2019 -0400
+
+    Use type aliasing for meta-functions, ie. those returning a type
+
+ src/hb-algs.hh   |  3 ++-
+ src/hb-array.hh  |  6 +++---
+ src/hb-atomic.hh |  2 +-
+ src/hb-blob.hh   |  2 +-
+ src/hb-common.cc |  2 +-
+ src/hb-ft.cc     |  2 +-
+ src/hb-iter.hh   |  2 +-
+ src/hb-meta.hh   | 12 ++++++------
+ src/hb-null.hh   |  6 +++---
+ 9 files changed, 19 insertions(+), 18 deletions(-)
+
+commit 1ce11b44375dae74e8984ace1db4f08c51ac9c38
+Author: David Corbett <corbett.dav@husky.neu.edu>
+Date:   Tue Apr 16 10:04:45 2019 -0400
+
+    Reduce LangTag from 3 language system tags to 1
+
+ src/gen-tag-table.py   |   13 +-
+ src/hb-ot-tag-table.hh | 2078 ++++++++++++++++++++++++------------------------
+ src/hb-ot-tag.cc       |   22 +-
+ 3 files changed, 1053 insertions(+), 1060 deletions(-)
+
+commit 155e92f25908830bef192304a2039853f6f5d4b5
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Tue Apr 16 11:35:09 2019 -0400
+
+    Reduce NullPool size
+
+ src/hb-null.hh | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 4fc2d2d7248171c386c39630aa2612f240669a58
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Tue Apr 16 11:24:42 2019 -0400
+
+    [meta] Flesh out hb_invoke()
+
+ src/hb-algs.hh | 14 ++++++++++++--
+ 1 file changed, 12 insertions(+), 2 deletions(-)
+
+commit e03d9395aa79a29d731607bfd46533b700dc1a37
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Tue Apr 16 11:20:16 2019 -0400
+
+    Comment
+
+ src/hb-algs.hh | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit b8e763fd7140b3e298863e04053ec0f3c73a6a70
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Tue Apr 16 10:50:22 2019 -0400
+
+    [meta] Add hb_invoke()
+
+ src/hb-algs.hh | 34 ++++++++++++++++++++++++++++++++--
+ src/hb-iter.hh |  2 +-
+ 2 files changed, 33 insertions(+), 3 deletions(-)
+
+commit a3fcb9a370ad7a3c205342f831d8529c81660466
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Tue Apr 16 10:45:20 2019 -0400
+
+    [meta] Add HB_AUTO_RETURN_EXPR, HB_VOID_RETURN_EXPR, hb_priority, hb_has(), hb_get()
+    
+    The first three based on range-v3.
+
+ src/hb-algs.hh | 46 ++++++++++++++++++++++++++++++++++++++++++++++
+ src/hb-iter.hh |  7 ++++---
+ src/hb-meta.hh | 32 +++++++++++++++-----------------
+ src/hb.hh      |  2 +-
+ 4 files changed, 66 insertions(+), 21 deletions(-)
+
+commit ff68be31bf2ea82bf6bfcc6f993fb6806a895f97
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Tue Apr 16 09:59:08 2019 -0400
+
+    Add hb_void_tt<> ala std::void_t
+
+ src/hb-meta.hh | 7 +++++++
+ 1 file changed, 7 insertions(+)
+
+commit 89fea21697adfbba5057dd1d69c9806ee86e5ca8
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Mon Apr 15 17:36:09 2019 -0400
+
+    Fix copyright
+
+ src/hb-iter.hh | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit b7384c89e2685cec1b6761c918ec7d91e8ae3af8
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Mon Apr 15 16:53:10 2019 -0400
+
+    [fuzzing] Run valgrind with --leak-check=full
+
+ test/fuzzing/run-shape-fuzzer-tests.py | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 3ff66c00292b20325b0d991dfd5eee80284cb9a8
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Mon Apr 15 16:52:21 2019 -0400
+
+    [fuzzing] Fail if valgrind is requested but not found
+
+ test/fuzzing/run-shape-fuzzer-tests.py | 3 +++
+ 1 file changed, 3 insertions(+)
+
+commit 07776b60965d503dfb7fb5c611397e40759b0bdc
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Mon Apr 15 16:43:34 2019 -0400
+
+    More tweaks to previous commit
+    
+    Delete assignment operator of OffsetTo<> instead of Offset<>.
+    
+    In simple ArrayOf<>::sanitize() assert that Type has assignment operator.
+    Ideally we should SFINAE this and fallback to calling Type::sanitize()
+    if assignment operator is not available.  But we don't have a case of
+    that in the codebase.
+
+ src/hb-open-file.hh |  4 ++--
+ src/hb-open-type.hh | 16 +++++++++++-----
+ 2 files changed, 13 insertions(+), 7 deletions(-)
+
+commit 699de689e9aa2246ba9207c07140ccd564f5ec20
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Mon Apr 15 16:00:20 2019 -0400
+
+    Delete default assignment operator Offset<>
+
+ src/hb-open-type.hh        |  3 +++
+ src/hb-ot-cmap-table.hh    |  2 +-
+ src/hb-ot-layout-common.hh | 14 +++++++-------
+ 3 files changed, 11 insertions(+), 8 deletions(-)
+
+commit 02d864aa26359b7f057e2aa81404309e17180d47
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Mon Apr 15 15:39:03 2019 -0400
+
+    Add HB_FUNCOBJ()
+    
+    Fixes https://github.com/harfbuzz/harfbuzz/issues/1651
+
+ src/hb-algs.hh | 28 +++++++++++++++-------------
+ src/hb-iter.hh | 56 ++++++++++++++++++++++++++++----------------------------
+ src/hb-meta.hh | 22 +++++++++++++---------
+ src/hb.hh      |  7 +++++++
+ 4 files changed, 63 insertions(+), 50 deletions(-)
+
+commit 60be1450ad04612a6c2a6116036dbf3e436018de
+Author: Nathan Willis <nwillis@glyphography.com>
+Date:   Mon Apr 15 18:05:14 2019 +0100
+
+    [Usermanual]: fix Tamil error in Why-do-I-need-a-shaping-engine section.
+
+ docs/usermanual-what-is-harfbuzz.xml | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+commit 38b1d0b9b2e798dd808a816a397323ed7ba697ab
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Mon Apr 15 12:44:31 2019 -0400
+
+    Move static const to post-struct for a function object
+    
+    Just sending this to bots to see if all happy, then turn it into macro and
+    apply everywhere.
+    
+    Part of https://github.com/harfbuzz/harfbuzz/issues/1651
+
+ src/hb-algs.hh | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+commit 19e800c9d881ec016ab2e5fcaadab55ab5188398
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Mon Apr 15 12:07:00 2019 -0400
+
+    Ugh.  Another try, to unbreak gcc this time!
+    
+    Jenga.
+
+ src/hb-subset.cc | 7 +++++--
+ 1 file changed, 5 insertions(+), 2 deletions(-)
+
+commit 3a88f55c15b625a0ad10fbfadf4562bcbb41ae53
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Mon Apr 15 11:59:57 2019 -0400
+
+    Move location of HB_UNUSED to make MSVC happy
+
+ src/hb-subset.cc | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+commit 1ae265888e144328dbf1df796d379bf742c4151a
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Mon Apr 15 11:31:40 2019 -0400
+
+    Fix gcc warning
+
+ src/hb-array.hh | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+commit c0ea37b557f53b50094042f11fe2611b1b30d725
+Author: Ebrahim Byagowi <ebrahim@gnu.org>
+Date:   Mon Apr 15 00:34:04 2019 +0430
+
+    [ci] Fix macOS glib issue
+
+ .circleci/config.yml | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+commit ad126036643e44a98c4c42d2a2a4a3b4a3649937
+Merge: 341b70a3 47e538a3
+Author: Nathan Willis <nwillis@glyphography.com>
+Date:   Sun Apr 14 15:42:42 2019 +0100
+
+    Merge branch 'master' of https://github.com/harfbuzz/harfbuzz
+
+commit cd9889cac3ac3b271f7335f3e94acc4667a59b40
+Author: Nathan Willis <nwillis@glyphography.com>
+Date:   Sun Apr 14 15:33:56 2019 +0100
+
+    Docs: update and extended GTK-Doc comments for hb-ot-math.
+
+ src/hb-ot-math.cc | 133 ++++++++++++++++++++++++++++++++----------------------
+ src/hb-ot-math.h  |  21 +++++++++
+ 2 files changed, 99 insertions(+), 55 deletions(-)
+
+commit 3f74b7a14bffb8e91cd98edd0c3ddf0b0ddc169a
+Author: Nathan Willis <nwillis@glyphography.com>
+Date:   Sun Apr 14 15:20:56 2019 +0100
+
+    Docs: Regularize GTK-Doc comments for hb-ot-color.
+
+ src/hb-ot-color.cc | 136 ++++++++++++++++++++++++++++++-----------------------
+ src/hb-ot-color.h  |   6 +--
+ 2 files changed, 80 insertions(+), 62 deletions(-)
+
+commit 47e538a35f9072e5775a65e2bf110ae895818321
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Fri Apr 12 22:50:22 2019 -0400
+
+    Add HB_NO_SUBSET_LAYOUT
+    
+    Part of https://github.com/harfbuzz/harfbuzz/issues/1652
+
+ src/hb-subset.cc | 10 +++++++++-
+ 1 file changed, 9 insertions(+), 1 deletion(-)
+
+commit a98e4068e76d50bd9562d85a452b56e681f1d62b
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Fri Apr 12 22:42:44 2019 -0400
+
+    Revert "Hide symbols in hb-iter"
+    
+    This reverts commit 98f14c4cdb837a962083a6702f401d41b4c1ec5c.
+    
+    Same as previous commit.
+
+ src/hb-iter.hh | 88 +++++++++++++++++++++++++++++-----------------------------
+ 1 file changed, 44 insertions(+), 44 deletions(-)
+
+commit dab92bdd4623aa7dac8eb00b14131566d75d095e
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Fri Apr 12 22:39:38 2019 -0400
+
+    Revert "Hide more symbols"
+    
+    This reverts commit 2e86d50915cf1a791da9acb95245aa820a3d70f4.
+    
+    I think the setup that caused me to do this is faulty and not hiding inlines.
+
+ src/hb-blob.hh | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 98f14c4cdb837a962083a6702f401d41b4c1ec5c
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Fri Apr 12 18:11:18 2019 -0400
+
+    Hide symbols in hb-iter
+    
+    Painful.  All template methods need to be explicitly hidden :(.
+    
+    Maybe we should switch to -fvisibility=hidden pragma.
+    
+    A LOT more to go.
+
+ src/hb-iter.hh | 88 +++++++++++++++++++++++++++++-----------------------------
+ 1 file changed, 44 insertions(+), 44 deletions(-)
+
+commit 2e86d50915cf1a791da9acb95245aa820a3d70f4
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Fri Apr 12 18:07:42 2019 -0400
+
+    Hide more symbols
+    
+    Exposed by:
+    
+    $ make -j5 CPPFLAGS="-O0" CXXFLAGS=-flto=thin LDFLAGS=-lc++ && ./check-symbols.sh
+
+ src/hb-blob.hh | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit caa20e4ef9dff61a86312daec5d5a1df27d95ff7
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Fri Apr 12 17:59:18 2019 -0400
+
+    Hide a few more symbols
+    
+    Exposed by:
+    
+    $ make CPPFLAGS=-O0
+
+ src/hb-array.hh | 4 ++--
+ src/hb-meta.hh  | 6 +++---
+ 2 files changed, 5 insertions(+), 5 deletions(-)
+
+commit 95df00aec1996d521acdff6deff063ba98214fb9
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Fri Apr 12 17:50:03 2019 -0400
+
+    Hide a few static methods
+    
+    Looks like static methods that do not get inlined end up exported.
+    We have a lot more.  Need to protect all at some point.  Wish there
+    was an easier way, like the visibility flag we pass that automatically
+    hides all inline methods.
+    
+    Was exposed by check-symbols.sh when compiling on OS X 10.14 with:
+    
+    $ make CPPFLAGS=-Oz CXXFLAGS=-flto=thin LDFLAGS=-lc++
+
+ src/hb-aat-layout.hh           |  2 +-
+ src/hb-aat-map.hh              |  2 +-
+ src/hb-array.hh                |  2 +-
+ src/hb-coretext.cc             |  4 ++--
+ src/hb-open-file.hh            |  2 +-
+ src/hb-open-type.hh            |  3 ++-
+ src/hb-ot-cmap-table.hh        | 14 +++++++-------
+ src/hb-ot-layout-base-table.hh |  6 +++---
+ src/hb-ot-layout-gpos-table.hh |  8 ++++----
+ src/hb-ot-layout-gsub-table.hh |  8 ++++----
+ src/hb-ot-layout-gsubgpos.hh   |  2 +-
+ src/hb-ot-map.hh               |  4 ++--
+ src/hb-uniscribe.cc            |  4 ++--
+ 13 files changed, 31 insertions(+), 30 deletions(-)
+
+commit 2f4be4ba54b539fbadc31fc53bdcfca81d7db77a
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Fri Apr 12 16:21:58 2019 -0400
+
+    Add HB_NO_OPTIONS
+    
+    Part of https://github.com/harfbuzz/harfbuzz/issues/1652
+
+ src/hb-debug.hh | 3 +++
+ 1 file changed, 3 insertions(+)
+
+commit 079d2dcbb2607cda3daa497199090c5813a51de5
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Fri Apr 12 15:00:37 2019 -0400
+
+    Add HB_NO_NAME_TABLE_AAT
+    
+    Part of https://github.com/harfbuzz/harfbuzz/issues/1652
+
+ src/hb-ot-name-table.hh | 2 ++
+ 1 file changed, 2 insertions(+)
+
+commit 60a58aa61c09cafd12c432fdc1f7325f2a6d44bd
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Fri Apr 12 14:58:53 2019 -0400
+
+    Add HB_NO_OT_FONT_BITMAP
+    
+    Part of https://github.com/harfbuzz/harfbuzz/issues/1652
+
+ src/hb-ot-font.cc | 2 ++
+ 1 file changed, 2 insertions(+)
+
+commit 160c4d8b2d9f6c205b713236f043081e6dd532ee
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Fri Apr 12 14:57:49 2019 -0400
+
+    Add HB_NO_OT_FONT_CFF
+    
+    Part of https://github.com/harfbuzz/harfbuzz/issues/1652
+
+ src/hb-ot-font.cc | 2 ++
+ 1 file changed, 2 insertions(+)
+
+commit 35f3b97fac3b106d345a06a4970f6adce182797b
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Fri Apr 12 10:16:12 2019 -0400
+
+    Add HB_NO_OT_SHAPE_COMPLEX_HEBREW_FALLBACK
+    
+    Part of https://github.com/harfbuzz/harfbuzz/issues/1652
+
+ src/hb-ot-shape-complex-hebrew.cc | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+commit 414c5de26b34c0c53f6f4b5f00ddc8e1a3b62ac2
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Fri Apr 12 10:12:11 2019 -0400
+
+    Add HB_NO_OT_SHAPE_FALLBACK
+    
+    Part of https://github.com/harfbuzz/harfbuzz/issues/1652
+
+ src/hb-ot-shape-fallback.cc | 12 ++++++++++++
+ 1 file changed, 12 insertions(+)
+
+commit fe0018f7ef804acefa729e888f5a9935e571079d
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Fri Apr 12 09:35:29 2019 -0400
+
+    Add HB_NO_OT_SHAPE_COMPLEX_THAI_FALLBACK
+    
+    Part of https://github.com/harfbuzz/harfbuzz/issues/1652
+
+ src/hb-ot-shape-complex-thai.cc | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+commit 9ddbfa006d752f6ddd3610ff968f84cf18dec031
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Fri Apr 12 09:33:25 2019 -0400
+
+    Add HB_NO_OT_LAYOUT_BLACKLIST
+    
+    Part of https://github.com/harfbuzz/harfbuzz/issues/1652
+
+ src/hb-ot-layout.cc | 9 +++++++++
+ 1 file changed, 9 insertions(+)
+
+commit 571fad4cf17d90434562d1b6f5d08b6f27343c7a
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Thu Apr 11 17:54:38 2019 -0400
+
+    Add HB_NO_OT_SHAPE_COMPLEX_VOWEL_CONSTRAINTS
+    
+    Part of https://github.com/harfbuzz/harfbuzz/issues/1652
+
+ src/hb-ot-shape-complex-vowel-constraints.cc | 3 +++
+ 1 file changed, 3 insertions(+)
+
+commit 3db227265bc0790ffd718bf265d245c78598a49d
+Author: Nathan Willis <nwillis@glyphography.com>
+Date:   Tue Apr 2 18:49:40 2019 +0100
+
+    Update gtk-doc annotations for inout counts on various getter functions.
+
+ src/hb-ot-layout.cc | 122 ++++++++++++++++++++++++++++++----------------------
+ 1 file changed, 70 insertions(+), 52 deletions(-)
+
+commit c08ddbd91b7f0fffe761638a2ee4893304b012db
+Author: Nathan Willis <nwillis@glyphography.com>
+Date:   Sun Mar 24 15:07:07 2019 +0000
+
+    [Docs] Minor edits to gtk-doc inline comment review.
+
+ src/hb-ot-layout.cc | 21 +++++++++++++--------
+ 1 file changed, 13 insertions(+), 8 deletions(-)
+
+commit af5230bce39020cf6fc87ee5e21cca3ba201a417
+Author: Nathan Willis <nwillis@glyphography.com>
+Date:   Mon Mar 18 14:03:16 2019 +0000
+
+    [Docs] Minor; fix formatting for gtk-doc multiple-annotations.
+
+ src/hb-ot-layout.cc | 12 ++++++------
+ 1 file changed, 6 insertions(+), 6 deletions(-)
+
+commit 6c0a1e8cd67144d20c8b5fcad23953910eeeea51
+Author: Nathan Willis <nwillis@glyphography.com>
+Date:   Sun Mar 17 14:50:47 2019 +0000
+
+    [Docs] Annotate gtk-doc formatting with some un-annotated (out)s.
+
+ src/hb-ot-layout.cc | 8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+commit 5122805c740961d4fdfbff440ed68792b63d50ed
+Author: Nathan Willis <nwillis@glyphography.com>
+Date:   Sun Mar 17 14:43:06 2019 +0000
+
+    [Docs] Fix gtk-doc formatting for (out) and (inout).
+
+ src/hb-ot-layout.cc | 108 ++++++++++++++++++++++++++--------------------------
+ 1 file changed, 54 insertions(+), 54 deletions(-)
+
+commit d3178aa52ae822ac6af606027ac8150ded0a2966
+Author: Nathan Willis <nwillis@glyphography.com>
+Date:   Sun Mar 17 14:27:27 2019 +0000
+
+    [Docs] Fix gtk-doc references to 'kern' table functions, clarifying that GPOS is not examined.
+
+ src/hb-ot-layout.cc | 10 +++++++---
+ 1 file changed, 7 insertions(+), 3 deletions(-)
+
+commit 3449031fad9dff7acedde7dceb0e47db708fc025
+Author: Nathan Willis <nwillis@glyphography.com>
+Date:   Sat Mar 16 15:38:08 2019 +0000
+
+    [Docs] Add inline gtk-doc documentation of GDEF glyph classes.
+
+ src/hb-ot-layout.h | 12 ++++++------
+ 1 file changed, 6 insertions(+), 6 deletions(-)
+
+commit 930f6fc3da04ce1897e65862fccb03afa9d3a780
+Author: Nathan Willis <nwillis@glyphography.com>
+Date:   Sat Mar 16 15:10:21 2019 +0000
+
+    [Docs] Add inlind gtk-doc comments for hb-ot-layout functions.
+
+ src/hb-ot-layout.cc | 456 +++++++++++++++++++++++++++++++++++++++++++++++++++-
+ src/hb-ot-layout.h  |  11 ++
+ 2 files changed, 462 insertions(+), 5 deletions(-)
+
+commit b52c0e54b9855a1f3d400e4dbcd0372520f2c2fc
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Thu Apr 11 11:20:10 2019 -0400
+
+    Use injected class name to simplify macros
+
+ src/hb-open-type.hh | 10 +++++-----
+ src/hb.hh           | 14 --------------
+ 2 files changed, 5 insertions(+), 19 deletions(-)
+
+commit baf1e79075b0f917b79484446cd2ca47b58f50aa
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Thu Apr 11 11:18:04 2019 -0400
+
+    [C++11] Use deleted methods
+
+ src/hb.hh | 30 +++++++++++++++---------------
+ 1 file changed, 15 insertions(+), 15 deletions(-)
+
+commit 824fd342d5d66584a5ed88951e05975f33c55617
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Thu Apr 11 11:16:01 2019 -0400
+
+    Rename a few macros
+
+ src/hb-map.hh       |  2 +-
+ src/hb-open-type.hh | 10 +++++-----
+ src/hb-set.hh       |  2 +-
+ src/hb.hh           | 12 ++++++------
+ 4 files changed, 13 insertions(+), 13 deletions(-)
+
+commit edfc6be4a0362efa5c1d39f4792a28b5726c3ce5
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Wed Apr 10 15:53:48 2019 -0400
+
+    [arabic] Disable fallback shaping if HB_NO_OT_SHAPE_COMPLEX_ARABIC_FALLBACK defined
+    
+    Part of https://github.com/harfbuzz/harfbuzz/issues/1652
+
+ src/hb-ot-shape-complex-arabic-fallback.hh | 1 -
+ src/hb-ot-shape-complex-arabic.cc          | 4 ++++
+ 2 files changed, 4 insertions(+), 1 deletion(-)
+
+commit 4d31662b5da20790f6f860cec8f5fdabf48210f0
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Wed Apr 10 15:40:03 2019 -0400
+
+    Don't install ot-font funcs on new fonts if HB_NO_OT_FONT defined
+    
+    Currently linker cannot GC hb-ot-font completely because we install
+    it on fonts by default.  Don't do that if HB_NO_OT_FONT defined.
+    
+    Part of https://github.com/harfbuzz/harfbuzz/issues/1652
+
+ src/hb-font.cc | 2 ++
+ 1 file changed, 2 insertions(+)
+
+commit b111b3de020cde6fb0686efc224cace4608f2e45
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Wed Apr 10 15:38:15 2019 -0400
+
+    Don't use any default unicode funcs if HB_NO_UNICODE_FUNCS is defined
+    
+    Part of https://github.com/harfbuzz/harfbuzz/issues/1652
+
+ src/hb-unicode.cc | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+commit c5509be93a351177724f2891dd5e9ddb02553452
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Mon Apr 8 14:50:58 2019 -0400
+
+    [coretext] Fix unused-variable error
+    
+    Fixes https://github.com/harfbuzz/harfbuzz/issues/1659
+
+ src/hb-coretext.cc | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 4c19aa26204d0dc2f08b6e4a824e9088301f68d8
+Author: Maks Naumov <maksqwe1@ukr.net>
+Date:   Fri Apr 5 21:46:27 2019 +0300
+
+    Fix MSVC C4068 warning (#1656)
+
+ src/hb-blob.cc | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit e44b83aac0443bd23df15b505a3d638883621b0e
+Author: Michiharu Ariza <ariza@adobe.com>
+Date:   Fri Apr 5 10:15:08 2019 -0700
+
+    replace test font SourceHanSans with its subet
+
+ ...gular.default.3042,3044,3046,3048,304A,304B.otf |    Bin 6356 -> 0 bytes
+ ...gular.default.3042,3044,3046,73E0,5EA6,8F38.otf |    Bin 6564 -> 0 bytes
+ .../SourceHanSans-Regular.default.61,63,65,6B.otf  |    Bin 5532 -> 0 bytes
+ ...gular.default.660E,6975,73E0,5EA6,8F38,6E05.otf |    Bin 6780 -> 0 bytes
+ .../SourceHanSans-Regular.default.660E.otf         |    Bin 5248 -> 0 bytes
+ ...e-retain-gids.3042,3044,3046,3048,304A,304B.otf |    Bin 537992 -> 0 bytes
+ ...e-retain-gids.3042,3044,3046,73E0,5EA6,8F38.otf |    Bin 692312 -> 0 bytes
+ ...ular.desubroutinize-retain-gids.61,63,65,6B.otf |    Bin 531624 -> 0 bytes
+ ...e-retain-gids.660E,6975,73E0,5EA6,8F38,6E05.otf |    Bin 692496 -> 0 bytes
+ ...ans-Regular.desubroutinize-retain-gids.660E.otf |    Bin 613836 -> 0 bytes
+ ...esubroutinize.3042,3044,3046,3048,304A,304B.otf |    Bin 6272 -> 0 bytes
+ ...esubroutinize.3042,3044,3046,73E0,5EA6,8F38.otf |    Bin 6456 -> 0 bytes
+ ...eHanSans-Regular.desubroutinize.61,63,65,6B.otf |    Bin 5460 -> 0 bytes
+ ...esubroutinize.660E,6975,73E0,5EA6,8F38,6E05.otf |    Bin 6572 -> 0 bytes
+ .../SourceHanSans-Regular.desubroutinize.660E.otf  |    Bin 5224 -> 0 bytes
+ ...e-retain-gids.3042,3044,3046,3048,304A,304B.otf |    Bin 537424 -> 0 bytes
+ ...e-retain-gids.3042,3044,3046,73E0,5EA6,8F38.otf |    Bin 691692 -> 0 bytes
+ ...ints-desubroutinize-retain-gids.61,63,65,6B.otf |    Bin 531124 -> 0 bytes
+ ...e-retain-gids.660E,6975,73E0,5EA6,8F38,6E05.otf |    Bin 691808 -> 0 bytes
+ ....drop-hints-desubroutinize-retain-gids.660E.otf |    Bin 613348 -> 0 bytes
+ ...esubroutinize.3042,3044,3046,3048,304A,304B.otf |    Bin 6096 -> 0 bytes
+ ...esubroutinize.3042,3044,3046,73E0,5EA6,8F38.otf |    Bin 6204 -> 0 bytes
+ ...gular.drop-hints-desubroutinize.61,63,65,6B.otf |    Bin 5344 -> 0 bytes
+ ...esubroutinize.660E,6975,73E0,5EA6,8F38,6E05.otf |    Bin 6268 -> 0 bytes
+ ...Sans-Regular.drop-hints-desubroutinize.660E.otf |    Bin 5120 -> 0 bytes
+ ...s-retain-gids.3042,3044,3046,3048,304A,304B.otf |    Bin 537492 -> 0 bytes
+ ...s-retain-gids.3042,3044,3046,73E0,5EA6,8F38.otf |    Bin 691788 -> 0 bytes
+ ...-Regular.drop-hints-retain-gids.61,63,65,6B.otf |    Bin 531164 -> 0 bytes
+ ...-Regular.drop-hints-retain-gids.61,63,65,6B.ttx | 393879 ------------------
+ ...s-retain-gids.660E,6975,73E0,5EA6,8F38,6E05.otf |    Bin 692008 -> 0 bytes
+ ...HanSans-Regular.drop-hints-retain-gids.660E.otf |    Bin 613368 -> 0 bytes
+ ...ar.drop-hints.3042,3044,3046,3048,304A,304B.otf |    Bin 6164 -> 0 bytes
+ ...ar.drop-hints.3042,3044,3046,73E0,5EA6,8F38.otf |    Bin 6300 -> 0 bytes
+ ...ourceHanSans-Regular.drop-hints.61,63,65,6B.otf |    Bin 5376 -> 0 bytes
+ ...ar.drop-hints.660E,6975,73E0,5EA6,8F38,6E05.otf |    Bin 6472 -> 0 bytes
+ .../SourceHanSans-Regular.drop-hints.660E.otf      |    Bin 5140 -> 0 bytes
+ ...r.retain-gids.3042,3044,3046,3048,304A,304B.otf |    Bin 538076 -> 0 bytes
+ ...r.retain-gids.3042,3044,3046,73E0,5EA6,8F38.otf |    Bin 692420 -> 0 bytes
+ ...urceHanSans-Regular.retain-gids.61,63,65,6B.otf |    Bin 531704 -> 0 bytes
+ ...r.retain-gids.660E,6975,73E0,5EA6,8F38,6E05.otf |    Bin 692700 -> 0 bytes
+ .../SourceHanSans-Regular.retain-gids.660E.otf     |    Bin 613860 -> 0 bytes
+ ...ubset.default.3042,3044,3046,3048,304A,304B.otf |    Bin 0 -> 3028 bytes
+ ...ubset.default.3042,3044,3046,73E0,5EA6,8F38.otf |    Bin 0 -> 3240 bytes
+ ...eHanSans-Regular_subset.default.61,63,65,6B.otf |    Bin 0 -> 2200 bytes
+ ...ubset.default.660E,6975,73E0,5EA6,8F38,6E05.otf |    Bin 0 -> 3460 bytes
+ .../SourceHanSans-Regular_subset.default.660E.otf  |    Bin 0 -> 1920 bytes
+ ...e-retain-gids.3042,3044,3046,3048,304A,304B.otf |    Bin 0 -> 90956 bytes
+ ...e-retain-gids.3042,3044,3046,73E0,5EA6,8F38.otf |    Bin 0 -> 125820 bytes
+ ...bset.desubroutinize-retain-gids.61,63,65,6B.otf |    Bin 0 -> 88392 bytes
+ ...e-retain-gids.660E,6975,73E0,5EA6,8F38,6E05.otf |    Bin 0 -> 126004 bytes
+ ...ular_subset.desubroutinize-retain-gids.660E.otf |    Bin 0 -> 103780 bytes
+ ...esubroutinize.3042,3044,3046,3048,304A,304B.otf |    Bin 0 -> 2952 bytes
+ ...esubroutinize.3042,3044,3046,73E0,5EA6,8F38.otf |    Bin 0 -> 3136 bytes
+ ...s-Regular_subset.desubroutinize.61,63,65,6B.otf |    Bin 0 -> 2132 bytes
+ ...esubroutinize.660E,6975,73E0,5EA6,8F38,6E05.otf |    Bin 0 -> 3256 bytes
+ ...eHanSans-Regular_subset.desubroutinize.660E.otf |    Bin 0 -> 1896 bytes
+ ...e-retain-gids.3042,3044,3046,3048,304A,304B.otf |    Bin 0 -> 90656 bytes
+ ...e-retain-gids.3042,3044,3046,73E0,5EA6,8F38.otf |    Bin 0 -> 125468 bytes
+ ...ints-desubroutinize-retain-gids.61,63,65,6B.otf |    Bin 0 -> 88156 bytes
+ ...e-retain-gids.660E,6975,73E0,5EA6,8F38,6E05.otf |    Bin 0 -> 125584 bytes
+ ....drop-hints-desubroutinize-retain-gids.660E.otf |    Bin 0 -> 103556 bytes
+ ...esubroutinize.3042,3044,3046,3048,304A,304B.otf |    Bin 0 -> 2792 bytes
+ ...esubroutinize.3042,3044,3046,73E0,5EA6,8F38.otf |    Bin 0 -> 2896 bytes
+ ...ubset.drop-hints-desubroutinize.61,63,65,6B.otf |    Bin 0 -> 2028 bytes
+ ...esubroutinize.660E,6975,73E0,5EA6,8F38,6E05.otf |    Bin 0 -> 2964 bytes
+ ...gular_subset.drop-hints-desubroutinize.660E.otf |    Bin 0 -> 1804 bytes
+ ...s-retain-gids.3042,3044,3046,3048,304A,304B.otf |    Bin 0 -> 90724 bytes
+ ...s-retain-gids.3042,3044,3046,73E0,5EA6,8F38.otf |    Bin 0 -> 125560 bytes
+ ...r_subset.drop-hints-retain-gids.61,63,65,6B.otf |    Bin 0 -> 88196 bytes
+ ...s-retain-gids.660E,6975,73E0,5EA6,8F38,6E05.otf |    Bin 0 -> 125780 bytes
+ ...-Regular_subset.drop-hints-retain-gids.660E.otf |    Bin 0 -> 103572 bytes
+ ...et.drop-hints.3042,3044,3046,3048,304A,304B.otf |    Bin 0 -> 2848 bytes
+ ...et.drop-hints.3042,3044,3046,73E0,5EA6,8F38.otf |    Bin 0 -> 2988 bytes
+ ...nSans-Regular_subset.drop-hints.61,63,65,6B.otf |    Bin 0 -> 2060 bytes
+ ...et.drop-hints.660E,6975,73E0,5EA6,8F38,6E05.otf |    Bin 0 -> 3164 bytes
+ ...ourceHanSans-Regular_subset.drop-hints.660E.otf |    Bin 0 -> 1824 bytes
+ ...t.retain-gids.3042,3044,3046,3048,304A,304B.otf |    Bin 0 -> 91040 bytes
+ ...t.retain-gids.3042,3044,3046,73E0,5EA6,8F38.otf |    Bin 0 -> 125924 bytes
+ ...Sans-Regular_subset.retain-gids.61,63,65,6B.otf |    Bin 0 -> 88468 bytes
+ ...t.retain-gids.660E,6975,73E0,5EA6,8F38,6E05.otf |    Bin 0 -> 126208 bytes
+ ...urceHanSans-Regular_subset.retain-gids.660E.otf |    Bin 0 -> 103800 bytes
+ test/subset/data/fonts/SourceHanSans-Regular.otf   |    Bin 16427580 -> 0 bytes
+ .../data/fonts/SourceHanSans-Regular_subset.otf    |    Bin 0 -> 2707728 bytes
+ test/subset/data/tests/cff-japanese.tests          |      2 +-
+ 84 files changed, 1 insertion(+), 393880 deletions(-)
+
+commit a96d003d6ec4212fadad4f5b9058c9f8b07bcf89
+Author: Maks Naumov <maksqwe1@ukr.net>
+Date:   Fri Apr 5 12:29:56 2019 +0300
+
+    Fix MSVC C4138 warning (#1657)
+
+ src/hb-ot-cff-common.hh | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit c68eb7002f1c2b847d955797e27f5403199e3d9d
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Wed Apr 3 16:24:12 2019 -0700
+
+    Minor
+
+ src/hb-ot-layout-common.hh | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+commit 85adf4ad5c76172514f281bfbe3850ef35473cc7
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Wed Apr 3 16:06:55 2019 -0700
+
+    [GDEF] Don't assume glyphlist is sorted
+    
+    As was hit by the fuzzer.
+    
+    Fixes https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=14032
+
+ src/hb-ot-layout-common.hh | 8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+commit ecabdffc61cb0b71424f4845aeda8cd0a6d25a29
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Wed Apr 3 16:06:34 2019 -0700
+
+    [algs] Add hb_min() and hb_max()
+
+ src/hb-algs.hh | 11 +++++++++++
+ 1 file changed, 11 insertions(+)
+
+commit 7b863142ceb82fc2fd23802f19f7379aa2f152e5
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Wed Apr 3 15:48:27 2019 -0700
+
+    [serialize] Make putting breakpoint on out-of-memory easier
+
+ src/hb-serialize.hh | 5 ++++-
+ 1 file changed, 4 insertions(+), 1 deletion(-)
+
+commit 2bd275023405b6a669d59ad4cdcb2e8cb410d593
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Wed Apr 3 15:31:53 2019 -0700
+
+    [iter] Tweak SFINAE again
+    
+    Don't think we need hb_is_same().
+
+ src/hb-iter.hh | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit f02ebc89ec89e78a348f9b67d613a2024feabc18
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Wed Apr 3 15:23:06 2019 -0700
+
+    [array] Add compy assignment operator since copy constructor is explicit
+
+ src/hb-array.hh | 6 ++++++
+ 1 file changed, 6 insertions(+)
+
+commit 20a73da2c9227a0f9bc943a3d766eedeb5bed3b3
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Wed Apr 3 14:32:15 2019 -0700
+
+    [array] Add default copy constructor
+    
+    MSVC seems to need it.
+
+ src/hb-array.hh | 1 +
+ 1 file changed, 1 insertion(+)
+
+commit d419a9a4376de7b2ae1dec7df09f8d034cc2d039
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Wed Apr 3 14:18:19 2019 -0700
+
+    [iter] Use different SFINAE scheme to make MSVC happy
+    
+    From Orvid King: TLDR; MSVC has some issues using sizeof(declval<T>()) for
+    SFINAE of templated types, so I just used SFINAE in a different context where
+    MSVC doesn't have the issue.
+
+ src/hb-iter.hh | 21 ++++++++++++---------
+ 1 file changed, 12 insertions(+), 9 deletions(-)
+
+commit 2778df7972f537192b51cd0719adf2ab4d1f3397
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Wed Apr 3 14:15:01 2019 -0700
+
+    [meta] Add hb_is_same()
+
+ src/hb-meta.hh | 9 ++++++---
+ 1 file changed, 6 insertions(+), 3 deletions(-)
+
+commit 6215fb8e68bdf69f4af9f7f4959ad55a70723774
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Tue Apr 2 23:10:03 2019 -0700
+
+    [serialize] Actually reclaim storage from duplicate objects
+
+ src/hb-serialize.hh | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 3305a2cad24f878f5d8773c2acae491ebd5a9059
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Tue Apr 2 22:42:22 2019 -0700
+
+    [serialize] Port to use object pool
+    
+    Tested, but feels fragile :(.
+
+ src/hb-pool.hh      |   5 +-
+ src/hb-serialize.hh | 141 ++++++++++++++++++++++++++++++++--------------------
+ 2 files changed, 91 insertions(+), 55 deletions(-)
+
+commit 5efbc01174127bede4d533866acac239e5a0cfd5
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Tue Apr 2 22:41:06 2019 -0700
+
+    [pool] Uses memset() instead of assigning Null()
+    
+    Assignment is invalid on invalid object.
+
+ src/hb-pool.hh | 5 +++--
+ 1 file changed, 3 insertions(+), 2 deletions(-)
+
+commit 434d78bf91ac5204ffbf2144f199eb7a0f65c421
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Tue Apr 2 21:46:40 2019 -0700
+
+    Add hb_pool_t<> for pooled memory allocation
+
+ src/Makefile.sources |  1 +
+ src/hb-pool.hh       | 98 ++++++++++++++++++++++++++++++++++++++++++++++++++++
+ 2 files changed, 99 insertions(+)
+
+commit 8e4df1a152f3916613594fa1bac308efdb61d512
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Tue Apr 2 20:20:53 2019 -0700
+
+    [serialize] Disable packed_map again
+    
+    Ugh.  Need to think of something else.
+
+ src/hb-serialize.hh | 1 +
+ 1 file changed, 1 insertion(+)
+
+commit 31c1a83899147310b27bd40fac755c629cb59cef
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Tue Apr 2 20:17:27 2019 -0700
+
+    [map] Protect more against pointer deref
+
+ src/hb-map.hh | 5 +++--
+ 1 file changed, 3 insertions(+), 2 deletions(-)
+
+commit 5bffa9e375fe294718452ad51e4c5ff017a046b4
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Tue Apr 2 20:13:16 2019 -0700
+
+    More
+
+ src/hb-map.hh    | 5 +++++
+ src/hb-set.hh    | 9 ++++++++-
+ src/hb-vector.hh | 8 ++++----
+ 3 files changed, 17 insertions(+), 5 deletions(-)
+
+commit 5b66b033fd2cd9c95284d283f08d6789c7ec985d
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Tue Apr 2 19:27:02 2019 -0700
+
+    [serialize] Fix hb_hashmap_t<> for pointers and use in packed_map
+
+ src/hb-array.hh     | 12 +++++++++++-
+ src/hb-map.hh       | 22 ++++++++++++++--------
+ src/hb-serialize.hh |  8 +++-----
+ src/hb-vector.hh    |  1 +
+ 4 files changed, 29 insertions(+), 14 deletions(-)
+
+commit 42ab32cbbaf8b403c351953f091c0fbe8464c4cb
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Tue Apr 2 18:41:33 2019 -0700
+
+    [iter] Remove passing pointer to hb_iter()
+    
+    While doable with hb_deref_pointer() as well, we also would then
+    need to do it in a ton of places.  Not worth it / messy.
+
+ src/hb-array.hh  | 2 +-
+ src/hb-iter.hh   | 5 -----
+ src/test-iter.cc | 3 ---
+ 3 files changed, 1 insertion(+), 9 deletions(-)
+
+commit d0da547b3741323493398eed8975a76f4a5742c2
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Tue Apr 2 18:22:39 2019 -0700
+
+    [array] Use dagger for hashing array
+    
+    Also switch to better mixing.
+
+ src/hb-array.hh | 9 +++++----
+ 1 file changed, 5 insertions(+), 4 deletions(-)
+
+commit b6f29bf14153cac51b218e3aaba9e1b3aa747a8c
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Tue Apr 2 18:12:01 2019 -0700
+
+    [iter] Accept pointers in hb_iter()
+    
+    No idea how to avoid dupicating code.  Was hoping hb_deref_pointer()
+    would do it, but looks like a pointer can't bind to a universal
+    reference T&&.  Humm.
+
+ src/hb-iter.hh   | 5 +++++
+ src/test-iter.cc | 3 +++
+ 2 files changed, 8 insertions(+)
+
+commit fc24bb9046e7e39d52a245bdc3480a30095cb6ee
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Tue Apr 2 17:49:52 2019 -0700
+
+    [serialize] Towards maintaining packed_map
+
+ src/hb-serialize.hh | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+commit aa2293a55eaa39f4e77b60851bbdee56b1120225
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Tue Apr 2 17:42:10 2019 -0700
+
+    [serialize] Minor
+
+ src/hb-open-type.hh | 10 +++++-----
+ 1 file changed, 5 insertions(+), 5 deletions(-)
+
+commit e42b82c828ecec6f534040dae5518e04643b5f10
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Tue Apr 2 17:21:54 2019 -0700
+
+    [serialize] Handle non-nullable offsets
+
+ src/hb-open-type.hh | 13 +++++++++----
+ 1 file changed, 9 insertions(+), 4 deletions(-)
+
+commit e04518bafc66224887bf7f478e1affb54bc7acd0
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Tue Apr 2 17:20:04 2019 -0700
+
+    [serialize] Movce empty-object handling earlier
+
+ src/hb-serialize.hh | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+commit 7f73c9744e6c0e8dd37a208b75a4bc299bccbd4d
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Tue Apr 2 17:12:24 2019 -0700
+
+    [serialize] Minor
+
+ src/hb-open-type.hh | 14 +++++---------
+ 1 file changed, 5 insertions(+), 9 deletions(-)
+
+commit 5a3de4f4f8791139d2c04a66244001aba192ef6b
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Tue Apr 2 16:53:05 2019 -0700
+
+    [serialize] Allow offset links that have base offset from the object base
+    
+    Rarely used, but used, in name table or similar constructs.
+
+ src/hb-serialize.hh | 18 +++++++++---------
+ 1 file changed, 9 insertions(+), 9 deletions(-)
+
+commit edad6b2c450e22e67ae86c5f2328cca3c29aaad2
+Author: Ebrahim Byagowi <ebrahim@gnu.org>
+Date:   Wed Apr 3 00:48:59 2019 +0430
+
+    [test][iter] minor, fix double promotion warning
+
+ src/test-iter.cc | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 062f5d6e7aa061358eb5874a8f3a3f3bd6e9f16f
+Author: Ebrahim Byagowi <ebrahim@gnu.org>
+Date:   Tue Apr 2 20:27:00 2019 +0430
+
+    [test] minor, c style comments
+
+ src/test-iter.cc | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+commit afdbf960d6147ec607ddb2c780d3a83068f61357
+Author: Ebrahim Byagowi <ebrahim@gnu.org>
+Date:   Tue Apr 2 20:25:06 2019 +0430
+
+    [iter][test] Add another test for hb_reduce
+    
+    Different initial and accumulator types
+
+ src/test-iter.cc | 6 ++++++
+ 1 file changed, 6 insertions(+)
+
+commit bfa02bef4546f448e048288c1162988c8c39322a
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Mon Apr 1 21:36:13 2019 -0700
+
+    [serialize] Switch to tetris-packing
+
+ src/hb-open-type.hh | 15 +++++++++++----
+ 1 file changed, 11 insertions(+), 4 deletions(-)
+
+commit f0ea3ac17bef98409d302b9f285e94015e069823
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Mon Apr 1 21:36:03 2019 -0700
+
+    [serialize] Fix linking
+
+ src/hb-serialize.hh | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+commit 7c0e2054e0799ed89cdc5de8c1416d009c0029b5
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Mon Apr 1 21:32:29 2019 -0700
+
+    [serialize] Minor
+
+ src/hb-serialize.hh | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 64d0f0893812fa1cb2746071d8b021560969526d
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Mon Apr 1 16:50:28 2019 -0700
+
+    [cmap] Minor
+
+ src/hb-ot-cmap-table.hh | 7 ++++---
+ 1 file changed, 4 insertions(+), 3 deletions(-)
+
+commit 2e675cc7b50b5a57ceddf799d63811801ffcfe94
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Mon Apr 1 16:45:50 2019 -0700
+
+    [subset] Call serialize start/end around it
+    
+    To be cleaned up.
+
+ src/hb-subset.cc | 2 ++
+ 1 file changed, 2 insertions(+)
+
+commit abe33c6149719eb371c5f2b0d8c143550938129e
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Mon Apr 1 16:45:40 2019 -0700
+
+    [serialize] Assert stack
+
+ src/hb-serialize.hh | 1 +
+ 1 file changed, 1 insertion(+)
+
+commit 72e9b2c16cd1bc183226ca0aa8a58a5b1222573d
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Mon Apr 1 16:17:30 2019 -0700
+
+    [serialize] Add add_link() to add link
+
+ src/hb-serialize.hh | 26 +++++++++++++++++++++++---
+ 1 file changed, 23 insertions(+), 3 deletions(-)
+
+commit 74addbecac3b8be699ac90b3853970f6c7efd0eb
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Mon Apr 1 14:17:09 2019 -0700
+
+    [serialize] Add default template type to push()
+
+ src/hb-serialize.hh | 7 ++++++-
+ 1 file changed, 6 insertions(+), 1 deletion(-)
+
+commit b8642087e6c2ec96dc70fcef617128b6ce353a7e
+Author: Ebrahim Byagowi <ebrahim@gnu.org>
+Date:   Tue Apr 2 00:30:06 2019 +0430
+
+    [iter] hb_reduce, accumulator with a different type
+
+ src/hb-iter.hh   | 22 ++++++++++++----------
+ src/test-iter.cc | 26 +++++++++++++++++++++++++-
+ 2 files changed, 37 insertions(+), 11 deletions(-)
+
+commit e526414c759ebca82f1071cdeafe1160bcaa9637
+Author: Ebrahim Byagowi <ebrahim@gnu.org>
+Date:   Sun Mar 31 12:41:58 2019 +0430
+
+    [iter] Implement hb_reduce
+
+ src/hb-iter.hh   | 28 ++++++++++++++++++++++++++++
+ src/test-iter.cc |  5 +++++
+ 2 files changed, 33 insertions(+)
+
+commit f3aca6aa267f7687a0406c7c545aefb5eed300b2
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Sun Mar 31 21:37:14 2019 -0700
+
+    [serialize] Implement linking
+    
+    Untested!
+
+ src/hb-serialize.hh | 29 +++++++++++++++++++++++++++--
+ 1 file changed, 27 insertions(+), 2 deletions(-)
+
+commit 17f0cfa7ea3a5f0946d8800b98c1582c05dad853
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Sun Mar 31 21:34:19 2019 -0700
+
+    Move BEInt to hb.hh
+    
+    I knows...
+
+ src/hb-machinery.hh | 88 ----------------------------------------------------
+ src/hb.hh           | 89 +++++++++++++++++++++++++++++++++++++++++++++++++++++
+ 2 files changed, 89 insertions(+), 88 deletions(-)
+
+commit 78fc43f2930064cd6cf4229c1e4cb76edb8ed7f6
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Sun Mar 31 19:17:07 2019 -0700
+
+    [iter] Fix up build, ouch
+    
+    Yeah, some things not very clear...
+
+ src/hb-iter.hh   | 8 ++++++--
+ src/test-iter.cc | 4 ++--
+ 2 files changed, 8 insertions(+), 4 deletions(-)
+
+commit e5d6fe9782a9fcde0786392c075c6c0b85c24829
+Author: Jonathan Kew <jfkthame@gmail.com>
+Date:   Sun Mar 31 19:17:32 2019 +0100
+
+    Don't skip setting the .end field of the first range
+    
+    Fixes a bug in CoverageFormat2::serialize whereby the first range
+    was not serialized correctly if it consists of only a single glyph ID.
+    This broke shaping of U+0626 in the Arabic fallback shaper, because it
+    is not found in the coverage table of the 'init' and 'medi' lookups.
+    
+    Also fix similar bug in ClassDefFormat2::serialize, noted during code
+    inspection (I haven't observed a case that was actually affected by
+    this, but it looks broken).
+    
+    Fixes https://github.com/harfbuzz/harfbuzz/issues/1504
+
+ src/hb-ot-layout-common.hh | 14 +++++++++-----
+ 1 file changed, 9 insertions(+), 5 deletions(-)
+
+commit 8a8d45b924cdb4343b4b11a7ef14e2d1fabb6f82
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Sun Mar 31 19:00:09 2019 -0700
+
+    [iter] Adjust hb_copy() and use it
+    
+    Untested.
+
+ src/hb-iter.hh   | 11 ++++-------
+ src/hb-vector.hh |  4 ++--
+ 2 files changed, 6 insertions(+), 9 deletions(-)
+
+commit ba4b7be45523e88c26f763f8a329cc43c13b98a1
+Author: Ebrahim Byagowi <ebrahim@gnu.org>
+Date:   Sun Mar 31 01:32:30 2019 -0700
+
+    Remove coretext_aat shaper (#1581)
+    
+    coretext_aat was a temporary shaper to redirect shaping of AAT fonts
+    to CoreText and leaving the rest for HarfBuzz.  As HarfBuzz now supports
+    AAT and Chrome now actually ships that on a stable version on macOS,
+    we no longer care about such use-case.  If a client really wants 100%
+    metrics compatibility with CoreText better to use it directly or through
+    our API.  Replicating the same behavior still is possible using
+    hb_shape_full, something we don't care or like to offer anymore.
+    
+    Fixes https://github.com/harfbuzz/harfbuzz/issues/1478
+
+ src/hb-coretext.cc    | 56 ---------------------------------------------------
+ src/hb-shaper-list.hh |  4 ----
+ 2 files changed, 60 deletions(-)
+
+commit d6005b49b32410543a8dfa93ce2a213223cf8f01
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Sat Mar 30 19:49:56 2019 -0700
+
+    [serialize] Start implementing linking
+
+ src/hb-serialize.hh | 15 ++++++++++++---
+ 1 file changed, 12 insertions(+), 3 deletions(-)
+
+commit 313b3057c335da6baa4cd447bac95812992413b9
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Sat Mar 30 19:46:35 2019 -0700
+
+    [serializer] Implement dedup!
+
+ src/hb-serialize.hh | 18 +++++++++++++++---
+ 1 file changed, 15 insertions(+), 3 deletions(-)
+
+commit b189bbc48fb4b7c251d30b26a57ad84d1cb6dbe4
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Sat Mar 30 19:41:48 2019 -0700
+
+    Implement hashing of objects
+    
+    Should be improved for hb_bytes_t.
+
+ src/hb-algs.hh      |  2 +-
+ src/hb-array.hh     | 13 +++++++++++++
+ src/hb-serialize.hh |  5 +++++
+ src/hb-vector.hh    |  5 +++++
+ 4 files changed, 24 insertions(+), 1 deletion(-)
+
+commit d6b28057a5cc636138cd453947d3a2008f18729f
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Sat Mar 30 19:31:51 2019 -0700
+
+    Fix hb_hash(pointer)
+
+ src/hb-algs.hh | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit d74dc3ef65a159fe585e906deccdb32b570433aa
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Sat Mar 30 19:26:37 2019 -0700
+
+    [serialize] Don't insert empty object into tree
+
+ src/hb-serialize.hh | 5 ++++-
+ 1 file changed, 4 insertions(+), 1 deletion(-)
+
+commit 7fd82283263f8caded4870d6e12f74c7e660fa8d
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Sat Mar 30 19:16:20 2019 -0700
+
+    [serialize] Towards maintaining hashmap
+
+ src/hb-algs.hh      |  2 +-
+ src/hb-serialize.hh | 16 ++++++++++++++--
+ src/hb-vector.hh    |  1 +
+ 3 files changed, 16 insertions(+), 3 deletions(-)
+
+commit f254f45a1e6b1de6d83c97033773d20408772763
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Sat Mar 30 19:05:51 2019 -0700
+
+    [serialize] Only pack main object if there are other objects
+    
+    Avoids a memmove for tables that don't use the object packing mechanism.
+
+ src/hb-serialize.hh | 7 +++++--
+ 1 file changed, 5 insertions(+), 2 deletions(-)
+
+commit 946d446f9b795f657d56ca443edbc0b77d660a50
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Sat Mar 30 19:03:55 2019 -0700
+
+    [serialize] Copy both sides of the buffer
+
+ src/hb-serialize.hh | 13 +++++++++----
+ 1 file changed, 9 insertions(+), 4 deletions(-)
+
+commit 8512dc565d310e9fd80d831282736284cc3ecd2e
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Sat Mar 30 19:01:23 2019 -0700
+
+    [serialize] Simplify copy
+
+ src/hb-serialize.hh | 22 +++++++---------------
+ 1 file changed, 7 insertions(+), 15 deletions(-)
+
+commit 0b1fe7b716628f7b7b4098da9ef544e1518008f5
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Sat Mar 30 18:48:26 2019 -0700
+
+    [serializer] Unbreak for now
+
+ src/hb-serialize.hh | 5 +++--
+ 1 file changed, 3 insertions(+), 2 deletions(-)
+
+commit 10f062234eb7c762a36cf750e75fe6f74ee89a3d
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Sat Mar 30 18:44:01 2019 -0700
+
+    [map] Shuffle fini code
+
+ src/hb-map.hh | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit e6b78003efbe02ba4542cadcc13bc1dd0b1d57b0
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Sat Mar 30 18:33:30 2019 -0700
+
+    [vector] Add move semantics
+
+ src/hb-vector.hh | 16 ++++++++++++++++
+ 1 file changed, 16 insertions(+)
+
+commit 4c4d3c3ed55a8f1eea20593c08322e61fe1cdd3c
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Sat Mar 30 18:30:50 2019 -0700
+
+    [vector] Add some move and forwarding
+
+ src/hb-serialize.hh | 2 +-
+ src/hb-vector.hh    | 8 ++++----
+ 2 files changed, 5 insertions(+), 5 deletions(-)
+
+commit 7c9ceabcef426ca6fc54b70db9dd8cb63937710b
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Sat Mar 30 18:19:36 2019 -0700
+
+    [meta] Add hb_move and hb_forward ala std::
+
+ src/hb-meta.hh | 11 +++++++++++
+ 1 file changed, 11 insertions(+)
+
+commit 9a19b885f9136b0b7cdfa04679274cd4b6d16188
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Sat Mar 30 18:14:30 2019 -0700
+
+    [serialize] Flesh out packing
+
+ src/hb-serialize.hh | 58 +++++++++++++++++++++++++++++++----------------------
+ 1 file changed, 34 insertions(+), 24 deletions(-)
+
+commit 357c7c611cc20f86c646bd2d392c243140f92d34
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Sat Mar 30 18:13:57 2019 -0700
+
+    [vector] Add copy constructor and assignment operator
+
+ src/hb-vector.hh | 17 ++++++++++++++++-
+ 1 file changed, 16 insertions(+), 1 deletion(-)
+
+commit 6f69c9d26fa53cd8a2331395bbc146bfc85fd1e3
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Sat Mar 30 18:00:03 2019 -0700
+
+    [serialize] Minor
+
+ src/hb-serialize.hh | 9 +++++----
+ 1 file changed, 5 insertions(+), 4 deletions(-)
+
+commit a43290192beedc6335efc3841c05ec7fa54e8871
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Sat Mar 30 17:51:26 2019 -0700
+
+    [serialize] Add packed_map
+
+ src/hb-map.hh       |  7 +++++++
+ src/hb-serialize.hh | 24 +++++++++++++++++++++---
+ 2 files changed, 28 insertions(+), 3 deletions(-)
+
+commit bed150bd2e8d61950ea17d1b5a4bf4705801c1cc
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Sat Mar 30 17:26:35 2019 -0700
+
+    [serialize] Start fleshing out object stack
+
+ src/hb-serialize.hh | 91 ++++++++++++++++++++++++++++++++++++++---------------
+ src/hb-vector.hh    |  9 ++++--
+ 2 files changed, 72 insertions(+), 28 deletions(-)
+
+commit 63c35651893b2a1c555f728012e9ad36c0f84145
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Sat Mar 30 17:12:40 2019 -0700
+
+    [serialize] Simplify propagate_error()
+
+ src/hb-serialize.hh | 9 ++-------
+ 1 file changed, 2 insertions(+), 7 deletions(-)
+
+commit dbe9ba6711c6d35374de645097babfd81bc295b2
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Sat Mar 30 17:10:59 2019 -0700
+
+    [serialize] Add object_t, link_t, and snapshot_t
+
+ src/hb-serialize.hh | 32 +++++++++++++++++++++++++++++++-
+ 1 file changed, 31 insertions(+), 1 deletion(-)
+
+commit 38d57b9a66008c9722125d4d677d759a910cf2a1
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Sat Mar 30 16:38:06 2019 -0700
+
+    [map] Add another TODO item
+
+ src/hb-map.hh | 2 ++
+ 1 file changed, 2 insertions(+)
+
+commit 7fd940f899da4948d2c61ed497c1face42776187
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Sat Mar 30 16:29:19 2019 -0700
+
+    [map] Add TODO
+
+ src/hb-map.hh | 8 ++++++++
+ 1 file changed, 8 insertions(+)
+
+commit 6dcf7c4017619c782dbc8bd2c584bb33df96fc83
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Sat Mar 30 15:08:39 2019 -0700
+
+    [serialize] Add unused 'tail'
+
+ src/hb-serialize.hh | 5 +++--
+ 1 file changed, 3 insertions(+), 2 deletions(-)
+
+commit fe05e48086be9ed685b8a6ca4af966660744bc0f
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Sat Mar 30 15:06:25 2019 -0700
+
+    [serialize] Add ran_out_of_room
+
+ src/hb-serialize.hh | 8 +++++++-
+ src/hb-subset.cc    | 7 ++++++-
+ 2 files changed, 13 insertions(+), 2 deletions(-)
+
+commit a7c63cd8f8475c6de7fd5bb6444bf5d24082a191
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Sat Mar 30 14:59:40 2019 -0700
+
+    Split sanitize and dispatch into their own files
+
+ src/Makefile.sources |   2 +
+ src/hb-dispatch.hh   |  50 +++++++
+ src/hb-machinery.hh  | 369 +-----------------------------------------------
+ src/hb-sanitize.hh   | 388 +++++++++++++++++++++++++++++++++++++++++++++++++++
+ 4 files changed, 442 insertions(+), 367 deletions(-)
+
+commit be66b575fc15dbbe82cf1a7fa0b58020e86cffdc
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Sat Mar 30 14:53:54 2019 -0700
+
+    Move serializer to hb-serialize.hh
+
+ src/Makefile.sources |   1 +
+ src/hb-machinery.hh  | 164 +-----------------------------------------
+ src/hb-serialize.hh  | 196 +++++++++++++++++++++++++++++++++++++++++++++++++++
+ 3 files changed, 198 insertions(+), 163 deletions(-)
+
+commit bb22462f292995a724bf20363adf52d3a8357a97
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Sat Mar 30 14:46:54 2019 -0700
+
+    Whitespace
+
+ src/hb-machinery.hh | 3 +--
+ 1 file changed, 1 insertion(+), 2 deletions(-)
+
+commit ef33b5d1f6d3ec21e15ad74ca2524a117f594e06
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Sat Mar 30 14:39:21 2019 -0700
+
+    [map] Deref pointers before equality check
+
+ src/hb-map.hh  | 6 ++++--
+ src/hb-meta.hh | 4 ++--
+ 2 files changed, 6 insertions(+), 4 deletions(-)
+
+commit c98f51da719d1792bf23b53a9a345926056bf34d
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Sat Mar 30 14:30:22 2019 -0700
+
+    [map] Templatize hb_map_t
+    
+    Template name is hb_hashmap_t<K,V>.
+
+ src/hb-map.hh | 65 ++++++++++++++++++++++++++++++++++-------------------------
+ 1 file changed, 37 insertions(+), 28 deletions(-)
+
+commit 4b7f4dbc0cf58d87f4c91f059734e91e4d988480
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Sat Mar 30 13:48:32 2019 -0700
+
+    Add hb_deref_pointer()
+
+ src/hb-algs.hh | 18 +++++++++++++-----
+ src/hb-meta.hh |  8 ++++++++
+ 2 files changed, 21 insertions(+), 5 deletions(-)
+
+commit e5306927994e8e412dea5dd960b8b3ed4ca848eb
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Fri Mar 29 23:31:07 2019 -0700
+
+    [iter] Fix bug in hb_any() and hb_none()
+
+ src/hb-iter.hh               |  4 ++--
+ src/hb-ot-layout-gsubgpos.hh | 12 ++++++------
+ src/test-iter.cc             |  2 +-
+ 3 files changed, 9 insertions(+), 9 deletions(-)
+
+commit f505b5d5c9c05741a933b4b986503e1697bbdfdb
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Fri Mar 29 22:55:02 2019 -0700
+
+    [iter] Port remaining "for (auto" instances to daggers
+
+ src/hb-ot-layout-gsubgpos.hh | 35 +++++++++++++++++++++++------------
+ 1 file changed, 23 insertions(+), 12 deletions(-)
+
+commit 668d2d562fec797d779c6d6a43eb6e1c7cfbc07a
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Fri Mar 29 22:48:38 2019 -0700
+
+    [iter] One more dagger
+
+ src/hb-ot-layout-gsubgpos.hh | 13 +++++++------
+ 1 file changed, 7 insertions(+), 6 deletions(-)
+
+commit d51452500f909803a346f26c71cf4b3f84f619bd
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Fri Mar 29 22:48:12 2019 -0700
+
+    [iter] Remove more wrong &&'s
+    
+    Sigh...
+
+ src/hb-iter.hh | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 05f2130a1c479afe7982e8ddcfb3d83af9960e5b
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Fri Mar 29 22:40:13 2019 -0700
+
+    [iter] More daggers
+
+ src/hb-ot-layout-gsubgpos.hh | 110 +++++++++++++++++++++++++------------------
+ 1 file changed, 64 insertions(+), 46 deletions(-)
+
+commit 22ec4c3aa5aa41b7aa2a89290851ddd386273579
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Fri Mar 29 22:27:46 2019 -0700
+
+    [iter] More daggers
+
+ src/hb-ot-layout-gsubgpos.hh | 55 ++++++++++++++++++++++++++------------------
+ 1 file changed, 33 insertions(+), 22 deletions(-)
+
+commit 688069bbfb40d69fb141371633cd499d91324cc2
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Fri Mar 29 22:17:31 2019 -0700
+
+    [iter] One more dagger
+
+ src/hb-ot-layout-gsub-table.hh | 13 +++++--------
+ 1 file changed, 5 insertions(+), 8 deletions(-)
+
+commit 90b60bd6909ffc6d0bff3e6901057439460407ca
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Fri Mar 29 22:12:42 2019 -0700
+
+    Remove HB_DEBUG_WOULD_APPLY
+    
+    Not that useful.
+
+ src/hb-debug.hh                | 15 +---------
+ src/hb-ot-layout-gsub-table.hh | 49 ++++++++++----------------------
+ src/hb-ot-layout-gsubgpos.hh   | 64 ++++++++++++++++++------------------------
+ 3 files changed, 43 insertions(+), 85 deletions(-)
+
+commit 4d28267e59406cc85761131b84c5b2b4c65c6b35
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Fri Mar 29 22:04:15 2019 -0700
+
+    [iter] Port more to daggers
+
+ src/hb-ot-layout-gsub-table.hh | 22 +++++++++++-----------
+ 1 file changed, 11 insertions(+), 11 deletions(-)
+
+commit 9d8c72042b4a023b55cb39779407fdecaf098af1
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Fri Mar 29 21:59:28 2019 -0700
+
+    Whitespace
+
+ src/hb-ot-layout-gpos-table.hh | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 418e9d07e2120f806852312f4c74204fa085a6cc
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Fri Mar 29 21:57:26 2019 -0700
+
+    Simplify code
+
+ src/hb-ot-layout-gsub-table.hh | 20 +++-----------------
+ 1 file changed, 3 insertions(+), 17 deletions(-)
+
+commit f5ef8a7347656ad5f5bb8cec5f9a3de262a79411
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Fri Mar 29 21:57:17 2019 -0700
+
+    [iter] Port one more function to dagger
+
+ src/hb-ot-layout-gpos-table.hh | 14 ++++++++------
+ 1 file changed, 8 insertions(+), 6 deletions(-)
+
+commit bcab098c8f35ac4bef6618d949a7bf1d95869fa5
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Fri Mar 29 21:49:18 2019 -0700
+
+    [iter] Port more code to daggers
+
+ src/hb-ot-layout-gsub-table.hh | 14 ++++++++------
+ 1 file changed, 8 insertions(+), 6 deletions(-)
+
+commit 4c75158e1803e73d6126f715aa4b22ebe30aa7c7
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Fri Mar 29 21:46:13 2019 -0700
+
+    [iter] Port two more functions to daggers
+
+ src/hb-ot-layout-gsub-table.hh | 29 +++++++++++++++++------------
+ 1 file changed, 17 insertions(+), 12 deletions(-)
+
+commit e70ccbe9edd4d5e033df4afa728b3593ba9f78af
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Fri Mar 29 21:45:49 2019 -0700
+
+    Fix pair signature
+    
+    Oh well.  Again, who does fully understand what is right???
+
+ src/hb-algs.hh | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 6237b47f0c59fd3913b19b23800cdf83eaa01fb6
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Fri Mar 29 21:36:49 2019 -0700
+
+    [iter] Add hb_unzip()
+
+ src/hb-iter.hh | 38 ++++++++++++++++++++++++++++++++++++++
+ 1 file changed, 38 insertions(+)
+
+commit f1dad91eb3ce9dcdedbb4a0d6e34517db0154a84
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Fri Mar 29 21:17:08 2019 -0700
+
+    Whitespace
+
+ src/hb-ot-layout-gsub-table.hh | 3 +++
+ 1 file changed, 3 insertions(+)
+
+commit 896b31670d07cbe276feff1db249b64faa5c552c
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Fri Mar 29 21:16:30 2019 -0700
+
+    [iter] Port two more loops to dagger
+
+ src/hb-ot-layout-gsub-table.hh | 14 +++++++++-----
+ 1 file changed, 9 insertions(+), 5 deletions(-)
+
+commit 8e34cb251a9b22d6fbc637fd2f25965beb260270
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Fri Mar 29 21:14:20 2019 -0700
+
+    [iter] Remove unneeded &&
+    
+    Next commit needs this.  I never fully get this, sigh.
+
+ src/hb-iter.hh | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 12a4c0441ff13e56bb87f53eab45930c2a6142ed
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Fri Mar 29 21:06:10 2019 -0700
+
+    Whitespace
+
+ src/hb-ot-layout-gsub-table.hh | 12 ++++++------
+ 1 file changed, 6 insertions(+), 6 deletions(-)
+
+commit 4c38a9f6011a9b1dd6c4fc98620e23decc340322
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Fri Mar 29 20:23:07 2019 -0700
+
+    Remove hb_assign()
+    
+    Not needed anymore.  We just use operator= now.
+
+ src/hb-iter.hh      |  2 +-
+ src/hb-machinery.hh |  2 +-
+ src/hb-null.hh      | 13 -------------
+ src/hb-open-type.hh |  2 +-
+ 4 files changed, 3 insertions(+), 16 deletions(-)
+
+commit b986c6a321f7d997eba0a9308b651966644bf336
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Fri Mar 29 20:17:46 2019 -0700
+
+    [C++11] Remove IntType::set() in favor of operator=
+
+ src/hb-cff-interp-common.hh                |  4 +-
+ src/hb-ft.cc                               |  2 +-
+ src/hb-null.hh                             |  6 ---
+ src/hb-open-file.hh                        | 14 +++---
+ src/hb-open-type.hh                        | 43 +++++++++++------
+ src/hb-ot-cff-common.hh                    | 24 +++++-----
+ src/hb-ot-cff1-table.hh                    | 32 ++++++-------
+ src/hb-ot-cmap-table.hh                    | 77 +++++++++++++++---------------
+ src/hb-ot-glyf-table.hh                    |  2 +-
+ src/hb-ot-hdmx-table.hh                    | 12 ++---
+ src/hb-ot-hmtx-table.hh                    |  8 ++--
+ src/hb-ot-layout-common.hh                 | 44 ++++++++---------
+ src/hb-ot-layout-gdef-table.hh             |  8 ++--
+ src/hb-ot-layout-gsub-table.hh             | 18 +++----
+ src/hb-ot-maxp-table.hh                    | 16 +++----
+ src/hb-ot-os2-table.hh                     | 10 ++--
+ src/hb-ot-post-table.hh                    |  2 +-
+ src/hb-ot-shape-complex-arabic-fallback.hh | 10 ++--
+ src/hb-ot-vorg-table.hh                    | 12 ++---
+ src/hb-subset-cff-common.cc                | 12 ++---
+ src/hb-subset-cff-common.hh                |  2 +-
+ src/hb-subset-cff1.cc                      | 10 ++--
+ src/hb-subset-cff2.cc                      |  8 ++--
+ src/hb-subset-glyf.cc                      |  8 ++--
+ src/hb-uniscribe.cc                        | 22 ++++-----
+ 25 files changed, 206 insertions(+), 200 deletions(-)
+
+commit 58ad357951a732f05d9680573d00a4764171a9dd
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Fri Mar 29 20:05:19 2019 -0700
+
+    [vector] Accept all types in push(...)
+    
+    Let assignment operator worry about conversion.
+
+ src/hb-vector.hh | 6 ++++--
+ 1 file changed, 4 insertions(+), 2 deletions(-)
+
+commit 489faf826ca16e9bc89515869ebaf52653450b54
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Fri Mar 29 20:01:37 2019 -0700
+
+    [C++11] Use type aliases for template partial instantiations
+
+ src/hb-open-type.hh | 24 ++++++++++++++----------
+ 1 file changed, 14 insertions(+), 10 deletions(-)
+
+commit 4fd02f6ee58ebf7b4ecf0526328938c5bd74a180
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Fri Mar 29 17:57:59 2019 -0700
+
+    Remove unused line
+
+ src/hb-machinery.hh | 1 -
+ 1 file changed, 1 deletion(-)
+
+commit 9a5b15dc1eda4f34496bb942d78f0df4e975b469
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Fri Mar 29 17:57:24 2019 -0700
+
+    [C++11] Replace BEInt.set() with operator=
+
+ src/hb-machinery.hh | 15 +++++++++++----
+ src/hb-open-type.hh |  8 ++++----
+ 2 files changed, 15 insertions(+), 8 deletions(-)
+
+commit 0aa59b1de34ddebc242cca3ebddde6859269f5f1
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Fri Mar 29 17:49:55 2019 -0700
+
+    [C++11] Add operator= to IntType<>
+    
+    Now that we require C++11 we can do this.
+
+ src/hb-open-type.hh | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit eca466e6b1a3e29532af92a2d30b2555c0fafbfc
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Fri Mar 29 15:59:04 2019 -0700
+
+    Err.  Fixup C++11 polyfill removal
+    
+    Fixes 1d75db19fb5df139b9648ff3f5e6184a5c554345
+
+ src/hb.hh | 27 +++++++++++++++++++++------
+ 1 file changed, 21 insertions(+), 6 deletions(-)
+
+commit 3f36c89f2ea16e293f8af7e7f549ebcd7247ea97
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Fri Mar 29 15:22:46 2019 -0700
+
+    Inline explicit_operator macro
+    
+    Now that we require C++11, no need to macro.
+
+ src/hb-iter.hh      | 2 +-
+ src/hb-machinery.hh | 2 +-
+ src/hb-open-type.hh | 2 +-
+ src/hb-vector.hh    | 6 +++---
+ src/hb.hh           | 5 -----
+ 5 files changed, 6 insertions(+), 11 deletions(-)
+
+commit 1d75db19fb5df139b9648ff3f5e6184a5c554345
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Fri Mar 29 15:20:34 2019 -0700
+
+    Remove C++<11 polyfill
+    
+    Leaving hb-atomic.hh as is since harmless and other projects might
+    copy from that file.
+
+ src/hb.hh | 81 ---------------------------------------------------------------
+ 1 file changed, 81 deletions(-)
+
+commit 8e7887ca5f8a2822345bdcbdc873c73a31c81177
+Merge: 7929b0f0 90aebc6c
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Fri Mar 29 14:37:04 2019 -0700
+
+    Merge branch 'master' into iter
+
+commit 90aebc6cf1aaca281ce51cb8e23831d7167cdcd3
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Fri Mar 29 14:30:02 2019 -0700
+
+    Update RELEASING
+
+ RELEASING.md | 9 +++++----
+ 1 file changed, 5 insertions(+), 4 deletions(-)
+
+commit 7929b0f07e87a77687ea50205e6e4013c9264f85
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Fri Mar 29 14:14:55 2019 -0700
+
+    [ci] Fix build
+
+ .circleci/config.yml | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit b292772e6ef15728dd66329e637265748df0efe1
+Author: Ebrahim Byagowi <ebrahim@gnu.org>
+Date:   Fri Mar 29 13:00:56 2019 -0700
+
+    [dwrite] A new API, hb_directwrite_face_get_font_face (#1600)
+    
+    Can be useful when using HarfBuzz for font loading and shaping
+    but using DirectWrite for rendering.
+
+ docs/harfbuzz-sections.txt | 10 ++++++++--
+ src/hb-directwrite.cc      | 34 ++++++++++++++++++++++++++++++----
+ src/hb-directwrite.h       |  3 +++
+ 3 files changed, 41 insertions(+), 6 deletions(-)
+
+commit 59f36f36820f6e6fb1d3b6da26d6b5ee7588c42f
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Fri Mar 29 10:55:12 2019 -0700
+
+    Replace REPLACEME's left out of 2.4.0
+    
+    https://github.com/harfbuzz/harfbuzz/issues/1641
+
+ src/hb-common.h        | 2 +-
+ src/hb-directwrite.cc  | 2 +-
+ src/hb-subset-input.cc | 4 ++--
+ 3 files changed, 4 insertions(+), 4 deletions(-)
+
+commit fe570bc043ca2c6be71b18f7401c8f06e73527e0
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Fri Mar 29 10:51:38 2019 -0700
+
+    [docs] Remove unexisting section
+
+ docs/harfbuzz-docs.xml | 1 -
+ 1 file changed, 1 deletion(-)
+
+commit 443db2a24624b63c49fa3ad9a10d3b4c523af1ce
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Fri Mar 29 10:46:44 2019 -0700
+
+    [iter] Remove hb_len()
+    
+    Not planning on using it.  So remove.  Can add later if needed.
+
+ src/hb-iter.hh   | 8 --------
+ src/test-iter.cc | 2 --
+ 2 files changed, 10 deletions(-)
+
+commit bdd5a9c48d644b660f8fcac16902a576cc7ff443
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Thu Mar 28 21:58:07 2019 -0700
+
+    Add hb_hash()
+    
+    I don't like the hb_remove_reference() hack, but necessary.
+
+ src/hb-algs.hh | 17 +++++++++++++++++
+ src/hb-map.hh  | 10 +---------
+ src/hb.hh      |  2 +-
+ 3 files changed, 19 insertions(+), 10 deletions(-)
+
+commit 343e6063dcd512164a999f1d12bae50877392a82
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Thu Mar 28 21:44:12 2019 -0700
+
+    Add hb_is_integer(T)
+
+ src/hb-meta.hh | 14 ++++++++++++++
+ 1 file changed, 14 insertions(+)
+
+commit f639b9a8eab369bee6e36b3e60b585b4f720e77e
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Thu Mar 28 21:34:47 2019 -0700
+
+    [iter] Add hb_len() function-object
+
+ src/hb-iter.hh   | 8 ++++++++
+ src/test-iter.cc | 2 ++
+ 2 files changed, 10 insertions(+)
+
+commit a030ce4ff83e0948e4f865accc5670e8b5e78dde
+Merge: 11456b2d d6fc1d49
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Thu Mar 28 21:26:50 2019 -0700
+
+    Merge branch 'master' into iter
+
+commit d6fc1d49aa099104a889c96bc9087c21d8fc0960
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Thu Mar 28 21:21:26 2019 -0700
+
+    2.4.0
+
+ NEWS             | 11 +++++++++++
+ configure.ac     |  2 +-
+ src/hb-buffer.h  |  2 +-
+ src/hb-version.h |  6 +++---
+ 4 files changed, 16 insertions(+), 5 deletions(-)
+
+commit d2db71fdc4764eecf8320cf465ee0e4254146b6e
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Thu Mar 28 21:00:58 2019 -0700
+
+    Use internal bsearch() for language tags
+    
+    Fixes https://github.com/harfbuzz/harfbuzz/pull/1639
+
+ src/hb-ot-tag.cc | 46 ++++++++++++++++++++++------------------------
+ 1 file changed, 22 insertions(+), 24 deletions(-)
+
+commit 21bb80ebf2e20025a196386cee8fd92dd1eb4597
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Thu Mar 28 20:50:04 2019 -0700
+
+    [indic] Add back medial-consonant to grammar
+    
+    Fixes https://github.com/harfbuzz/harfbuzz/issues/1592
+
+ src/hb-ot-shape-complex-indic-machine.hh           | 1244 +++++++++++---------
+ src/hb-ot-shape-complex-indic-machine.rl           |    5 +-
+ src/hb-ot-shape-complex-indic.cc                   |    2 +-
+ src/hb-ot-shape-complex-indic.hh                   |    6 +-
+ .../f75c4b05a0a4d67c1a808081ae3d74a9c66509e8.ttf   |  Bin 0 -> 1924 bytes
+ .../data/in-house/tests/indic-syllable.tests       |    2 +
+ 6 files changed, 672 insertions(+), 587 deletions(-)
+
+commit 5ab6de7a6fbad4c4a954c2c81d216486a5a14f72
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Thu Mar 28 20:23:12 2019 -0700
+
+    [khmer] Add trailing Coeng to syllable grammar
+    
+    Fixes https://github.com/harfbuzz/harfbuzz/issues/1541
+
+ src/hb-ot-shape-complex-khmer-machine.hh           | 248 ++++++++++-----------
+ src/hb-ot-shape-complex-khmer-machine.rl           |   2 +-
+ .../ad01ab2ea1cb1a4d3a2783e2675112ef11ae6404.ttf   | Bin 0 -> 1500 bytes
+ test/shaping/data/in-house/tests/khmer-misc.tests  |   1 +
+ 4 files changed, 122 insertions(+), 129 deletions(-)
+
+commit 7360265e69a8cdaa9f993c36def2860a79cca49f
+Author: Ebrahim Byagowi <ebrahim@gnu.org>
+Date:   Thu Mar 28 16:57:56 2019 -0700
+
+    [ci] Tweak macos and psvita bots (#1638)
+    
+    * Add --with-graphite2 to macOS
+    * Add a dummy ragel script for psvita
+
+ .circleci/config.yml | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+commit a548d1da78b506cc6460fdde3715f6ef13ccad48
+Author: Ebrahim Byagowi <ebrahim@gnu.org>
+Date:   Thu Mar 28 15:42:45 2019 -0700
+
+    [ci] Use only CircleCI for macOS (#1637)
+
+ .circleci/config.yml |  5 +++--
+ .travis.yml          | 18 ------------------
+ 2 files changed, 3 insertions(+), 20 deletions(-)
+
+commit 160b4a2b01e925812fbf0e7db5bc9dcb90dc81cc
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Thu Mar 28 13:44:38 2019 -0700
+
+    Fix shell syntax error
+    
+    Fixes https://github.com/harfbuzz/harfbuzz/issues/1612
+
+ src/check-symbols.sh | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 8665b9b0a24e4d46e486057d72c0486b9da16523
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Thu Mar 28 11:11:52 2019 -0700
+
+    Comment
+
+ src/hb.hh | 1 +
+ 1 file changed, 1 insertion(+)
+
+commit a7eed7e41dba8e583a9c740a4ca7ddf53e77de63
+Author: punchcutter <zarijoscha@gmail.com>
+Date:   Wed Mar 27 23:12:58 2019 -0700
+
+    Override USE category for Grantha and Tirhuta visargas to allow marks
+
+ src/gen-use-table.py                 | 3 ++-
+ src/hb-ot-shape-complex-use-table.cc | 4 ++--
+ 2 files changed, 4 insertions(+), 3 deletions(-)
+
+commit cf040c0fef4a049a75a5ec7972f518b9034bdc76
+Author: Egor Pugin <egor.pugin@gmail.com>
+Date:   Thu Mar 28 19:06:12 2019 +0300
+
+    Disable unwanted C++ definitions for MSVC.
+    
+    MSVC does not set __cplusplus to the latest standard and also it does not like redefining some keywords.
+
+ src/hb.hh | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 717181c5943c13a682c719dce10bfc3d9cc47e6b
+Author: Ebrahim Byagowi <ebrahim@gnu.org>
+Date:   Wed Mar 27 16:38:39 2019 +0430
+
+    [ci] remove ragel from psvita compile bot
+
+ .circleci/config.yml | 1 -
+ 1 file changed, 1 deletion(-)
+
+commit 08e36c5d8be22b3a7e31f33af9452372dafeacc0
+Author: Ebrahim Byagowi <ebrahim@gnu.org>
+Date:   Wed Mar 27 16:21:47 2019 +0430
+
+    [ci] Don't install ragel on cmake build bot images
+    
+    It is not needed anyway
+
+ .circleci/config.yml | 5 -----
+ 1 file changed, 5 deletions(-)
+
+commit ec2a5dc859b03ceb92518aa992e4e9c053b30534
+Author: Behdad Esfahbod <behdad@fb.com>
+Date:   Tue Mar 26 16:18:03 2019 -0700
+
+    Use class templates for Null objects
+    
+    This allows partial-instantiating custom Null object for template Lookup<T>.
+    Before, this had to be handcoded per instantiation.  Apparently I missed
+    adding one for AAT::ankr.lookupTable, so it was getting the wrong (generic)
+    null for Lookup object, which is wrong and unsafe.
+    
+    Fixes https://bugs.chromium.org/p/chromium/issues/detail?id=944346
+
+ src/hb-aat-layout-common.hh                        |  14 ++++------
+ src/hb-null.hh                                     |  31 +++++++++++++--------
+ ...case-minimized-harfbuzz_fuzzer-5748102301614080 | Bin 0 -> 213 bytes
+ 3 files changed, 24 insertions(+), 21 deletions(-)
+
+commit 96f12377942dbe1c6b1d0ffa7d626d99cb265443
+Author: Behdad Esfahbod <behdad@fb.com>
+Date:   Tue Mar 26 16:17:45 2019 -0700
+
+    [aat] Add missing check to ankr table
+    
+    Isn't absolutely needed.  But helps.
+
+ src/hb-aat-layout-ankr-table.hh | 1 +
+ 1 file changed, 1 insertion(+)
+
+commit e5dfffb1ef610a982ed9878fbf3f9ee49cbc3a97
+Author: Behdad Esfahbod <behdad@fb.com>
+Date:   Mon Mar 25 15:15:37 2019 -0700
+
+    [docs] Update
+
+ docs/harfbuzz-docs.xml | 1 +
+ 1 file changed, 1 insertion(+)
+
+commit 0dd3fdf9d227f9bd79f395078f8e58dcfc32d1bf
+Author: Behdad Esfahbod <behdad@fb.com>
+Date:   Mon Mar 25 15:08:14 2019 -0700
+
+    Update ChangeLog generation
+    
+    Let's see if I can make a release on Mac...
+
+ Makefile.am | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 2d9034491eca0a63db82d3801f05c067a5241b7d
+Author: Qunxin Liu <qxliu@google.com>
+Date:   Tue Mar 26 10:37:24 2019 -0700
+
+    completely remove lines that are commented out
+
+ src/hb-subset-plan.cc | 6 ------
+ src/hb-subset-plan.hh | 3 ---
+ 2 files changed, 9 deletions(-)
+
+commit 3147133b6173487c26813a2a406aebd067b53fbf
+Author: Qunxin Liu <qxliu@google.com>
+Date:   Tue Mar 26 09:15:56 2019 -0700
+
+    update arguments in_populate_gids_to_retain() and _create_old_gid_to_new_gid_map()
+    so they don't use deprecated variable
+
+ src/hb-subset-plan.cc | 36 ++++++++++++++++++------------------
+ 1 file changed, 18 insertions(+), 18 deletions(-)
+
+commit 79a6c258497e80be15245a7b576e34443d9f7bff
+Author: Qunxin Liu <qxliu@google.com>
+Date:   Mon Mar 25 19:59:37 2019 -0700
+
+    try to remove deprecated variable from struct definition
+
+ src/hb-subset-plan.cc | 9 +++++----
+ src/hb-subset-plan.hh | 2 +-
+ 2 files changed, 6 insertions(+), 5 deletions(-)
+
+commit bcb4e505d6ffe33e3268a06698e75d6be0e64957
+Author: Michiharu Ariza <ariza@adobe.com>
+Date:   Fri Mar 15 13:46:25 2019 -0700
+
+    cff2 subset fuzzer issues (#1619)
+    
+    * add check to FDArray::serialize
+    
+    * add test files
+    
+    * fix off by one
+
+ src/hb-ot-cff-common.hh                                   |   1 +
+ ...z-testcase-minimized-hb-subset-fuzzer-5739000398086144 | Bin 0 -> 620 bytes
+ ...z-testcase-minimized-hb-subset-fuzzer-5760768497156096 | Bin 0 -> 210 bytes
+ ...z-testcase-minimized-hb-subset-fuzzer-5764268627066880 | Bin 0 -> 687 bytes
+ 4 files changed, 1 insertion(+)
+
+commit 8aaab78efcac81a05ec919be13792c98741ea1b5
+Author: Ebrahim Byagowi <ebrahim@gnu.org>
+Date:   Thu Mar 14 16:49:42 2019 -0700
+
+    Allow zero length ranges in sanitization (#1617)
+    
+    Fixes fvar table sanitization where there are no named instance
+    by allowing zero length ranges starting from Null() address.
+    
+    Fixes #1607
+
+ src/hb-machinery.hh      |  30 ++++++++++++++++--------------
+ test/api/fonts/Zycon.ttf | Bin 0 -> 21036 bytes
+ test/api/test-ot-face.c  |   9 +++++++++
+ 3 files changed, 25 insertions(+), 14 deletions(-)
+
+commit b1dfb8c850f36d4065190a779a6e3342a5fbb593
+Author: Khaled Hosny <khaledhosny@eglug.org>
+Date:   Thu Mar 14 21:41:25 2019 +0200
+
+    [ci] Cache FreeType build on Travis
+
+ .ci/build-freetype.sh | 17 +++++++++++++++++
+ .travis.yml           | 18 ++++++++++++------
+ 2 files changed, 29 insertions(+), 6 deletions(-)
+
+commit 7de9f92ee9ced6f4c176459cf25f4ca931ca5ceb
+Author: David Corbett <corbett.dav@husky.neu.edu>
+Date:   Tue Mar 12 19:30:47 2019 -0400
+
+    Categorize U+09FC as Consonant_Placeholder
+
+ src/hb-ot-shape-complex-indic.hh | 1 +
+ 1 file changed, 1 insertion(+)
+
+commit 8b1eaecd9485fe504af364db1537bb04852b265c
+Author: Khaled Hosny <khaledhosny@eglug.org>
+Date:   Wed Mar 13 13:21:12 2019 +0200
+
+    [ci] Simplify and fix Travis CI macOS build
+
+ .travis.yml | 16 +++++++++-------
+ 1 file changed, 9 insertions(+), 7 deletions(-)
+
+commit e52ec3fc23c2d5a881849f047885e0423bd74740
+Author: Behdad Esfahbod <behdad@fb.com>
+Date:   Mon Mar 11 18:09:51 2019 -0700
+
+    Remove redundant hb_ot_layout_lookup_would_substitute_fast
+
+ src/hb-ot-layout.cc              | 13 -------------
+ src/hb-ot-layout.hh              |  7 -------
+ src/hb-ot-shape-complex-indic.cc |  2 +-
+ src/hb-ot-shape-complex-khmer.cc |  2 +-
+ 4 files changed, 2 insertions(+), 22 deletions(-)
+
+commit c2442c90d6ecfaee987ed8ac6f93a9ac6b07c642
+Author: Khaled Hosny <khaledhosny@eglug.org>
+Date:   Tue Mar 12 01:09:27 2019 +0200
+
+    [doc] Add placeholder since version for new flag
+
+ src/hb-buffer.h | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 8c42f03215097d7c1bae74db7e98315263d3e8a4
+Author: David Corbett <corbett.dav@husky.neu.edu>
+Date:   Fri Mar 8 09:46:48 2019 -0500
+
+    Remove obsolete overrides from Indic/USE scripts
+
+ src/gen-indic-table.py               |  4 ----
+ src/gen-use-table.py                 | 30 +++++++-----------------------
+ src/hb-ot-shape-complex-use-table.cc |  2 +-
+ 3 files changed, 8 insertions(+), 28 deletions(-)
+
+commit b38bab86229bc40d9cdf4819d6dc6aab444d0291
+Author: Eric Muller <emuller@amazon.com>
+Date:   Tue Feb 12 11:41:16 2019 -0800
+
+    Update generation code for hb-ot-shape-complex-vowel-constraints.cc. Remove 'unlikely'
+
+ src/gen-vowel-constraints.py                 | 3 +++
+ src/hb-ot-shape-complex-vowel-constraints.cc | 2 +-
+ 2 files changed, 4 insertions(+), 1 deletion(-)
+
+commit 44a67ddeb878f7639b30d1884e38b1525aab4f4a
+Author: Eric Muller <emuller@amazon.com>
+Date:   Sun Feb 10 04:31:41 2019 -0800
+
+    Fix coding style.
+
+ src/hb-ot-shape-complex-hangul.cc | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+commit 30d7c40f8ce9f47d733b1f43a93f20739772859e
+Author: Eric Muller <emuller@amazon.com>
+Date:   Sat Feb 9 02:55:27 2019 -0800
+
+    Add a flag to hb_buffer_t to prevent the insertion of dotted circles on incorrect character sequences.
+    
+    Current behavior unchanged if this flag is not set (and it isn't by default).
+
+ src/hb-buffer.h                              | 7 ++++++-
+ src/hb-ot-shape-complex-hangul.cc            | 3 ++-
+ src/hb-ot-shape-complex-indic.cc             | 3 +++
+ src/hb-ot-shape-complex-khmer.cc             | 3 +++
+ src/hb-ot-shape-complex-myanmar.cc           | 3 +++
+ src/hb-ot-shape-complex-use.cc               | 3 +++
+ src/hb-ot-shape-complex-vowel-constraints.cc | 3 +++
+ src/hb-ot-shape.cc                           | 3 +++
+ 8 files changed, 26 insertions(+), 2 deletions(-)
+
+commit 8b6eb6cf465032d0ca747f4b75f6e9155082bc45
+Author: Ebrahim Byagowi <ebrahim@gnu.org>
+Date:   Fri Mar 8 01:33:41 2019 +0330
+
+    Add a macOS 10.14.3 fonts tests (#1608)
+
+ .circleci/config.yml                         | 11 +++++++++++
+ test/shaping/data/in-house/tests/macos.tests | 19 +++++++++++++++++++
+ 2 files changed, 30 insertions(+)
+
+commit e723c04de1b3dcd96e6a70baf09e3ae2ddbbc0bf
+Author: David Corbett <corbett.dav@husky.neu.edu>
+Date:   Wed Mar 6 12:37:25 2019 -0500
+
+    Update to Unicode 12.0.0
+
+ src/gen-use-table.py                         |    1 -
+ src/gen-vowel-constraints.py                 |    1 +
+ src/hb-common.h                              |    8 +
+ src/hb-ot-shape-complex-arabic-table.hh      |   14 +-
+ src/hb-ot-shape-complex-indic-table.cc       |   56 +-
+ src/hb-ot-shape-complex-use-table.cc         |   49 +-
+ src/hb-ot-shape-complex-vowel-constraints.cc |    4 +-
+ src/hb-ot-shape-complex.hh                   |    3 +
+ src/hb-ot-tag-table.hh                       |   12 +-
+ src/hb-ucdn.cc                               |    4 +
+ src/hb-ucdn/ucdn.h                           |   11 +
+ src/hb-ucdn/ucdn_db.h                        | 2998 +++++++++++++-------------
+ src/hb-unicode-emoji-table.hh                |    6 +-
+ 13 files changed, 1631 insertions(+), 1536 deletions(-)
+
+commit 2f125b0fa763c3be7d8d74489c027f7155607756
+Author: Adrian Wong <adrianwjw@gmail.com>
+Date:   Wed Feb 13 21:04:46 2019 +1100
+
+    [indic] Remove superfluous ZWNJ check in final reorder of pre-base matras
+
+ src/hb-ot-shape-complex-indic.cc | 11 ++++++++---
+ 1 file changed, 8 insertions(+), 3 deletions(-)
+
+commit d936ad4582a0017cf88406372d7c08b9896beed6
+Author: Stephan Bergmann <sbergman@redhat.com>
+Date:   Tue Mar 5 17:18:57 2019 +0100
+
+    Fix hb_atomic_* variants based on C++11 atomics
+    
+    I stumbled over this when trying to upgrade the version of HarfBuzz used by
+    LibreOffice to 3.2.1 (see <https://gerrit.libreoffice.org/plugins/gitiles/core/
+    +/b7ddc514bff9bdf682abae537f990aa01dc2c0fb%5E!/> "Upgrade to latest
+    HarfBuzz 2.3.1"), where building with MSVC 2017 failed like
+    
+    > c:\cygwin\home\tdf\lode\jenkins\workspace\gerrit_windows\workdir\unpackedtarball\harfbuzz\src\hb-atomic.hh(272): error C2440: 'reinterpret_cast': cannot convert from 'const int *' to 'std::atomic<int> *'
+    > c:\cygwin\home\tdf\lode\jenkins\workspace\gerrit_windows\workdir\unpackedtarball\harfbuzz\src\hb-atomic.hh(272): note: Conversion loses qualifiers
+    > c:\cygwin\home\tdf\lode\jenkins\workspace\gerrit_windows\workdir\unpackedtarball\harfbuzz\src\hb-atomic.hh(272): error C2227: left of '->load' must point to class/struct/union/generic type
+    
+    (see <https://ci.libreoffice.org/job/gerrit_windows/29916/>).
+    
+    I added all the necessary "const" to make building of HarfBuzz 2.3.1 with
+    MSVC 2017 succeed for me.  There may be more missing at least conceptually.
+
+ src/hb-atomic.hh | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+commit 731b13e4e9190a45e51f855f19e88869a7718d43
+Author: Martin Hosken <martin_hosken@sil.org>
+Date:   Mon Mar 4 11:12:21 2019 +0700
+
+    Fix offset drift in graphite integration
+
+ src/hb-graphite2.cc | 35 +++++++++++++++++++----------------
+ 1 file changed, 19 insertions(+), 16 deletions(-)
+
+commit 8a25868e6a41a3d82782aadb3c7b744ad87d20ff
+Author: Ebrahim Byagowi <ebrahim@gnu.org>
+Date:   Sat Mar 2 03:24:49 2019 +0330
+
+    Minor, remove .editorconfig hack
+    
+    As vscode is going to support it soon
+
+ .editorconfig | 7 ++-----
+ 1 file changed, 2 insertions(+), 5 deletions(-)
+
+commit 4f37ab63de9705d7bf74ee75364747e41b7c06a1
+Author: Garret Rieger <grieger@google.com>
+Date:   Thu Feb 28 17:25:05 2019 -0800
+
+    Make hb_subset_input_glyph_set () actually do something.
+
+ src/hb-subset-plan.cc       |  3 +++
+ test/api/hb-subset-test.h   | 11 ++++++++++-
+ test/api/test-subset-glyf.c | 24 ++++++++++++++++++++++++
+ 3 files changed, 37 insertions(+), 1 deletion(-)
+
+commit 45149eb34f9735b5d690a2a7956adb42b938c8d9
+Author: Ebrahim Byagowi <ebrahim@gnu.org>
+Date:   Fri Feb 22 13:13:42 2019 +0330
+
+    [dwrite] hb_directwrite_face_create, a new API
+    
+    It makes a hb_face_t from IDWriteFontFace, useful when using
+    DirectWrite facilities for font selection, loading and rendering
+    but using harfbuzz for shaping.
+
+ src/hb-directwrite.cc | 70 +++++++++++++++++++++++++++++++++++++++++++++++----
+ src/hb-directwrite.h  |  5 +++-
+ 2 files changed, 69 insertions(+), 6 deletions(-)
+
+commit 45adc185260f0fa1fa86472aafb7f91f942c567e
+Author: David Corbett <corbett.dav@husky.neu.edu>
+Date:   Mon Feb 18 22:30:40 2019 -0500
+
+    Fix or document unsupported font-feature-settings
+
+ src/hb-common.cc | 18 ++++++++++++------
+ util/options.cc  |  3 ++-
+ 2 files changed, 14 insertions(+), 7 deletions(-)
+
+commit d66f7e14a0097d8ca54ad9824f7aa7daee6c7f72
+Author: Joël R. Langlois <joel.r.langlois@gmail.com>
+Date:   Mon Feb 25 15:26:58 2019 -0500
+
+    Remove Forcing Diagnostic Colours from CMakeLists.txt (#1597)
+    
+    Fixes https://github.com/harfbuzz/harfbuzz/issues/1596
+
+ CMakeLists.txt | 12 ------------
+ 1 file changed, 12 deletions(-)
+
+commit 93739242e1aab9b745d0ba3c22c33b4acaf9526c
+Author: Michiharu Ariza <ariza@adobe.com>
+Date:   Wed Feb 20 13:23:12 2019 -0800
+
+    minor edit
+
+ src/hb-map.hh | 3 +--
+ 1 file changed, 1 insertion(+), 2 deletions(-)
+
+commit eebc21c8de08d58c806fcd3d0f3a5aedee867776
+Author: Michiharu Ariza <ariza@adobe.com>
+Date:   Wed Feb 20 12:43:18 2019 -0800
+
+    fix crash in hb_map_t::clear()
+    
+    in case called immediately after init()
+
+ src/hb-map.hh | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+commit a17ed8459ee1e01caf4761f682bcda821bc8e656
+Author: Khaled Hosny <khaledhosny@eglug.org>
+Date:   Tue Feb 19 21:14:11 2019 +0200
+
+    [doc] Move hb_variation_t to hb-common section
+
+ docs/harfbuzz-sections.txt | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+commit 9caabc9cf898e1d66921f88890d5b7d46494dc90
+Author: Khaled Hosny <khaledhosny@eglug.org>
+Date:   Tue Feb 19 19:27:28 2019 +0200
+
+    [doc] Move feature_t and its function to hb-common
+    
+    It is rather confusing to have script, language etc, in hb-common section
+    while feature is in hb-shape section. I keep looking for it in hb-common
+    section then using the API index because I can’t find it there.
+
+ docs/harfbuzz-sections.txt | 10 +++++-----
+ 1 file changed, 5 insertions(+), 5 deletions(-)
+
+commit d29c8424c8bfa47c910d0e270f05b5c0a1f803a2
+Author: Evgeniy Reizner <razrfalcon@gmail.com>
+Date:   Tue Feb 19 18:35:00 2019 +0200
+
+    Typo (#1588)
+    
+    Fixed a small typo.
+    [skip ci]
+
+ src/hb-ot-font.cc | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 6bd4c082e49143d0631881645b81f999347257f8
+Author: Khaled Hosny <khaledhosny@eglug.org>
+Date:   Tue Feb 19 02:23:58 2019 +0200
+
+    [doc] Document hb_feature_from_string() syntax
+    
+    Copied and edited from the util option documentation. The docbook table
+    syntax is too verbose, but that is the best I can come up with.
+
+ src/hb-common.cc | 35 ++++++++++++++++++++++++++++++++++-
+ 1 file changed, 34 insertions(+), 1 deletion(-)
+
+commit 11456b2d9c1c567d1ad6496a3056154b69cafa21
+Author: Behdad Esfahbod <behdad@fb.com>
+Date:   Fri Feb 15 16:58:43 2019 -0800
+
+    WHitespace
+
+ src/hb-ot-layout-gsubgpos.hh | 4 ----
+ 1 file changed, 4 deletions(-)
+
+commit 77060bcda229dc237d3952fbf5da59709cd81e05
+Author: Behdad Esfahbod <behdad@fb.com>
+Date:   Fri Feb 15 16:55:08 2019 -0800
+
+    [iter] Add hb_all, hb_any, hb_none
+
+ src/hb-iter.hh   | 46 +++++++++++++++++++++++++++++++++++++++++++++-
+ src/test-iter.cc |  2 ++
+ 2 files changed, 47 insertions(+), 1 deletion(-)
+
+commit 72dd5e34e0fc2902857c39cd4609d40b71fa4736
+Author: Behdad Esfahbod <behdad@fb.com>
+Date:   Fri Feb 15 16:11:32 2019 -0800
+
+    [iter] Make hb_iter() into function-object
+
+ src/hb-iter.hh | 28 +++++++++++++++++++---------
+ 1 file changed, 19 insertions(+), 9 deletions(-)
+
+commit 98be7bd77ada32e58dad76897cefcf1d99538d2b
+Author: Behdad Esfahbod <behdad@fb.com>
+Date:   Fri Feb 15 16:09:29 2019 -0800
+
+    [iter] Make hb_map into function-object
+
+ src/hb-iter.hh | 11 +++++++----
+ 1 file changed, 7 insertions(+), 4 deletions(-)
+
+commit c1e5ba81fe4888143c1cf4a3deb3597875580c6d
+Merge: b8b3b3e3 3da79dd5
+Author: Behdad Esfahbod <behdad@fb.com>
+Date:   Fri Feb 15 16:06:03 2019 -0800
+
+    Merge remote-tracking branch 'origin/master' into iter
+
+commit b8b3b3e38b08ee7bb8d44481dd25febcee693554
+Author: Behdad Esfahbod <behdad@fb.com>
+Date:   Fri Feb 15 16:05:36 2019 -0800
+
+    [iter] Add hb_enumerate() and use it
+
+ src/hb-iter.hh               | 39 +++++++++++++++++++++++++++++++++++++--
+ src/hb-ot-layout-gsubgpos.hh | 32 ++++++++++++--------------------
+ 2 files changed, 49 insertions(+), 22 deletions(-)
+
+commit 3da79dd5b92b89fbf062cbe591e6b1ba83083aec
+Merge: 50005501 d8a68728
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Fri Feb 15 15:54:51 2019 -0800
+
+    Merge pull request #1557 from harfbuzz/cff-more-arrayof-fixes
+    
+    CFF more arrayof fixes
+
+commit 5000550183022db8c9cfef63a9ed90eb9f37764d
+Merge: 5c2bb1de 90c8bbf9
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Fri Feb 15 15:54:13 2019 -0800
+
+    Merge pull request #1583 from harfbuzz/cff-retain-gids
+    
+    [subset] Implement --retain-gids with CFF/CFF2
+
+commit d8a68728a077a8c5fc8ceae19f2866cdc8b70baf
+Merge: 1cb1d5d7 5c2bb1de
+Author: Michiharu Ariza <ariza@adobe.com>
+Date:   Fri Feb 15 14:48:10 2019 -0800
+
+    Merge branch 'master' into cff-more-arrayof-fixes
+
+commit 90c8bbf98747eb29687471da892b4a34a9236242
+Merge: 6f1dfd08 5c2bb1de
+Author: Michiharu Ariza <ariza@adobe.com>
+Date:   Fri Feb 15 14:47:38 2019 -0800
+
+    Merge branch 'master' into cff-retain-gids
+
+commit 5c2bb1de8de31fecf0dae2ef905b896e42d39f1d
+Author: Martin <44297768+TheRealMDoerr@users.noreply.github.com>
+Date:   Fri Feb 15 19:23:46 2019 +0100
+
+    Support xlclang++ on AIX. (#1584)
+
+ src/hb-atomic.hh | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 1558a43342e2c5649cf48cb5860ac8a7aa9faf1d
+Author: Behdad Esfahbod <behdad@fb.com>
+Date:   Thu Feb 14 20:46:13 2019 -0800
+
+    [test] Minor
+
+ src/test-algs.cc | 1 +
+ 1 file changed, 1 insertion(+)
+
+commit fa373584def11c97d8a7db00d9abc04851ca9480
+Author: Behdad Esfahbod <behdad@fb.com>
+Date:   Thu Feb 14 20:15:07 2019 -0800
+
+    [algs] Test pair more
+
+ src/test-algs.cc | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+commit 0d7af5fb02723d8f4e8ad93848e9abe384174b36
+Author: Behdad Esfahbod <behdad@fb.com>
+Date:   Thu Feb 14 19:37:57 2019 -0800
+
+    [algs] Use universal references for hb_pair()
+    
+    Such that it carries lvalues inside.
+
+ src/Makefile.am  |  6 +++++-
+ src/hb-algs.hh   |  2 +-
+ src/test-algs.cc | 45 +++++++++++++++++++++++++++++++++++++++++++++
+ 3 files changed, 51 insertions(+), 2 deletions(-)
+
+commit 5b99c92d4c6e294bb328113308e5c9cd23b3ed67
+Author: Behdad Esfahbod <behdad@fb.com>
+Date:   Thu Feb 14 17:10:04 2019 -0800
+
+    [iter] Use more
+
+ src/hb-iter.hh               |  4 ++--
+ src/hb-ot-layout-gsubgpos.hh | 10 ++++------
+ 2 files changed, 6 insertions(+), 8 deletions(-)
+
+commit 72c1b59588bec30322abfa4de04b53e93122b25b
+Author: Behdad Esfahbod <behdad@fb.com>
+Date:   Thu Feb 14 15:43:20 2019 -0800
+
+    [iter] Use in more places
+
+ src/hb-ot-layout-gsubgpos.hh | 48 ++++++++++++++++++--------------------------
+ 1 file changed, 20 insertions(+), 28 deletions(-)
+
+commit 40cce41eaeac731334251cccaa124407e6bffccb
+Author: Behdad Esfahbod <behdad@fb.com>
+Date:   Thu Feb 14 15:14:37 2019 -0800
+
+    [iter] Use in a couple more intersects() calls
+
+ src/hb-ot-layout-gsubgpos.hh | 10 ++++------
+ 1 file changed, 4 insertions(+), 6 deletions(-)
+
+commit bafdf1829d15e658df55eabc0548e9ca71d18b1b
+Author: Behdad Esfahbod <behdad@fb.com>
+Date:   Thu Feb 14 15:13:16 2019 -0800
+
+    [iter] Use in a couple more closure() calls
+
+ src/hb-ot-layout-gsubgpos.hh | 10 ++++------
+ 1 file changed, 4 insertions(+), 6 deletions(-)
+
+commit fa35d3fd81c1ddb847cdd83556f817db9ef7f35b
+Author: Behdad Esfahbod <behdad@fb.com>
+Date:   Thu Feb 14 14:04:05 2019 -0800
+
+    [iter] Add hb_drain
+
+ src/hb-iter.hh   | 11 +++++++++++
+ src/test-iter.cc |  7 ++++++-
+ 2 files changed, 17 insertions(+), 1 deletion(-)
+
+commit f4cfd6b6adbe0a87fe565a29b6cd600cf86f65dd
+Author: Behdad Esfahbod <behdad@fb.com>
+Date:   Thu Feb 14 13:45:52 2019 -0800
+
+    [iter] A couple more hb_apply() + lambda uses
+
+ src/hb-ot-layout-gsub-table.hh | 16 +++++++++-------
+ 1 file changed, 9 insertions(+), 7 deletions(-)
+
+commit 7514a49f217c42ae0c895755e305f1d5b75c759d
+Author: Behdad Esfahbod <behdad@fb.com>
+Date:   Thu Feb 14 13:16:33 2019 -0800
+
+    [iter] Use hb_apply() with lambda functions in a few places
+
+ src/hb-ot-layout-gsub-table.hh | 30 +++++++++++++++++-------------
+ 1 file changed, 17 insertions(+), 13 deletions(-)
+
+commit 0670e1a6f5d9938d30d5d0674ea10752d4a58114
+Author: Behdad Esfahbod <behdad@fb.com>
+Date:   Thu Feb 14 11:53:40 2019 -0800
+
+    [iter] Remove excess use of universal references
+    
+    Every time I have to study these to understand why a change is right..
+
+ src/hb-iter.hh | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+commit 773d75637c36426b96be43f1188c68d77ac4ba47
+Author: Behdad Esfahbod <behdad@fb.com>
+Date:   Thu Feb 14 11:40:22 2019 -0800
+
+    [iter] Add hb_apply()
+
+ src/hb-iter.hh   | 30 ++++++++++++++++++++++++++++++
+ src/test-iter.cc |  3 +++
+ 2 files changed, 33 insertions(+)
+
+commit 5b725784e53a96ba4d983184a2670aba2aa0fd9c
+Merge: 00db9409 28f77361
+Author: Behdad Esfahbod <behdad@fb.com>
+Date:   Thu Feb 14 11:34:55 2019 -0800
+
+    Merge branch 'master' into iter
+
+commit 28f77361322886360743fdbffd388c9482cf4257
+Author: Behdad Esfahbod <behdad@fb.com>
+Date:   Thu Feb 14 11:34:28 2019 -0800
+
+    [CI] Install more packages
+    
+    Wish there was a way to streamline this :(.
+
+ .circleci/config.yml | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+commit 00db94095d53bd5e954be31caa428a3fd8f5f4c2
+Author: Behdad Esfahbod <behdad@fb.com>
+Date:   Thu Feb 14 11:10:13 2019 -0800
+
+    [iter] Make hb_filter() a function-object
+
+ src/hb-iter.hh | 13 ++++++++-----
+ 1 file changed, 8 insertions(+), 5 deletions(-)
+
+commit aa4c3212628f6861f1ef3ecb9eb5205b5780ac91
+Author: Behdad Esfahbod <behdad@fb.com>
+Date:   Thu Feb 14 11:07:12 2019 -0800
+
+    [iter] Make hb_zip() a function-object
+
+ src/hb-iter.hh | 13 ++++++++-----
+ 1 file changed, 8 insertions(+), 5 deletions(-)
+
+commit f8fcfb263e197c27015eeea56761b2dc8138da91
+Author: Behdad Esfahbod <behdad@fb.com>
+Date:   Thu Feb 14 11:03:29 2019 -0800
+
+    [iter] Accept pointers to hb_sink()
+
+ src/hb-iter.hh                 | 4 ++++
+ src/hb-ot-layout-gsub-table.hh | 6 +++---
+ 2 files changed, 7 insertions(+), 3 deletions(-)
+
+commit b530573ad9b30e06d5cecfd107941c573cd5d999
+Author: Behdad Esfahbod <behdad@fb.com>
+Date:   Thu Feb 14 11:00:10 2019 -0800
+
+    [iter] Make hb_sink function-object
+
+ src/hb-iter.hh | 11 ++++++-----
+ 1 file changed, 6 insertions(+), 5 deletions(-)
+
+commit bb139cb8d0e4339042c5d0d0f192e13707c2bda4
+Author: Behdad Esfahbod <behdad@fb.com>
+Date:   Thu Feb 14 10:51:47 2019 -0800
+
+    [iter] Back to dagger formatting for pipelines
+
+ src/hb-ot-layout-gsub-table.hh | 9 ++++++---
+ 1 file changed, 6 insertions(+), 3 deletions(-)
+
+commit 5fa52e62b1744347970c42f42bbcd8d2e82d6c60
+Author: Behdad Esfahbod <behdad@fb.com>
+Date:   Thu Feb 14 10:51:02 2019 -0800
+
+    [iter] Accept iterator, not iterable, in hb_sink()()
+
+ src/hb-iter.hh   | 8 ++++----
+ src/test-iter.cc | 1 +
+ 2 files changed, 5 insertions(+), 4 deletions(-)
+
+commit 0f292ea85f54b3496fe87e6466acf43b76f57dcd
+Author: Behdad Esfahbod <behdad@fb.com>
+Date:   Thu Feb 14 10:49:31 2019 -0800
+
+    [iter] Accept iterator, not iterable, in hb_filter()()
+
+ src/hb-iter.hh | 10 +++++-----
+ 1 file changed, 5 insertions(+), 5 deletions(-)
+
+commit 345bfbb207b4d1174ee0ec41cf35cdc2e14936ff
+Author: Behdad Esfahbod <behdad@fb.com>
+Date:   Thu Feb 14 10:48:20 2019 -0800
+
+    [iter] Accept iterator, not iterable, in hb_map()()
+
+ src/hb-iter.hh | 10 +++++-----
+ 1 file changed, 5 insertions(+), 5 deletions(-)
+
+commit 16cc313dcd7d4ddf16451cadc118aeb680101384
+Author: Behdad Esfahbod <behdad@fb.com>
+Date:   Thu Feb 14 10:40:05 2019 -0800
+
+    [iter] Use hb_sink()
+
+ src/hb-ot-layout-gsub-table.hh | 22 +++++++++++-----------
+ 1 file changed, 11 insertions(+), 11 deletions(-)
+
+commit b702a0cbf8abae4622a99adf3a3b6adda3d9f2c1
+Author: Behdad Esfahbod <behdad@fb.com>
+Date:   Thu Feb 14 10:39:58 2019 -0800
+
+    [iter] Add hb_sink()
+
+ src/hb-iter.hh | 25 +++++++++++++++++++++++++
+ 1 file changed, 25 insertions(+)
+
+commit 1cb1d5d7fb74e9f42dc8361dcdf669ed479d595d
+Merge: 8a568a88 d5287e1b
+Author: Michiharu Ariza <ariza@adobe.com>
+Date:   Thu Feb 14 10:09:19 2019 -0800
+
+    Merge branch 'master' into cff-more-arrayof-fixes
+
+commit 6f1dfd082cf79488ae6773e7d99172f13575668c
+Merge: b1dbc77f d5287e1b
+Author: Michiharu Ariza <ariza@adobe.com>
+Date:   Thu Feb 14 10:08:16 2019 -0800
+
+    Merge branch 'master' into cff-retain-gids
+
+commit 9e7383d124f1f1422f542720c76b4ee9605bda8b
+Author: Behdad Esfahbod <behdad@fb.com>
+Date:   Wed Feb 13 23:54:36 2019 -0800
+
+    [CI] Disable cmake-oracledeveloperstudio bot
+    
+    Weird error:
+    
+    "/root/project/src/hb-iter.hh", line 277: Error: Type name expected instead of "decltype()".
+    "/root/project/src/hb-iter.hh", line 278: Error: Invalid type while substituting into Iter::item_t.
+    "/root/project/src/hb-iter.hh", line 317: Error: Type name expected instead of "decltype()".
+    "/root/project/src/hb-iter.hh", line 318: Error: Invalid type while substituting into Iter::item_t.
+
+ .circleci/config.yml | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 4103252323b15a821f0a912b580c2107211b918f
+Merge: f1b89344 d5287e1b
+Author: Behdad Esfahbod <behdad@fb.com>
+Date:   Wed Feb 13 23:46:43 2019 -0800
+
+    Merge branch 'master' into iter
+
+commit d5287e1ba40638be5d48178ce3d64557b622b01f
+Author: Behdad Esfahbod <behdad@fb.com>
+Date:   Wed Feb 13 23:46:17 2019 -0800
+
+    [CI] Install wget on clang-O3-O0 bot
+
+ .circleci/config.yml | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit f1b8934400137fe832909730ad86d73595612e9e
+Author: Behdad Esfahbod <behdad@fb.com>
+Date:   Wed Feb 13 23:30:21 2019 -0800
+
+    [CI] Remove macos-notest-ios bot
+    
+    Not sure what ancient compiler it is (gcc 4.2?), but didn't like hb_zip SFINAE
+    apparently:
+    
+    In file included from /Users/distiller/project/src/hb-aat-layout.cc:28:
+    In file included from /Users/distiller/project/src/hb-open-type.hh:32:
+    In file included from /Users/distiller/project/src/hb.hh:642:
+    /Users/distiller/project/src/hb-iter.hh:364:1: note: candidate template ignored: substitution failure [with A = OT::Coverage, B = OT::OffsetArrayOf<OT::ChainRuleSet>]: non-type template argument does not refer to any declaration
+    hb_zip (const A& a, const B &b)
+    ^
+    In file included from /Users/distiller/project/src/hb-aat-layout.cc:37:
+    In file included from /Users/distiller/project/src/hb-aat-layout-kerx-table.hh:31:
+    In file included from /Users/distiller/project/src/hb-kern.hh:32:
+    /Users/distiller/project/src/hb-ot-layout-gpos-table.hh:725:20: error: no matching function for call to 'hb_zip'
+        for (auto it = hb_zip (this+coverage, pairSet)
+                       ^~~~~~
+    
+    Not going to try to appease.
+
+ .circleci/config.yml | 13 -------------
+ 1 file changed, 13 deletions(-)
+
+commit 7d2376de336c7fc14d69e01add02115335f92db8
+Merge: 2d940946 890d0ee7
+Author: Behdad Esfahbod <behdad@fb.com>
+Date:   Wed Feb 13 22:08:54 2019 -0800
+
+    Merge branch 'master' into iter
+
+commit 890d0ee77fecd6aa4f19b663bb2897735a0d4c0b
+Author: Ebrahim Byagowi <ebrahim@gnu.org>
+Date:   Thu Feb 14 00:27:01 2019 +0330
+
+    Minor, use a meaningful naming in template parameter (#1582)
+
+ src/hb-ot-layout.hh | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+commit 8a568a8858b44a81ca43a82761a70bf8d53e7c26
+Merge: c83412e4 1e1d0e63
+Author: Michiharu Ariza <ariza@adobe.com>
+Date:   Wed Feb 13 11:25:00 2019 -0800
+
+    Merge branch 'master' into cff-more-arrayof-fixes
+
+commit b1dbc77fa62a99047df539663cfd1e8778d2c907
+Merge: c3a3536c 1e1d0e63
+Author: Michiharu Ariza <ariza@adobe.com>
+Date:   Wed Feb 13 11:24:38 2019 -0800
+
+    Merge branch 'master' into cff-retain-gids
+
+commit 1e1d0e63df405730ed542ae1d729928623addf08
+Author: Ebrahim Byagowi <ebrahim@gnu.org>
+Date:   Wed Feb 13 12:58:01 2019 +0330
+
+    Fix djgpp complains by tweaking templates (#1579)
+    
+    For some reasons djgpp doesn't understand "unsigned int" can be same
+    with one of uint*_t anyway so lets do that for it explicitly.
+    
+    Just to note, our CI's djgpp is based GCC 7.2.0 and isn't old.
+
+ src/hb-ot-layout.hh               | 4 ++--
+ src/hb-ot-shape-complex-arabic.cc | 6 +++---
+ 2 files changed, 5 insertions(+), 5 deletions(-)
+
+commit c3a3536c9a00a989ebd83d52e67d06525ed669bc
+Merge: bc33c617 85a6d312
+Author: Michiharu Ariza <ariza@adobe.com>
+Date:   Tue Feb 12 15:10:59 2019 -0800
+
+    Merge branch 'cff-retain-gids' of https://github.com/harfbuzz/harfbuzz into cff-retain-gids
+
+commit bc33c617b85988f4d81312e62a75f92601852c76
+Merge: c6af8461 fdfa3d29
+Author: Michiharu Ariza <ariza@adobe.com>
+Date:   Tue Feb 12 15:10:50 2019 -0800
+
+    Merge branch 'master' into cff-retain-gids
+
+commit c6af846178bba10af318bcea1e9ac5165ec2aea6
+Author: Michiharu Ariza <ariza@adobe.com>
+Date:   Tue Feb 12 15:10:43 2019 -0800
+
+    tweaked --desubroutinize to remove hintmask only subrs
+
+ src/hb-subset-cff-common.hh | 26 ++++++++++++++++++++++++--
+ 1 file changed, 24 insertions(+), 2 deletions(-)
+
+commit 85a6d3121a26c9bcbec60d37b64643ff8dc97a0a
+Merge: d9ded069 fdfa3d29
+Author: Michiharu Ariza <ariza@adobe.com>
+Date:   Mon Feb 11 14:25:21 2019 -0800
+
+    Merge branch 'master' into cff-retain-gids
+
+commit c83412e4cec10f6f6f6ac38f202b3ce373da5daf
+Merge: 1239b6b2 fdfa3d29
+Author: Michiharu Ariza <ariza@adobe.com>
+Date:   Mon Feb 11 14:16:25 2019 -0800
+
+    Merge branch 'master' into cff-more-arrayof-fixes
+
+commit fdfa3d29b7c347b5038f4f9148428c80dde462ae
+Author: Ken <21211439+kencu@users.noreply.github.com>
+Date:   Sun Feb 10 23:46:05 2019 -0800
+
+    hb-coretext.cc: remove TARGET_OS_MAC from test (#1578)
+    
+    it is always true when building on APPLE systems
+    and this file only builds on APPLE systems
+
+ src/hb-coretext.cc | 10 +++++-----
+ 1 file changed, 5 insertions(+), 5 deletions(-)
+
+commit f55e7bf5835c59e478d6a448327d53027c4e9f4a
+Author: Ebrahim Byagowi <ebrahim@gnu.org>
+Date:   Sun Feb 10 01:08:05 2019 +0330
+
+    [ci] Install 'base-devel' on ArchLinux CI bot
+
+ .circleci/config.yml | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 8f4eb919bd0498e997852aa39656adc4c65b3f0e
+Author: Ebrahim Byagowi <ebrahim@gnu.org>
+Date:   Sat Feb 9 16:58:02 2019 +0330
+
+    [ci] Install 'which' in ArchLinux bot
+
+ .circleci/config.yml | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 02294349618037f59b32834b49880ca75ed96261
+Author: Ebrahim Byagowi <ebrahim@gnu.org>
+Date:   Sat Feb 9 16:33:28 2019 +0330
+
+    [ci] Speculative fix for Alpine and ArchLinux bots
+
+ .circleci/config.yml | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+commit d9ded069926bf46a5d8e5edbf5201c98044db78e
+Merge: a5e933eb 84694af7
+Author: Michiharu Ariza <ariza@adobe.com>
+Date:   Fri Feb 8 14:44:20 2019 -0800
+
+    Merge branch 'master' into cff-retain-gids
+
+commit a5e933eba08ff50ac3beb1055ae952ccc26d0af7
+Author: Michiharu Ariza <ariza@adobe.com>
+Date:   Fri Feb 8 14:44:13 2019 -0800
+
+    Updated expected/cff-japanese fonts with retained FDs
+
+ ...gular.default.3042,3044,3046,3048,304A,304B.otf |    Bin 6324 -> 6356 bytes
+ ...gular.default.3042,3044,3046,73E0,5EA6,8F38.otf |    Bin 6568 -> 6564 bytes
+ .../SourceHanSans-Regular.default.61,63,65,6B.otf  |    Bin 5500 -> 5532 bytes
+ ...gular.default.660E,6975,73E0,5EA6,8F38,6E05.otf |    Bin 6780 -> 6780 bytes
+ .../SourceHanSans-Regular.default.660E.otf         |    Bin 5248 -> 5248 bytes
+ ...e-retain-gids.3042,3044,3046,3048,304A,304B.otf |    Bin 536352 -> 537992 bytes
+ ...e-retain-gids.3042,3044,3046,73E0,5EA6,8F38.otf |    Bin 690752 -> 692312 bytes
+ ...ular.desubroutinize-retain-gids.61,63,65,6B.otf |    Bin 530004 -> 531624 bytes
+ ...e-retain-gids.660E,6975,73E0,5EA6,8F38,6E05.otf |    Bin 690868 -> 692496 bytes
+ ...ans-Regular.desubroutinize-retain-gids.660E.otf |    Bin 612212 -> 613836 bytes
+ ...esubroutinize.3042,3044,3046,3048,304A,304B.otf |    Bin 6248 -> 6272 bytes
+ ...esubroutinize.3042,3044,3046,73E0,5EA6,8F38.otf |    Bin 6432 -> 6456 bytes
+ ...eHanSans-Regular.desubroutinize.61,63,65,6B.otf |    Bin 5428 -> 5460 bytes
+ ...esubroutinize.660E,6975,73E0,5EA6,8F38,6E05.otf |    Bin 6552 -> 6572 bytes
+ .../SourceHanSans-Regular.desubroutinize.660E.otf  |    Bin 5196 -> 5224 bytes
+ ...e-retain-gids.3042,3044,3046,3048,304A,304B.otf |    Bin 536176 -> 537424 bytes
+ ...e-retain-gids.3042,3044,3046,73E0,5EA6,8F38.otf |    Bin 690500 -> 691692 bytes
+ ...ints-desubroutinize-retain-gids.61,63,65,6B.otf |    Bin 529888 -> 531124 bytes
+ ...e-retain-gids.660E,6975,73E0,5EA6,8F38,6E05.otf |    Bin 690564 -> 691808 bytes
+ ....drop-hints-desubroutinize-retain-gids.660E.otf |    Bin 612108 -> 613348 bytes
+ ...s-retain-gids.3042,3044,3046,3048,304A,304B.otf |    Bin 536244 -> 537492 bytes
+ ...s-retain-gids.3042,3044,3046,73E0,5EA6,8F38.otf |    Bin 690596 -> 691788 bytes
+ ...-Regular.drop-hints-retain-gids.61,63,65,6B.otf |    Bin 529928 -> 531164 bytes
+ ...-Regular.drop-hints-retain-gids.61,63,65,6B.ttx | 393879 ++++++++++++++++++
+ ...s-retain-gids.660E,6975,73E0,5EA6,8F38,6E05.otf |    Bin 690768 -> 692008 bytes
+ ...HanSans-Regular.drop-hints-retain-gids.660E.otf |    Bin 612128 -> 613368 bytes
+ ...ar.drop-hints.3042,3044,3046,3048,304A,304B.otf |    Bin 6132 -> 6164 bytes
+ ...ar.drop-hints.3042,3044,3046,73E0,5EA6,8F38.otf |    Bin 6304 -> 6300 bytes
+ ...ourceHanSans-Regular.drop-hints.61,63,65,6B.otf |    Bin 5344 -> 5376 bytes
+ ...ar.drop-hints.660E,6975,73E0,5EA6,8F38,6E05.otf |    Bin 6472 -> 6472 bytes
+ .../SourceHanSans-Regular.drop-hints.660E.otf      |    Bin 5140 -> 5140 bytes
+ ...r.retain-gids.3042,3044,3046,3048,304A,304B.otf |    Bin 536436 -> 538076 bytes
+ ...r.retain-gids.3042,3044,3046,73E0,5EA6,8F38.otf |    Bin 690860 -> 692420 bytes
+ ...urceHanSans-Regular.retain-gids.61,63,65,6B.otf |    Bin 530084 -> 531704 bytes
+ ...r.retain-gids.660E,6975,73E0,5EA6,8F38,6E05.otf |    Bin 691076 -> 692700 bytes
+ .../SourceHanSans-Regular.retain-gids.660E.otf     |    Bin 612236 -> 613860 bytes
+ 36 files changed, 393879 insertions(+)
+
+commit 84694af723bde07cf3231ed2d2e193123f5f73ed
+Author: Ebrahim Byagowi <ebrahim@gnu.org>
+Date:   Fri Feb 8 15:30:17 2019 +0330
+
+    [ci] Disable the just added bot
+    
+    Doesn't play well with CircleCI apparently
+    
+    https://circleci.com/gh/harfbuzz/harfbuzz/74289
+
+ .circleci/config.yml | 19 ++++++++++---------
+ 1 file changed, 10 insertions(+), 9 deletions(-)
+
+commit 81ae4974e35aa8ca408abd6238eb768f5c948287
+Author: Ebrahim Byagowi <ebrahim@gnu.org>
+Date:   Fri Feb 8 15:18:26 2019 +0330
+
+    [ci] Add a Void Linux bot
+    
+    https://voidlinux.org/ is yet another and different distro written from scratch, thus completely eligible to have a bot here!
+    
+    Seriously however not that useful yet however but I will try to overload it other tasks later, like our other bots.
+    
+    No test yet also, couldn't install cairo-devel, will try to fix that later.
+    
+    Their harfbuzz package source: https://github.com/void-linux/void-packages/blob/master/srcpkgs/harfbuzz/template
+
+ .circleci/config.yml | 11 ++++++++++-
+ 1 file changed, 10 insertions(+), 1 deletion(-)
+
+commit e2856c2d85eb0f6ce0c780d1889dc9bb05cdc433
+Author: Michiharu Ariza <ariza@adobe.com>
+Date:   Thu Feb 7 15:32:32 2019 -0800
+
+    retain FDSelect & FDArray with --retain-gids
+    
+    so in sync with fonttools behavior
+
+ src/hb-subset-cff-common.cc                           |  12 ++++--------
+ .../SourceHanSans-Regular.41,4C2E.retaingids.otf      | Bin 2604 -> 2736 bytes
+ 2 files changed, 4 insertions(+), 8 deletions(-)
+
+commit 1239b6b2b4430658aea78216a1dcc885724a7ab4
+Merge: 9f80eb01 126abca9
+Author: Michiharu Ariza <ariza@adobe.com>
+Date:   Thu Feb 7 10:29:40 2019 -0800
+
+    Merge branch 'master' into cff-more-arrayof-fixes
+
+commit a5fa76977b5bdf3bd40ede3cdd0da9c5546557a6
+Merge: 214d0b02 126abca9
+Author: Michiharu Ariza <ariza@adobe.com>
+Date:   Thu Feb 7 10:28:13 2019 -0800
+
+    Merge branch 'master' into cff-retain-gids
+
+commit 214d0b024b49edd51974ff2c051535ae06de0709
+Author: Michiharu Ariza <ariza@adobe.com>
+Date:   Thu Feb 7 10:27:43 2019 -0800
+
+    minor change
+
+ src/hb-subset-cff-common.cc | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+commit 126abca98a954f7ec3374d0593fee25f78dc10f3
+Merge: 1e062821 7859decd
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Wed Feb 6 13:36:52 2019 -0800
+
+    Merge pull request #1571 from kencu/cleanostests
+    
+    hb-coretext.cc: clean up macosx test
+
+commit 7859decdd02f65dfb3da07bd95742b14b4697638
+Author: Ken Cunningham <kencu@macports.org>
+Date:   Tue Feb 5 20:26:49 2019 -0800
+
+    hb-coretext.cc: clean up macosx test
+    
+    TARGET_OS_OSX was introduced only in late OS versions
+    so always returns as "0" on older systems.
+    
+    if !TARGET_OS_IPHONE can work, as it returns as !0 on older
+    systems where TARGET_OS_IPHONE is not defined, but is not
+    specific
+    
+    if TARGET_OS_MAC && !(defined(TARGET_OS_IPHONE) && TARGET_OS_IPHONE)
+    is both specific and accurate on all systems.
+
+ src/hb-coretext.cc | 10 +++++-----
+ 1 file changed, 5 insertions(+), 5 deletions(-)
+
+commit 9328354a83252a8d8d74fe424ab3894d398b0bd0
+Author: Michiharu Ariza <ariza@adobe.com>
+Date:   Mon Feb 4 11:28:15 2019 -0800
+
+    separate CFF from TrueType in full font tests
+
+ ...eSansPro-Regular.default.1FC,21,41,20,62,63.otf | Bin
+ .../SourceSansPro-Regular.default.61,62,63.otf     | Bin
+ ...ourceSansPro-Regular.default.D7,D8,D9,DA,DE.otf | Bin
+ ...subroutinize-retain-gids.1FC,21,41,20,62,63.otf | Bin
+ ...Regular.desubroutinize-retain-gids.61,62,63.otf | Bin
+ ...r.desubroutinize-retain-gids.D7,D8,D9,DA,DE.otf | Bin
+ ...o-Regular.desubroutinize.1FC,21,41,20,62,63.otf | Bin
  ...urceSansPro-Regular.desubroutinize.61,62,63.otf | Bin
  ...nsPro-Regular.desubroutinize.D7,D8,D9,DA,DE.otf | Bin
  ...subroutinize-retain-gids.1FC,21,41,20,62,63.otf | Bin
@@ -949,1012 +15307,2738 @@ Date:   Mon Feb 4 11:28:15 2019 -0800
  test/subset/subset_test_suite.py                   |   7 +------
  69 files changed, 41 insertions(+), 20 deletions(-)
 
-commit ec30a8a9acf7be9918a8a6bff41696127090173f
-Author: Michiharu Ariza <ariza@adobe.com>
-Date:   Fri Feb 1 15:58:03 2019 -0800
+commit ec30a8a9acf7be9918a8a6bff41696127090173f
+Author: Michiharu Ariza <ariza@adobe.com>
+Date:   Fri Feb 1 15:58:03 2019 -0800
+
+    removed unused test data
+
+ ...ts.desubroutinize-retain-gids.1FC,21,41,20,62,63.otf | Bin 15456 -> 0 bytes
+ ...r.drop-hints.desubroutinize-retain-gids.61,62,63.otf | Bin 13036 -> 0 bytes
+ ...-hints.desubroutinize-retain-gids.D7,D8,D9,DA,DE.otf | Bin 16656 -> 0 bytes
+ ...nsPro-Regular.drop-hints.desubroutinize.61,62,63.otf | Bin 3276 -> 0 bytes
+ ...-hints.desubroutinize.retain-gids.D7,D8,D9,DA,DE.otf | Bin 34560 -> 0 bytes
+ ...ro-Regular.drop-hints.retain-gids.D7,D8,D9,DA,DE.otf | Bin 34576 -> 0 bytes
+ 6 files changed, 0 insertions(+), 0 deletions(-)
+
+commit 30b781f20a8e386732f8e2858a22665d7af98061
+Merge: c1286265 1e062821
+Author: Michiharu Ariza <ariza@adobe.com>
+Date:   Fri Feb 1 14:50:34 2019 -0800
+
+    Merge branch 'master' into cff-retain-gids
+
+commit c12862657f24b6c197e23d99a4edbdfcf3c90653
+Author: Michiharu Ariza <ariza@adobe.com>
+Date:   Fri Feb 1 14:50:01 2019 -0800
+
+    added desubroutinize & retain-gids full test cases with CFF fonts
+    
+    and CFF retain-gids fixes
+
+ src/hb-subset-cff1.cc                              |  44 +++++++++------------
+ .../SourceHanSans-Regular.41,4C2E.retaingids.otf   | Bin 2600 -> 2604 bytes
+ ...subroutinize-retain-gids.1FC,21,41,20,62,63.otf | Bin 0 -> 33516 bytes
+ ...Regular.desubroutinize-retain-gids.61,62,63.otf | Bin 0 -> 31080 bytes
+ ...r.desubroutinize-retain-gids.D7,D8,D9,DA,DE.otf | Bin 0 -> 34708 bytes
+ ...subroutinize-retain-gids.1FC,21,41,20,62,63.otf | Bin 0 -> 33352 bytes
+ ...p-hints-desubroutinize-retain-gids.61,62,63.otf | Bin 0 -> 30956 bytes
+ ...s-desubroutinize-retain-gids.D7,D8,D9,DA,DE.otf | Bin 0 -> 34560 bytes
+ ...op-hints-desubroutinize.1FC,21,41,20,62,63.otf} | Bin
+ ...-Regular.drop-hints-desubroutinize.61,62,63.otf | Bin 0 -> 3288 bytes
+ ...r.drop-hints-desubroutinize.D7,D8,D9,DA,DE.otf} | Bin
+ ...r.drop-hints-retain-gids.1FC,21,41,20,62,63.otf | Bin 0 -> 33448 bytes
+ ...Pro-Regular.drop-hints-retain-gids.61,62,63.otf | Bin 0 -> 31028 bytes
+ ...gular.drop-hints-retain-gids.D7,D8,D9,DA,DE.otf | Bin 0 -> 34576 bytes
+ ...subroutinize-retain-gids.1FC,21,41,20,62,63.otf | Bin 0 -> 15456 bytes
+ ...p-hints.desubroutinize-retain-gids.61,62,63.otf | Bin 0 -> 13036 bytes
+ ...s.desubroutinize-retain-gids.D7,D8,D9,DA,DE.otf | Bin 0 -> 16656 bytes
+ ...s.desubroutinize.retain-gids.D7,D8,D9,DA,DE.otf | Bin 0 -> 34560 bytes
+ ...gular.drop-hints.retain-gids.D7,D8,D9,DA,DE.otf | Bin 0 -> 34576 bytes
+ ...sPro-Regular.retain-gids.1FC,21,41,20,62,63.otf | Bin 0 -> 33668 bytes
+ .../SourceSansPro-Regular.retain-gids.61,62,63.otf | Bin 0 -> 31180 bytes
+ ...eSansPro-Regular.retain-gids.D7,D8,D9,DA,DE.otf | Bin 0 -> 34724 bytes
+ ...e-retain-gids.3042,3044,3046,3048,304A,304B.otf | Bin 0 -> 536352 bytes
+ ...e-retain-gids.3042,3044,3046,73E0,5EA6,8F38.otf | Bin 0 -> 690752 bytes
+ ...ular.desubroutinize-retain-gids.61,63,65,6B.otf | Bin 0 -> 530004 bytes
+ ...e-retain-gids.660E,6975,73E0,5EA6,8F38,6E05.otf | Bin 0 -> 690868 bytes
+ ...ans-Regular.desubroutinize-retain-gids.660E.otf | Bin 0 -> 612212 bytes
+ .../SourceHanSans-Regular.desubroutinize..otf      | Bin 2340 -> 0 bytes
+ ...e-retain-gids.3042,3044,3046,3048,304A,304B.otf | Bin 0 -> 536176 bytes
+ ...e-retain-gids.3042,3044,3046,73E0,5EA6,8F38.otf | Bin 0 -> 690500 bytes
+ ...ints-desubroutinize-retain-gids.61,63,65,6B.otf | Bin 0 -> 529888 bytes
+ ...e-retain-gids.660E,6975,73E0,5EA6,8F38,6E05.otf | Bin 0 -> 690564 bytes
+ ....drop-hints-desubroutinize-retain-gids.660E.otf | Bin 0 -> 612108 bytes
+ ...subroutinize.3042,3044,3046,3048,304A,304B.otf} | Bin 6076 -> 6096 bytes
+ ...subroutinize.3042,3044,3046,73E0,5EA6,8F38.otf} | Bin 6180 -> 6204 bytes
+ ...ular.drop-hints-desubroutinize.61,63,65,6B.otf} | Bin 5312 -> 5344 bytes
+ ...subroutinize.660E,6975,73E0,5EA6,8F38,6E05.otf} | Bin 6248 -> 6268 bytes
+ ...ans-Regular.drop-hints-desubroutinize.660E.otf} | Bin 5140 -> 5120 bytes
+ ...s-retain-gids.3042,3044,3046,3048,304A,304B.otf | Bin 0 -> 536244 bytes
+ ...s-retain-gids.3042,3044,3046,73E0,5EA6,8F38.otf | Bin 0 -> 690596 bytes
+ ...-Regular.drop-hints-retain-gids.61,63,65,6B.otf | Bin 0 -> 529928 bytes
+ ...s-retain-gids.660E,6975,73E0,5EA6,8F38,6E05.otf | Bin 0 -> 690768 bytes
+ ...HanSans-Regular.drop-hints-retain-gids.660E.otf | Bin 0 -> 612128 bytes
+ ...eHanSans-Regular.drop-hints.desubroutinize..otf | Bin 2188 -> 0 bytes
+ ...r.retain-gids.3042,3044,3046,3048,304A,304B.otf | Bin 0 -> 536436 bytes
+ ...r.retain-gids.3042,3044,3046,73E0,5EA6,8F38.otf | Bin 0 -> 690860 bytes
+ ...urceHanSans-Regular.retain-gids.61,63,65,6B.otf | Bin 0 -> 530084 bytes
+ ...r.retain-gids.660E,6975,73E0,5EA6,8F38,6E05.otf | Bin 0 -> 691076 bytes
+ .../SourceHanSans-Regular.retain-gids.660E.otf     | Bin 0 -> 612236 bytes
+ .../data/profiles/desubroutinize-retain-gids.txt   |   2 +
+ .../drop-hints-desubroutinize-retain-gids.txt      |   3 ++
+ test/subset/data/tests/full-font.tests             |   6 +++
+ test/subset/data/tests/japanese.tests              |   6 +++
+ test/subset/subset_test_suite.py                   |   2 +-
+ 54 files changed, 36 insertions(+), 27 deletions(-)
+
+commit f2908b4d8f9b02ce06d3f648c3f08757797073b6
+Author: Michiharu Ariza <ariza@adobe.com>
+Date:   Thu Jan 31 14:16:37 2019 -0800
+
+    Implement subset --regain-gids option with CFF1/2
+    
+    along with api tests & expected results
+
+ src/hb-subset-cff-common.cc                        |  17 +++-
+ src/hb-subset-cff-common.hh                        |  91 +++++++++++++--------
+ src/hb-subset-cff1.cc                              |  89 ++++++++++++--------
+ src/hb-subset-cff2.cc                              |  30 ++++---
+ test/api/fonts/AdobeVFPrototype.ac.retaingids.otf  | Bin 0 -> 7000 bytes
+ .../SourceHanSans-Regular.41,4C2E.retaingids.otf   | Bin 0 -> 2600 bytes
+ .../fonts/SourceSansPro-Regular.ac.retaingids.otf  | Bin 0 -> 1708 bytes
+ test/api/test-subset-cff1.c                        |  48 +++++++++++
+ test/api/test-subset-cff2.c                        |  24 ++++++
+ 9 files changed, 217 insertions(+), 82 deletions(-)
+
+commit 1e06282105a2d579aab32094cc7abc10ed231978
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Thu Jan 31 13:56:58 2019 -0800
+
+    Adjust hb_is_signed<>
+    
+    Fixes https://github.com/harfbuzz/harfbuzz/issues/1535
+
+ src/hb-dsalgs.hh | 27 +++++++++------------------
+ 1 file changed, 9 insertions(+), 18 deletions(-)
+
+commit 21ea1c91529471c05e03b6db61df256f24fa23c1
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Thu Jan 31 13:49:18 2019 -0800
+
+    Remove stale comment
+
+ src/hb-dsalgs.hh | 5 -----
+ 1 file changed, 5 deletions(-)
+
+commit 9f80eb0177e527253818ad9171fc75fb565318cb
+Merge: b3799007 d14d2c20
+Author: Michiharu Ariza <ariza@adobe.com>
+Date:   Thu Jan 31 12:54:36 2019 -0800
+
+    Merge branch 'master' into cff-more-arrayof-fixes
+
+commit 2d940946d5af0e3869a2324b6e36ca8ea3698c48
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Wed Jan 30 16:03:16 2019 -0800
+
+    [iter] Fix mystery crash
+    
+    Fuzzer caught it:
+    
+    ==14==ERROR: AddressSanitizer: stack-use-after-return on address 0x7fca2ed7a3e0 at pc 0x0000006057aa bp 0x7ffc3290f1d0 sp 0x7ffc3290f1c8
+    READ of size 4 at 0x7fca2ed7a3e0 thread T0
+    SCARINESS: 55 (4-byte-read-stack-use-after-return)
+        #0 0x6057a9 in OT::SingleSubstFormat2::subset(hb_subset_context_t*) const /src/harfbuzz/src/./hb-ot-layout-gsub-table.hh:194:40
+        #1 0x5ff921 in hb_subset_context_t::return_t OT::SingleSubst::dispatch<hb_subset_context_t>(hb_subset_context_t*) const /src/harfbuzz/src/./hb-ot-layout-gsub-table.hh:256:13
+    
+    I can't reproduce locally, but many of the bots are failing because of this
+    as well.
+    
+    It's a pity that operator-> must return pointer.  Ugh.  Why?!
+
+ src/hb-iter.hh                 | 4 ++++
+ src/hb-ot-layout-gsub-table.hh | 4 ++--
+ 2 files changed, 6 insertions(+), 2 deletions(-)
+
+commit d14d2c20b05c5acf0a6f9c6dc36a7b8d8966153e
+Merge: acf5f0a3 dc04261a
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Wed Jan 30 18:36:57 2019 -0500
+
+    Merge pull request #1567 from googlefonts/fuzzer
+    
+    [subset] Update the subset fuzzer to get  options to use from test case.
+
+commit dc04261a5b8408bcfde16090ddf91568c3d8dae7
+Author: Garret Rieger <grieger@google.com>
+Date:   Wed Jan 30 15:23:19 2019 -0800
+
+    [subset] Update the subset fuzzer to determine which options to use based on data in the fuzzing test case.
+    Add support for toggling retain_gids.
+
+ test/fuzzing/hb-subset-fuzzer.cc | 32 +++++++++++++++++++-------------
+ 1 file changed, 19 insertions(+), 13 deletions(-)
+
+commit 2e675d49f2f705a5b5d95574a5336d5e670a0fba
+Merge: ede117dc acf5f0a3
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Wed Jan 30 15:10:43 2019 -0800
+
+    Merge branch 'master' into iter
+
+commit acf5f0a3aff0e128509b0979f629edf0596fcee5
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Wed Jan 30 15:10:23 2019 -0800
+
+    [configure] Fix up
+
+ configure.ac | 11 +++++------
+ 1 file changed, 5 insertions(+), 6 deletions(-)
+
+commit ede117dc40d547cd457a420c9f7c9829cdb5f307
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Wed Jan 30 15:10:23 2019 -0800
+
+    [configure] Fix up
+
+ configure.ac | 11 +++++------
+ 1 file changed, 5 insertions(+), 6 deletions(-)
+
+commit cbe2118c588622070612ba7ac7eae7496a092e3c
+Merge: 8b46c2d9 6b834c1c
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Wed Jan 30 15:07:09 2019 -0800
+
+    Merge branch 'master' into iter
+
+commit 6b834c1c76b867ef32747202a755255d2f360f1e
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Wed Jan 30 15:06:22 2019 -0800
+
+    [configure] Print compiler version info in report
+
+ configure.ac | 6 ++++++
+ 1 file changed, 6 insertions(+)
+
+commit 8b46c2d933b546a88799b08f4a74fd1285518ed5
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Wed Jan 30 15:06:22 2019 -0800
+
+    [configure] Print compiler version info in report
+
+ configure.ac | 6 ++++++
+ 1 file changed, 6 insertions(+)
+
+commit 4aa4eedfd5633ee84d37469c9625d12856dbc575
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Wed Jan 30 15:02:29 2019 -0800
+
+    [ci] Switch clang-O3-O0 bot to Ubuntu image
+    
+    https://github.com/harfbuzz/harfbuzz/issues/1566
+
+ .circleci/config.yml | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 7c292c0853140540f13f73d43ef7f7e0746e5f28
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Wed Jan 30 14:54:23 2019 -0800
+
+    [iter] Warning fix
+    
+    Not sure why I don't get it, but this warning:
+    
+    warning: base class ‘struct hb_iter_fallback_mixin_t<hb_array_t<const OT::UVSMapping>, const OT::UVSMapping&>’ should be explicitly initialized in the copy constructor [-Wextra]
+
+ src/hb-iter.hh | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+commit a84b0145ea799c9452ecb97713689247955d30ff
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Wed Jan 30 14:42:48 2019 -0800
+
+    [ci] Disable -Wunused-template on -Weverything bot
+    
+    ./hb-algs.hh:37:3: error: unused function template 'operator()' [-Werror,-Wunused-template]
+      operator () (const T& v) const { return v; }
+      ^
+
+ .circleci/config.yml | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit d983c529b66b530715e9c813c69e699b1d8029d3
+Merge: 55d1d7c8 e6ffcc59
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Wed Jan 30 17:17:59 2019 -0500
+
+    Merge pull request #1564 from googlefonts/retain_gids
+    
+    [subset] Add --retain-gids option to the subsetter.
+
+commit 55d1d7c8bcd8d97c4e618e5dd21f13df50b10ce8
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Wed Jan 30 13:54:15 2019 -0800
+
+    2.3.1
+
+ NEWS             | 7 +++++++
+ configure.ac     | 2 +-
+ src/hb-version.h | 4 ++--
+ 3 files changed, 10 insertions(+), 3 deletions(-)
+
+commit e799004e9f6821864b955a09673544d92e8b45e6
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Tue Jan 29 17:15:12 2019 -0800
+
+    [iter] Whitespace
+
+ src/hb-iter.hh | 23 ++++++++++++++---------
+ 1 file changed, 14 insertions(+), 9 deletions(-)
+
+commit 849a0f1758b67eb3b4d864047b9df671e76404a5
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Tue Jan 29 17:10:19 2019 -0800
+
+    [iter] Add hb_iter_with_fallback_t instead
+
+ src/hb-array.hh            |  5 +----
+ src/hb-iter.hh             | 29 +++++++++++++----------------
+ src/hb-ot-layout-common.hh |  5 +----
+ src/hb-set.hh              |  5 +----
+ src/test-iter.cc           |  5 +----
+ 5 files changed, 17 insertions(+), 32 deletions(-)
+
+commit 4d40ed9d1a7a4f18af6710a1b8ba90257b8456a0
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Tue Jan 29 13:55:23 2019 -0800
+
+    [iter] Add hb_iter_with_mixin_t<>
+
+ src/hb-array.hh            |  5 +++--
+ src/hb-iter.hh             | 18 ++++++++++++++++--
+ src/hb-ot-layout-common.hh |  5 +++--
+ src/hb-set.hh              |  5 +++--
+ src/test-iter.cc           |  5 +++--
+ 5 files changed, 28 insertions(+), 10 deletions(-)
+
+commit 6521d5b201cb8df5a3c2657b4da703cf52472f81
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Tue Jan 29 13:44:39 2019 -0800
+
+    [iter] Export operator << / >>
+
+ src/hb-iter.hh | 2 ++
+ 1 file changed, 2 insertions(+)
+
+commit 84a25d79c649776a299526c087bf369a9705f89e
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Tue Jan 29 13:39:19 2019 -0800
+
+    [iter] Rename
+
+ src/hb-array.hh            |  2 +-
+ src/hb-iter.hh             | 12 ++++++------
+ src/hb-ot-layout-common.hh |  2 +-
+ src/hb-set.hh              |  2 +-
+ src/test-iter.cc           |  2 +-
+ 5 files changed, 10 insertions(+), 10 deletions(-)
+
+commit e6ffcc5904ab88143cad0c7a7a4c990147af278b
+Author: Garret Rieger <grieger@google.com>
+Date:   Mon Jan 28 18:12:19 2019 -0800
+
+    [subset] Add expected files for retain-gids integration tests.
+
+ ...oboto-Regular.abc.drop-hints-retain-gids.61,62,63.ttf | Bin 0 -> 924 bytes
+ .../Roboto-Regular.abc.drop-hints-retain-gids.61,63.ttf  | Bin 0 -> 856 bytes
+ .../Roboto-Regular.abc.drop-hints-retain-gids.61.ttf     | Bin 0 -> 744 bytes
+ .../Roboto-Regular.abc.drop-hints-retain-gids.62.ttf     | Bin 0 -> 712 bytes
+ .../Roboto-Regular.abc.drop-hints-retain-gids.63.ttf     | Bin 0 -> 716 bytes
+ .../basics/Roboto-Regular.abc.retain-gids.61,62,63.ttf   | Bin 0 -> 2168 bytes
+ .../basics/Roboto-Regular.abc.retain-gids.61,63.ttf      | Bin 0 -> 1996 bytes
+ .../basics/Roboto-Regular.abc.retain-gids.61.ttf         | Bin 0 -> 1808 bytes
+ .../basics/Roboto-Regular.abc.retain-gids.62.ttf         | Bin 0 -> 1756 bytes
+ .../basics/Roboto-Regular.abc.retain-gids.63.ttf         | Bin 0 -> 1732 bytes
+ test/subset/data/profiles/retain-gids.txt                |   1 -
+ 11 files changed, 1 deletion(-)
+
+commit 198859bb3702e45cb271dd51b7231f10d01576be
+Author: Garret Rieger <grieger@google.com>
+Date:   Mon Jan 28 18:10:56 2019 -0800
+
+    [subset] For retain gids don't truncate glyphs past the highest requested subset glyph.
+
+ src/hb-subset-plan.cc | 8 +++++---
+ 1 file changed, 5 insertions(+), 3 deletions(-)
+
+commit 490d52f908aaa4722e71a4a682de20e94d89ad00
+Author: Garret Rieger <grieger@google.com>
+Date:   Mon Jan 28 17:43:42 2019 -0800
+
+    [subset] Add retain-gids option to hb-subset executable.
+
+ util/hb-subset.cc | 1 +
+ util/options.cc   | 1 +
+ util/options.hh   | 2 ++
+ 3 files changed, 4 insertions(+)
+
+commit a903f9c228d1f3e8065f89de16e50027d6018e58
+Author: Garret Rieger <grieger@google.com>
+Date:   Mon Jan 28 17:43:11 2019 -0800
+
+    [subset] Add some subsetting integration tests covering retain gids.
+
+ test/subset/data/profiles/drop-hints-retain-gids.txt | 2 ++
+ test/subset/data/profiles/retain-gids.txt            | 2 ++
+ test/subset/data/tests/basics.tests                  | 2 ++
+ 3 files changed, 6 insertions(+)
+
+commit 05e99c86baa0e95c2bff1c87d601eaf022c9d1f8
+Author: Garret Rieger <grieger@google.com>
+Date:   Mon Jan 28 17:05:04 2019 -0800
+
+    [subset] A few small fixes for the new subset plan api.
+
+ src/hb-ot-hdmx-table.hh | 6 +++---
+ src/hb-ot-hmtx-table.hh | 9 +++------
+ src/hb-subset.cc        | 2 +-
+ 3 files changed, 7 insertions(+), 10 deletions(-)
+
+commit bdbe047d6ce3d8873c6740500d38d1b0c4e851f8
+Author: Garret Rieger <grieger@google.com>
+Date:   Mon Jan 28 16:59:15 2019 -0800
+
+    [subset] Update hb-subset-plan.cc to match hb-subset-plan.hh.
+
+ src/hb-subset-plan.cc | 20 ++++++++++----------
+ src/hb-subset-plan.hh |  1 -
+ 2 files changed, 10 insertions(+), 11 deletions(-)
+
+commit 74c44ffebafe7758937d82524758be8bb4ecc4e2
+Author: Garret Rieger <grieger@google.com>
+Date:   Mon Jan 28 16:53:01 2019 -0800
+
+    [subset] Update hb-subset-glyf.cc to use new hb-subset-plan API.
+
+ src/hb-subset-glyf.cc | 57 ++++++++++++++++++++-------------------------------
+ 1 file changed, 22 insertions(+), 35 deletions(-)
+
+commit 4842294b861b9fe322c811abef0ebb0553be2bf0
+Author: Garret Rieger <grieger@google.com>
+Date:   Mon Jan 28 16:51:27 2019 -0800
+
+    [subset] Update gsub to use glyphset() method of subset plan.
+
+ src/hb-ot-layout-gsub-table.hh | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+commit 853b1f1aa5489b8439c41c30be77ed042c8c89e5
+Author: Garret Rieger <grieger@google.com>
+Date:   Mon Jan 28 16:50:56 2019 -0800
+
+    [subset] Correct maxp num glyph's to use new subset plan method.
+
+ src/hb-ot-maxp-table.hh | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 846e05a298bc088f2cd2fe53b75ca531916a56f8
+Author: Garret Rieger <grieger@google.com>
+Date:   Mon Jan 28 16:50:20 2019 -0800
+
+    [subset] Re-add glyphs array to subset plan, with new name 'glyphs_deprecated'. Switch CFF subsetting to use it.
+
+ src/hb-subset-cff1.cc | 36 ++++++++++++++++++------------------
+ src/hb-subset-cff2.cc | 12 ++++++------
+ src/hb-subset-plan.hh |  3 +++
+ 3 files changed, 27 insertions(+), 24 deletions(-)
+
+commit 03e88eab5c0f8775ccffc0925532748140d93470
+Author: Garret Rieger <grieger@google.com>
+Date:   Mon Jan 28 16:15:06 2019 -0800
+
+    Re-implement HMTX/VMTX subsetting. Update it to support glyph renumbering and simplify the implementation.
+
+ src/hb-ot-hmtx-table.hh | 99 +++++++++++++++++++++++++------------------------
+ src/hb-subset-plan.cc   |  2 +-
+ src/hb-subset-plan.hh   |  2 +-
+ 3 files changed, 53 insertions(+), 50 deletions(-)
+
+commit 925be2922348336335a96d84e606d4bdd9a11110
+Author: Garret Rieger <grieger@google.com>
+Date:   Fri Jan 25 18:04:41 2019 -0800
+
+    Update hb-ot-vorg-table and hb-ot-layout-common to use the updated subset plan api.
+
+ src/hb-ot-layout-common.hh |  4 ++--
+ src/hb-ot-vorg-table.hh    | 30 +++++++++++++++++++-----------
+ 2 files changed, 21 insertions(+), 13 deletions(-)
+
+commit 4af3be6ef8654ae05b331941e6e690ac197fd144
+Author: Garret Rieger <grieger@google.com>
+Date:   Fri Jan 25 18:03:47 2019 -0800
+
+    Remove glyph array from subset plan, make num_glyphs and glyphset private.
+
+ src/hb-subset-plan.hh | 51 +++++++++++++++++++++++++++++++++++++++++----------
+ 1 file changed, 41 insertions(+), 10 deletions(-)
+
+commit 23f364429dc9350ee06146bdf0ff73d7035e1d71
+Author: Garret Rieger <grieger@google.com>
+Date:   Fri Jan 18 18:33:21 2019 -0800
+
+    [subset] Fix hdmx subsetting when retain gids is enabled.
+
+ src/hb-ot-hdmx-table.hh | 19 +++++++++++--------
+ src/hb-subset-plan.cc   | 10 ++++++++++
+ src/hb-subset-plan.hh   | 16 +++++++++++++++-
+ 3 files changed, 36 insertions(+), 9 deletions(-)
+
+commit 2da1654aefbe4f8e5f1320f1c061adbf90963951
+Author: Garret Rieger <grieger@google.com>
+Date:   Fri Jan 18 17:49:35 2019 -0800
+
+    [subset] Compute num_glyphs during subset plan construction.
+    Update maxp to use the correct num glyphs.
+
+ src/hb-ot-maxp-table.hh |  2 +-
+ src/hb-subset-glyf.cc   |  6 +-----
+ src/hb-subset-plan.cc   | 16 +++++++++++++---
+ src/hb-subset-plan.hh   |  1 +
+ 4 files changed, 16 insertions(+), 9 deletions(-)
+
+commit ccc59dc6121e98ed8d610350b43218e540f61f25
+Author: Garret Rieger <grieger@google.com>
+Date:   Fri Jan 18 17:36:32 2019 -0800
+
+    [subset] Add unit test for glyf subsetting and retain gids.
+
+ test/api/fonts/Roboto-Regular.ac.retaingids.ttf | Bin 0 -> 2284 bytes
+ test/api/test-subset-glyf.c                     |  26 ++++++++++++++++++++++++
+ 2 files changed, 26 insertions(+)
+
+commit 96b038f375bcfcfdf76c75200ca02758ea7a4ff6
+Author: Garret Rieger <grieger@google.com>
+Date:   Fri Jan 18 16:41:08 2019 -0800
+
+    [subset] fix failure to init instruction ranges values for an invalid glyph.
+
+ src/hb-subset-glyf.cc | 8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+commit 4b1ac3a2fa0a5842b5d45d287fe33e5050ffda3f
+Author: Garret Rieger <grieger@google.com>
+Date:   Fri Jan 18 15:11:26 2019 -0800
+
+    [subset] Do some refactoring in hb-subset-glyf.cc.
+    - Extract code out into helper methods in several places.
+    - Bundle loca address, size and is short into a struct.
+
+ src/hb-subset-glyf.cc | 264 ++++++++++++++++++++++++++++----------------------
+ 1 file changed, 148 insertions(+), 116 deletions(-)
+
+commit b7f971884ed838636be85de216bf60ca4a28ccb9
+Author: Garret Rieger <grieger@google.com>
+Date:   Thu Jan 17 18:55:56 2019 -0800
+
+    Add retain_gids option to subset input. Update glyf and loca handling to respect retain_gids.
+
+ src/hb-subset-glyf.cc  | 39 ++++++++++++++++++++++++++++++---------
+ src/hb-subset-input.cc | 27 +++++++++++++++++++++++++++
+ src/hb-subset-input.hh |  1 +
+ src/hb-subset-plan.cc  | 14 ++++++++++----
+ src/hb-subset.h        |  6 ++++++
+ 5 files changed, 74 insertions(+), 13 deletions(-)
+
+commit b3799007554f2909170df941b07c72f7dc02dfcd
+Merge: c6856443 fe532923
+Author: Michiharu Ariza <ariza@adobe.com>
+Date:   Tue Jan 29 12:19:57 2019 -0800
+
+    Merge branch 'master' into cff-more-arrayof-fixes
+
+commit e75b22039f4129b5057f4b175c9e9d79634b1728
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Mon Jan 28 21:26:23 2019 -0500
+
+    Move hb_addressof() to hb-meta.hh
+
+ src/hb-algs.hh | 12 ------------
+ src/hb-iter.hh |  1 -
+ src/hb-meta.hh | 14 +++++++++++++-
+ src/hb.hh      |  2 +-
+ 4 files changed, 14 insertions(+), 15 deletions(-)
+
+commit 6cf25c2971aa9a7471b1cc00176ef36e9acacad4
+Merge: 71157a45 fe532923
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Mon Jan 28 21:23:28 2019 -0500
+
+    Merge branch 'master' into iter
+
+commit 71157a4520ae5cdbbeb197a979ae02b484856686
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Mon Jan 28 21:20:12 2019 -0500
+
+    [meta] Remove _ft struct names
+    
+    Using decltype() instead.
+
+ src/hb-algs.hh | 8 ++++----
+ src/hb-iter.hh | 2 +-
+ 2 files changed, 5 insertions(+), 5 deletions(-)
+
+commit 9103bd056fadd73eab2531f632790920ce602f18
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Mon Jan 28 21:16:51 2019 -0500
+
+    [pair] Use decltype
+
+ src/hb-algs.hh | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+commit fe532923101586e316b300d419a337d357cd93da
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Mon Jan 28 20:47:58 2019 -0500
+
+    [CI] Peg CircleCI badge link to master branch
+    
+    [skip ci]
+
+ README.md | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 9569819e24f72926a5b26e4c8a86d815c0132745
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Mon Jan 28 20:43:43 2019 -0500
+
+    [ci] Peg build status badges to master branch
+    
+    [skip ci]
+
+ README.md | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+commit 1e29906a77c275c34a440a416654a514810485e1
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Mon Jan 28 20:38:15 2019 -0500
+
+    Switch README / README.md
+    
+    [skip ci]
+
+ README    | 19 +------------------
+ README.md | 19 ++++++++++++++++++-
+ 2 files changed, 19 insertions(+), 19 deletions(-)
+
+commit a30e13469e6d3ec6ff412211722d26f70a97e261
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Mon Jan 28 16:39:01 2019 -0500
+
+    [iter] Add operator << to set / vector
+
+ src/hb-set.hh    | 3 +++
+ src/hb-vector.hh | 3 +++
+ 2 files changed, 6 insertions(+)
+
+commit d438e610420d931a203b31332cf74d7e0f9dd3f7
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Mon Jan 28 16:34:04 2019 -0500
+
+    [iter] Fix operator() impls
+
+ src/hb-map.hh              | 5 +++--
+ src/hb-ot-layout-common.hh | 8 +++++---
+ src/hb-set.hh              | 3 ++-
+ 3 files changed, 10 insertions(+), 6 deletions(-)
+
+commit 57795bc8dd6a9ee894c2abb8633c271876b5f596
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Mon Jan 28 16:23:12 2019 -0500
+
+    [iter] Add operator>> and operator<<
+
+ src/hb-iter.hh   | 4 ++++
+ src/test-iter.cc | 4 ++++
+ 2 files changed, 8 insertions(+)
+
+commit 8bd96be9940ca73e45138172f9f4178190566225
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Mon Jan 28 16:17:36 2019 -0500
+
+    [iter] Use auto c = C.iter() internally
+
+ src/hb-iter.hh | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+commit 073fa4ac5aff4ee72bbb38676bd351b5aa1ec167
+Merge: d592bd16 9a1df82e
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Mon Jan 28 14:35:41 2019 -0500
+
+    Merge branch 'master' into iter
+
+commit 9a1df82e3f13fbd4488ee9955814bbb5d0957074
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Mon Jan 28 14:15:18 2019 -0500
+
+    [uniscribe] Whitelist function type cast
+
+ src/hb-uniscribe.cc | 3 +++
+ 1 file changed, 3 insertions(+)
+
+commit 6e1c3eaf7005d06c89f0807f693aadd835aa0468
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Mon Jan 28 14:12:41 2019 -0500
+
+    Fix sign comparison error
+
+ src/hb-open-file.hh | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+commit 9db7a7da6339eacbb6c699fa1939bbd7e9e148f5
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Mon Jan 28 14:09:59 2019 -0500
+
+    Fix warning
+    
+    c:\projects\harfbuzz\src\hb-ot-color-cbdt-table.hh(59): warning C4146: unary minus operator applied to unsigned type, result still unsigned [C:\projects\harfbuzz\build\harfbuzz.vcxproj]
+
+ src/hb-ot-color-cbdt-table.hh | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 51b584880e550545ced3aa8ba4ccad3cf79bb53e
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Mon Jan 28 14:09:45 2019 -0500
+
+    [pragma] Silence MSVC unknown-pragma warning
+
+ src/hb.hh | 3 +++
+ 1 file changed, 3 insertions(+)
+
+commit d592bd16cd6c5ad1ee351d90d213ee2a1ea71b05
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Mon Jan 28 13:41:40 2019 -0500
+
+    Try fixing MSVC build
+
+ src/hb-algs.hh | 16 ++++++++--------
+ 1 file changed, 8 insertions(+), 8 deletions(-)
+
+commit 0363ce650b6085f62e66aff4639aa203fa17d419
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Sun Jan 27 01:03:56 2019 +0100
+
+    [iter] Accept C arrays in hb_iter()
+
+ src/hb-array.hh  |  4 +---
+ src/hb-iter.hh   | 11 +++++++++++
+ src/test-iter.cc |  5 ++++-
+ 3 files changed, 16 insertions(+), 4 deletions(-)
+
+commit b62e7f9223a6369768bde2500efe1bd1d27a0ea2
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Sun Jan 27 00:51:43 2019 +0100
+
+    [test] Test unary operator+
+    
+    "Test" as in compiles..
+
+ src/test-iter.cc | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+commit 778c96b8d7b86ae2a0fe944f499fa4a57c12e365
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Sun Jan 27 00:50:54 2019 +0100
+
+    [iter] Fix hb_iter()
+
+ src/hb-algs.hh   |  4 ----
+ src/hb-iter.hh   | 10 +++++++---
+ src/test-iter.cc |  2 +-
+ 3 files changed, 8 insertions(+), 8 deletions(-)
+
+commit 2f5b1a9104e5f4a14aa77a2f4c3c6e1c2837500c
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Sun Jan 27 00:49:37 2019 +0100
+
+    [iter] Add unary operator+ that returns a copy
+
+ src/hb-iter.hh   | 1 +
+ src/test-iter.cc | 2 +-
+ 2 files changed, 2 insertions(+), 1 deletion(-)
+
+commit fbab07f9b3dac90ce2136506f72879335193fc02
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Sun Jan 27 00:44:45 2019 +0100
+
+    [iter] Add hb_bool() and make hb_filter default to it for predicate
+
+ src/hb-algs.hh   |  6 ++++++
+ src/hb-iter.hh   |  4 ++--
+ src/test-iter.cc | 10 +++++++++-
+ 3 files changed, 17 insertions(+), 3 deletions(-)
+
+commit 313d63e240736bfe7c312133fe8c09ccff428d52
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Sat Jan 26 22:58:26 2019 +0100
+
+    [meta] Back to using _ft suffix for function-object types
+    
+    Seprate namespace, cleaner, more clear.
+
+ src/hb-algs.hh | 6 +++---
+ src/hb-iter.hh | 2 +-
+ 2 files changed, 4 insertions(+), 4 deletions(-)
+
+commit 2aff6d9625673062b1129e2af5b7d029f7622e71
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Sat Jan 26 22:54:25 2019 +0100
+
+    [iter] Test that default-constructed iterators are empty
+
+ src/test-iter.cc | 2 ++
+ 1 file changed, 2 insertions(+)
+
+commit f35e7eabf10d99c2a4ddab054cf89f3da359e7a8
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Sat Jan 26 22:50:00 2019 +0100
+
+    pragma GCC diagnostic error   "-Winjected-class-name"
+    
+    See 6b6783e1588ebe5772a1edc19552219e9d931bda
+
+ src/hb.hh | 1 +
+ 1 file changed, 1 insertion(+)
+
+commit 509353357c220a3a60910b70b3a90ea8fa6a14a8
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Sat Jan 26 22:47:35 2019 +0100
+
+    [iter] Use hb_declval() instead of Null() to get instance
+    
+    I had used Null to make one of the bots happy before.  Not going
+    to bend to such demands anymore..
+
+ src/hb-iter.hh | 3 +--
+ src/hb.hh      | 2 +-
+ 2 files changed, 2 insertions(+), 3 deletions(-)
+
+commit 6b6783e1588ebe5772a1edc19552219e9d931bda
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Sat Jan 26 22:44:09 2019 +0100
+
+    [iter/meta] Fix build on newer clang
+    
+    The mystery failure had to do with SFINAE failure because the template
+    function involved was accessing ::iter_t of a type that was also named iter_t.
+    In this context, apparently:
+    
+    warning: ISO C++ specifies that qualified reference to 'iter_t' is a
+    constructor name rather than a type in this context, despite preceding 'typename' keyword
+    [-Winjected-class-name]
+    
+    We use a new macro, also called hb_iter_t(), to get iterator type of
+    a type.  This uses declval/hb_decltype, and has the added benefit
+    that it returns correct type for const vs non-const objects, if they
+    have different iterators.
+
+ src/hb-iter.hh | 22 ++++++++++++----------
+ 1 file changed, 12 insertions(+), 10 deletions(-)
+
+commit 5adb113bafb2cf10ea768ff7a15ad4e6a1270a29
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Sat Jan 26 22:15:59 2019 +0100
+
+    [meta] Mark function-objects as const
+
+ src/hb-algs.hh | 6 +++---
+ src/hb-iter.hh | 2 +-
+ 2 files changed, 4 insertions(+), 4 deletions(-)
+
+commit ac90f17c552e5264ad0a9d17c50fac9008d6ebe7
+Merge: 090fe56d 60022ecc
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Sat Jan 26 14:05:39 2019 +0100
+
+    Merge branch 'master' into iter
+
+commit 60022ecced202760daa7f75516bba6a4689a49de
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Sat Jan 26 14:04:51 2019 +0100
+
+    Fix -Wcast-function-type warnings in util/ with gcc 4.8
+
+ src/hb.hh       | 1 +
+ util/options.hh | 5 ++++-
+ 2 files changed, 5 insertions(+), 1 deletion(-)
+
+commit a9321cb5f88cae1dafbd623b8bf7c68a82a3c211
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Fri Jan 25 16:11:45 2019 +0100
+
+    Fix mac test
+
+ test/shaping/data/in-house/tests/macos.tests | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+commit f39809752909f193a9c60f4357a88ea1c3ce1162
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Fri Jan 25 16:08:25 2019 +0100
+
+    More static constexpr
+
+ src/hb-machinery.hh  | 10 +++++-----
+ src/hb-set-digest.hh | 14 +++++++-------
+ 2 files changed, 12 insertions(+), 12 deletions(-)
+
+commit 090fe56dc6ef5f7afa297f2cb200418a520a2026
+Merge: 21c0713a 06358ae9
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Fri Jan 25 15:34:03 2019 +0100
+
+    Merge branch 'master' into iter
+
+commit 06358ae9746ae72c0917e8a5f294d14fd695f380
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Fri Jan 25 15:11:47 2019 +0100
+
+    [AAT] Add test for recent Ligature stack fix, using Zapfino on Mac
+
+ test/shaping/data/in-house/tests/macos.tests | 2 ++
+ 1 file changed, 2 insertions(+)
+
+commit c685644386d1c88d6df6e024e56d61c792d94418
+Merge: 0bd0a331 e970de48
+Author: Michiharu Ariza <ariza@adobe.com>
+Date:   Thu Jan 24 13:19:18 2019 -0800
+
+    Merge branch 'master' into cff-more-arrayof-fixes
+
+commit e970de48bcbdccd29350f331288c0a98f7846c16
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Thu Jan 24 18:16:17 2019 +0100
+
+    [AAT] Minor sign
+
+ src/hb-aat-layout-morx-table.hh | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+commit a371a28cda23805cbea22867e0a3ed53ecb811ed
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Thu Jan 24 18:12:25 2019 +0100
+
+    [AAT] Use a ring buffer for ligature stack
+    
+    I think Apple does very similarly, but probably with a stack size of 16.
+    We do it with a stack size that is currently set to 64.
+    
+    Fixes https://github.com/harfbuzz/harfbuzz/issues/1531
+
+ src/hb-aat-layout-morx-table.hh | 15 ++++++---------
+ 1 file changed, 6 insertions(+), 9 deletions(-)
+
+commit 7886b1578fceee368ae5afe206ff98f50e1c42e3
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Thu Jan 24 18:06:17 2019 +0100
+
+    Whitespace
+
+ src/hb-aat-layout-morx-table.hh | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit b976940243bf1f174bd6abb85955789ef2631d24
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Thu Jan 24 18:01:07 2019 +0100
+
+    [AAT] Handle transition errors during machine operation
+    
+    Before we used to give up.  Now, just ignore error and continue processing.
+    
+    Fixes https://github.com/harfbuzz/harfbuzz/issues/1531
+
+ src/hb-aat-layout-common.hh     |  3 +--
+ src/hb-aat-layout-kerx-table.hh | 21 +++++++--------------
+ src/hb-aat-layout-morx-table.hh | 34 +++++++++++++---------------------
+ 3 files changed, 21 insertions(+), 37 deletions(-)
+
+commit 0bd0a3311cfded5ffa4d9d488d404558cf65e8ed
+Merge: 12cd3171 f60282c5
+Author: Michiharu Ariza <ariza@adobe.com>
+Date:   Thu Jan 24 08:53:28 2019 -0800
+
+    Merge branch 'master' into cff-more-arrayof-fixes
+
+commit e234bb6a428cd6c8ddf57eb078cd51b9d1f25ba8
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Thu Jan 24 17:23:11 2019 +0100
+
+    [AAT] Ignore machine errors and continue
+
+ src/hb-aat-layout-common.hh | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 1ec90514f69efc329691186466f62373efa863b1
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Thu Jan 24 17:21:41 2019 +0100
+
+    [AAT] Minor
+
+ src/hb-aat-layout-common.hh     | 12 ++++----
+ src/hb-aat-layout-kerx-table.hh | 38 +++++++++++------------
+ src/hb-aat-layout-morx-table.hh | 68 ++++++++++++++++++++---------------------
+ 3 files changed, 59 insertions(+), 59 deletions(-)
+
+commit 299eca0c3b28c99add006420bc667431d874fb2e
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Thu Jan 24 17:17:00 2019 +0100
+
+    [AAT] Handle out-of-bounds classes
+
+ src/hb-aat-layout-common.hh | 13 ++++++-------
+ 1 file changed, 6 insertions(+), 7 deletions(-)
+
+commit c4623db4a3f963394db940449007fa3312460993
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Thu Jan 24 17:10:12 2019 +0100
+
+    [AAT] Minor
+
+ src/hb-aat-layout-common.hh | 11 ++++-------
+ 1 file changed, 4 insertions(+), 7 deletions(-)
+
+commit c4e36f97b6df1eb5fba588b09ae1630bb5c49589
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Thu Jan 24 17:06:16 2019 +0100
+
+    [AAT] Minor
+
+ src/hb-aat-layout-common.hh | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+commit f60282c5bff4a317ba3180e3519274963c6e8849
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Thu Jan 24 16:29:09 2019 +0100
+
+    More pragma control
+    
+    Fixes https://bugs.chromium.org/p/chromium/issues/detail?id=924848
+
+ src/hb.hh | 16 +++++++++++++++-
+ 1 file changed, 15 insertions(+), 1 deletion(-)
+
+commit fd0889f903ac1ba2da06e77eed8424395ea85a90
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Thu Jan 24 16:12:52 2019 +0100
+
+    Comment
+
+ src/hb-ot-shape.cc | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+commit 00f06d1aa61e9a6d01b5943ce55ba2b0c40237ee
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Thu Jan 24 16:11:05 2019 +0100
+
+    Fix test
+
+ test/shaping/data/in-house/tests/cluster.tests | 1 -
+ test/shaping/data/in-house/tests/emoji.tests   | 3 ++-
+ 2 files changed, 2 insertions(+), 2 deletions(-)
+
+commit 9f314177336f9551756944e0e555614c9189c7a5
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Thu Jan 24 16:08:33 2019 +0100
+
+    Form cluster for Emoji sub-region tag sequences
+    
+    Fixes https://github.com/harfbuzz/harfbuzz/issues/1556
+
+ src/hb-ot-shape.cc                                       |  13 +++++++++++++
+ .../fonts/8d9c4b193808b8bde94389ba7831c1fc6f9e794e.ttf   | Bin 0 -> 1548 bytes
+ test/shaping/data/in-house/tests/cluster.tests           |   1 +
+ 3 files changed, 14 insertions(+)
+
+commit 5034f8f2ab8f53eb0395e6f6ce2f8da69a08460d
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Thu Jan 24 12:50:38 2019 +0100
+
+    Fix macos tests with previous commit
+
+ test/shaping/data/in-house/tests/macos.tests | 8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+commit 3ecda71041a7239ca37ec7b888809efe8f595a19
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Thu Jan 24 12:08:23 2019 +0100
+
+    Adjust mark offsets when zeroing from fallback mark positioning code
+    
+    Adjust tests.
+    
+    Fixes https://github.com/harfbuzz/harfbuzz/issues/1532
+
+ src/hb-ot-shape-fallback.cc                        | 31 +++++++++++++++-------
+ src/hb-ot-shape-fallback.hh                        |  3 ++-
+ src/hb-ot-shape.cc                                 |  3 ++-
+ .../in-house/tests/arabic-fallback-shaping.tests   |  2 +-
+ test/shaping/data/in-house/tests/cluster.tests     |  2 +-
+ .../data/in-house/tests/fallback-positioning.tests |  4 +--
+ 6 files changed, 30 insertions(+), 15 deletions(-)
+
+commit 12cd3171ba3b84eff9f359778fabcab8f66ce36e
+Merge: 261a7421 36fb2b4d
+Author: Michiharu Ariza <ariza@adobe.com>
+Date:   Wed Jan 23 14:05:42 2019 -0800
+
+    Merge branch 'master' into cff-more-arrayof-fixes
+
+commit 261a7421814d83f84d8def046b7108a245347461
+Author: Michiharu Ariza <ariza@adobe.com>
+Date:   Wed Jan 23 14:04:29 2019 -0800
+
+    more rewriting with ArrayOf<>
+    
+    CFF1 Encoding0, Encoding1, CFF1SuppEncData
+
+ src/hb-ot-cff1-table.hh | 51 +++++++++++++++++++++++--------------------------
+ 1 file changed, 24 insertions(+), 27 deletions(-)
+
+commit 36fb2b4da9718a86978fa07c99ba4345f7ca9b4b
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Wed Jan 23 20:53:57 2019 +0100
+
+    [AAT] In InsertionChain, set mark to previous-position if inserting
+    
+    Fixes MORX-31
+
+ src/hb-aat-layout-morx-table.hh | 8 +++++---
+ 1 file changed, 5 insertions(+), 3 deletions(-)
+
+commit cbe0ed117ac86179183c389977d15981d26524f7
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Wed Jan 23 20:45:18 2019 +0100
+
+    [AAT] Re-enable tests MORX-31 and MORX-41
+
+ test/shaping/data/text-rendering-tests/DISABLED         | 3 ---
+ test/shaping/data/text-rendering-tests/Makefile.sources | 2 ++
+ 2 files changed, 2 insertions(+), 3 deletions(-)
+
+commit baf4d6a68a031bf65e17ccd5dac15fe7d0df33b6
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Wed Jan 23 20:36:07 2019 +0100
+
+    [AAT] Remove mark_set from InsertionChain
+
+ src/hb-aat-layout-morx-table.hh | 7 +------
+ 1 file changed, 1 insertion(+), 6 deletions(-)
+
+commit 410731d3fb678365c07a4d1745b72b6bb3142b70
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Wed Jan 23 20:30:48 2019 +0100
+
+    [test/text-rendering-tests] Update from upstream
+
+ test/shaping/data/text-rendering-tests/extract-tests.py    | 2 +-
+ test/shaping/data/text-rendering-tests/tests/MORX-14.tests | 2 +-
+ test/shaping/data/text-rendering-tests/tests/MORX-32.tests | 8 ++++----
+ test/shaping/data/text-rendering-tests/tests/MORX-41.tests | 4 ++--
+ 4 files changed, 8 insertions(+), 8 deletions(-)
+
+commit 0b2fa342de88bbe609b2147444e56c94680cbd38
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Tue Jan 22 16:36:00 2019 +0100
+
+    More of previous
+
+ src/hb-subset-cff1.cc | 20 ++++++++++----------
+ 1 file changed, 10 insertions(+), 10 deletions(-)
+
+commit a5e5dd8b42b40c3647e06e6bb62580af77bed42b
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Tue Jan 22 16:30:07 2019 +0100
+
+    Fix sign-compare error resulted from promoting unsigned integers to signed larger ints
+    
+    Clang and gcc know not to warn in these cases, but not nonmainstream compilers
+
+ src/hb-subset-cff2.cc | 14 +++++++-------
+ 1 file changed, 7 insertions(+), 7 deletions(-)
+
+commit 32379bbf10726bb7ed2e507d0a6b5917c350e056
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Tue Jan 22 12:55:29 2019 +0100
+
+    Cast HB_UNTAG results to uint8_t
+
+ src/hb-common.h | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 83d4aa5ca9a39dbe66db9b81b34f5b568503bd7e
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Tue Jan 22 12:52:23 2019 +0100
+
+    More -Wcast-error fix
+
+ src/hb-dsalgs.hh | 3 +++
+ 1 file changed, 3 insertions(+)
+
+commit 447323b85a7b68bd41561a87c91431cd05227b97
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Tue Jan 22 12:45:40 2019 +0100
+
+    Better fix for -Wcast-align errors
+
+ src/hb-font.cc          | 33 +++++++++------------------------
+ src/hb-ft.cc            | 14 ++++----------
+ src/hb-machinery.hh     | 16 ++++++++++++++++
+ src/hb-ot-cmap-table.hh |  7 ++-----
+ src/hb-ot-font.cc       | 14 ++++----------
+ 5 files changed, 35 insertions(+), 49 deletions(-)
+
+commit 81ec543d800c4a94b5e608fd87e84d33d7dae8ac
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Tue Jan 22 12:43:12 2019 +0100
+
+    More -Wcast-error fixes
+
+ src/hb-font.cc    | 8 ++++----
+ src/hb-ft.cc      | 2 +-
+ src/hb-ot-font.cc | 4 ++--
+ 3 files changed, 7 insertions(+), 7 deletions(-)
+
+commit 90772725493108c79487a67620f0240e5d68f4ee
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Tue Jan 22 12:40:18 2019 +0100
+
+    pragma GCC diagnostic error   "-Wsign-compare"
+
+ src/hb.hh | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 8d05bf7dc0094e75be07ca1f7ef852a1e45d0687
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Tue Jan 22 12:34:05 2019 +0100
+
+    Fix cast-align error
+    
+    If compiler doesn't inline StructAtOffset, this was an error since we
+    only disable cast-align at call-site.  So, move the cast out.
+    
+    ../src/hb-machinery.hh: In instantiation of 'const Type& StructAtOffset(const void*, unsigned int) [with Type = unsigned int]':
+    ../src/hb-font.cc:146:85:   required from here
+    ../src/hb-machinery.hh:63:12: error: cast from 'const char*' to 'const unsigned int*' increases required alignment of target type [-Werror=cast-align]
+     { return * reinterpret_cast<const Type*> ((const char *) P + offset); }
+                ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+    ../src/hb-machinery.hh: In instantiation of 'Type& StructAtOffset(void*, unsigned int) [with Type = unsigned int]':
+    ../src/hb-font.cc:147:79:   required from here
+    ../src/hb-machinery.hh:66:12: error: cast from 'char*' to 'unsigned int*' increases required alignment of target type [-Werror=cast-align]
+     { return * reinterpret_cast<Type*> ((char *) P + offset); }
+                ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+ src/hb-font.cc          | 8 ++++----
+ src/hb-ft.cc            | 6 +++---
+ src/hb-ot-cmap-table.hh | 4 ++--
+ src/hb-ot-font.cc       | 4 ++--
+ 4 files changed, 11 insertions(+), 11 deletions(-)
+
+commit b270cee6c5800c019aafb55e9ca9d7e92a92d3ec
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Tue Jan 22 12:29:05 2019 +0100
+
+    [CI] Remove gcc 4.2 bots
+    
+    We don't support that version anymore.
+
+ .circleci/config.yml | 25 -------------------------
+ 1 file changed, 25 deletions(-)
+
+commit 70a52d6bd8c45630ca90e945fc4d716fe9114010
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Tue Jan 22 12:15:23 2019 +0100
+
+    Convert all other enum class consts to static constexpr
+    
+    Fixes https://github.com/harfbuzz/harfbuzz/issues/1553
+
+ src/hb-cff-interp-common.hh |  2 +-
+ src/hb-iter.hh              |  2 +-
+ src/hb-machinery.hh         | 12 ++++++------
+ src/hb-open-type.hh         |  8 ++++----
+ src/hb-set-digest.hh        |  4 ++--
+ src/hb-set.hh               | 10 +++++-----
+ src/hb-vector.hh            |  2 +-
+ 7 files changed, 20 insertions(+), 20 deletions(-)
+
+commit 5d4b0377b99ddc4112b8ffb2b787eac0b383081c
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Tue Jan 22 12:11:24 2019 +0100
+
+    Convert unsigned enum class consts to static constexpr
+    
+    Part of https://github.com/harfbuzz/harfbuzz/issues/1553
+
+ src/hb-aat-layout-common.hh     | 6 +++---
+ src/hb-aat-layout-kerx-table.hh | 2 +-
+ src/hb-buffer.hh                | 2 +-
+ src/hb-open-type.hh             | 2 +-
+ src/hb-ot-kern-table.hh         | 4 ++--
+ src/hb-ot-layout-common.hh      | 2 +-
+ src/hb-ot-layout.cc             | 4 ++--
+ 7 files changed, 11 insertions(+), 11 deletions(-)
+
+commit ef00654962204ae706b276871e2b6758fbbf69e0
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Tue Jan 22 12:08:57 2019 +0100
+
+    Convert tag enum class consts to static constexpr
+    
+    Part of https://github.com/harfbuzz/harfbuzz/issues/1553
+
+ src/hb-aat-fdsc-table.hh        |  2 +-
+ src/hb-aat-layout-ankr-table.hh |  2 +-
+ src/hb-aat-layout-bsln-table.hh |  2 +-
+ src/hb-aat-layout-feat-table.hh |  2 +-
+ src/hb-aat-layout-just-table.hh |  2 +-
+ src/hb-aat-layout-kerx-table.hh |  2 +-
+ src/hb-aat-layout-lcar-table.hh |  2 +-
+ src/hb-aat-layout-morx-table.hh |  6 +++---
+ src/hb-aat-layout-trak-table.hh |  2 +-
+ src/hb-aat-ltag-table.hh        |  2 +-
+ src/hb-ot-cff1-table.hh         |  2 +-
+ src/hb-ot-cff2-table.hh         |  2 +-
+ src/hb-ot-cmap-table.hh         |  2 +-
+ src/hb-ot-color-cbdt-table.hh   |  4 ++--
+ src/hb-ot-color-colr-table.hh   |  2 +-
+ src/hb-ot-color-cpal-table.hh   |  2 +-
+ src/hb-ot-color-sbix-table.hh   |  2 +-
+ src/hb-ot-color-svg-table.hh    |  2 +-
+ src/hb-ot-gasp-table.hh         |  2 +-
+ src/hb-ot-glyf-table.hh         |  4 ++--
+ src/hb-ot-hdmx-table.hh         |  2 +-
+ src/hb-ot-head-table.hh         |  2 +-
+ src/hb-ot-hhea-table.hh         |  4 ++--
+ src/hb-ot-hmtx-table.hh         | 12 ++++++------
+ src/hb-ot-kern-table.hh         |  6 +++---
+ src/hb-ot-layout-base-table.hh  |  2 +-
+ src/hb-ot-layout-gdef-table.hh  |  2 +-
+ src/hb-ot-layout-gpos-table.hh  |  2 +-
+ src/hb-ot-layout-gsub-table.hh  |  2 +-
+ src/hb-ot-layout-jstf-table.hh  |  2 +-
+ src/hb-ot-math-table.hh         |  2 +-
+ src/hb-ot-maxp-table.hh         |  2 +-
+ src/hb-ot-name-table.hh         |  2 +-
+ src/hb-ot-os2-table.hh          |  2 +-
+ src/hb-ot-post-table.hh         |  2 +-
+ src/hb-ot-stat-table.hh         |  2 +-
+ src/hb-ot-var-avar-table.hh     |  2 +-
+ src/hb-ot-var-fvar-table.hh     |  2 +-
+ src/hb-ot-var-hvar-table.hh     |  8 ++++----
+ src/hb-ot-var-mvar-table.hh     |  2 +-
+ src/hb-ot-vorg-table.hh         |  2 +-
+ 41 files changed, 56 insertions(+), 56 deletions(-)
+
+commit 39e1b6d03f71ccb8f18d64dfbff64acfaf02970b
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Tue Jan 22 12:07:43 2019 +0100
+
+    Convert boolean enum class consts to static constexpr
+    
+    Part of https://github.com/harfbuzz/harfbuzz/issues/1553
+
+ src/hb-aat-layout-common.hh     |  4 ++--
+ src/hb-aat-layout-kerx-table.hh |  4 ++--
+ src/hb-aat-layout-morx-table.hh |  8 ++++----
+ src/hb-dsalgs.hh                | 16 ++++++++--------
+ src/hb-ot-kern-table.hh         |  4 ++--
+ src/hb-ot-layout.cc             |  4 ++--
+ 6 files changed, 20 insertions(+), 20 deletions(-)
+
+commit 271cb7c1c0f49c7af786daa5d5310b9f08142148
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Tue Jan 22 12:05:35 2019 +0100
+
+    Make some enum constants unsigned
+
+ src/hb-aat-layout-common.hh | 6 +++---
+ src/hb-buffer.hh            | 2 +-
+ src/hb-ot-layout.cc         | 8 ++++----
+ 3 files changed, 8 insertions(+), 8 deletions(-)
+
+commit 3d9a6e62662fb769e0f785fa7a43df806988d2a2
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Tue Jan 22 12:02:06 2019 +0100
+
+    Whitespace
+
+ src/hb-ot-layout-gsubgpos.hh | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit c81f02fd06fcbc4426c9e3255833f8d7057cc97a
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Tue Jan 22 12:00:44 2019 +0100
+
+    pragma GCC diagnostic error   "-Wvla"
+
+ src/hb.hh | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit ff98109455bfbf92f7633262bc570b05d15d5d01
+Author: Alfie John <alfie@alfie.wtf>
+Date:   Tue Jan 22 19:58:36 2019 +1100
+
+    Fix grammar
+
+ docs/usermanual-clusters.xml | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit e9c0f5e714cc62bcf6349b86b13e1c031f9bb764
+Author: Alfie John <alfie@alfie.wtf>
+Date:   Tue Jan 22 00:03:02 2019 +0000
+
+    Grammar fix
+
+ docs/usermanual-clusters.xml | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 789396ed6bf2c76c1bb955e80efb43f75e3c61d2
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Sun Jan 20 20:09:10 2019 -0500
+
+    Remove wrongly added files
+
+ test/api/test-ot-extents-cff                        | Bin 8574336 -> 0 bytes
+ .../test-ot-extents-cff.dSYM/Contents/Info.plist    |  20 --------------------
+ .../Contents/Resources/DWARF/test-ot-extents-cff    | Bin 7650053 -> 0 bytes
+ 3 files changed, 20 deletions(-)
+
+commit 380c3cffb9353083913a3bb505c2c62367613096
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Sun Jan 20 19:51:08 2019 -0500
+
+    Use enum for class constant
+
+ src/hb-cff-interp-common.hh | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 6d042a18e7079e07a2b2f465a6a56483a42ef189
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Sun Jan 20 19:49:59 2019 -0500
+
+    [CFF] Use enum for tableTag
+
+ src/hb-ot-cff1-table.hh | 2 +-
+ src/hb-ot-cff2-table.hh | 2 +-
+ 2 files changed, 2 insertions(+), 2 deletions(-)
+
+commit c1cbbb94595641f0609cc8d2dbe8415540c10f77
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Sun Jan 20 19:47:52 2019 -0500
+
+    Use static constexpr for large class constants
+
+ src/hb-map.hh | 2 +-
+ src/hb-set.hh | 2 +-
+ 2 files changed, 2 insertions(+), 2 deletions(-)
+
+commit 30ae62779f1a68c5657ab27bc7e77496ba8a906c
+Author: Khaled Hosny <khaledhosny@eglug.org>
+Date:   Mon Jan 21 16:44:48 2019 +0200
+
+    Regular spaces will do
+
+ docs/usermanual-getting-started.xml | 16 ++++++++--------
+ 1 file changed, 8 insertions(+), 8 deletions(-)
+
+commit ed62551d67ac5bb8dbfaf3fa5eb51013157b214a
+Author: Alfie John <alfie@alfie.wtf>
+Date:   Mon Jan 21 05:00:01 2019 +0000
+
+    Adding leading space for code example
+
+ docs/usermanual-getting-started.xml | 16 ++++++++--------
+ 1 file changed, 8 insertions(+), 8 deletions(-)
+
+commit 3e332544db35ca08de767ecab01b489a9905c559
+Author: Alfie John <alfie@alfie.wtf>
+Date:   Mon Jan 21 04:54:27 2019 +0000
+
+    Fix description of example
+
+ docs/usermanual-getting-started.xml | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 2144ca9f01d01b6de386d17ada73a288372ee553
+Author: Alfie John <alfie@alfie.wtf>
+Date:   Mon Jan 21 04:47:05 2019 +0000
+
+    Added option to build docs to docs
+
+ docs/usermanual-install-harfbuzz.xml | 12 ++++++++++++
+ 1 file changed, 12 insertions(+)
+
+commit 21c0713a1cf4b42b5dfa8fb9bdf1c1935a481b00
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Wed Jan 9 21:24:51 2019 -0800
+
+    Whitespace
+
+ src/hb-ot-layout-gsub-table.hh | 8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+commit 934d3fa2a7d5d47da7030f43ea7ca7234625fc7e
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Wed Jan 9 21:00:13 2019 -0800
+
+    Use more iter pipelines
+
+ src/hb-ot-layout-gpos-table.hh |  9 +++++----
+ src/hb-ot-layout-gsubgpos.hh   | 32 ++++++++++++++++++--------------
+ 2 files changed, 23 insertions(+), 18 deletions(-)
+
+commit 420d8ac350590d776832dc7b353d997857cd7b45
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Wed Jan 9 20:58:25 2019 -0800
+
+    [algs] Add hb_iter()
+    
+    Makes it nicer in pipelines.
+
+ src/hb-algs.hh                 | 4 ++++
+ src/hb-ot-layout-gsub-table.hh | 6 +++---
+ 2 files changed, 7 insertions(+), 3 deletions(-)
+
+commit 54ec48ea20d7d7d9e62bca12265e2f26383f9bc1
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Wed Jan 9 20:54:21 2019 -0800
+
+    Use iter pipelines more
+
+ src/hb-ot-layout-gsub-table.hh | 81 +++++++++++++++++++++++-------------------
+ 1 file changed, 44 insertions(+), 37 deletions(-)
+
+commit 83cecd80d93a1e09231b8deaa6ecf8cd44875dfd
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Wed Jan 9 19:49:13 2019 -0800
+
+    [iter] Default projection to identity
+
+ src/hb-algs.hh | 6 +++---
+ src/hb-iter.hh | 4 ++--
+ 2 files changed, 5 insertions(+), 5 deletions(-)
+
+commit a699c6b17cf2d272ac445838e82db6b0017cdbd7
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Wed Jan 9 19:42:41 2019 -0800
+
+    [algs] Add hb_identity
+
+ src/hb-algs.hh | 8 +++++---
+ 1 file changed, 5 insertions(+), 3 deletions(-)
+
+commit 463cfb426ff94b78b8e44f1c5662931b948beca7
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Wed Jan 9 16:19:40 2019 -0800
+
+    Fix unused-variable warnings
+    
+    inline variables are not C++11, so mark them unused...
+
+ src/hb-algs.hh | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+commit f4cbb1ee0c7e1c2911c3676936e1bb571f6b255f
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Wed Jan 9 13:28:00 2019 -0800
+
+    WIP
+
+ src/hb-ot-layout-gsub-table.hh | 8 +++++---
+ 1 file changed, 5 insertions(+), 3 deletions(-)
+
+commit 471e96e55d3366a6ad723fe88c9aa895921c048f
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Wed Jan 9 12:42:01 2019 -0800
+
+    [iter] Use forwarding references
+
+ src/hb-iter.hh | 12 ++++++------
+ 1 file changed, 6 insertions(+), 6 deletions(-)
+
+commit 528ea66f24c326d7361663a145bd9b8081c7c5c2
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Wed Jan 9 12:36:17 2019 -0800
+
+    [algs] Fix hb_first() / hb_second()
+
+ src/hb-algs.hh | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+commit 343f5a4bfcf528ed8f5239fae9ddfca64b998fde
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Wed Jan 9 12:35:45 2019 -0800
+
+    [iter] Misc fixes to get piping almost work
+
+ src/hb-iter.hh | 19 ++++++++++++-------
+ 1 file changed, 12 insertions(+), 7 deletions(-)
+
+commit 7cedf7f64c2be0d16771dba73fd370325f7b66a1
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Wed Jan 9 12:22:14 2019 -0800
+
+    Change hb_first() and hb_second() to function objects
+
+ src/hb-algs.hh | 14 ++++++++++----
+ 1 file changed, 10 insertions(+), 4 deletions(-)
+
+commit f35568d603df6409e4f867acf2f58794560f6649
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Wed Jan 9 11:32:33 2019 -0800
+
+    [iter] Add hb_filter()
+    
+    Untested.
+
+ src/hb-iter.hh | 39 +++++++++++++++++++++++++++++++++++++++
+ 1 file changed, 39 insertions(+)
+
+commit 1733e4702c4f4f8058e69500008d050cf9df0318
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Wed Jan 9 11:15:49 2019 -0800
+
+    [iter] Add hb_map()
+    
+    Untested.
+
+ src/hb-iter.hh | 43 ++++++++++++++++++++++++++++++++++++++++++-
+ 1 file changed, 42 insertions(+), 1 deletion(-)
+
+commit f7fcc476418099e2b89c52068ac81280a95bf76f
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Wed Jan 9 11:00:32 2019 -0800
+
+    [iter] Make hb_zip() take const references
+
+ src/hb-iter.hh | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
 
-    removed unused test data
+commit ede1a71b31f49a6dc247ac0491b78508346e9932
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Wed Jan 9 10:45:53 2019 -0800
 
- ...ts.desubroutinize-retain-gids.1FC,21,41,20,62,63.otf | Bin 15456 -> 0 bytes
- ...r.drop-hints.desubroutinize-retain-gids.61,62,63.otf | Bin 13036 -> 0 bytes
- ...-hints.desubroutinize-retain-gids.D7,D8,D9,DA,DE.otf | Bin 16656 -> 0 bytes
- ...nsPro-Regular.drop-hints.desubroutinize.61,62,63.otf | Bin 3276 -> 0 bytes
- ...-hints.desubroutinize.retain-gids.D7,D8,D9,DA,DE.otf | Bin 34560 -> 0 bytes
- ...ro-Regular.drop-hints.retain-gids.D7,D8,D9,DA,DE.otf | Bin 34576 -> 0 bytes
- 6 files changed, 0 insertions(+), 0 deletions(-)
+    Minor rename
 
-commit 30b781f20a8e386732f8e2858a22665d7af98061
-Merge: c1286265 1e062821
-Author: Michiharu Ariza <ariza@adobe.com>
-Date:   Fri Feb 1 14:50:34 2019 -0800
+ src/hb-ot-layout-gsub-table.hh | 12 ++++++------
+ src/hb-ot-layout-gsubgpos.hh   |  6 +++---
+ 2 files changed, 9 insertions(+), 9 deletions(-)
 
-    Merge branch 'master' into cff-retain-gids
+commit 93551669c5a41ee11a156ef60a9f80dc328430b9
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Wed Jan 9 10:18:49 2019 -0800
 
-commit c12862657f24b6c197e23d99a4edbdfcf3c90653
-Author: Michiharu Ariza <ariza@adobe.com>
-Date:   Fri Feb 1 14:50:01 2019 -0800
+    Remove unused Coverage::iter_t::get_coverage()
 
-    added desubroutinize & retain-gids full test cases with CFF fonts
+ src/hb-ot-layout-common.hh | 11 -----------
+ 1 file changed, 11 deletions(-)
+
+commit af2067e87b06995a9cc9154baab2a5bc4f3f6955
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Wed Jan 9 10:17:33 2019 -0800
+
+    Use hb_zip() moooore
+
+ src/hb-ot-layout-gsub-table.hh | 24 ++++++++++++------------
+ 1 file changed, 12 insertions(+), 12 deletions(-)
+
+commit 0d1fdf939de13bb1994bc8f70da7f9f511b7e5be
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Wed Jan 9 10:06:48 2019 -0800
+
+    Use hb_zip() some mooore
+
+ src/hb-ot-layout-gpos-table.hh | 13 +++------
+ src/hb-ot-layout-gsub-table.hh | 64 +++++++++++-------------------------------
+ 2 files changed, 21 insertions(+), 56 deletions(-)
+
+commit af6c1902356c937bc47ad8c37ab6f037b5810b67
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Wed Jan 9 10:01:28 2019 -0800
+
+    Use hb_zip() some moore
+
+ src/hb-ot-layout-gsubgpos.hh | 52 ++++++++++++--------------------------------
+ 1 file changed, 14 insertions(+), 38 deletions(-)
+
+commit 83ad0b6d0f3e7656f78611e89d7ebb939cd8e713
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Wed Jan 9 09:57:36 2019 -0800
+
+    Use hb_zip() some more
+
+ src/hb-ot-layout-gsub-table.hh | 36 ++++++++++--------------------------
+ 1 file changed, 10 insertions(+), 26 deletions(-)
+
+commit f0dd0656b8d2038ae6aa8d0a39d17130ddc8f16f
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Wed Jan 9 09:52:10 2019 -0800
+
+    Use hb_zip() some
+
+ src/hb-ot-layout-gsub-table.hh | 20 +++++---------------
+ 1 file changed, 5 insertions(+), 15 deletions(-)
+
+commit 200cdb721bfb125cd462437ccbcc40554560c4d0
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Wed Jan 9 09:49:12 2019 -0800
+
+    [iter] Rename hb_zip_t to hb_zip_iter_t
+
+ src/hb-iter.hh | 12 ++++++------
+ 1 file changed, 6 insertions(+), 6 deletions(-)
+
+commit 3290c181c17db33991cd1b79eca49f70d2601ce0
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Wed Jan 9 09:08:15 2019 -0800
+
+    [algs] Whitespace
+
+ src/hb-algs.hh | 12 +++++++-----
+ 1 file changed, 7 insertions(+), 5 deletions(-)
+
+commit 014c50292b471de0167b65fdc0eb446245438b84
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Wed Jan 9 09:07:01 2019 -0800
+
+    [iter] Move code
+
+ src/hb-iter.hh | 47 ++++++++++++++++++++++++++++-------------------
+ 1 file changed, 28 insertions(+), 19 deletions(-)
+
+commit 6e3ad650d1b864742084c6254d020734f09cb396
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Wed Jan 9 09:05:01 2019 -0800
+
+    Rename hb-dsalgs to hb-algs
+
+ src/Makefile.sources             | 2 +-
+ src/{hb-dsalgs.hh => hb-algs.hh} | 6 +++---
+ src/hb-array.hh                  | 2 +-
+ src/hb-debug.hh                  | 2 +-
+ src/hb-iter.hh                   | 2 +-
+ src/hb.hh                        | 8 ++++----
+ 6 files changed, 11 insertions(+), 11 deletions(-)
+
+commit f27607580e4d13e8ddf721df971a7d5062c54fb2
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Wed Jan 9 09:03:21 2019 -0800
+
+    [algs] Add hb_first() and hb_second()
+
+ src/hb-dsalgs.hh | 7 +++++++
+ 1 file changed, 7 insertions(+)
+
+commit a7de144df342f30b3d6f9e61c3fe3d1348ab222d
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Wed Jan 9 08:39:25 2019 -0800
+
+    Implement uniform map interface
     
-    and CFF retain-gids fixes
+    Coverage, ClassDef, hb_set_t, and hb_map_t implement.
 
- src/hb-subset-cff1.cc                              |  44 +++++++++------------
- .../SourceHanSans-Regular.41,4C2E.retaingids.otf   | Bin 2600 -> 2604 bytes
- ...subroutinize-retain-gids.1FC,21,41,20,62,63.otf | Bin 0 -> 33516 bytes
- ...Regular.desubroutinize-retain-gids.61,62,63.otf | Bin 0 -> 31080 bytes
- ...r.desubroutinize-retain-gids.D7,D8,D9,DA,DE.otf | Bin 0 -> 34708 bytes
- ...subroutinize-retain-gids.1FC,21,41,20,62,63.otf | Bin 0 -> 33352 bytes
- ...p-hints-desubroutinize-retain-gids.61,62,63.otf | Bin 0 -> 30956 bytes
- ...s-desubroutinize-retain-gids.D7,D8,D9,DA,DE.otf | Bin 0 -> 34560 bytes
- ...op-hints-desubroutinize.1FC,21,41,20,62,63.otf} | Bin
- ...-Regular.drop-hints-desubroutinize.61,62,63.otf | Bin 0 -> 3288 bytes
- ...r.drop-hints-desubroutinize.D7,D8,D9,DA,DE.otf} | Bin
- ...r.drop-hints-retain-gids.1FC,21,41,20,62,63.otf | Bin 0 -> 33448 bytes
- ...Pro-Regular.drop-hints-retain-gids.61,62,63.otf | Bin 0 -> 31028 bytes
- ...gular.drop-hints-retain-gids.D7,D8,D9,DA,DE.otf | Bin 0 -> 34576 bytes
- ...subroutinize-retain-gids.1FC,21,41,20,62,63.otf | Bin 0 -> 15456 bytes
- ...p-hints.desubroutinize-retain-gids.61,62,63.otf | Bin 0 -> 13036 bytes
- ...s.desubroutinize-retain-gids.D7,D8,D9,DA,DE.otf | Bin 0 -> 16656 bytes
- ...s.desubroutinize.retain-gids.D7,D8,D9,DA,DE.otf | Bin 0 -> 34560 bytes
- ...gular.drop-hints.retain-gids.D7,D8,D9,DA,DE.otf | Bin 0 -> 34576 bytes
- ...sPro-Regular.retain-gids.1FC,21,41,20,62,63.otf | Bin 0 -> 33668 bytes
- .../SourceSansPro-Regular.retain-gids.61,62,63.otf | Bin 0 -> 31180 bytes
- ...eSansPro-Regular.retain-gids.D7,D8,D9,DA,DE.otf | Bin 0 -> 34724 bytes
- ...e-retain-gids.3042,3044,3046,3048,304A,304B.otf | Bin 0 -> 536352 bytes
- ...e-retain-gids.3042,3044,3046,73E0,5EA6,8F38.otf | Bin 0 -> 690752 bytes
- ...ular.desubroutinize-retain-gids.61,63,65,6B.otf | Bin 0 -> 530004 bytes
- ...e-retain-gids.660E,6975,73E0,5EA6,8F38,6E05.otf | Bin 0 -> 690868 bytes
- ...ans-Regular.desubroutinize-retain-gids.660E.otf | Bin 0 -> 612212 bytes
- .../SourceHanSans-Regular.desubroutinize..otf      | Bin 2340 -> 0 bytes
- ...e-retain-gids.3042,3044,3046,3048,304A,304B.otf | Bin 0 -> 536176 bytes
- ...e-retain-gids.3042,3044,3046,73E0,5EA6,8F38.otf | Bin 0 -> 690500 bytes
- ...ints-desubroutinize-retain-gids.61,63,65,6B.otf | Bin 0 -> 529888 bytes
- ...e-retain-gids.660E,6975,73E0,5EA6,8F38,6E05.otf | Bin 0 -> 690564 bytes
- ....drop-hints-desubroutinize-retain-gids.660E.otf | Bin 0 -> 612108 bytes
- ...subroutinize.3042,3044,3046,3048,304A,304B.otf} | Bin 6076 -> 6096 bytes
- ...subroutinize.3042,3044,3046,73E0,5EA6,8F38.otf} | Bin 6180 -> 6204 bytes
- ...ular.drop-hints-desubroutinize.61,63,65,6B.otf} | Bin 5312 -> 5344 bytes
- ...subroutinize.660E,6975,73E0,5EA6,8F38,6E05.otf} | Bin 6248 -> 6268 bytes
- ...ans-Regular.drop-hints-desubroutinize.660E.otf} | Bin 5140 -> 5120 bytes
- ...s-retain-gids.3042,3044,3046,3048,304A,304B.otf | Bin 0 -> 536244 bytes
- ...s-retain-gids.3042,3044,3046,73E0,5EA6,8F38.otf | Bin 0 -> 690596 bytes
- ...-Regular.drop-hints-retain-gids.61,63,65,6B.otf | Bin 0 -> 529928 bytes
- ...s-retain-gids.660E,6975,73E0,5EA6,8F38,6E05.otf | Bin 0 -> 690768 bytes
- ...HanSans-Regular.drop-hints-retain-gids.660E.otf | Bin 0 -> 612128 bytes
- ...eHanSans-Regular.drop-hints.desubroutinize..otf | Bin 2188 -> 0 bytes
- ...r.retain-gids.3042,3044,3046,3048,304A,304B.otf | Bin 0 -> 536436 bytes
- ...r.retain-gids.3042,3044,3046,73E0,5EA6,8F38.otf | Bin 0 -> 690860 bytes
- ...urceHanSans-Regular.retain-gids.61,63,65,6B.otf | Bin 0 -> 530084 bytes
- ...r.retain-gids.660E,6975,73E0,5EA6,8F38,6E05.otf | Bin 0 -> 691076 bytes
- .../SourceHanSans-Regular.retain-gids.660E.otf     | Bin 0 -> 612236 bytes
- .../data/profiles/desubroutinize-retain-gids.txt   |   2 +
- .../drop-hints-desubroutinize-retain-gids.txt      |   3 ++
- test/subset/data/tests/full-font.tests             |   6 +++
- test/subset/data/tests/japanese.tests              |   6 +++
- test/subset/subset_test_suite.py                   |   2 +-
- 54 files changed, 36 insertions(+), 27 deletions(-)
+ src/hb-map.hh              | 13 +++++++------
+ src/hb-ot-layout-common.hh | 14 ++++++++++++--
+ src/hb-set.hh              | 17 ++++++++++++-----
+ 3 files changed, 31 insertions(+), 13 deletions(-)
 
-commit f2908b4d8f9b02ce06d3f648c3f08757797073b6
-Author: Michiharu Ariza <ariza@adobe.com>
-Date:   Thu Jan 31 14:16:37 2019 -0800
+commit 7987095e64e52b509661828aeadabe0b27bba0d0
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Wed Jan 9 01:02:38 2019 -0800
 
-    Implement subset --regain-gids option with CFF1/2
+    [meta] Remove hb_enable_if_t
     
-    along with api tests & expected results
+    It was only used for C++<11 which does not allow default parameters
+    in function templates.  Looks like we cannot support <11 anyway, so,
+    start cleaning up.
 
- src/hb-subset-cff-common.cc                        |  17 +++-
- src/hb-subset-cff-common.hh                        |  91 +++++++++++++--------
- src/hb-subset-cff1.cc                              |  89 ++++++++++++--------
- src/hb-subset-cff2.cc                              |  30 ++++---
- test/api/fonts/AdobeVFPrototype.ac.retaingids.otf  | Bin 0 -> 7000 bytes
- .../SourceHanSans-Regular.41,4C2E.retaingids.otf   | Bin 0 -> 2600 bytes
- .../fonts/SourceSansPro-Regular.ac.retaingids.otf  | Bin 0 -> 1708 bytes
- test/api/test-subset-cff1.c                        |  48 +++++++++++
- test/api/test-subset-cff2.c                        |  24 ++++++
- 9 files changed, 217 insertions(+), 82 deletions(-)
+ src/hb-iter.hh             | 18 +++++++++---------
+ src/hb-meta.hh             |  1 -
+ src/hb-open-type.hh        | 14 ++++++--------
+ src/hb-ot-layout-common.hh | 21 +++++++++------------
+ src/test-iter.cc           | 12 ++++++------
+ 5 files changed, 30 insertions(+), 36 deletions(-)
 
-commit 1e06282105a2d579aab32094cc7abc10ed231978
+commit 15a69284369ce739e79bf288a55c4c3010313144
 Author: Behdad Esfahbod <behdad@behdad.org>
-Date:   Thu Jan 31 13:56:58 2019 -0800
+Date:   Wed Jan 9 00:36:47 2019 -0800
 
-    Adjust hb_is_signed<>
+    [iter] Implement operator-> unconditionally
     
-    Fixes https://github.com/harfbuzz/harfbuzz/issues/1535
+    The right condition to check for would have been "is_struct", which
+    we don't have.
 
- src/hb-dsalgs.hh | 27 +++++++++------------------
- 1 file changed, 9 insertions(+), 18 deletions(-)
+ src/hb-iter.hh | 1 -
+ 1 file changed, 1 deletion(-)
 
-commit 21ea1c91529471c05e03b6db61df256f24fa23c1
+commit 8f52a827e7d93abf3ef6159fd00f7c85c6d46793
 Author: Behdad Esfahbod <behdad@behdad.org>
-Date:   Thu Jan 31 13:49:18 2019 -0800
+Date:   Wed Jan 9 00:36:26 2019 -0800
 
-    Remove stale comment
+    Allow rvalues in hb_addressof()
 
- src/hb-dsalgs.hh | 5 -----
- 1 file changed, 5 deletions(-)
+ src/hb-dsalgs.hh | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
 
-commit 9f80eb0177e527253818ad9171fc75fb565318cb
-Merge: b3799007 d14d2c20
-Author: Michiharu Ariza <ariza@adobe.com>
-Date:   Thu Jan 31 12:54:36 2019 -0800
+commit a4ea0d368015b91df8d4c164a8838c45943562dc
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Wed Jan 9 00:32:11 2019 -0800
 
-    Merge branch 'master' into cff-more-arrayof-fixes
+    [iter] Change from const_iter_t/iter_t to iter_t/writer_t
 
-commit d14d2c20b05c5acf0a6f9c6dc36a7b8d8966153e
-Merge: acf5f0a3 dc04261a
+ src/hb-open-type.hh | 26 ++++++++++++--------------
+ src/hb-vector.hh    | 13 ++++++-------
+ 2 files changed, 18 insertions(+), 21 deletions(-)
+
+commit 7798e4fcc34edca5c7d5d2fe7abd09a0540f0fea
 Author: Behdad Esfahbod <behdad@behdad.org>
-Date:   Wed Jan 30 18:36:57 2019 -0500
+Date:   Wed Jan 9 00:25:53 2019 -0800
 
-    Merge pull request #1567 from googlefonts/fuzzer
-    
-    [subset] Update the subset fuzzer to get  options to use from test case.
+    [iter] Change Coverage iterator to only return glyph-id
 
-commit dc04261a5b8408bcfde16090ddf91568c3d8dae7
-Author: Garret Rieger <grieger@google.com>
-Date:   Wed Jan 30 15:23:19 2019 -0800
+ src/hb-ot-layout-common.hh | 8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
 
-    [subset] Update the subset fuzzer to determine which options to use based on data in the fuzzing test case.
-    Add support for toggling retain_gids.
+commit 84e5d002290eb2f58392743bc841fa7def7fc96d
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Tue Jan 8 23:57:16 2019 -0800
 
- test/fuzzing/hb-subset-fuzzer.cc | 32 +++++++++++++++++++-------------
- 1 file changed, 19 insertions(+), 13 deletions(-)
+    [iter] Add hb_zip()
 
-commit acf5f0a3aff0e128509b0979f629edf0596fcee5
+ src/hb-iter.hh   | 34 ++++++++++++++++++++++++++++++++++
+ src/test-iter.cc |  2 ++
+ 2 files changed, 36 insertions(+)
+
+commit 636786ecaf18c52d4c337d009434b22e868ab796
 Author: Behdad Esfahbod <behdad@behdad.org>
-Date:   Wed Jan 30 15:10:23 2019 -0800
+Date:   Tue Jan 8 23:48:35 2019 -0800
 
-    [configure] Fix up
+    [iter] Rename __item_type__ to __item_t__
 
- configure.ac | 11 +++++------
- 1 file changed, 5 insertions(+), 6 deletions(-)
+ src/hb-array.hh            | 2 +-
+ src/hb-iter.hh             | 4 ++--
+ src/hb-ot-layout-common.hh | 4 ++--
+ src/hb-set.hh              | 2 +-
+ src/test-iter.cc           | 2 +-
+ 5 files changed, 7 insertions(+), 7 deletions(-)
 
-commit 6b834c1c76b867ef32747202a755255d2f360f1e
+commit 6caf76f4a8b5e232a87b84dc5e357dddef63d00b
 Author: Behdad Esfahbod <behdad@behdad.org>
-Date:   Wed Jan 30 15:06:22 2019 -0800
+Date:   Tue Jan 8 23:28:05 2019 -0800
 
-    [configure] Print compiler version info in report
+    Tighten Coverage iteration
 
- configure.ac | 6 ++++++
- 1 file changed, 6 insertions(+)
+ src/hb-ot-layout-common.hh | 7 +++++--
+ 1 file changed, 5 insertions(+), 2 deletions(-)
 
-commit d983c529b66b530715e9c813c69e699b1d8029d3
-Merge: 55d1d7c8 e6ffcc59
+commit ff3a7ce1e75b020c2d536200beb5610ed054e097
 Author: Behdad Esfahbod <behdad@behdad.org>
-Date:   Wed Jan 30 17:17:59 2019 -0500
+Date:   Tue Jan 8 23:20:23 2019 -0800
 
-    Merge pull request #1564 from googlefonts/retain_gids
+    [subset] Minor
+
+ src/hb-ot-layout-common.hh | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 42bf80e578a1b7f4023b3edeea7de103a3c7d7be
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Tue Jan 8 19:13:17 2019 -0800
+
+    [iter] More semicolon
+
+ src/hb-iter.hh | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit f78f837ef17591144d6b22ae3cc71c49458253ff
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Tue Jan 8 16:38:08 2019 -0800
+
+    [iter] Use aliasing using for types
     
-    [subset] Add --retain-gids option to the subsetter.
+    Fix ambiguity of hb_sorted_array_t::item_t with gcc.  No idea if that's a gcc bug
+    or what spec requires, but using aliasing using seems to fix it.  It probably breaks
+    our non-C++11 bots, in which case I have to condition the change.  Testing.
 
-commit 55d1d7c8bcd8d97c4e618e5dd21f13df50b10ce8
+ src/hb-iter.hh | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+commit 3fc03e42ce73021c4573729a637d19346f7e5f44
 Author: Behdad Esfahbod <behdad@behdad.org>
-Date:   Wed Jan 30 13:54:15 2019 -0800
+Date:   Tue Jan 8 16:33:31 2019 -0800
 
-    2.3.1
+    [iter] Use static_assert with hb_is_random_access_iterator()
+    
+    Both, checks constexpr'ness, and fixes build with cra**y implementations
+    of assert() macro:
+    
+    test-iter.cc:108:11: error: too many arguments provided to function-like macro invocation
+      assert (hb_is_random_access_iterator (array_iter_t<int>));
+              ^
+    ./hb-iter.hh:186:42: note: expanded from macro 'hb_is_random_access_iterator'
+      hb_is_random_access_iterator_of (Iter, typename Iter::item_t)
+                                             ^
+    /usr/include/x86_64-linux-gnu/sys/cdefs.h:89:9: note: macro '__STRING' defined here
+    \#define __STRING(x)     #x
+            ^
+    test-iter.cc:108:3: error: use of undeclared identifier '__STRING'
+      assert (hb_is_random_access_iterator (array_iter_t<int>));
+      ^
+    /usr/include/assert.h:91:21: note: expanded from macro 'assert'
+       : __assert_fail (__STRING(expr), __FILE__, __LINE__, __ASSERT_FUNCTION))
+                        ^
 
- NEWS             | 7 +++++++
- configure.ac     | 2 +-
- src/hb-version.h | 4 ++--
- 3 files changed, 10 insertions(+), 3 deletions(-)
+ src/test-iter.cc | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
 
-commit e6ffcc5904ab88143cad0c7a7a4c990147af278b
-Author: Garret Rieger <grieger@google.com>
-Date:   Mon Jan 28 18:12:19 2019 -0800
+commit 6af9c5f18eaf51f2d7e564d23d9b09219af9d700
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Tue Jan 8 16:27:37 2019 -0800
 
-    [subset] Add expected files for retain-gids integration tests.
+    [iter] Remove stray semicolons
 
- ...oboto-Regular.abc.drop-hints-retain-gids.61,62,63.ttf | Bin 0 -> 924 bytes
- .../Roboto-Regular.abc.drop-hints-retain-gids.61,63.ttf  | Bin 0 -> 856 bytes
- .../Roboto-Regular.abc.drop-hints-retain-gids.61.ttf     | Bin 0 -> 744 bytes
- .../Roboto-Regular.abc.drop-hints-retain-gids.62.ttf     | Bin 0 -> 712 bytes
- .../Roboto-Regular.abc.drop-hints-retain-gids.63.ttf     | Bin 0 -> 716 bytes
- .../basics/Roboto-Regular.abc.retain-gids.61,62,63.ttf   | Bin 0 -> 2168 bytes
- .../basics/Roboto-Regular.abc.retain-gids.61,63.ttf      | Bin 0 -> 1996 bytes
- .../basics/Roboto-Regular.abc.retain-gids.61.ttf         | Bin 0 -> 1808 bytes
- .../basics/Roboto-Regular.abc.retain-gids.62.ttf         | Bin 0 -> 1756 bytes
- .../basics/Roboto-Regular.abc.retain-gids.63.ttf         | Bin 0 -> 1732 bytes
- test/subset/data/profiles/retain-gids.txt                |   1 -
- 11 files changed, 1 deletion(-)
+ src/hb-iter.hh | 8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
 
-commit 198859bb3702e45cb271dd51b7231f10d01576be
-Author: Garret Rieger <grieger@google.com>
-Date:   Mon Jan 28 18:10:56 2019 -0800
+commit 74ca7b580c284d6fe3bf7067a19a2095102e72d1
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Tue Jan 8 13:48:42 2019 -0800
 
-    [subset] For retain gids don't truncate glyphs past the highest requested subset glyph.
+    [OT] Implement operator[] for Coverage and ClassDef
 
- src/hb-subset-plan.cc | 8 +++++---
- 1 file changed, 5 insertions(+), 3 deletions(-)
+ src/hb-ot-layout-common.hh | 7 ++++++-
+ 1 file changed, 6 insertions(+), 1 deletion(-)
 
-commit 490d52f908aaa4722e71a4a682de20e94d89ad00
-Author: Garret Rieger <grieger@google.com>
-Date:   Mon Jan 28 17:43:42 2019 -0800
+commit 6c548b6657d419e013969f9a456418e46bef0b30
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Tue Jan 8 13:43:49 2019 -0800
 
-    [subset] Add retain-gids option to hb-subset executable.
+    [iter] Add TODO
 
- util/hb-subset.cc | 1 +
- util/options.cc   | 1 +
- util/options.hh   | 2 ++
- 3 files changed, 4 insertions(+)
+ src/hb-iter.hh | 4 ++++
+ 1 file changed, 4 insertions(+)
 
-commit a903f9c228d1f3e8065f89de16e50027d6018e58
-Author: Garret Rieger <grieger@google.com>
-Date:   Mon Jan 28 17:43:11 2019 -0800
+commit 362d4e7cc324bf99b087aa34a4fae6898e50674f
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Tue Jan 8 13:41:30 2019 -0800
 
-    [subset] Add some subsetting integration tests covering retain gids.
+    [iter] Implement for OT::ArrayOf / OT::SortedArrayOf
 
- test/subset/data/profiles/drop-hints-retain-gids.txt | 2 ++
- test/subset/data/profiles/retain-gids.txt            | 2 ++
- test/subset/data/tests/basics.tests                  | 2 ++
- 3 files changed, 6 insertions(+)
+ src/hb-open-type.hh | 36 ++++++++++++++++++++++++------------
+ 1 file changed, 24 insertions(+), 12 deletions(-)
 
-commit 05e99c86baa0e95c2bff1c87d601eaf022c9d1f8
-Author: Garret Rieger <grieger@google.com>
-Date:   Mon Jan 28 17:05:04 2019 -0800
+commit 2f837a365c0986c2f925624d9c00ede8cd9e7669
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Tue Jan 8 13:05:01 2019 -0800
 
-    [subset] A few small fixes for the new subset plan api.
+    [SortedArrayOf] Fix sub_array() return type
 
- src/hb-ot-hdmx-table.hh | 6 +++---
- src/hb-ot-hmtx-table.hh | 9 +++------
- src/hb-subset.cc        | 2 +-
- 3 files changed, 7 insertions(+), 10 deletions(-)
+ src/hb-open-type.hh | 8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
 
-commit bdbe047d6ce3d8873c6740500d38d1b0c4e851f8
-Author: Garret Rieger <grieger@google.com>
-Date:   Mon Jan 28 16:59:15 2019 -0800
+commit 54c30e949e7d0a80c19cb8a12c300d62425683a9
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Tue Jan 8 13:00:06 2019 -0800
 
-    [subset] Update hb-subset-plan.cc to match hb-subset-plan.hh.
+    [iter] Constrain hb_fill() and hb_copy()
 
- src/hb-subset-plan.cc | 20 ++++++++++----------
- src/hb-subset-plan.hh |  1 -
- 2 files changed, 10 insertions(+), 11 deletions(-)
+ src/hb-iter.hh | 10 +++++++---
+ 1 file changed, 7 insertions(+), 3 deletions(-)
 
-commit 74c44ffebafe7758937d82524758be8bb4ecc4e2
-Author: Garret Rieger <grieger@google.com>
-Date:   Mon Jan 28 16:53:01 2019 -0800
+commit dc0a98cbe7be25a38220eda19ee06b19bf2d130d
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Tue Jan 8 12:57:01 2019 -0800
 
-    [subset] Update hb-subset-glyf.cc to use new hb-subset-plan API.
+    [iter] Add TODO
 
- src/hb-subset-glyf.cc | 57 ++++++++++++++++++++-------------------------------
- 1 file changed, 22 insertions(+), 35 deletions(-)
+ src/hb-iter.hh | 3 +++
+ 1 file changed, 3 insertions(+)
 
-commit 4842294b861b9fe322c811abef0ebb0553be2bf0
-Author: Garret Rieger <grieger@google.com>
-Date:   Mon Jan 28 16:51:27 2019 -0800
+commit 2658e40ffb66dba6e2e5525d6ee4792fe1ea1dd1
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Tue Jan 8 12:53:02 2019 -0800
 
-    [subset] Update gsub to use glyphset() method of subset plan.
+    [iter] Add hb_is_random_access_iterator()
 
- src/hb-ot-layout-gsub-table.hh | 4 ++--
- 1 file changed, 2 insertions(+), 2 deletions(-)
+ src/hb-iter.hh   | 10 +++++++---
+ src/test-iter.cc |  2 ++
+ 2 files changed, 9 insertions(+), 3 deletions(-)
 
-commit 853b1f1aa5489b8439c41c30be77ed042c8c89e5
-Author: Garret Rieger <grieger@google.com>
-Date:   Mon Jan 28 16:50:56 2019 -0800
+commit 445364d80a06007de5ac4c0fca9bb0b846f25c9c
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Tue Jan 8 12:42:15 2019 -0800
 
-    [subset] Correct maxp num glyph's to use new subset plan method.
+    [iter] Rename hb_is_[sorted_]iterator() -> hb_is_[sorted_]iterator_of()
 
- src/hb-ot-maxp-table.hh | 2 +-
+ src/hb-iter.hh             | 15 +++++++++------
+ src/hb-open-type.hh        |  4 ++--
+ src/hb-ot-layout-common.hh |  6 +++---
+ src/test-iter.cc           |  2 +-
+ 4 files changed, 15 insertions(+), 12 deletions(-)
+
+commit a6c013b1bf1f828f1eea7db801f2efb9a1486773
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Tue Jan 8 14:27:51 2019 -0500
+
+    [meta] Add hb_declval() macro
+
+ src/hb-iter.hh | 2 +-
+ src/hb-meta.hh | 1 +
+ 2 files changed, 2 insertions(+), 1 deletion(-)
+
+commit adc5910a63f209e35133c59f4466443844c9a18a
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Tue Jan 8 14:26:41 2019 -0500
+
+    [iter] Syntax
+
+ src/hb-iter.hh | 2 +-
  1 file changed, 1 insertion(+), 1 deletion(-)
 
-commit 846e05a298bc088f2cd2fe53b75ca531916a56f8
-Author: Garret Rieger <grieger@google.com>
-Date:   Mon Jan 28 16:50:20 2019 -0800
+commit ca6adcd1ad35932aeac4d46a191809b010636b3d
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Tue Jan 8 14:23:12 2019 -0500
 
-    [subset] Re-add glyphs array to subset plan, with new name 'glyphs_deprecated'. Switch CFF subsetting to use it.
+    [iter] Test hb_is_iterable / hb_is_iterator
 
- src/hb-subset-cff1.cc | 36 ++++++++++++++++++------------------
- src/hb-subset-cff2.cc | 12 ++++++------
- src/hb-subset-plan.hh |  3 +++
- 3 files changed, 27 insertions(+), 24 deletions(-)
+ src/test-iter.cc | 12 ++++++++----
+ 1 file changed, 8 insertions(+), 4 deletions(-)
 
-commit 03e88eab5c0f8775ccffc0925532748140d93470
-Author: Garret Rieger <grieger@google.com>
-Date:   Mon Jan 28 16:15:06 2019 -0800
+commit 8237809f065f41653a12c95885e3b76409c42f36
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Mon Jan 7 22:00:45 2019 -0500
 
-    Re-implement HMTX/VMTX subsetting. Update it to support glyph renumbering and simplify the implementation.
+    [serialize] Make SortedArrayOf:;serialize() take sorted-iterator
 
- src/hb-ot-hmtx-table.hh | 99 +++++++++++++++++++++++++------------------------
- src/hb-subset-plan.cc   |  2 +-
- src/hb-subset-plan.hh   |  2 +-
- 3 files changed, 53 insertions(+), 50 deletions(-)
+ src/hb-open-type.hh     | 17 +++++++++++++++++
+ src/hb-ot-cmap-table.hh | 18 +++++++++---------
+ 2 files changed, 26 insertions(+), 9 deletions(-)
 
-commit 925be2922348336335a96d84e606d4bdd9a11110
-Author: Garret Rieger <grieger@google.com>
-Date:   Fri Jan 25 18:04:41 2019 -0800
+commit 47333c8a304c6f57f848b5f60eea8ec85ffe2b33
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Mon Jan 7 21:38:49 2019 -0500
 
-    Update hb-ot-vorg-table and hb-ot-layout-common to use the updated subset plan api.
+    [iter] Fix operator->
 
- src/hb-ot-layout-common.hh |  4 ++--
- src/hb-ot-vorg-table.hh    | 30 +++++++++++++++++++-----------
- 2 files changed, 21 insertions(+), 13 deletions(-)
+ src/hb-iter.hh   | 3 ++-
+ src/test-iter.cc | 3 +++
+ 2 files changed, 5 insertions(+), 1 deletion(-)
 
-commit 4af3be6ef8654ae05b331941e6e690ac197fd144
-Author: Garret Rieger <grieger@google.com>
-Date:   Fri Jan 25 18:03:47 2019 -0800
+commit 177a8af380738e5be598952adbf275503bb3f5bc
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Mon Jan 7 20:20:44 2019 -0500
 
-    Remove glyph array from subset plan, make num_glyphs and glyphset private.
+    [array] SFINAE fun
 
- src/hb-subset-plan.hh | 51 +++++++++++++++++++++++++++++++++++++++++----------
- 1 file changed, 41 insertions(+), 10 deletions(-)
+ src/hb-array.hh | 2 ++
+ 1 file changed, 2 insertions(+)
 
-commit 23f364429dc9350ee06146bdf0ff73d7035e1d71
-Author: Garret Rieger <grieger@google.com>
-Date:   Fri Jan 18 18:33:21 2019 -0800
+commit 8414f167879c1af8ce5c80a15ba1aec2f7e436a6
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Mon Jan 7 19:41:52 2019 -0500
 
-    [subset] Fix hdmx subsetting when retain gids is enabled.
+    [meta] Rename
 
- src/hb-ot-hdmx-table.hh | 19 +++++++++++--------
- src/hb-subset-plan.cc   | 10 ++++++++++
- src/hb-subset-plan.hh   | 16 +++++++++++++++-
- 3 files changed, 36 insertions(+), 9 deletions(-)
+ src/hb-meta.hh | 18 +++++++++---------
+ 1 file changed, 9 insertions(+), 9 deletions(-)
 
-commit 2da1654aefbe4f8e5f1320f1c061adbf90963951
-Author: Garret Rieger <grieger@google.com>
-Date:   Fri Jan 18 17:49:35 2019 -0800
+commit 8e0a58e1b3f338098d2384f2e6e0b4ad08d6c042
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Mon Jan 7 19:03:53 2019 -0500
 
-    [subset] Compute num_glyphs during subset plan construction.
-    Update maxp to use the correct num glyphs.
+    [array] Remove construction that was removing constness
 
- src/hb-ot-maxp-table.hh |  2 +-
- src/hb-subset-glyf.cc   |  6 +-----
- src/hb-subset-plan.cc   | 16 +++++++++++++---
- src/hb-subset-plan.hh   |  1 +
- 4 files changed, 16 insertions(+), 9 deletions(-)
+ src/hb-array.hh | 2 --
+ 1 file changed, 2 deletions(-)
 
-commit ccc59dc6121e98ed8d610350b43218e540f61f25
-Author: Garret Rieger <grieger@google.com>
-Date:   Fri Jan 18 17:36:32 2019 -0800
+commit 85969e357a34691cc42c88490fc7e341175783dd
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Mon Jan 7 18:59:26 2019 -0500
 
-    [subset] Add unit test for glyf subsetting and retain gids.
+    [iter] Fix test
 
- test/api/fonts/Roboto-Regular.ac.retaingids.ttf | Bin 0 -> 2284 bytes
- test/api/test-subset-glyf.c                     |  26 ++++++++++++++++++++++++
- 2 files changed, 26 insertions(+)
+ src/test-iter.cc | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
 
-commit 96b038f375bcfcfdf76c75200ca02758ea7a4ff6
-Author: Garret Rieger <grieger@google.com>
-Date:   Fri Jan 18 16:41:08 2019 -0800
+commit da4996183693b4acecf245c58b58d6040d92a1bf
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Mon Jan 7 18:36:14 2019 -0500
 
-    [subset] fix failure to init instruction ranges values for an invalid glyph.
+    [iter] Remove comment
 
- src/hb-subset-glyf.cc | 8 ++++----
- 1 file changed, 4 insertions(+), 4 deletions(-)
+ src/hb-iter.hh | 1 -
+ 1 file changed, 1 deletion(-)
 
-commit 4b1ac3a2fa0a5842b5d45d287fe33e5050ffda3f
-Author: Garret Rieger <grieger@google.com>
-Date:   Fri Jan 18 15:11:26 2019 -0800
+commit 815cde9fa3465828030ca1ed4f32ca1df72c1f37
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Mon Jan 7 18:33:04 2019 -0500
 
-    [subset] Do some refactoring in hb-subset-glyf.cc.
-    - Extract code out into helper methods in several places.
-    - Bundle loca address, size and is short into a struct.
+    [iter] Use is_sorted_iterator
 
- src/hb-subset-glyf.cc | 264 ++++++++++++++++++++++++++++----------------------
- 1 file changed, 148 insertions(+), 116 deletions(-)
+ src/hb-aat-map.hh                          |  2 +-
+ src/hb-array.hh                            |  4 +++
+ src/hb-meta.hh                             | 23 +++++++++-------
+ src/hb-ot-layout-common.hh                 |  8 +++---
+ src/hb-ot-layout-gsub-table.hh             | 42 +++++++++++++++---------------
+ src/hb-ot-map.hh                           |  2 +-
+ src/hb-ot-shape-complex-arabic-fallback.hh |  4 +--
+ src/hb-set.hh                              |  2 +-
+ src/hb-vector.hh                           | 32 ++++++++++++++---------
+ 9 files changed, 66 insertions(+), 53 deletions(-)
 
-commit b7f971884ed838636be85de216bf60ca4a28ccb9
-Author: Garret Rieger <grieger@google.com>
-Date:   Thu Jan 17 18:55:56 2019 -0800
+commit ed4336680d3fc080f99c7dd67db48c55bcd7a020
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Mon Jan 7 17:24:23 2019 -0500
 
-    Add retain_gids option to subset input. Update glyf and loca handling to respect retain_gids.
+    [iter] Handhold hb_is_iterator() type deduction
+    
+    by partial-instantiating on Iter.
 
- src/hb-subset-glyf.cc  | 39 ++++++++++++++++++++++++++++++---------
- src/hb-subset-input.cc | 27 +++++++++++++++++++++++++++
- src/hb-subset-input.hh |  1 +
- src/hb-subset-plan.cc  | 14 ++++++++++----
- src/hb-subset.h        |  6 ++++++
- 5 files changed, 74 insertions(+), 13 deletions(-)
+ src/hb-iter.hh | 18 +++++++++++-------
+ 1 file changed, 11 insertions(+), 7 deletions(-)
 
-commit b3799007554f2909170df941b07c72f7dc02dfcd
-Merge: c6856443 fe532923
-Author: Michiharu Ariza <ariza@adobe.com>
-Date:   Tue Jan 29 12:19:57 2019 -0800
+commit cb5011d364904452a625cfc0485f5a713f472d07
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Fri Jan 4 11:22:32 2019 -0500
 
-    Merge branch 'master' into cff-more-arrayof-fixes
+    Revert "[iter] Add hb_iter_of_t<>"
+    
+    This reverts commit d6cbe96e2fc7bc8f1c10e631b52b1ef31ff9a6f5.
+    
+    Isn't useful, as duplicate inheritance of same type results in ambiguity
+    errors...
 
-commit fe532923101586e316b300d419a337d357cd93da
+ src/hb-iter.hh | 14 ++++++--------
+ 1 file changed, 6 insertions(+), 8 deletions(-)
+
+commit c132cda9d98286f002d2f5b27d1d00bf80b42a9c
 Author: Behdad Esfahbod <behdad@behdad.org>
-Date:   Mon Jan 28 20:47:58 2019 -0500
+Date:   Wed Jan 2 17:00:01 2019 -0500
 
-    [CI] Peg CircleCI badge link to master branch
+    [iter] Fix warnings
+
+ src/hb-iter.hh | 10 +++++-----
+ 1 file changed, 5 insertions(+), 5 deletions(-)
+
+commit c9d8a07e30d05b870c3d2374853adba019601b02
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Wed Jan 2 16:43:52 2019 -0500
+
+    [iter] Add hb_iter_of_t<>
+
+ src/hb-iter.hh | 14 ++++++++------
+ 1 file changed, 8 insertions(+), 6 deletions(-)
+
+commit b5d6fe1a452c72dd47d20c03a563321771330acc
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Wed Jan 2 16:20:40 2019 -0500
+
+    [iter] Remove hb_sorted_iter_t
     
-    [skip ci]
+    Not enforcing it using type hierarchy.
 
- README.md | 2 +-
+ src/hb-array.hh            |  6 ++++--
+ src/hb-iter.hh             | 26 ++++----------------------
+ src/hb-ot-layout-common.hh |  3 ++-
+ src/hb-set.hh              |  3 ++-
+ 4 files changed, 12 insertions(+), 26 deletions(-)
+
+commit 255085bd599cb108779d467690b372263f304dcb
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Wed Jan 2 16:14:00 2019 -0500
+
+    [iter] Const correctness
+
+ src/hb-open-type.hh | 2 +-
  1 file changed, 1 insertion(+), 1 deletion(-)
 
-commit 9569819e24f72926a5b26e4c8a86d815c0132745
+commit 415f3f4320c80d47e03fe9594a917fb2964b1144
 Author: Behdad Esfahbod <behdad@behdad.org>
-Date:   Mon Jan 28 20:43:43 2019 -0500
+Date:   Mon Dec 31 13:37:13 2018 -0500
 
-    [ci] Peg build status badges to master branch
+    Add operator= to IntType, commented out
     
-    [skip ci]
+    https://github.com/harfbuzz/harfbuzz/pull/1510
 
- README.md | 6 +++---
- 1 file changed, 3 insertions(+), 3 deletions(-)
+ src/hb-open-type.hh | 1 +
+ 1 file changed, 1 insertion(+)
 
-commit 1e29906a77c275c34a440a416654a514810485e1
+commit 183be8f452862aaf0cdedb28d54ec114d67745b2
 Author: Behdad Esfahbod <behdad@behdad.org>
-Date:   Mon Jan 28 20:38:15 2019 -0500
+Date:   Sun Dec 30 20:58:25 2018 -0500
 
-    Switch README / README.md
+    [iter] Minor
+
+ src/hb-iter.hh | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit 6cd96ba1aca99b6eb31f8402d02c565dd4e96e03
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Sun Dec 30 20:51:31 2018 -0500
+
+    [iter] Make is_random_access_iterator a constant
     
-    [skip ci]
+    We cannot rely on constexpr functions...
 
- README    | 19 +------------------
- README.md | 19 ++++++++++++++++++-
- 2 files changed, 19 insertions(+), 19 deletions(-)
+ src/hb-array.hh  |  2 +-
+ src/hb-iter.hh   | 11 ++++-------
+ src/test-iter.cc |  2 +-
+ 3 files changed, 6 insertions(+), 9 deletions(-)
 
-commit 9a1df82e3f13fbd4488ee9955814bbb5d0957074
+commit a685bfe8fc93ac1886a708687ea6fa7aa0b7c8c4
 Author: Behdad Esfahbod <behdad@behdad.org>
-Date:   Mon Jan 28 14:15:18 2019 -0500
+Date:   Sun Dec 30 20:24:21 2018 -0500
 
-    [uniscribe] Whitelist function type cast
+    Separate GlyphID from HBUINT16
+    
+    For stricter enforcement.
 
- src/hb-uniscribe.cc | 3 +++
- 1 file changed, 3 insertions(+)
+ src/hb-dsalgs.hh                           | 8 ++++----
+ src/hb-open-type.hh                        | 2 +-
+ src/hb-ot-layout-common.hh                 | 2 +-
+ src/hb-ot-shape-complex-arabic-fallback.hh | 8 ++++++--
+ 4 files changed, 12 insertions(+), 8 deletions(-)
 
-commit 6e1c3eaf7005d06c89f0807f693aadd835aa0468
+commit 8ac64d00907756333d5917db4b627619420f9260
 Author: Behdad Esfahbod <behdad@behdad.org>
-Date:   Mon Jan 28 14:12:41 2019 -0500
+Date:   Sun Dec 30 20:06:12 2018 -0500
 
-    Fix sign comparison error
+    [iter] Fix sorted_iter iter class
 
- src/hb-open-file.hh | 3 ++-
- 1 file changed, 2 insertions(+), 1 deletion(-)
+ src/hb-array.hh | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
 
-commit 9db7a7da6339eacbb6c699fa1939bbd7e9e148f5
+commit 93615b9598f6b5e514384327b30acfd6bd8cfcfb
 Author: Behdad Esfahbod <behdad@behdad.org>
-Date:   Mon Jan 28 14:09:59 2019 -0500
+Date:   Sun Dec 30 19:12:06 2018 -0500
 
-    Fix warning
-    
-    c:\projects\harfbuzz\src\hb-ot-color-cbdt-table.hh(59): warning C4146: unary minus operator applied to unsigned type, result still unsigned [C:\projects\harfbuzz\build\harfbuzz.vcxproj]
+    [iter/meta] Add hb_is_sorted_iterator()
 
- src/hb-ot-color-cbdt-table.hh | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
+ src/hb-iter.hh | 16 ++++++++++++----
+ 1 file changed, 12 insertions(+), 4 deletions(-)
+
+commit 92f25db1e86c7b79962a2eb735cd3596c302f71f
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Sun Dec 30 19:10:26 2018 -0500
+
+    [iter] Remove stale comment
+
+ src/hb-iter.hh | 5 +----
+ 1 file changed, 1 insertion(+), 4 deletions(-)
+
+commit 40c24fd4a623c5f570e657f22fb4e88cba48b02b
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Sun Dec 30 19:06:47 2018 -0500
+
+    [iter] Port Coverage towards iter_t instead of array_t specifics
 
-commit 51b584880e550545ced3aa8ba4ccad3cf79bb53e
+ src/hb-ot-layout-common.hh | 12 ++++++++----
+ 1 file changed, 8 insertions(+), 4 deletions(-)
+
+commit d552b6818c21efe9eae8b9cd72d5199dadd3724f
 Author: Behdad Esfahbod <behdad@behdad.org>
-Date:   Mon Jan 28 14:09:45 2019 -0500
+Date:   Sun Dec 30 18:54:07 2018 -0500
 
-    [pragma] Silence MSVC unknown-pragma warning
+    [meta] Move typename around
+    
+    We'll see if bots like.
 
- src/hb.hh | 3 +++
- 1 file changed, 3 insertions(+)
+ src/hb-atomic.hh | 2 +-
+ src/hb-blob.hh   | 2 +-
+ src/hb-iter.hh   | 2 +-
+ src/hb-meta.hh   | 6 +++---
+ src/hb-null.hh   | 6 +++---
+ 5 files changed, 9 insertions(+), 9 deletions(-)
 
-commit 60022ecced202760daa7f75516bba6a4689a49de
+commit f64ea8fc65b0dacc2ac3b1de97c92488b6e1b6fa
 Author: Behdad Esfahbod <behdad@behdad.org>
-Date:   Sat Jan 26 14:04:51 2019 +0100
+Date:   Sun Dec 30 18:49:34 2018 -0500
 
-    Fix -Wcast-function-type warnings in util/ with gcc 4.8
+    [meta] Move code around
 
- src/hb.hh       | 1 +
- util/options.hh | 5 ++++-
- 2 files changed, 5 insertions(+), 1 deletion(-)
+ src/hb-atomic.hh |  1 +
+ src/hb-meta.hh   | 10 ++++++++++
+ src/hb.hh        | 14 +-------------
+ 3 files changed, 12 insertions(+), 13 deletions(-)
 
-commit a9321cb5f88cae1dafbd623b8bf7c68a82a3c211
+commit aa2ab4f0617c50de2501722205d3d0eaaf808ff4
 Author: Behdad Esfahbod <behdad@behdad.org>
-Date:   Fri Jan 25 16:11:45 2019 +0100
+Date:   Sun Dec 30 18:47:47 2018 -0500
 
-    Fix mac test
+    [iter] WHitespace
 
test/shaping/data/in-house/tests/macos.tests | 4 ++--
- 1 file changed, 2 insertions(+), 2 deletions(-)
src/hb-iter.hh | 12 ++++--------
+ 1 file changed, 4 insertions(+), 8 deletions(-)
 
-commit f39809752909f193a9c60f4357a88ea1c3ce1162
+commit 851fbb23ea552bc639269670949a9937236d96d5
 Author: Behdad Esfahbod <behdad@behdad.org>
-Date:   Fri Jan 25 16:08:25 2019 +0100
+Date:   Sun Dec 30 18:45:50 2018 -0500
 
-    More static constexpr
+    [iter] Port Coverage::serialize to hb_is_iterator
 
- src/hb-machinery.hh  | 10 +++++-----
- src/hb-set-digest.hh | 14 +++++++-------
- 2 files changed, 12 insertions(+), 12 deletions(-)
+ src/hb-open-type.hh        |  2 +-
+ src/hb-ot-layout-common.hh | 18 ++++++++++++------
+ 2 files changed, 13 insertions(+), 7 deletions(-)
 
-commit 06358ae9746ae72c0917e8a5f294d14fd695f380
+commit 06a44e2e537303ab8ed1fb761bf3885eb433a718
 Author: Behdad Esfahbod <behdad@behdad.org>
-Date:   Fri Jan 25 15:11:47 2019 +0100
+Date:   Sun Dec 30 18:42:14 2018 -0500
 
-    [AAT] Add test for recent Ligature stack fix, using Zapfino on Mac
+    [iter/meta] Match hb_is_iterator<> using SFINAE
+    
+    By specifying Item type, which is desirable.
 
- test/shaping/data/in-house/tests/macos.tests | 2 ++
- 1 file changed, 2 insertions(+)
+ src/hb-iter.hh      | 28 +++++++++++-----------------
+ src/hb-open-type.hh |  2 +-
+ 2 files changed, 12 insertions(+), 18 deletions(-)
 
-commit c685644386d1c88d6df6e024e56d61c792d94418
-Merge: 0bd0a331 e970de48
-Author: Michiharu Ariza <ariza@adobe.com>
-Date:   Thu Jan 24 13:19:18 2019 -0800
+commit bcb913efb484e971d8a76ac1a897a1724bdad58b
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Sun Dec 30 17:54:24 2018 -0500
 
-    Merge branch 'master' into cff-more-arrayof-fixes
+    Minor
 
-commit e970de48bcbdccd29350f331288c0a98f7846c16
+ src/hb-ot-layout-common.hh | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit fa1ae3d465fd627ea99c5eb597b85cffe04c1e34
 Author: Behdad Esfahbod <behdad@behdad.org>
-Date:   Thu Jan 24 18:16:17 2019 +0100
+Date:   Sun Dec 30 12:01:13 2018 -0500
 
-    [AAT] Minor sign
+    Use C++11 when available
 
src/hb-aat-layout-morx-table.hh | 4 ++--
- 1 file changed, 2 insertions(+), 2 deletions(-)
configure.ac | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
 
-commit a371a28cda23805cbea22867e0a3ed53ecb811ed
+commit dc0f98298eca6520efd6e05d34f9aa7847979203
 Author: Behdad Esfahbod <behdad@behdad.org>
-Date:   Thu Jan 24 18:12:25 2019 +0100
+Date:   Sun Dec 30 11:22:16 2018 -0500
 
-    [AAT] Use a ring buffer for ligature stack
+    [ci] Remove unused config for gcc 4.2
     
-    I think Apple does very similarly, but probably with a stack size of 16.
-    We do it with a stack size that is currently set to 64.
-    
-    Fixes https://github.com/harfbuzz/harfbuzz/issues/1531
+    [skip ci]
 
src/hb-aat-layout-morx-table.hh | 15 ++++++---------
- 1 file changed, 6 insertions(+), 9 deletions(-)
.circleci/config.yml | 25 -------------------------
+ 1 file changed, 25 deletions(-)
 
-commit 7886b1578fceee368ae5afe206ff98f50e1c42e3
+commit eaa9023634282bed5955a068f9f92b8ef1733c39
 Author: Behdad Esfahbod <behdad@behdad.org>
-Date:   Thu Jan 24 18:06:17 2019 +0100
+Date:   Sun Dec 30 11:16:14 2018 -0500
 
-    Whitespace
+    [ci] Disable other gcc 4.2 bot
 
src/hb-aat-layout-morx-table.hh | 2 +-
.circleci/config.yml | 2 +-
  1 file changed, 1 insertion(+), 1 deletion(-)
 
-commit b976940243bf1f174bd6abb85955789ef2631d24
+commit 859a880b083c67e767162c394e08c46367078b0b
 Author: Behdad Esfahbod <behdad@behdad.org>
-Date:   Thu Jan 24 18:01:07 2019 +0100
+Date:   Sun Dec 30 02:11:03 2018 -0500
 
-    [AAT] Handle transition errors during machine operation
+    [iter] Add back operator +
     
-    Before we used to give up.  Now, just ignore error and continue processing.
+    Too ugly to remove..
+
+ src/hb-iter.hh   | 6 +++---
+ src/test-iter.cc | 4 ++--
+ 2 files changed, 5 insertions(+), 5 deletions(-)
+
+commit 076faf7c1803238f135034579935e6b8f10c774c
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Sun Dec 30 01:40:08 2018 -0500
+
+    [iter] Disable operator +
     
-    Fixes https://github.com/harfbuzz/harfbuzz/issues/1531
+    To see if it makes bots happy... This is frustrating.
 
- src/hb-aat-layout-common.hh     |  3 +--
- src/hb-aat-layout-kerx-table.hh | 21 +++++++--------------
- src/hb-aat-layout-morx-table.hh | 34 +++++++++++++---------------------
- 3 files changed, 21 insertions(+), 37 deletions(-)
+ src/hb-iter.hh   | 5 +++--
+ src/test-iter.cc | 5 +++--
+ 2 files changed, 6 insertions(+), 4 deletions(-)
 
-commit 0bd0a3311cfded5ffa4d9d488d404558cf65e8ed
-Merge: 12cd3171 f60282c5
-Author: Michiharu Ariza <ariza@adobe.com>
-Date:   Thu Jan 24 08:53:28 2019 -0800
+commit a46874f1ab4b2470784c9ef688c7a8e00592165f
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Fri Dec 28 21:23:26 2018 -0500
 
-    Merge branch 'master' into cff-more-arrayof-fixes
+    [iter] Revert back uses of C++11 auto type deduction
 
-commit e234bb6a428cd6c8ddf57eb078cd51b9d1f25ba8
+ src/hb-ot-layout-gpos-table.hh |  2 +-
+ src/hb-ot-layout-gsub-table.hh | 26 +++++++++++++-------------
+ src/hb-ot-layout-gsubgpos.hh   |  8 ++++----
+ 3 files changed, 18 insertions(+), 18 deletions(-)
+
+commit 0828db8444d4b6922469770ca1b432356512db18
 Author: Behdad Esfahbod <behdad@behdad.org>
-Date:   Thu Jan 24 17:23:11 2019 +0100
+Date:   Fri Dec 28 21:22:26 2018 -0500
 
-    [AAT] Ignore machine errors and continue
+    [iter] Rename
 
- src/hb-aat-layout-common.hh | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
+ src/hb-ot-layout-common.hh | 18 +++++++++---------
+ 1 file changed, 9 insertions(+), 9 deletions(-)
 
-commit 1ec90514f69efc329691186466f62373efa863b1
+commit 037f735efdc77ae9c8a24527da5d9805163180a6
 Author: Behdad Esfahbod <behdad@behdad.org>
-Date:   Thu Jan 24 17:21:41 2019 +0100
+Date:   Fri Dec 28 21:09:15 2018 -0500
 
-    [AAT] Minor
+    [iter] Remove friend operator +, hoping to fix some bots
 
- src/hb-aat-layout-common.hh     | 12 ++++----
- src/hb-aat-layout-kerx-table.hh | 38 +++++++++++------------
- src/hb-aat-layout-morx-table.hh | 68 ++++++++++++++++++++---------------------
- 3 files changed, 59 insertions(+), 59 deletions(-)
+ src/hb-iter.hh   | 1 -
+ src/test-iter.cc | 1 -
+ 2 files changed, 2 deletions(-)
 
-commit 299eca0c3b28c99add006420bc667431d874fb2e
+commit cb27918d0a104c5f3884013a7dc7c99f3e3e3378
 Author: Behdad Esfahbod <behdad@behdad.org>
-Date:   Thu Jan 24 17:17:00 2019 +0100
+Date:   Fri Dec 28 20:16:44 2018 -0500
 
-    [AAT] Handle out-of-bounds classes
+    Use Null() instead of declval(), hoping to fix some bots
 
- src/hb-aat-layout-common.hh | 13 ++++++-------
- 1 file changed, 6 insertions(+), 7 deletions(-)
+ src/hb-iter.hh | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
 
-commit c4623db4a3f963394db940449007fa3312460993
+commit 3d22900f6251b4386d8a7dfd7e2118dd75f12763
 Author: Behdad Esfahbod <behdad@behdad.org>
-Date:   Thu Jan 24 17:10:12 2019 +0100
+Date:   Fri Dec 28 20:01:57 2018 -0500
 
-    [AAT] Minor
+    [meta] Don't use template default arguments for functions
+    
+    That's a C++11 extension apparently...
 
- src/hb-aat-layout-common.hh | 11 ++++-------
- 1 file changed, 4 insertions(+), 7 deletions(-)
+ src/hb-meta.hh      | 2 +-
+ src/hb-open-type.hh | 8 ++++----
+ 2 files changed, 5 insertions(+), 5 deletions(-)
 
-commit c4e36f97b6df1eb5fba588b09ae1630bb5c49589
+commit b89d20dd9f7e0b4fad3f6c8803c73d2ace34c340
 Author: Behdad Esfahbod <behdad@behdad.org>
-Date:   Thu Jan 24 17:06:16 2019 +0100
+Date:   Fri Dec 28 16:41:04 2018 -0500
 
-    [AAT] Minor
+    [meta] Fix unused-function-template warning
 
- src/hb-aat-layout-common.hh | 3 ++-
- 1 file changed, 2 insertions(+), 1 deletion(-)
+ src/hb-meta.hh | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
 
-commit f60282c5bff4a317ba3180e3519274963c6e8849
+commit df138da2e67ce72bec13e656e3146b21b4600c14
 Author: Behdad Esfahbod <behdad@behdad.org>
-Date:   Thu Jan 24 16:29:09 2019 +0100
+Date:   Fri Dec 28 16:29:48 2018 -0500
 
-    More pragma control
+    [iter/meta] Implement is_iterator
     
-    Fixes https://bugs.chromium.org/p/chromium/issues/detail?id=924848
+    Removes use of auto type deduction again, which was not supported on many bots.
 
- src/hb.hh | 16 +++++++++++++++-
- 1 file changed, 15 insertions(+), 1 deletion(-)
+ src/hb-iter.hh      | 42 +++++++++++++++++++++++++++++++++++++++---
+ src/hb-meta.hh      |  4 ++--
+ src/hb-open-type.hh | 13 +++++++------
+ 3 files changed, 48 insertions(+), 11 deletions(-)
 
-commit fd0889f903ac1ba2da06e77eed8424395ea85a90
+commit 8570da1d741bbe6becbfd27d7bce3b2a6b78dae7
 Author: Behdad Esfahbod <behdad@behdad.org>
-Date:   Thu Jan 24 16:12:52 2019 +0100
+Date:   Fri Dec 28 14:40:30 2018 -0500
 
-    Comment
+    [meta] Minor
 
- src/hb-ot-shape.cc | 3 ++-
- 1 file changed, 2 insertions(+), 1 deletion(-)
+ src/hb-iter.hh | 4 ++--
+ src/hb-null.hh | 8 ++++----
+ 2 files changed, 6 insertions(+), 6 deletions(-)
 
-commit 00f06d1aa61e9a6d01b5943ce55ba2b0c40237ee
+commit 442f4a58919b8e997daf5465b948975ecbe7e3df
 Author: Behdad Esfahbod <behdad@behdad.org>
-Date:   Thu Jan 24 16:11:05 2019 +0100
+Date:   Fri Dec 28 14:34:00 2018 -0500
 
-    Fix test
+    [meta] Move more code here
 
- test/shaping/data/in-house/tests/cluster.tests | 1 -
- test/shaping/data/in-house/tests/emoji.tests   | 3 ++-
- 2 files changed, 2 insertions(+), 2 deletions(-)
+ src/hb-dsalgs.hh    | 20 --------------------
+ src/hb-meta.hh      | 31 +++++++++++++++++++++++++++++++
+ src/hb-open-type.hh |  6 +-----
+ 3 files changed, 32 insertions(+), 25 deletions(-)
 
-commit 9f314177336f9551756944e0e555614c9189c7a5
+commit 8c6cbbdfa326d6edee4a4b5f33971ad1ecfbcd2c
 Author: Behdad Esfahbod <behdad@behdad.org>
-Date:   Thu Jan 24 16:08:33 2019 +0100
+Date:   Fri Dec 28 14:29:09 2018 -0500
 
-    Form cluster for Emoji sub-region tag sequences
-    
-    Fixes https://github.com/harfbuzz/harfbuzz/issues/1556
+    [iter/meta] Add hb_is_iterable
 
- src/hb-ot-shape.cc                                       |  13 +++++++++++++
- .../fonts/8d9c4b193808b8bde94389ba7831c1fc6f9e794e.ttf   | Bin 0 -> 1548 bytes
- test/shaping/data/in-house/tests/cluster.tests           |   1 +
- 3 files changed, 14 insertions(+)
+ src/hb-iter.hh      | 26 +++++++++++++++++++++++---
+ src/hb-meta.hh      | 15 ++++++++++-----
+ src/hb-null.hh      | 17 ++++++++---------
+ src/hb-open-type.hh |  6 ++++--
+ src/hb.hh           |  2 +-
+ 5 files changed, 46 insertions(+), 20 deletions(-)
 
-commit 5034f8f2ab8f53eb0395e6f6ce2f8da69a08460d
+commit 576d5e242028b492c2a8bbe56edeaa484b8a886a
 Author: Behdad Esfahbod <behdad@behdad.org>
-Date:   Thu Jan 24 12:50:38 2019 +0100
+Date:   Thu Dec 27 18:39:39 2018 -0500
 
-    Fix macos tests with previous commit
+    Don't use delegating constructors
+    
+    Not all C++11 features are created equal when it comes to support...
 
test/shaping/data/in-house/tests/macos.tests | 8 ++++----
- 1 file changed, 4 insertions(+), 4 deletions(-)
src/hb-dsalgs.hh | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
 
-commit 3ecda71041a7239ca37ec7b888809efe8f595a19
+commit e32bf3976686c01fe9804086a8ca48aa0069b392
 Author: Behdad Esfahbod <behdad@behdad.org>
-Date:   Thu Jan 24 12:08:23 2019 +0100
+Date:   Thu Dec 27 17:38:26 2018 -0500
 
-    Adjust mark offsets when zeroing from fallback mark positioning code
-    
-    Adjust tests.
-    
-    Fixes https://github.com/harfbuzz/harfbuzz/issues/1532
+    [meta] Add enable_if
 
- src/hb-ot-shape-fallback.cc                        | 31 +++++++++++++++-------
- src/hb-ot-shape-fallback.hh                        |  3 ++-
- src/hb-ot-shape.cc                                 |  3 ++-
- .../in-house/tests/arabic-fallback-shaping.tests   |  2 +-
- test/shaping/data/in-house/tests/cluster.tests     |  2 +-
- .../data/in-house/tests/fallback-positioning.tests |  4 +--
- 6 files changed, 30 insertions(+), 15 deletions(-)
+ src/hb-meta.hh | 16 ++++++++++++++++
+ 1 file changed, 16 insertions(+)
 
-commit 12cd3171ba3b84eff9f359778fabcab8f66ce36e
-Merge: 261a7421 36fb2b4d
-Author: Michiharu Ariza <ariza@adobe.com>
-Date:   Wed Jan 23 14:05:42 2019 -0800
+commit e76a3cae0fd8cb1e716f4e55f4abbb57af49b10f
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Thu Dec 27 17:23:12 2018 -0500
 
-    Merge branch 'master' into cff-more-arrayof-fixes
+    Add hb-meta.hh for meta-programming
 
-commit 261a7421814d83f84d8def046b7108a245347461
-Author: Michiharu Ariza <ariza@adobe.com>
-Date:   Wed Jan 23 14:04:29 2019 -0800
+ src/Makefile.sources |  1 +
+ src/hb-dsalgs.hh     |  4 ----
+ src/hb-iter.hh       |  1 +
+ src/hb-meta.hh       | 40 ++++++++++++++++++++++++++++++++++++++++
+ src/hb.hh            |  3 ++-
+ 5 files changed, 44 insertions(+), 5 deletions(-)
 
-    more rewriting with ArrayOf<>
+commit 5ec11ce13a6bf4479205f3cf2a9cc96342df7f60
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Thu Dec 27 17:17:28 2018 -0500
+
+    [iter] Clarify readonly vs lvalue iterators
     
-    CFF1 Encoding0, Encoding1, CFF1SuppEncData
+    lvalue iterators must declare __item_type__ as a reference.
 
- src/hb-ot-cff1-table.hh | 51 +++++++++++++++++++++++--------------------------
- 1 file changed, 24 insertions(+), 27 deletions(-)
+ src/hb-array.hh  |  6 +++---
+ src/hb-iter.hh   | 11 ++++++-----
+ src/hb-set.hh    |  6 +++---
+ src/test-iter.cc |  6 ++++--
+ 4 files changed, 16 insertions(+), 13 deletions(-)
 
-commit 36fb2b4da9718a86978fa07c99ba4345f7ca9b4b
+commit 2cbf5bf3a959402a7f69b328469232b7050bae01
 Author: Behdad Esfahbod <behdad@behdad.org>
-Date:   Wed Jan 23 20:53:57 2019 +0100
+Date:   Thu Dec 27 16:55:18 2018 -0500
 
-    [AAT] In InsertionChain, set mark to previous-position if inserting
-    
-    Fixes MORX-31
+    [iter] Test OT::Coverage iter
 
- src/hb-aat-layout-morx-table.hh | 8 +++++---
- 1 file changed, 5 insertions(+), 3 deletions(-)
+ src/hb-dsalgs.hh           | 6 +++++-
+ src/hb-ot-layout-common.hh | 6 +++---
+ src/test-iter.cc           | 9 ++++++++-
+ 3 files changed, 16 insertions(+), 5 deletions(-)
 
-commit cbe0ed117ac86179183c389977d15981d26524f7
+commit fd75d29f0f317c4fb36b093c8fabf2a7dcd28042
 Author: Behdad Esfahbod <behdad@behdad.org>
-Date:   Wed Jan 23 20:45:18 2019 +0100
+Date:   Thu Dec 27 16:29:22 2018 -0500
 
-    [AAT] Re-enable tests MORX-31 and MORX-41
+    [iter] Streamline vector iterators
 
- test/shaping/data/text-rendering-tests/DISABLED         | 3 ---
- test/shaping/data/text-rendering-tests/Makefile.sources | 2 ++
- 2 files changed, 2 insertions(+), 3 deletions(-)
+ src/hb-vector.hh | 15 +++++++--------
+ 1 file changed, 7 insertions(+), 8 deletions(-)
 
-commit baf4d6a68a031bf65e17ccd5dac15fe7d0df33b6
+commit 570473a345a73ab05ea8e8acf88cfba9b90a81a4
 Author: Behdad Esfahbod <behdad@behdad.org>
-Date:   Wed Jan 23 20:36:07 2019 +0100
+Date:   Thu Dec 27 13:29:51 2018 -0500
 
-    [AAT] Remove mark_set from InsertionChain
+    [iter] Make hb_sorted_array_t work as iter
+    
+    Ugly, but does the job.
 
- src/hb-aat-layout-morx-table.hh | 7 +------
- 1 file changed, 1 insertion(+), 6 deletions(-)
+ src/hb-array.hh  |  6 ++++--
+ src/hb-iter.hh   | 18 ++++++++++++++++++
+ src/test-iter.cc |  2 ++
+ 3 files changed, 24 insertions(+), 2 deletions(-)
 
-commit 410731d3fb678365c07a4d1745b72b6bb3142b70
+commit d6024794fb072647d8233b184c25da5def26c435
 Author: Behdad Esfahbod <behdad@behdad.org>
-Date:   Wed Jan 23 20:30:48 2019 +0100
+Date:   Thu Dec 27 09:56:41 2018 -0500
 
-    [test/text-rendering-tests] Update from upstream
+    Change hb_void_t implementation
 
- test/shaping/data/text-rendering-tests/extract-tests.py    | 2 +-
- test/shaping/data/text-rendering-tests/tests/MORX-14.tests | 2 +-
- test/shaping/data/text-rendering-tests/tests/MORX-32.tests | 8 ++++----
- test/shaping/data/text-rendering-tests/tests/MORX-41.tests | 4 ++--
- 4 files changed, 8 insertions(+), 8 deletions(-)
+ src/hb-dsalgs.hh               |  3 +--
+ src/hb-ot-layout-gsub-table.hh |  2 +-
+ src/hb-ot-layout-gsubgpos.hh   | 12 ++++++------
+ 3 files changed, 8 insertions(+), 9 deletions(-)
 
-commit 0b2fa342de88bbe609b2147444e56c94680cbd38
+commit cde31988c26043a47e4599bf7e0d88ea67fc333f
 Author: Behdad Esfahbod <behdad@behdad.org>
-Date:   Tue Jan 22 16:36:00 2019 +0100
+Date:   Thu Dec 27 09:39:34 2018 -0500
 
-    More of previous
+    [iter] Mark Coverage iterator sorted
 
- src/hb-subset-cff1.cc | 20 ++++++++++----------
- 1 file changed, 10 insertions(+), 10 deletions(-)
+ src/hb-ot-layout-common.hh | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
 
-commit a5e5dd8b42b40c3647e06e6bb62580af77bed42b
+commit 49161d411f30d06bc920f4153f5925944895cdbc
 Author: Behdad Esfahbod <behdad@behdad.org>
-Date:   Tue Jan 22 16:30:07 2019 +0100
+Date:   Wed Dec 26 22:50:33 2018 -0500
 
-    Fix sign-compare error resulted from promoting unsigned integers to signed larger ints
+    [subset] Take iterator in ArrayOf serialize
     
-    Clang and gcc know not to warn in these cases, but not nonmainstream compilers
+    Still not satisfied with how I can enforce iterators only, but
+    seems to work for now.
 
- src/hb-subset-cff2.cc | 14 +++++++-------
- 1 file changed, 7 insertions(+), 7 deletions(-)
+ src/hb-open-type.hh | 12 +++++++-----
+ 1 file changed, 7 insertions(+), 5 deletions(-)
 
-commit 32379bbf10726bb7ed2e507d0a6b5917c350e056
+commit e16884248f80c52cd29e39a9b27b15422d76b0f1
 Author: Behdad Esfahbod <behdad@behdad.org>
-Date:   Tue Jan 22 12:55:29 2019 +0100
+Date:   Wed Dec 26 22:27:23 2018 -0500
 
-    Cast HB_UNTAG results to uint8_t
+    [iter] Port Coverage iterator to hb_iter_t
 
- src/hb-common.h | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
+ src/hb-ot-layout-common.hh     | 12 +++++++++---
+ src/hb-ot-layout-gpos-table.hh |  2 +-
+ src/hb-ot-layout-gsub-table.hh | 26 +++++++++++++-------------
+ src/hb-ot-layout-gsubgpos.hh   |  8 ++++----
+ 4 files changed, 27 insertions(+), 21 deletions(-)
 
-commit 83d4aa5ca9a39dbe66db9b81b34f5b568503bd7e
+commit c68bca0f953f5b7b7e15780f65a8e3da24917800
 Author: Behdad Esfahbod <behdad@behdad.org>
-Date:   Tue Jan 22 12:52:23 2019 +0100
+Date:   Wed Dec 26 22:21:58 2018 -0500
 
-    More -Wcast-error fix
+    Add hb_pair_t<> and hb_pair()
 
- src/hb-dsalgs.hh | +++
- 1 file changed, 3 insertions(+)
+ src/hb-dsalgs.hh | 17 +++++++++++++++++
+ 1 file changed, 17 insertions(+)
 
-commit 447323b85a7b68bd41561a87c91431cd05227b97
+commit 8303a9b011eb2ab710371b9bd7d75693c7639bc1
 Author: Behdad Esfahbod <behdad@behdad.org>
-Date:   Tue Jan 22 12:45:40 2019 +0100
+Date:   Wed Dec 26 22:08:54 2018 -0500
 
-    Better fix for -Wcast-align errors
+    [Coverage] Ensure increasing coverage in iteration
 
- src/hb-font.cc          | 33 +++++++++------------------------
- src/hb-ft.cc            | 14 ++++----------
- src/hb-machinery.hh     | 16 ++++++++++++++++
- src/hb-ot-cmap-table.hh |  7 ++-----
- src/hb-ot-font.cc       | 14 ++++----------
- 5 files changed, 35 insertions(+), 49 deletions(-)
+ src/hb-ot-layout-common.hh | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
 
-commit 81ec543d800c4a94b5e608fd87e84d33d7dae8ac
+commit 50cd26d3941156daefb1d9ba7f514049eed04b16
 Author: Behdad Esfahbod <behdad@behdad.org>
-Date:   Tue Jan 22 12:43:12 2019 +0100
+Date:   Wed Dec 26 22:05:25 2018 -0500
 
-    More -Wcast-error fixes
+    [Coverage] Mark iterator methods const
 
- src/hb-font.cc    | 8 ++++----
- src/hb-ft.cc      | 2 +-
- src/hb-ot-font.cc | 4 ++--
- 3 files changed, 7 insertions(+), 7 deletions(-)
+ src/hb-ot-layout-common.hh | 25 ++++++++++++-------------
+ 1 file changed, 12 insertions(+), 13 deletions(-)
 
-commit 90772725493108c79487a67620f0240e5d68f4ee
+commit 9df1a6eba77e8b7319fc7724e41ceaeda70c2590
 Author: Behdad Esfahbod <behdad@behdad.org>
-Date:   Tue Jan 22 12:40:18 2019 +0100
+Date:   Wed Dec 26 20:28:41 2018 -0500
 
-    pragma GCC diagnostic error   "-Wsign-compare"
+    [iter] Use operator bool in a few places
 
- src/hb.hh | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
+ src/hb-ot-layout-common.hh | 12 ++++++------
+ 1 file changed, 6 insertions(+), 6 deletions(-)
 
-commit 8d05bf7dc0094e75be07ca1f7ef852a1e45d0687
+commit 7788ac14a408e038fae9da4299fad69158c7b465
 Author: Behdad Esfahbod <behdad@behdad.org>
-Date:   Tue Jan 22 12:34:05 2019 +0100
+Date:   Wed Dec 26 20:06:10 2018 -0500
 
-    Fix cast-align error
-    
-    If compiler doesn't inline StructAtOffset, this was an error since we
-    only disable cast-align at call-site.  So, move the cast out.
-    
-    ../src/hb-machinery.hh: In instantiation of 'const Type& StructAtOffset(const void*, unsigned int) [with Type = unsigned int]':
-    ../src/hb-font.cc:146:85:   required from here
-    ../src/hb-machinery.hh:63:12: error: cast from 'const char*' to 'const unsigned int*' increases required alignment of target type [-Werror=cast-align]
-     { return * reinterpret_cast<const Type*> ((const char *) P + offset); }
-                ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-    ../src/hb-machinery.hh: In instantiation of 'Type& StructAtOffset(void*, unsigned int) [with Type = unsigned int]':
-    ../src/hb-font.cc:147:79:   required from here
-    ../src/hb-machinery.hh:66:12: error: cast from 'char*' to 'unsigned int*' increases required alignment of target type [-Werror=cast-align]
-     { return * reinterpret_cast<Type*> ((char *) P + offset); }
-                ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+    [iter] Remove redundant methods
 
- src/hb-font.cc          | 8 ++++----
- src/hb-ft.cc            | 6 +++---
- src/hb-ot-cmap-table.hh | 4 ++--
- src/hb-ot-font.cc       | 4 ++--
- 4 files changed, 11 insertions(+), 11 deletions(-)
+ src/hb-iter.hh | 44 +++++++++++++++++---------------------------
+ 1 file changed, 17 insertions(+), 27 deletions(-)
 
-commit b270cee6c5800c019aafb55e9ca9d7e92a92d3ec
+commit 3dea9affdaa063c01d67d6697df1f16c62f55c9a
 Author: Behdad Esfahbod <behdad@behdad.org>
-Date:   Tue Jan 22 12:29:05 2019 +0100
+Date:   Wed Dec 26 19:56:37 2018 -0500
 
-    [CI] Remove gcc 4.2 bots
-    
-    We don't support that version anymore.
+    [iter] Test default-constructability
 
- .circleci/config.yml | 25 -------------------------
- 1 file changed, 25 deletions(-)
+ src/test-iter.cc | 2 ++
+ 1 file changed, 2 insertions(+)
 
-commit 70a52d6bd8c45630ca90e945fc4d716fe9114010
+commit 743ff09368f223c56beeda9b72b0520766130322
 Author: Behdad Esfahbod <behdad@behdad.org>
-Date:   Tue Jan 22 12:15:23 2019 +0100
+Date:   Wed Dec 26 19:54:52 2018 -0500
 
-    Convert all other enum class consts to static constexpr
-    
-    Fixes https://github.com/harfbuzz/harfbuzz/issues/1553
+    [iter] Implement friend opeator + (int, iter)
 
- src/hb-cff-interp-common.hh |  2 +-
- src/hb-iter.hh              |  2 +-
- src/hb-machinery.hh         | 12 ++++++------
- src/hb-open-type.hh         |  8 ++++----
- src/hb-set-digest.hh        |  4 ++--
- src/hb-set.hh               | 10 +++++-----
- src/hb-vector.hh            |  2 +-
- 7 files changed, 20 insertions(+), 20 deletions(-)
+ src/hb-iter.hh   | 1 +
+ src/test-iter.cc | 1 +
+ 2 files changed, 2 insertions(+)
 
-commit 5d4b0377b99ddc4112b8ffb2b787eac0b383081c
+commit 6dc4a1c9b1f6aa38bca094d251154f9e51049d4d
 Author: Behdad Esfahbod <behdad@behdad.org>
-Date:   Tue Jan 22 12:11:24 2019 +0100
+Date:   Wed Dec 26 19:49:13 2018 -0500
 
-    Convert unsigned enum class consts to static constexpr
-    
-    Part of https://github.com/harfbuzz/harfbuzz/issues/1553
+    [iter] Remove const_iter
 
- src/hb-aat-layout-common.hh     | 6 +++---
- src/hb-aat-layout-kerx-table.hh | 2 +-
- src/hb-buffer.hh                | 2 +-
- src/hb-open-type.hh             | 2 +-
- src/hb-ot-kern-table.hh         | 4 ++--
- src/hb-ot-layout-common.hh      | 2 +-
- src/hb-ot-layout.cc             | 4 ++--
- 7 files changed, 11 insertions(+), 11 deletions(-)
+ src/hb-iter.hh   |  2 --
+ src/hb-set.hh    | 14 ++++++--------
+ src/hb-vector.hh |  6 +++---
+ 3 files changed, 9 insertions(+), 13 deletions(-)
 
-commit ef00654962204ae706b276871e2b6758fbbf69e0
+commit d12b80c05a2673c4e4bf2337e2cd4f3100e9f88b
 Author: Behdad Esfahbod <behdad@behdad.org>
-Date:   Tue Jan 22 12:08:57 2019 +0100
+Date:   Wed Dec 26 19:15:21 2018 -0500
 
-    Convert tag enum class consts to static constexpr
+    [ci] Disable macos-llvm-gcc-4.2 again
     
-    Part of https://github.com/harfbuzz/harfbuzz/issues/1553
+    Not C++11.
 
- src/hb-aat-fdsc-table.hh        |  2 +-
- src/hb-aat-layout-ankr-table.hh |  2 +-
- src/hb-aat-layout-bsln-table.hh |  2 +-
- src/hb-aat-layout-feat-table.hh |  2 +-
- src/hb-aat-layout-just-table.hh |  2 +-
- src/hb-aat-layout-kerx-table.hh |  2 +-
- src/hb-aat-layout-lcar-table.hh |  2 +-
- src/hb-aat-layout-morx-table.hh |  6 +++---
- src/hb-aat-layout-trak-table.hh |  2 +-
- src/hb-aat-ltag-table.hh        |  2 +-
- src/hb-ot-cff1-table.hh         |  2 +-
- src/hb-ot-cff2-table.hh         |  2 +-
- src/hb-ot-cmap-table.hh         |  2 +-
- src/hb-ot-color-cbdt-table.hh   |  4 ++--
- src/hb-ot-color-colr-table.hh   |  2 +-
- src/hb-ot-color-cpal-table.hh   |  2 +-
- src/hb-ot-color-sbix-table.hh   |  2 +-
- src/hb-ot-color-svg-table.hh    |  2 +-
- src/hb-ot-gasp-table.hh         |  2 +-
- src/hb-ot-glyf-table.hh         |  4 ++--
- src/hb-ot-hdmx-table.hh         |  2 +-
- src/hb-ot-head-table.hh         |  2 +-
- src/hb-ot-hhea-table.hh         |  4 ++--
- src/hb-ot-hmtx-table.hh         | 12 ++++++------
- src/hb-ot-kern-table.hh         |  6 +++---
- src/hb-ot-layout-base-table.hh  |  2 +-
- src/hb-ot-layout-gdef-table.hh  |  2 +-
- src/hb-ot-layout-gpos-table.hh  |  2 +-
- src/hb-ot-layout-gsub-table.hh  |  2 +-
- src/hb-ot-layout-jstf-table.hh  |  2 +-
- src/hb-ot-math-table.hh         |  2 +-
- src/hb-ot-maxp-table.hh         |  2 +-
- src/hb-ot-name-table.hh         |  2 +-
- src/hb-ot-os2-table.hh          |  2 +-
- src/hb-ot-post-table.hh         |  2 +-
- src/hb-ot-stat-table.hh         |  2 +-
- src/hb-ot-var-avar-table.hh     |  2 +-
- src/hb-ot-var-fvar-table.hh     |  2 +-
- src/hb-ot-var-hvar-table.hh     |  8 ++++----
- src/hb-ot-var-mvar-table.hh     |  2 +-
- src/hb-ot-vorg-table.hh         |  2 +-
- 41 files changed, 56 insertions(+), 56 deletions(-)
+ .circleci/config.yml | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
 
-commit 39e1b6d03f71ccb8f18d64dfbff64acfaf02970b
+commit f2b56af3ef721ce3961bea7d2ee8b6dba6f3fbf2
 Author: Behdad Esfahbod <behdad@behdad.org>
-Date:   Tue Jan 22 12:07:43 2019 +0100
+Date:   Wed Dec 26 19:14:39 2018 -0500
 
-    Convert boolean enum class consts to static constexpr
-    
-    Part of https://github.com/harfbuzz/harfbuzz/issues/1553
+    [iter] Remove hack for older compilers
 
- src/hb-aat-layout-common.hh     |  4 ++--
- src/hb-aat-layout-kerx-table.hh |  4 ++--
- src/hb-aat-layout-morx-table.hh |  8 ++++----
- src/hb-dsalgs.hh                | 16 ++++++++--------
- src/hb-ot-kern-table.hh         |  4 ++--
- src/hb-ot-layout.cc             |  4 ++--
- 6 files changed, 20 insertions(+), 20 deletions(-)
+ src/hb-iter.hh | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
 
-commit 271cb7c1c0f49c7af786daa5d5310b9f08142148
+commit 2ea79e0340c01d58ebeeaab9d31ffdd64250a24b
 Author: Behdad Esfahbod <behdad@behdad.org>
-Date:   Tue Jan 22 12:05:35 2019 +0100
+Date:   Wed Dec 26 19:01:46 2018 -0500
 
-    Make some enum constants unsigned
+    [iter] Minor
 
- src/hb-aat-layout-common.hh | 6 +++---
- src/hb-buffer.hh            | 2 +-
- src/hb-ot-layout.cc         | 8 ++++----
- 3 files changed, 8 insertions(+), 8 deletions(-)
+ src/test-iter.cc | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
 
-commit 3d9a6e62662fb769e0f785fa7a43df806988d2a2
+commit fb053b633351afe2012ece0874a8ac15d504a15c
 Author: Behdad Esfahbod <behdad@behdad.org>
-Date:   Tue Jan 22 12:02:06 2019 +0100
+Date:   Wed Dec 26 19:01:30 2018 -0500
 
-    Whitespace
+    [iter] Rename random_access() to constexpr is_random_access()
 
- src/hb-ot-layout-gsubgpos.hh | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
+ src/hb-iter.hh   | 4 ++--
+ src/test-iter.cc | 2 ++
+ 2 files changed, 4 insertions(+), 2 deletions(-)
 
-commit c81f02fd06fcbc4426c9e3255833f8d7057cc97a
+commit 2790aad28ce58acf0077e02921332120325edb4c
 Author: Behdad Esfahbod <behdad@behdad.org>
-Date:   Tue Jan 22 12:00:44 2019 +0100
+Date:   Wed Dec 26 18:58:42 2018 -0500
 
-    pragma GCC diagnostic error   "-Wvla"
+    [iter] Add operator ->
 
- src/hb.hh | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
+ src/hb-iter.hh | 2 ++
+ src/hb.hh      | 2 +-
+ 2 files changed, 3 insertions(+), 1 deletion(-)
 
-commit ff98109455bfbf92f7633262bc570b05d15d5d01
-Author: Alfie John <alfie@alfie.wtf>
-Date:   Tue Jan 22 19:58:36 2019 +1100
+commit d3976b7e63559b87ef34abc62acf5033f3369197
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Wed Dec 26 18:54:27 2018 -0500
 
-    Fix grammar
+    [iter] Make them work, mostly
 
- docs/usermanual-clusters.xml | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
+ src/hb-iter.hh   | 11 ++++++++---
+ src/hb-set.hh    | 18 ++++++++++--------
+ src/test-iter.cc | 25 +++++++++++++++++++++++++
+ 3 files changed, 43 insertions(+), 11 deletions(-)
 
-commit e9c0f5e714cc62bcf6349b86b13e1c031f9bb764
-Author: Alfie John <alfie@alfie.wtf>
-Date:   Tue Jan 22 00:03:02 2019 +0000
+commit 959bb58bdda8e78690789441e07cf22a99113c53
+Author: Behdad Esfahbod <behdad@behdad.org>
+Date:   Wed Dec 26 18:54:15 2018 -0500
 
-    Grammar fix
+    [vector] Add iterator
 
docs/usermanual-clusters.xml | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
src/hb-vector.hh | 10 ++++++++--
+ 1 file changed, 8 insertions(+), 2 deletions(-)
 
-commit 789396ed6bf2c76c1bb955e80efb43f75e3c61d2
+commit 6fc6a141e6d68955310d15c91f6e3d061f7221fb
 Author: Behdad Esfahbod <behdad@behdad.org>
 Date:   Sun Jan 20 20:09:10 2019 -0500
 
@@ -1965,7 +18049,7 @@ Date:   Sun Jan 20 20:09:10 2019 -0500
  .../Contents/Resources/DWARF/test-ot-extents-cff    | Bin 7650053 -> 0 bytes
  3 files changed, 20 deletions(-)
 
-commit 380c3cffb9353083913a3bb505c2c62367613096
+commit dd7c628ed122f858be9ad08c184c87ff31f2ec2d
 Author: Behdad Esfahbod <behdad@behdad.org>
 Date:   Sun Jan 20 19:51:08 2019 -0500
 
@@ -1974,7 +18058,7 @@ Date:   Sun Jan 20 19:51:08 2019 -0500
  src/hb-cff-interp-common.hh | 2 +-
  1 file changed, 1 insertion(+), 1 deletion(-)
 
-commit 6d042a18e7079e07a2b2f465a6a56483a42ef189
+commit cf7edf52c3cb38989af20b196a69bf099a1681d6
 Author: Behdad Esfahbod <behdad@behdad.org>
 Date:   Sun Jan 20 19:49:59 2019 -0500
 
@@ -1984,7 +18068,7 @@ Date:   Sun Jan 20 19:49:59 2019 -0500
  src/hb-ot-cff2-table.hh | 2 +-
  2 files changed, 2 insertions(+), 2 deletions(-)
 
-commit c1cbbb94595641f0609cc8d2dbe8415540c10f77
+commit bd1318b8ccf08d5f9241851dbb689c7dac717f0a
 Author: Behdad Esfahbod <behdad@behdad.org>
 Date:   Sun Jan 20 19:47:52 2019 -0500
 
@@ -1994,42 +18078,6 @@ Date:   Sun Jan 20 19:47:52 2019 -0500
  src/hb-set.hh | 2 +-
  2 files changed, 2 insertions(+), 2 deletions(-)
 
-commit 30ae62779f1a68c5657ab27bc7e77496ba8a906c
-Author: Khaled Hosny <khaledhosny@eglug.org>
-Date:   Mon Jan 21 16:44:48 2019 +0200
-
-    Regular spaces will do
-
- docs/usermanual-getting-started.xml | 16 ++++++++--------
- 1 file changed, 8 insertions(+), 8 deletions(-)
-
-commit ed62551d67ac5bb8dbfaf3fa5eb51013157b214a
-Author: Alfie John <alfie@alfie.wtf>
-Date:   Mon Jan 21 05:00:01 2019 +0000
-
-    Adding leading space for code example
-
- docs/usermanual-getting-started.xml | 16 ++++++++--------
- 1 file changed, 8 insertions(+), 8 deletions(-)
-
-commit 3e332544db35ca08de767ecab01b489a9905c559
-Author: Alfie John <alfie@alfie.wtf>
-Date:   Mon Jan 21 04:54:27 2019 +0000
-
-    Fix description of example
-
- docs/usermanual-getting-started.xml | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
-commit 2144ca9f01d01b6de386d17ada73a288372ee553
-Author: Alfie John <alfie@alfie.wtf>
-Date:   Mon Jan 21 04:47:05 2019 +0000
-
-    Added option to build docs to docs
-
- docs/usermanual-install-harfbuzz.xml | 12 ++++++++++++
- 1 file changed, 12 insertions(+)
-
 commit 043b610fa698ed247347dfaa042f032f3fd3f572
 Author: Behdad Esfahbod <behdad@behdad.org>
 Date:   Sat Jan 19 09:20:46 2019 -0500
@@ -2555,6 +18603,49 @@ Date:   Tue Jan 15 13:58:19 2019 -0500
  src/hb-machinery.hh | 10 +++-------
  1 file changed, 3 insertions(+), 7 deletions(-)
 
+commit f401f85a5a3ec4ab9c28012a0bfe713d7ee96951
+Author: Tor Arne Vestbø <tor.arne.vestbo@qt.io>
+Date:   Mon Dec 17 00:48:35 2018 +0100
+
+    Remove assumption about Core Text working in 96 DPI
+    
+    Core Text doesn't actually have a concept of DPI internally, as it
+    doesn't rasterize anything by itself, it just generates vector paths
+    that get passed along to Core Graphics.
+    
+    In practice this means Core Text operates in the classical macOS
+    logical DPI of 72, with one typographic point corresponding to one
+    point in the Core Graphics coordinate system, which for a normal
+    bitmap context then corresponds to one pixel -- or two pixels for
+    a "retina" context with a 2x scale transform.
+    
+    Scaling the font point sizes given to HarfBuzz to an assumed DPI
+    of 96 is problematic with this in mind, as fonts with optical
+    features such as 'trak' tables for tracking, or color glyphs,
+    will then base the metrics off of the wrong point size compared
+    to what the client asked for.
+    
+    This in turn causes mismatches between the metrics of the shaped
+    text and the actual rasterization, which doesn't include the 72
+    to 96 DPI scaling.
+    
+    If a 96 DPI is needed, such as on the Web, the scaling should be
+    done outside of HarfBuzz, allowing the client to keep the DPI of
+    the shaping in sync with the rasterization.
+    
+    The recommended way to do that is by scaling the font point size,
+    not by applying a transform to the target Core Graphics context,
+    to let Core Text choose the right optical features of the target
+    point size, as described in WWDC 2015 session 804:
+    
+      https://developer.apple.com/videos/play/wwdc2015/804/
+
+ src/hb-aat-layout-trak-table.hh                 | 11 ++---------
+ src/hb-coretext.cc                              | 25 ++++---------------------
+ test/shaping/data/in-house/tests/aat-trak.tests | 14 +++++++-------
+ test/shaping/data/in-house/tests/macos.tests    |  4 ++--
+ 4 files changed, 15 insertions(+), 39 deletions(-)
+
 commit 0d2727f4fe734af146785df10a44e3505e410ba1
 Author: Behdad Esfahbod <behdad@behdad.org>
 Date:   Mon Jan 14 18:23:17 2019 -0800
@@ -21462,6 +37553,15 @@ Date:   Thu Sep 27 16:54:23 2018 -0400
  src/hb-cache.hh | 5 ++++-
  1 file changed, 4 insertions(+), 1 deletion(-)
 
+commit 341b70a3b47ef3ceeb81e715937d6b2305258060
+Merge: bbf2a095 9e9a36ee
+Author: n8willis <n8willis@users.noreply.github.com>
+Date:   Thu Sep 27 11:15:22 2018 -0500
+
+    Merge pull request #1 from harfbuzz/master
+    
+    Resync with upstream
+
 commit 9e9a36ee651502b69717895385387951a2d0802a
 Author: Volker Krause <vkrause@kde.org>
 Date:   Thu Sep 27 16:33:49 2018 +0200
@@ -28073,6 +44173,15 @@ Date:   Fri Jun 22 15:29:34 2018 -0700
  ...testcase-minimized-hb-subset-fuzzer-5750092395970560 | Bin 0 -> 72435 bytes
  1 file changed, 0 insertions(+), 0 deletions(-)
 
+commit bbf2a09549a88bd52ac3db89a0ae93f3b71b3e37
+Merge: 8db058d2 35ce8f31
+Author: Nathan Willis <nwillis@glyphography.com>
+Date:   Mon Jun 25 13:02:11 2018 -0500
+
+    Merge branch 'master' of http://github.com/behdad/harfbuzz
+    
+    Catching up.
+
 commit 35ce8f31d37cf7c2a1f8265d36ba4c2c9a3efb2c
 Author: Ebrahim Byagowi <ebrahim@gnu.org>
 Date:   Mon Jun 25 22:23:43 2018 +0430
@@ -40295,6 +56404,15 @@ Date:   Tue Dec 5 17:43:09 2017 +0000
  src/hb-ot-shape-complex-indic.cc | 16 ++++++++--------
  1 file changed, 8 insertions(+), 8 deletions(-)
 
+commit 8db058d20c1b7efce33157c676d4aee97591deb1
+Author: Nathan Willis <nwillis@glyphography.com>
+Date:   Tue Dec 5 17:43:09 2017 +0000
+
+    Indic: always hyphenate pre-base-reordering, for clarity.
+
+ src/hb-ot-shape-complex-indic.cc | 16 ++++++++--------
+ 1 file changed, 8 insertions(+), 8 deletions(-)
+
 commit be59f3cbf4e3269ea05d5a707cdae04a32e097ce
 Author: Behdad Esfahbod <behdad@behdad.org>
 Date:   Tue Dec 5 09:01:28 2017 -0800
index f9f6e36..2bbd3c5 100644 (file)
@@ -9,12 +9,19 @@ SUBDIRS = src util test docs
 EXTRA_DIST = \
        autogen.sh \
        harfbuzz.doap \
+       README.md \
+       README.mingw.md \
        README.python.md \
-       README.wine.md \
        BUILD.md \
+       CONFIG.md \
        RELEASING.md \
+       TESTING.md \
        CMakeLists.txt \
        replace-enum-strings.cmake \
+       mingw-configure.sh \
+       mingw-ldd.py \
+       mingw32.sh \
+       mingw64.sh \
        $(NULL)
 
 MAINTAINERCLEANFILES = \
@@ -60,8 +67,6 @@ DISTCHECK_CONFIGURE_FLAGS = \
        --enable-introspection \
        $(NULL)
 
-# TODO: Copy infrastructure from cairo
-
 # TAR_OPTIONS is not set as env var for 'make dist'.  How to fix that?
 TAR_OPTIONS = --owner=0 --group=0
 
@@ -70,8 +75,7 @@ dist-hook: dist-clear-sticky-bits
 dist-clear-sticky-bits:
        chmod -R a-s $(distdir)
 
-
-tar_file = $(PACKAGE_TARNAME)-$(VERSION).tar.bz2
+tar_file = $(PACKAGE_TARNAME)-$(VERSION).tar.xz
 sha256_file = $(tar_file).sha256
 gpg_file = $(sha256_file).asc
 $(sha256_file): $(tar_file)
@@ -82,5 +86,18 @@ $(gpg_file): $(sha256_file)
 
 release-files: $(tar_file) $(sha256_file) $(gpg_file)
 
+dist-win:
+       @case $(host_triplet) in *-w64-mingw32) ;; *) echo "Error: Requires mingw build. See README.mingw.md.">&2; exit 1 ;; esac
+       @DIR=$(PACKAGE_TARNAME)-$(VERSION)-win`case $(host_triplet) in i686-*) echo 32 ;; x86_64-*) echo 64 ;; esac`; \
+       $(RM) -r $$DIR; $(MKDIR_P) $$DIR || exit 1; \
+       cp util/.libs/hb-{shape,view,subset}.exe $$DIR && \
+       $(top_srcdir)/mingw-ldd.py $$DIR/hb-view.exe | grep -v 'not found' | cut -d '>' -f 2 | xargs cp -t $$DIR && \
+       cp src/.libs/libharfbuzz{,-subset}-0.dll $$DIR && \
+       chmod a+x $$DIR/*.{exe,dll} && \
+       $(STRIP) $$DIR/*.{exe,dll} && \
+       zip -r $$DIR.zip $$DIR && \
+       $(RM) -r $$DIR && \
+       echo "$$DIR.zip is ready."
+
 
 -include $(top_srcdir)/git.mk
index 9f62cb8..27d3a99 100644 (file)
@@ -93,6 +93,7 @@ subdir = .
 ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
 am__aclocal_m4_deps = $(top_srcdir)/m4/ax_check_link_flag.m4 \
        $(top_srcdir)/m4/ax_code_coverage.m4 \
+       $(top_srcdir)/m4/ax_cxx_compile_stdcxx.m4 \
        $(top_srcdir)/m4/ax_pthread.m4 $(top_srcdir)/m4/gtk-doc.m4 \
        $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \
        $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \
@@ -166,7 +167,8 @@ CSCOPE = cscope
 DIST_SUBDIRS = $(SUBDIRS)
 am__DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/config.h.in AUTHORS \
        COPYING ChangeLog INSTALL NEWS README THANKS TODO ar-lib \
-       compile config.guess config.sub install-sh ltmain.sh missing
+       compile config.guess config.sub depcomp install-sh ltmain.sh \
+       missing
 DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
 distdir = $(PACKAGE)-$(VERSION)
 top_distdir = $(distdir)
@@ -203,8 +205,8 @@ am__relativize = \
   done; \
   reldir="$$dir2"
 GZIP_ENV = --best
-DIST_ARCHIVES = $(distdir).tar.bz2
-DIST_TARGETS = dist-bzip2
+DIST_ARCHIVES = $(distdir).tar.xz
+DIST_TARGETS = dist-xz
 distuninstallcheck_listfiles = find . -type f -print
 am__distuninstallcheck_listfiles = $(distuninstallcheck_listfiles) \
   | sed 's|^\./|$(prefix)/|' | grep -v '$(infodir)/dir$$'
@@ -258,6 +260,8 @@ FREETYPE_CFLAGS = @FREETYPE_CFLAGS@
 FREETYPE_DEPS = @FREETYPE_DEPS@
 FREETYPE_LIBS = @FREETYPE_LIBS@
 GCOV = @GCOV@
+GDI_CFLAGS = @GDI_CFLAGS@
+GDI_LIBS = @GDI_LIBS@
 GENHTML = @GENHTML@
 GIT = @GIT@
 GLIB_CFLAGS = @GLIB_CFLAGS@
@@ -276,6 +280,7 @@ GTKDOC_DEPS_CFLAGS = @GTKDOC_DEPS_CFLAGS@
 GTKDOC_DEPS_LIBS = @GTKDOC_DEPS_LIBS@
 GTKDOC_MKPDF = @GTKDOC_MKPDF@
 GTKDOC_REBASE = @GTKDOC_REBASE@
+HAVE_CXX11 = @HAVE_CXX11@
 HB_LIBTOOL_VERSION_INFO = @HB_LIBTOOL_VERSION_INFO@
 HB_VERSION = @HB_VERSION@
 HB_VERSION_MAJOR = @HB_VERSION_MAJOR@
@@ -401,12 +406,19 @@ SUBDIRS = src util test docs
 EXTRA_DIST = \
        autogen.sh \
        harfbuzz.doap \
+       README.md \
+       README.mingw.md \
        README.python.md \
-       README.wine.md \
        BUILD.md \
+       CONFIG.md \
        RELEASING.md \
+       TESTING.md \
        CMakeLists.txt \
        replace-enum-strings.cmake \
+       mingw-configure.sh \
+       mingw-ldd.py \
+       mingw32.sh \
+       mingw64.sh \
        $(NULL)
 
 MAINTAINERCLEANFILES = \
@@ -436,11 +448,9 @@ DISTCHECK_CONFIGURE_FLAGS = \
        $(NULL)
 
 
-# TODO: Copy infrastructure from cairo
-
 # TAR_OPTIONS is not set as env var for 'make dist'.  How to fix that?
 TAR_OPTIONS = --owner=0 --group=0
-tar_file = $(PACKAGE_TARNAME)-$(VERSION).tar.bz2
+tar_file = $(PACKAGE_TARNAME)-$(VERSION).tar.xz
 sha256_file = $(tar_file).sha256
 gpg_file = $(sha256_file).asc
 all: config.h
@@ -690,6 +700,7 @@ distdir-am: $(DISTFILES)
 dist-gzip: distdir
        tardir=$(distdir) && $(am__tar) | eval GZIP= gzip $(GZIP_ENV) -c >$(distdir).tar.gz
        $(am__post_remove_distdir)
+
 dist-bzip2: distdir
        tardir=$(distdir) && $(am__tar) | BZIP2=$${BZIP2--9} bzip2 -c >$(distdir).tar.bz2
        $(am__post_remove_distdir)
@@ -697,7 +708,6 @@ dist-bzip2: distdir
 dist-lzip: distdir
        tardir=$(distdir) && $(am__tar) | lzip -c $${LZIP_OPT--9} >$(distdir).tar.lz
        $(am__post_remove_distdir)
-
 dist-xz: distdir
        tardir=$(distdir) && $(am__tar) | XZ_OPT=$${XZ_OPT--e} xz -c >$(distdir).tar.xz
        $(am__post_remove_distdir)
@@ -965,6 +975,19 @@ $(gpg_file): $(sha256_file)
 
 release-files: $(tar_file) $(sha256_file) $(gpg_file)
 
+dist-win:
+       @case $(host_triplet) in *-w64-mingw32) ;; *) echo "Error: Requires mingw build. See README.mingw.md.">&2; exit 1 ;; esac
+       @DIR=$(PACKAGE_TARNAME)-$(VERSION)-win`case $(host_triplet) in i686-*) echo 32 ;; x86_64-*) echo 64 ;; esac`; \
+       $(RM) -r $$DIR; $(MKDIR_P) $$DIR || exit 1; \
+       cp util/.libs/hb-{shape,view,subset}.exe $$DIR && \
+       $(top_srcdir)/mingw-ldd.py $$DIR/hb-view.exe | grep -v 'not found' | cut -d '>' -f 2 | xargs cp -t $$DIR && \
+       cp src/.libs/libharfbuzz{,-subset}-0.dll $$DIR && \
+       chmod a+x $$DIR/*.{exe,dll} && \
+       $(STRIP) $$DIR/*.{exe,dll} && \
+       zip -r $$DIR.zip $$DIR && \
+       $(RM) -r $$DIR && \
+       echo "$$DIR.zip is ready."
+
 -include $(top_srcdir)/git.mk
 
 # Tell versions [3.59,3.63) of GNU make to not export all variables.
diff --git a/NEWS b/NEWS
index f3e424f..7dde119 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -1,3 +1,102 @@
+Overview of changes leading to 2.6.4
+Monday, October 29, 2019
+====================================
+- Small bug fix.
+- Build fixes.
+
+
+Overview of changes leading to 2.6.3
+Monday, October 28, 2019
+====================================
+- Misc small fixes, mostly to build-related issues.
+- New API:
++hb_font_get_nominal_glyphs()
+
+
+Overview of changes leading to 2.6.2
+Monday, September 30, 2019
+====================================
+- Misc small fixes, mostly to build-related issues.
+
+
+Overview of changes leading to 2.6.1
+Thursday, August 22, 2019
+====================================
+- Fix regression with hb_font_create_sub_font scaling introduced in 2.6.0.
+- Change interpretation of font PTEM size / CoreText font size handling.
+  See https://github.com/harfbuzz/harfbuzz/pull/1484
+- hb-ot-font: Prefer symbol cmap subtable if present.
+- Apply 'dist'/'abvm'/'blwm' features to all scripts.
+- Drop experimental DirectWrite API.
+
+
+Overview of changes leading to 2.6.0
+Tuesday, August 13, 2019
+====================================
+- New OpenType metrics, baseline, and metadata table access APIs.
+- New API to set font variations to a named-instance.
+- New hb-gdi.h header and API for creating hb_face_t from HFONT.
+- Amalgam: Provide a single-file harfbuzz.cc file for easier alternate building.
+- More size-reduction configurable options, enabled by HB_TINY.
+- New API:
++hb_font_set_var_named_instance()
++hb_gdi_face_create()
++hb_ot_layout_baseline_tag_t
++hb_ot_layout_get_baseline()
++hb_ot_meta_tag_t
++hb_ot_meta_get_entry_tags()
++hb_ot_meta_reference_entry()
++hb_ot_metrics_tag_t
++hb_ot_metrics_get_position()
++hb_ot_metrics_get_variation()
++hb_ot_metrics_get_x_variation()
++hb_ot_metrics_get_y_variation()
+
+
+Overview of changes leading to 2.5.3
+Wednesday, June 26, 2019
+====================================
+- Fix UCD script data for Unicode 10+ scripts.  This was broken since 2.5.0.
+- More optimizations for HB_TINY.
+
+
+Overview of changes leading to 2.5.2
+Thursday, June 20, 2019
+====================================
+- More hb-config.hh facilities to shrink library size, namely when built as
+  HB_TINY.
+- New documentation of custom configurations in CONFIG.md.
+- Fix build on gcc 4.8.  That's supported again.
+- Universal Shaping Engine improvements thanks to David Corbett.
+- API Changes: Undeprecate some horizontal-kerning API and re-enable in hb-ft,
+  such that Type1 fonts will continue kerning.
+
+
+Overview of changes leading to 2.5.1
+Friday, May 31, 2019
+====================================
+- Fix build with various versions of Visual Studio.
+- Improved documentation, thanks to Nathan Willis.
+- Bugfix in subsetting glyf table.
+- Improved scripts for cross-compiling for Windows using mingw.
+- Rename HB_MATH_GLYPH_PART_FLAG_EXTENDER to HB_OT_MATH_GLYPH_PART_FLAG_EXTENDER.
+  A deprecated macro is added for backwards-compatibility.
+
+
+Overview of changes leading to 2.5.0
+Friday, May 24, 2019
+====================================
+- This release does not include much functional changes, but includes major internal
+  code-base changes.  We now require C++11.  Support for gcc 4.8 and earlier has been
+  dropped.
+- New hb-config.hh facility for compiling smaller library for embedded and web usecases.
+- New Unicode Character Databse implementation that is half the size of previously-used
+  UCDN.
+- Subsetter improvements.
+- Improved documentation, thanks to Nathan Willis.
+- Misc shaping fixes.
+
+
 Overview of changes leading to 2.4.0
 Monday, March 25, 2019
 ====================================
diff --git a/README b/README
index fd93be8..e0ef935 100644 (file)
--- a/README
+++ b/README
@@ -1,10 +1,12 @@
 [![Travis Build Status](https://travis-ci.org/harfbuzz/harfbuzz.svg?branch=master)](https://travis-ci.org/harfbuzz/harfbuzz)
 [![AppVeyor Build Status](https://ci.appveyor.com/api/projects/status/0t0flrxpstj9lb9w?svg=true&branch=master)](https://ci.appveyor.com/project/harfbuzz/harfbuzz)
 [![CircleCI Build Status](https://circleci.com/gh/harfbuzz/harfbuzz/tree/master.svg?style=svg)](https://circleci.com/gh/harfbuzz/harfbuzz/tree/master)
+[![OSS-Fuzz Status](https://oss-fuzz-build-logs.storage.googleapis.com/badges/harfbuzz.svg)](https://oss-fuzz-build-logs.storage.googleapis.com/index.html)
 [![Coverity Code Health](https://img.shields.io/coverity/scan/5450.svg)](https://scan.coverity.com/projects/behdad-harfbuzz)
 [![Codacy Code Health](https://api.codacy.com/project/badge/Grade/f17f1708783c447488bc8dd317150eaa)](https://app.codacy.com/app/behdad/harfbuzz)
 [![Codecov Code Coverage](https://codecov.io/gh/harfbuzz/harfbuzz/branch/master/graph/badge.svg)](https://codecov.io/gh/harfbuzz/harfbuzz)
 [![Coverals Code Coverage](https://img.shields.io/coveralls/harfbuzz/harfbuzz.svg)](https://coveralls.io/r/harfbuzz/harfbuzz)
+[![Packaging status](https://repology.org/badge/tiny-repos/harfbuzz.svg)](https://repology.org/project/harfbuzz/versions)
 [ABI Tracker](http://abi-laboratory.pro/tracker/timeline/harfbuzz/)
 
 This is HarfBuzz, a text shaping library.
@@ -13,6 +15,20 @@ For bug reports, mailing list, and other information please visit:
 
   http://harfbuzz.org/
 
-For license information, see the file COPYING.
+For license information, see [COPYING](COPYING).
+
+For build information, see [BUILD.md](BUILD.md).
+
+For custom configurations, see [CONFIG.md](CONFIG.md).
+
+For test execution, see [TESTING.md](TESTING.md).
 
 Documentation: https://harfbuzz.github.io
+
+
+<details>
+  <summary>Packaging status of HarfBuzz</summary
+
+[![Packaging status](https://repology.org/badge/vertical-allrepos/harfbuzz.svg?header=harfbuzz)](https://repology.org/project/harfbuzz/versions)  
+
+</details>
diff --git a/README.md b/README.md
new file mode 100644 (file)
index 0000000..e0ef935
--- /dev/null
+++ b/README.md
@@ -0,0 +1,34 @@
+[![Travis Build Status](https://travis-ci.org/harfbuzz/harfbuzz.svg?branch=master)](https://travis-ci.org/harfbuzz/harfbuzz)
+[![AppVeyor Build Status](https://ci.appveyor.com/api/projects/status/0t0flrxpstj9lb9w?svg=true&branch=master)](https://ci.appveyor.com/project/harfbuzz/harfbuzz)
+[![CircleCI Build Status](https://circleci.com/gh/harfbuzz/harfbuzz/tree/master.svg?style=svg)](https://circleci.com/gh/harfbuzz/harfbuzz/tree/master)
+[![OSS-Fuzz Status](https://oss-fuzz-build-logs.storage.googleapis.com/badges/harfbuzz.svg)](https://oss-fuzz-build-logs.storage.googleapis.com/index.html)
+[![Coverity Code Health](https://img.shields.io/coverity/scan/5450.svg)](https://scan.coverity.com/projects/behdad-harfbuzz)
+[![Codacy Code Health](https://api.codacy.com/project/badge/Grade/f17f1708783c447488bc8dd317150eaa)](https://app.codacy.com/app/behdad/harfbuzz)
+[![Codecov Code Coverage](https://codecov.io/gh/harfbuzz/harfbuzz/branch/master/graph/badge.svg)](https://codecov.io/gh/harfbuzz/harfbuzz)
+[![Coverals Code Coverage](https://img.shields.io/coveralls/harfbuzz/harfbuzz.svg)](https://coveralls.io/r/harfbuzz/harfbuzz)
+[![Packaging status](https://repology.org/badge/tiny-repos/harfbuzz.svg)](https://repology.org/project/harfbuzz/versions)
+[ABI Tracker](http://abi-laboratory.pro/tracker/timeline/harfbuzz/)
+
+This is HarfBuzz, a text shaping library.
+
+For bug reports, mailing list, and other information please visit:
+
+  http://harfbuzz.org/
+
+For license information, see [COPYING](COPYING).
+
+For build information, see [BUILD.md](BUILD.md).
+
+For custom configurations, see [CONFIG.md](CONFIG.md).
+
+For test execution, see [TESTING.md](TESTING.md).
+
+Documentation: https://harfbuzz.github.io
+
+
+<details>
+  <summary>Packaging status of HarfBuzz</summary
+
+[![Packaging status](https://repology.org/badge/vertical-allrepos/harfbuzz.svg?header=harfbuzz)](https://repology.org/project/harfbuzz/versions)  
+
+</details>
diff --git a/README.mingw.md b/README.mingw.md
new file mode 100644 (file)
index 0000000..76d1a87
--- /dev/null
@@ -0,0 +1,48 @@
+For the development of HarfBuzz, the Microsoft shaping technology, Uniscribe,
+as a widely used and tested shaper is used as more-or-less OpenType reference
+implementation and that specially is important where OpenType specification
+is or wasn't that clear. For having access to Uniscribe on Linux/macOS these
+steps are recommended:
+
+1. Install Wine from your favorite package manager.  On Fedora that's `dnf install wine`.
+
+2. And `mingw-w64` compiler.
+   With `brew` on macOS, you can have it like `brew install mingw-w64`.
+   On Fedora, with `dnf install mingw32-gcc-c++`, or `dnf install mingw64-gcc-c++` for the
+   64-bit Windows.
+
+3. Install cross-compiled dependency packages.  Alternatively see [^1] below.
+   On Fedora that would be `dnf install mingw32-glib2 mingw32-cairo mingw32-freetype`
+   for 32-bit, or `dnf install mingw64-glib2 mingw64-cairo mingw64-freetype` for 64-bit.
+
+5. `NOCONFIGURE=1 ./autogen.sh && mkdir winbuild && cd winbuild`
+
+6. Run `../mingw32.sh` for 32-bit build, or `../mingw64.sh` for 64-bit.  This configures
+   HarfBuzz for cross-compiling.  It enables Uniscribe backend as well.
+
+7. `make`
+
+Now you can use hb-shape using `wine util/hb-shape.exe` but if you like to shape with
+the Microsoft Uniscribe,
+
+8. Bring a 32bit version of `usp10.dll` for yourself from `C:\Windows\SysWOW64\usp10.dll` of your
+   Windows installation (assuming you have a 64-bit installation, otherwise
+   `C:\Windows\System32\usp10.dll`) that it is not a DirectWrite proxy
+   ([for more info](https://en.wikipedia.org/wiki/Uniscribe)).
+   Rule of thumb, your `usp10.dll` should have a size more than 500kb, otherwise
+   it is designed to work with DirectWrite which Wine can't work with its original one.
+   You want a Uniscribe from Windows 7 or older.
+
+   Put the DLL in the folder you are going to run the next command,
+
+9. `WINEDLLOVERRIDES="usp10=n" wine util/hb-shape.exe fontname.ttf -u 0061,0062,0063 --shaper=uniscribe`
+
+(`0061,0062,0063` means `abc`, use test/shaping/hb-unicode-decode to generate ones you need)
+
+
+[^1] Download and put [this](https://drive.google.com/open?id=0B3_fQkxDZZXXbWltRGd5bjVrUDQ)
+     in your `~/.local/i686-w64-mingw32`.  Then replace all the instances of
+     `/home/behdad/.local/i586-mingw32msvc` and `/home/behdad/.local/i686-w64-mingw32`
+     with `<$HOME>/.local/i686-w64-mingw32` on that folder.
+     (`<$HOME>` replace it with `/home/XXX` or `/Users/XXX` on macOS)
+     You shouldn't replace the instances of those inside binary files.
index 7cf091a..d9aaf89 100644 (file)
@@ -6,21 +6,21 @@ you can install that this way:
 sudo apt-get install libgirepository1.0-dev
 ```
 
-And then run autogen.sh (if building from git), and then:
+And then run `autogen.sh` (if building from git), and then:
 
 ```bash
 ./configure --with-gobject --enable-introspection
 ```
 
-Make sure that gobject-introspection is enabled then in the final report.
+Make sure that gobject-introspection is reported enabled then in the `configure` script output.
 
 Compile and install.
 
-Make sure you have the installation lib dir in LD_LIBRARY_PATH, as needed
+Make sure you have the installation lib dir in `LD_LIBRARY_PATH`, as needed
 for the linker to find the library.
 
-Then make sure you also have GI_TYPELIB_PATH pointing to the resulting
-$prefix/lib/girepository-* directory.
+Then make sure you also have `GI_TYPELIB_PATH` pointing to the resulting
+`$prefix/lib/girepository-*` directory.
 
 Make sure you have pygobject installed.  Then check that the following
 import works in your Python interpreter:
@@ -30,7 +30,7 @@ from gi.repository import HarfBuzz
 ```
 
 If it does, you are ready to call HarfBuzz from Python!  Congratulations.
-See src/sample.py.
+See [`src/sample.py`](src/sample.py).
 
 The Python API will change.  Let us know on the mailing list if you are
 using it, and send lots of feedback.
diff --git a/README.wine.md b/README.wine.md
deleted file mode 100644 (file)
index 799eb63..0000000
+++ /dev/null
@@ -1,40 +0,0 @@
-For the development of HarfBuzz, the Microsoft shaping technology, Uniscribe,
-as a widely used and tested shaper is used as more-or-less OpenType reference
-implementation and that specially is important where OpenType specification
-is or wasn't that clear. For having access to Uniscribe on Linux/macOS these
-steps are recommended:
-
-1. Install Wine from your favorite package manager.
-
-2. And `mingw-w64` compiler.
-   With `brew` on macOS, you can have it like `brew install mingw-w64`
-
-3. Download and put [this](https://drive.google.com/open?id=0B3_fQkxDZZXXbWltRGd5bjVrUDQ)
-   on your `~/.local/i686-w64-mingw32`.
-
-4. Replace all the instances of `/home/behdad/.local/i586-mingw32msvc`
-   and `/home/behdad/.local/i686-w64-mingw32` with `<$HOME>/.local/i686-w64-mingw32`
-   on that folder. (`<$HOME>` replace it with `/home/XXX` or `/Users/XXX` on macOS)
-
-   Probably you shouldn't replace the ones are inside binaries.
-
-5. `NOCONFIGURE=1 ./autogen.sh && mkdir winbuild && cd winbuild`
-
-6. `../mingw32.sh --with-uniscribe && cd ..`
-
-7. `make -Cwinbuild`
-
-Now you can use hb-shape using `wine winbuild/util/hb-shape.exe` but if you like to
-to use the original Uniscribe,
-
-8. Bring a 32bit version of `usp10.dll` for yourself from `C:\Windows\SysWOW64\usp10.dll` of your
-   Windows installation (assuming you have a 64-bit installation, otherwise `C:\Windows\System32\usp10.dll`)
-   that it is not a DirectWrite proxy ([for more info](https://en.wikipedia.org/wiki/Uniscribe)).
-   Rule of thumb, your `usp10.dll` should have a size more than 500kb, otherwise
-   it is designed to work with DirectWrite which Wine can't work with its original one.
-
-   Put the dll on the folder you are going to run the next command,
-
-9. `WINEDLLOVERRIDES="usp10=n" wine winbuild/util/hb-shape.exe fontname.ttf -u 0061,0062,0063 --shaper=uniscribe`
-
-(`0061,0062,0063` means `abc`, use test/shaping/hb-unicode-decode to generate ones you need)
index 1fd8365..360aea7 100644 (file)
@@ -33,39 +33,34 @@ HarfBuzz release walk-through checklist:
    That's what happened to 2.0.0 going out with 1.8.0 hb-version.h...  So, that's
    a clue.
 
-7. "make release-files".  Enter your GPG password.  This creates a sha256 hash
-   and signs it.
-
-8. Now that you have release files, commit NEWS, configure.ac, and src/hb-version.h,
+7. Now that you have release files, commit NEWS, configure.ac, and src/hb-version.h,
    as well as any REPLACEME changes you made.  The commit message is simply the
    release number.  Eg. "1.4.7"
 
+8. "make dist" again to get a tarball with your new commit in the ChangeLog.  Then
+   "make release-files".  Enter your GPG password.  This creates a sha256 hash
+   and signs it.  Check the size of the three resulting files.
+
 9. Tag the release and sign it: Eg. "git tag -s 1.4.7 -m 1.4.7".  Enter your
    GPG password again.
 
 10. Build win32 bundle.
 
-   a. Put contents of [this](https://drive.google.com/open?id=0B3_fQkxDZZXXbWltRGd5bjVrUDQ) on your `~/.local/i686-w64-mingw32`,
-
-   b. Run `../mingw32.sh --with-uniscribe` script to configure harfbuzz with mingw
-   in a subdirector (eg. winbuild/),
-
-   c. make
+   a. Build Win32 binaries.  See [README.mingw.md](README.mingw.md).
 
-   d. Back in the parent directory, run `./UPDATE.sh`(available below) to build win32
-      bundle.
+   b. Run "make dist-win" to build Win32 bundle.
 
 11. Copy all artefacts to users.freedesktop.org and move them into
     `/srv/www.freedesktop.org/www/software/harfbuzz/release` There should be four
     files.  Eg.:
  ```
--rw-r--r--  1 behdad eng 1592693 Jul 18 11:25 harfbuzz-1.4.7.tar.bz2
--rw-r--r--  1 behdad eng      89 Jul 18 11:34 harfbuzz-1.4.7.tar.bz2.sha256
--rw-r--r--  1 behdad eng     339 Jul 18 11:34 harfbuzz-1.4.7.tar.bz2.sha256.asc
+-rw-r--r--  1 behdad eng 1592693 Jul 18 11:25 harfbuzz-1.4.7.tar.xz
+-rw-r--r--  1 behdad eng      89 Jul 18 11:34 harfbuzz-1.4.7.tar.xz.sha256
+-rw-r--r--  1 behdad eng     339 Jul 18 11:34 harfbuzz-1.4.7.tar.xz.sha256.asc
 -rw-r--r--  1 behdad eng 2895619 Jul 18 11:34 harfbuzz-1.4.7-win32.zip
 ```
 
-12. While doing that, quickly double-check the size of the .tar.bz2 and .zip
+12. While doing that, quickly double-check the size of the .tar.xz and .zip
     files against their previous releases to make sure nothing bad happened.
     They should be in the ballpark, perhaps slightly larger.  Sometimes they
     do shrink, that's not by itself a stopper.
@@ -75,39 +70,3 @@ HarfBuzz release walk-through checklist:
 
 14. Go to GitHub release page [here](https://github.com/harfbuzz/harfbuzz/releases),
     edit the tag, upload artefacts and NEWS entry and save.
-
-
-## UPDATE.sh
-```bash
-#!/bin/bash
-
-v=$1
-
-if test "x$v" = x; then
-       echo "usage: UPDATE.sh micro-version"
-       exit 1
-fi
-
-dir_prefix=harfbuzz-1.4.
-dir_suffix=-win32
-dir=$dir_prefix$v$dir_suffix
-dir_old=$dir_prefix$((v-1))$dir_suffix
-if test -d "$dir"; then
-       echo "New dir $dir exists; not overwriting"
-       exit 1
-fi
-if ! test -d "$dir_old"; then
-       echo "Old dir $dir_old does NOT exist; aborting"
-       exit 1
-fi
-set -ex
-cp -a "$dir_old" "$dir.tmp"
-rm -f "$dir.tmp"/GDX32.dll
-rm -f "$dir.tmp"/usp10.dll
-cp ../winbuild/src/.libs/libharfbuzz-0.dll{,.def} $dir.tmp/
-cp ../winbuild/util/.libs/hb-{shape,view}.exe $dir.tmp/
-i686-w64-mingw32-strip $dir.tmp/{hb-shape.exe,hb-view.exe,libharfbuzz-0.dll}
-mv $dir.tmp $dir
-zip -r $dir.zip $dir
-echo Bundle $dir.zip ready
-```
diff --git a/TESTING.md b/TESTING.md
new file mode 100644 (file)
index 0000000..94be3a0
--- /dev/null
@@ -0,0 +1,86 @@
+## Build & Run
+
+Depending on what area you are working in change or add `HB_DEBUG_<whatever>`.
+Values defined in `hb-debug.hh`.
+
+```shell
+# quick sanity check
+time (make -j4 CPPFLAGS='-DHB_DEBUG_SUBSET=100' \
+  && (make -j4 -C test/api check || cat test/api/test-suite.log))
+
+# slower sanity check
+time (make -j4 CPPFLAGS='-DHB_DEBUG_SUBSET=100' \
+   && make -j4 -C src check \
+   && make -j4 -C test/api check \
+   && make -j4 -C test/subset check)
+
+# confirm you didn't break anything else
+time (make -j4 CPPFLAGS='-DHB_DEBUG_SUBSET=100' \
+  && make -j4 check)
+
+# often catches files you didn't add, e.g. test fonts to EXTRA_DIST
+make distcheck
+```
+
+### Run tests with asan
+
+**NOTE**: this sometimes yields harder to read results than the full fuzzer
+
+```shell
+# For nice symbols tell asan how to symoblize. Note that it doesn't like versioned copies like llvm-symbolizer-3.8
+# export ASAN_SYMBOLIZER_PATH=path to version-less llvm-symbolizer
+# ex
+export ASAN_SYMBOLIZER_PATH=/usr/lib/llvm-3.8/bin/llvm-symbolizer
+
+./configure CC=clang CXX=clang++ CPPFLAGS=-fsanitize=address LDFLAGS=-fsanitize=address
+# make/run tests as usual
+```
+
+### Debug with GDB
+
+```
+cd ./util
+../libtool --mode=execute gdb --args ./hb-subset ...
+```
+
+### Enable Debug Logging
+
+```shell
+# make clean if you previously build w/o debug logging
+make CPPFLAGS=-DHB_DEBUG_SUBSET=100
+```
+
+## Build and Test via CMake
+
+Note: You'll need to first install ninja-build via apt-get.
+
+```shell
+cd harfbuzz
+mkdir buid
+cmake -DHB_CHECK=ON -Bbuild -H. -GNinja && ninja -Cbuild && CTEST_OUTPUT_ON_FAILURE=1 ninja -Cbuild test
+```
+## Test with the Fuzzer
+
+```shell
+# push your changs to a branch on googlefonts/harfbuzz
+# In a local copy of oss-fuzz, edit projects/harfbuzz/Dockerfile
+# Change the git clone to pull your branch
+
+# Do this periodically
+sudo python infra/helper.py build_image harfbuzz
+
+# Do these to update/run
+sudo python infra/helper.py build_fuzzers --sanitizer address harfbuzz
+sudo python infra/helper.py run_fuzzer harfbuzz hb-subset-fuzzer
+```
+
+## Profiling
+
+```
+make clean
+./configure CXXFLAGS="-fno-omit-frame-pointer -g"
+make
+perf record -o <perf output file> -g <command to run>
+perf report -i<perf output file>
+```
+
diff --git a/THANKS b/THANKS
index 940cfde..88cb7e9 100644 (file)
--- a/THANKS
+++ b/THANKS
@@ -1,6 +1,6 @@
 Bradley Grainger
-Khaled Hosny
 Kenichi Ishibashi
+Ivan Kuckir <https://photopea.com/>
 Ryan Lortie
 Jeff Muizelaar
 suzuki toshiya
index 8fef336..a2efd89 100644 (file)
@@ -1636,6 +1636,7 @@ AC_SUBST([am__untar])
 
 m4_include([m4/ax_check_link_flag.m4])
 m4_include([m4/ax_code_coverage.m4])
+m4_include([m4/ax_cxx_compile_stdcxx.m4])
 m4_include([m4/ax_pthread.m4])
 m4_include([m4/gtk-doc.m4])
 m4_include([m4/libtool.m4])
index 7faa9fd..381036e 100644 (file)
@@ -15,9 +15,8 @@
 /* Have Core Text backend */
 #undef HAVE_CORETEXT
 
-/* Define to 1 if you have the declaration of `round', and to 0 if you don't.
-   */
-#undef HAVE_DECL_ROUND
+/* define if the compiler supports basic C++11 syntax */
+#undef HAVE_CXX11
 
 /* Have DirectWrite library */
 #undef HAVE_DIRECTWRITE
@@ -28,9 +27,6 @@
 /* Define to 1 if you have the <dwrite.h> header file. */
 #undef HAVE_DWRITE_H
 
-/* Have simple TrueType Layout backend */
-#undef HAVE_FALLBACK
-
 /* Have fontconfig library */
 #undef HAVE_FONTCONFIG
 
@@ -46,6 +42,9 @@
 /* Define to 1 if you have the `FT_Set_Var_Blend_Coordinates' function. */
 #undef HAVE_FT_SET_VAR_BLEND_COORDINATES
 
+/* Have GDI library */
+#undef HAVE_GDI
+
 /* Define to 1 if you have the `getpagesize' function. */
 #undef HAVE_GETPAGESIZE
 
 /* Define to 1 if you have the `newlocale' function. */
 #undef HAVE_NEWLOCALE
 
-/* Define to 1 if you have the `posix_memalign' function. */
-#undef HAVE_POSIX_MEMALIGN
-
 /* Have POSIX threads */
 #undef HAVE_PTHREAD
 
 /* Have PTHREAD_PRIO_INHERIT. */
 #undef HAVE_PTHREAD_PRIO_INHERIT
 
-/* Define to 1 if you have the `round' function. */
-#undef HAVE_ROUND
+/* Define to 1 if you have the `roundf' function. */
+#undef HAVE_ROUNDF
 
 /* Define to 1 if you have the <sched.h> header file. */
 #undef HAVE_SCHED_H
 /* Define to 1 if you have the <sys/types.h> header file. */
 #undef HAVE_SYS_TYPES_H
 
-/* Have UCDN Unicode functions */
-#undef HAVE_UCDN
-
 /* Have Uniscribe library */
 #undef HAVE_UNISCRIBE
 
index 9ccf09a..20f7cf2 100755 (executable)
@@ -2,7 +2,7 @@
 # Configuration validation subroutine script.
 #   Copyright 1992-2018 Free Software Foundation, Inc.
 
-timestamp='2018-03-08'
+timestamp='2018-05-05'
 
 # This file is free software; you can redistribute it and/or modify it
 # under the terms of the GNU General Public License as published by
@@ -110,28 +110,48 @@ case $# in
     exit 1;;
 esac
 
-# Separate what the user gave into CPU-COMPANY and OS or KERNEL-OS (if any).
-# Here we must recognize all the valid KERNEL-OS combinations.
-maybe_os=`echo "$1" | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'`
-case $maybe_os in
-  nto-qnx* | linux-gnu* | linux-android* | linux-dietlibc | linux-newlib* | \
-  linux-musl* | linux-uclibc* | uclinux-uclibc* | uclinux-gnu* | kfreebsd*-gnu* | \
-  knetbsd*-gnu* | netbsd*-gnu* | netbsd*-eabi* | \
-  kopensolaris*-gnu* | cloudabi*-eabi* | \
-  storm-chaos* | os2-emx* | rtmk-nova*)
-    os=-$maybe_os
-    basic_machine=`echo "$1" | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`
-    ;;
-  android-linux)
-    os=-linux-android
-    basic_machine=`echo "$1" | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`-unknown
-    ;;
-  *)
-    basic_machine=`echo "$1" | sed 's/-[^-]*$//'`
-    if [ "$basic_machine" != "$1" ]
-    then os=`echo "$1" | sed 's/.*-/-/'`
-    else os=; fi
-    ;;
+# Spilt fields of configuration type
+IFS="-" read -r field1 field2 field3 field4 <<EOF
+$1
+EOF
+
+# Separate into logical components for further validation
+case $1 in
+       *-*-*-*)
+               basic_machine=$field1-$field2
+               os=-$field3-$field4
+               ;;
+       *-*-*)
+               # Ambiguous whether COMPANY is present, or skipped and KERNEL-OS is two
+               # parts
+               maybe_os=$field2-$field3
+               case $maybe_os in
+                       nto-qnx* | linux-gnu* | linux-android* | linux-dietlibc \
+                       | linux-newlib* | linux-musl* | linux-uclibc* | uclinux-uclibc* \
+                       | uclinux-gnu* | kfreebsd*-gnu* | knetbsd*-gnu* | netbsd*-gnu* \
+                       | netbsd*-eabi* | kopensolaris*-gnu* | cloudabi*-eabi* \
+                       | storm-chaos* | os2-emx* | rtmk-nova*)
+                               basic_machine=$field1
+                               os=-$maybe_os
+                               ;;
+                       android-linux)
+                               basic_machine=$field1-unknown
+                               os=-linux-android
+                               ;;
+                       *)
+                               basic_machine=$field1-$field2
+                               os=-$field3
+                               ;;
+               esac
+               ;;
+       *-*)
+               basic_machine=$field1
+               os=-$field2
+               ;;
+       *)
+               basic_machine=$1
+               os=
+               ;;
 esac
 
 ### Let's recognize common machines as not being operating systems so
@@ -249,12 +269,12 @@ case $basic_machine in
        | alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] | alpha64pca5[67] \
        | am33_2.0 \
        | arc | arceb \
-       | arm | arm[bl]e | arme[lb] | armv[2-8] | armv[3-8][lb] | armv7[arm] \
+       | arm | arm[bl]e | arme[lb] | armv[2-8] | armv[3-8][lb] | armv6m | armv[78][arm] \
        | avr | avr32 \
        | ba \
        | be32 | be64 \
        | bfin \
-       | c4x | c8051 | clipper \
+       | c4x | c8051 | clipper | csky \
        | d10v | d30v | dlx | dsp16xx \
        | e2k | epiphany \
        | fido | fr30 | frv | ft32 \
@@ -293,6 +313,7 @@ case $basic_machine in
        | mt \
        | msp430 \
        | nds32 | nds32le | nds32be \
+       | nfp \
        | nios | nios2 | nios2eb | nios2el \
        | ns16k | ns32k \
        | open8 | or1k | or1knd | or32 \
@@ -335,6 +356,10 @@ case $basic_machine in
                ;;
        m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | v70 | w65)
                ;;
+       m9s12z | m68hcs12z | hcs12z | s12z)
+               basic_machine=s12z-unknown
+               os=-none
+               ;;
        ms1)
                basic_machine=mt-unknown
                ;;
@@ -378,7 +403,7 @@ case $basic_machine in
        | be32-* | be64-* \
        | bfin-* | bs2000-* \
        | c[123]* | c30-* | [cjt]90-* | c4x-* \
-       | c8051-* | clipper-* | craynv-* | cydra-* \
+       | c8051-* | clipper-* | craynv-* | csky-* | cydra-* \
        | d10v-* | d30v-* | dlx-* \
        | e2k-* | elxsi-* \
        | f30[01]-* | f700-* | fido-* | fr30-* | frv-* | fx80-* \
@@ -419,6 +444,7 @@ case $basic_machine in
        | mt-* \
        | msp430-* \
        | nds32-* | nds32le-* | nds32be-* \
+       | nfp-* \
        | nios-* | nios2-* | nios2eb-* | nios2el-* \
        | none-* | np1-* | ns16k-* | ns32k-* \
        | open8-* \
@@ -1334,7 +1360,7 @@ esac
 
 # Decode manufacturer-specific aliases for certain operating systems.
 
-if [ x"$os" != x"" ]
+if [ x$os != x ]
 then
 case $os in
        # First match some system type aliases that might get confused
@@ -1524,6 +1550,12 @@ case $os in
                ;;
        -none)
                ;;
+       -*-eabi)
+               case $basic_machine in
+                   arm*)
+                       ;;
+               esac
+               ;;
        *)
                # Get rid of the `-' at the beginning of $os.
                os=`echo $os | sed 's/[^-]*-//'`
index 783a66d..8d63038 100755 (executable)
--- a/configure
+++ b/configure
@@ -1,6 +1,6 @@
 #! /bin/sh
 # Guess values for system-dependent variables and create Makefiles.
-# Generated by GNU Autoconf 2.69 for HarfBuzz 2.4.0.
+# Generated by GNU Autoconf 2.69 for HarfBuzz 2.6.4.
 #
 # Report bugs to <https://github.com/harfbuzz/harfbuzz/issues/new>.
 #
@@ -590,8 +590,8 @@ MAKEFLAGS=
 # Identity of this package.
 PACKAGE_NAME='HarfBuzz'
 PACKAGE_TARNAME='harfbuzz'
-PACKAGE_VERSION='2.4.0'
-PACKAGE_STRING='HarfBuzz 2.4.0'
+PACKAGE_VERSION='2.6.4'
+PACKAGE_STRING='HarfBuzz 2.6.4'
 PACKAGE_BUGREPORT='https://github.com/harfbuzz/harfbuzz/issues/new'
 PACKAGE_URL='http://harfbuzz.org/'
 
@@ -644,6 +644,10 @@ HAVE_DIRECTWRITE_FALSE
 HAVE_DIRECTWRITE_TRUE
 DIRECTWRITE_LIBS
 DIRECTWRITE_CXXFLAGS
+HAVE_GDI_FALSE
+HAVE_GDI_TRUE
+GDI_LIBS
+GDI_CFLAGS
 HAVE_UNISCRIBE_FALSE
 HAVE_UNISCRIBE_TRUE
 UNISCRIBE_LIBS
@@ -658,8 +662,6 @@ HAVE_GRAPHITE2_TRUE
 GRAPHITE2_LIBS
 GRAPHITE2_CFLAGS
 GRAPHITE2_DEPS
-HAVE_UCDN_FALSE
-HAVE_UCDN_TRUE
 HAVE_ICU_BUILTIN_FALSE
 HAVE_ICU_BUILTIN_TRUE
 HAVE_ICU_FALSE
@@ -700,8 +702,6 @@ HAVE_GLIB_TRUE
 GLIB_LIBS
 GLIB_CFLAGS
 GLIB_DEPS
-HAVE_FALLBACK_FALSE
-HAVE_FALLBACK_TRUE
 HAVE_PTHREAD_FALSE
 HAVE_PTHREAD_TRUE
 PTHREAD_CFLAGS
@@ -743,6 +743,7 @@ RAGEL
 PKG_CONFIG_LIBDIR
 PKG_CONFIG_PATH
 PKG_CONFIG
+HAVE_CXX11
 CXXCPP
 am__fastdepCXX_FALSE
 am__fastdepCXX_TRUE
@@ -902,10 +903,10 @@ enable_introspection
 with_cairo
 with_fontconfig
 with_icu
-with_ucdn
 with_graphite2
 with_freetype
 with_uniscribe
+with_gdi
 with_directwrite
 with_coretext
 '
@@ -1484,7 +1485,7 @@ if test "$ac_init_help" = "long"; then
   # 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 2.4.0 to adapt to many kinds of systems.
+\`configure' configures HarfBuzz 2.6.4 to adapt to many kinds of systems.
 
 Usage: $0 [OPTION]... [VAR=VALUE]...
 
@@ -1554,7 +1555,7 @@ fi
 
 if test -n "$ac_init_help"; then
   case $ac_init_help in
-     short | recursive ) echo "Configuration of HarfBuzz 2.4.0:";;
+     short | recursive ) echo "Configuration of HarfBuzz 2.6.4:";;
    esac
   cat <<\_ACEOF
 
@@ -1606,13 +1607,14 @@ Optional Packages:
                           Use fontconfig [default=auto]
   --with-icu=[yes/no/builtin/auto]
                           Use ICU [default=auto]
-  --with-ucdn=[yes/no]    Use builtin UCDN library [default=yes]
   --with-graphite2=[yes/no/auto]
                           Use the graphite2 library [default=no]
   --with-freetype=[yes/no/auto]
                           Use the FreeType library [default=auto]
   --with-uniscribe=[yes/no/auto]
                           Use the Uniscribe library [default=no]
+  --with-gdi=[yes/no/auto]
+                          Provide GDI integration helpers [default=no]
   --with-directwrite=[yes/no/auto]
                           Use the DirectWrite library (experimental)
                           [default=no]
@@ -1737,7 +1739,7 @@ fi
 test -n "$ac_init_help" && exit $ac_status
 if $ac_init_version; then
   cat <<\_ACEOF
-HarfBuzz configure 2.4.0
+HarfBuzz configure 2.6.4
 generated by GNU Autoconf 2.69
 
 Copyright (C) 2012 Free Software Foundation, Inc.
@@ -2133,52 +2135,6 @@ fi
 
 } # ac_fn_cxx_try_link
 
-# ac_fn_c_check_decl LINENO SYMBOL VAR INCLUDES
-# ---------------------------------------------
-# Tests whether SYMBOL is declared in INCLUDES, setting cache variable VAR
-# accordingly.
-ac_fn_c_check_decl ()
-{
-  as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
-  as_decl_name=`echo $2|sed 's/ *(.*//'`
-  as_decl_use=`echo $2|sed -e 's/(/((/' -e 's/)/) 0&/' -e 's/,/) 0& (/g'`
-  { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $as_decl_name is declared" >&5
-$as_echo_n "checking whether $as_decl_name is declared... " >&6; }
-if eval \${$3+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
-  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h.  */
-$4
-int
-main ()
-{
-#ifndef $as_decl_name
-#ifdef __cplusplus
-  (void) $as_decl_use;
-#else
-  (void) $as_decl_name;
-#endif
-#endif
-
-  ;
-  return 0;
-}
-_ACEOF
-if ac_fn_c_try_compile "$LINENO"; then :
-  eval "$3=yes"
-else
-  eval "$3=no"
-fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-fi
-eval ac_res=\$$3
-              { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
-$as_echo "$ac_res" >&6; }
-  eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
-
-} # ac_fn_c_check_decl
-
 # ac_fn_c_check_header_mongrel LINENO HEADER VAR INCLUDES
 # -------------------------------------------------------
 # Tests whether HEADER exists, giving a warning if it cannot be compiled using
@@ -2601,7 +2557,7 @@ cat >config.log <<_ACEOF
 This file contains any messages produced by compilers while
 running configure, to aid debugging if configure makes a mistake.
 
-It was created by HarfBuzz $as_me 2.4.0, which was
+It was created by HarfBuzz $as_me 2.6.4, which was
 generated by GNU Autoconf 2.69.  Invocation command line was
 
   $ $0 $@
@@ -3470,7 +3426,7 @@ fi
 
 # Define the identity of the package.
  PACKAGE='harfbuzz'
- VERSION='2.4.0'
+ VERSION='2.6.4'
 
 
 # Some tools Automake needs.
@@ -5370,8 +5326,8 @@ esac
 
 
 
-macro_version='2.4.6.42-b88ce'
-macro_revision='2.4.6.42'
+macro_version='2.4.6'
+macro_revision='2.4.6'
 
 
 
@@ -7033,29 +6989,13 @@ esac
 fi
 
 : ${AR=ar}
+: ${AR_FLAGS=cru}
 
 
 
 
 
 
-# Use ARFLAGS variable as AR's operation code to sync the variable naming with
-# Automake.  If both AR_FLAGS and ARFLAGS are specified, AR_FLAGS should have
-# higher priority because thats what people were doing historically (setting
-# ARFLAGS for automake and AR_FLAGS for libtool).  FIXME: Make the AR_FLAGS
-# variable obsoleted/removed.
-
-test ${AR_FLAGS+y} || AR_FLAGS=${ARFLAGS-cr}
-lt_ar_flags=$AR_FLAGS
-
-
-
-
-
-
-# Make AR_FLAGS overridable by 'make ARFLAGS='.  Don't try to run-time override
-# by AR_FLAGS because that was never working and AR_FLAGS is about to die.
-
 
 
 
@@ -7504,7 +7444,7 @@ for ac_symprfx in "" "_"; do
   if test "$lt_cv_nm_interface" = "MS dumpbin"; then
     # Fake it for dumpbin and say T for any non-static function,
     # D for any global variable and I for any imported variable.
-    # Also find C++ and __fastcall symbols from MSVC++ or ICC,
+    # Also find C++ and __fastcall symbols from MSVC++,
     # which start with @ or ?.
     lt_cv_sys_global_symbol_pipe="$AWK '"\
 "     {last_section=section; section=\$ 3};"\
@@ -8773,8 +8713,8 @@ int forced_loaded() { return 2;}
 _LT_EOF
       echo "$LTCC $LTCFLAGS -c -o conftest.o conftest.c" >&5
       $LTCC $LTCFLAGS -c -o conftest.o conftest.c 2>&5
-      echo "$AR $AR_FLAGS libconftest.a conftest.o" >&5
-      $AR $AR_FLAGS libconftest.a conftest.o 2>&5
+      echo "$AR cru libconftest.a conftest.o" >&5
+      $AR cru libconftest.a conftest.o 2>&5
       echo "$RANLIB libconftest.a" >&5
       $RANLIB libconftest.a 2>&5
       cat > conftest.c << _LT_EOF
@@ -9436,8 +9376,8 @@ esac
 ofile=libtool
 can_build_shared=yes
 
-# All known linkers require a '.a' archive for static linking (except MSVC and
-# ICC, which need '.lib').
+# All known linkers require a '.a' archive for static linking (except MSVC,
+# which needs '.lib').
 libext=a
 
 with_gnu_ld=$lt_cv_prog_gnu_ld
@@ -10364,15 +10304,15 @@ $as_echo_n "checking whether the $compiler linker ($LD) supports shared librarie
 
   case $host_os in
   cygwin* | mingw* | pw32* | cegcc*)
-    # FIXME: the MSVC++ and ICC port hasn't been tested in a loooong time
+    # FIXME: the MSVC++ port hasn't been tested in a loooong time
     # When not using gcc, we currently assume that we are using
-    # Microsoft Visual C++ or Intel C++ Compiler.
+    # Microsoft Visual C++.
     if test yes != "$GCC"; then
       with_gnu_ld=no
     fi
     ;;
   interix*)
-    # we just hope/assume this is gcc and not c89 (= MSVC++ or ICC)
+    # we just hope/assume this is gcc and not c89 (= MSVC++)
     with_gnu_ld=yes
     ;;
   openbsd* | bitrig*)
@@ -10536,7 +10476,6 @@ _LT_EOF
        emximp -o $lib $output_objdir/$libname.def'
       old_archive_From_new_cmds='emximp -o $output_objdir/${libname}_dll.a $output_objdir/$libname.def'
       enable_shared_with_static_runtimes=yes
-      file_list_spec='@'
       ;;
 
     interix[3-9]*)
@@ -10754,7 +10693,7 @@ _LT_EOF
        if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then
          export_symbols_cmds='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W")) && (substr(\$ 3,1,1) != ".")) { if (\$ 2 == "W") { print \$ 3 " weak" } else { print \$ 3 } } }'\'' | sort -u > $export_symbols'
        else
-         export_symbols_cmds='`func_echo_all $NM | $SED -e '\''s/B\([^B]*\)$/P\1/'\''` -PCpgl $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "L") || (\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) && (substr(\$ 1,1,1) != ".")) { if ((\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) { print \$ 1 " weak" } else { print \$ 1 } } }'\'' | sort -u > $export_symbols'
+         export_symbols_cmds='`func_echo_all $NM | $SED -e '\''s/B\([^B]*\)$/P\1/'\''` -PCpgl $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) && (substr(\$ 1,1,1) != ".")) { if ((\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) { print \$ 1 " weak" } else { print \$ 1 } } }'\'' | sort -u > $export_symbols'
        fi
        aix_use_runtimelinking=no
 
 
     cygwin* | mingw* | pw32* | cegcc*)
       # When not using gcc, we currently assume that we are using
-      # Microsoft Visual C++ or Intel C++ Compiler.
+      # Microsoft Visual C++.
       # hardcode_libdir_flag_spec is actually meaningless, as there is
       # no search path for DLLs.
       case $cc_basename in
-      cl* | icl*)
-       # Native MSVC or ICC
+      cl*)
+       # Native MSVC
        hardcode_libdir_flag_spec=' '
        allow_undefined_flag=unsupported
        always_export_symbols=yes
@@ -11067,7 +11006,7 @@ fi
           fi'
        ;;
       *)
-       # Assume MSVC and ICC wrapper
+       # Assume MSVC wrapper
        hardcode_libdir_flag_spec=' '
        allow_undefined_flag=unsupported
        # Tell ltmain to make .lib files, not .a files.
@@ -11391,7 +11330,6 @@ $as_echo "$lt_cv_irix_exported_symbol" >&6; }
        emximp -o $lib $output_objdir/$libname.def'
       old_archive_From_new_cmds='emximp -o $output_objdir/${libname}_dll.a $output_objdir/$libname.def'
       enable_shared_with_static_runtimes=yes
-      file_list_spec='@'
       ;;
 
     osf3*)
@@ -12099,8 +12037,8 @@ cygwin* | mingw* | pw32* | cegcc*)
     dynamic_linker='Win32 ld.exe'
     ;;
 
-  *,cl* | *,icl*)
-    # Native MSVC or ICC
+  *,cl*)
+    # Native MSVC
     libname_spec='$name'
     soname_spec='$libname`echo $release | $SED -e 's/[.]/-/g'`$versuffix$shared_ext'
     library_names_spec='$libname.dll.lib'
@@ -12156,7 +12094,7 @@ cygwin* | mingw* | pw32* | cegcc*)
     ;;
 
   *)
-    # Assume MSVC and ICC wrapper
+    # Assume MSVC wrapper
     library_names_spec='$libname`echo $release | $SED -e 's/[.]/-/g'`$versuffix$shared_ext $libname.lib'
     dynamic_linker='Win32 ld.exe'
     ;;
@@ -12420,6 +12358,9 @@ fi
   # before this can be enabled.
   hardcode_into_libs=yes
 
+  # Add ABI-specific directories to the system library path.
+  sys_lib_dlsearch_path_spec="/lib64 /usr/lib64 /lib /usr/lib"
+
   # Ideally, we could use ldconfig to report *all* directores which are
   # searched for libraries, however this is still not possible.  Aside from not
   # being certain /sbin/ldconfig is available, command
@@ -12428,7 +12369,7 @@ fi
   # appending ld.so.conf contents (and includes) to the search path.
   if test -f /etc/ld.so.conf; then
     lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s 2>/dev/null", \$2)); skip = 1; } { if (!skip) print \$0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;/^[      ]*hwcap[        ]/d;s/[:,      ]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;s/"//g;/^$/d' | tr '\n' ' '`
-    sys_lib_dlsearch_path_spec="/lib /usr/lib $lt_ld_extra"
+    sys_lib_dlsearch_path_spec="$sys_lib_dlsearch_path_spec $lt_ld_extra"
   fi
 
   # We used to test for /lib/ld.so.1 and disable shared libraries on
@@ -13335,41 +13276,30 @@ striplib=
 old_striplib=
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether stripping libraries is possible" >&5
 $as_echo_n "checking whether stripping libraries is possible... " >&6; }
-if test -z "$STRIP"; then
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
-else
-  if $STRIP -V 2>&1 | $GREP "GNU strip" >/dev/null; then
-    old_striplib="$STRIP --strip-debug"
-    striplib="$STRIP --strip-unneeded"
-    { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+if test -n "$STRIP" && $STRIP -V 2>&1 | $GREP "GNU strip" >/dev/null; then
+  test -z "$old_striplib" && old_striplib="$STRIP --strip-debug"
+  test -z "$striplib" && striplib="$STRIP --strip-unneeded"
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
 $as_echo "yes" >&6; }
-  else
-    case $host_os in
-    darwin*)
-      # FIXME - insert some real tests, host_os isn't really good enough
+else
+# FIXME - insert some real tests, host_os isn't really good enough
+  case $host_os in
+  darwin*)
+    if test -n "$STRIP"; then
       striplib="$STRIP -x"
       old_striplib="$STRIP -S"
       { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
 $as_echo "yes" >&6; }
-      ;;
-    freebsd*)
-      if $STRIP -V 2>&1 | $GREP "elftoolchain" >/dev/null; then
-        old_striplib="$STRIP --strip-debug"
-        striplib="$STRIP --strip-unneeded"
-        { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
-$as_echo "yes" >&6; }
-      else
-        { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
-      fi
-      ;;
-    *)
+    else
       { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
 $as_echo "no" >&6; }
-      ;;
-    esac
-  fi
+    fi
+    ;;
+  *)
+    { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+    ;;
+  esac
 fi
 
 
@@ -15460,8 +15390,8 @@ fi
 
       cygwin* | mingw* | pw32* | cegcc*)
        case $GXX,$cc_basename in
-       ,cl* | no,cl* | ,icl* | no,icl*)
-         # Native MSVC or ICC
+       ,cl* | no,cl*)
+         # Native MSVC
          # hardcode_libdir_flag_spec is actually meaningless, as there is
          # no search path for DLLs.
          hardcode_libdir_flag_spec_CXX=' '
@@ -15591,7 +15521,6 @@ fi
          emximp -o $lib $output_objdir/$libname.def'
        old_archive_From_new_cmds_CXX='emximp -o $output_objdir/${libname}_dll.a $output_objdir/$libname.def'
        enable_shared_with_static_runtimes_CXX=yes
-       file_list_spec_CXX='@'
        ;;
 
       dgux*)
@@ -17027,7 +16956,7 @@ $as_echo_n "checking whether the $compiler linker ($LD) supports shared librarie
     if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then
       export_symbols_cmds_CXX='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W")) && (substr(\$ 3,1,1) != ".")) { if (\$ 2 == "W") { print \$ 3 " weak" } else { print \$ 3 } } }'\'' | sort -u > $export_symbols'
     else
-      export_symbols_cmds_CXX='`func_echo_all $NM | $SED -e '\''s/B\([^B]*\)$/P\1/'\''` -PCpgl $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "L") || (\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) && (substr(\$ 1,1,1) != ".")) { if ((\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) { print \$ 1 " weak" } else { print \$ 1 } } }'\'' | sort -u > $export_symbols'
+      export_symbols_cmds_CXX='`func_echo_all $NM | $SED -e '\''s/B\([^B]*\)$/P\1/'\''` -PCpgl $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) && (substr(\$ 1,1,1) != ".")) { if ((\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) { print \$ 1 " weak" } else { print \$ 1 } } }'\'' | sort -u > $export_symbols'
     fi
     ;;
   pw32*)
@@ -17035,7 +16964,7 @@ $as_echo_n "checking whether the $compiler linker ($LD) supports shared librarie
     ;;
   cygwin* | mingw* | cegcc*)
     case $cc_basename in
-    cl* | icl*)
+    cl*)
       exclude_expsyms_CXX='_NULL_IMPORT_DESCRIPTOR|_IMPORT_DESCRIPTOR_.*'
       ;;
     *)
@@ -17397,8 +17326,8 @@ cygwin* | mingw* | pw32* | cegcc*)
     dynamic_linker='Win32 ld.exe'
     ;;
 
-  *,cl* | *,icl*)
-    # Native MSVC or ICC
+  *,cl*)
+    # Native MSVC
     libname_spec='$name'
     soname_spec='$libname`echo $release | $SED -e 's/[.]/-/g'`$versuffix$shared_ext'
     library_names_spec='$libname.dll.lib'
@@ -17454,7 +17383,7 @@ cygwin* | mingw* | pw32* | cegcc*)
     ;;
 
   *)
-    # Assume MSVC and ICC wrapper
+    # Assume MSVC wrapper
     library_names_spec='$libname`echo $release | $SED -e 's/[.]/-/g'`$versuffix$shared_ext $libname.lib'
     dynamic_linker='Win32 ld.exe'
     ;;
@@ -17717,6 +17646,9 @@ fi
   # before this can be enabled.
   hardcode_into_libs=yes
 
+  # Add ABI-specific directories to the system library path.
+  sys_lib_dlsearch_path_spec="/lib64 /usr/lib64 /lib /usr/lib"
+
   # Ideally, we could use ldconfig to report *all* directores which are
   # searched for libraries, however this is still not possible.  Aside from not
   # being certain /sbin/ldconfig is available, command
@@ -17725,7 +17657,7 @@ fi
   # appending ld.so.conf contents (and includes) to the search path.
   if test -f /etc/ld.so.conf; then
     lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s 2>/dev/null", \$2)); skip = 1; } { if (!skip) print \$0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;/^[      ]*hwcap[        ]/d;s/[:,      ]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;s/"//g;/^$/d' | tr '\n' ' '`
-    sys_lib_dlsearch_path_spec="/lib /usr/lib $lt_ld_extra"
+    sys_lib_dlsearch_path_spec="$sys_lib_dlsearch_path_spec $lt_ld_extra"
   fi
 
   # We used to test for /lib/ld.so.1 and disable shared libraries on
@@ -18065,73 +17997,1058 @@ ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $
 ac_compiler_gnu=$ac_cv_c_compiler_gnu
 
 
-# Check whether --enable-largefile was given.
-if test "${enable_largefile+set}" = set; then :
-  enableval=$enable_largefile;
-fi
-
-if test "$enable_largefile" != no; then
-
-  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for special C compiler options needed for large files" >&5
-$as_echo_n "checking for special C compiler options needed for large files... " >&6; }
-if ${ac_cv_sys_largefile_CC+:} false; then :
+  ax_cxx_compile_alternatives="11 0x"    ax_cxx_compile_cxx11_required=false
+  ac_ext=cpp
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+  ac_success=no
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CXX supports C++11 features by default" >&5
+$as_echo_n "checking whether $CXX supports C++11 features by default... " >&6; }
+if ${ax_cv_cxx_compile_cxx11+:} false; then :
   $as_echo_n "(cached) " >&6
 else
-  ac_cv_sys_largefile_CC=no
-     if test "$GCC" != yes; then
-       ac_save_CC=$CC
-       while :; do
-        # IRIX 6.2 and later do not support large files by default,
-        # so use the C compiler's -n32 option if that helps.
-        cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
 /* end confdefs.h.  */
-#include <sys/types.h>
- /* Check that off_t can represent 2**63 - 1 correctly.
-    We can't simply define LARGE_OFF_T to be 9223372036854775807,
-    since some C++ compilers masquerading as C compilers
-    incorrectly reject 9223372036854775807.  */
-#define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62))
-  int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721
-                      && LARGE_OFF_T % 2147483647 == 1)
-                     ? 1 : -1];
-int
-main ()
+
+
+// If the compiler admits that it is not ready for C++11, why torture it?
+// Hopefully, this will speed up the test.
+
+#ifndef __cplusplus
+
+#error "This is not a C++ compiler"
+
+#elif __cplusplus < 201103L
+
+#error "This is not a C++11 compiler"
+
+#else
+
+namespace cxx11
 {
 
-  ;
-  return 0;
-}
+  namespace test_static_assert
+  {
+
+    template <typename T>
+    struct check
+    {
+      static_assert(sizeof(int) <= sizeof(T), "not big enough");
+    };
+
+  }
+
+  namespace test_final_override
+  {
+
+    struct Base
+    {
+      virtual void f() {}
+    };
+
+    struct Derived : public Base
+    {
+      virtual void f() override {}
+    };
+
+  }
+
+  namespace test_double_right_angle_brackets
+  {
+
+    template < typename T >
+    struct check {};
+
+    typedef check<void> single_type;
+    typedef check<check<void>> double_type;
+    typedef check<check<check<void>>> triple_type;
+    typedef check<check<check<check<void>>>> quadruple_type;
+
+  }
+
+  namespace test_decltype
+  {
+
+    int
+    f()
+    {
+      int a = 1;
+      decltype(a) b = 2;
+      return a + b;
+    }
+
+  }
+
+  namespace test_type_deduction
+  {
+
+    template < typename T1, typename T2 >
+    struct is_same
+    {
+      static const bool value = false;
+    };
+
+    template < typename T >
+    struct is_same<T, T>
+    {
+      static const bool value = true;
+    };
+
+    template < typename T1, typename T2 >
+    auto
+    add(T1 a1, T2 a2) -> decltype(a1 + a2)
+    {
+      return a1 + a2;
+    }
+
+    int
+    test(const int c, volatile int v)
+    {
+      static_assert(is_same<int, decltype(0)>::value == true, "");
+      static_assert(is_same<int, decltype(c)>::value == false, "");
+      static_assert(is_same<int, decltype(v)>::value == false, "");
+      auto ac = c;
+      auto av = v;
+      auto sumi = ac + av + 'x';
+      auto sumf = ac + av + 1.0;
+      static_assert(is_same<int, decltype(ac)>::value == true, "");
+      static_assert(is_same<int, decltype(av)>::value == true, "");
+      static_assert(is_same<int, decltype(sumi)>::value == true, "");
+      static_assert(is_same<int, decltype(sumf)>::value == false, "");
+      static_assert(is_same<int, decltype(add(c, v))>::value == true, "");
+      return (sumf > 0.0) ? sumi : add(c, v);
+    }
+
+  }
+
+  namespace test_noexcept
+  {
+
+    int f() { return 0; }
+    int g() noexcept { return 0; }
+
+    static_assert(noexcept(f()) == false, "");
+    static_assert(noexcept(g()) == true, "");
+
+  }
+
+  namespace test_constexpr
+  {
+
+    template < typename CharT >
+    unsigned long constexpr
+    strlen_c_r(const CharT *const s, const unsigned long acc) noexcept
+    {
+      return *s ? strlen_c_r(s + 1, acc + 1) : acc;
+    }
+
+    template < typename CharT >
+    unsigned long constexpr
+    strlen_c(const CharT *const s) noexcept
+    {
+      return strlen_c_r(s, 0UL);
+    }
+
+    static_assert(strlen_c("") == 0UL, "");
+    static_assert(strlen_c("1") == 1UL, "");
+    static_assert(strlen_c("example") == 7UL, "");
+    static_assert(strlen_c("another\0example") == 7UL, "");
+
+  }
+
+  namespace test_rvalue_references
+  {
+
+    template < int N >
+    struct answer
+    {
+      static constexpr int value = N;
+    };
+
+    answer<1> f(int&)       { return answer<1>(); }
+    answer<2> f(const int&) { return answer<2>(); }
+    answer<3> f(int&&)      { return answer<3>(); }
+
+    void
+    test()
+    {
+      int i = 0;
+      const int c = 0;
+      static_assert(decltype(f(i))::value == 1, "");
+      static_assert(decltype(f(c))::value == 2, "");
+      static_assert(decltype(f(0))::value == 3, "");
+    }
+
+  }
+
+  namespace test_uniform_initialization
+  {
+
+    struct test
+    {
+      static const int zero {};
+      static const int one {1};
+    };
+
+    static_assert(test::zero == 0, "");
+    static_assert(test::one == 1, "");
+
+  }
+
+  namespace test_lambdas
+  {
+
+    void
+    test1()
+    {
+      auto lambda1 = [](){};
+      auto lambda2 = lambda1;
+      lambda1();
+      lambda2();
+    }
+
+    int
+    test2()
+    {
+      auto a = [](int i, int j){ return i + j; }(1, 2);
+      auto b = []() -> int { return '0'; }();
+      auto c = [=](){ return a + b; }();
+      auto d = [&](){ return c; }();
+      auto e = [a, &b](int x) mutable {
+        const auto identity = [](int y){ return y; };
+        for (auto i = 0; i < a; ++i)
+          a += b--;
+        return x + identity(a + b);
+      }(0);
+      return a + b + c + d + e;
+    }
+
+    int
+    test3()
+    {
+      const auto nullary = [](){ return 0; };
+      const auto unary = [](int x){ return x; };
+      using nullary_t = decltype(nullary);
+      using unary_t = decltype(unary);
+      const auto higher1st = [](nullary_t f){ return f(); };
+      const auto higher2nd = [unary](nullary_t f1){
+        return [unary, f1](unary_t f2){ return f2(unary(f1())); };
+      };
+      return higher1st(nullary) + higher2nd(nullary)(unary);
+    }
+
+  }
+
+  namespace test_variadic_templates
+  {
+
+    template <int...>
+    struct sum;
+
+    template <int N0, int... N1toN>
+    struct sum<N0, N1toN...>
+    {
+      static constexpr auto value = N0 + sum<N1toN...>::value;
+    };
+
+    template <>
+    struct sum<>
+    {
+      static constexpr auto value = 0;
+    };
+
+    static_assert(sum<>::value == 0, "");
+    static_assert(sum<1>::value == 1, "");
+    static_assert(sum<23>::value == 23, "");
+    static_assert(sum<1, 2>::value == 3, "");
+    static_assert(sum<5, 5, 11>::value == 21, "");
+    static_assert(sum<2, 3, 5, 7, 11, 13>::value == 41, "");
+
+  }
+
+  // http://stackoverflow.com/questions/13728184/template-aliases-and-sfinae
+  // Clang 3.1 fails with headers of libstd++ 4.8.3 when using std::function
+  // because of this.
+  namespace test_template_alias_sfinae
+  {
+
+    struct foo {};
+
+    template<typename T>
+    using member = typename T::member_type;
+
+    template<typename T>
+    void func(...) {}
+
+    template<typename T>
+    void func(member<T>*) {}
+
+    void test();
+
+    void test() { func<foo>(0); }
+
+  }
+
+}  // namespace cxx11
+
+#endif  // __cplusplus >= 201103L
+
+
+
 _ACEOF
-        if ac_fn_c_try_compile "$LINENO"; then :
-  break
-fi
-rm -f core conftest.err conftest.$ac_objext
-        CC="$CC -n32"
-        if ac_fn_c_try_compile "$LINENO"; then :
-  ac_cv_sys_largefile_CC=' -n32'; break
+if ac_fn_cxx_try_compile "$LINENO"; then :
+  ax_cv_cxx_compile_cxx11=yes
+else
+  ax_cv_cxx_compile_cxx11=no
 fi
-rm -f core conftest.err conftest.$ac_objext
-        break
-       done
-       CC=$ac_save_CC
-       rm -f conftest.$ac_ext
-    fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
 fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sys_largefile_CC" >&5
-$as_echo "$ac_cv_sys_largefile_CC" >&6; }
-  if test "$ac_cv_sys_largefile_CC" != no; then
-    CC=$CC$ac_cv_sys_largefile_CC
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ax_cv_cxx_compile_cxx11" >&5
+$as_echo "$ax_cv_cxx_compile_cxx11" >&6; }
+  if test x$ax_cv_cxx_compile_cxx11 = xyes; then
+    ac_success=yes
   fi
 
-  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for _FILE_OFFSET_BITS value needed for large files" >&5
-$as_echo_n "checking for _FILE_OFFSET_BITS value needed for large files... " >&6; }
-if ${ac_cv_sys_file_offset_bits+:} false; then :
+    if test x$ac_success = xno; then
+    for alternative in ${ax_cxx_compile_alternatives}; do
+      switch="-std=gnu++${alternative}"
+      cachevar=`$as_echo "ax_cv_cxx_compile_cxx11_$switch" | $as_tr_sh`
+      { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CXX supports C++11 features with $switch" >&5
+$as_echo_n "checking whether $CXX supports C++11 features with $switch... " >&6; }
+if eval \${$cachevar+:} false; then :
   $as_echo_n "(cached) " >&6
 else
-  while :; do
-  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+  ac_save_CXX="$CXX"
+         CXX="$CXX $switch"
+         cat confdefs.h - <<_ACEOF >conftest.$ac_ext
 /* end confdefs.h.  */
-#include <sys/types.h>
+
+
+// If the compiler admits that it is not ready for C++11, why torture it?
+// Hopefully, this will speed up the test.
+
+#ifndef __cplusplus
+
+#error "This is not a C++ compiler"
+
+#elif __cplusplus < 201103L
+
+#error "This is not a C++11 compiler"
+
+#else
+
+namespace cxx11
+{
+
+  namespace test_static_assert
+  {
+
+    template <typename T>
+    struct check
+    {
+      static_assert(sizeof(int) <= sizeof(T), "not big enough");
+    };
+
+  }
+
+  namespace test_final_override
+  {
+
+    struct Base
+    {
+      virtual void f() {}
+    };
+
+    struct Derived : public Base
+    {
+      virtual void f() override {}
+    };
+
+  }
+
+  namespace test_double_right_angle_brackets
+  {
+
+    template < typename T >
+    struct check {};
+
+    typedef check<void> single_type;
+    typedef check<check<void>> double_type;
+    typedef check<check<check<void>>> triple_type;
+    typedef check<check<check<check<void>>>> quadruple_type;
+
+  }
+
+  namespace test_decltype
+  {
+
+    int
+    f()
+    {
+      int a = 1;
+      decltype(a) b = 2;
+      return a + b;
+    }
+
+  }
+
+  namespace test_type_deduction
+  {
+
+    template < typename T1, typename T2 >
+    struct is_same
+    {
+      static const bool value = false;
+    };
+
+    template < typename T >
+    struct is_same<T, T>
+    {
+      static const bool value = true;
+    };
+
+    template < typename T1, typename T2 >
+    auto
+    add(T1 a1, T2 a2) -> decltype(a1 + a2)
+    {
+      return a1 + a2;
+    }
+
+    int
+    test(const int c, volatile int v)
+    {
+      static_assert(is_same<int, decltype(0)>::value == true, "");
+      static_assert(is_same<int, decltype(c)>::value == false, "");
+      static_assert(is_same<int, decltype(v)>::value == false, "");
+      auto ac = c;
+      auto av = v;
+      auto sumi = ac + av + 'x';
+      auto sumf = ac + av + 1.0;
+      static_assert(is_same<int, decltype(ac)>::value == true, "");
+      static_assert(is_same<int, decltype(av)>::value == true, "");
+      static_assert(is_same<int, decltype(sumi)>::value == true, "");
+      static_assert(is_same<int, decltype(sumf)>::value == false, "");
+      static_assert(is_same<int, decltype(add(c, v))>::value == true, "");
+      return (sumf > 0.0) ? sumi : add(c, v);
+    }
+
+  }
+
+  namespace test_noexcept
+  {
+
+    int f() { return 0; }
+    int g() noexcept { return 0; }
+
+    static_assert(noexcept(f()) == false, "");
+    static_assert(noexcept(g()) == true, "");
+
+  }
+
+  namespace test_constexpr
+  {
+
+    template < typename CharT >
+    unsigned long constexpr
+    strlen_c_r(const CharT *const s, const unsigned long acc) noexcept
+    {
+      return *s ? strlen_c_r(s + 1, acc + 1) : acc;
+    }
+
+    template < typename CharT >
+    unsigned long constexpr
+    strlen_c(const CharT *const s) noexcept
+    {
+      return strlen_c_r(s, 0UL);
+    }
+
+    static_assert(strlen_c("") == 0UL, "");
+    static_assert(strlen_c("1") == 1UL, "");
+    static_assert(strlen_c("example") == 7UL, "");
+    static_assert(strlen_c("another\0example") == 7UL, "");
+
+  }
+
+  namespace test_rvalue_references
+  {
+
+    template < int N >
+    struct answer
+    {
+      static constexpr int value = N;
+    };
+
+    answer<1> f(int&)       { return answer<1>(); }
+    answer<2> f(const int&) { return answer<2>(); }
+    answer<3> f(int&&)      { return answer<3>(); }
+
+    void
+    test()
+    {
+      int i = 0;
+      const int c = 0;
+      static_assert(decltype(f(i))::value == 1, "");
+      static_assert(decltype(f(c))::value == 2, "");
+      static_assert(decltype(f(0))::value == 3, "");
+    }
+
+  }
+
+  namespace test_uniform_initialization
+  {
+
+    struct test
+    {
+      static const int zero {};
+      static const int one {1};
+    };
+
+    static_assert(test::zero == 0, "");
+    static_assert(test::one == 1, "");
+
+  }
+
+  namespace test_lambdas
+  {
+
+    void
+    test1()
+    {
+      auto lambda1 = [](){};
+      auto lambda2 = lambda1;
+      lambda1();
+      lambda2();
+    }
+
+    int
+    test2()
+    {
+      auto a = [](int i, int j){ return i + j; }(1, 2);
+      auto b = []() -> int { return '0'; }();
+      auto c = [=](){ return a + b; }();
+      auto d = [&](){ return c; }();
+      auto e = [a, &b](int x) mutable {
+        const auto identity = [](int y){ return y; };
+        for (auto i = 0; i < a; ++i)
+          a += b--;
+        return x + identity(a + b);
+      }(0);
+      return a + b + c + d + e;
+    }
+
+    int
+    test3()
+    {
+      const auto nullary = [](){ return 0; };
+      const auto unary = [](int x){ return x; };
+      using nullary_t = decltype(nullary);
+      using unary_t = decltype(unary);
+      const auto higher1st = [](nullary_t f){ return f(); };
+      const auto higher2nd = [unary](nullary_t f1){
+        return [unary, f1](unary_t f2){ return f2(unary(f1())); };
+      };
+      return higher1st(nullary) + higher2nd(nullary)(unary);
+    }
+
+  }
+
+  namespace test_variadic_templates
+  {
+
+    template <int...>
+    struct sum;
+
+    template <int N0, int... N1toN>
+    struct sum<N0, N1toN...>
+    {
+      static constexpr auto value = N0 + sum<N1toN...>::value;
+    };
+
+    template <>
+    struct sum<>
+    {
+      static constexpr auto value = 0;
+    };
+
+    static_assert(sum<>::value == 0, "");
+    static_assert(sum<1>::value == 1, "");
+    static_assert(sum<23>::value == 23, "");
+    static_assert(sum<1, 2>::value == 3, "");
+    static_assert(sum<5, 5, 11>::value == 21, "");
+    static_assert(sum<2, 3, 5, 7, 11, 13>::value == 41, "");
+
+  }
+
+  // http://stackoverflow.com/questions/13728184/template-aliases-and-sfinae
+  // Clang 3.1 fails with headers of libstd++ 4.8.3 when using std::function
+  // because of this.
+  namespace test_template_alias_sfinae
+  {
+
+    struct foo {};
+
+    template<typename T>
+    using member = typename T::member_type;
+
+    template<typename T>
+    void func(...) {}
+
+    template<typename T>
+    void func(member<T>*) {}
+
+    void test();
+
+    void test() { func<foo>(0); }
+
+  }
+
+}  // namespace cxx11
+
+#endif  // __cplusplus >= 201103L
+
+
+
+_ACEOF
+if ac_fn_cxx_try_compile "$LINENO"; then :
+  eval $cachevar=yes
+else
+  eval $cachevar=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+         CXX="$ac_save_CXX"
+fi
+eval ac_res=\$$cachevar
+              { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+      if eval test x\$$cachevar = xyes; then
+        CXX="$CXX $switch"
+        if test -n "$CXXCPP" ; then
+          CXXCPP="$CXXCPP $switch"
+        fi
+        ac_success=yes
+        break
+      fi
+    done
+  fi
+
+    if test x$ac_success = xno; then
+                for alternative in ${ax_cxx_compile_alternatives}; do
+      for switch in -std=c++${alternative} +std=c++${alternative} "-h std=c++${alternative}"; do
+        cachevar=`$as_echo "ax_cv_cxx_compile_cxx11_$switch" | $as_tr_sh`
+        { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CXX supports C++11 features with $switch" >&5
+$as_echo_n "checking whether $CXX supports C++11 features with $switch... " >&6; }
+if eval \${$cachevar+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_save_CXX="$CXX"
+           CXX="$CXX $switch"
+           cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+
+// If the compiler admits that it is not ready for C++11, why torture it?
+// Hopefully, this will speed up the test.
+
+#ifndef __cplusplus
+
+#error "This is not a C++ compiler"
+
+#elif __cplusplus < 201103L
+
+#error "This is not a C++11 compiler"
+
+#else
+
+namespace cxx11
+{
+
+  namespace test_static_assert
+  {
+
+    template <typename T>
+    struct check
+    {
+      static_assert(sizeof(int) <= sizeof(T), "not big enough");
+    };
+
+  }
+
+  namespace test_final_override
+  {
+
+    struct Base
+    {
+      virtual void f() {}
+    };
+
+    struct Derived : public Base
+    {
+      virtual void f() override {}
+    };
+
+  }
+
+  namespace test_double_right_angle_brackets
+  {
+
+    template < typename T >
+    struct check {};
+
+    typedef check<void> single_type;
+    typedef check<check<void>> double_type;
+    typedef check<check<check<void>>> triple_type;
+    typedef check<check<check<check<void>>>> quadruple_type;
+
+  }
+
+  namespace test_decltype
+  {
+
+    int
+    f()
+    {
+      int a = 1;
+      decltype(a) b = 2;
+      return a + b;
+    }
+
+  }
+
+  namespace test_type_deduction
+  {
+
+    template < typename T1, typename T2 >
+    struct is_same
+    {
+      static const bool value = false;
+    };
+
+    template < typename T >
+    struct is_same<T, T>
+    {
+      static const bool value = true;
+    };
+
+    template < typename T1, typename T2 >
+    auto
+    add(T1 a1, T2 a2) -> decltype(a1 + a2)
+    {
+      return a1 + a2;
+    }
+
+    int
+    test(const int c, volatile int v)
+    {
+      static_assert(is_same<int, decltype(0)>::value == true, "");
+      static_assert(is_same<int, decltype(c)>::value == false, "");
+      static_assert(is_same<int, decltype(v)>::value == false, "");
+      auto ac = c;
+      auto av = v;
+      auto sumi = ac + av + 'x';
+      auto sumf = ac + av + 1.0;
+      static_assert(is_same<int, decltype(ac)>::value == true, "");
+      static_assert(is_same<int, decltype(av)>::value == true, "");
+      static_assert(is_same<int, decltype(sumi)>::value == true, "");
+      static_assert(is_same<int, decltype(sumf)>::value == false, "");
+      static_assert(is_same<int, decltype(add(c, v))>::value == true, "");
+      return (sumf > 0.0) ? sumi : add(c, v);
+    }
+
+  }
+
+  namespace test_noexcept
+  {
+
+    int f() { return 0; }
+    int g() noexcept { return 0; }
+
+    static_assert(noexcept(f()) == false, "");
+    static_assert(noexcept(g()) == true, "");
+
+  }
+
+  namespace test_constexpr
+  {
+
+    template < typename CharT >
+    unsigned long constexpr
+    strlen_c_r(const CharT *const s, const unsigned long acc) noexcept
+    {
+      return *s ? strlen_c_r(s + 1, acc + 1) : acc;
+    }
+
+    template < typename CharT >
+    unsigned long constexpr
+    strlen_c(const CharT *const s) noexcept
+    {
+      return strlen_c_r(s, 0UL);
+    }
+
+    static_assert(strlen_c("") == 0UL, "");
+    static_assert(strlen_c("1") == 1UL, "");
+    static_assert(strlen_c("example") == 7UL, "");
+    static_assert(strlen_c("another\0example") == 7UL, "");
+
+  }
+
+  namespace test_rvalue_references
+  {
+
+    template < int N >
+    struct answer
+    {
+      static constexpr int value = N;
+    };
+
+    answer<1> f(int&)       { return answer<1>(); }
+    answer<2> f(const int&) { return answer<2>(); }
+    answer<3> f(int&&)      { return answer<3>(); }
+
+    void
+    test()
+    {
+      int i = 0;
+      const int c = 0;
+      static_assert(decltype(f(i))::value == 1, "");
+      static_assert(decltype(f(c))::value == 2, "");
+      static_assert(decltype(f(0))::value == 3, "");
+    }
+
+  }
+
+  namespace test_uniform_initialization
+  {
+
+    struct test
+    {
+      static const int zero {};
+      static const int one {1};
+    };
+
+    static_assert(test::zero == 0, "");
+    static_assert(test::one == 1, "");
+
+  }
+
+  namespace test_lambdas
+  {
+
+    void
+    test1()
+    {
+      auto lambda1 = [](){};
+      auto lambda2 = lambda1;
+      lambda1();
+      lambda2();
+    }
+
+    int
+    test2()
+    {
+      auto a = [](int i, int j){ return i + j; }(1, 2);
+      auto b = []() -> int { return '0'; }();
+      auto c = [=](){ return a + b; }();
+      auto d = [&](){ return c; }();
+      auto e = [a, &b](int x) mutable {
+        const auto identity = [](int y){ return y; };
+        for (auto i = 0; i < a; ++i)
+          a += b--;
+        return x + identity(a + b);
+      }(0);
+      return a + b + c + d + e;
+    }
+
+    int
+    test3()
+    {
+      const auto nullary = [](){ return 0; };
+      const auto unary = [](int x){ return x; };
+      using nullary_t = decltype(nullary);
+      using unary_t = decltype(unary);
+      const auto higher1st = [](nullary_t f){ return f(); };
+      const auto higher2nd = [unary](nullary_t f1){
+        return [unary, f1](unary_t f2){ return f2(unary(f1())); };
+      };
+      return higher1st(nullary) + higher2nd(nullary)(unary);
+    }
+
+  }
+
+  namespace test_variadic_templates
+  {
+
+    template <int...>
+    struct sum;
+
+    template <int N0, int... N1toN>
+    struct sum<N0, N1toN...>
+    {
+      static constexpr auto value = N0 + sum<N1toN...>::value;
+    };
+
+    template <>
+    struct sum<>
+    {
+      static constexpr auto value = 0;
+    };
+
+    static_assert(sum<>::value == 0, "");
+    static_assert(sum<1>::value == 1, "");
+    static_assert(sum<23>::value == 23, "");
+    static_assert(sum<1, 2>::value == 3, "");
+    static_assert(sum<5, 5, 11>::value == 21, "");
+    static_assert(sum<2, 3, 5, 7, 11, 13>::value == 41, "");
+
+  }
+
+  // http://stackoverflow.com/questions/13728184/template-aliases-and-sfinae
+  // Clang 3.1 fails with headers of libstd++ 4.8.3 when using std::function
+  // because of this.
+  namespace test_template_alias_sfinae
+  {
+
+    struct foo {};
+
+    template<typename T>
+    using member = typename T::member_type;
+
+    template<typename T>
+    void func(...) {}
+
+    template<typename T>
+    void func(member<T>*) {}
+
+    void test();
+
+    void test() { func<foo>(0); }
+
+  }
+
+}  // namespace cxx11
+
+#endif  // __cplusplus >= 201103L
+
+
+
+_ACEOF
+if ac_fn_cxx_try_compile "$LINENO"; then :
+  eval $cachevar=yes
+else
+  eval $cachevar=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+           CXX="$ac_save_CXX"
+fi
+eval ac_res=\$$cachevar
+              { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+        if eval test x\$$cachevar = xyes; then
+          CXX="$CXX $switch"
+          if test -n "$CXXCPP" ; then
+            CXXCPP="$CXXCPP $switch"
+          fi
+          ac_success=yes
+          break
+        fi
+      done
+      if test x$ac_success = xyes; then
+        break
+      fi
+    done
+  fi
+  ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+  if test x$ax_cxx_compile_cxx11_required = xtrue; then
+    if test x$ac_success = xno; then
+      as_fn_error $? "*** A compiler with support for C++11 language features is required." "$LINENO" 5
+    fi
+  fi
+  if test x$ac_success = xno; then
+    HAVE_CXX11=0
+    { $as_echo "$as_me:${as_lineno-$LINENO}: No compiler with C++11 support was found" >&5
+$as_echo "$as_me: No compiler with C++11 support was found" >&6;}
+  else
+    HAVE_CXX11=1
+
+$as_echo "#define HAVE_CXX11 1" >>confdefs.h
+
+  fi
+
+
+
+# Check whether --enable-largefile was given.
+if test "${enable_largefile+set}" = set; then :
+  enableval=$enable_largefile;
+fi
+
+if test "$enable_largefile" != no; then
+
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for special C compiler options needed for large files" >&5
+$as_echo_n "checking for special C compiler options needed for large files... " >&6; }
+if ${ac_cv_sys_largefile_CC+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_cv_sys_largefile_CC=no
+     if test "$GCC" != yes; then
+       ac_save_CC=$CC
+       while :; do
+        # IRIX 6.2 and later do not support large files by default,
+        # so use the C compiler's -n32 option if that helps.
+        cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <sys/types.h>
+ /* Check that off_t can represent 2**63 - 1 correctly.
+    We can't simply define LARGE_OFF_T to be 9223372036854775807,
+    since some C++ compilers masquerading as C compilers
+    incorrectly reject 9223372036854775807.  */
+#define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62))
+  int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721
+                      && LARGE_OFF_T % 2147483647 == 1)
+                     ? 1 : -1];
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+        if ac_fn_c_try_compile "$LINENO"; then :
+  break
+fi
+rm -f core conftest.err conftest.$ac_objext
+        CC="$CC -n32"
+        if ac_fn_c_try_compile "$LINENO"; then :
+  ac_cv_sys_largefile_CC=' -n32'; break
+fi
+rm -f core conftest.err conftest.$ac_objext
+        break
+       done
+       CC=$ac_save_CC
+       rm -f conftest.$ac_ext
+    fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sys_largefile_CC" >&5
+$as_echo "$ac_cv_sys_largefile_CC" >&6; }
+  if test "$ac_cv_sys_largefile_CC" != no; then
+    CC=$CC$ac_cv_sys_largefile_CC
+  fi
+
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for _FILE_OFFSET_BITS value needed for large files" >&5
+$as_echo_n "checking for _FILE_OFFSET_BITS value needed for large files... " >&6; }
+if ${ac_cv_sys_file_offset_bits+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  while :; do
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <sys/types.h>
  /* Check that off_t can represent 2**63 - 1 correctly.
     We can't simply define LARGE_OFF_T to be 9223372036854775807,
     since some C++ compilers masquerading as C compilers
@@ -18398,9 +19315,9 @@ GIT=${GIT-"${am_missing_run}git"}
 
 
 HB_VERSION_MAJOR=2
-HB_VERSION_MINOR=4
-HB_VERSION_MICRO=0
-HB_VERSION=2.4.0
+HB_VERSION_MINOR=6
+HB_VERSION_MICRO=4
+HB_VERSION=2.6.4
 
 
 
@@ -18411,7 +19328,7 @@ HB_VERSION=2.4.0
 
 
 
-HB_LIBTOOL_VERSION_INFO=20400:0:20400
+HB_LIBTOOL_VERSION_INFO=20600:4:20600
 
 
 
@@ -18810,7 +19727,7 @@ fi
 
 
 # Functions and headers
-for ac_func in atexit mprotect sysconf getpagesize mmap isatty newlocale strtod_l posix_memalign
+for ac_func in atexit mprotect sysconf getpagesize mmap isatty newlocale strtod_l roundf
 do :
   as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
 ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var"
@@ -18822,35 +19739,6 @@ _ACEOF
 fi
 done
 
-
-save_libs="$LIBS"
-LIBS="$LIBS -lm"
-for ac_func in round
-do :
-  ac_fn_c_check_func "$LINENO" "round" "ac_cv_func_round"
-if test "x$ac_cv_func_round" = xyes; then :
-  cat >>confdefs.h <<_ACEOF
-#define HAVE_ROUND 1
-_ACEOF
-
-else
-  ac_fn_c_check_decl "$LINENO" "round" "ac_cv_have_decl_round" "#include <math.h>
-"
-if test "x$ac_cv_have_decl_round" = xyes; then :
-  ac_have_decl=1
-else
-  ac_have_decl=0
-fi
-
-cat >>confdefs.h <<_ACEOF
-#define HAVE_DECL_ROUND $ac_have_decl
-_ACEOF
-
-fi
-done
-
-LIBS="$save_libs"
-
 for ac_header in unistd.h sys/mman.h xlocale.h stdbool.h
 do :
   as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh`
@@ -18998,7 +19886,6 @@ fi
 
 
 have_pthread=false
-if test "$hb_os_win32" = no; then
 
 
 
@@ -19638,7 +20525,6 @@ ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $
 ac_compiler_gnu=$ac_cv_c_compiler_gnu
 
 
-fi
 if $have_pthread; then
 
 $as_echo "#define HAVE_PTHREAD 1" >>confdefs.h
 
 
 
-have_fallback=true
-if $have_fallback; then
-
-$as_echo "#define HAVE_FALLBACK 1" >>confdefs.h
-
-fi
- if $have_fallback; then
-  HAVE_FALLBACK_TRUE=
-  HAVE_FALLBACK_FALSE='#'
-else
-  HAVE_FALLBACK_TRUE='#'
-  HAVE_FALLBACK_FALSE=
-fi
-
-
-
 
 # Check whether --with-glib was given.
 if test "${with_glib+set}" = set; then :
 
 
 
-# Check whether --with-ucdn was given.
-if test "${with_ucdn+set}" = set; then :
-  withval=$with_ucdn;
-else
-  with_ucdn=yes
-fi
-
-have_ucdn=false
-if test "x$with_ucdn" = "xyes"; then
-       have_ucdn=true
-fi
-if $have_ucdn; then
-
-$as_echo "#define HAVE_UCDN 1" >>confdefs.h
-
-fi
- if $have_ucdn; then
-  HAVE_UCDN_TRUE=
-  HAVE_UCDN_FALSE='#'
-else
-  HAVE_UCDN_TRUE='#'
-  HAVE_UCDN_FALSE=
-fi
-
-
-
-
 # Check whether --with-graphite2 was given.
 if test "${with_graphite2+set}" = set; then :
   withval=$with_graphite2;
 
 
 
+# Check whether --with-gdi was given.
+if test "${with_gdi+set}" = set; then :
+  withval=$with_gdi;
+else
+  with_gdi=no
+fi
+
+have_gdi=false
+if test "x$with_gdi" = "xyes" -o "x$with_gdi" = "xauto"; then
+       for ac_header in windows.h
+do :
+  ac_fn_c_check_header_mongrel "$LINENO" "windows.h" "ac_cv_header_windows_h" "$ac_includes_default"
+if test "x$ac_cv_header_windows_h" = xyes; then :
+  cat >>confdefs.h <<_ACEOF
+#define HAVE_WINDOWS_H 1
+_ACEOF
+ have_gdi=true
+fi
+
+done
+
+fi
+if test "x$with_gdi" = "xyes" -a "x$have_gdi" != "xtrue"; then
+       as_fn_error $? "gdi support requested but not found" "$LINENO" 5
+fi
+if $have_gdi; then
+       GDI_CFLAGS=
+       GDI_LIBS="-lgdi32"
+
+
+
+$as_echo "#define HAVE_GDI 1" >>confdefs.h
+
+fi
+ if $have_gdi; then
+  HAVE_GDI_TRUE=
+  HAVE_GDI_FALSE='#'
+else
+  HAVE_GDI_TRUE='#'
+  HAVE_GDI_FALSE=
+fi
+
+
+
+
 # Check whether --with-directwrite was given.
 if test "${with_directwrite+set}" = set; then :
   withval=$with_directwrite;
@@ -20856,7 +21744,7 @@ if test "x$with_directwrite" = "xyes" -a "x$have_directwrite" != "xtrue"; then
 fi
 if $have_directwrite; then
        DIRECTWRITE_CXXFLAGS=
-       DIRECTWRITE_LIBS="-ldwrite"
+       DIRECTWRITE_LIBS=
 
 
 
@@ -21088,7 +21976,7 @@ fi
 fi
 
 
-ac_config_files="$ac_config_files Makefile src/Makefile src/harfbuzz-config.cmake src/hb-ucdn/Makefile util/Makefile test/Makefile test/api/Makefile test/fuzzing/Makefile test/shaping/Makefile test/shaping/data/Makefile test/shaping/data/aots/Makefile test/shaping/data/in-house/Makefile test/shaping/data/text-rendering-tests/Makefile test/subset/Makefile test/subset/data/Makefile docs/Makefile docs/version.xml"
+ac_config_files="$ac_config_files Makefile src/Makefile src/harfbuzz-config.cmake util/Makefile test/Makefile test/api/Makefile test/fuzzing/Makefile test/shaping/Makefile test/shaping/data/Makefile test/shaping/data/aots/Makefile test/shaping/data/in-house/Makefile test/shaping/data/text-rendering-tests/Makefile test/subset/Makefile test/subset/data/Makefile docs/Makefile docs/version.xml"
 
 
 cat >confcache <<\_ACEOF
@@ -21276,10 +22164,6 @@ if test -z "${HAVE_PTHREAD_TRUE}" && test -z "${HAVE_PTHREAD_FALSE}"; then
   as_fn_error $? "conditional \"HAVE_PTHREAD\" was never defined.
 Usually this means the macro was only invoked conditionally." "$LINENO" 5
 fi
-if test -z "${HAVE_FALLBACK_TRUE}" && test -z "${HAVE_FALLBACK_FALSE}"; then
-  as_fn_error $? "conditional \"HAVE_FALLBACK\" was never defined.
-Usually this means the macro was only invoked conditionally." "$LINENO" 5
-fi
 if test -z "${HAVE_GLIB_TRUE}" && test -z "${HAVE_GLIB_FALSE}"; then
   as_fn_error $? "conditional \"HAVE_GLIB\" was never defined.
 Usually this means the macro was only invoked conditionally." "$LINENO" 5
@@ -21316,10 +22200,6 @@ if test -z "${HAVE_ICU_BUILTIN_TRUE}" && test -z "${HAVE_ICU_BUILTIN_FALSE}"; th
   as_fn_error $? "conditional \"HAVE_ICU_BUILTIN\" was never defined.
 Usually this means the macro was only invoked conditionally." "$LINENO" 5
 fi
-if test -z "${HAVE_UCDN_TRUE}" && test -z "${HAVE_UCDN_FALSE}"; then
-  as_fn_error $? "conditional \"HAVE_UCDN\" was never defined.
-Usually this means the macro was only invoked conditionally." "$LINENO" 5
-fi
 if test -z "${HAVE_GRAPHITE2_TRUE}" && test -z "${HAVE_GRAPHITE2_FALSE}"; then
   as_fn_error $? "conditional \"HAVE_GRAPHITE2\" was never defined.
 Usually this means the macro was only invoked conditionally." "$LINENO" 5
@@ -21332,6 +22212,10 @@ if test -z "${HAVE_UNISCRIBE_TRUE}" && test -z "${HAVE_UNISCRIBE_FALSE}"; then
   as_fn_error $? "conditional \"HAVE_UNISCRIBE\" was never defined.
 Usually this means the macro was only invoked conditionally." "$LINENO" 5
 fi
+if test -z "${HAVE_GDI_TRUE}" && test -z "${HAVE_GDI_FALSE}"; then
+  as_fn_error $? "conditional \"HAVE_GDI\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
 if test -z "${HAVE_DIRECTWRITE_TRUE}" && test -z "${HAVE_DIRECTWRITE_FALSE}"; then
   as_fn_error $? "conditional \"HAVE_DIRECTWRITE\" was never defined.
 Usually this means the macro was only invoked conditionally." "$LINENO" 5
@@ -21737,7 +22621,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
 # report actual input values of CONFIG_FILES etc. instead of their
 # values after options handling.
 ac_log="
-This file was extended by HarfBuzz $as_me 2.4.0, which was
+This file was extended by HarfBuzz $as_me 2.6.4, which was
 generated by GNU Autoconf 2.69.  Invocation command line was
 
   CONFIG_FILES    = $CONFIG_FILES
@@ -21804,7 +22688,7 @@ _ACEOF
 cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`"
 ac_cs_version="\\
-HarfBuzz config.status 2.4.0
+HarfBuzz config.status 2.6.4
 configured by $0, generated by GNU Autoconf 2.69,
   with options \\"\$ac_cs_config\\"
 
@@ -21975,7 +22859,6 @@ want_nocaseglob='`$ECHO "$want_nocaseglob" | $SED "$delay_single_quote_subst"`'
 DLLTOOL='`$ECHO "$DLLTOOL" | $SED "$delay_single_quote_subst"`'
 sharedlib_from_linklib_cmd='`$ECHO "$sharedlib_from_linklib_cmd" | $SED "$delay_single_quote_subst"`'
 AR='`$ECHO "$AR" | $SED "$delay_single_quote_subst"`'
-lt_ar_flags='`$ECHO "$lt_ar_flags" | $SED "$delay_single_quote_subst"`'
 AR_FLAGS='`$ECHO "$AR_FLAGS" | $SED "$delay_single_quote_subst"`'
 archiver_list_spec='`$ECHO "$archiver_list_spec" | $SED "$delay_single_quote_subst"`'
 STRIP='`$ECHO "$STRIP" | $SED "$delay_single_quote_subst"`'
@@ -22158,6 +23041,7 @@ want_nocaseglob \
 DLLTOOL \
 sharedlib_from_linklib_cmd \
 AR \
+AR_FLAGS \
 archiver_list_spec \
 STRIP \
 RANLIB \
@@ -22320,7 +23204,6 @@ do
     "Makefile") CONFIG_FILES="$CONFIG_FILES Makefile" ;;
     "src/Makefile") CONFIG_FILES="$CONFIG_FILES src/Makefile" ;;
     "src/harfbuzz-config.cmake") CONFIG_FILES="$CONFIG_FILES src/harfbuzz-config.cmake" ;;
-    "src/hb-ucdn/Makefile") CONFIG_FILES="$CONFIG_FILES src/hb-ucdn/Makefile" ;;
     "util/Makefile") CONFIG_FILES="$CONFIG_FILES util/Makefile" ;;
     "test/Makefile") CONFIG_FILES="$CONFIG_FILES test/Makefile" ;;
     "test/api/Makefile") CONFIG_FILES="$CONFIG_FILES test/api/Makefile" ;;
@@ -23182,11 +24065,8 @@ sharedlib_from_linklib_cmd=$lt_sharedlib_from_linklib_cmd
 # The archiver.
 AR=$lt_AR
 
-# Flags to create an archive (by configure).
-lt_ar_flags=$lt_ar_flags
-
 # Flags to create an archive.
-AR_FLAGS=\${ARFLAGS-"\$lt_ar_flags"}
+AR_FLAGS=$lt_AR_FLAGS
 
 # How to feed a file listing to the archiver.
 archiver_list_spec=$lt_archiver_list_spec
@@ -23785,7 +24665,7 @@ echo
 Build configuration:
 
 Unicode callbacks (you want at least one):
-       Builtin (UCDN):         ${have_ucdn}
+       Builtin                 true
        Glib:                   ${have_glib}
        ICU:                    ${have_icu}
 
@@ -23802,6 +24682,7 @@ Additional shapers (the more the merrier):
 Platform shapers (not normally needed):
        CoreText:               ${have_coretext}
        DirectWrite:            ${have_directwrite}
+       GDI:                    ${have_gdi}
        Uniscribe:              ${have_uniscribe}
 
 Other features:
@@ -23814,7 +24695,7 @@ $as_echo "$as_me:
 Build configuration:
 
 Unicode callbacks (you want at least one):
-       Builtin (UCDN):         ${have_ucdn}
+       Builtin                 true
        Glib:                   ${have_glib}
        ICU:                    ${have_icu}
 
@@ -23831,6 +24712,7 @@ Additional shapers (the more the merrier):
 Platform shapers (not normally needed):
        CoreText:               ${have_coretext}
        DirectWrite:            ${have_directwrite}
+       GDI:                    ${have_gdi}
        Uniscribe:              ${have_uniscribe}
 
 Other features:
index b51ac4a..4125756 100644 (file)
@@ -1,6 +1,6 @@
 AC_PREREQ([2.64])
 AC_INIT([HarfBuzz],
-        [2.4.0],
+        [2.6.4],
         [https://github.com/harfbuzz/harfbuzz/issues/new],
         [harfbuzz],
         [http://harfbuzz.org/])
@@ -9,7 +9,7 @@ AC_CONFIG_MACRO_DIR([m4])
 AC_CONFIG_SRCDIR([src/harfbuzz.pc.in])
 AC_CONFIG_HEADERS([config.h])
 
-AM_INIT_AUTOMAKE([1.13.0 gnits tar-ustar dist-bzip2 no-dist-gzip -Wall no-define color-tests -Wno-portability])
+AM_INIT_AUTOMAKE([1.13.0 gnits tar-ustar dist-xz no-dist-gzip -Wall no-define color-tests -Wno-portability])
 AM_SILENT_RULES([yes])
 AX_CODE_COVERAGE
 
@@ -23,7 +23,7 @@ AC_PROG_CC
 AC_PROG_CC_C99
 AM_PROG_CC_C_O
 AC_PROG_CXX
-dnl AX_CXX_COMPILE_STDCXX(11, noext, optional)
+AX_CXX_COMPILE_STDCXX(11,, optional)
 AC_SYS_LARGEFILE
 PKG_PROG_PKG_CONFIG([0.20])
 AM_MISSING_PROG([RAGEL], [ragel])
@@ -77,13 +77,7 @@ GTK_DOC_CHECK([1.15],[--flavour no-tmpl])
 ])
 
 # Functions and headers
-AC_CHECK_FUNCS(atexit mprotect sysconf getpagesize mmap isatty newlocale strtod_l posix_memalign)
-
-save_libs="$LIBS"
-LIBS="$LIBS -lm"
-AC_CHECK_FUNCS([round], ,[AC_CHECK_DECLS([round], , ,[#include <math.h>])])
-LIBS="$save_libs"
-
+AC_CHECK_FUNCS(atexit mprotect sysconf getpagesize mmap isatty newlocale strtod_l roundf)
 AC_CHECK_HEADERS(unistd.h sys/mman.h xlocale.h stdbool.h)
 
 # Compiler flags
@@ -134,9 +128,7 @@ AC_MSG_RESULT([$hb_os_win32])
 AM_CONDITIONAL(OS_WIN32, test "$hb_os_win32" = "yes")
 
 have_pthread=false
-if test "$hb_os_win32" = no; then
-       AX_PTHREAD([have_pthread=true])
-fi
+AX_PTHREAD([have_pthread=true])
 if $have_pthread; then
        AC_DEFINE(HAVE_PTHREAD, 1, [Have POSIX threads])
 fi
@@ -144,14 +136,6 @@ AM_CONDITIONAL(HAVE_PTHREAD, $have_pthread)
 
 dnl ==========================================================================
 
-have_fallback=true
-if $have_fallback; then
-       AC_DEFINE(HAVE_FALLBACK, 1, [Have simple TrueType Layout backend])
-fi
-AM_CONDITIONAL(HAVE_FALLBACK, $have_fallback)
-
-dnl ===========================================================================
-
 AC_ARG_WITH(glib,
        [AS_HELP_STRING([--with-glib=@<:@yes/no/auto@:>@],
                        [Use glib @<:@default=auto@:>@])],,
@@ -300,21 +284,6 @@ AM_CONDITIONAL(HAVE_ICU_BUILTIN, $have_icu && test "x$with_icu" = "xbuiltin")
 
 dnl ===========================================================================
 
-AC_ARG_WITH(ucdn,
-       [AS_HELP_STRING([--with-ucdn=@<:@yes/no@:>@],
-                       [Use builtin UCDN library @<:@default=yes@:>@])],,
-       [with_ucdn=yes])
-have_ucdn=false
-if test "x$with_ucdn" = "xyes"; then
-       have_ucdn=true
-fi
-if $have_ucdn; then
-       AC_DEFINE(HAVE_UCDN, 1, [Have UCDN Unicode functions])
-fi
-AM_CONDITIONAL(HAVE_UCDN, $have_ucdn)
-
-dnl ==========================================================================
-
 AC_ARG_WITH(graphite2,
        [AS_HELP_STRING([--with-graphite2=@<:@yes/no/auto@:>@],
                        [Use the graphite2 library @<:@default=no@:>@])],,
@@ -392,6 +361,28 @@ AM_CONDITIONAL(HAVE_UNISCRIBE, $have_uniscribe)
 
 dnl ===========================================================================
 
+AC_ARG_WITH(gdi,
+       [AS_HELP_STRING([--with-gdi=@<:@yes/no/auto@:>@],
+                       [Provide GDI integration helpers @<:@default=no@:>@])],,
+       [with_gdi=no])
+have_gdi=false
+if test "x$with_gdi" = "xyes" -o "x$with_gdi" = "xauto"; then
+       AC_CHECK_HEADERS(windows.h, have_gdi=true)
+fi
+if test "x$with_gdi" = "xyes" -a "x$have_gdi" != "xtrue"; then
+       AC_MSG_ERROR([gdi support requested but not found])
+fi
+if $have_gdi; then
+       GDI_CFLAGS=
+       GDI_LIBS="-lgdi32"
+       AC_SUBST(GDI_CFLAGS)
+       AC_SUBST(GDI_LIBS)
+       AC_DEFINE(HAVE_GDI, 1, [Have GDI library])
+fi
+AM_CONDITIONAL(HAVE_GDI, $have_gdi)
+
+dnl ===========================================================================
+
 AC_ARG_WITH(directwrite,
        [AS_HELP_STRING([--with-directwrite=@<:@yes/no/auto@:>@],
                        [Use the DirectWrite library (experimental) @<:@default=no@:>@])],,
@@ -407,7 +398,7 @@ if test "x$with_directwrite" = "xyes" -a "x$have_directwrite" != "xtrue"; then
 fi
 if $have_directwrite; then
        DIRECTWRITE_CXXFLAGS=
-       DIRECTWRITE_LIBS="-ldwrite"
+       DIRECTWRITE_LIBS=
        AC_SUBST(DIRECTWRITE_CXXFLAGS)
        AC_SUBST(DIRECTWRITE_LIBS)
        AC_DEFINE(HAVE_DIRECTWRITE, 1, [Have DirectWrite library])
@@ -497,7 +488,6 @@ AC_CONFIG_FILES([
 Makefile
 src/Makefile
 src/harfbuzz-config.cmake
-src/hb-ucdn/Makefile
 util/Makefile
 test/Makefile
 test/api/Makefile
@@ -525,7 +515,7 @@ AC_MSG_NOTICE([
 Build configuration:
 
 Unicode callbacks (you want at least one):
-       Builtin (UCDN):         ${have_ucdn}
+       Builtin                 true
        Glib:                   ${have_glib}
        ICU:                    ${have_icu}
 
@@ -542,6 +532,7 @@ Additional shapers (the more the merrier):
 Platform shapers (not normally needed):
        CoreText:               ${have_coretext}
        DirectWrite:            ${have_directwrite}
+       GDI:                    ${have_gdi}
        Uniscribe:              ${have_uniscribe}
 
 Other features:
index 9b54b40..f4bf2fd 100644 (file)
@@ -33,7 +33,7 @@ SCAN_OPTIONS=--rebuild-types --deprecated-guards="HB_DISABLE_DEPRECATED" \
 
 # Header files or dirs to ignore when scanning. Use base file/dir names
 # e.g. IGNORE_HFILES=gtkdebug.h gtkintl.h private_code
-IGNORE_HFILES=`cd $(top_srcdir)/src; find . -path './hb-*/*.h' | sed 's@^.*/@@'`
+IGNORE_HFILES=`cd $(top_srcdir)/src; find . -path './*/*.h' | sed 's@^.*/@@'`
 if HAVE_GOBJECT
 else
 IGNORE_HFILES+=hb-gobject.h hb-gobject-enums.h hb-gobject-structs.h
@@ -75,12 +75,14 @@ content_files=      \
        usermanual-what-is-harfbuzz.xml \
        usermanual-install-harfbuzz.xml \
        usermanual-getting-started.xml \
+       usermanual-glyph-information.xml \
        usermanual-shaping-concepts.xml \
+       usermanual-object-model.xml \
        usermanual-buffers-language-script-and-direction.xml \
        usermanual-fonts-and-faces.xml \
-       usermanual-clusters.xml \
        usermanual-opentype-features.xml \
-       usermanual-glyph-information.xml \
+       usermanual-clusters.xml \
+       usermanual-utilities.xml \
        version.xml
 
 # SGML files where gtk-doc abbrevations (#GtkWidget) are expanded
index 3fa4a70..c4c2902 100644 (file)
@@ -119,6 +119,7 @@ subdir = docs
 ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
 am__aclocal_m4_deps = $(top_srcdir)/m4/ax_check_link_flag.m4 \
        $(top_srcdir)/m4/ax_code_coverage.m4 \
+       $(top_srcdir)/m4/ax_cxx_compile_stdcxx.m4 \
        $(top_srcdir)/m4/ax_pthread.m4 $(top_srcdir)/m4/gtk-doc.m4 \
        $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \
        $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \
@@ -202,6 +203,8 @@ FREETYPE_CFLAGS = @FREETYPE_CFLAGS@
 FREETYPE_DEPS = @FREETYPE_DEPS@
 FREETYPE_LIBS = @FREETYPE_LIBS@
 GCOV = @GCOV@
+GDI_CFLAGS = @GDI_CFLAGS@
+GDI_LIBS = @GDI_LIBS@
 GENHTML = @GENHTML@
 GIT = @GIT@
 GLIB_CFLAGS = @GLIB_CFLAGS@
@@ -220,6 +223,7 @@ GTKDOC_DEPS_CFLAGS = @GTKDOC_DEPS_CFLAGS@
 GTKDOC_DEPS_LIBS = @GTKDOC_DEPS_LIBS@
 GTKDOC_MKPDF = @GTKDOC_MKPDF@
 GTKDOC_REBASE = @GTKDOC_REBASE@
+HAVE_CXX11 = @HAVE_CXX11@
 HB_LIBTOOL_VERSION_INFO = @HB_LIBTOOL_VERSION_INFO@
 HB_VERSION = @HB_VERSION@
 HB_VERSION_MAJOR = @HB_VERSION_MAJOR@
@@ -374,7 +378,7 @@ SCAN_OPTIONS = --rebuild-types --deprecated-guards="HB_DISABLE_DEPRECATED" \
 
 # Header files or dirs to ignore when scanning. Use base file/dir names
 # e.g. IGNORE_HFILES=gtkdebug.h gtkintl.h private_code
-IGNORE_HFILES = `cd $(top_srcdir)/src; find . -path './hb-*/*.h' | sed \
+IGNORE_HFILES = `cd $(top_srcdir)/src; find . -path './*/*.h' | sed \
        's@^.*/@@'` $(am__append_1)
 
 # Extra options to supply to gtkdoc-mkdb.
@@ -414,12 +418,14 @@ content_files = \
        usermanual-what-is-harfbuzz.xml \
        usermanual-install-harfbuzz.xml \
        usermanual-getting-started.xml \
+       usermanual-glyph-information.xml \
        usermanual-shaping-concepts.xml \
+       usermanual-object-model.xml \
        usermanual-buffers-language-script-and-direction.xml \
        usermanual-fonts-and-faces.xml \
-       usermanual-clusters.xml \
        usermanual-opentype-features.xml \
-       usermanual-glyph-information.xml \
+       usermanual-clusters.xml \
+       usermanual-utilities.xml \
        version.xml
 
 
index 0c462f3..433c206 100644 (file)
 
       <para>
        The canonical source-code tree is available at
-        <ulink
-           url="https://github.com/harfbuzz/harfbuzz">github.com/harfbuzz/harfbuzz</ulink>
-        and is also available at
-        <ulink
-           url="http://cgit.freedesktop.org/harfbuzz/">cgit.freedesktop.org/harfbuzz</ulink>.
+        <ulink url="https://github.com/harfbuzz/harfbuzz">github.com/harfbuzz/harfbuzz</ulink>.
        See <xref linkend="download" endterm="download.title"/> for
        release tarballs.
       </para>
       <xi:include href="usermanual-install-harfbuzz.xml"/>
       <xi:include href="usermanual-getting-started.xml"/>
       <xi:include href="usermanual-shaping-concepts.xml"/>
+      <xi:include href="usermanual-object-model.xml"/>
       <xi:include href="usermanual-buffers-language-script-and-direction.xml"/>
       <xi:include href="usermanual-fonts-and-faces.xml"/>
-      <xi:include href="usermanual-clusters.xml"/>
       <xi:include href="usermanual-opentype-features.xml"/>
-      <xi:include href="usermanual-glyph-information.xml"/>
+      <xi:include href="usermanual-clusters.xml"/>
+      <xi:include href="usermanual-utilities.xml"/>
   </part>
 
   <part>
       <index id="api-index-full"><title>API Index</title><xi:include href="xml/api-index-full.xml"><xi:fallback /></xi:include></index>
       <index id="deprecated-api-index" role="deprecated"><title>Index of deprecated API</title><xi:include href="xml/api-index-deprecated.xml"><xi:fallback /></xi:include></index>
 
+      <index id="api-index-2-6-0" role="2.6.0"><title>Index of new symbols in 2.6.0</title><xi:include href="xml/api-index-2.6.0.xml"><xi:fallback /></xi:include></index>
+      <index id="api-index-2-5-0" role="2.5.0"><title>Index of new symbols in 2.5.0</title><xi:include href="xml/api-index-2.5.0.xml"><xi:fallback /></xi:include></index>
+      <index id="api-index-2-4-0" role="2.4.0"><title>Index of new symbols in 2.4.0</title><xi:include href="xml/api-index-2.4.0.xml"><xi:fallback /></xi:include></index>
+      <index id="api-index-2-3-0" role="2.3.0"><title>Index of new symbols in 2.3.0</title><xi:include href="xml/api-index-2.3.0.xml"><xi:fallback /></xi:include></index>
       <index id="api-index-2-2-0" role="2.2.0"><title>Index of new symbols in 2.2.0</title><xi:include href="xml/api-index-2.2.0.xml"><xi:fallback /></xi:include></index>
       <index id="api-index-2-1-0" role="2.1.0"><title>Index of new symbols in 2.1.0</title><xi:include href="xml/api-index-2.1.0.xml"><xi:fallback /></xi:include></index>
       <index id="api-index-2-0-0" role="2.0.0"><title>Index of new symbols in 2.0.0</title><xi:include href="xml/api-index-2.0.0.xml"><xi:fallback /></xi:include></index>
       <index id="api-index-1-5-0" role="1.5.0"><title>Index of new symbols in 1.5.0</title><xi:include href="xml/api-index-1.5.0.xml"><xi:fallback /></xi:include></index>
       <index id="api-index-1-4-3" role="1.4.3"><title>Index of new symbols in 1.4.3</title><xi:include href="xml/api-index-1.4.3.xml"><xi:fallback /></xi:include></index>
       <index id="api-index-1-4-2" role="1.4.2"><title>Index of new symbols in 1.4.2</title><xi:include href="xml/api-index-1.4.2.xml"><xi:fallback /></xi:include></index>
-      <index id="api-index-1-4-0" role="1.4.0"><title>Index of new symbols in 1.4.0</title><xi:include href="xml/api-index-1.4.0.xml"><xi:fallback /></xi:include></index>
       <index id="api-index-1-3-3" role="1.3.3"><title>Index of new symbols in 1.3.3</title><xi:include href="xml/api-index-1.3.3.xml"><xi:fallback /></xi:include></index>
       <index id="api-index-1-2-3" role="1.2.3"><title>Index of new symbols in 1.2.3</title><xi:include href="xml/api-index-1.2.3.xml"><xi:fallback /></xi:include></index>
       <index id="api-index-1-1-3" role="1.1.3"><title>Index of new symbols in 1.1.3</title><xi:include href="xml/api-index-1.1.3.xml"><xi:fallback /></xi:include></index>
index 27dc1e2..c625b92 100644 (file)
@@ -1,6 +1,7 @@
 <SUBSECTION Private>
 HB_H_IN
 HB_OT_H_IN
+HB_AAT_H_IN
 </SECTION>
 
 <SECTION>
@@ -179,6 +180,7 @@ HB_BUFFER_SERIALIZE_FLAGS_DEFAULT
 HB_SCRIPT_CANADIAN_ABORIGINAL
 hb_font_funcs_set_glyph_func
 hb_font_get_glyph_func_t
+HB_MATH_GLYPH_PART_FLAG_EXTENDER
 hb_ot_layout_table_choose_script
 hb_ot_layout_table_find_script
 hb_ot_tag_from_language
@@ -195,12 +197,7 @@ HB_UNICODE_MAX_DECOMPOSITION_LEN
 hb_unicode_decompose_compatibility_func_t
 hb_unicode_decompose_compatibility
 hb_unicode_funcs_set_decompose_compatibility_func
-hb_font_funcs_set_glyph_h_kerning_func
 hb_font_funcs_set_glyph_v_kerning_func
-hb_font_get_glyph_h_kerning
-hb_font_get_glyph_h_kerning_func_t
-hb_font_get_glyph_kerning_for_direction
-hb_font_get_glyph_kerning_func_t
 hb_font_get_glyph_v_kerning
 hb_font_get_glyph_v_kerning_func_t
 </SECTION>
@@ -217,6 +214,14 @@ hb_coretext_font_get_ct_font
 </SECTION>
 
 <SECTION>
+<FILE>hb-directwrite</FILE>
+hb_directwrite_face_create
+hb_directwrite_face_get_font_face
+<SUBSECTION Private>
+hb_directwrite_shape_experimental_width
+</SECTION>
+
+<SECTION>
 <FILE>hb-face</FILE>
 hb_face_count
 hb_face_t
@@ -263,6 +268,7 @@ hb_font_funcs_set_glyph_extents_func
 hb_font_funcs_set_glyph_from_name_func
 hb_font_funcs_set_glyph_h_advance_func
 hb_font_funcs_set_glyph_h_advances_func
+hb_font_funcs_set_glyph_h_kerning_func
 hb_font_funcs_set_glyph_h_origin_func
 hb_font_funcs_set_glyph_name_func
 hb_font_funcs_set_glyph_v_advance_func
@@ -292,8 +298,12 @@ hb_font_get_glyph_h_advance
 hb_font_get_glyph_h_advance_func_t
 hb_font_get_glyph_h_advances
 hb_font_get_glyph_h_advances_func_t
+hb_font_get_glyph_h_kerning
+hb_font_get_glyph_h_kerning_func_t
 hb_font_get_glyph_h_origin
 hb_font_get_glyph_h_origin_func_t
+hb_font_get_glyph_kerning_for_direction
+hb_font_get_glyph_kerning_func_t
 hb_font_get_glyph_name
 hb_font_get_glyph_name_func_t
 hb_font_get_glyph_origin_for_direction
@@ -332,6 +342,7 @@ hb_font_set_user_data
 hb_font_set_variations
 hb_font_set_var_coords_design
 hb_font_set_var_coords_normalized
+hb_font_set_var_named_instance
 hb_font_subtract_glyph_origin_for_direction
 hb_font_t
 hb_reference_table_func_t
@@ -360,6 +371,11 @@ hb_ft_font_set_funcs
 </SECTION>
 
 <SECTION>
+<FILE>hb-gdi</FILE>
+hb_gdi_face_create
+</SECTION>
+
+<SECTION>
 <FILE>hb-glib</FILE>
 hb_glib_get_unicode_funcs
 hb_glib_script_from_script
@@ -532,6 +548,7 @@ HB_OT_TAG_GDEF
 HB_OT_TAG_GPOS
 HB_OT_TAG_GSUB
 HB_OT_TAG_JSTF
+hb_ot_layout_baseline_tag_t
 hb_ot_layout_collect_lookups
 hb_ot_layout_collect_features
 hb_ot_layout_feature_get_characters
@@ -539,6 +556,7 @@ hb_ot_layout_feature_get_lookups
 hb_ot_layout_feature_get_name_ids
 hb_ot_layout_feature_with_variations_get_lookups
 hb_ot_layout_get_attach_points
+hb_ot_layout_get_baseline
 hb_ot_layout_get_glyph_class
 hb_ot_layout_get_glyphs_in_class
 hb_ot_layout_get_ligature_carets
@@ -593,6 +611,22 @@ hb_ot_math_get_glyph_assembly
 </SECTION>
 
 <SECTION>
+<FILE>hb-ot-meta</FILE>
+hb_ot_meta_tag_t
+hb_ot_meta_get_entry_tags
+hb_ot_meta_reference_entry
+</SECTION>
+
+<SECTION>
+<FILE>hb-ot-metrics</FILE>
+hb_ot_metrics_tag_t
+hb_ot_metrics_get_position
+hb_ot_metrics_get_variation
+hb_ot_metrics_get_x_variation
+hb_ot_metrics_get_y_variation
+</SECTION>
+
+<SECTION>
 <FILE>hb-ot-shape</FILE>
 hb_ot_shape_glyphs_closure
 </SECTION>
@@ -715,8 +749,6 @@ hb_unicode_script_func_t
 <FILE>hb-uniscribe</FILE>
 hb_uniscribe_font_get_hfont
 hb_uniscribe_font_get_logfontw
-<SUBSECTION Private>
-hb_directwrite_shape_experimental_width
 </SECTION>
 
 <SECTION>
diff --git a/docs/harfbuzz.types b/docs/harfbuzz.types
new file mode 100644 (file)
index 0000000..ef81792
--- /dev/null
@@ -0,0 +1,39 @@
+hb_gobject_aat_layout_feature_selector_get_type
+hb_gobject_aat_layout_feature_type_get_type
+hb_gobject_blob_get_type
+hb_gobject_buffer_cluster_level_get_type
+hb_gobject_buffer_content_type_get_type
+hb_gobject_buffer_diff_flags_get_type
+hb_gobject_buffer_flags_get_type
+hb_gobject_buffer_get_type
+hb_gobject_buffer_serialize_flags_get_type
+hb_gobject_buffer_serialize_format_get_type
+hb_gobject_direction_get_type
+hb_gobject_face_get_type
+hb_gobject_feature_get_type
+hb_gobject_font_funcs_get_type
+hb_gobject_font_get_type
+hb_gobject_glyph_flags_get_type
+hb_gobject_glyph_info_get_type
+hb_gobject_glyph_position_get_type
+hb_gobject_map_get_type
+hb_gobject_memory_mode_get_type
+hb_gobject_ot_color_palette_flags_get_type
+hb_gobject_ot_layout_baseline_tag_get_type
+hb_gobject_ot_layout_glyph_class_get_type
+hb_gobject_ot_math_constant_get_type
+hb_gobject_ot_math_glyph_part_flags_get_type
+hb_gobject_ot_math_glyph_part_get_type
+hb_gobject_ot_math_glyph_variant_get_type
+hb_gobject_ot_math_kern_get_type
+hb_gobject_ot_meta_tag_get_type
+hb_gobject_ot_metrics_tag_get_type
+hb_gobject_ot_var_axis_flags_get_type
+hb_gobject_script_get_type
+hb_gobject_segment_properties_get_type
+hb_gobject_set_get_type
+hb_gobject_shape_plan_get_type
+hb_gobject_unicode_combining_class_get_type
+hb_gobject_unicode_funcs_get_type
+hb_gobject_unicode_general_category_get_type
+hb_gobject_user_data_key_get_type
index 8a50f3f..eede307 100644 (file)
@@ -7,7 +7,7 @@
 <link rel="home" href="index.html" title="HarfBuzz Manual">
 <link rel="up" href="shaping-concepts.html" title="Shaping concepts">
 <link rel="prev" href="graphite-shaping.html" title="Graphite shaping">
-<link rel="next" href="buffers-language-script-and-direction.html" title="Buffers, language, script and direction">
+<link rel="next" href="object-model.html" title="The HarfBuzz object model">
 <meta name="generator" content="GTK-Doc V1.29 (XML mode)">
 <link rel="stylesheet" href="style.css" type="text/css">
 </head>
@@ -17,7 +17,7 @@
 <td><a accesskey="h" href="index.html"><img src="home.png" width="16" height="16" border="0" alt="Home"></a></td>
 <td><a accesskey="u" href="shaping-concepts.html"><img src="up.png" width="16" height="16" border="0" alt="Up"></a></td>
 <td><a accesskey="p" href="graphite-shaping.html"><img src="left.png" width="16" height="16" border="0" alt="Prev"></a></td>
-<td><a accesskey="n" href="buffers-language-script-and-direction.html"><img src="right.png" width="16" height="16" border="0" alt="Next"></a></td>
+<td><a accesskey="n" href="object-model.html"><img src="right.png" width="16" height="16" border="0" alt="Next"></a></td>
 </tr></table>
 <div class="section">
 <div class="titlepage"><div><div><h2 class="title" style="clear: both">
index 07e7dda..e44694b 100644 (file)
 <p>
       Now we have a brand new HarfBuzz buffer. Let's start filling it
       with text! From HarfBuzz's perspective, a buffer is just a stream
-      of Unicode codepoints, but your input string is probably in one of
-      the standard Unicode character encodings (UTF-8, UTF-16, UTF-32)
+      of Unicode code points, but your input string is probably in one of
+      the standard Unicode character encodings (UTF-8, UTF-16, or
+      UTF-32). HarfBuzz provides convenience functions that accept
+      each of these encodings:
+      <code class="function">hb_buffer_add_utf8()</code>,
+      <code class="function">hb_buffer_add_utf16()</code>, and
+      <code class="function">hb_buffer_add_utf32()</code>. Other than the
+      character encoding they accept, they function identically.
+    </p>
+<p>
+      You can add UTF-8 text to a buffer by passing in the text array,
+      the array's length, an offset into the array for the first
+      character to add, and the length of the segment to add:
+    </p>
+<pre class="programlisting">
+    hb_buffer_add_utf8 (hb_buffer_t *buf,
+                    const char *text,
+                    int text_length,
+                    unsigned int item_offset,
+                    int item_length)
+    </pre>
+<p>
+      So, in practice, you can say:
+    </p>
+<pre class="programlisting">
+      hb_buffer_add_utf8(buf, text, strlen(text), 0, strlen(text));
+    </pre>
+<p>
+      This will append your new characters to
+      <em class="parameter"><code>buf</code></em>, not replace its existing
+      contents. Also, note that you can use <code class="literal">-1</code> in
+      place of the first instance of <code class="function">strlen(text)</code>
+      if your text array is NULL-terminated. Similarly, you can also use
+      <code class="literal">-1</code> as the final argument want to add its full
+      contents.
+    </p>
+<p>
+      Whatever start <em class="parameter"><code>item_offset</code></em> and
+      <em class="parameter"><code>item_length</code></em> you provide, HarfBuzz will also
+      attempt to grab the five characters <span class="emphasis"><em>before</em></span>
+      the offset point and the five characters
+      <span class="emphasis"><em>after</em></span> the designated end. These are the
+      before and after "context" segments, which are used internally
+      for HarfBuzz to make shaping decisions. They will not be part of
+      the final output, but they ensure that HarfBuzz's
+      script-specific shaping operations are correct. If there are
+      fewer than five characters available for the before or after
+      contexts, HarfBuzz will just grab what is there.
+    </p>
+<p>
+      For longer text runs, such as full paragraphs, it might be
+      tempting to only add smaller sub-segments to a buffer and
+      shape them in piecemeal fashion. Generally, this is not a good
+      idea, however, because a lot of shaping decisions are
+      dependent on this context information. For example, in Arabic
+      and other connected scripts, HarfBuzz needs to know the code
+      points before and after each character in order to correctly
+      determine which glyph to return.
+    </p>
+<p>
+      The safest approach is to add all of the text available, then
+      use <em class="parameter"><code>item_offset</code></em> and
+      <em class="parameter"><code>item_length</code></em> to indicate which characters you
+      want shaped, so that HarfBuzz has access to any context.
+    </p>
+<p>
+      You can also add Unicode code points directly with
+      <code class="function">hb_buffer_add_codepoints()</code>. The arguments
+      to this function are the same as those for the UTF
+      encodings. But it is particularly important to note that
+      HarfBuzz does not do validity checking on the text that is added
+      to a buffer. Invalid code points will be replaced, but it is up
+      to you to do any deep-sanity checking necessary.
     </p>
 </div>
 <div class="footer">
index 9e3926d..2f9ee96 100644 (file)
 </dt>
 <dd></dd>
 <dt>
-<a class="link" href="harfbuzz-hb-blob.html#hb-blob-t" title="hb_blob_t">hb_blob_t</a>, typedef in <a class="link" href="harfbuzz-hb-blob.html" title="hb-blob">hb-blob</a>
+<a class="link" href="harfbuzz-hb-blob.html#hb-blob-t">hb_blob_t</a>, typedef in <a class="link" href="harfbuzz-hb-blob.html" title="hb-blob">hb-blob</a>
 </dt>
 <dd></dd>
 <dt>
 </dt>
 <dd></dd>
 <dt>
-<a class="link" href="harfbuzz-hb-buffer.html#hb-buffer-t" title="hb_buffer_t">hb_buffer_t</a>, typedef in <a class="link" href="harfbuzz-hb-buffer.html" title="hb-buffer">hb-buffer</a>
+<a class="link" href="harfbuzz-hb-buffer.html#hb-buffer-t">hb_buffer_t</a>, typedef in <a class="link" href="harfbuzz-hb-buffer.html" title="hb-buffer">hb-buffer</a>
 </dt>
 <dd></dd>
 <a name="idxC"></a><h3 class="title">C</h3>
 </dt>
 <dd></dd>
 <dt>
-<a class="link" href="harfbuzz-hb-ot-color.html#hb-color-get-alpha" title="hb_color_get_alpha()">hb_color_get_alpha</a>, macro in <a class="link" href="harfbuzz-hb-ot-color.html" title="hb-ot-color">hb-ot-color</a>
+<a class="link" href="harfbuzz-hb-ot-color.html#hb-color-get-alpha" title="hb_color_get_alpha ()">hb_color_get_alpha</a>, function in <a class="link" href="harfbuzz-hb-ot-color.html" title="hb-ot-color">hb-ot-color</a>
 </dt>
 <dd></dd>
 <dt>
-<a class="link" href="harfbuzz-hb-ot-color.html#hb-color-get-blue" title="hb_color_get_blue()">hb_color_get_blue</a>, macro in <a class="link" href="harfbuzz-hb-ot-color.html" title="hb-ot-color">hb-ot-color</a>
+<a class="link" href="harfbuzz-hb-ot-color.html#hb-color-get-blue" title="hb_color_get_blue ()">hb_color_get_blue</a>, function in <a class="link" href="harfbuzz-hb-ot-color.html" title="hb-ot-color">hb-ot-color</a>
 </dt>
 <dd></dd>
 <dt>
-<a class="link" href="harfbuzz-hb-ot-color.html#hb-color-get-green" title="hb_color_get_green()">hb_color_get_green</a>, macro in <a class="link" href="harfbuzz-hb-ot-color.html" title="hb-ot-color">hb-ot-color</a>
+<a class="link" href="harfbuzz-hb-ot-color.html#hb-color-get-green" title="hb_color_get_green ()">hb_color_get_green</a>, function in <a class="link" href="harfbuzz-hb-ot-color.html" title="hb-ot-color">hb-ot-color</a>
 </dt>
 <dd></dd>
 <dt>
-<a class="link" href="harfbuzz-hb-ot-color.html#hb-color-get-red" title="hb_color_get_red()">hb_color_get_red</a>, macro in <a class="link" href="harfbuzz-hb-ot-color.html" title="hb-ot-color">hb-ot-color</a>
+<a class="link" href="harfbuzz-hb-ot-color.html#hb-color-get-red" title="hb_color_get_red ()">hb_color_get_red</a>, function in <a class="link" href="harfbuzz-hb-ot-color.html" title="hb-ot-color">hb-ot-color</a>
 </dt>
 <dd></dd>
 <dt>
 <a class="link" href="harfbuzz-hb-common.html#hb-direction-to-string" title="hb_direction_to_string ()">hb_direction_to_string</a>, function in <a class="link" href="harfbuzz-hb-common.html" title="hb-common">hb-common</a>
 </dt>
 <dd></dd>
+<dt>
+hb_directwrite_face_create, function in hb-directwrite
+</dt>
+<dd></dd>
+<dt>
+hb_directwrite_face_get_font_face, function in hb-directwrite
+</dt>
+<dd></dd>
 <a name="idxF"></a><h3 class="title">F</h3>
 <dt>
 <a class="link" href="harfbuzz-hb-face.html#hb-face-builder-add-table" title="hb_face_builder_add_table ()">hb_face_builder_add_table</a>, function in <a class="link" href="harfbuzz-hb-face.html" title="hb-face">hb-face</a>
 </dt>
 <dd></dd>
 <dt>
-<a class="link" href="harfbuzz-hb-face.html#hb-face-t" title="hb_face_t">hb_face_t</a>, typedef in <a class="link" href="harfbuzz-hb-face.html" title="hb-face">hb-face</a>
+<a class="link" href="harfbuzz-hb-face.html#hb-face-t">hb_face_t</a>, typedef in <a class="link" href="harfbuzz-hb-face.html" title="hb-face">hb-face</a>
 </dt>
 <dd></dd>
 <dt>
 </dt>
 <dd></dd>
 <dt>
-<a class="link" href="harfbuzz-hb-common.html#hb-feature-t" title="hb_feature_t">hb_feature_t</a>, struct in <a class="link" href="harfbuzz-hb-common.html" title="hb-common">hb-common</a>
+<a class="link" href="harfbuzz-hb-common.html#hb-feature-t-struct" title="hb_feature_t">hb_feature_t</a>, struct in <a class="link" href="harfbuzz-hb-common.html" title="hb-common">hb-common</a>
 </dt>
 <dd></dd>
 <dt>
 </dt>
 <dd></dd>
 <dt>
-<a class="link" href="harfbuzz-hb-deprecated.html#hb-font-funcs-set-glyph-h-kerning-func" title="hb_font_funcs_set_glyph_h_kerning_func ()">hb_font_funcs_set_glyph_h_kerning_func</a>, function in <a class="link" href="harfbuzz-hb-deprecated.html" title="hb-deprecated">hb-deprecated</a>
+<a class="link" href="harfbuzz-hb-font.html#hb-font-funcs-set-glyph-h-kerning-func" title="hb_font_funcs_set_glyph_h_kerning_func ()">hb_font_funcs_set_glyph_h_kerning_func</a>, function in <a class="link" href="harfbuzz-hb-font.html" title="hb-font">hb-font</a>
 </dt>
 <dd></dd>
 <dt>
 </dt>
 <dd></dd>
 <dt>
-<a class="link" href="harfbuzz-hb-font.html#hb-font-funcs-t" title="hb_font_funcs_t">hb_font_funcs_t</a>, typedef in <a class="link" href="harfbuzz-hb-font.html" title="hb-font">hb-font</a>
+<a class="link" href="harfbuzz-hb-font.html#hb-font-funcs-t">hb_font_funcs_t</a>, typedef in <a class="link" href="harfbuzz-hb-font.html" title="hb-font">hb-font</a>
 </dt>
 <dd></dd>
 <dt>
 </dt>
 <dd></dd>
 <dt>
-<a class="link" href="harfbuzz-hb-deprecated.html#hb-font-get-glyph-h-kerning" title="hb_font_get_glyph_h_kerning ()">hb_font_get_glyph_h_kerning</a>, function in <a class="link" href="harfbuzz-hb-deprecated.html" title="hb-deprecated">hb-deprecated</a>
+<a class="link" href="harfbuzz-hb-font.html#hb-font-get-glyph-h-kerning" title="hb_font_get_glyph_h_kerning ()">hb_font_get_glyph_h_kerning</a>, function in <a class="link" href="harfbuzz-hb-font.html" title="hb-font">hb-font</a>
 </dt>
 <dd></dd>
 <dt>
-<a class="link" href="harfbuzz-hb-deprecated.html#hb-font-get-glyph-h-kerning-func-t" title="hb_font_get_glyph_h_kerning_func_t">hb_font_get_glyph_h_kerning_func_t</a>, typedef in <a class="link" href="harfbuzz-hb-deprecated.html" title="hb-deprecated">hb-deprecated</a>
+<a class="link" href="harfbuzz-hb-font.html#hb-font-get-glyph-h-kerning-func-t" title="hb_font_get_glyph_h_kerning_func_t">hb_font_get_glyph_h_kerning_func_t</a>, typedef in <a class="link" href="harfbuzz-hb-font.html" title="hb-font">hb-font</a>
 </dt>
 <dd></dd>
 <dt>
 </dt>
 <dd></dd>
 <dt>
-<a class="link" href="harfbuzz-hb-deprecated.html#hb-font-get-glyph-kerning-for-direction" title="hb_font_get_glyph_kerning_for_direction ()">hb_font_get_glyph_kerning_for_direction</a>, function in <a class="link" href="harfbuzz-hb-deprecated.html" title="hb-deprecated">hb-deprecated</a>
+<a class="link" href="harfbuzz-hb-font.html#hb-font-get-glyph-kerning-for-direction" title="hb_font_get_glyph_kerning_for_direction ()">hb_font_get_glyph_kerning_for_direction</a>, function in <a class="link" href="harfbuzz-hb-font.html" title="hb-font">hb-font</a>
 </dt>
 <dd></dd>
 <dt>
-<a class="link" href="harfbuzz-hb-deprecated.html#hb-font-get-glyph-kerning-func-t" title="hb_font_get_glyph_kerning_func_t ()">hb_font_get_glyph_kerning_func_t</a>, user_function in <a class="link" href="harfbuzz-hb-deprecated.html" title="hb-deprecated">hb-deprecated</a>
+<a class="link" href="harfbuzz-hb-font.html#hb-font-get-glyph-kerning-func-t" title="hb_font_get_glyph_kerning_func_t ()">hb_font_get_glyph_kerning_func_t</a>, user_function in <a class="link" href="harfbuzz-hb-font.html" title="hb-font">hb-font</a>
 </dt>
 <dd></dd>
 <dt>
 </dt>
 <dd></dd>
 <dt>
+<a class="link" href="harfbuzz-hb-font.html#hb-font-get-nominal-glyphs" title="hb_font_get_nominal_glyphs ()">hb_font_get_nominal_glyphs</a>, function in <a class="link" href="harfbuzz-hb-font.html" title="hb-font">hb-font</a>
+</dt>
+<dd></dd>
+<dt>
 <a class="link" href="harfbuzz-hb-font.html#hb-font-get-nominal-glyph-func-t" title="hb_font_get_nominal_glyph_func_t ()">hb_font_get_nominal_glyph_func_t</a>, user_function in <a class="link" href="harfbuzz-hb-font.html" title="hb-font">hb-font</a>
 </dt>
 <dd></dd>
 </dt>
 <dd></dd>
 <dt>
+<a class="link" href="harfbuzz-hb-font.html#hb-font-set-var-named-instance" title="hb_font_set_var_named_instance ()">hb_font_set_var_named_instance</a>, function in <a class="link" href="harfbuzz-hb-font.html" title="hb-font">hb-font</a>
+</dt>
+<dd></dd>
+<dt>
 <a class="link" href="harfbuzz-hb-font.html#hb-font-subtract-glyph-origin-for-direction" title="hb_font_subtract_glyph_origin_for_direction ()">hb_font_subtract_glyph_origin_for_direction</a>, function in <a class="link" href="harfbuzz-hb-font.html" title="hb-font">hb-font</a>
 </dt>
 <dd></dd>
 <dt>
-<a class="link" href="harfbuzz-hb-font.html#hb-font-t" title="hb_font_t">hb_font_t</a>, typedef in <a class="link" href="harfbuzz-hb-font.html" title="hb-font">hb-font</a>
+<a class="link" href="harfbuzz-hb-font.html#hb-font-t">hb_font_t</a>, typedef in <a class="link" href="harfbuzz-hb-font.html" title="hb-font">hb-font</a>
 </dt>
 <dd></dd>
 <dt>
 <dd></dd>
 <a name="idxG"></a><h3 class="title">G</h3>
 <dt>
+hb_gdi_face_create, function in hb-gdi
+</dt>
+<dd></dd>
+<dt>
 <a class="link" href="harfbuzz-hb-glib.html#hb-glib-blob-create" title="hb_glib_blob_create ()">hb_glib_blob_create</a>, function in <a class="link" href="harfbuzz-hb-glib.html" title="hb-glib">hb-glib</a>
 </dt>
 <dd></dd>
 </dt>
 <dd></dd>
 <dt>
-<a class="link" href="harfbuzz-hb-buffer.html#hb-glyph-position-t" title="hb_glyph_position_t">hb_glyph_position_t</a>, struct in <a class="link" href="harfbuzz-hb-buffer.html" title="hb-buffer">hb-buffer</a>
+<a class="link" href="harfbuzz-hb-buffer.html#hb-glyph-position-t-struct" title="hb_glyph_position_t">hb_glyph_position_t</a>, struct in <a class="link" href="harfbuzz-hb-buffer.html" title="hb-buffer">hb-buffer</a>
+</dt>
+<dd></dd>
+<dt>
+<a class="link" href="harfbuzz-hb-gobject.html#hb-gobject-blob-get-type" title="hb_gobject_blob_get_type ()">hb_gobject_blob_get_type</a>, function in <a class="link" href="harfbuzz-hb-gobject.html" title="hb-gobject">hb-gobject</a>
+</dt>
+<dd></dd>
+<dt>
+<a class="link" href="harfbuzz-hb-gobject.html#hb-gobject-buffer-cluster-level-get-type" title="hb_gobject_buffer_cluster_level_get_type ()">hb_gobject_buffer_cluster_level_get_type</a>, function in <a class="link" href="harfbuzz-hb-gobject.html" title="hb-gobject">hb-gobject</a>
+</dt>
+<dd></dd>
+<dt>
+<a class="link" href="harfbuzz-hb-gobject.html#hb-gobject-buffer-content-type-get-type" title="hb_gobject_buffer_content_type_get_type ()">hb_gobject_buffer_content_type_get_type</a>, function in <a class="link" href="harfbuzz-hb-gobject.html" title="hb-gobject">hb-gobject</a>
+</dt>
+<dd></dd>
+<dt>
+<a class="link" href="harfbuzz-hb-gobject.html#hb-gobject-buffer-diff-flags-get-type" title="hb_gobject_buffer_diff_flags_get_type ()">hb_gobject_buffer_diff_flags_get_type</a>, function in <a class="link" href="harfbuzz-hb-gobject.html" title="hb-gobject">hb-gobject</a>
+</dt>
+<dd></dd>
+<dt>
+<a class="link" href="harfbuzz-hb-gobject.html#hb-gobject-buffer-flags-get-type" title="hb_gobject_buffer_flags_get_type ()">hb_gobject_buffer_flags_get_type</a>, function in <a class="link" href="harfbuzz-hb-gobject.html" title="hb-gobject">hb-gobject</a>
+</dt>
+<dd></dd>
+<dt>
+<a class="link" href="harfbuzz-hb-gobject.html#hb-gobject-buffer-get-type" title="hb_gobject_buffer_get_type ()">hb_gobject_buffer_get_type</a>, function in <a class="link" href="harfbuzz-hb-gobject.html" title="hb-gobject">hb-gobject</a>
+</dt>
+<dd></dd>
+<dt>
+<a class="link" href="harfbuzz-hb-gobject.html#hb-gobject-buffer-serialize-flags-get-type" title="hb_gobject_buffer_serialize_flags_get_type ()">hb_gobject_buffer_serialize_flags_get_type</a>, function in <a class="link" href="harfbuzz-hb-gobject.html" title="hb-gobject">hb-gobject</a>
+</dt>
+<dd></dd>
+<dt>
+<a class="link" href="harfbuzz-hb-gobject.html#hb-gobject-buffer-serialize-format-get-type" title="hb_gobject_buffer_serialize_format_get_type ()">hb_gobject_buffer_serialize_format_get_type</a>, function in <a class="link" href="harfbuzz-hb-gobject.html" title="hb-gobject">hb-gobject</a>
+</dt>
+<dd></dd>
+<dt>
+<a class="link" href="harfbuzz-hb-gobject.html#hb-gobject-direction-get-type" title="hb_gobject_direction_get_type ()">hb_gobject_direction_get_type</a>, function in <a class="link" href="harfbuzz-hb-gobject.html" title="hb-gobject">hb-gobject</a>
+</dt>
+<dd></dd>
+<dt>
+<a class="link" href="harfbuzz-hb-gobject.html#hb-gobject-face-get-type" title="hb_gobject_face_get_type ()">hb_gobject_face_get_type</a>, function in <a class="link" href="harfbuzz-hb-gobject.html" title="hb-gobject">hb-gobject</a>
+</dt>
+<dd></dd>
+<dt>
+<a class="link" href="harfbuzz-hb-gobject.html#hb-gobject-feature-get-type" title="hb_gobject_feature_get_type ()">hb_gobject_feature_get_type</a>, function in <a class="link" href="harfbuzz-hb-gobject.html" title="hb-gobject">hb-gobject</a>
+</dt>
+<dd></dd>
+<dt>
+<a class="link" href="harfbuzz-hb-gobject.html#hb-gobject-font-funcs-get-type" title="hb_gobject_font_funcs_get_type ()">hb_gobject_font_funcs_get_type</a>, function in <a class="link" href="harfbuzz-hb-gobject.html" title="hb-gobject">hb-gobject</a>
+</dt>
+<dd></dd>
+<dt>
+<a class="link" href="harfbuzz-hb-gobject.html#hb-gobject-font-get-type" title="hb_gobject_font_get_type ()">hb_gobject_font_get_type</a>, function in <a class="link" href="harfbuzz-hb-gobject.html" title="hb-gobject">hb-gobject</a>
+</dt>
+<dd></dd>
+<dt>
+<a class="link" href="harfbuzz-hb-gobject.html#hb-gobject-glyph-flags-get-type" title="hb_gobject_glyph_flags_get_type ()">hb_gobject_glyph_flags_get_type</a>, function in <a class="link" href="harfbuzz-hb-gobject.html" title="hb-gobject">hb-gobject</a>
+</dt>
+<dd></dd>
+<dt>
+<a class="link" href="harfbuzz-hb-gobject.html#hb-gobject-glyph-info-get-type" title="hb_gobject_glyph_info_get_type ()">hb_gobject_glyph_info_get_type</a>, function in <a class="link" href="harfbuzz-hb-gobject.html" title="hb-gobject">hb-gobject</a>
+</dt>
+<dd></dd>
+<dt>
+<a class="link" href="harfbuzz-hb-gobject.html#hb-gobject-glyph-position-get-type" title="hb_gobject_glyph_position_get_type ()">hb_gobject_glyph_position_get_type</a>, function in <a class="link" href="harfbuzz-hb-gobject.html" title="hb-gobject">hb-gobject</a>
+</dt>
+<dd></dd>
+<dt>
+<a class="link" href="harfbuzz-hb-gobject.html#hb-gobject-map-get-type" title="hb_gobject_map_get_type ()">hb_gobject_map_get_type</a>, function in <a class="link" href="harfbuzz-hb-gobject.html" title="hb-gobject">hb-gobject</a>
+</dt>
+<dd></dd>
+<dt>
+<a class="link" href="harfbuzz-hb-gobject.html#hb-gobject-memory-mode-get-type" title="hb_gobject_memory_mode_get_type ()">hb_gobject_memory_mode_get_type</a>, function in <a class="link" href="harfbuzz-hb-gobject.html" title="hb-gobject">hb-gobject</a>
+</dt>
+<dd></dd>
+<dt>
+<a class="link" href="harfbuzz-hb-gobject.html#hb-gobject-ot-color-palette-flags-get-type" title="hb_gobject_ot_color_palette_flags_get_type ()">hb_gobject_ot_color_palette_flags_get_type</a>, function in <a class="link" href="harfbuzz-hb-gobject.html" title="hb-gobject">hb-gobject</a>
+</dt>
+<dd></dd>
+<dt>
+<a class="link" href="harfbuzz-hb-gobject.html#hb-gobject-ot-layout-glyph-class-get-type" title="hb_gobject_ot_layout_glyph_class_get_type ()">hb_gobject_ot_layout_glyph_class_get_type</a>, function in <a class="link" href="harfbuzz-hb-gobject.html" title="hb-gobject">hb-gobject</a>
+</dt>
+<dd></dd>
+<dt>
+<a class="link" href="harfbuzz-hb-gobject.html#hb-gobject-ot-math-constant-get-type" title="hb_gobject_ot_math_constant_get_type ()">hb_gobject_ot_math_constant_get_type</a>, function in <a class="link" href="harfbuzz-hb-gobject.html" title="hb-gobject">hb-gobject</a>
+</dt>
+<dd></dd>
+<dt>
+<a class="link" href="harfbuzz-hb-gobject.html#hb-gobject-ot-math-glyph-part-flags-get-type" title="hb_gobject_ot_math_glyph_part_flags_get_type ()">hb_gobject_ot_math_glyph_part_flags_get_type</a>, function in <a class="link" href="harfbuzz-hb-gobject.html" title="hb-gobject">hb-gobject</a>
+</dt>
+<dd></dd>
+<dt>
+<a class="link" href="harfbuzz-hb-gobject.html#hb-gobject-ot-math-glyph-part-get-type" title="hb_gobject_ot_math_glyph_part_get_type ()">hb_gobject_ot_math_glyph_part_get_type</a>, function in <a class="link" href="harfbuzz-hb-gobject.html" title="hb-gobject">hb-gobject</a>
+</dt>
+<dd></dd>
+<dt>
+<a class="link" href="harfbuzz-hb-gobject.html#hb-gobject-ot-math-glyph-variant-get-type" title="hb_gobject_ot_math_glyph_variant_get_type ()">hb_gobject_ot_math_glyph_variant_get_type</a>, function in <a class="link" href="harfbuzz-hb-gobject.html" title="hb-gobject">hb-gobject</a>
+</dt>
+<dd></dd>
+<dt>
+<a class="link" href="harfbuzz-hb-gobject.html#hb-gobject-ot-math-kern-get-type" title="hb_gobject_ot_math_kern_get_type ()">hb_gobject_ot_math_kern_get_type</a>, function in <a class="link" href="harfbuzz-hb-gobject.html" title="hb-gobject">hb-gobject</a>
+</dt>
+<dd></dd>
+<dt>
+<a class="link" href="harfbuzz-hb-gobject.html#hb-gobject-script-get-type" title="hb_gobject_script_get_type ()">hb_gobject_script_get_type</a>, function in <a class="link" href="harfbuzz-hb-gobject.html" title="hb-gobject">hb-gobject</a>
+</dt>
+<dd></dd>
+<dt>
+<a class="link" href="harfbuzz-hb-gobject.html#hb-gobject-segment-properties-get-type" title="hb_gobject_segment_properties_get_type ()">hb_gobject_segment_properties_get_type</a>, function in <a class="link" href="harfbuzz-hb-gobject.html" title="hb-gobject">hb-gobject</a>
+</dt>
+<dd></dd>
+<dt>
+<a class="link" href="harfbuzz-hb-gobject.html#hb-gobject-set-get-type" title="hb_gobject_set_get_type ()">hb_gobject_set_get_type</a>, function in <a class="link" href="harfbuzz-hb-gobject.html" title="hb-gobject">hb-gobject</a>
+</dt>
+<dd></dd>
+<dt>
+<a class="link" href="harfbuzz-hb-gobject.html#hb-gobject-shape-plan-get-type" title="hb_gobject_shape_plan_get_type ()">hb_gobject_shape_plan_get_type</a>, function in <a class="link" href="harfbuzz-hb-gobject.html" title="hb-gobject">hb-gobject</a>
+</dt>
+<dd></dd>
+<dt>
+<a class="link" href="harfbuzz-hb-gobject.html#HB-GOBJECT-TYPE-BLOB:CAPS" title="HB_GOBJECT_TYPE_BLOB">HB_GOBJECT_TYPE_BLOB</a>, macro in <a class="link" href="harfbuzz-hb-gobject.html" title="hb-gobject">hb-gobject</a>
+</dt>
+<dd></dd>
+<dt>
+<a class="link" href="harfbuzz-hb-gobject.html#HB-GOBJECT-TYPE-BUFFER:CAPS" title="HB_GOBJECT_TYPE_BUFFER">HB_GOBJECT_TYPE_BUFFER</a>, macro in <a class="link" href="harfbuzz-hb-gobject.html" title="hb-gobject">hb-gobject</a>
+</dt>
+<dd></dd>
+<dt>
+<a class="link" href="harfbuzz-hb-gobject.html#HB-GOBJECT-TYPE-BUFFER-CLUSTER-LEVEL:CAPS" title="HB_GOBJECT_TYPE_BUFFER_CLUSTER_LEVEL">HB_GOBJECT_TYPE_BUFFER_CLUSTER_LEVEL</a>, macro in <a class="link" href="harfbuzz-hb-gobject.html" title="hb-gobject">hb-gobject</a>
+</dt>
+<dd></dd>
+<dt>
+<a class="link" href="harfbuzz-hb-gobject.html#HB-GOBJECT-TYPE-BUFFER-CONTENT-TYPE:CAPS" title="HB_GOBJECT_TYPE_BUFFER_CONTENT_TYPE">HB_GOBJECT_TYPE_BUFFER_CONTENT_TYPE</a>, macro in <a class="link" href="harfbuzz-hb-gobject.html" title="hb-gobject">hb-gobject</a>
+</dt>
+<dd></dd>
+<dt>
+<a class="link" href="harfbuzz-hb-gobject.html#HB-GOBJECT-TYPE-BUFFER-DIFF-FLAGS:CAPS" title="HB_GOBJECT_TYPE_BUFFER_DIFF_FLAGS">HB_GOBJECT_TYPE_BUFFER_DIFF_FLAGS</a>, macro in <a class="link" href="harfbuzz-hb-gobject.html" title="hb-gobject">hb-gobject</a>
+</dt>
+<dd></dd>
+<dt>
+<a class="link" href="harfbuzz-hb-gobject.html#HB-GOBJECT-TYPE-BUFFER-FLAGS:CAPS" title="HB_GOBJECT_TYPE_BUFFER_FLAGS">HB_GOBJECT_TYPE_BUFFER_FLAGS</a>, macro in <a class="link" href="harfbuzz-hb-gobject.html" title="hb-gobject">hb-gobject</a>
+</dt>
+<dd></dd>
+<dt>
+<a class="link" href="harfbuzz-hb-gobject.html#HB-GOBJECT-TYPE-BUFFER-SERIALIZE-FLAGS:CAPS" title="HB_GOBJECT_TYPE_BUFFER_SERIALIZE_FLAGS">HB_GOBJECT_TYPE_BUFFER_SERIALIZE_FLAGS</a>, macro in <a class="link" href="harfbuzz-hb-gobject.html" title="hb-gobject">hb-gobject</a>
+</dt>
+<dd></dd>
+<dt>
+<a class="link" href="harfbuzz-hb-gobject.html#HB-GOBJECT-TYPE-BUFFER-SERIALIZE-FORMAT:CAPS" title="HB_GOBJECT_TYPE_BUFFER_SERIALIZE_FORMAT">HB_GOBJECT_TYPE_BUFFER_SERIALIZE_FORMAT</a>, macro in <a class="link" href="harfbuzz-hb-gobject.html" title="hb-gobject">hb-gobject</a>
+</dt>
+<dd></dd>
+<dt>
+<a class="link" href="harfbuzz-hb-gobject.html#HB-GOBJECT-TYPE-DIRECTION:CAPS" title="HB_GOBJECT_TYPE_DIRECTION">HB_GOBJECT_TYPE_DIRECTION</a>, macro in <a class="link" href="harfbuzz-hb-gobject.html" title="hb-gobject">hb-gobject</a>
+</dt>
+<dd></dd>
+<dt>
+<a class="link" href="harfbuzz-hb-gobject.html#HB-GOBJECT-TYPE-FACE:CAPS" title="HB_GOBJECT_TYPE_FACE">HB_GOBJECT_TYPE_FACE</a>, macro in <a class="link" href="harfbuzz-hb-gobject.html" title="hb-gobject">hb-gobject</a>
+</dt>
+<dd></dd>
+<dt>
+<a class="link" href="harfbuzz-hb-gobject.html#HB-GOBJECT-TYPE-FEATURE:CAPS" title="HB_GOBJECT_TYPE_FEATURE">HB_GOBJECT_TYPE_FEATURE</a>, macro in <a class="link" href="harfbuzz-hb-gobject.html" title="hb-gobject">hb-gobject</a>
+</dt>
+<dd></dd>
+<dt>
+<a class="link" href="harfbuzz-hb-gobject.html#HB-GOBJECT-TYPE-FONT:CAPS" title="HB_GOBJECT_TYPE_FONT">HB_GOBJECT_TYPE_FONT</a>, macro in <a class="link" href="harfbuzz-hb-gobject.html" title="hb-gobject">hb-gobject</a>
+</dt>
+<dd></dd>
+<dt>
+<a class="link" href="harfbuzz-hb-gobject.html#HB-GOBJECT-TYPE-FONT-FUNCS:CAPS" title="HB_GOBJECT_TYPE_FONT_FUNCS">HB_GOBJECT_TYPE_FONT_FUNCS</a>, macro in <a class="link" href="harfbuzz-hb-gobject.html" title="hb-gobject">hb-gobject</a>
+</dt>
+<dd></dd>
+<dt>
+<a class="link" href="harfbuzz-hb-gobject.html#HB-GOBJECT-TYPE-GLYPH-FLAGS:CAPS" title="HB_GOBJECT_TYPE_GLYPH_FLAGS">HB_GOBJECT_TYPE_GLYPH_FLAGS</a>, macro in <a class="link" href="harfbuzz-hb-gobject.html" title="hb-gobject">hb-gobject</a>
+</dt>
+<dd></dd>
+<dt>
+<a class="link" href="harfbuzz-hb-gobject.html#HB-GOBJECT-TYPE-GLYPH-INFO:CAPS" title="HB_GOBJECT_TYPE_GLYPH_INFO">HB_GOBJECT_TYPE_GLYPH_INFO</a>, macro in <a class="link" href="harfbuzz-hb-gobject.html" title="hb-gobject">hb-gobject</a>
+</dt>
+<dd></dd>
+<dt>
+<a class="link" href="harfbuzz-hb-gobject.html#HB-GOBJECT-TYPE-GLYPH-POSITION:CAPS" title="HB_GOBJECT_TYPE_GLYPH_POSITION">HB_GOBJECT_TYPE_GLYPH_POSITION</a>, macro in <a class="link" href="harfbuzz-hb-gobject.html" title="hb-gobject">hb-gobject</a>
+</dt>
+<dd></dd>
+<dt>
+<a class="link" href="harfbuzz-hb-gobject.html#HB-GOBJECT-TYPE-MAP:CAPS" title="HB_GOBJECT_TYPE_MAP">HB_GOBJECT_TYPE_MAP</a>, macro in <a class="link" href="harfbuzz-hb-gobject.html" title="hb-gobject">hb-gobject</a>
+</dt>
+<dd></dd>
+<dt>
+<a class="link" href="harfbuzz-hb-gobject.html#HB-GOBJECT-TYPE-MEMORY-MODE:CAPS" title="HB_GOBJECT_TYPE_MEMORY_MODE">HB_GOBJECT_TYPE_MEMORY_MODE</a>, macro in <a class="link" href="harfbuzz-hb-gobject.html" title="hb-gobject">hb-gobject</a>
+</dt>
+<dd></dd>
+<dt>
+<a class="link" href="harfbuzz-hb-gobject.html#HB-GOBJECT-TYPE-OT-COLOR-PALETTE-FLAGS:CAPS" title="HB_GOBJECT_TYPE_OT_COLOR_PALETTE_FLAGS">HB_GOBJECT_TYPE_OT_COLOR_PALETTE_FLAGS</a>, macro in <a class="link" href="harfbuzz-hb-gobject.html" title="hb-gobject">hb-gobject</a>
+</dt>
+<dd></dd>
+<dt>
+<a class="link" href="harfbuzz-hb-gobject.html#HB-GOBJECT-TYPE-OT-LAYOUT-GLYPH-CLASS:CAPS" title="HB_GOBJECT_TYPE_OT_LAYOUT_GLYPH_CLASS">HB_GOBJECT_TYPE_OT_LAYOUT_GLYPH_CLASS</a>, macro in <a class="link" href="harfbuzz-hb-gobject.html" title="hb-gobject">hb-gobject</a>
+</dt>
+<dd></dd>
+<dt>
+<a class="link" href="harfbuzz-hb-gobject.html#HB-GOBJECT-TYPE-OT-MATH-CONSTANT:CAPS" title="HB_GOBJECT_TYPE_OT_MATH_CONSTANT">HB_GOBJECT_TYPE_OT_MATH_CONSTANT</a>, macro in <a class="link" href="harfbuzz-hb-gobject.html" title="hb-gobject">hb-gobject</a>
+</dt>
+<dd></dd>
+<dt>
+<a class="link" href="harfbuzz-hb-gobject.html#HB-GOBJECT-TYPE-OT-MATH-GLYPH-PART:CAPS" title="HB_GOBJECT_TYPE_OT_MATH_GLYPH_PART">HB_GOBJECT_TYPE_OT_MATH_GLYPH_PART</a>, macro in <a class="link" href="harfbuzz-hb-gobject.html" title="hb-gobject">hb-gobject</a>
+</dt>
+<dd></dd>
+<dt>
+<a class="link" href="harfbuzz-hb-gobject.html#HB-GOBJECT-TYPE-OT-MATH-GLYPH-PART-FLAGS:CAPS" title="HB_GOBJECT_TYPE_OT_MATH_GLYPH_PART_FLAGS">HB_GOBJECT_TYPE_OT_MATH_GLYPH_PART_FLAGS</a>, macro in <a class="link" href="harfbuzz-hb-gobject.html" title="hb-gobject">hb-gobject</a>
+</dt>
+<dd></dd>
+<dt>
+<a class="link" href="harfbuzz-hb-gobject.html#HB-GOBJECT-TYPE-OT-MATH-GLYPH-VARIANT:CAPS" title="HB_GOBJECT_TYPE_OT_MATH_GLYPH_VARIANT">HB_GOBJECT_TYPE_OT_MATH_GLYPH_VARIANT</a>, macro in <a class="link" href="harfbuzz-hb-gobject.html" title="hb-gobject">hb-gobject</a>
+</dt>
+<dd></dd>
+<dt>
+<a class="link" href="harfbuzz-hb-gobject.html#HB-GOBJECT-TYPE-OT-MATH-KERN:CAPS" title="HB_GOBJECT_TYPE_OT_MATH_KERN">HB_GOBJECT_TYPE_OT_MATH_KERN</a>, macro in <a class="link" href="harfbuzz-hb-gobject.html" title="hb-gobject">hb-gobject</a>
+</dt>
+<dd></dd>
+<dt>
+<a class="link" href="harfbuzz-hb-gobject.html#HB-GOBJECT-TYPE-SCRIPT:CAPS" title="HB_GOBJECT_TYPE_SCRIPT">HB_GOBJECT_TYPE_SCRIPT</a>, macro in <a class="link" href="harfbuzz-hb-gobject.html" title="hb-gobject">hb-gobject</a>
+</dt>
+<dd></dd>
+<dt>
+<a class="link" href="harfbuzz-hb-gobject.html#HB-GOBJECT-TYPE-SEGMENT-PROPERTIES:CAPS" title="HB_GOBJECT_TYPE_SEGMENT_PROPERTIES">HB_GOBJECT_TYPE_SEGMENT_PROPERTIES</a>, macro in <a class="link" href="harfbuzz-hb-gobject.html" title="hb-gobject">hb-gobject</a>
+</dt>
+<dd></dd>
+<dt>
+<a class="link" href="harfbuzz-hb-gobject.html#HB-GOBJECT-TYPE-SET:CAPS" title="HB_GOBJECT_TYPE_SET">HB_GOBJECT_TYPE_SET</a>, macro in <a class="link" href="harfbuzz-hb-gobject.html" title="hb-gobject">hb-gobject</a>
+</dt>
+<dd></dd>
+<dt>
+<a class="link" href="harfbuzz-hb-gobject.html#HB-GOBJECT-TYPE-SHAPE-PLAN:CAPS" title="HB_GOBJECT_TYPE_SHAPE_PLAN">HB_GOBJECT_TYPE_SHAPE_PLAN</a>, macro in <a class="link" href="harfbuzz-hb-gobject.html" title="hb-gobject">hb-gobject</a>
+</dt>
+<dd></dd>
+<dt>
+<a class="link" href="harfbuzz-hb-gobject.html#HB-GOBJECT-TYPE-UNICODE-COMBINING-CLASS:CAPS" title="HB_GOBJECT_TYPE_UNICODE_COMBINING_CLASS">HB_GOBJECT_TYPE_UNICODE_COMBINING_CLASS</a>, macro in <a class="link" href="harfbuzz-hb-gobject.html" title="hb-gobject">hb-gobject</a>
+</dt>
+<dd></dd>
+<dt>
+<a class="link" href="harfbuzz-hb-gobject.html#HB-GOBJECT-TYPE-UNICODE-FUNCS:CAPS" title="HB_GOBJECT_TYPE_UNICODE_FUNCS">HB_GOBJECT_TYPE_UNICODE_FUNCS</a>, macro in <a class="link" href="harfbuzz-hb-gobject.html" title="hb-gobject">hb-gobject</a>
+</dt>
+<dd></dd>
+<dt>
+<a class="link" href="harfbuzz-hb-gobject.html#HB-GOBJECT-TYPE-UNICODE-GENERAL-CATEGORY:CAPS" title="HB_GOBJECT_TYPE_UNICODE_GENERAL_CATEGORY">HB_GOBJECT_TYPE_UNICODE_GENERAL_CATEGORY</a>, macro in <a class="link" href="harfbuzz-hb-gobject.html" title="hb-gobject">hb-gobject</a>
+</dt>
+<dd></dd>
+<dt>
+<a class="link" href="harfbuzz-hb-gobject.html#HB-GOBJECT-TYPE-USER-DATA-KEY:CAPS" title="HB_GOBJECT_TYPE_USER_DATA_KEY">HB_GOBJECT_TYPE_USER_DATA_KEY</a>, macro in <a class="link" href="harfbuzz-hb-gobject.html" title="hb-gobject">hb-gobject</a>
+</dt>
+<dd></dd>
+<dt>
+<a class="link" href="harfbuzz-hb-gobject.html#hb-gobject-unicode-combining-class-get-type" title="hb_gobject_unicode_combining_class_get_type ()">hb_gobject_unicode_combining_class_get_type</a>, function in <a class="link" href="harfbuzz-hb-gobject.html" title="hb-gobject">hb-gobject</a>
+</dt>
+<dd></dd>
+<dt>
+<a class="link" href="harfbuzz-hb-gobject.html#hb-gobject-unicode-funcs-get-type" title="hb_gobject_unicode_funcs_get_type ()">hb_gobject_unicode_funcs_get_type</a>, function in <a class="link" href="harfbuzz-hb-gobject.html" title="hb-gobject">hb-gobject</a>
+</dt>
+<dd></dd>
+<dt>
+<a class="link" href="harfbuzz-hb-gobject.html#hb-gobject-unicode-general-category-get-type" title="hb_gobject_unicode_general_category_get_type ()">hb_gobject_unicode_general_category_get_type</a>, function in <a class="link" href="harfbuzz-hb-gobject.html" title="hb-gobject">hb-gobject</a>
+</dt>
+<dd></dd>
+<dt>
+<a class="link" href="harfbuzz-hb-gobject.html#hb-gobject-user-data-key-get-type" title="hb_gobject_user_data_key_get_type ()">hb_gobject_user_data_key_get_type</a>, function in <a class="link" href="harfbuzz-hb-gobject.html" title="hb-gobject">hb-gobject</a>
 </dt>
 <dd></dd>
 <dt>
 </dt>
 <dd></dd>
 <dt>
-<a class="link" href="harfbuzz-hb-map.html#hb-map-t" title="hb_map_t">hb_map_t</a>, typedef in <a class="link" href="harfbuzz-hb-map.html" title="hb-map">hb-map</a>
+<a class="link" href="harfbuzz-hb-map.html#hb-map-t">hb_map_t</a>, typedef in <a class="link" href="harfbuzz-hb-map.html" title="hb-map">hb-map</a>
 </dt>
 <dd></dd>
 <dt>
 </dt>
 <dd></dd>
 <dt>
+<a class="link" href="harfbuzz-hb-deprecated.html#HB-MATH-GLYPH-PART-FLAG-EXTENDER:CAPS" title="HB_MATH_GLYPH_PART_FLAG_EXTENDER">HB_MATH_GLYPH_PART_FLAG_EXTENDER</a>, macro in <a class="link" href="harfbuzz-hb-deprecated.html" title="hb-deprecated">hb-deprecated</a>
+</dt>
+<dd></dd>
+<dt>
 <a class="link" href="harfbuzz-hb-blob.html#hb-memory-mode-t" title="enum hb_memory_mode_t">hb_memory_mode_t</a>, enum in <a class="link" href="harfbuzz-hb-blob.html" title="hb-blob">hb-blob</a>
 </dt>
 <dd></dd>
 </dt>
 <dd></dd>
 <dt>
+<a class="link" href="harfbuzz-hb-ot-layout.html#hb-ot-layout-baseline-tag-t" title="enum hb_ot_layout_baseline_tag_t">hb_ot_layout_baseline_tag_t</a>, enum in <a class="link" href="harfbuzz-hb-ot-layout.html" title="hb-ot-layout">hb-ot-layout</a>
+</dt>
+<dd></dd>
+<dt>
 <a class="link" href="harfbuzz-hb-ot-layout.html#hb-ot-layout-collect-features" title="hb_ot_layout_collect_features ()">hb_ot_layout_collect_features</a>, function in <a class="link" href="harfbuzz-hb-ot-layout.html" title="hb-ot-layout">hb-ot-layout</a>
 </dt>
 <dd></dd>
 </dt>
 <dd></dd>
 <dt>
+<a class="link" href="harfbuzz-hb-ot-layout.html#hb-ot-layout-get-baseline" title="hb_ot_layout_get_baseline ()">hb_ot_layout_get_baseline</a>, function in <a class="link" href="harfbuzz-hb-ot-layout.html" title="hb-ot-layout">hb-ot-layout</a>
+</dt>
+<dd></dd>
+<dt>
 <a class="link" href="harfbuzz-hb-ot-layout.html#hb-ot-layout-get-glyphs-in-class" title="hb_ot_layout_get_glyphs_in_class ()">hb_ot_layout_get_glyphs_in_class</a>, function in <a class="link" href="harfbuzz-hb-ot-layout.html" title="hb-ot-layout">hb-ot-layout</a>
 </dt>
 <dd></dd>
 </dt>
 <dd></dd>
 <dt>
-<a class="link" href="harfbuzz-hb-ot-math.html#hb-ot-math-glyph-part-t" title="hb_ot_math_glyph_part_t">hb_ot_math_glyph_part_t</a>, struct in <a class="link" href="harfbuzz-hb-ot-math.html" title="hb-ot-math">hb-ot-math</a>
+<a class="link" href="harfbuzz-hb-ot-math.html#hb-ot-math-glyph-part-t-struct" title="hb_ot_math_glyph_part_t">hb_ot_math_glyph_part_t</a>, struct in <a class="link" href="harfbuzz-hb-ot-math.html" title="hb-ot-math">hb-ot-math</a>
 </dt>
 <dd></dd>
 <dt>
-<a class="link" href="harfbuzz-hb-ot-math.html#hb-ot-math-glyph-variant-t" title="hb_ot_math_glyph_variant_t">hb_ot_math_glyph_variant_t</a>, struct in <a class="link" href="harfbuzz-hb-ot-math.html" title="hb-ot-math">hb-ot-math</a>
+<a class="link" href="harfbuzz-hb-ot-math.html#hb-ot-math-glyph-variant-t-struct" title="hb_ot_math_glyph_variant_t">hb_ot_math_glyph_variant_t</a>, struct in <a class="link" href="harfbuzz-hb-ot-math.html" title="hb-ot-math">hb-ot-math</a>
 </dt>
 <dd></dd>
 <dt>
 </dt>
 <dd></dd>
 <dt>
+hb_ot_meta_get_entry_tags, function in hb-ot-meta
+</dt>
+<dd></dd>
+<dt>
+hb_ot_meta_reference_entry, function in hb-ot-meta
+</dt>
+<dd></dd>
+<dt>
+hb_ot_meta_tag_t, enum in hb-ot-meta
+</dt>
+<dd></dd>
+<dt>
+hb_ot_metrics_get_position, function in hb-ot-metrics
+</dt>
+<dd></dd>
+<dt>
+hb_ot_metrics_get_variation, function in hb-ot-metrics
+</dt>
+<dd></dd>
+<dt>
+hb_ot_metrics_get_x_variation, function in hb-ot-metrics
+</dt>
+<dd></dd>
+<dt>
+hb_ot_metrics_get_y_variation, function in hb-ot-metrics
+</dt>
+<dd></dd>
+<dt>
+hb_ot_metrics_tag_t, enum in hb-ot-metrics
+</dt>
+<dd></dd>
+<dt>
 <a class="link" href="harfbuzz-hb-ot-name.html#hb-ot-name-get-utf16" title="hb_ot_name_get_utf16 ()">hb_ot_name_get_utf16</a>, function in <a class="link" href="harfbuzz-hb-ot-name.html" title="hb-ot-name">hb-ot-name</a>
 </dt>
 <dd></dd>
 </dt>
 <dd></dd>
 <dt>
-<a class="link" href="harfbuzz-hb-buffer.html#hb-segment-properties-t" title="hb_segment_properties_t">hb_segment_properties_t</a>, struct in <a class="link" href="harfbuzz-hb-buffer.html" title="hb-buffer">hb-buffer</a>
+<a class="link" href="harfbuzz-hb-buffer.html#hb-segment-properties-t-struct" title="hb_segment_properties_t">hb_segment_properties_t</a>, struct in <a class="link" href="harfbuzz-hb-buffer.html" title="hb-buffer">hb-buffer</a>
 </dt>
 <dd></dd>
 <dt>
 </dt>
 <dd></dd>
 <dt>
-<a class="link" href="harfbuzz-hb-set.html#hb-set-t" title="hb_set_t">hb_set_t</a>, typedef in <a class="link" href="harfbuzz-hb-set.html" title="hb-set">hb-set</a>
+<a class="link" href="harfbuzz-hb-set.html#hb-set-t">hb_set_t</a>, typedef in <a class="link" href="harfbuzz-hb-set.html" title="hb-set">hb-set</a>
 </dt>
 <dd></dd>
 <dt>
 </dt>
 <dd></dd>
 <dt>
-<a class="link" href="harfbuzz-hb-shape-plan.html#hb-shape-plan-t" title="hb_shape_plan_t">hb_shape_plan_t</a>, typedef in <a class="link" href="harfbuzz-hb-shape-plan.html" title="hb-shape-plan">hb-shape-plan</a>
+<a class="link" href="harfbuzz-hb-shape-plan.html#hb-shape-plan-t">hb_shape_plan_t</a>, typedef in <a class="link" href="harfbuzz-hb-shape-plan.html" title="hb-shape-plan">hb-shape-plan</a>
 </dt>
 <dd></dd>
 <a name="idxT"></a><h3 class="title">T</h3>
 </dt>
 <dd></dd>
 <dt>
-<a class="link" href="harfbuzz-hb-unicode.html#hb-unicode-funcs-t" title="hb_unicode_funcs_t">hb_unicode_funcs_t</a>, typedef in <a class="link" href="harfbuzz-hb-unicode.html" title="hb-unicode">hb-unicode</a>
+<a class="link" href="harfbuzz-hb-unicode.html#hb-unicode-funcs-t">hb_unicode_funcs_t</a>, typedef in <a class="link" href="harfbuzz-hb-unicode.html" title="hb-unicode">hb-unicode</a>
 </dt>
 <dd></dd>
 <dt>
 </dt>
 <dd></dd>
 <dt>
-<a class="link" href="harfbuzz-hb-common.html#hb-user-data-key-t" title="hb_user_data_key_t">hb_user_data_key_t</a>, struct in <a class="link" href="harfbuzz-hb-common.html" title="hb-common">hb-common</a>
+<a class="link" href="harfbuzz-hb-common.html#hb-user-data-key-t-struct" title="hb_user_data_key_t">hb_user_data_key_t</a>, struct in <a class="link" href="harfbuzz-hb-common.html" title="hb-common">hb-common</a>
 </dt>
 <dd></dd>
 <a name="idxV"></a><h3 class="title">V</h3>
index 57f2f59..2f0aca5 100644 (file)
@@ -6,7 +6,7 @@
 <meta name="generator" content="DocBook XSL Stylesheets Vsnapshot">
 <link rel="home" href="index.html" title="HarfBuzz Manual">
 <link rel="up" href="pt01.html" title="Part I. User's manual">
-<link rel="prev" href="aat-shaping.html" title="AAT shaping">
+<link rel="prev" href="object-model-blobs.html" title="Blobs">
 <link rel="next" href="adding-text-to-the-buffer.html" title="Adding text to the buffer">
 <meta name="generator" content="GTK-Doc V1.29 (XML mode)">
 <link rel="stylesheet" href="style.css" type="text/css">
@@ -16,7 +16,7 @@
 <td width="100%" align="left" class="shortcuts"></td>
 <td><a accesskey="h" href="index.html"><img src="home.png" width="16" height="16" border="0" alt="Home"></a></td>
 <td><a accesskey="u" href="pt01.html"><img src="up.png" width="16" height="16" border="0" alt="Up"></a></td>
-<td><a accesskey="p" href="aat-shaping.html"><img src="left.png" width="16" height="16" border="0" alt="Prev"></a></td>
+<td><a accesskey="p" href="object-model-blobs.html"><img src="left.png" width="16" height="16" border="0" alt="Prev"></a></td>
 <td><a accesskey="n" href="adding-text-to-the-buffer.html"><img src="right.png" width="16" height="16" border="0" alt="Next"></a></td>
 </tr></table>
 <div class="chapter">
 <dt><span class="section"><a href="buffers-language-script-and-direction.html#creating-and-destroying-buffers">Creating and destroying buffers</a></span></dt>
 <dt><span class="section"><a href="adding-text-to-the-buffer.html">Adding text to the buffer</a></span></dt>
 <dt><span class="section"><a href="setting-buffer-properties.html">Setting buffer properties</a></span></dt>
-<dt><span class="section"><a href="what-about-the-other-scripts.html">What about the other scripts?</a></span></dt>
 <dt><span class="section"><a href="customizing-unicode-functions.html">Customizing Unicode functions</a></span></dt>
 </dl></div>
 <p>
-    The input to HarfBuzz is a series of Unicode characters, stored in a
+    The input to the HarfBuzz shaper is a series of Unicode characters, stored in a
     buffer. In this chapter, we'll look at how to set up a buffer with
-    the text that we want and then customize the properties of the
-    buffer.
+    the text that we want and how to customize the properties of the
+    buffer. We'll also look at a piece of lower-level machinery that
+    you will need to understand before proceeding: the functions that
+    HarfBuzz uses to retrieve Unicode information.
+  </p>
+<p>
+    After shaping is complete, HarfBuzz puts its output back
+    into the buffer. But getting that output requires setting up a
+    face and a font first, so we will look at that in the next chapter
+    instead of here.
   </p>
 <div class="section">
 <div class="titlepage"><div><div><h2 class="title" style="clear: both">
 <p>
       As we saw in our <span class="emphasis"><em>Getting Started</em></span> example, a
       buffer is created and 
-      initialized with <code class="literal">hb_buffer_create()</code>. This
+      initialized with <code class="function">hb_buffer_create()</code>. This
       produces a new, empty buffer object, instantiated with some
       default values and ready to accept your Unicode strings.
     </p>
 <p>
       HarfBuzz manages the memory of objects (such as buffers) that it
       creates, so you don't have to. When you have finished working on 
-      a buffer, you can call <code class="literal">hb_buffer_destroy()</code>:
+      a buffer, you can call <code class="function">hb_buffer_destroy()</code>:
     </p>
 <pre class="programlisting">
-  hb_buffer_t *buffer = hb_buffer_create();
-  ...
-  hb_buffer_destroy(buffer);
-</pre>
+      hb_buffer_t *buf = hb_buffer_create();
+      ...
+      hb_buffer_destroy(buf);
+    </pre>
 <p>
       This will destroy the object and free its associated memory -
       unless some other part of the program holds a reference to this
       else destroying it, you should increase its reference count:
     </p>
 <pre class="programlisting">
-void somefunc(hb_buffer_t *buffer) {
-  buffer = hb_buffer_reference(buffer);
-  ...
-</pre>
+      void somefunc(hb_buffer_t *buf) {
+      buf = hb_buffer_reference(buf);
+      ...
+    </pre>
 <p>
       And then decrease it once you're done with it:
     </p>
 <pre class="programlisting">
-  hb_buffer_destroy(buffer);
-}
-</pre>
+      hb_buffer_destroy(buf);
+      }
+    </pre>
+<p>
+      While we are on the subject of reference-counting buffers, it is
+      worth noting that an individual buffer can only meaningfully be
+      used by one thread at a time.
+    </p>
 <p>
       To throw away all the data in your buffer and start from scratch,
-      call <code class="literal">hb_buffer_reset(buffer)</code>. If you want to
+      call <code class="function">hb_buffer_reset(buf)</code>. If you want to
       throw away the string in the buffer but keep the options, you can
-      instead call <code class="literal">hb_buffer_clear_contents(buffer)</code>.
+      instead call <code class="function">hb_buffer_clear_contents(buf)</code>.
     </p>
 </div>
 </div>
index 7b158ae..8870342 100644 (file)
 </td>
 </tr>
 <tr>
-<td><p><span class="term"><span class="command"><strong>--with-ucdn</strong></span></span></p></td>
-<td>
-<p>
-             Use HarfBuzz's <a class="ulink" href="https://github.com/harfbuzz/harfbuzz/tree/master/src/hb-ucdn" target="_top">built-in UCDN library</a>. <span class="emphasis"><em>(Default = auto)</em></span>
-           </p>
-<p>
-             The HarfBuzz source tree includes a <span class="emphasis"><em>Unicode
-             Database and Normalization</em></span> (UCDN) library
-             that provides access to basic character properties in
-             the Unicode Character Database (UCD) as well as low-level
-             normalization functions. HarfBuzz can be built without
-             this UCDN support if the usage of a different UCDN
-             library is desired.
-           </p>
-</td>
-</tr>
-<tr>
 <td><p><span class="term"><span class="command"><strong>--with-graphite2</strong></span></span></p></td>
 <td>
 <p>
diff --git a/docs/html/ch09.html b/docs/html/ch09.html
deleted file mode 100644 (file)
index c6cac7b..0000000
+++ /dev/null
@@ -1,67 +0,0 @@
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
-<html>
-<head>
-<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
-<title>Core API: HarfBuzz Manual</title>
-<meta name="generator" content="DocBook XSL Stylesheets Vsnapshot">
-<link rel="home" href="index.html" title="HarfBuzz Manual">
-<link rel="up" href="pt02.html" title="Part II. Reference manual">
-<link rel="prev" href="pt02.html" title="Part II. Reference manual">
-<link rel="next" href="harfbuzz-hb-blob.html" title="hb-blob">
-<meta name="generator" content="GTK-Doc V1.29 (XML mode)">
-<link rel="stylesheet" href="style.css" type="text/css">
-</head>
-<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
-<table class="navigation" id="top" width="100%" summary="Navigation header" cellpadding="2" cellspacing="5"><tr valign="middle">
-<td width="100%" align="left" class="shortcuts"></td>
-<td><a accesskey="h" href="index.html"><img src="home.png" width="16" height="16" border="0" alt="Home"></a></td>
-<td><a accesskey="u" href="pt02.html"><img src="up.png" width="16" height="16" border="0" alt="Up"></a></td>
-<td><a accesskey="p" href="pt02.html"><img src="left.png" width="16" height="16" border="0" alt="Prev"></a></td>
-<td><a accesskey="n" href="harfbuzz-hb-blob.html"><img src="right.png" width="16" height="16" border="0" alt="Next"></a></td>
-</tr></table>
-<div class="chapter">
-<div class="titlepage"><div><div><h2 class="title">
-<a name="id-1.3.4"></a>Core API</h2></div></div></div>
-<div class="toc"><dl class="toc">
-<dt>
-<span class="refentrytitle"><a href="harfbuzz-hb-blob.html">hb-blob</a></span><span class="refpurpose"> — Binary data containers</span>
-</dt>
-<dt>
-<span class="refentrytitle"><a href="harfbuzz-hb-buffer.html">hb-buffer</a></span><span class="refpurpose"> — Input and output buffers</span>
-</dt>
-<dt>
-<span class="refentrytitle"><a href="harfbuzz-hb-common.html">hb-common</a></span><span class="refpurpose"> — Common data types</span>
-</dt>
-<dt>
-<span class="refentrytitle"><a href="harfbuzz-hb-deprecated.html">hb-deprecated</a></span><span class="refpurpose"> — Deprecated API</span>
-</dt>
-<dt>
-<span class="refentrytitle"><a href="harfbuzz-hb-face.html">hb-face</a></span><span class="refpurpose"> — Font face objects</span>
-</dt>
-<dt>
-<span class="refentrytitle"><a href="harfbuzz-hb-font.html">hb-font</a></span><span class="refpurpose"> — Font objects</span>
-</dt>
-<dt>
-<span class="refentrytitle"><a href="harfbuzz-hb-map.html">hb-map</a></span><span class="refpurpose"> — Object representing integer to integer mapping</span>
-</dt>
-<dt>
-<span class="refentrytitle"><a href="harfbuzz-hb-set.html">hb-set</a></span><span class="refpurpose"> — Object representing a set of integers</span>
-</dt>
-<dt>
-<span class="refentrytitle"><a href="harfbuzz-hb-shape-plan.html">hb-shape-plan</a></span><span class="refpurpose"> — Object representing a shaping plan</span>
-</dt>
-<dt>
-<span class="refentrytitle"><a href="harfbuzz-hb-shape.html">hb-shape</a></span><span class="refpurpose"> — Conversion of text strings into positioned glyphs</span>
-</dt>
-<dt>
-<span class="refentrytitle"><a href="harfbuzz-hb-unicode.html">hb-unicode</a></span><span class="refpurpose"> — Unicode character property access</span>
-</dt>
-<dt>
-<span class="refentrytitle"><a href="harfbuzz-hb-version.html">hb-version</a></span><span class="refpurpose"> — Information about the version of HarfBuzz in use</span>
-</dt>
-</dl></div>
-</div>
-<div class="footer">
-<hr>Generated by GTK-Doc V1.29</div>
-</body>
-</html>
\ No newline at end of file
diff --git a/docs/html/ch10.html b/docs/html/ch10.html
deleted file mode 100644 (file)
index 7c615c1..0000000
+++ /dev/null
@@ -1,52 +0,0 @@
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
-<html>
-<head>
-<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
-<title>OpenType API: HarfBuzz Manual</title>
-<meta name="generator" content="DocBook XSL Stylesheets Vsnapshot">
-<link rel="home" href="index.html" title="HarfBuzz Manual">
-<link rel="up" href="pt02.html" title="Part II. Reference manual">
-<link rel="prev" href="harfbuzz-hb-version.html" title="hb-version">
-<link rel="next" href="harfbuzz-hb-ot-color.html" title="hb-ot-color">
-<meta name="generator" content="GTK-Doc V1.29 (XML mode)">
-<link rel="stylesheet" href="style.css" type="text/css">
-</head>
-<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
-<table class="navigation" id="top" width="100%" summary="Navigation header" cellpadding="2" cellspacing="5"><tr valign="middle">
-<td width="100%" align="left" class="shortcuts"></td>
-<td><a accesskey="h" href="index.html"><img src="home.png" width="16" height="16" border="0" alt="Home"></a></td>
-<td><a accesskey="u" href="pt02.html"><img src="up.png" width="16" height="16" border="0" alt="Up"></a></td>
-<td><a accesskey="p" href="harfbuzz-hb-version.html"><img src="left.png" width="16" height="16" border="0" alt="Prev"></a></td>
-<td><a accesskey="n" href="harfbuzz-hb-ot-color.html"><img src="right.png" width="16" height="16" border="0" alt="Next"></a></td>
-</tr></table>
-<div class="chapter">
-<div class="titlepage"><div><div><h2 class="title">
-<a name="id-1.3.5"></a>OpenType API</h2></div></div></div>
-<div class="toc"><dl class="toc">
-<dt>
-<span class="refentrytitle"><a href="harfbuzz-hb-ot-color.html">hb-ot-color</a></span><span class="refpurpose"> — OpenType Color Fonts</span>
-</dt>
-<dt>
-<span class="refentrytitle"><a href="harfbuzz-hb-ot-font.html">hb-ot-font</a></span><span class="refpurpose"> — OpenType font implementation</span>
-</dt>
-<dt>
-<span class="refentrytitle"><a href="harfbuzz-hb-ot-layout.html">hb-ot-layout</a></span><span class="refpurpose"> — OpenType Layout</span>
-</dt>
-<dt>
-<span class="refentrytitle"><a href="harfbuzz-hb-ot-math.html">hb-ot-math</a></span><span class="refpurpose"> — OpenType Math information</span>
-</dt>
-<dt>
-<span class="refentrytitle"><a href="harfbuzz-hb-ot-name.html">hb-ot-name</a></span><span class="refpurpose"> — OpenType font name information</span>
-</dt>
-<dt>
-<span class="refentrytitle"><a href="harfbuzz-hb-ot-shape.html">hb-ot-shape</a></span><span class="refpurpose"> — OpenType shaping support</span>
-</dt>
-<dt>
-<span class="refentrytitle"><a href="harfbuzz-hb-ot-var.html">hb-ot-var</a></span><span class="refpurpose"> — OpenType Font Variations</span>
-</dt>
-</dl></div>
-</div>
-<div class="footer">
-<hr>Generated by GTK-Doc V1.29</div>
-</body>
-</html>
\ No newline at end of file
index 4081a6d..c6cac7b 100644 (file)
@@ -2,12 +2,12 @@
 <html>
 <head>
 <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
-<title>Apple Advanced Typography API: HarfBuzz Manual</title>
+<title>Core API: HarfBuzz Manual</title>
 <meta name="generator" content="DocBook XSL Stylesheets Vsnapshot">
 <link rel="home" href="index.html" title="HarfBuzz Manual">
 <link rel="up" href="pt02.html" title="Part II. Reference manual">
-<link rel="prev" href="harfbuzz-hb-ot-var.html" title="hb-ot-var">
-<link rel="next" href="harfbuzz-hb-aat-layout.html" title="hb-aat-layout">
+<link rel="prev" href="pt02.html" title="Part II. Reference manual">
+<link rel="next" href="harfbuzz-hb-blob.html" title="hb-blob">
 <meta name="generator" content="GTK-Doc V1.29 (XML mode)">
 <link rel="stylesheet" href="style.css" type="text/css">
 </head>
 <td width="100%" align="left" class="shortcuts"></td>
 <td><a accesskey="h" href="index.html"><img src="home.png" width="16" height="16" border="0" alt="Home"></a></td>
 <td><a accesskey="u" href="pt02.html"><img src="up.png" width="16" height="16" border="0" alt="Up"></a></td>
-<td><a accesskey="p" href="harfbuzz-hb-ot-var.html"><img src="left.png" width="16" height="16" border="0" alt="Prev"></a></td>
-<td><a accesskey="n" href="harfbuzz-hb-aat-layout.html"><img src="right.png" width="16" height="16" border="0" alt="Next"></a></td>
+<td><a accesskey="p" href="pt02.html"><img src="left.png" width="16" height="16" border="0" alt="Prev"></a></td>
+<td><a accesskey="n" href="harfbuzz-hb-blob.html"><img src="right.png" width="16" height="16" border="0" alt="Next"></a></td>
 </tr></table>
 <div class="chapter">
 <div class="titlepage"><div><div><h2 class="title">
-<a name="id-1.3.6"></a>Apple Advanced Typography API</h2></div></div></div>
-<div class="toc"><dl class="toc"><dt>
-<span class="refentrytitle"><a href="harfbuzz-hb-aat-layout.html">hb-aat-layout</a></span><span class="refpurpose"> — Apple Advanced Typography Layout</span>
-</dt></dl></div>
+<a name="id-1.3.4"></a>Core API</h2></div></div></div>
+<div class="toc"><dl class="toc">
+<dt>
+<span class="refentrytitle"><a href="harfbuzz-hb-blob.html">hb-blob</a></span><span class="refpurpose"> — Binary data containers</span>
+</dt>
+<dt>
+<span class="refentrytitle"><a href="harfbuzz-hb-buffer.html">hb-buffer</a></span><span class="refpurpose"> — Input and output buffers</span>
+</dt>
+<dt>
+<span class="refentrytitle"><a href="harfbuzz-hb-common.html">hb-common</a></span><span class="refpurpose"> — Common data types</span>
+</dt>
+<dt>
+<span class="refentrytitle"><a href="harfbuzz-hb-deprecated.html">hb-deprecated</a></span><span class="refpurpose"> — Deprecated API</span>
+</dt>
+<dt>
+<span class="refentrytitle"><a href="harfbuzz-hb-face.html">hb-face</a></span><span class="refpurpose"> — Font face objects</span>
+</dt>
+<dt>
+<span class="refentrytitle"><a href="harfbuzz-hb-font.html">hb-font</a></span><span class="refpurpose"> — Font objects</span>
+</dt>
+<dt>
+<span class="refentrytitle"><a href="harfbuzz-hb-map.html">hb-map</a></span><span class="refpurpose"> — Object representing integer to integer mapping</span>
+</dt>
+<dt>
+<span class="refentrytitle"><a href="harfbuzz-hb-set.html">hb-set</a></span><span class="refpurpose"> — Object representing a set of integers</span>
+</dt>
+<dt>
+<span class="refentrytitle"><a href="harfbuzz-hb-shape-plan.html">hb-shape-plan</a></span><span class="refpurpose"> — Object representing a shaping plan</span>
+</dt>
+<dt>
+<span class="refentrytitle"><a href="harfbuzz-hb-shape.html">hb-shape</a></span><span class="refpurpose"> — Conversion of text strings into positioned glyphs</span>
+</dt>
+<dt>
+<span class="refentrytitle"><a href="harfbuzz-hb-unicode.html">hb-unicode</a></span><span class="refpurpose"> — Unicode character property access</span>
+</dt>
+<dt>
+<span class="refentrytitle"><a href="harfbuzz-hb-version.html">hb-version</a></span><span class="refpurpose"> — Information about the version of HarfBuzz in use</span>
+</dt>
+</dl></div>
 </div>
 <div class="footer">
 <hr>Generated by GTK-Doc V1.29</div>
index b504c84..7c615c1 100644 (file)
@@ -2,12 +2,12 @@
 <html>
 <head>
 <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
-<title>Integration API: HarfBuzz Manual</title>
+<title>OpenType API: HarfBuzz Manual</title>
 <meta name="generator" content="DocBook XSL Stylesheets Vsnapshot">
 <link rel="home" href="index.html" title="HarfBuzz Manual">
 <link rel="up" href="pt02.html" title="Part II. Reference manual">
-<link rel="prev" href="harfbuzz-hb-aat-layout.html" title="hb-aat-layout">
-<link rel="next" href="harfbuzz-hb-coretext.html" title="hb-coretext">
+<link rel="prev" href="harfbuzz-hb-version.html" title="hb-version">
+<link rel="next" href="harfbuzz-hb-ot-color.html" title="hb-ot-color">
 <meta name="generator" content="GTK-Doc V1.29 (XML mode)">
 <link rel="stylesheet" href="style.css" type="text/css">
 </head>
 <td width="100%" align="left" class="shortcuts"></td>
 <td><a accesskey="h" href="index.html"><img src="home.png" width="16" height="16" border="0" alt="Home"></a></td>
 <td><a accesskey="u" href="pt02.html"><img src="up.png" width="16" height="16" border="0" alt="Up"></a></td>
-<td><a accesskey="p" href="harfbuzz-hb-aat-layout.html"><img src="left.png" width="16" height="16" border="0" alt="Prev"></a></td>
-<td><a accesskey="n" href="harfbuzz-hb-coretext.html"><img src="right.png" width="16" height="16" border="0" alt="Next"></a></td>
+<td><a accesskey="p" href="harfbuzz-hb-version.html"><img src="left.png" width="16" height="16" border="0" alt="Prev"></a></td>
+<td><a accesskey="n" href="harfbuzz-hb-ot-color.html"><img src="right.png" width="16" height="16" border="0" alt="Next"></a></td>
 </tr></table>
 <div class="chapter">
 <div class="titlepage"><div><div><h2 class="title">
-<a name="id-1.3.7"></a>Integration API</h2></div></div></div>
+<a name="id-1.3.5"></a>OpenType API</h2></div></div></div>
 <div class="toc"><dl class="toc">
 <dt>
-<span class="refentrytitle"><a href="harfbuzz-hb-coretext.html">hb-coretext</a></span><span class="refpurpose"> — CoreText integration</span>
+<span class="refentrytitle"><a href="harfbuzz-hb-ot-color.html">hb-ot-color</a></span><span class="refpurpose"> — OpenType Color Fonts</span>
 </dt>
 <dt>
-<span class="refentrytitle"><a href="harfbuzz-hb-ft.html">hb-ft</a></span><span class="refpurpose"> — FreeType integration</span>
+<span class="refentrytitle"><a href="harfbuzz-hb-ot-font.html">hb-ot-font</a></span><span class="refpurpose"> — OpenType font implementation</span>
 </dt>
 <dt>
-<span class="refentrytitle"><a href="harfbuzz-hb-glib.html">hb-glib</a></span><span class="refpurpose"> — GLib integration</span>
+<span class="refentrytitle"><a href="harfbuzz-hb-ot-layout.html">hb-ot-layout</a></span><span class="refpurpose"> — OpenType Layout</span>
 </dt>
 <dt>
-<span class="refentrytitle"><a href="harfbuzz-hb-gobject.html">hb-gobject</a></span><span class="refpurpose"> — GObject integration</span>
+<span class="refentrytitle"><a href="harfbuzz-hb-ot-math.html">hb-ot-math</a></span><span class="refpurpose"> — OpenType Math information</span>
 </dt>
 <dt>
-<span class="refentrytitle"><a href="harfbuzz-hb-graphite2.html">hb-graphite2</a></span><span class="refpurpose"> — Graphite2 integration</span>
+<span class="refentrytitle"><a href="harfbuzz-hb-ot-name.html">hb-ot-name</a></span><span class="refpurpose"> — OpenType font name information</span>
 </dt>
 <dt>
-<span class="refentrytitle"><a href="harfbuzz-hb-icu.html">hb-icu</a></span><span class="refpurpose"> — ICU integration</span>
+<span class="refentrytitle"><a href="harfbuzz-hb-ot-shape.html">hb-ot-shape</a></span><span class="refpurpose"> — OpenType shaping support</span>
 </dt>
 <dt>
-<span class="refentrytitle"><a href="harfbuzz-hb-uniscribe.html">hb-uniscribe</a></span><span class="refpurpose"> — Windows integration</span>
+<span class="refentrytitle"><a href="harfbuzz-hb-ot-var.html">hb-ot-var</a></span><span class="refpurpose"> — OpenType Font Variations</span>
 </dt>
 </dl></div>
 </div>
diff --git a/docs/html/ch13.html b/docs/html/ch13.html
new file mode 100644 (file)
index 0000000..4081a6d
--- /dev/null
@@ -0,0 +1,32 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>Apple Advanced Typography API: HarfBuzz Manual</title>
+<meta name="generator" content="DocBook XSL Stylesheets Vsnapshot">
+<link rel="home" href="index.html" title="HarfBuzz Manual">
+<link rel="up" href="pt02.html" title="Part II. Reference manual">
+<link rel="prev" href="harfbuzz-hb-ot-var.html" title="hb-ot-var">
+<link rel="next" href="harfbuzz-hb-aat-layout.html" title="hb-aat-layout">
+<meta name="generator" content="GTK-Doc V1.29 (XML mode)">
+<link rel="stylesheet" href="style.css" type="text/css">
+</head>
+<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
+<table class="navigation" id="top" width="100%" summary="Navigation header" cellpadding="2" cellspacing="5"><tr valign="middle">
+<td width="100%" align="left" class="shortcuts"></td>
+<td><a accesskey="h" href="index.html"><img src="home.png" width="16" height="16" border="0" alt="Home"></a></td>
+<td><a accesskey="u" href="pt02.html"><img src="up.png" width="16" height="16" border="0" alt="Up"></a></td>
+<td><a accesskey="p" href="harfbuzz-hb-ot-var.html"><img src="left.png" width="16" height="16" border="0" alt="Prev"></a></td>
+<td><a accesskey="n" href="harfbuzz-hb-aat-layout.html"><img src="right.png" width="16" height="16" border="0" alt="Next"></a></td>
+</tr></table>
+<div class="chapter">
+<div class="titlepage"><div><div><h2 class="title">
+<a name="id-1.3.6"></a>Apple Advanced Typography API</h2></div></div></div>
+<div class="toc"><dl class="toc"><dt>
+<span class="refentrytitle"><a href="harfbuzz-hb-aat-layout.html">hb-aat-layout</a></span><span class="refpurpose"> — Apple Advanced Typography Layout</span>
+</dt></dl></div>
+</div>
+<div class="footer">
+<hr>Generated by GTK-Doc V1.29</div>
+</body>
+</html>
\ No newline at end of file
diff --git a/docs/html/ch14.html b/docs/html/ch14.html
new file mode 100644 (file)
index 0000000..b504c84
--- /dev/null
@@ -0,0 +1,52 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>Integration API: HarfBuzz Manual</title>
+<meta name="generator" content="DocBook XSL Stylesheets Vsnapshot">
+<link rel="home" href="index.html" title="HarfBuzz Manual">
+<link rel="up" href="pt02.html" title="Part II. Reference manual">
+<link rel="prev" href="harfbuzz-hb-aat-layout.html" title="hb-aat-layout">
+<link rel="next" href="harfbuzz-hb-coretext.html" title="hb-coretext">
+<meta name="generator" content="GTK-Doc V1.29 (XML mode)">
+<link rel="stylesheet" href="style.css" type="text/css">
+</head>
+<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
+<table class="navigation" id="top" width="100%" summary="Navigation header" cellpadding="2" cellspacing="5"><tr valign="middle">
+<td width="100%" align="left" class="shortcuts"></td>
+<td><a accesskey="h" href="index.html"><img src="home.png" width="16" height="16" border="0" alt="Home"></a></td>
+<td><a accesskey="u" href="pt02.html"><img src="up.png" width="16" height="16" border="0" alt="Up"></a></td>
+<td><a accesskey="p" href="harfbuzz-hb-aat-layout.html"><img src="left.png" width="16" height="16" border="0" alt="Prev"></a></td>
+<td><a accesskey="n" href="harfbuzz-hb-coretext.html"><img src="right.png" width="16" height="16" border="0" alt="Next"></a></td>
+</tr></table>
+<div class="chapter">
+<div class="titlepage"><div><div><h2 class="title">
+<a name="id-1.3.7"></a>Integration API</h2></div></div></div>
+<div class="toc"><dl class="toc">
+<dt>
+<span class="refentrytitle"><a href="harfbuzz-hb-coretext.html">hb-coretext</a></span><span class="refpurpose"> — CoreText integration</span>
+</dt>
+<dt>
+<span class="refentrytitle"><a href="harfbuzz-hb-ft.html">hb-ft</a></span><span class="refpurpose"> — FreeType integration</span>
+</dt>
+<dt>
+<span class="refentrytitle"><a href="harfbuzz-hb-glib.html">hb-glib</a></span><span class="refpurpose"> — GLib integration</span>
+</dt>
+<dt>
+<span class="refentrytitle"><a href="harfbuzz-hb-gobject.html">hb-gobject</a></span><span class="refpurpose"> — GObject integration</span>
+</dt>
+<dt>
+<span class="refentrytitle"><a href="harfbuzz-hb-graphite2.html">hb-graphite2</a></span><span class="refpurpose"> — Graphite2 integration</span>
+</dt>
+<dt>
+<span class="refentrytitle"><a href="harfbuzz-hb-icu.html">hb-icu</a></span><span class="refpurpose"> — ICU integration</span>
+</dt>
+<dt>
+<span class="refentrytitle"><a href="harfbuzz-hb-uniscribe.html">hb-uniscribe</a></span><span class="refpurpose"> — Windows integration</span>
+</dt>
+</dl></div>
+</div>
+<div class="footer">
+<hr>Generated by GTK-Doc V1.29</div>
+</body>
+</html>
\ No newline at end of file
index 2d6c36d..d6f3d6a 100644 (file)
@@ -6,7 +6,7 @@
 <meta name="generator" content="DocBook XSL Stylesheets Vsnapshot">
 <link rel="home" href="index.html" title="HarfBuzz Manual">
 <link rel="up" href="pt01.html" title="Part I. User's manual">
-<link rel="prev" href="using-your-own-font-functions.html" title="Using your own font functions">
+<link rel="prev" href="shaping-plans-and-caching.html" title="Plans and caching">
 <link rel="next" href="working-with-harfbuzz-clusters.html" title="Working with HarfBuzz clusters">
 <meta name="generator" content="GTK-Doc V1.29 (XML mode)">
 <link rel="stylesheet" href="style.css" type="text/css">
@@ -16,7 +16,7 @@
 <td width="100%" align="left" class="shortcuts"></td>
 <td><a accesskey="h" href="index.html"><img src="home.png" width="16" height="16" border="0" alt="Home"></a></td>
 <td><a accesskey="u" href="pt01.html"><img src="up.png" width="16" height="16" border="0" alt="Up"></a></td>
-<td><a accesskey="p" href="using-your-own-font-functions.html"><img src="left.png" width="16" height="16" border="0" alt="Prev"></a></td>
+<td><a accesskey="p" href="shaping-plans-and-caching.html"><img src="left.png" width="16" height="16" border="0" alt="Prev"></a></td>
 <td><a accesskey="n" href="working-with-harfbuzz-clusters.html"><img src="right.png" width="16" height="16" border="0" alt="Next"></a></td>
 </tr></table>
 <div class="chapter">
index 5528b53..76b4645 100644 (file)
@@ -6,8 +6,8 @@
 <meta name="generator" content="DocBook XSL Stylesheets Vsnapshot">
 <link rel="home" href="index.html" title="HarfBuzz Manual">
 <link rel="up" href="buffers-language-script-and-direction.html" title="Buffers, language, script and direction">
-<link rel="prev" href="what-about-the-other-scripts.html" title="What about the other scripts?">
-<link rel="next" href="fonts-and-faces.html" title="Fonts and faces">
+<link rel="prev" href="setting-buffer-properties.html" title="Setting buffer properties">
+<link rel="next" href="fonts-and-faces.html" title="Fonts, faces, and output">
 <meta name="generator" content="GTK-Doc V1.29 (XML mode)">
 <link rel="stylesheet" href="style.css" type="text/css">
 </head>
 <td width="100%" align="left" class="shortcuts"></td>
 <td><a accesskey="h" href="index.html"><img src="home.png" width="16" height="16" border="0" alt="Home"></a></td>
 <td><a accesskey="u" href="buffers-language-script-and-direction.html"><img src="up.png" width="16" height="16" border="0" alt="Up"></a></td>
-<td><a accesskey="p" href="what-about-the-other-scripts.html"><img src="left.png" width="16" height="16" border="0" alt="Prev"></a></td>
+<td><a accesskey="p" href="setting-buffer-properties.html"><img src="left.png" width="16" height="16" border="0" alt="Prev"></a></td>
 <td><a accesskey="n" href="fonts-and-faces.html"><img src="right.png" width="16" height="16" border="0" alt="Next"></a></td>
 </tr></table>
 <div class="section">
 <div class="titlepage"><div><div><h2 class="title" style="clear: both">
 <a name="customizing-unicode-functions"></a>Customizing Unicode functions</h2></div></div></div>
 <p>
+      HarfBuzz requires some simple functions for accessing
+      information from the Unicode Character Database (such as the
+      <code class="literal">General_Category</code> (gc) and
+      <code class="literal">Script</code> (sc) properties) that is useful
+      for shaping, as well as some useful operations like composing and
+      decomposing code points.
+    </p>
+<p>
+      HarfBuzz includes its own internal, lightweight set of Unicode
+      functions. At build time, it is also possible to compile support
+      for some other options, such as the Unicode functions provided
+      by GLib or the International Components for Unicode (ICU)
+      library. Generally, this option is only of interest for client
+      programs that have specific integration requirements or that do
+      a significant amount of customization.
+    </p>
+<p>
+      If your program has access to other Unicode functions, however,
+      such as through a system library or application framework, you
+      might prefer to use those instead of the built-in
+      options. HarfBuzz supports this by implementing its Unicode
+      functions as a set of virtual methods that you can replace —
+      without otherwise affecting HarfBuzz's functionality.
+    </p>
+<p>
+      The Unicode functions are specified in a structure called
+      <code class="literal">unicode_funcs</code> which is attached to each
+      buffer. But even though <code class="literal">unicode_funcs</code> is
+      associated with a <span class="type">hb_buffer_t</span>, the functions
+      themselves are called by other HarfBuzz APIs that access
+      buffers, so it would be unwise for you to hook different
+      functions into different buffers.
+    </p>
+<p>
+      In addition, you can mark your <code class="literal">unicode_funcs</code>
+      as immutable by calling
+      <code class="function">hb_unicode_funcs_make_immutable (ufuncs)</code>.
+      This is especially useful if your code is a
+      library or framework that will have its own client programs. By
+      marking your Unicode function choices as immutable, you prevent
+      your own client programs from changing the
+      <code class="literal">unicode_funcs</code> configuration and introducing
+      inconsistencies and errors downstream.
+    </p>
+<p>
+      You can retrieve the Unicode-functions configuration for
+      your buffer by calling <code class="function">hb_buffer_get_unicode_funcs()</code>:
+    </p>
+<pre class="programlisting">
+      hb_unicode_funcs_t *ufunctions;
+      ufunctions = hb_buffer_get_unicode_funcs(buf);
+    </pre>
+<p>
+      The current version of <code class="literal">unicode_funcs</code> uses six functions:
+    </p>
+<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; ">
+<li class="listitem"><p>
+         <code class="function">hb_unicode_combining_class_func_t</code>:
+         returns the Canonical Combining Class of a code point.
+       </p></li>
+<li class="listitem"><p>
+         <code class="function">hb_unicode_general_category_func_t</code>:
+         returns the General Category (gc) of a code point.
+       </p></li>
+<li class="listitem"><p>
+         <code class="function">hb_unicode_mirroring_func_t</code>: returns
+         the Mirroring Glyph code point (for bi-directional
+         replacement) of a code point.
+       </p></li>
+<li class="listitem"><p>
+         <code class="function">hb_unicode_script_func_t</code>: returns the
+         Script (sc) property of a code point.
+       </p></li>
+<li class="listitem"><p>
+         <code class="function">hb_unicode_compose_func_t</code>: returns the
+         canonical composition of a sequence of two code points.
+       </p></li>
+<li class="listitem"><p>
+         <code class="function">hb_unicode_decompose_func_t</code>: returns
+         the canonical decomposition of a code point.
+       </p></li>
+</ul></div>
+<p>
+      Note, however, that future HarfBuzz releases may alter this set.
+    </p>
+<p>
+      Each Unicode function has a corresponding setter, with which you
+      can assign a callback to your replacement function. For example,
+      to replace
+      <code class="function">hb_unicode_general_category_func_t</code>, you can call
+    </p>
+<pre class="programlisting">
+      hb_unicode_funcs_set_general_category_func (*ufuncs, func, *user_data, destroy)      
+    </pre>
+<p>
+      Virtualizing this set of Unicode functions is primarily intended
+      to improve portability. There is no need for every client
+      program to make the effort to replace the default options, so if
+      you are unsure, do not feel any pressure to customize
+      <code class="literal">unicode_funcs</code>. 
     </p>
 </div>
 <div class="footer">
diff --git a/docs/html/fonts-and-faces-custom-functions.html b/docs/html/fonts-and-faces-custom-functions.html
new file mode 100644 (file)
index 0000000..80221f2
--- /dev/null
@@ -0,0 +1,156 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>Customizing font functions: HarfBuzz Manual</title>
+<meta name="generator" content="DocBook XSL Stylesheets Vsnapshot">
+<link rel="home" href="index.html" title="HarfBuzz Manual">
+<link rel="up" href="fonts-and-faces.html" title="Fonts, faces, and output">
+<link rel="prev" href="fonts-and-faces.html" title="Fonts, faces, and output">
+<link rel="next" href="fonts-and-faces-native-opentype.html" title="Font objects and HarfBuzz's native OpenType implementation">
+<meta name="generator" content="GTK-Doc V1.29 (XML mode)">
+<link rel="stylesheet" href="style.css" type="text/css">
+</head>
+<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
+<table class="navigation" id="top" width="100%" summary="Navigation header" cellpadding="2" cellspacing="5"><tr valign="middle">
+<td width="100%" align="left" class="shortcuts"></td>
+<td><a accesskey="h" href="index.html"><img src="home.png" width="16" height="16" border="0" alt="Home"></a></td>
+<td><a accesskey="u" href="fonts-and-faces.html"><img src="up.png" width="16" height="16" border="0" alt="Up"></a></td>
+<td><a accesskey="p" href="fonts-and-faces.html"><img src="left.png" width="16" height="16" border="0" alt="Prev"></a></td>
+<td><a accesskey="n" href="fonts-and-faces-native-opentype.html"><img src="right.png" width="16" height="16" border="0" alt="Next"></a></td>
+</tr></table>
+<div class="section">
+<div class="titlepage"><div><div><h2 class="title" style="clear: both">
+<a name="fonts-and-faces-custom-functions"></a>Customizing font functions</h2></div></div></div>
+<p>
+      During shaping, HarfBuzz frequently needs to query font objects
+      to get at the contents and parameters of the glyphs in a font
+      file. It includes a built-in set of functions that is tailored
+      to working with OpenType fonts. However, as was the case with
+      Unicode functions in the buffers chapter, HarfBuzz also wants to
+      make it easy for you to assign a substitute set of font
+      functions if you are developing a program to work with a library
+      or platform that provides its own font functions. 
+    </p>
+<p>
+      Therefore, the HarfBuzz API defines a set of virtual
+      methods for accessing font-object properties, and you can
+      replace the defaults with your own selections without
+      interfering with the shaping process. Each font object in
+      HarfBuzz includes a structure called
+      <code class="literal">font_funcs</code> that serves as a vtable for the
+      font object. The virtual methods in
+      <code class="literal">font_funcs</code> are:
+    </p>
+<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; ">
+<li class="listitem"><p>
+      <code class="function">hb_font_get_font_h_extents_func_t</code>: returns
+      the extents of the font for horizontal text.
+    </p></li>
+<li class="listitem"><p>
+      <code class="function">hb_font_get_font_v_extents_func_t</code>: returns
+      the extents of the font for vertical text.
+    </p></li>
+<li class="listitem"><p>
+      <code class="function">hb_font_get_nominal_glyph_func_t</code>: returns
+      the font's nominal glyph for a given code point.
+    </p></li>
+<li class="listitem"><p>
+      <code class="function">hb_font_get_variation_glyph_func_t</code>: returns
+      the font's glyph for a given code point when it is followed by a
+      given Variation Selector.
+    </p></li>
+<li class="listitem"><p>
+      <code class="function">hb_font_get_nominal_glyphs_func_t</code>: returns
+      the font's nominal glyphs for a series of code points.
+    </p></li>
+<li class="listitem"><p>
+      <code class="function">hb_font_get_glyph_advance_func_t</code>: returns
+      the advance for a glyph.
+    </p></li>
+<li class="listitem"><p>
+      <code class="function">hb_font_get_glyph_h_advance_func_t</code>: returns
+      the advance for a glyph for horizontal text.
+    </p></li>
+<li class="listitem"><p>
+      <code class="function">hb_font_get_glyph_v_advance_func_t</code>:returns
+      the advance for a glyph for vertical text.
+    </p></li>
+<li class="listitem"><p>
+      <code class="function">hb_font_get_glyph_advances_func_t</code>: returns
+      the advances for a series of glyphs.
+    </p></li>
+<li class="listitem"><p>
+      <code class="function">hb_font_get_glyph_h_advances_func_t</code>: returns
+      the advances for a series of glyphs for horizontal text .
+    </p></li>
+<li class="listitem"><p>
+      <code class="function">hb_font_get_glyph_v_advances_func_t</code>: returns
+      the advances for a series of glyphs for vertical text.
+    </p></li>
+<li class="listitem"><p>
+      <code class="function">hb_font_get_glyph_origin_func_t</code>: returns
+      the origin coordinates of a glyph.
+    </p></li>
+<li class="listitem"><p>
+      <code class="function">hb_font_get_glyph_h_origin_func_t</code>: returns
+      the origin coordinates of a glyph for horizontal text.
+    </p></li>
+<li class="listitem"><p>
+      <code class="function">hb_font_get_glyph_v_origin_func_t</code>: returns
+      the origin coordinates of a glyph for vertical text.
+    </p></li>
+<li class="listitem"><p>
+      <code class="function">hb_font_get_glyph_extents_func_t</code>: returns
+      the extents for a glyph.
+    </p></li>
+<li class="listitem"><p>
+      <code class="function">hb_font_get_glyph_contour_point_func_t</code>:
+      returns the coordinates of a specific contour point from a glyph.
+    </p></li>
+<li class="listitem"><p>
+      <code class="function">hb_font_get_glyph_name_func_t</code>: returns the
+      name of a glyph (from its glyph index).
+    </p></li>
+<li class="listitem"><p>
+      <code class="function">hb_font_get_glyph_from_name_func_t</code>: returns
+      the glyph index that corresponds to a given glyph name.
+    </p></li>
+</ul></div>
+<p>
+      You can fetch the font-functions configuration for a font object
+      by calling <code class="function">hb_font_get_font_funcs()</code>:
+    </p>
+<pre class="programlisting">
+      hb_font_funcs_t *ffunctions;
+      ffunctions = hb_font_get_font_funcs (font);
+    </pre>
+<p>
+      The individual methods can each be replaced with their own setter
+      function, such as
+      <code class="function">hb_font_funcs_set_nominal_glyph_func(*ffunctions,
+      func, *user_data, destroy)</code>. 
+    </p>
+<p>
+      Font-functions structures can be reused for multiple font
+      objects, and can be reference counted with
+      <code class="function">hb_font_funcs_reference()</code> and
+      <code class="function">hb_font_funcs_destroy()</code>. Just like other
+      objects in HarfBuzz, you can set user-data for each
+      font-functions structure and assign a destroy callback for
+      it.
+    </p>
+<p>
+      You can also mark a font-functions structure as immutable,
+      with <code class="function">hb_font_funcs_make_immutable()</code>. This
+      is especially useful if your code is a library or framework that
+      will have its own client programs. By marking your
+      font-functions structures as immutable, you prevent your client
+      programs from changing the configuration and introducing
+      inconsistencies and errors downstream.
+    </p>
+</div>
+<div class="footer">
+<hr>Generated by GTK-Doc V1.29</div>
+</body>
+</html>
\ No newline at end of file
diff --git a/docs/html/fonts-and-faces-native-opentype.html b/docs/html/fonts-and-faces-native-opentype.html
new file mode 100644 (file)
index 0000000..48daf19
--- /dev/null
@@ -0,0 +1,93 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>Font objects and HarfBuzz's native OpenType implementation: HarfBuzz Manual</title>
+<meta name="generator" content="DocBook XSL Stylesheets Vsnapshot">
+<link rel="home" href="index.html" title="HarfBuzz Manual">
+<link rel="up" href="fonts-and-faces.html" title="Fonts, faces, and output">
+<link rel="prev" href="fonts-and-faces-custom-functions.html" title="Customizing font functions">
+<link rel="next" href="fonts-and-faces-variable.html" title="Working with OpenType Variable Fonts">
+<meta name="generator" content="GTK-Doc V1.29 (XML mode)">
+<link rel="stylesheet" href="style.css" type="text/css">
+</head>
+<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
+<table class="navigation" id="top" width="100%" summary="Navigation header" cellpadding="2" cellspacing="5"><tr valign="middle">
+<td width="100%" align="left" class="shortcuts"></td>
+<td><a accesskey="h" href="index.html"><img src="home.png" width="16" height="16" border="0" alt="Home"></a></td>
+<td><a accesskey="u" href="fonts-and-faces.html"><img src="up.png" width="16" height="16" border="0" alt="Up"></a></td>
+<td><a accesskey="p" href="fonts-and-faces-custom-functions.html"><img src="left.png" width="16" height="16" border="0" alt="Prev"></a></td>
+<td><a accesskey="n" href="fonts-and-faces-variable.html"><img src="right.png" width="16" height="16" border="0" alt="Next"></a></td>
+</tr></table>
+<div class="section">
+<div class="titlepage"><div><div><h2 class="title" style="clear: both">
+<a name="fonts-and-faces-native-opentype"></a>Font objects and HarfBuzz's native OpenType implementation</h2></div></div></div>
+<p>
+      By default, whenever HarfBuzz creates a font object, it will
+      configure the font to use a built-in set of font functions that
+      supports contemporary OpenType font internals. If you want to
+      work with OpenType or TrueType fonts, you should be able to use
+      these functions without difficulty.
+    </p>
+<p>
+      Many of the methods in the font-functions structure deal with
+      the fundamental properties of glyphs that are required for
+      shaping text: extents (the maximums and minimums on each axis),
+      origins (the <code class="literal">(0,0)</code> coordinate point which
+      glyphs are drawn in reference to), and advances (the amount that
+      the cursor needs to be moved after drawing each glyph, including
+      any empty space for the glyph's side bearings).
+    </p>
+<p>
+      As you can see in the list of functions, there are separate "horizontal"
+      and "vertical" variants depending on whether the text is set in
+      the horizontal or vertical direction. For some scripts, fonts
+      that are designed to support text set horizontally or vertically (for
+      example, in Japanese) may include metrics for both text
+      directions. When fonts don't include this information, HarfBuzz
+      does its best to transform what the font provides.
+    </p>
+<p>
+      In addition to the direction-specific functions, HarfBuzz
+      provides some higher-level functions for fetching information
+      like extents and advances for a glyph. If you call
+    </p>
+<pre class="programlisting">
+      hb_font_get_glyph_advance_for_direction(font, direction, extents);
+    </pre>
+<p>
+      then you can provide any <span class="type">hb_direction_t</span> as the
+      <em class="parameter"><code>direction</code></em> parameter, and HarfBuzz will
+      use the correct function variant for the text direction. There
+      are similar higher-level versions of the functions for fetching
+      extents, origin coordinates, and contour-point
+      coordinates. There are also addition and subtraction functions
+      for moving points with respect to the origin.
+    </p>
+<p>
+      There are also methods for fetching the glyph ID that
+      corresponds to a Unicode code point (possibly when followed by a
+      variation-selector code point), fetching the glyph name from the
+      font, and fetching the glyph ID that corresponds to a glyph name
+      you already have.
+    </p>
+<p>
+      HarfBuzz also provides functions for converting between glyph
+      names and string
+      variables. <code class="function">hb_font_glyph_to_string(font, glyph, s,
+      size)</code> retrieves the name for the glyph ID
+      <em class="parameter"><code>glyph</code></em> from the font object. It generates a
+      generic name of the form <code class="literal">gidDDD</code> (where DDD is
+      the glyph index) if there is no name for the glyph in the
+      font. The <code class="function">hb_font_glyph_from_string(font, s, len,
+      glyph)</code> takes an input string <em class="parameter"><code>s</code></em>
+      and looks for a glyph with that name in the font, returning its
+      glyph ID in the <em class="parameter"><code>glyph</code></em>
+      output parameter. It automatically parses
+      <code class="literal">gidDDD</code> and <code class="literal">uniUUUU</code> strings.
+    </p>
+</div>
+<div class="footer">
+<hr>Generated by GTK-Doc V1.29</div>
+</body>
+</html>
\ No newline at end of file
diff --git a/docs/html/fonts-and-faces-variable.html b/docs/html/fonts-and-faces-variable.html
new file mode 100644 (file)
index 0000000..b0a1f39
--- /dev/null
@@ -0,0 +1,100 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>Working with OpenType Variable Fonts: HarfBuzz Manual</title>
+<meta name="generator" content="DocBook XSL Stylesheets Vsnapshot">
+<link rel="home" href="index.html" title="HarfBuzz Manual">
+<link rel="up" href="fonts-and-faces.html" title="Fonts, faces, and output">
+<link rel="prev" href="fonts-and-faces-native-opentype.html" title="Font objects and HarfBuzz's native OpenType implementation">
+<link rel="next" href="shaping-and-shape-plans.html" title="Shaping and shape plans">
+<meta name="generator" content="GTK-Doc V1.29 (XML mode)">
+<link rel="stylesheet" href="style.css" type="text/css">
+</head>
+<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
+<table class="navigation" id="top" width="100%" summary="Navigation header" cellpadding="2" cellspacing="5"><tr valign="middle">
+<td width="100%" align="left" class="shortcuts"></td>
+<td><a accesskey="h" href="index.html"><img src="home.png" width="16" height="16" border="0" alt="Home"></a></td>
+<td><a accesskey="u" href="fonts-and-faces.html"><img src="up.png" width="16" height="16" border="0" alt="Up"></a></td>
+<td><a accesskey="p" href="fonts-and-faces-native-opentype.html"><img src="left.png" width="16" height="16" border="0" alt="Prev"></a></td>
+<td><a accesskey="n" href="shaping-and-shape-plans.html"><img src="right.png" width="16" height="16" border="0" alt="Next"></a></td>
+</tr></table>
+<div class="section">
+<div class="titlepage"><div><div><h2 class="title" style="clear: both">
+<a name="fonts-and-faces-variable"></a>Working with OpenType Variable Fonts</h2></div></div></div>
+<p>
+      If you are working with OpenType Variable Fonts, there are a few
+      additional functions you should use to specify the
+      variation-axis settings of your font object. Without doing so,
+      your variable font's font object can still be used, but only at
+      the default setting for every axis (which, of course, is
+      sometimes what you want, but does not cover general usage).
+    </p>
+<p>
+      HarfBuzz manages variation settings in the
+      <span class="type">hb_variation_t</span> data type, which holds a <span class="property">tag</span> for the
+      variation-axis identifier tag and a <span class="property">value</span> for its
+      setting. You can retrieve the list of variation axes in a font
+      binary from the face object (not from a font object, notably) by
+      calling <code class="function">hb_ot_var_get_axis_count(face)</code> to
+      find the number of axes, then using
+      <code class="function">hb_ot_var_get_axis_infos()</code> to collect the 
+      axis structures:
+    </p>
+<pre class="programlisting">
+      axes = hb_ot_var_get_axis_count(face);
+      ...
+      hb_ot_var_get_axis_infos(face, 0, axes, axes_array);
+    </pre>
+<p>
+      For each axis returned in the array, you can can access the
+      identifier in its <span class="property">tag</span>. HarfBuzz also has
+      tag definitions predefined for the five standard axes specified
+      in OpenType (<code class="literal">ital</code> for italic,
+      <code class="literal">opsz</code> for optical size,
+      <code class="literal">slnt</code> for slant, <code class="literal">wdth</code> for
+      width, and <code class="literal">wght</code> for weight). Each axis also
+      has a <span class="property">min_value</span>, a
+      <span class="property">default_value</span>, and a <span class="property">max_value</span>.
+    </p>
+<p>
+      To set your font object's variation settings, you call the
+      <code class="function">hb_font_set_variations()</code> function with an
+      array of <span class="type">hb_variation_t</span> variation settings. Let's
+      say our font has weight and width axes. We need to specify each
+      of the axes by tag and assign a value on the axis:
+    </p>
+<pre class="programlisting">
+      unsigned int variation_count = 2;
+      hb_variation_t variation_data[variation_count];
+      variation_data[0].tag = HB_OT_TAG_VAR_AXIS_WIDTH;
+      variation_data[1].tag = HB_OT_TAG_VAR_AXIS_WEIGHT;
+      variation_data[0].value = 80;
+      variation_data[1].value = 750;
+      ...
+      hb_font_set_variations(font, variation_data, variation_count);
+    </pre>
+<p>
+      That should give us a slightly condensed font ("normal" on the
+      <code class="literal">wdth</code> axis is 100) at a noticeably bolder
+      weight ("regular" is 400 on the <code class="literal">wght</code> axis).
+    </p>
+<p>
+      In practice, though, you should always check that the value you
+      want to set on the axis is within the
+      [<span class="property">min_value</span>,<span class="property">max_value</span>]
+      range actually implemented in the font's variation axis. After
+      all, a font might only provide lighter-than-regular weights, and
+      setting a heavier value on the <code class="literal">wght</code> axis will
+      not change that. 
+    </p>
+<p>
+      Once your variation settings are specified on your font object,
+      however, shaping with a variable font is just like shaping a
+      static font.
+    </p>
+</div>
+<div class="footer">
+<hr>Generated by GTK-Doc V1.29</div>
+</body>
+</html>
\ No newline at end of file
index b5b825f..97a1a7a 100644 (file)
@@ -2,12 +2,12 @@
 <html>
 <head>
 <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
-<title>Fonts and faces: HarfBuzz Manual</title>
+<title>Fonts, faces, and output: HarfBuzz Manual</title>
 <meta name="generator" content="DocBook XSL Stylesheets Vsnapshot">
 <link rel="home" href="index.html" title="HarfBuzz Manual">
 <link rel="up" href="pt01.html" title="Part I. User's manual">
 <link rel="prev" href="customizing-unicode-functions.html" title="Customizing Unicode functions">
-<link rel="next" href="using-harfbuzzs-native-opentype-implementation.html" title="Using HarfBuzz's native OpenType implementation">
+<link rel="next" href="fonts-and-faces-custom-functions.html" title="Customizing font functions">
 <meta name="generator" content="GTK-Doc V1.29 (XML mode)">
 <link rel="stylesheet" href="style.css" type="text/css">
 </head>
 <td><a accesskey="h" href="index.html"><img src="home.png" width="16" height="16" border="0" alt="Home"></a></td>
 <td><a accesskey="u" href="pt01.html"><img src="up.png" width="16" height="16" border="0" alt="Up"></a></td>
 <td><a accesskey="p" href="customizing-unicode-functions.html"><img src="left.png" width="16" height="16" border="0" alt="Prev"></a></td>
-<td><a accesskey="n" href="using-harfbuzzs-native-opentype-implementation.html"><img src="right.png" width="16" height="16" border="0" alt="Next"></a></td>
+<td><a accesskey="n" href="fonts-and-faces-custom-functions.html"><img src="right.png" width="16" height="16" border="0" alt="Next"></a></td>
 </tr></table>
 <div class="chapter">
 <div class="titlepage"><div><div><h2 class="title">
-<a name="fonts-and-faces"></a>Fonts and faces</h2></div></div></div>
+<a name="fonts-and-faces"></a>Fonts, faces, and output</h2></div></div></div>
 <div class="toc"><dl class="toc">
-<dt><span class="section"><a href="fonts-and-faces.html#using-freetype">Using FreeType</a></span></dt>
-<dt><span class="section"><a href="using-harfbuzzs-native-opentype-implementation.html">Using HarfBuzz's native OpenType implementation</a></span></dt>
-<dt><span class="section"><a href="using-your-own-font-functions.html">Using your own font functions</a></span></dt>
+<dt><span class="section"><a href="fonts-and-faces.html#fonts-and-faces-objects">Font and face objects</a></span></dt>
+<dt><span class="section"><a href="fonts-and-faces-custom-functions.html">Customizing font functions</a></span></dt>
+<dt><span class="section"><a href="fonts-and-faces-native-opentype.html">Font objects and HarfBuzz's native OpenType implementation</a></span></dt>
+<dt><span class="section"><a href="fonts-and-faces-variable.html">Working with OpenType Variable Fonts</a></span></dt>
 </dl></div>
+<p>
+      In the previous chapter, we saw how to set up a buffer and fill
+      it with text as Unicode code points. In order to shape this
+      buffer text with HarfBuzz, you will need also need a font
+      object.
+    </p>
+<p>
+      HarfBuzz provides abstractions to help you cache and reuse the
+      heavier parts of working with binary fonts, so we will look at
+      how to do that. We will also look at how to work with the
+      FreeType font-rendering library and at how you can customize
+      HarfBuzz to work with other libraries.
+    </p>
+<p>
+      Finally, we will look at how to work with OpenType variable
+      fonts, the latest update to the OpenType font format, and at
+      some other recent additions to OpenType.
+    </p>
 <div class="section">
 <div class="titlepage"><div><div><h2 class="title" style="clear: both">
-<a name="using-freetype"></a>Using FreeType</h2></div></div></div>
+<a name="fonts-and-faces-objects"></a>Font and face objects</h2></div></div></div>
+<p>
+      The outcome of shaping a run of text depends on the contents of
+      a specific font file (such as the substitutions and positioning
+      moves in the 'GSUB' and 'GPOS' tables), so HarfBuzz makes
+      accessing those internals fast.
+    </p>
+<p>
+      An <span class="type">hb_face_t</span> represents a <span class="emphasis"><em>face</em></span>
+      in HarfBuzz. This data type is a wrapper around an
+      <span class="type">hb_blob_t</span> blob that holds the contents of a binary
+      font file. Since HarfBuzz supports TrueType Collections and
+      OpenType Collections (each of which can include multiple
+      typefaces), a HarfBuzz face also requires an index number
+      specifying which typeface in the file you want to use. Most of
+      the font files you will encounter in the wild include just a
+      single face, however, so most of the time you would pass in
+      <code class="literal">0</code> as the index when you create a face:
+    </p>
+<pre class="programlisting">
+      hb_blob_t* blob = hb_blob_create_from_file(file);
+      ...
+      hb_face_t* face = hb_face_create(blob, 0);
+    </pre>
+<p>
+      On its own, a face object is not quite ready to use for
+      shaping. The typeface must be set to a specific point size in
+      order for some details (such as hinting) to work. In addition,
+      if the font file in question is an OpenType Variable Font, then
+      you may need to specify one or variation-axis settings (or a
+      named instance) in order to get the output you need.
+    </p>
+<p>
+      In HarfBuzz, you do this by creating a <span class="emphasis"><em>font</em></span>
+      object from your face.
+    </p>
+<p>
+      Font objects also have the advantage of being considerably
+      lighter-weight than face objects (remember that a face contains
+      the contents of a binary font file mapped into memory). As a
+      result, you can cache and reuse a font object, but you could
+      also create a new one for each additional size you needed.
+      Creating new fonts incurs some additional overhead, of course,
+      but whether or not it is excessive is your call in the end. In
+      contrast, face objects are substantially larger, and you really
+      should cache them and reuse them whenever possible.
+    </p>
+<p>
+      You can create a font object from a face object:
+    </p>
+<pre class="programlisting">
+      hb_font_t* hb_font = hb_font_create(hb_face);
+    </pre>
+<p>
+      After creating a font, there are a few properties you should
+      set. Many fonts enable and disable hints based on the size it
+      is used at, so setting this is important for font
+      objects. <code class="function">hb_font_set_ppem(font, x_ppem,
+      y_ppem)</code> sets the pixels-per-EM value of the font. You
+      can also set the point size of the font with
+      <code class="function">hb_font_set_ptem(font, ptem)</code>. HarfBuzz uses the
+      industry standard 72 points per inch.
+    </p>
+<p>
+      HarfBuzz lets you specify the degree subpixel precision you want
+      through a scaling factor. You can set horizontal and
+      vertical scaling factors on the
+      font by calling <code class="function">hb_font_set_scale(font, x_scale,
+      y_scale)</code>. 
+    </p>
+<p>
+      There may be times when you are handed a font object and need to
+      access the face object that it comes from. For that, you can call
+    </p>
+<pre class="programlisting">
+      hb_face = hb_font_get_face(hb_font);
+    </pre>
+<p>
+      You can also create a font object from an existing font object
+      using the <code class="function">hb_font_create_sub_font()</code>
+      function. This creates a child font object that is initiated
+      with the same attributes as its parent; it can be used to
+      quickly set up a new font for the purpose of overriding a specific
+      font-functions method.
+    </p>
+<p>
+      All face objects and font objects are lifecycle-managed by
+      HarfBuzz. After creating a face, you increase its reference
+      count with <code class="function">hb_face_reference(face)</code> and
+      decrease it with
+      <code class="function">hb_face_destroy(face)</code>. Likewise, you
+      increase the reference count on a font with
+      <code class="function">hb_font_reference(font)</code> and decrease it
+      with <code class="function">hb_font_destroy(font)</code>.
+    </p>
 <p>
+      You can also attach user data to face objects and font objects.
     </p>
 </div>
 </div>
index 55c8b1c..b2e3e01 100644 (file)
@@ -5,9 +5,9 @@
 <title>hb-aat-layout: HarfBuzz Manual</title>
 <meta name="generator" content="DocBook XSL Stylesheets Vsnapshot">
 <link rel="home" href="index.html" title="HarfBuzz Manual">
-<link rel="up" href="ch11.html" title="Apple Advanced Typography API">
-<link rel="prev" href="ch11.html" title="Apple Advanced Typography API">
-<link rel="next" href="ch12.html" title="Integration API">
+<link rel="up" href="ch13.html" title="Apple Advanced Typography API">
+<link rel="prev" href="ch13.html" title="Apple Advanced Typography API">
+<link rel="next" href="ch14.html" title="Integration API">
 <meta name="generator" content="GTK-Doc V1.29 (XML mode)">
 <link rel="stylesheet" href="style.css" type="text/css">
 </head>
 <table class="navigation" id="top" width="100%" summary="Navigation header" cellpadding="2" cellspacing="5"><tr valign="middle">
 <td width="100%" align="left" class="shortcuts">
 <a href="#" class="shortcut">Top</a><span id="nav_description">  <span class="dim">|</span> 
-                  <a href="#harfbuzz-hb-aat-layout.description" class="shortcut">Description</a></span>
+                  <a href="#harfbuzz-hb-aat-layout.description" class="shortcut">Description</a></span><span id="nav_hierarchy">  <span class="dim">|</span> 
+                  <a href="#harfbuzz-hb-aat-layout.object-hierarchy" class="shortcut">Object Hierarchy</a></span>
 </td>
 <td><a accesskey="h" href="index.html"><img src="home.png" width="16" height="16" border="0" alt="Home"></a></td>
-<td><a accesskey="u" href="ch11.html"><img src="up.png" width="16" height="16" border="0" alt="Up"></a></td>
-<td><a accesskey="p" href="ch11.html"><img src="left.png" width="16" height="16" border="0" alt="Prev"></a></td>
-<td><a accesskey="n" href="ch12.html"><img src="right.png" width="16" height="16" border="0" alt="Next"></a></td>
+<td><a accesskey="u" href="ch13.html"><img src="up.png" width="16" height="16" border="0" alt="Up"></a></td>
+<td><a accesskey="p" href="ch13.html"><img src="left.png" width="16" height="16" border="0" alt="Prev"></a></td>
+<td><a accesskey="n" href="ch14.html"><img src="right.png" width="16" height="16" border="0" alt="Next"></a></td>
 </tr></table>
 <div class="refentry">
 <a name="harfbuzz-hb-aat-layout"></a><div class="titlepage"></div>
 </table></div>
 </div>
 <div class="refsect1">
+<a name="harfbuzz-hb-aat-layout.object-hierarchy"></a><h2>Object Hierarchy</h2>
+<pre class="screen">    <a href="/usr/share/gtk-doc/html/gobject/gobject-Enumeration-and-Flag-Types.html">GEnum</a>
+    <span class="lineart">├──</span> hb_aat_layout_feature_selector_t
+    <span class="lineart">╰──</span> hb_aat_layout_feature_type_t
+</pre>
+</div>
+<div class="refsect1">
 <a name="harfbuzz-hb-aat-layout.includes"></a><h2>Includes</h2>
 <pre class="synopsis">#include &lt;hb-aat.h&gt;
 </pre>
 <a name="hb-aat-layout-feature-type-get-name-id"></a><h3>hb_aat_layout_feature_type_get_name_id ()</h3>
 <pre class="programlisting"><a class="link" href="harfbuzz-hb-ot-name.html#hb-ot-name-id-t" title="hb_ot_name_id_t"><span class="returnvalue">hb_ot_name_id_t</span></a>
 hb_aat_layout_feature_type_get_name_id
-                               (<em class="parameter"><code><a class="link" href="harfbuzz-hb-face.html#hb-face-t" title="hb_face_t"><span class="type">hb_face_t</span></a> *face</code></em>,
+                               (<em class="parameter"><code><a class="link" href="harfbuzz-hb-face.html#hb-face-t"><span class="type">hb_face_t</span></a> *face</code></em>,
                                 <em class="parameter"><code><a class="link" href="harfbuzz-hb-aat-layout.html#hb-aat-layout-feature-type-t" title="enum hb_aat_layout_feature_type_t"><span class="type">hb_aat_layout_feature_type_t</span></a> feature_type</code></em>);</pre>
 <div class="refsect3">
 <a name="hb-aat-layout-feature-type-get-name-id.parameters"></a><h4>Parameters</h4>
@@ -161,7 +169,7 @@ hb_aat_layout_feature_type_get_name_id
 <a name="hb-aat-layout-feature-type-get-selector-infos"></a><h3>hb_aat_layout_feature_type_get_selector_infos ()</h3>
 <pre class="programlisting">unsigned <span class="returnvalue">int</span>
 hb_aat_layout_feature_type_get_selector_infos
-                               (<em class="parameter"><code><a class="link" href="harfbuzz-hb-face.html#hb-face-t" title="hb_face_t"><span class="type">hb_face_t</span></a> *face</code></em>,
+                               (<em class="parameter"><code><a class="link" href="harfbuzz-hb-face.html#hb-face-t"><span class="type">hb_face_t</span></a> *face</code></em>,
                                 <em class="parameter"><code><a class="link" href="harfbuzz-hb-aat-layout.html#hb-aat-layout-feature-type-t" title="enum hb_aat_layout_feature_type_t"><span class="type">hb_aat_layout_feature_type_t</span></a> feature_type</code></em>,
                                 <em class="parameter"><code>unsigned <span class="type">int</span> start_offset</code></em>,
                                 <em class="parameter"><code>unsigned <span class="type">int</span> *selector_count</code></em>,
@@ -172,7 +180,7 @@ hb_aat_layout_feature_type_get_selector_infos
 <div class="refsect2">
 <a name="hb-aat-layout-get-feature-types"></a><h3>hb_aat_layout_get_feature_types ()</h3>
 <pre class="programlisting">unsigned <span class="returnvalue">int</span>
-hb_aat_layout_get_feature_types (<em class="parameter"><code><a class="link" href="harfbuzz-hb-face.html#hb-face-t" title="hb_face_t"><span class="type">hb_face_t</span></a> *face</code></em>,
+hb_aat_layout_get_feature_types (<em class="parameter"><code><a class="link" href="harfbuzz-hb-face.html#hb-face-t"><span class="type">hb_face_t</span></a> *face</code></em>,
                                  <em class="parameter"><code>unsigned <span class="type">int</span> start_offset</code></em>,
                                  <em class="parameter"><code>unsigned <span class="type">int</span> *feature_count</code></em>,
                                  <em class="parameter"><code><a class="link" href="harfbuzz-hb-aat-layout.html#hb-aat-layout-feature-type-t" title="enum hb_aat_layout_feature_type_t"><span class="type">hb_aat_layout_feature_type_t</span></a> *features</code></em>);</pre>
@@ -218,19 +226,19 @@ hb_aat_layout_get_feature_types (<em class="parameter"><code><a class="link" hre
 <div class="refsect2">
 <a name="hb-aat-layout-has-positioning"></a><h3>hb_aat_layout_has_positioning ()</h3>
 <pre class="programlisting"><a class="link" href="harfbuzz-hb-common.html#hb-bool-t" title="hb_bool_t"><span class="returnvalue">hb_bool_t</span></a>
-hb_aat_layout_has_positioning (<em class="parameter"><code><a class="link" href="harfbuzz-hb-face.html#hb-face-t" title="hb_face_t"><span class="type">hb_face_t</span></a> *face</code></em>);</pre>
+hb_aat_layout_has_positioning (<em class="parameter"><code><a class="link" href="harfbuzz-hb-face.html#hb-face-t"><span class="type">hb_face_t</span></a> *face</code></em>);</pre>
 </div>
 <hr>
 <div class="refsect2">
 <a name="hb-aat-layout-has-substitution"></a><h3>hb_aat_layout_has_substitution ()</h3>
 <pre class="programlisting"><a class="link" href="harfbuzz-hb-common.html#hb-bool-t" title="hb_bool_t"><span class="returnvalue">hb_bool_t</span></a>
-hb_aat_layout_has_substitution (<em class="parameter"><code><a class="link" href="harfbuzz-hb-face.html#hb-face-t" title="hb_face_t"><span class="type">hb_face_t</span></a> *face</code></em>);</pre>
+hb_aat_layout_has_substitution (<em class="parameter"><code><a class="link" href="harfbuzz-hb-face.html#hb-face-t"><span class="type">hb_face_t</span></a> *face</code></em>);</pre>
 </div>
 <hr>
 <div class="refsect2">
 <a name="hb-aat-layout-has-tracking"></a><h3>hb_aat_layout_has_tracking ()</h3>
 <pre class="programlisting"><a class="link" href="harfbuzz-hb-common.html#hb-bool-t" title="hb_bool_t"><span class="returnvalue">hb_bool_t</span></a>
-hb_aat_layout_has_tracking (<em class="parameter"><code><a class="link" href="harfbuzz-hb-face.html#hb-face-t" title="hb_face_t"><span class="type">hb_face_t</span></a> *face</code></em>);</pre>
+hb_aat_layout_has_tracking (<em class="parameter"><code><a class="link" href="harfbuzz-hb-face.html#hb-face-t"><span class="type">hb_face_t</span></a> *face</code></em>);</pre>
 </div>
 </div>
 <div class="refsect1">
index f6ff6e7..6a4cf42 100644 (file)
@@ -5,8 +5,8 @@
 <title>hb-blob: HarfBuzz Manual</title>
 <meta name="generator" content="DocBook XSL Stylesheets Vsnapshot">
 <link rel="home" href="index.html" title="HarfBuzz Manual">
-<link rel="up" href="ch09.html" title="Core API">
-<link rel="prev" href="ch09.html" title="Core API">
+<link rel="up" href="ch11.html" title="Core API">
+<link rel="prev" href="ch11.html" title="Core API">
 <link rel="next" href="harfbuzz-hb-buffer.html" title="hb-buffer">
 <meta name="generator" content="GTK-Doc V1.29 (XML mode)">
 <link rel="stylesheet" href="style.css" type="text/css">
 <table class="navigation" id="top" width="100%" summary="Navigation header" cellpadding="2" cellspacing="5"><tr valign="middle">
 <td width="100%" align="left" class="shortcuts">
 <a href="#" class="shortcut">Top</a><span id="nav_description">  <span class="dim">|</span> 
-                  <a href="#harfbuzz-hb-blob.description" class="shortcut">Description</a></span>
+                  <a href="#harfbuzz-hb-blob.description" class="shortcut">Description</a></span><span id="nav_hierarchy">  <span class="dim">|</span> 
+                  <a href="#harfbuzz-hb-blob.object-hierarchy" class="shortcut">Object Hierarchy</a></span>
 </td>
 <td><a accesskey="h" href="index.html"><img src="home.png" width="16" height="16" border="0" alt="Home"></a></td>
-<td><a accesskey="u" href="ch09.html"><img src="up.png" width="16" height="16" border="0" alt="Up"></a></td>
-<td><a accesskey="p" href="ch09.html"><img src="left.png" width="16" height="16" border="0" alt="Prev"></a></td>
+<td><a accesskey="u" href="ch11.html"><img src="up.png" width="16" height="16" border="0" alt="Up"></a></td>
+<td><a accesskey="p" href="ch11.html"><img src="left.png" width="16" height="16" border="0" alt="Prev"></a></td>
 <td><a accesskey="n" href="harfbuzz-hb-buffer.html"><img src="right.png" width="16" height="16" border="0" alt="Next"></a></td>
 </tr></table>
 <div class="refentry">
@@ -41,7 +42,7 @@
 <tbody>
 <tr>
 <td class="function_type">
-<a class="link" href="harfbuzz-hb-blob.html#hb-blob-t" title="hb_blob_t"><span class="returnvalue">hb_blob_t</span></a> *
+<a class="link" href="harfbuzz-hb-blob.html#hb-blob-t"><span class="returnvalue">hb_blob_t</span></a> *
 </td>
 <td class="function_name">
 <a class="link" href="harfbuzz-hb-blob.html#hb-blob-create" title="hb_blob_create ()">hb_blob_create</a> <span class="c_punctuation">()</span>
@@ -49,7 +50,7 @@
 </tr>
 <tr>
 <td class="function_type">
-<a class="link" href="harfbuzz-hb-blob.html#hb-blob-t" title="hb_blob_t"><span class="returnvalue">hb_blob_t</span></a> *
+<a class="link" href="harfbuzz-hb-blob.html#hb-blob-t"><span class="returnvalue">hb_blob_t</span></a> *
 </td>
 <td class="function_name">
 <a class="link" href="harfbuzz-hb-blob.html#hb-blob-create-from-file" title="hb_blob_create_from_file ()">hb_blob_create_from_file</a> <span class="c_punctuation">()</span>
@@ -57,7 +58,7 @@
 </tr>
 <tr>
 <td class="function_type">
-<a class="link" href="harfbuzz-hb-blob.html#hb-blob-t" title="hb_blob_t"><span class="returnvalue">hb_blob_t</span></a> *
+<a class="link" href="harfbuzz-hb-blob.html#hb-blob-t"><span class="returnvalue">hb_blob_t</span></a> *
 </td>
 <td class="function_name">
 <a class="link" href="harfbuzz-hb-blob.html#hb-blob-create-sub-blob" title="hb_blob_create_sub_blob ()">hb_blob_create_sub_blob</a> <span class="c_punctuation">()</span>
@@ -65,7 +66,7 @@
 </tr>
 <tr>
 <td class="function_type">
-<a class="link" href="harfbuzz-hb-blob.html#hb-blob-t" title="hb_blob_t"><span class="returnvalue">hb_blob_t</span></a> *
+<a class="link" href="harfbuzz-hb-blob.html#hb-blob-t"><span class="returnvalue">hb_blob_t</span></a> *
 </td>
 <td class="function_name">
 <a class="link" href="harfbuzz-hb-blob.html#hb-blob-copy-writable-or-fail" title="hb_blob_copy_writable_or_fail ()">hb_blob_copy_writable_or_fail</a> <span class="c_punctuation">()</span>
@@ -96,7 +97,7 @@
 </tr>
 <tr>
 <td class="function_type">
-<a class="link" href="harfbuzz-hb-blob.html#hb-blob-t" title="hb_blob_t"><span class="returnvalue">hb_blob_t</span></a> *
+<a class="link" href="harfbuzz-hb-blob.html#hb-blob-t"><span class="returnvalue">hb_blob_t</span></a> *
 </td>
 <td class="function_name">
 <a class="link" href="harfbuzz-hb-blob.html#hb-blob-get-empty" title="hb_blob_get_empty ()">hb_blob_get_empty</a> <span class="c_punctuation">()</span>
 </tr>
 <tr>
 <td class="function_type">
-<a class="link" href="harfbuzz-hb-blob.html#hb-blob-t" title="hb_blob_t"><span class="returnvalue">hb_blob_t</span></a> *
+<a class="link" href="harfbuzz-hb-blob.html#hb-blob-t"><span class="returnvalue">hb_blob_t</span></a> *
 </td>
 <td class="function_name">
 <a class="link" href="harfbuzz-hb-blob.html#hb-blob-reference" title="hb_blob_reference ()">hb_blob_reference</a> <span class="c_punctuation">()</span>
 </tbody>
 </table></div>
 </div>
-<div class="refsect1">
+<a name="hb-blob-t"></a><div class="refsect1">
 <a name="harfbuzz-hb-blob.other"></a><h2>Types and Values</h2>
 <div class="informaltable"><table class="informaltable" width="100%" border="0">
 <colgroup>
 <tbody>
 <tr>
 <td class="typedef_keyword">typedef</td>
-<td class="function_name"><a class="link" href="harfbuzz-hb-blob.html#hb-blob-t" title="hb_blob_t">hb_blob_t</a></td>
+<td class="function_name"><a class="link" href="harfbuzz-hb-blob.html#hb-blob-t">hb_blob_t</a></td>
 </tr>
 <tr>
 <td class="datatype_keyword">enum</td>
 </table></div>
 </div>
 <div class="refsect1">
+<a name="harfbuzz-hb-blob.object-hierarchy"></a><h2>Object Hierarchy</h2>
+<pre class="screen">    <a href="/usr/share/gtk-doc/html/gobject/gobject-Boxed-Types.html">GBoxed</a>
+    <span class="lineart">╰──</span> hb_blob_t
+    <a href="/usr/share/gtk-doc/html/gobject/gobject-Enumeration-and-Flag-Types.html">GEnum</a>
+    <span class="lineart">╰──</span> hb_memory_mode_t
+</pre>
+</div>
+<div class="refsect1">
 <a name="harfbuzz-hb-blob.includes"></a><h2>Includes</h2>
 <pre class="synopsis">#include &lt;hb.h&gt;
 </pre>
@@ -187,7 +196,7 @@ pass around other binary data.</p>
 <a name="harfbuzz-hb-blob.functions_details"></a><h2>Functions</h2>
 <div class="refsect2">
 <a name="hb-blob-create"></a><h3>hb_blob_create ()</h3>
-<pre class="programlisting"><a class="link" href="harfbuzz-hb-blob.html#hb-blob-t" title="hb_blob_t"><span class="returnvalue">hb_blob_t</span></a> *
+<pre class="programlisting"><a class="link" href="harfbuzz-hb-blob.html#hb-blob-t"><span class="returnvalue">hb_blob_t</span></a> *
 hb_blob_create (<em class="parameter"><code>const <span class="type">char</span> *data</code></em>,
                 <em class="parameter"><code>unsigned <span class="type">int</span> length</code></em>,
                 <em class="parameter"><code><a class="link" href="harfbuzz-hb-blob.html#hb-memory-mode-t" title="enum hb_memory_mode_t"><span class="type">hb_memory_mode_t</span></a> mode</code></em>,
@@ -251,7 +260,7 @@ zero.  Destroy with <a class="link" href="harfbuzz-hb-blob.html#hb-blob-destroy"
 <hr>
 <div class="refsect2">
 <a name="hb-blob-create-from-file"></a><h3>hb_blob_create_from_file ()</h3>
-<pre class="programlisting"><a class="link" href="harfbuzz-hb-blob.html#hb-blob-t" title="hb_blob_t"><span class="returnvalue">hb_blob_t</span></a> *
+<pre class="programlisting"><a class="link" href="harfbuzz-hb-blob.html#hb-blob-t"><span class="returnvalue">hb_blob_t</span></a> *
 hb_blob_create_from_file (<em class="parameter"><code>const <span class="type">char</span> *file_name</code></em>);</pre>
 <div class="refsect3">
 <a name="hb-blob-create-from-file.parameters"></a><h4>Parameters</h4>
@@ -277,8 +286,8 @@ hb_blob_create_from_file (<em class="parameter"><code>const <span class="type">c
 <hr>
 <div class="refsect2">
 <a name="hb-blob-create-sub-blob"></a><h3>hb_blob_create_sub_blob ()</h3>
-<pre class="programlisting"><a class="link" href="harfbuzz-hb-blob.html#hb-blob-t" title="hb_blob_t"><span class="returnvalue">hb_blob_t</span></a> *
-hb_blob_create_sub_blob (<em class="parameter"><code><a class="link" href="harfbuzz-hb-blob.html#hb-blob-t" title="hb_blob_t"><span class="type">hb_blob_t</span></a> *parent</code></em>,
+<pre class="programlisting"><a class="link" href="harfbuzz-hb-blob.html#hb-blob-t"><span class="returnvalue">hb_blob_t</span></a> *
+hb_blob_create_sub_blob (<em class="parameter"><code><a class="link" href="harfbuzz-hb-blob.html#hb-blob-t"><span class="type">hb_blob_t</span></a> *parent</code></em>,
                          <em class="parameter"><code>unsigned <span class="type">int</span> offset</code></em>,
                          <em class="parameter"><code>unsigned <span class="type">int</span> length</code></em>);</pre>
 <p>Returns a blob that represents a range of bytes in <em class="parameter"><code>parent</code></em>
@@ -331,8 +340,8 @@ with <a class="link" href="harfbuzz-hb-blob.html#hb-blob-destroy" title="hb_blob
 <hr>
 <div class="refsect2">
 <a name="hb-blob-copy-writable-or-fail"></a><h3>hb_blob_copy_writable_or_fail ()</h3>
-<pre class="programlisting"><a class="link" href="harfbuzz-hb-blob.html#hb-blob-t" title="hb_blob_t"><span class="returnvalue">hb_blob_t</span></a> *
-hb_blob_copy_writable_or_fail (<em class="parameter"><code><a class="link" href="harfbuzz-hb-blob.html#hb-blob-t" title="hb_blob_t"><span class="type">hb_blob_t</span></a> *blob</code></em>);</pre>
+<pre class="programlisting"><a class="link" href="harfbuzz-hb-blob.html#hb-blob-t"><span class="returnvalue">hb_blob_t</span></a> *
+hb_blob_copy_writable_or_fail (<em class="parameter"><code><a class="link" href="harfbuzz-hb-blob.html#hb-blob-t"><span class="type">hb_blob_t</span></a> *blob</code></em>);</pre>
 <p>Makes a writable copy of <em class="parameter"><code>blob</code></em>
 .</p>
 <div class="refsect3">
@@ -360,7 +369,7 @@ hb_blob_copy_writable_or_fail (<em class="parameter"><code><a class="link" href=
 <div class="refsect2">
 <a name="hb-blob-destroy"></a><h3>hb_blob_destroy ()</h3>
 <pre class="programlisting"><span class="returnvalue">void</span>
-hb_blob_destroy (<em class="parameter"><code><a class="link" href="harfbuzz-hb-blob.html#hb-blob-t" title="hb_blob_t"><span class="type">hb_blob_t</span></a> *blob</code></em>);</pre>
+hb_blob_destroy (<em class="parameter"><code><a class="link" href="harfbuzz-hb-blob.html#hb-blob-t"><span class="type">hb_blob_t</span></a> *blob</code></em>);</pre>
 <p>Decreases the reference count on <em class="parameter"><code>blob</code></em>
 , and if it reaches zero, destroys
 <em class="parameter"><code>blob</code></em>
@@ -389,7 +398,7 @@ was created for if it has not been called already.</p>
 <div class="refsect2">
 <a name="hb-blob-get-data"></a><h3>hb_blob_get_data ()</h3>
 <pre class="programlisting">const <span class="returnvalue">char</span> *
-hb_blob_get_data (<em class="parameter"><code><a class="link" href="harfbuzz-hb-blob.html#hb-blob-t" title="hb_blob_t"><span class="type">hb_blob_t</span></a> *blob</code></em>,
+hb_blob_get_data (<em class="parameter"><code><a class="link" href="harfbuzz-hb-blob.html#hb-blob-t"><span class="type">hb_blob_t</span></a> *blob</code></em>,
                   <em class="parameter"><code>unsigned <span class="type">int</span> *length</code></em>);</pre>
 <div class="refsect3">
 <a name="hb-blob-get-data.parameters"></a><h4>Parameters</h4>
@@ -424,7 +433,7 @@ hb_blob_get_data (<em class="parameter"><code><a class="link" href="harfbuzz-hb-
 <div class="refsect2">
 <a name="hb-blob-get-data-writable"></a><h3>hb_blob_get_data_writable ()</h3>
 <pre class="programlisting"><span class="returnvalue">char</span> *
-hb_blob_get_data_writable (<em class="parameter"><code><a class="link" href="harfbuzz-hb-blob.html#hb-blob-t" title="hb_blob_t"><span class="type">hb_blob_t</span></a> *blob</code></em>,
+hb_blob_get_data_writable (<em class="parameter"><code><a class="link" href="harfbuzz-hb-blob.html#hb-blob-t"><span class="type">hb_blob_t</span></a> *blob</code></em>,
                            <em class="parameter"><code>unsigned <span class="type">int</span> *length</code></em>);</pre>
 <p>Tries to make blob data writable (possibly copying it) and
 return pointer to data.</p>
@@ -455,7 +464,7 @@ fails.</p>
 <div class="refsect3">
 <a name="hb-blob-get-data-writable.returns"></a><h4>Returns</h4>
 <p>Writable blob data,
-or <a href="/usr/share/gtk-doc/html/glib/glib-Standard-Macros.html#NULL:CAPS"><code class="literal">NULL</code></a> if failed. </p>
+or <code class="literal">NULL</code> if failed. </p>
 <p><span class="annotation">[<acronym title="Don't free data after the code is done."><span class="acronym">transfer none</span></acronym>][<acronym title="Parameter points to an array of items."><span class="acronym">array</span></acronym> length=length]</span></p>
 </div>
 <p class="since">Since: <a class="link" href="api-index-0-9-2.html#api-index-0.9.2">0.9.2</a></p>
@@ -463,7 +472,7 @@ or <a href="/usr/share/gtk-doc/html/glib/glib-Standard-Macros.html#NULL:CAPS"><c
 <hr>
 <div class="refsect2">
 <a name="hb-blob-get-empty"></a><h3>hb_blob_get_empty ()</h3>
-<pre class="programlisting"><a class="link" href="harfbuzz-hb-blob.html#hb-blob-t" title="hb_blob_t"><span class="returnvalue">hb_blob_t</span></a> *
+<pre class="programlisting"><a class="link" href="harfbuzz-hb-blob.html#hb-blob-t"><span class="returnvalue">hb_blob_t</span></a> *
 hb_blob_get_empty (<em class="parameter"><code><span class="type">void</span></code></em>);</pre>
 <p>Returns the singleton empty blob.</p>
 <p>See TODO:link object types for more information.</p>
@@ -478,7 +487,7 @@ hb_blob_get_empty (<em class="parameter"><code><span class="type">void</span></c
 <div class="refsect2">
 <a name="hb-blob-get-length"></a><h3>hb_blob_get_length ()</h3>
 <pre class="programlisting">unsigned <span class="returnvalue">int</span>
-hb_blob_get_length (<em class="parameter"><code><a class="link" href="harfbuzz-hb-blob.html#hb-blob-t" title="hb_blob_t"><span class="type">hb_blob_t</span></a> *blob</code></em>);</pre>
+hb_blob_get_length (<em class="parameter"><code><a class="link" href="harfbuzz-hb-blob.html#hb-blob-t"><span class="type">hb_blob_t</span></a> *blob</code></em>);</pre>
 <div class="refsect3">
 <a name="hb-blob-get-length.parameters"></a><h4>Parameters</h4>
 <div class="informaltable"><table class="informaltable" width="100%" border="0">
@@ -504,8 +513,8 @@ hb_blob_get_length (<em class="parameter"><code><a class="link" href="harfbuzz-h
 <div class="refsect2">
 <a name="hb-blob-get-user-data"></a><h3>hb_blob_get_user_data ()</h3>
 <pre class="programlisting"><span class="returnvalue">void</span> *
-hb_blob_get_user_data (<em class="parameter"><code><a class="link" href="harfbuzz-hb-blob.html#hb-blob-t" title="hb_blob_t"><span class="type">hb_blob_t</span></a> *blob</code></em>,
-                       <em class="parameter"><code><a class="link" href="harfbuzz-hb-common.html#hb-user-data-key-t" title="hb_user_data_key_t"><span class="type">hb_user_data_key_t</span></a> *key</code></em>);</pre>
+hb_blob_get_user_data (<em class="parameter"><code><a class="link" href="harfbuzz-hb-blob.html#hb-blob-t"><span class="type">hb_blob_t</span></a> *blob</code></em>,
+                       <em class="parameter"><code><a class="link" href="harfbuzz-hb-common.html#hb-user-data-key-t"><span class="type">hb_user_data_key_t</span></a> *key</code></em>);</pre>
 <p><span class="annotation">[<acronym title="Exposed in C code, not necessarily available in other languages."><span class="acronym">skip</span></acronym>]</span></p>
 <div class="refsect3">
 <a name="hb-blob-get-user-data.parameters"></a><h4>Parameters</h4>
@@ -540,7 +549,7 @@ hb_blob_get_user_data (<em class="parameter"><code><a class="link" href="harfbuz
 <div class="refsect2">
 <a name="hb-blob-is-immutable"></a><h3>hb_blob_is_immutable ()</h3>
 <pre class="programlisting"><a class="link" href="harfbuzz-hb-common.html#hb-bool-t" title="hb_bool_t"><span class="returnvalue">hb_bool_t</span></a>
-hb_blob_is_immutable (<em class="parameter"><code><a class="link" href="harfbuzz-hb-blob.html#hb-blob-t" title="hb_blob_t"><span class="type">hb_blob_t</span></a> *blob</code></em>);</pre>
+hb_blob_is_immutable (<em class="parameter"><code><a class="link" href="harfbuzz-hb-blob.html#hb-blob-t"><span class="type">hb_blob_t</span></a> *blob</code></em>);</pre>
 <div class="refsect3">
 <a name="hb-blob-is-immutable.parameters"></a><h4>Parameters</h4>
 <div class="informaltable"><table class="informaltable" width="100%" border="0">
@@ -566,7 +575,7 @@ hb_blob_is_immutable (<em class="parameter"><code><a class="link" href="harfbuzz
 <div class="refsect2">
 <a name="hb-blob-make-immutable"></a><h3>hb_blob_make_immutable ()</h3>
 <pre class="programlisting"><span class="returnvalue">void</span>
-hb_blob_make_immutable (<em class="parameter"><code><a class="link" href="harfbuzz-hb-blob.html#hb-blob-t" title="hb_blob_t"><span class="type">hb_blob_t</span></a> *blob</code></em>);</pre>
+hb_blob_make_immutable (<em class="parameter"><code><a class="link" href="harfbuzz-hb-blob.html#hb-blob-t"><span class="type">hb_blob_t</span></a> *blob</code></em>);</pre>
 <div class="refsect3">
 <a name="hb-blob-make-immutable.parameters"></a><h4>Parameters</h4>
 <div class="informaltable"><table class="informaltable" width="100%" border="0">
@@ -587,8 +596,8 @@ hb_blob_make_immutable (<em class="parameter"><code><a class="link" href="harfbu
 <hr>
 <div class="refsect2">
 <a name="hb-blob-reference"></a><h3>hb_blob_reference ()</h3>
-<pre class="programlisting"><a class="link" href="harfbuzz-hb-blob.html#hb-blob-t" title="hb_blob_t"><span class="returnvalue">hb_blob_t</span></a> *
-hb_blob_reference (<em class="parameter"><code><a class="link" href="harfbuzz-hb-blob.html#hb-blob-t" title="hb_blob_t"><span class="type">hb_blob_t</span></a> *blob</code></em>);</pre>
+<pre class="programlisting"><a class="link" href="harfbuzz-hb-blob.html#hb-blob-t"><span class="returnvalue">hb_blob_t</span></a> *
+hb_blob_reference (<em class="parameter"><code><a class="link" href="harfbuzz-hb-blob.html#hb-blob-t"><span class="type">hb_blob_t</span></a> *blob</code></em>);</pre>
 <p>Increases the reference count on <em class="parameter"><code>blob</code></em>
 .</p>
 <p>See TODO:link object types for more information.</p>
@@ -619,8 +628,8 @@ hb_blob_reference (<em class="parameter"><code><a class="link" href="harfbuzz-hb
 <div class="refsect2">
 <a name="hb-blob-set-user-data"></a><h3>hb_blob_set_user_data ()</h3>
 <pre class="programlisting"><a class="link" href="harfbuzz-hb-common.html#hb-bool-t" title="hb_bool_t"><span class="returnvalue">hb_bool_t</span></a>
-hb_blob_set_user_data (<em class="parameter"><code><a class="link" href="harfbuzz-hb-blob.html#hb-blob-t" title="hb_blob_t"><span class="type">hb_blob_t</span></a> *blob</code></em>,
-                       <em class="parameter"><code><a class="link" href="harfbuzz-hb-common.html#hb-user-data-key-t" title="hb_user_data_key_t"><span class="type">hb_user_data_key_t</span></a> *key</code></em>,
+hb_blob_set_user_data (<em class="parameter"><code><a class="link" href="harfbuzz-hb-blob.html#hb-blob-t"><span class="type">hb_blob_t</span></a> *blob</code></em>,
+                       <em class="parameter"><code><a class="link" href="harfbuzz-hb-common.html#hb-user-data-key-t"><span class="type">hb_user_data_key_t</span></a> *key</code></em>,
                        <em class="parameter"><code><span class="type">void</span> *data</code></em>,
                        <em class="parameter"><code><a class="link" href="harfbuzz-hb-common.html#hb-destroy-func-t" title="hb_destroy_func_t ()"><span class="type">hb_destroy_func_t</span></a> destroy</code></em>,
                        <em class="parameter"><code><a class="link" href="harfbuzz-hb-common.html#hb-bool-t" title="hb_bool_t"><span class="type">hb_bool_t</span></a> replace</code></em>);</pre>
index 1aeee6f..0ab8ae1 100644 (file)
@@ -5,7 +5,7 @@
 <title>hb-buffer: HarfBuzz Manual</title>
 <meta name="generator" content="DocBook XSL Stylesheets Vsnapshot">
 <link rel="home" href="index.html" title="HarfBuzz Manual">
-<link rel="up" href="ch09.html" title="Core API">
+<link rel="up" href="ch11.html" title="Core API">
 <link rel="prev" href="harfbuzz-hb-blob.html" title="hb-blob">
 <link rel="next" href="harfbuzz-hb-common.html" title="hb-common">
 <meta name="generator" content="GTK-Doc V1.29 (XML mode)">
 <table class="navigation" id="top" width="100%" summary="Navigation header" cellpadding="2" cellspacing="5"><tr valign="middle">
 <td width="100%" align="left" class="shortcuts">
 <a href="#" class="shortcut">Top</a><span id="nav_description">  <span class="dim">|</span> 
-                  <a href="#harfbuzz-hb-buffer.description" class="shortcut">Description</a></span>
+                  <a href="#harfbuzz-hb-buffer.description" class="shortcut">Description</a></span><span id="nav_hierarchy">  <span class="dim">|</span> 
+                  <a href="#harfbuzz-hb-buffer.object-hierarchy" class="shortcut">Object Hierarchy</a></span>
 </td>
 <td><a accesskey="h" href="index.html"><img src="home.png" width="16" height="16" border="0" alt="Home"></a></td>
-<td><a accesskey="u" href="ch09.html"><img src="up.png" width="16" height="16" border="0" alt="Up"></a></td>
+<td><a accesskey="u" href="ch11.html"><img src="up.png" width="16" height="16" border="0" alt="Up"></a></td>
 <td><a accesskey="p" href="harfbuzz-hb-blob.html"><img src="left.png" width="16" height="16" border="0" alt="Prev"></a></td>
 <td><a accesskey="n" href="harfbuzz-hb-common.html"><img src="right.png" width="16" height="16" border="0" alt="Next"></a></td>
 </tr></table>
@@ -41,7 +42,7 @@
 <tbody>
 <tr>
 <td class="function_type">
-<a class="link" href="harfbuzz-hb-buffer.html#hb-buffer-t" title="hb_buffer_t"><span class="returnvalue">hb_buffer_t</span></a> *
+<a class="link" href="harfbuzz-hb-buffer.html#hb-buffer-t"><span class="returnvalue">hb_buffer_t</span></a> *
 </td>
 <td class="function_name">
 <a class="link" href="harfbuzz-hb-buffer.html#hb-buffer-create" title="hb_buffer_create ()">hb_buffer_create</a> <span class="c_punctuation">()</span>
@@ -49,7 +50,7 @@
 </tr>
 <tr>
 <td class="function_type">
-<a class="link" href="harfbuzz-hb-buffer.html#hb-buffer-t" title="hb_buffer_t"><span class="returnvalue">hb_buffer_t</span></a> *
+<a class="link" href="harfbuzz-hb-buffer.html#hb-buffer-t"><span class="returnvalue">hb_buffer_t</span></a> *
 </td>
 <td class="function_name">
 <a class="link" href="harfbuzz-hb-buffer.html#hb-buffer-reference" title="hb_buffer_reference ()">hb_buffer_reference</a> <span class="c_punctuation">()</span>
@@ -57,7 +58,7 @@
 </tr>
 <tr>
 <td class="function_type">
-<a class="link" href="harfbuzz-hb-buffer.html#hb-buffer-t" title="hb_buffer_t"><span class="returnvalue">hb_buffer_t</span></a> *
+<a class="link" href="harfbuzz-hb-buffer.html#hb-buffer-t"><span class="returnvalue">hb_buffer_t</span></a> *
 </td>
 <td class="function_name">
 <a class="link" href="harfbuzz-hb-buffer.html#hb-buffer-get-empty" title="hb_buffer_get_empty ()">hb_buffer_get_empty</a> <span class="c_punctuation">()</span>
 </tr>
 <tr>
 <td class="function_type">
-<a class="link" href="harfbuzz-hb-unicode.html#hb-unicode-funcs-t" title="hb_unicode_funcs_t"><span class="returnvalue">hb_unicode_funcs_t</span></a> *
+<a class="link" href="harfbuzz-hb-unicode.html#hb-unicode-funcs-t"><span class="returnvalue">hb_unicode_funcs_t</span></a> *
 </td>
 <td class="function_name">
 <a class="link" href="harfbuzz-hb-buffer.html#hb-buffer-get-unicode-funcs" title="hb_buffer_get_unicode_funcs ()">hb_buffer_get_unicode_funcs</a> <span class="c_punctuation">()</span>
 </tr>
 <tr>
 <td class="function_type">
-<a class="link" href="harfbuzz-hb-buffer.html#hb-glyph-position-t" title="hb_glyph_position_t"><span class="returnvalue">hb_glyph_position_t</span></a> *
+<a class="link" href="harfbuzz-hb-buffer.html#hb-glyph-position-t"><span class="returnvalue">hb_glyph_position_t</span></a> *
 </td>
 <td class="function_name">
 <a class="link" href="harfbuzz-hb-buffer.html#hb-buffer-get-glyph-positions" title="hb_buffer_get_glyph_positions ()">hb_buffer_get_glyph_positions</a> <span class="c_punctuation">()</span>
 </tbody>
 </table></div>
 </div>
-<div class="refsect1">
+<a name="hb-buffer-t"></a><a name="hb-glyph-position-t"></a><a name="hb-segment-properties-t"></a><div class="refsect1">
 <a name="harfbuzz-hb-buffer.other"></a><h2>Types and Values</h2>
 <div class="informaltable"><table class="informaltable" width="100%" border="0">
 <colgroup>
 </tr>
 <tr>
 <td class="typedef_keyword">typedef</td>
-<td class="function_name"><a class="link" href="harfbuzz-hb-buffer.html#hb-buffer-t" title="hb_buffer_t">hb_buffer_t</a></td>
+<td class="function_name"><a class="link" href="harfbuzz-hb-buffer.html#hb-buffer-t">hb_buffer_t</a></td>
 </tr>
 <tr>
 <td class="datatype_keyword">enum</td>
 </tr>
 <tr>
 <td class="datatype_keyword"> </td>
-<td class="function_name"><a class="link" href="harfbuzz-hb-buffer.html#hb-glyph-position-t" title="hb_glyph_position_t">hb_glyph_position_t</a></td>
+<td class="function_name"><a class="link" href="harfbuzz-hb-buffer.html#hb-glyph-position-t-struct" title="hb_glyph_position_t">hb_glyph_position_t</a></td>
 </tr>
 <tr>
 <td class="datatype_keyword">enum</td>
 </tr>
 <tr>
 <td class="datatype_keyword"> </td>
-<td class="function_name"><a class="link" href="harfbuzz-hb-buffer.html#hb-segment-properties-t" title="hb_segment_properties_t">hb_segment_properties_t</a></td>
+<td class="function_name"><a class="link" href="harfbuzz-hb-buffer.html#hb-segment-properties-t-struct" title="hb_segment_properties_t">hb_segment_properties_t</a></td>
 </tr>
 <tr>
 <td class="datatype_keyword">enum</td>
 </table></div>
 </div>
 <div class="refsect1">
+<a name="harfbuzz-hb-buffer.object-hierarchy"></a><h2>Object Hierarchy</h2>
+<pre class="screen">    <a href="/usr/share/gtk-doc/html/gobject/gobject-Boxed-Types.html">GBoxed</a>
+    <span class="lineart">├──</span> hb_buffer_t
+    <span class="lineart">├──</span> hb_glyph_position_t
+    <span class="lineart">╰──</span> hb_segment_properties_t
+    <a href="/usr/share/gtk-doc/html/gobject/gobject-Enumeration-and-Flag-Types.html">GEnum</a>
+    <span class="lineart">├──</span> hb_buffer_cluster_level_t
+    <span class="lineart">├──</span> hb_buffer_content_type_t
+    <span class="lineart">╰──</span> hb_buffer_serialize_format_t
+    <a href="/usr/share/gtk-doc/html/gobject/gobject-Enumeration-and-Flag-Types.html">GFlags</a>
+    <span class="lineart">├──</span> hb_buffer_diff_flags_t
+    <span class="lineart">├──</span> hb_buffer_flags_t
+    <span class="lineart">├──</span> hb_buffer_serialize_flags_t
+    <span class="lineart">╰──</span> hb_glyph_flags_t
+</pre>
+</div>
+<div class="refsect1">
 <a name="harfbuzz-hb-buffer.includes"></a><h2>Includes</h2>
 <pre class="synopsis">#include &lt;hb.h&gt;
 </pre>
@@ -566,16 +584,16 @@ passed to <a class="link" href="harfbuzz-hb-shape.html#hb-shape" title="hb_shape
 <a name="harfbuzz-hb-buffer.functions_details"></a><h2>Functions</h2>
 <div class="refsect2">
 <a name="hb-buffer-create"></a><h3>hb_buffer_create ()</h3>
-<pre class="programlisting"><a class="link" href="harfbuzz-hb-buffer.html#hb-buffer-t" title="hb_buffer_t"><span class="returnvalue">hb_buffer_t</span></a> *
+<pre class="programlisting"><a class="link" href="harfbuzz-hb-buffer.html#hb-buffer-t"><span class="returnvalue">hb_buffer_t</span></a> *
 hb_buffer_create (<em class="parameter"><code><span class="type">void</span></code></em>);</pre>
-<p>Creates a new <a class="link" href="harfbuzz-hb-buffer.html#hb-buffer-t" title="hb_buffer_t"><span class="type">hb_buffer_t</span></a> with all properties to defaults.</p>
+<p>Creates a new <a class="link" href="harfbuzz-hb-buffer.html#hb-buffer-t"><span class="type">hb_buffer_t</span></a> with all properties to defaults.</p>
 <p><span class="annotation">[Xconstructor]</span></p>
 <div class="refsect3">
 <a name="hb-buffer-create.returns"></a><h4>Returns</h4>
-<p>A newly allocated <a class="link" href="harfbuzz-hb-buffer.html#hb-buffer-t" title="hb_buffer_t"><span class="type">hb_buffer_t</span></a> with a reference count of 1. The initial
+<p>A newly allocated <a class="link" href="harfbuzz-hb-buffer.html#hb-buffer-t"><span class="type">hb_buffer_t</span></a> with a reference count of 1. The initial
 reference count should be released with <a class="link" href="harfbuzz-hb-buffer.html#hb-buffer-destroy" title="hb_buffer_destroy ()"><code class="function">hb_buffer_destroy()</code></a> when you are done
-using the <a class="link" href="harfbuzz-hb-buffer.html#hb-buffer-t" title="hb_buffer_t"><span class="type">hb_buffer_t</span></a>. This function never returns <a href="/usr/share/gtk-doc/html/glib/glib-Standard-Macros.html#NULL:CAPS"><code class="literal">NULL</code></a>. If memory cannot
-be allocated, a special <a class="link" href="harfbuzz-hb-buffer.html#hb-buffer-t" title="hb_buffer_t"><span class="type">hb_buffer_t</span></a> object will be returned on which
+using the <a class="link" href="harfbuzz-hb-buffer.html#hb-buffer-t"><span class="type">hb_buffer_t</span></a>. This function never returns <code class="literal">NULL</code>. If memory cannot
+be allocated, a special <a class="link" href="harfbuzz-hb-buffer.html#hb-buffer-t"><span class="type">hb_buffer_t</span></a> object will be returned on which
 <a class="link" href="harfbuzz-hb-buffer.html#hb-buffer-allocation-successful" title="hb_buffer_allocation_successful ()"><code class="function">hb_buffer_allocation_successful()</code></a> returns <code class="literal">false</code>. </p>
 <p><span class="annotation">[<acronym title="Free data after the code is done."><span class="acronym">transfer full</span></acronym>]</span></p>
 </div>
@@ -584,8 +602,8 @@ be allocated, a special <a class="link" href="harfbuzz-hb-buffer.html#hb-buffer-
 <hr>
 <div class="refsect2">
 <a name="hb-buffer-reference"></a><h3>hb_buffer_reference ()</h3>
-<pre class="programlisting"><a class="link" href="harfbuzz-hb-buffer.html#hb-buffer-t" title="hb_buffer_t"><span class="returnvalue">hb_buffer_t</span></a> *
-hb_buffer_reference (<em class="parameter"><code><a class="link" href="harfbuzz-hb-buffer.html#hb-buffer-t" title="hb_buffer_t"><span class="type">hb_buffer_t</span></a> *buffer</code></em>);</pre>
+<pre class="programlisting"><a class="link" href="harfbuzz-hb-buffer.html#hb-buffer-t"><span class="returnvalue">hb_buffer_t</span></a> *
+hb_buffer_reference (<em class="parameter"><code><a class="link" href="harfbuzz-hb-buffer.html#hb-buffer-t"><span class="type">hb_buffer_t</span></a> *buffer</code></em>);</pre>
 <p>Increases the reference count on <em class="parameter"><code>buffer</code></em>
  by one. This prevents <em class="parameter"><code>buffer</code></em>
  from
@@ -601,14 +619,14 @@ being destroyed until a matching call to <a class="link" href="harfbuzz-hb-buffe
 </colgroup>
 <tbody><tr>
 <td class="parameter_name"><p>buffer</p></td>
-<td class="parameter_description"><p>an <a class="link" href="harfbuzz-hb-buffer.html#hb-buffer-t" title="hb_buffer_t"><span class="type">hb_buffer_t</span></a>.</p></td>
+<td class="parameter_description"><p>an <a class="link" href="harfbuzz-hb-buffer.html#hb-buffer-t"><span class="type">hb_buffer_t</span></a>.</p></td>
 <td class="parameter_annotations"> </td>
 </tr></tbody>
 </table></div>
 </div>
 <div class="refsect3">
 <a name="hb-buffer-reference.returns"></a><h4>Returns</h4>
-<p>The referenced <a class="link" href="harfbuzz-hb-buffer.html#hb-buffer-t" title="hb_buffer_t"><span class="type">hb_buffer_t</span></a>. </p>
+<p>The referenced <a class="link" href="harfbuzz-hb-buffer.html#hb-buffer-t"><span class="type">hb_buffer_t</span></a>. </p>
 <p><span class="annotation">[<acronym title="Free data after the code is done."><span class="acronym">transfer full</span></acronym>]</span></p>
 </div>
 <p class="since">Since: <a class="link" href="api-index-0-9-2.html#api-index-0.9.2">0.9.2</a></p>
@@ -616,7 +634,7 @@ being destroyed until a matching call to <a class="link" href="harfbuzz-hb-buffe
 <hr>
 <div class="refsect2">
 <a name="hb-buffer-get-empty"></a><h3>hb_buffer_get_empty ()</h3>
-<pre class="programlisting"><a class="link" href="harfbuzz-hb-buffer.html#hb-buffer-t" title="hb_buffer_t"><span class="returnvalue">hb_buffer_t</span></a> *
+<pre class="programlisting"><a class="link" href="harfbuzz-hb-buffer.html#hb-buffer-t"><span class="returnvalue">hb_buffer_t</span></a> *
 hb_buffer_get_empty (<em class="parameter"><code><span class="type">void</span></code></em>);</pre>
 <div class="refsect3">
 <a name="hb-buffer-get-empty.returns"></a><h4>Returns</h4>
@@ -629,7 +647,7 @@ hb_buffer_get_empty (<em class="parameter"><code><span class="type">void</span><
 <div class="refsect2">
 <a name="hb-buffer-destroy"></a><h3>hb_buffer_destroy ()</h3>
 <pre class="programlisting"><span class="returnvalue">void</span>
-hb_buffer_destroy (<em class="parameter"><code><a class="link" href="harfbuzz-hb-buffer.html#hb-buffer-t" title="hb_buffer_t"><span class="type">hb_buffer_t</span></a> *buffer</code></em>);</pre>
+hb_buffer_destroy (<em class="parameter"><code><a class="link" href="harfbuzz-hb-buffer.html#hb-buffer-t"><span class="type">hb_buffer_t</span></a> *buffer</code></em>);</pre>
 <p>Deallocate the <em class="parameter"><code>buffer</code></em>
 .
 Decreases the reference count on <em class="parameter"><code>buffer</code></em>
@@ -647,7 +665,7 @@ Decreases the reference count on <em class="parameter"><code>buffer</code></em>
 </colgroup>
 <tbody><tr>
 <td class="parameter_name"><p>buffer</p></td>
-<td class="parameter_description"><p>an <a class="link" href="harfbuzz-hb-buffer.html#hb-buffer-t" title="hb_buffer_t"><span class="type">hb_buffer_t</span></a>.</p></td>
+<td class="parameter_description"><p>an <a class="link" href="harfbuzz-hb-buffer.html#hb-buffer-t"><span class="type">hb_buffer_t</span></a>.</p></td>
 <td class="parameter_annotations"> </td>
 </tr></tbody>
 </table></div>
@@ -658,7 +676,7 @@ Decreases the reference count on <em class="parameter"><code>buffer</code></em>
 <div class="refsect2">
 <a name="hb-buffer-reset"></a><h3>hb_buffer_reset ()</h3>
 <pre class="programlisting"><span class="returnvalue">void</span>
-hb_buffer_reset (<em class="parameter"><code><a class="link" href="harfbuzz-hb-buffer.html#hb-buffer-t" title="hb_buffer_t"><span class="type">hb_buffer_t</span></a> *buffer</code></em>);</pre>
+hb_buffer_reset (<em class="parameter"><code><a class="link" href="harfbuzz-hb-buffer.html#hb-buffer-t"><span class="type">hb_buffer_t</span></a> *buffer</code></em>);</pre>
 <p>Resets the buffer to its initial status, as if it was just newly created
 with <a class="link" href="harfbuzz-hb-buffer.html#hb-buffer-create" title="hb_buffer_create ()"><code class="function">hb_buffer_create()</code></a>.</p>
 <div class="refsect3">
@@ -671,7 +689,7 @@ with <a class="link" href="harfbuzz-hb-buffer.html#hb-buffer-create" title="hb_b
 </colgroup>
 <tbody><tr>
 <td class="parameter_name"><p>buffer</p></td>
-<td class="parameter_description"><p>an <a class="link" href="harfbuzz-hb-buffer.html#hb-buffer-t" title="hb_buffer_t"><span class="type">hb_buffer_t</span></a>.</p></td>
+<td class="parameter_description"><p>an <a class="link" href="harfbuzz-hb-buffer.html#hb-buffer-t"><span class="type">hb_buffer_t</span></a>.</p></td>
 <td class="parameter_annotations"> </td>
 </tr></tbody>
 </table></div>
@@ -682,7 +700,7 @@ with <a class="link" href="harfbuzz-hb-buffer.html#hb-buffer-create" title="hb_b
 <div class="refsect2">
 <a name="hb-buffer-clear-contents"></a><h3>hb_buffer_clear_contents ()</h3>
 <pre class="programlisting"><span class="returnvalue">void</span>
-hb_buffer_clear_contents (<em class="parameter"><code><a class="link" href="harfbuzz-hb-buffer.html#hb-buffer-t" title="hb_buffer_t"><span class="type">hb_buffer_t</span></a> *buffer</code></em>);</pre>
+hb_buffer_clear_contents (<em class="parameter"><code><a class="link" href="harfbuzz-hb-buffer.html#hb-buffer-t"><span class="type">hb_buffer_t</span></a> *buffer</code></em>);</pre>
 <p>Similar to <a class="link" href="harfbuzz-hb-buffer.html#hb-buffer-reset" title="hb_buffer_reset ()"><code class="function">hb_buffer_reset()</code></a>, but does not clear the Unicode functions and
 the replacement code point.</p>
 <div class="refsect3">
@@ -695,7 +713,7 @@ the replacement code point.</p>
 </colgroup>
 <tbody><tr>
 <td class="parameter_name"><p>buffer</p></td>
-<td class="parameter_description"><p>an <a class="link" href="harfbuzz-hb-buffer.html#hb-buffer-t" title="hb_buffer_t"><span class="type">hb_buffer_t</span></a>.</p></td>
+<td class="parameter_description"><p>an <a class="link" href="harfbuzz-hb-buffer.html#hb-buffer-t"><span class="type">hb_buffer_t</span></a>.</p></td>
 <td class="parameter_annotations"> </td>
 </tr></tbody>
 </table></div>
@@ -706,7 +724,7 @@ the replacement code point.</p>
 <div class="refsect2">
 <a name="hb-buffer-pre-allocate"></a><h3>hb_buffer_pre_allocate ()</h3>
 <pre class="programlisting"><a class="link" href="harfbuzz-hb-common.html#hb-bool-t" title="hb_bool_t"><span class="returnvalue">hb_bool_t</span></a>
-hb_buffer_pre_allocate (<em class="parameter"><code><a class="link" href="harfbuzz-hb-buffer.html#hb-buffer-t" title="hb_buffer_t"><span class="type">hb_buffer_t</span></a> *buffer</code></em>,
+hb_buffer_pre_allocate (<em class="parameter"><code><a class="link" href="harfbuzz-hb-buffer.html#hb-buffer-t"><span class="type">hb_buffer_t</span></a> *buffer</code></em>,
                         <em class="parameter"><code>unsigned <span class="type">int</span> size</code></em>);</pre>
 <p>Pre allocates memory for <em class="parameter"><code>buffer</code></em>
  to fit at least <em class="parameter"><code>size</code></em>
@@ -722,7 +740,7 @@ hb_buffer_pre_allocate (<em class="parameter"><code><a class="link" href="harfbu
 <tbody>
 <tr>
 <td class="parameter_name"><p>buffer</p></td>
-<td class="parameter_description"><p>an <a class="link" href="harfbuzz-hb-buffer.html#hb-buffer-t" title="hb_buffer_t"><span class="type">hb_buffer_t</span></a>.</p></td>
+<td class="parameter_description"><p>an <a class="link" href="harfbuzz-hb-buffer.html#hb-buffer-t"><span class="type">hb_buffer_t</span></a>.</p></td>
 <td class="parameter_annotations"> </td>
 </tr>
 <tr>
@@ -744,7 +762,7 @@ memory allocation succeeded, <code class="literal">false</code> otherwise.</p>
 <div class="refsect2">
 <a name="hb-buffer-allocation-successful"></a><h3>hb_buffer_allocation_successful ()</h3>
 <pre class="programlisting"><a class="link" href="harfbuzz-hb-common.html#hb-bool-t" title="hb_bool_t"><span class="returnvalue">hb_bool_t</span></a>
-hb_buffer_allocation_successful (<em class="parameter"><code><a class="link" href="harfbuzz-hb-buffer.html#hb-buffer-t" title="hb_buffer_t"><span class="type">hb_buffer_t</span></a> *buffer</code></em>);</pre>
+hb_buffer_allocation_successful (<em class="parameter"><code><a class="link" href="harfbuzz-hb-buffer.html#hb-buffer-t"><span class="type">hb_buffer_t</span></a> *buffer</code></em>);</pre>
 <p>Check if allocating memory for the buffer succeeded.</p>
 <div class="refsect3">
 <a name="hb-buffer-allocation-successful.parameters"></a><h4>Parameters</h4>
@@ -756,7 +774,7 @@ hb_buffer_allocation_successful (<em class="parameter"><code><a class="link" hre
 </colgroup>
 <tbody><tr>
 <td class="parameter_name"><p>buffer</p></td>
-<td class="parameter_description"><p>an <a class="link" href="harfbuzz-hb-buffer.html#hb-buffer-t" title="hb_buffer_t"><span class="type">hb_buffer_t</span></a>.</p></td>
+<td class="parameter_description"><p>an <a class="link" href="harfbuzz-hb-buffer.html#hb-buffer-t"><span class="type">hb_buffer_t</span></a>.</p></td>
 <td class="parameter_annotations"> </td>
 </tr></tbody>
 </table></div>
@@ -772,7 +790,7 @@ memory allocation succeeded, <code class="literal">false</code> otherwise.</p>
 <div class="refsect2">
 <a name="hb-buffer-add"></a><h3>hb_buffer_add ()</h3>
 <pre class="programlisting"><span class="returnvalue">void</span>
-hb_buffer_add (<em class="parameter"><code><a class="link" href="harfbuzz-hb-buffer.html#hb-buffer-t" title="hb_buffer_t"><span class="type">hb_buffer_t</span></a> *buffer</code></em>,
+hb_buffer_add (<em class="parameter"><code><a class="link" href="harfbuzz-hb-buffer.html#hb-buffer-t"><span class="type">hb_buffer_t</span></a> *buffer</code></em>,
                <em class="parameter"><code><a class="link" href="harfbuzz-hb-common.html#hb-codepoint-t" title="hb_codepoint_t"><span class="type">hb_codepoint_t</span></a> codepoint</code></em>,
                <em class="parameter"><code>unsigned <span class="type">int</span> cluster</code></em>);</pre>
 <p>Appends a character with the Unicode value of <em class="parameter"><code>codepoint</code></em>
@@ -797,7 +815,7 @@ caller to ensure it is a valid Unicode code point.</p>
 <tbody>
 <tr>
 <td class="parameter_name"><p>buffer</p></td>
-<td class="parameter_description"><p>an <a class="link" href="harfbuzz-hb-buffer.html#hb-buffer-t" title="hb_buffer_t"><span class="type">hb_buffer_t</span></a>.</p></td>
+<td class="parameter_description"><p>an <a class="link" href="harfbuzz-hb-buffer.html#hb-buffer-t"><span class="type">hb_buffer_t</span></a>.</p></td>
 <td class="parameter_annotations"> </td>
 </tr>
 <tr>
@@ -820,7 +838,7 @@ caller to ensure it is a valid Unicode code point.</p>
 <div class="refsect2">
 <a name="hb-buffer-add-codepoints"></a><h3>hb_buffer_add_codepoints ()</h3>
 <pre class="programlisting"><span class="returnvalue">void</span>
-hb_buffer_add_codepoints (<em class="parameter"><code><a class="link" href="harfbuzz-hb-buffer.html#hb-buffer-t" title="hb_buffer_t"><span class="type">hb_buffer_t</span></a> *buffer</code></em>,
+hb_buffer_add_codepoints (<em class="parameter"><code><a class="link" href="harfbuzz-hb-buffer.html#hb-buffer-t"><span class="type">hb_buffer_t</span></a> *buffer</code></em>,
                           <em class="parameter"><code>const <a class="link" href="harfbuzz-hb-common.html#hb-codepoint-t" title="hb_codepoint_t"><span class="type">hb_codepoint_t</span></a> *text</code></em>,
                           <em class="parameter"><code><span class="type">int</span> text_length</code></em>,
                           <em class="parameter"><code>unsigned <span class="type">int</span> item_offset</code></em>,
@@ -855,7 +873,7 @@ to ensure it contains a valid Unicode code points.</p>
 <tbody>
 <tr>
 <td class="parameter_name"><p>buffer</p></td>
-<td class="parameter_description"><p>a <a class="link" href="harfbuzz-hb-buffer.html#hb-buffer-t" title="hb_buffer_t"><span class="type">hb_buffer_t</span></a> to append characters to.</p></td>
+<td class="parameter_description"><p>a <a class="link" href="harfbuzz-hb-buffer.html#hb-buffer-t"><span class="type">hb_buffer_t</span></a> to append characters to.</p></td>
 <td class="parameter_annotations"> </td>
 </tr>
 <tr>
@@ -866,7 +884,7 @@ to ensure it contains a valid Unicode code points.</p>
 <tr>
 <td class="parameter_name"><p>text_length</p></td>
 <td class="parameter_description"><p>the length of the <em class="parameter"><code>text</code></em>
-, or -1 if it is <a href="/usr/share/gtk-doc/html/glib/glib-Standard-Macros.html#NULL:CAPS"><code class="literal">NULL</code></a> terminated.</p></td>
+, or -1 if it is <code class="literal">NULL</code> terminated.</p></td>
 <td class="parameter_annotations"> </td>
 </tr>
 <tr>
@@ -880,7 +898,7 @@ to ensure it contains a valid Unicode code points.</p>
 <td class="parameter_description"><p>the number of code points to add to the <em class="parameter"><code>buffer</code></em>
 , or -1 for the
 end of <em class="parameter"><code>text</code></em>
-(assuming it is <a href="/usr/share/gtk-doc/html/glib/glib-Standard-Macros.html#NULL:CAPS"><code class="literal">NULL</code></a> terminated).</p></td>
+(assuming it is <code class="literal">NULL</code> terminated).</p></td>
 <td class="parameter_annotations"> </td>
 </tr>
 </tbody>
@@ -892,7 +910,7 @@ end of <em class="parameter"><code>text</code></em>
 <div class="refsect2">
 <a name="hb-buffer-add-utf32"></a><h3>hb_buffer_add_utf32 ()</h3>
 <pre class="programlisting"><span class="returnvalue">void</span>
-hb_buffer_add_utf32 (<em class="parameter"><code><a class="link" href="harfbuzz-hb-buffer.html#hb-buffer-t" title="hb_buffer_t"><span class="type">hb_buffer_t</span></a> *buffer</code></em>,
+hb_buffer_add_utf32 (<em class="parameter"><code><a class="link" href="harfbuzz-hb-buffer.html#hb-buffer-t"><span class="type">hb_buffer_t</span></a> *buffer</code></em>,
                      <em class="parameter"><code>const <span class="type">uint32_t</span> *text</code></em>,
                      <em class="parameter"><code><span class="type">int</span> text_length</code></em>,
                      <em class="parameter"><code>unsigned <span class="type">int</span> item_offset</code></em>,
@@ -912,7 +930,7 @@ see <a class="link" href="harfbuzz-hb-buffer.html#hb-buffer-set-replacement-code
 <tbody>
 <tr>
 <td class="parameter_name"><p>buffer</p></td>
-<td class="parameter_description"><p>an <a class="link" href="harfbuzz-hb-buffer.html#hb-buffer-t" title="hb_buffer_t"><span class="type">hb_buffer_t</span></a>.</p></td>
+<td class="parameter_description"><p>an <a class="link" href="harfbuzz-hb-buffer.html#hb-buffer-t"><span class="type">hb_buffer_t</span></a>.</p></td>
 <td class="parameter_annotations"> </td>
 </tr>
 <tr>
@@ -923,7 +941,7 @@ see <a class="link" href="harfbuzz-hb-buffer.html#hb-buffer-set-replacement-code
 <tr>
 <td class="parameter_name"><p>text_length</p></td>
 <td class="parameter_description"><p>the length of the <em class="parameter"><code>text</code></em>
-, or -1 if it is <a href="/usr/share/gtk-doc/html/glib/glib-Standard-Macros.html#NULL:CAPS"><code class="literal">NULL</code></a> terminated.</p></td>
+, or -1 if it is <code class="literal">NULL</code> terminated.</p></td>
 <td class="parameter_annotations"> </td>
 </tr>
 <tr>
@@ -937,7 +955,7 @@ see <a class="link" href="harfbuzz-hb-buffer.html#hb-buffer-set-replacement-code
 <td class="parameter_description"><p>the number of characters to add to the <em class="parameter"><code>buffer</code></em>
 , or -1 for the
 end of <em class="parameter"><code>text</code></em>
-(assuming it is <a href="/usr/share/gtk-doc/html/glib/glib-Standard-Macros.html#NULL:CAPS"><code class="literal">NULL</code></a> terminated).</p></td>
+(assuming it is <code class="literal">NULL</code> terminated).</p></td>
 <td class="parameter_annotations"> </td>
 </tr>
 </tbody>
@@ -949,7 +967,7 @@ end of <em class="parameter"><code>text</code></em>
 <div class="refsect2">
 <a name="hb-buffer-add-utf16"></a><h3>hb_buffer_add_utf16 ()</h3>
 <pre class="programlisting"><span class="returnvalue">void</span>
-hb_buffer_add_utf16 (<em class="parameter"><code><a class="link" href="harfbuzz-hb-buffer.html#hb-buffer-t" title="hb_buffer_t"><span class="type">hb_buffer_t</span></a> *buffer</code></em>,
+hb_buffer_add_utf16 (<em class="parameter"><code><a class="link" href="harfbuzz-hb-buffer.html#hb-buffer-t"><span class="type">hb_buffer_t</span></a> *buffer</code></em>,
                      <em class="parameter"><code>const <span class="type">uint16_t</span> *text</code></em>,
                      <em class="parameter"><code><span class="type">int</span> text_length</code></em>,
                      <em class="parameter"><code>unsigned <span class="type">int</span> item_offset</code></em>,
@@ -969,7 +987,7 @@ see <a class="link" href="harfbuzz-hb-buffer.html#hb-buffer-set-replacement-code
 <tbody>
 <tr>
 <td class="parameter_name"><p>buffer</p></td>
-<td class="parameter_description"><p>an <a class="link" href="harfbuzz-hb-buffer.html#hb-buffer-t" title="hb_buffer_t"><span class="type">hb_buffer_t</span></a>.</p></td>
+<td class="parameter_description"><p>an <a class="link" href="harfbuzz-hb-buffer.html#hb-buffer-t"><span class="type">hb_buffer_t</span></a>.</p></td>
 <td class="parameter_annotations"> </td>
 </tr>
 <tr>
@@ -980,7 +998,7 @@ see <a class="link" href="harfbuzz-hb-buffer.html#hb-buffer-set-replacement-code
 <tr>
 <td class="parameter_name"><p>text_length</p></td>
 <td class="parameter_description"><p>the length of the <em class="parameter"><code>text</code></em>
-, or -1 if it is <a href="/usr/share/gtk-doc/html/glib/glib-Standard-Macros.html#NULL:CAPS"><code class="literal">NULL</code></a> terminated.</p></td>
+, or -1 if it is <code class="literal">NULL</code> terminated.</p></td>
 <td class="parameter_annotations"> </td>
 </tr>
 <tr>
@@ -994,7 +1012,7 @@ see <a class="link" href="harfbuzz-hb-buffer.html#hb-buffer-set-replacement-code
 <td class="parameter_description"><p>the number of characters to add to the <em class="parameter"><code>buffer</code></em>
 , or -1 for the
 end of <em class="parameter"><code>text</code></em>
-(assuming it is <a href="/usr/share/gtk-doc/html/glib/glib-Standard-Macros.html#NULL:CAPS"><code class="literal">NULL</code></a> terminated).</p></td>
+(assuming it is <code class="literal">NULL</code> terminated).</p></td>
 <td class="parameter_annotations"> </td>
 </tr>
 </tbody>
@@ -1006,7 +1024,7 @@ end of <em class="parameter"><code>text</code></em>
 <div class="refsect2">
 <a name="hb-buffer-add-utf8"></a><h3>hb_buffer_add_utf8 ()</h3>
 <pre class="programlisting"><span class="returnvalue">void</span>
-hb_buffer_add_utf8 (<em class="parameter"><code><a class="link" href="harfbuzz-hb-buffer.html#hb-buffer-t" title="hb_buffer_t"><span class="type">hb_buffer_t</span></a> *buffer</code></em>,
+hb_buffer_add_utf8 (<em class="parameter"><code><a class="link" href="harfbuzz-hb-buffer.html#hb-buffer-t"><span class="type">hb_buffer_t</span></a> *buffer</code></em>,
                     <em class="parameter"><code>const <span class="type">char</span> *text</code></em>,
                     <em class="parameter"><code><span class="type">int</span> text_length</code></em>,
                     <em class="parameter"><code>unsigned <span class="type">int</span> item_offset</code></em>,
@@ -1026,7 +1044,7 @@ see <a class="link" href="harfbuzz-hb-buffer.html#hb-buffer-set-replacement-code
 <tbody>
 <tr>
 <td class="parameter_name"><p>buffer</p></td>
-<td class="parameter_description"><p>an <a class="link" href="harfbuzz-hb-buffer.html#hb-buffer-t" title="hb_buffer_t"><span class="type">hb_buffer_t</span></a>.</p></td>
+<td class="parameter_description"><p>an <a class="link" href="harfbuzz-hb-buffer.html#hb-buffer-t"><span class="type">hb_buffer_t</span></a>.</p></td>
 <td class="parameter_annotations"> </td>
 </tr>
 <tr>
@@ -1038,7 +1056,7 @@ characters to append. </p></td>
 <tr>
 <td class="parameter_name"><p>text_length</p></td>
 <td class="parameter_description"><p>the length of the <em class="parameter"><code>text</code></em>
-, or -1 if it is <a href="/usr/share/gtk-doc/html/glib/glib-Standard-Macros.html#NULL:CAPS"><code class="literal">NULL</code></a> terminated.</p></td>
+, or -1 if it is <code class="literal">NULL</code> terminated.</p></td>
 <td class="parameter_annotations"> </td>
 </tr>
 <tr>
@@ -1052,7 +1070,7 @@ characters to append. </p></td>
 <td class="parameter_description"><p>the number of characters to add to the <em class="parameter"><code>buffer</code></em>
 , or -1 for the
 end of <em class="parameter"><code>text</code></em>
-(assuming it is <a href="/usr/share/gtk-doc/html/glib/glib-Standard-Macros.html#NULL:CAPS"><code class="literal">NULL</code></a> terminated).</p></td>
+(assuming it is <code class="literal">NULL</code> terminated).</p></td>
 <td class="parameter_annotations"> </td>
 </tr>
 </tbody>
@@ -1064,7 +1082,7 @@ end of <em class="parameter"><code>text</code></em>
 <div class="refsect2">
 <a name="hb-buffer-add-latin1"></a><h3>hb_buffer_add_latin1 ()</h3>
 <pre class="programlisting"><span class="returnvalue">void</span>
-hb_buffer_add_latin1 (<em class="parameter"><code><a class="link" href="harfbuzz-hb-buffer.html#hb-buffer-t" title="hb_buffer_t"><span class="type">hb_buffer_t</span></a> *buffer</code></em>,
+hb_buffer_add_latin1 (<em class="parameter"><code><a class="link" href="harfbuzz-hb-buffer.html#hb-buffer-t"><span class="type">hb_buffer_t</span></a> *buffer</code></em>,
                       <em class="parameter"><code>const <span class="type">uint8_t</span> *text</code></em>,
                       <em class="parameter"><code><span class="type">int</span> text_length</code></em>,
                       <em class="parameter"><code>unsigned <span class="type">int</span> item_offset</code></em>,
@@ -1083,7 +1101,7 @@ Unicode code points that can fit in 8-bit strings.</p>
 <tbody>
 <tr>
 <td class="parameter_name"><p>buffer</p></td>
-<td class="parameter_description"><p>an <a class="link" href="harfbuzz-hb-buffer.html#hb-buffer-t" title="hb_buffer_t"><span class="type">hb_buffer_t</span></a>.</p></td>
+<td class="parameter_description"><p>an <a class="link" href="harfbuzz-hb-buffer.html#hb-buffer-t"><span class="type">hb_buffer_t</span></a>.</p></td>
 <td class="parameter_annotations"> </td>
 </tr>
 <tr>
@@ -1095,7 +1113,7 @@ characters to append. </p></td>
 <tr>
 <td class="parameter_name"><p>text_length</p></td>
 <td class="parameter_description"><p>the length of the <em class="parameter"><code>text</code></em>
-, or -1 if it is <a href="/usr/share/gtk-doc/html/glib/glib-Standard-Macros.html#NULL:CAPS"><code class="literal">NULL</code></a> terminated.</p></td>
+, or -1 if it is <code class="literal">NULL</code> terminated.</p></td>
 <td class="parameter_annotations"> </td>
 </tr>
 <tr>
@@ -1109,7 +1127,7 @@ characters to append. </p></td>
 <td class="parameter_description"><p>the number of characters to add to the <em class="parameter"><code>buffer</code></em>
 , or -1 for the
 end of <em class="parameter"><code>text</code></em>
-(assuming it is <a href="/usr/share/gtk-doc/html/glib/glib-Standard-Macros.html#NULL:CAPS"><code class="literal">NULL</code></a> terminated).</p></td>
+(assuming it is <code class="literal">NULL</code> terminated).</p></td>
 <td class="parameter_annotations"> </td>
 </tr>
 </tbody>
@@ -1121,8 +1139,8 @@ end of <em class="parameter"><code>text</code></em>
 <div class="refsect2">
 <a name="hb-buffer-append"></a><h3>hb_buffer_append ()</h3>
 <pre class="programlisting"><span class="returnvalue">void</span>
-hb_buffer_append (<em class="parameter"><code><a class="link" href="harfbuzz-hb-buffer.html#hb-buffer-t" title="hb_buffer_t"><span class="type">hb_buffer_t</span></a> *buffer</code></em>,
-                  <em class="parameter"><code><a class="link" href="harfbuzz-hb-buffer.html#hb-buffer-t" title="hb_buffer_t"><span class="type">hb_buffer_t</span></a> *source</code></em>,
+hb_buffer_append (<em class="parameter"><code><a class="link" href="harfbuzz-hb-buffer.html#hb-buffer-t"><span class="type">hb_buffer_t</span></a> *buffer</code></em>,
+                  <em class="parameter"><code><a class="link" href="harfbuzz-hb-buffer.html#hb-buffer-t"><span class="type">hb_buffer_t</span></a> *source</code></em>,
                   <em class="parameter"><code>unsigned <span class="type">int</span> start</code></em>,
                   <em class="parameter"><code>unsigned <span class="type">int</span> end</code></em>);</pre>
 <p>Append (part of) contents of another buffer to this buffer.</p>
@@ -1137,12 +1155,12 @@ hb_buffer_append (<em class="parameter"><code><a class="link" href="harfbuzz-hb-
 <tbody>
 <tr>
 <td class="parameter_name"><p>buffer</p></td>
-<td class="parameter_description"><p>an <a class="link" href="harfbuzz-hb-buffer.html#hb-buffer-t" title="hb_buffer_t"><span class="type">hb_buffer_t</span></a>.</p></td>
+<td class="parameter_description"><p>an <a class="link" href="harfbuzz-hb-buffer.html#hb-buffer-t"><span class="type">hb_buffer_t</span></a>.</p></td>
 <td class="parameter_annotations"> </td>
 </tr>
 <tr>
 <td class="parameter_name"><p>source</p></td>
-<td class="parameter_description"><p>source <a class="link" href="harfbuzz-hb-buffer.html#hb-buffer-t" title="hb_buffer_t"><span class="type">hb_buffer_t</span></a>.</p></td>
+<td class="parameter_description"><p>source <a class="link" href="harfbuzz-hb-buffer.html#hb-buffer-t"><span class="type">hb_buffer_t</span></a>.</p></td>
 <td class="parameter_annotations"> </td>
 </tr>
 <tr>
@@ -1164,7 +1182,7 @@ hb_buffer_append (<em class="parameter"><code><a class="link" href="harfbuzz-hb-
 <div class="refsect2">
 <a name="hb-buffer-set-content-type"></a><h3>hb_buffer_set_content_type ()</h3>
 <pre class="programlisting"><span class="returnvalue">void</span>
-hb_buffer_set_content_type (<em class="parameter"><code><a class="link" href="harfbuzz-hb-buffer.html#hb-buffer-t" title="hb_buffer_t"><span class="type">hb_buffer_t</span></a> *buffer</code></em>,
+hb_buffer_set_content_type (<em class="parameter"><code><a class="link" href="harfbuzz-hb-buffer.html#hb-buffer-t"><span class="type">hb_buffer_t</span></a> *buffer</code></em>,
                             <em class="parameter"><code><a class="link" href="harfbuzz-hb-buffer.html#hb-buffer-content-type-t" title="enum hb_buffer_content_type_t"><span class="type">hb_buffer_content_type_t</span></a> content_type</code></em>);</pre>
 <p>Sets the type of <em class="parameter"><code>buffer</code></em>
  contents, buffers are either empty, contain
@@ -1180,7 +1198,7 @@ characters (before shaping) or glyphs (the result of shaping).</p>
 <tbody>
 <tr>
 <td class="parameter_name"><p>buffer</p></td>
-<td class="parameter_description"><p>an <a class="link" href="harfbuzz-hb-buffer.html#hb-buffer-t" title="hb_buffer_t"><span class="type">hb_buffer_t</span></a>.</p></td>
+<td class="parameter_description"><p>an <a class="link" href="harfbuzz-hb-buffer.html#hb-buffer-t"><span class="type">hb_buffer_t</span></a>.</p></td>
 <td class="parameter_annotations"> </td>
 </tr>
 <tr>
@@ -1197,7 +1215,7 @@ characters (before shaping) or glyphs (the result of shaping).</p>
 <div class="refsect2">
 <a name="hb-buffer-get-content-type"></a><h3>hb_buffer_get_content_type ()</h3>
 <pre class="programlisting"><a class="link" href="harfbuzz-hb-buffer.html#hb-buffer-content-type-t" title="enum hb_buffer_content_type_t"><span class="returnvalue">hb_buffer_content_type_t</span></a>
-hb_buffer_get_content_type (<em class="parameter"><code><a class="link" href="harfbuzz-hb-buffer.html#hb-buffer-t" title="hb_buffer_t"><span class="type">hb_buffer_t</span></a> *buffer</code></em>);</pre>
+hb_buffer_get_content_type (<em class="parameter"><code><a class="link" href="harfbuzz-hb-buffer.html#hb-buffer-t"><span class="type">hb_buffer_t</span></a> *buffer</code></em>);</pre>
 <p>see <a class="link" href="harfbuzz-hb-buffer.html#hb-buffer-set-content-type" title="hb_buffer_set_content_type ()"><code class="function">hb_buffer_set_content_type()</code></a>.</p>
 <div class="refsect3">
 <a name="hb-buffer-get-content-type.parameters"></a><h4>Parameters</h4>
@@ -1209,7 +1227,7 @@ hb_buffer_get_content_type (<em class="parameter"><code><a class="link" href="ha
 </colgroup>
 <tbody><tr>
 <td class="parameter_name"><p>buffer</p></td>
-<td class="parameter_description"><p>an <a class="link" href="harfbuzz-hb-buffer.html#hb-buffer-t" title="hb_buffer_t"><span class="type">hb_buffer_t</span></a>.</p></td>
+<td class="parameter_description"><p>an <a class="link" href="harfbuzz-hb-buffer.html#hb-buffer-t"><span class="type">hb_buffer_t</span></a>.</p></td>
 <td class="parameter_annotations"> </td>
 </tr></tbody>
 </table></div>
@@ -1225,7 +1243,7 @@ contents.</p>
 <div class="refsect2">
 <a name="hb-buffer-set-direction"></a><h3>hb_buffer_set_direction ()</h3>
 <pre class="programlisting"><span class="returnvalue">void</span>
-hb_buffer_set_direction (<em class="parameter"><code><a class="link" href="harfbuzz-hb-buffer.html#hb-buffer-t" title="hb_buffer_t"><span class="type">hb_buffer_t</span></a> *buffer</code></em>,
+hb_buffer_set_direction (<em class="parameter"><code><a class="link" href="harfbuzz-hb-buffer.html#hb-buffer-t"><span class="type">hb_buffer_t</span></a> *buffer</code></em>,
                          <em class="parameter"><code><a class="link" href="harfbuzz-hb-common.html#hb-direction-t" title="enum hb_direction_t"><span class="type">hb_direction_t</span></a> direction</code></em>);</pre>
 <p>Set the text flow direction of the buffer. No shaping can happen without
 setting <em class="parameter"><code>buffer</code></em>
@@ -1246,7 +1264,7 @@ direction.</p>
 <tbody>
 <tr>
 <td class="parameter_name"><p>buffer</p></td>
-<td class="parameter_description"><p>an <a class="link" href="harfbuzz-hb-buffer.html#hb-buffer-t" title="hb_buffer_t"><span class="type">hb_buffer_t</span></a>.</p></td>
+<td class="parameter_description"><p>an <a class="link" href="harfbuzz-hb-buffer.html#hb-buffer-t"><span class="type">hb_buffer_t</span></a>.</p></td>
 <td class="parameter_annotations"> </td>
 </tr>
 <tr>
@@ -1264,7 +1282,7 @@ direction.</p>
 <div class="refsect2">
 <a name="hb-buffer-get-direction"></a><h3>hb_buffer_get_direction ()</h3>
 <pre class="programlisting"><a class="link" href="harfbuzz-hb-common.html#hb-direction-t" title="enum hb_direction_t"><span class="returnvalue">hb_direction_t</span></a>
-hb_buffer_get_direction (<em class="parameter"><code><a class="link" href="harfbuzz-hb-buffer.html#hb-buffer-t" title="hb_buffer_t"><span class="type">hb_buffer_t</span></a> *buffer</code></em>);</pre>
+hb_buffer_get_direction (<em class="parameter"><code><a class="link" href="harfbuzz-hb-buffer.html#hb-buffer-t"><span class="type">hb_buffer_t</span></a> *buffer</code></em>);</pre>
 <p>See <a class="link" href="harfbuzz-hb-buffer.html#hb-buffer-set-direction" title="hb_buffer_set_direction ()"><code class="function">hb_buffer_set_direction()</code></a></p>
 <div class="refsect3">
 <a name="hb-buffer-get-direction.parameters"></a><h4>Parameters</h4>
@@ -1276,7 +1294,7 @@ hb_buffer_get_direction (<em class="parameter"><code><a class="link" href="harfb
 </colgroup>
 <tbody><tr>
 <td class="parameter_name"><p>buffer</p></td>
-<td class="parameter_description"><p>an <a class="link" href="harfbuzz-hb-buffer.html#hb-buffer-t" title="hb_buffer_t"><span class="type">hb_buffer_t</span></a>.</p></td>
+<td class="parameter_description"><p>an <a class="link" href="harfbuzz-hb-buffer.html#hb-buffer-t"><span class="type">hb_buffer_t</span></a>.</p></td>
 <td class="parameter_annotations"> </td>
 </tr></tbody>
 </table></div>
@@ -1292,7 +1310,7 @@ hb_buffer_get_direction (<em class="parameter"><code><a class="link" href="harfb
 <div class="refsect2">
 <a name="hb-buffer-set-script"></a><h3>hb_buffer_set_script ()</h3>
 <pre class="programlisting"><span class="returnvalue">void</span>
-hb_buffer_set_script (<em class="parameter"><code><a class="link" href="harfbuzz-hb-buffer.html#hb-buffer-t" title="hb_buffer_t"><span class="type">hb_buffer_t</span></a> *buffer</code></em>,
+hb_buffer_set_script (<em class="parameter"><code><a class="link" href="harfbuzz-hb-buffer.html#hb-buffer-t"><span class="type">hb_buffer_t</span></a> *buffer</code></em>,
                       <em class="parameter"><code><a class="link" href="harfbuzz-hb-common.html#hb-script-t" title="enum hb_script_t"><span class="type">hb_script_t</span></a> script</code></em>);</pre>
 <p>Sets the script of <em class="parameter"><code>buffer</code></em>
  to <em class="parameter"><code>script</code></em>
@@ -1314,7 +1332,7 @@ corresponding script from an ISO 15924 script tag.</p>
 <tbody>
 <tr>
 <td class="parameter_name"><p>buffer</p></td>
-<td class="parameter_description"><p>an <a class="link" href="harfbuzz-hb-buffer.html#hb-buffer-t" title="hb_buffer_t"><span class="type">hb_buffer_t</span></a>.</p></td>
+<td class="parameter_description"><p>an <a class="link" href="harfbuzz-hb-buffer.html#hb-buffer-t"><span class="type">hb_buffer_t</span></a>.</p></td>
 <td class="parameter_annotations"> </td>
 </tr>
 <tr>
@@ -1331,7 +1349,7 @@ corresponding script from an ISO 15924 script tag.</p>
 <div class="refsect2">
 <a name="hb-buffer-get-script"></a><h3>hb_buffer_get_script ()</h3>
 <pre class="programlisting"><a class="link" href="harfbuzz-hb-common.html#hb-script-t" title="enum hb_script_t"><span class="returnvalue">hb_script_t</span></a>
-hb_buffer_get_script (<em class="parameter"><code><a class="link" href="harfbuzz-hb-buffer.html#hb-buffer-t" title="hb_buffer_t"><span class="type">hb_buffer_t</span></a> *buffer</code></em>);</pre>
+hb_buffer_get_script (<em class="parameter"><code><a class="link" href="harfbuzz-hb-buffer.html#hb-buffer-t"><span class="type">hb_buffer_t</span></a> *buffer</code></em>);</pre>
 <p>See <a class="link" href="harfbuzz-hb-buffer.html#hb-buffer-set-script" title="hb_buffer_set_script ()"><code class="function">hb_buffer_set_script()</code></a>.</p>
 <div class="refsect3">
 <a name="hb-buffer-get-script.parameters"></a><h4>Parameters</h4>
@@ -1343,7 +1361,7 @@ hb_buffer_get_script (<em class="parameter"><code><a class="link" href="harfbuzz
 </colgroup>
 <tbody><tr>
 <td class="parameter_name"><p>buffer</p></td>
-<td class="parameter_description"><p>an <a class="link" href="harfbuzz-hb-buffer.html#hb-buffer-t" title="hb_buffer_t"><span class="type">hb_buffer_t</span></a>.</p></td>
+<td class="parameter_description"><p>an <a class="link" href="harfbuzz-hb-buffer.html#hb-buffer-t"><span class="type">hb_buffer_t</span></a>.</p></td>
 <td class="parameter_annotations"> </td>
 </tr></tbody>
 </table></div>
@@ -1359,7 +1377,7 @@ hb_buffer_get_script (<em class="parameter"><code><a class="link" href="harfbuzz
 <div class="refsect2">
 <a name="hb-buffer-set-language"></a><h3>hb_buffer_set_language ()</h3>
 <pre class="programlisting"><span class="returnvalue">void</span>
-hb_buffer_set_language (<em class="parameter"><code><a class="link" href="harfbuzz-hb-buffer.html#hb-buffer-t" title="hb_buffer_t"><span class="type">hb_buffer_t</span></a> *buffer</code></em>,
+hb_buffer_set_language (<em class="parameter"><code><a class="link" href="harfbuzz-hb-buffer.html#hb-buffer-t"><span class="type">hb_buffer_t</span></a> *buffer</code></em>,
                         <em class="parameter"><code><a class="link" href="harfbuzz-hb-common.html#hb-language-t" title="hb_language_t"><span class="type">hb_language_t</span></a> language</code></em>);</pre>
 <p>Sets the language of <em class="parameter"><code>buffer</code></em>
  to <em class="parameter"><code>language</code></em>
@@ -1381,7 +1399,7 @@ different concepts and should not be confused with each other.</p>
 <tbody>
 <tr>
 <td class="parameter_name"><p>buffer</p></td>
-<td class="parameter_description"><p>an <a class="link" href="harfbuzz-hb-buffer.html#hb-buffer-t" title="hb_buffer_t"><span class="type">hb_buffer_t</span></a>.</p></td>
+<td class="parameter_description"><p>an <a class="link" href="harfbuzz-hb-buffer.html#hb-buffer-t"><span class="type">hb_buffer_t</span></a>.</p></td>
 <td class="parameter_annotations"> </td>
 </tr>
 <tr>
@@ -1398,7 +1416,7 @@ different concepts and should not be confused with each other.</p>
 <div class="refsect2">
 <a name="hb-buffer-get-language"></a><h3>hb_buffer_get_language ()</h3>
 <pre class="programlisting"><a class="link" href="harfbuzz-hb-common.html#hb-language-t" title="hb_language_t"><span class="returnvalue">hb_language_t</span></a>
-hb_buffer_get_language (<em class="parameter"><code><a class="link" href="harfbuzz-hb-buffer.html#hb-buffer-t" title="hb_buffer_t"><span class="type">hb_buffer_t</span></a> *buffer</code></em>);</pre>
+hb_buffer_get_language (<em class="parameter"><code><a class="link" href="harfbuzz-hb-buffer.html#hb-buffer-t"><span class="type">hb_buffer_t</span></a> *buffer</code></em>);</pre>
 <p>See <a class="link" href="harfbuzz-hb-buffer.html#hb-buffer-set-language" title="hb_buffer_set_language ()"><code class="function">hb_buffer_set_language()</code></a>.</p>
 <div class="refsect3">
 <a name="hb-buffer-get-language.parameters"></a><h4>Parameters</h4>
@@ -1410,7 +1428,7 @@ hb_buffer_get_language (<em class="parameter"><code><a class="link" href="harfbu
 </colgroup>
 <tbody><tr>
 <td class="parameter_name"><p>buffer</p></td>
-<td class="parameter_description"><p>an <a class="link" href="harfbuzz-hb-buffer.html#hb-buffer-t" title="hb_buffer_t"><span class="type">hb_buffer_t</span></a>.</p></td>
+<td class="parameter_description"><p>an <a class="link" href="harfbuzz-hb-buffer.html#hb-buffer-t"><span class="type">hb_buffer_t</span></a>.</p></td>
 <td class="parameter_annotations"> </td>
 </tr></tbody>
 </table></div>
@@ -1426,7 +1444,7 @@ hb_buffer_get_language (<em class="parameter"><code><a class="link" href="harfbu
 <div class="refsect2">
 <a name="hb-buffer-set-flags"></a><h3>hb_buffer_set_flags ()</h3>
 <pre class="programlisting"><span class="returnvalue">void</span>
-hb_buffer_set_flags (<em class="parameter"><code><a class="link" href="harfbuzz-hb-buffer.html#hb-buffer-t" title="hb_buffer_t"><span class="type">hb_buffer_t</span></a> *buffer</code></em>,
+hb_buffer_set_flags (<em class="parameter"><code><a class="link" href="harfbuzz-hb-buffer.html#hb-buffer-t"><span class="type">hb_buffer_t</span></a> *buffer</code></em>,
                      <em class="parameter"><code><a class="link" href="harfbuzz-hb-buffer.html#hb-buffer-flags-t" title="enum hb_buffer_flags_t"><span class="type">hb_buffer_flags_t</span></a> flags</code></em>);</pre>
 <p>Sets <em class="parameter"><code>buffer</code></em>
  flags to <em class="parameter"><code>flags</code></em>
@@ -1442,7 +1460,7 @@ hb_buffer_set_flags (<em class="parameter"><code><a class="link" href="harfbuzz-
 <tbody>
 <tr>
 <td class="parameter_name"><p>buffer</p></td>
-<td class="parameter_description"><p>an <a class="link" href="harfbuzz-hb-buffer.html#hb-buffer-t" title="hb_buffer_t"><span class="type">hb_buffer_t</span></a>.</p></td>
+<td class="parameter_description"><p>an <a class="link" href="harfbuzz-hb-buffer.html#hb-buffer-t"><span class="type">hb_buffer_t</span></a>.</p></td>
 <td class="parameter_annotations"> </td>
 </tr>
 <tr>
@@ -1459,7 +1477,7 @@ hb_buffer_set_flags (<em class="parameter"><code><a class="link" href="harfbuzz-
 <div class="refsect2">
 <a name="hb-buffer-get-flags"></a><h3>hb_buffer_get_flags ()</h3>
 <pre class="programlisting"><a class="link" href="harfbuzz-hb-buffer.html#hb-buffer-flags-t" title="enum hb_buffer_flags_t"><span class="returnvalue">hb_buffer_flags_t</span></a>
-hb_buffer_get_flags (<em class="parameter"><code><a class="link" href="harfbuzz-hb-buffer.html#hb-buffer-t" title="hb_buffer_t"><span class="type">hb_buffer_t</span></a> *buffer</code></em>);</pre>
+hb_buffer_get_flags (<em class="parameter"><code><a class="link" href="harfbuzz-hb-buffer.html#hb-buffer-t"><span class="type">hb_buffer_t</span></a> *buffer</code></em>);</pre>
 <p>See <a class="link" href="harfbuzz-hb-buffer.html#hb-buffer-set-flags" title="hb_buffer_set_flags ()"><code class="function">hb_buffer_set_flags()</code></a>.</p>
 <div class="refsect3">
 <a name="hb-buffer-get-flags.parameters"></a><h4>Parameters</h4>
@@ -1471,7 +1489,7 @@ hb_buffer_get_flags (<em class="parameter"><code><a class="link" href="harfbuzz-
 </colgroup>
 <tbody><tr>
 <td class="parameter_name"><p>buffer</p></td>
-<td class="parameter_description"><p>an <a class="link" href="harfbuzz-hb-buffer.html#hb-buffer-t" title="hb_buffer_t"><span class="type">hb_buffer_t</span></a>.</p></td>
+<td class="parameter_description"><p>an <a class="link" href="harfbuzz-hb-buffer.html#hb-buffer-t"><span class="type">hb_buffer_t</span></a>.</p></td>
 <td class="parameter_annotations"> </td>
 </tr></tbody>
 </table></div>
@@ -1487,7 +1505,7 @@ flags.</p>
 <div class="refsect2">
 <a name="hb-buffer-set-cluster-level"></a><h3>hb_buffer_set_cluster_level ()</h3>
 <pre class="programlisting"><span class="returnvalue">void</span>
-hb_buffer_set_cluster_level (<em class="parameter"><code><a class="link" href="harfbuzz-hb-buffer.html#hb-buffer-t" title="hb_buffer_t"><span class="type">hb_buffer_t</span></a> *buffer</code></em>,
+hb_buffer_set_cluster_level (<em class="parameter"><code><a class="link" href="harfbuzz-hb-buffer.html#hb-buffer-t"><span class="type">hb_buffer_t</span></a> *buffer</code></em>,
                              <em class="parameter"><code><a class="link" href="harfbuzz-hb-buffer.html#hb-buffer-cluster-level-t" title="enum hb_buffer_cluster_level_t"><span class="type">hb_buffer_cluster_level_t</span></a> cluster_level</code></em>);</pre>
 <div class="refsect3">
 <a name="hb-buffer-set-cluster-level.parameters"></a><h4>Parameters</h4>
@@ -1499,7 +1517,7 @@ hb_buffer_set_cluster_level (<em class="parameter"><code><a class="link" href="h
 </colgroup>
 <tbody><tr>
 <td class="parameter_name"><p>buffer</p></td>
-<td class="parameter_description"><p>an <a class="link" href="harfbuzz-hb-buffer.html#hb-buffer-t" title="hb_buffer_t"><span class="type">hb_buffer_t</span></a>.</p></td>
+<td class="parameter_description"><p>an <a class="link" href="harfbuzz-hb-buffer.html#hb-buffer-t"><span class="type">hb_buffer_t</span></a>.</p></td>
 <td class="parameter_annotations"> </td>
 </tr></tbody>
 </table></div>
@@ -1510,7 +1528,7 @@ hb_buffer_set_cluster_level (<em class="parameter"><code><a class="link" href="h
 <div class="refsect2">
 <a name="hb-buffer-get-cluster-level"></a><h3>hb_buffer_get_cluster_level ()</h3>
 <pre class="programlisting"><a class="link" href="harfbuzz-hb-buffer.html#hb-buffer-cluster-level-t" title="enum hb_buffer_cluster_level_t"><span class="returnvalue">hb_buffer_cluster_level_t</span></a>
-hb_buffer_get_cluster_level (<em class="parameter"><code><a class="link" href="harfbuzz-hb-buffer.html#hb-buffer-t" title="hb_buffer_t"><span class="type">hb_buffer_t</span></a> *buffer</code></em>);</pre>
+hb_buffer_get_cluster_level (<em class="parameter"><code><a class="link" href="harfbuzz-hb-buffer.html#hb-buffer-t"><span class="type">hb_buffer_t</span></a> *buffer</code></em>);</pre>
 <div class="refsect3">
 <a name="hb-buffer-get-cluster-level.parameters"></a><h4>Parameters</h4>
 <div class="informaltable"><table class="informaltable" width="100%" border="0">
@@ -1521,7 +1539,7 @@ hb_buffer_get_cluster_level (<em class="parameter"><code><a class="link" href="h
 </colgroup>
 <tbody><tr>
 <td class="parameter_name"><p>buffer</p></td>
-<td class="parameter_description"><p>an <a class="link" href="harfbuzz-hb-buffer.html#hb-buffer-t" title="hb_buffer_t"><span class="type">hb_buffer_t</span></a>.</p></td>
+<td class="parameter_description"><p>an <a class="link" href="harfbuzz-hb-buffer.html#hb-buffer-t"><span class="type">hb_buffer_t</span></a>.</p></td>
 <td class="parameter_annotations"> </td>
 </tr></tbody>
 </table></div>
@@ -1532,7 +1550,7 @@ hb_buffer_get_cluster_level (<em class="parameter"><code><a class="link" href="h
 <div class="refsect2">
 <a name="hb-buffer-set-length"></a><h3>hb_buffer_set_length ()</h3>
 <pre class="programlisting"><a class="link" href="harfbuzz-hb-common.html#hb-bool-t" title="hb_bool_t"><span class="returnvalue">hb_bool_t</span></a>
-hb_buffer_set_length (<em class="parameter"><code><a class="link" href="harfbuzz-hb-buffer.html#hb-buffer-t" title="hb_buffer_t"><span class="type">hb_buffer_t</span></a> *buffer</code></em>,
+hb_buffer_set_length (<em class="parameter"><code><a class="link" href="harfbuzz-hb-buffer.html#hb-buffer-t"><span class="type">hb_buffer_t</span></a> *buffer</code></em>,
                       <em class="parameter"><code>unsigned <span class="type">int</span> length</code></em>);</pre>
 <p>Similar to <a class="link" href="harfbuzz-hb-buffer.html#hb-buffer-pre-allocate" title="hb_buffer_pre_allocate ()"><code class="function">hb_buffer_pre_allocate()</code></a>, but clears any new items added at the
 end.</p>
@@ -1547,7 +1565,7 @@ end.</p>
 <tbody>
 <tr>
 <td class="parameter_name"><p>buffer</p></td>
-<td class="parameter_description"><p>an <a class="link" href="harfbuzz-hb-buffer.html#hb-buffer-t" title="hb_buffer_t"><span class="type">hb_buffer_t</span></a>.</p></td>
+<td class="parameter_description"><p>an <a class="link" href="harfbuzz-hb-buffer.html#hb-buffer-t"><span class="type">hb_buffer_t</span></a>.</p></td>
 <td class="parameter_annotations"> </td>
 </tr>
 <tr>
@@ -1570,7 +1588,7 @@ memory allocation succeeded, <code class="literal">false</code> otherwise.</p>
 <div class="refsect2">
 <a name="hb-buffer-get-length"></a><h3>hb_buffer_get_length ()</h3>
 <pre class="programlisting">unsigned <span class="returnvalue">int</span>
-hb_buffer_get_length (<em class="parameter"><code><a class="link" href="harfbuzz-hb-buffer.html#hb-buffer-t" title="hb_buffer_t"><span class="type">hb_buffer_t</span></a> *buffer</code></em>);</pre>
+hb_buffer_get_length (<em class="parameter"><code><a class="link" href="harfbuzz-hb-buffer.html#hb-buffer-t"><span class="type">hb_buffer_t</span></a> *buffer</code></em>);</pre>
 <p>Returns the number of items in the buffer.</p>
 <div class="refsect3">
 <a name="hb-buffer-get-length.parameters"></a><h4>Parameters</h4>
@@ -1582,7 +1600,7 @@ hb_buffer_get_length (<em class="parameter"><code><a class="link" href="harfbuzz
 </colgroup>
 <tbody><tr>
 <td class="parameter_name"><p>buffer</p></td>
-<td class="parameter_description"><p>an <a class="link" href="harfbuzz-hb-buffer.html#hb-buffer-t" title="hb_buffer_t"><span class="type">hb_buffer_t</span></a>.</p></td>
+<td class="parameter_description"><p>an <a class="link" href="harfbuzz-hb-buffer.html#hb-buffer-t"><span class="type">hb_buffer_t</span></a>.</p></td>
 <td class="parameter_annotations"> </td>
 </tr></tbody>
 </table></div>
@@ -1599,8 +1617,8 @@ The value valid as long as buffer has not been modified.</p>
 <div class="refsect2">
 <a name="hb-buffer-set-segment-properties"></a><h3>hb_buffer_set_segment_properties ()</h3>
 <pre class="programlisting"><span class="returnvalue">void</span>
-hb_buffer_set_segment_properties (<em class="parameter"><code><a class="link" href="harfbuzz-hb-buffer.html#hb-buffer-t" title="hb_buffer_t"><span class="type">hb_buffer_t</span></a> *buffer</code></em>,
-                                  <em class="parameter"><code>const <a class="link" href="harfbuzz-hb-buffer.html#hb-segment-properties-t" title="hb_segment_properties_t"><span class="type">hb_segment_properties_t</span></a> *props</code></em>);</pre>
+hb_buffer_set_segment_properties (<em class="parameter"><code><a class="link" href="harfbuzz-hb-buffer.html#hb-buffer-t"><span class="type">hb_buffer_t</span></a> *buffer</code></em>,
+                                  <em class="parameter"><code>const <a class="link" href="harfbuzz-hb-buffer.html#hb-segment-properties-t"><span class="type">hb_segment_properties_t</span></a> *props</code></em>);</pre>
 <p>Sets the segment properties of the buffer, a shortcut for calling
 <a class="link" href="harfbuzz-hb-buffer.html#hb-buffer-set-direction" title="hb_buffer_set_direction ()"><code class="function">hb_buffer_set_direction()</code></a>, <a class="link" href="harfbuzz-hb-buffer.html#hb-buffer-set-script" title="hb_buffer_set_script ()"><code class="function">hb_buffer_set_script()</code></a> and
 <a class="link" href="harfbuzz-hb-buffer.html#hb-buffer-set-language" title="hb_buffer_set_language ()"><code class="function">hb_buffer_set_language()</code></a> individually.</p>
@@ -1615,12 +1633,12 @@ hb_buffer_set_segment_properties (<em class="parameter"><code><a class="link" hr
 <tbody>
 <tr>
 <td class="parameter_name"><p>buffer</p></td>
-<td class="parameter_description"><p>an <a class="link" href="harfbuzz-hb-buffer.html#hb-buffer-t" title="hb_buffer_t"><span class="type">hb_buffer_t</span></a>.</p></td>
+<td class="parameter_description"><p>an <a class="link" href="harfbuzz-hb-buffer.html#hb-buffer-t"><span class="type">hb_buffer_t</span></a>.</p></td>
 <td class="parameter_annotations"> </td>
 </tr>
 <tr>
 <td class="parameter_name"><p>props</p></td>
-<td class="parameter_description"><p>an <a class="link" href="harfbuzz-hb-buffer.html#hb-segment-properties-t" title="hb_segment_properties_t"><span class="type">hb_segment_properties_t</span></a> to use.</p></td>
+<td class="parameter_description"><p>an <a class="link" href="harfbuzz-hb-buffer.html#hb-segment-properties-t"><span class="type">hb_segment_properties_t</span></a> to use.</p></td>
 <td class="parameter_annotations"> </td>
 </tr>
 </tbody>
@@ -1632,10 +1650,10 @@ hb_buffer_set_segment_properties (<em class="parameter"><code><a class="link" hr
 <div class="refsect2">
 <a name="hb-buffer-get-segment-properties"></a><h3>hb_buffer_get_segment_properties ()</h3>
 <pre class="programlisting"><span class="returnvalue">void</span>
-hb_buffer_get_segment_properties (<em class="parameter"><code><a class="link" href="harfbuzz-hb-buffer.html#hb-buffer-t" title="hb_buffer_t"><span class="type">hb_buffer_t</span></a> *buffer</code></em>,
-                                  <em class="parameter"><code><a class="link" href="harfbuzz-hb-buffer.html#hb-segment-properties-t" title="hb_segment_properties_t"><span class="type">hb_segment_properties_t</span></a> *props</code></em>);</pre>
+hb_buffer_get_segment_properties (<em class="parameter"><code><a class="link" href="harfbuzz-hb-buffer.html#hb-buffer-t"><span class="type">hb_buffer_t</span></a> *buffer</code></em>,
+                                  <em class="parameter"><code><a class="link" href="harfbuzz-hb-buffer.html#hb-segment-properties-t"><span class="type">hb_segment_properties_t</span></a> *props</code></em>);</pre>
 <p>Sets <em class="parameter"><code>props</code></em>
- to the <a class="link" href="harfbuzz-hb-buffer.html#hb-segment-properties-t" title="hb_segment_properties_t"><span class="type">hb_segment_properties_t</span></a> of <em class="parameter"><code>buffer</code></em>
+ to the <a class="link" href="harfbuzz-hb-buffer.html#hb-segment-properties-t"><span class="type">hb_segment_properties_t</span></a> of <em class="parameter"><code>buffer</code></em>
 .</p>
 <div class="refsect3">
 <a name="hb-buffer-get-segment-properties.parameters"></a><h4>Parameters</h4>
@@ -1648,12 +1666,12 @@ hb_buffer_get_segment_properties (<em class="parameter"><code><a class="link" hr
 <tbody>
 <tr>
 <td class="parameter_name"><p>buffer</p></td>
-<td class="parameter_description"><p>an <a class="link" href="harfbuzz-hb-buffer.html#hb-buffer-t" title="hb_buffer_t"><span class="type">hb_buffer_t</span></a>.</p></td>
+<td class="parameter_description"><p>an <a class="link" href="harfbuzz-hb-buffer.html#hb-buffer-t"><span class="type">hb_buffer_t</span></a>.</p></td>
 <td class="parameter_annotations"> </td>
 </tr>
 <tr>
 <td class="parameter_name"><p>props</p></td>
-<td class="parameter_description"><p>the output <a class="link" href="harfbuzz-hb-buffer.html#hb-segment-properties-t" title="hb_segment_properties_t"><span class="type">hb_segment_properties_t</span></a>. </p></td>
+<td class="parameter_description"><p>the output <a class="link" href="harfbuzz-hb-buffer.html#hb-segment-properties-t"><span class="type">hb_segment_properties_t</span></a>. </p></td>
 <td class="parameter_annotations"><span class="annotation">[<acronym title="Parameter for returning results. Default is transfer full."><span class="acronym">out</span></acronym>]</span></td>
 </tr>
 </tbody>
@@ -1665,7 +1683,7 @@ hb_buffer_get_segment_properties (<em class="parameter"><code><a class="link" hr
 <div class="refsect2">
 <a name="hb-buffer-guess-segment-properties"></a><h3>hb_buffer_guess_segment_properties ()</h3>
 <pre class="programlisting"><span class="returnvalue">void</span>
-hb_buffer_guess_segment_properties (<em class="parameter"><code><a class="link" href="harfbuzz-hb-buffer.html#hb-buffer-t" title="hb_buffer_t"><span class="type">hb_buffer_t</span></a> *buffer</code></em>);</pre>
+hb_buffer_guess_segment_properties (<em class="parameter"><code><a class="link" href="harfbuzz-hb-buffer.html#hb-buffer-t"><span class="type">hb_buffer_t</span></a> *buffer</code></em>);</pre>
 <p>Sets unset buffer segment properties based on buffer Unicode
 contents.  If buffer is not empty, it must have content type
 <a class="link" href="harfbuzz-hb-buffer.html#HB-BUFFER-CONTENT-TYPE-UNICODE:CAPS"><code class="literal">HB_BUFFER_CONTENT_TYPE_UNICODE</code></a>.</p>
@@ -1694,7 +1712,7 @@ it is called.  See documentation for that function for details.</p>
 </colgroup>
 <tbody><tr>
 <td class="parameter_name"><p>buffer</p></td>
-<td class="parameter_description"><p>an <a class="link" href="harfbuzz-hb-buffer.html#hb-buffer-t" title="hb_buffer_t"><span class="type">hb_buffer_t</span></a>.</p></td>
+<td class="parameter_description"><p>an <a class="link" href="harfbuzz-hb-buffer.html#hb-buffer-t"><span class="type">hb_buffer_t</span></a>.</p></td>
 <td class="parameter_annotations"> </td>
 </tr></tbody>
 </table></div>
@@ -1705,8 +1723,8 @@ it is called.  See documentation for that function for details.</p>
 <div class="refsect2">
 <a name="hb-buffer-set-unicode-funcs"></a><h3>hb_buffer_set_unicode_funcs ()</h3>
 <pre class="programlisting"><span class="returnvalue">void</span>
-hb_buffer_set_unicode_funcs (<em class="parameter"><code><a class="link" href="harfbuzz-hb-buffer.html#hb-buffer-t" title="hb_buffer_t"><span class="type">hb_buffer_t</span></a> *buffer</code></em>,
-                             <em class="parameter"><code><a class="link" href="harfbuzz-hb-unicode.html#hb-unicode-funcs-t" title="hb_unicode_funcs_t"><span class="type">hb_unicode_funcs_t</span></a> *unicode_funcs</code></em>);</pre>
+hb_buffer_set_unicode_funcs (<em class="parameter"><code><a class="link" href="harfbuzz-hb-buffer.html#hb-buffer-t"><span class="type">hb_buffer_t</span></a> *buffer</code></em>,
+                             <em class="parameter"><code><a class="link" href="harfbuzz-hb-unicode.html#hb-unicode-funcs-t"><span class="type">hb_unicode_funcs_t</span></a> *unicode_funcs</code></em>);</pre>
 <div class="refsect3">
 <a name="hb-buffer-set-unicode-funcs.parameters"></a><h4>Parameters</h4>
 <div class="informaltable"><table class="informaltable" width="100%" border="0">
@@ -1717,7 +1735,7 @@ hb_buffer_set_unicode_funcs (<em class="parameter"><code><a class="link" href="h
 </colgroup>
 <tbody><tr>
 <td class="parameter_name"><p>buffer</p></td>
-<td class="parameter_description"><p>an <a class="link" href="harfbuzz-hb-buffer.html#hb-buffer-t" title="hb_buffer_t"><span class="type">hb_buffer_t</span></a>.</p></td>
+<td class="parameter_description"><p>an <a class="link" href="harfbuzz-hb-buffer.html#hb-buffer-t"><span class="type">hb_buffer_t</span></a>.</p></td>
 <td class="parameter_annotations"> </td>
 </tr></tbody>
 </table></div>
@@ -1727,8 +1745,8 @@ hb_buffer_set_unicode_funcs (<em class="parameter"><code><a class="link" href="h
 <hr>
 <div class="refsect2">
 <a name="hb-buffer-get-unicode-funcs"></a><h3>hb_buffer_get_unicode_funcs ()</h3>
-<pre class="programlisting"><a class="link" href="harfbuzz-hb-unicode.html#hb-unicode-funcs-t" title="hb_unicode_funcs_t"><span class="returnvalue">hb_unicode_funcs_t</span></a> *
-hb_buffer_get_unicode_funcs (<em class="parameter"><code><a class="link" href="harfbuzz-hb-buffer.html#hb-buffer-t" title="hb_buffer_t"><span class="type">hb_buffer_t</span></a> *buffer</code></em>);</pre>
+<pre class="programlisting"><a class="link" href="harfbuzz-hb-unicode.html#hb-unicode-funcs-t"><span class="returnvalue">hb_unicode_funcs_t</span></a> *
+hb_buffer_get_unicode_funcs (<em class="parameter"><code><a class="link" href="harfbuzz-hb-buffer.html#hb-buffer-t"><span class="type">hb_buffer_t</span></a> *buffer</code></em>);</pre>
 <div class="refsect3">
 <a name="hb-buffer-get-unicode-funcs.parameters"></a><h4>Parameters</h4>
 <div class="informaltable"><table class="informaltable" width="100%" border="0">
@@ -1739,7 +1757,7 @@ hb_buffer_get_unicode_funcs (<em class="parameter"><code><a class="link" href="h
 </colgroup>
 <tbody><tr>
 <td class="parameter_name"><p>buffer</p></td>
-<td class="parameter_description"><p>an <a class="link" href="harfbuzz-hb-buffer.html#hb-buffer-t" title="hb_buffer_t"><span class="type">hb_buffer_t</span></a>.</p></td>
+<td class="parameter_description"><p>an <a class="link" href="harfbuzz-hb-buffer.html#hb-buffer-t"><span class="type">hb_buffer_t</span></a>.</p></td>
 <td class="parameter_annotations"> </td>
 </tr></tbody>
 </table></div>
@@ -1750,8 +1768,8 @@ hb_buffer_get_unicode_funcs (<em class="parameter"><code><a class="link" href="h
 <div class="refsect2">
 <a name="hb-buffer-set-user-data"></a><h3>hb_buffer_set_user_data ()</h3>
 <pre class="programlisting"><a class="link" href="harfbuzz-hb-common.html#hb-bool-t" title="hb_bool_t"><span class="returnvalue">hb_bool_t</span></a>
-hb_buffer_set_user_data (<em class="parameter"><code><a class="link" href="harfbuzz-hb-buffer.html#hb-buffer-t" title="hb_buffer_t"><span class="type">hb_buffer_t</span></a> *buffer</code></em>,
-                         <em class="parameter"><code><a class="link" href="harfbuzz-hb-common.html#hb-user-data-key-t" title="hb_user_data_key_t"><span class="type">hb_user_data_key_t</span></a> *key</code></em>,
+hb_buffer_set_user_data (<em class="parameter"><code><a class="link" href="harfbuzz-hb-buffer.html#hb-buffer-t"><span class="type">hb_buffer_t</span></a> *buffer</code></em>,
+                         <em class="parameter"><code><a class="link" href="harfbuzz-hb-common.html#hb-user-data-key-t"><span class="type">hb_user_data_key_t</span></a> *key</code></em>,
                          <em class="parameter"><code><span class="type">void</span> *data</code></em>,
                          <em class="parameter"><code><a class="link" href="harfbuzz-hb-common.html#hb-destroy-func-t" title="hb_destroy_func_t ()"><span class="type">hb_destroy_func_t</span></a> destroy</code></em>,
                          <em class="parameter"><code><a class="link" href="harfbuzz-hb-common.html#hb-bool-t" title="hb_bool_t"><span class="type">hb_bool_t</span></a> replace</code></em>);</pre>
@@ -1766,7 +1784,7 @@ hb_buffer_set_user_data (<em class="parameter"><code><a class="link" href="harfb
 </colgroup>
 <tbody><tr>
 <td class="parameter_name"><p>buffer</p></td>
-<td class="parameter_description"><p>an <a class="link" href="harfbuzz-hb-buffer.html#hb-buffer-t" title="hb_buffer_t"><span class="type">hb_buffer_t</span></a>.</p></td>
+<td class="parameter_description"><p>an <a class="link" href="harfbuzz-hb-buffer.html#hb-buffer-t"><span class="type">hb_buffer_t</span></a>.</p></td>
 <td class="parameter_annotations"> </td>
 </tr></tbody>
 </table></div>
@@ -1777,8 +1795,8 @@ hb_buffer_set_user_data (<em class="parameter"><code><a class="link" href="harfb
 <div class="refsect2">
 <a name="hb-buffer-get-user-data"></a><h3>hb_buffer_get_user_data ()</h3>
 <pre class="programlisting"><span class="returnvalue">void</span> *
-hb_buffer_get_user_data (<em class="parameter"><code><a class="link" href="harfbuzz-hb-buffer.html#hb-buffer-t" title="hb_buffer_t"><span class="type">hb_buffer_t</span></a> *buffer</code></em>,
-                         <em class="parameter"><code><a class="link" href="harfbuzz-hb-common.html#hb-user-data-key-t" title="hb_user_data_key_t"><span class="type">hb_user_data_key_t</span></a> *key</code></em>);</pre>
+hb_buffer_get_user_data (<em class="parameter"><code><a class="link" href="harfbuzz-hb-buffer.html#hb-buffer-t"><span class="type">hb_buffer_t</span></a> *buffer</code></em>,
+                         <em class="parameter"><code><a class="link" href="harfbuzz-hb-common.html#hb-user-data-key-t"><span class="type">hb_user_data_key_t</span></a> *key</code></em>);</pre>
 <p><span class="annotation">[<acronym title="Exposed in C code, not necessarily available in other languages."><span class="acronym">skip</span></acronym>]</span></p>
 <div class="refsect3">
 <a name="hb-buffer-get-user-data.parameters"></a><h4>Parameters</h4>
@@ -1790,7 +1808,7 @@ hb_buffer_get_user_data (<em class="parameter"><code><a class="link" href="harfb
 </colgroup>
 <tbody><tr>
 <td class="parameter_name"><p>buffer</p></td>
-<td class="parameter_description"><p>an <a class="link" href="harfbuzz-hb-buffer.html#hb-buffer-t" title="hb_buffer_t"><span class="type">hb_buffer_t</span></a>.</p></td>
+<td class="parameter_description"><p>an <a class="link" href="harfbuzz-hb-buffer.html#hb-buffer-t"><span class="type">hb_buffer_t</span></a>.</p></td>
 <td class="parameter_annotations"> </td>
 </tr></tbody>
 </table></div>
@@ -1801,7 +1819,7 @@ hb_buffer_get_user_data (<em class="parameter"><code><a class="link" href="harfb
 <div class="refsect2">
 <a name="hb-buffer-get-glyph-infos"></a><h3>hb_buffer_get_glyph_infos ()</h3>
 <pre class="programlisting"><span class="returnvalue">hb_glyph_info_t</span> *
-hb_buffer_get_glyph_infos (<em class="parameter"><code><a class="link" href="harfbuzz-hb-buffer.html#hb-buffer-t" title="hb_buffer_t"><span class="type">hb_buffer_t</span></a> *buffer</code></em>,
+hb_buffer_get_glyph_infos (<em class="parameter"><code><a class="link" href="harfbuzz-hb-buffer.html#hb-buffer-t"><span class="type">hb_buffer_t</span></a> *buffer</code></em>,
                            <em class="parameter"><code>unsigned <span class="type">int</span> *length</code></em>);</pre>
 <p>Returns <em class="parameter"><code>buffer</code></em>
  glyph information array.  Returned pointer
@@ -1818,7 +1836,7 @@ is valid as long as <em class="parameter"><code>buffer</code></em>
 <tbody>
 <tr>
 <td class="parameter_name"><p>buffer</p></td>
-<td class="parameter_description"><p>an <a class="link" href="harfbuzz-hb-buffer.html#hb-buffer-t" title="hb_buffer_t"><span class="type">hb_buffer_t</span></a>.</p></td>
+<td class="parameter_description"><p>an <a class="link" href="harfbuzz-hb-buffer.html#hb-buffer-t"><span class="type">hb_buffer_t</span></a>.</p></td>
 <td class="parameter_annotations"> </td>
 </tr>
 <tr>
@@ -1841,8 +1859,8 @@ The value valid as long as buffer has not been modified. </p>
 <hr>
 <div class="refsect2">
 <a name="hb-buffer-get-glyph-positions"></a><h3>hb_buffer_get_glyph_positions ()</h3>
-<pre class="programlisting"><a class="link" href="harfbuzz-hb-buffer.html#hb-glyph-position-t" title="hb_glyph_position_t"><span class="returnvalue">hb_glyph_position_t</span></a> *
-hb_buffer_get_glyph_positions (<em class="parameter"><code><a class="link" href="harfbuzz-hb-buffer.html#hb-buffer-t" title="hb_buffer_t"><span class="type">hb_buffer_t</span></a> *buffer</code></em>,
+<pre class="programlisting"><a class="link" href="harfbuzz-hb-buffer.html#hb-glyph-position-t"><span class="returnvalue">hb_glyph_position_t</span></a> *
+hb_buffer_get_glyph_positions (<em class="parameter"><code><a class="link" href="harfbuzz-hb-buffer.html#hb-buffer-t"><span class="type">hb_buffer_t</span></a> *buffer</code></em>,
                                <em class="parameter"><code>unsigned <span class="type">int</span> *length</code></em>);</pre>
 <p>Returns <em class="parameter"><code>buffer</code></em>
  glyph position array.  Returned pointer
@@ -1859,7 +1877,7 @@ is valid as long as <em class="parameter"><code>buffer</code></em>
 <tbody>
 <tr>
 <td class="parameter_name"><p>buffer</p></td>
-<td class="parameter_description"><p>an <a class="link" href="harfbuzz-hb-buffer.html#hb-buffer-t" title="hb_buffer_t"><span class="type">hb_buffer_t</span></a>.</p></td>
+<td class="parameter_description"><p>an <a class="link" href="harfbuzz-hb-buffer.html#hb-buffer-t"><span class="type">hb_buffer_t</span></a>.</p></td>
 <td class="parameter_annotations"> </td>
 </tr>
 <tr>
@@ -1883,7 +1901,7 @@ The value valid as long as buffer has not been modified. </p>
 <div class="refsect2">
 <a name="hb-buffer-get-invisible-glyph"></a><h3>hb_buffer_get_invisible_glyph ()</h3>
 <pre class="programlisting"><a class="link" href="harfbuzz-hb-common.html#hb-codepoint-t" title="hb_codepoint_t"><span class="returnvalue">hb_codepoint_t</span></a>
-hb_buffer_get_invisible_glyph (<em class="parameter"><code><a class="link" href="harfbuzz-hb-buffer.html#hb-buffer-t" title="hb_buffer_t"><span class="type">hb_buffer_t</span></a> *buffer</code></em>);</pre>
+hb_buffer_get_invisible_glyph (<em class="parameter"><code><a class="link" href="harfbuzz-hb-buffer.html#hb-buffer-t"><span class="type">hb_buffer_t</span></a> *buffer</code></em>);</pre>
 <p>See <a class="link" href="harfbuzz-hb-buffer.html#hb-buffer-set-invisible-glyph" title="hb_buffer_set_invisible_glyph ()"><code class="function">hb_buffer_set_invisible_glyph()</code></a>.</p>
 <div class="refsect3">
 <a name="hb-buffer-get-invisible-glyph.parameters"></a><h4>Parameters</h4>
@@ -1895,7 +1913,7 @@ hb_buffer_get_invisible_glyph (<em class="parameter"><code><a class="link" href=
 </colgroup>
 <tbody><tr>
 <td class="parameter_name"><p>buffer</p></td>
-<td class="parameter_description"><p>an <a class="link" href="harfbuzz-hb-buffer.html#hb-buffer-t" title="hb_buffer_t"><span class="type">hb_buffer_t</span></a>.</p></td>
+<td class="parameter_description"><p>an <a class="link" href="harfbuzz-hb-buffer.html#hb-buffer-t"><span class="type">hb_buffer_t</span></a>.</p></td>
 <td class="parameter_annotations"> </td>
 </tr></tbody>
 </table></div>
@@ -1911,7 +1929,7 @@ invisible <a class="link" href="harfbuzz-hb-common.html#hb-codepoint-t" title="h
 <div class="refsect2">
 <a name="hb-buffer-set-invisible-glyph"></a><h3>hb_buffer_set_invisible_glyph ()</h3>
 <pre class="programlisting"><span class="returnvalue">void</span>
-hb_buffer_set_invisible_glyph (<em class="parameter"><code><a class="link" href="harfbuzz-hb-buffer.html#hb-buffer-t" title="hb_buffer_t"><span class="type">hb_buffer_t</span></a> *buffer</code></em>,
+hb_buffer_set_invisible_glyph (<em class="parameter"><code><a class="link" href="harfbuzz-hb-buffer.html#hb-buffer-t"><span class="type">hb_buffer_t</span></a> *buffer</code></em>,
                                <em class="parameter"><code><a class="link" href="harfbuzz-hb-common.html#hb-codepoint-t" title="hb_codepoint_t"><span class="type">hb_codepoint_t</span></a> invisible</code></em>);</pre>
 <p>Sets the <a class="link" href="harfbuzz-hb-common.html#hb-codepoint-t" title="hb_codepoint_t"><span class="type">hb_codepoint_t</span></a> that replaces invisible characters in
 the shaping result.  If set to zero (default), the glyph for the
@@ -1928,7 +1946,7 @@ verbatim.</p>
 <tbody>
 <tr>
 <td class="parameter_name"><p>buffer</p></td>
-<td class="parameter_description"><p>an <a class="link" href="harfbuzz-hb-buffer.html#hb-buffer-t" title="hb_buffer_t"><span class="type">hb_buffer_t</span></a>.</p></td>
+<td class="parameter_description"><p>an <a class="link" href="harfbuzz-hb-buffer.html#hb-buffer-t"><span class="type">hb_buffer_t</span></a>.</p></td>
 <td class="parameter_annotations"> </td>
 </tr>
 <tr>
@@ -1945,7 +1963,7 @@ verbatim.</p>
 <div class="refsect2">
 <a name="hb-buffer-set-replacement-codepoint"></a><h3>hb_buffer_set_replacement_codepoint ()</h3>
 <pre class="programlisting"><span class="returnvalue">void</span>
-hb_buffer_set_replacement_codepoint (<em class="parameter"><code><a class="link" href="harfbuzz-hb-buffer.html#hb-buffer-t" title="hb_buffer_t"><span class="type">hb_buffer_t</span></a> *buffer</code></em>,
+hb_buffer_set_replacement_codepoint (<em class="parameter"><code><a class="link" href="harfbuzz-hb-buffer.html#hb-buffer-t"><span class="type">hb_buffer_t</span></a> *buffer</code></em>,
                                      <em class="parameter"><code><a class="link" href="harfbuzz-hb-common.html#hb-codepoint-t" title="hb_codepoint_t"><span class="type">hb_codepoint_t</span></a> replacement</code></em>);</pre>
 <p>Sets the <a class="link" href="harfbuzz-hb-common.html#hb-codepoint-t" title="hb_codepoint_t"><span class="type">hb_codepoint_t</span></a> that replaces invalid entries for a given encoding
 when adding text to <em class="parameter"><code>buffer</code></em>
@@ -1962,7 +1980,7 @@ when adding text to <em class="parameter"><code>buffer</code></em>
 <tbody>
 <tr>
 <td class="parameter_name"><p>buffer</p></td>
-<td class="parameter_description"><p>an <a class="link" href="harfbuzz-hb-buffer.html#hb-buffer-t" title="hb_buffer_t"><span class="type">hb_buffer_t</span></a>.</p></td>
+<td class="parameter_description"><p>an <a class="link" href="harfbuzz-hb-buffer.html#hb-buffer-t"><span class="type">hb_buffer_t</span></a>.</p></td>
 <td class="parameter_annotations"> </td>
 </tr>
 <tr>
@@ -1979,7 +1997,7 @@ when adding text to <em class="parameter"><code>buffer</code></em>
 <div class="refsect2">
 <a name="hb-buffer-get-replacement-codepoint"></a><h3>hb_buffer_get_replacement_codepoint ()</h3>
 <pre class="programlisting"><a class="link" href="harfbuzz-hb-common.html#hb-codepoint-t" title="hb_codepoint_t"><span class="returnvalue">hb_codepoint_t</span></a>
-hb_buffer_get_replacement_codepoint (<em class="parameter"><code><a class="link" href="harfbuzz-hb-buffer.html#hb-buffer-t" title="hb_buffer_t"><span class="type">hb_buffer_t</span></a> *buffer</code></em>);</pre>
+hb_buffer_get_replacement_codepoint (<em class="parameter"><code><a class="link" href="harfbuzz-hb-buffer.html#hb-buffer-t"><span class="type">hb_buffer_t</span></a> *buffer</code></em>);</pre>
 <p>See <a class="link" href="harfbuzz-hb-buffer.html#hb-buffer-set-replacement-codepoint" title="hb_buffer_set_replacement_codepoint ()"><code class="function">hb_buffer_set_replacement_codepoint()</code></a>.</p>
 <div class="refsect3">
 <a name="hb-buffer-get-replacement-codepoint.parameters"></a><h4>Parameters</h4>
@@ -1991,7 +2009,7 @@ hb_buffer_get_replacement_codepoint (<em class="parameter"><code><a class="link"
 </colgroup>
 <tbody><tr>
 <td class="parameter_name"><p>buffer</p></td>
-<td class="parameter_description"><p>an <a class="link" href="harfbuzz-hb-buffer.html#hb-buffer-t" title="hb_buffer_t"><span class="type">hb_buffer_t</span></a>.</p></td>
+<td class="parameter_description"><p>an <a class="link" href="harfbuzz-hb-buffer.html#hb-buffer-t"><span class="type">hb_buffer_t</span></a>.</p></td>
 <td class="parameter_annotations"> </td>
 </tr></tbody>
 </table></div>
@@ -2007,7 +2025,7 @@ replacement <a class="link" href="harfbuzz-hb-common.html#hb-codepoint-t" title=
 <div class="refsect2">
 <a name="hb-buffer-normalize-glyphs"></a><h3>hb_buffer_normalize_glyphs ()</h3>
 <pre class="programlisting"><span class="returnvalue">void</span>
-hb_buffer_normalize_glyphs (<em class="parameter"><code><a class="link" href="harfbuzz-hb-buffer.html#hb-buffer-t" title="hb_buffer_t"><span class="type">hb_buffer_t</span></a> *buffer</code></em>);</pre>
+hb_buffer_normalize_glyphs (<em class="parameter"><code><a class="link" href="harfbuzz-hb-buffer.html#hb-buffer-t"><span class="type">hb_buffer_t</span></a> *buffer</code></em>);</pre>
 <p>Reorders a glyph buffer to have canonical in-cluster glyph order / position.
 The resulting clusters should behave identical to pre-reordering clusters.</p>
 <div class="note">This has nothing to do with Unicode normalization.</div>
@@ -2021,7 +2039,7 @@ The resulting clusters should behave identical to pre-reordering clusters.</p>
 </colgroup>
 <tbody><tr>
 <td class="parameter_name"><p>buffer</p></td>
-<td class="parameter_description"><p>an <a class="link" href="harfbuzz-hb-buffer.html#hb-buffer-t" title="hb_buffer_t"><span class="type">hb_buffer_t</span></a>.</p></td>
+<td class="parameter_description"><p>an <a class="link" href="harfbuzz-hb-buffer.html#hb-buffer-t"><span class="type">hb_buffer_t</span></a>.</p></td>
 <td class="parameter_annotations"> </td>
 </tr></tbody>
 </table></div>
@@ -2032,7 +2050,7 @@ The resulting clusters should behave identical to pre-reordering clusters.</p>
 <div class="refsect2">
 <a name="hb-buffer-reverse"></a><h3>hb_buffer_reverse ()</h3>
 <pre class="programlisting"><span class="returnvalue">void</span>
-hb_buffer_reverse (<em class="parameter"><code><a class="link" href="harfbuzz-hb-buffer.html#hb-buffer-t" title="hb_buffer_t"><span class="type">hb_buffer_t</span></a> *buffer</code></em>);</pre>
+hb_buffer_reverse (<em class="parameter"><code><a class="link" href="harfbuzz-hb-buffer.html#hb-buffer-t"><span class="type">hb_buffer_t</span></a> *buffer</code></em>);</pre>
 <p>Reverses buffer contents.</p>
 <div class="refsect3">
 <a name="hb-buffer-reverse.parameters"></a><h4>Parameters</h4>
@@ -2044,7 +2062,7 @@ hb_buffer_reverse (<em class="parameter"><code><a class="link" href="harfbuzz-hb
 </colgroup>
 <tbody><tr>
 <td class="parameter_name"><p>buffer</p></td>
-<td class="parameter_description"><p>an <a class="link" href="harfbuzz-hb-buffer.html#hb-buffer-t" title="hb_buffer_t"><span class="type">hb_buffer_t</span></a>.</p></td>
+<td class="parameter_description"><p>an <a class="link" href="harfbuzz-hb-buffer.html#hb-buffer-t"><span class="type">hb_buffer_t</span></a>.</p></td>
 <td class="parameter_annotations"> </td>
 </tr></tbody>
 </table></div>
@@ -2055,7 +2073,7 @@ hb_buffer_reverse (<em class="parameter"><code><a class="link" href="harfbuzz-hb
 <div class="refsect2">
 <a name="hb-buffer-reverse-range"></a><h3>hb_buffer_reverse_range ()</h3>
 <pre class="programlisting"><span class="returnvalue">void</span>
-hb_buffer_reverse_range (<em class="parameter"><code><a class="link" href="harfbuzz-hb-buffer.html#hb-buffer-t" title="hb_buffer_t"><span class="type">hb_buffer_t</span></a> *buffer</code></em>,
+hb_buffer_reverse_range (<em class="parameter"><code><a class="link" href="harfbuzz-hb-buffer.html#hb-buffer-t"><span class="type">hb_buffer_t</span></a> *buffer</code></em>,
                          <em class="parameter"><code>unsigned <span class="type">int</span> start</code></em>,
                          <em class="parameter"><code>unsigned <span class="type">int</span> end</code></em>);</pre>
 <p>Reverses buffer contents between start to end.</p>
@@ -2070,7 +2088,7 @@ hb_buffer_reverse_range (<em class="parameter"><code><a class="link" href="harfb
 <tbody>
 <tr>
 <td class="parameter_name"><p>buffer</p></td>
-<td class="parameter_description"><p>an <a class="link" href="harfbuzz-hb-buffer.html#hb-buffer-t" title="hb_buffer_t"><span class="type">hb_buffer_t</span></a>.</p></td>
+<td class="parameter_description"><p>an <a class="link" href="harfbuzz-hb-buffer.html#hb-buffer-t"><span class="type">hb_buffer_t</span></a>.</p></td>
 <td class="parameter_annotations"> </td>
 </tr>
 <tr>
@@ -2092,7 +2110,7 @@ hb_buffer_reverse_range (<em class="parameter"><code><a class="link" href="harfb
 <div class="refsect2">
 <a name="hb-buffer-reverse-clusters"></a><h3>hb_buffer_reverse_clusters ()</h3>
 <pre class="programlisting"><span class="returnvalue">void</span>
-hb_buffer_reverse_clusters (<em class="parameter"><code><a class="link" href="harfbuzz-hb-buffer.html#hb-buffer-t" title="hb_buffer_t"><span class="type">hb_buffer_t</span></a> *buffer</code></em>);</pre>
+hb_buffer_reverse_clusters (<em class="parameter"><code><a class="link" href="harfbuzz-hb-buffer.html#hb-buffer-t"><span class="type">hb_buffer_t</span></a> *buffer</code></em>);</pre>
 <p>Reverses buffer clusters.  That is, the buffer contents are
 reversed, then each cluster (consecutive items having the
 same cluster number) are reversed again.</p>
@@ -2106,7 +2124,7 @@ same cluster number) are reversed again.</p>
 </colgroup>
 <tbody><tr>
 <td class="parameter_name"><p>buffer</p></td>
-<td class="parameter_description"><p>an <a class="link" href="harfbuzz-hb-buffer.html#hb-buffer-t" title="hb_buffer_t"><span class="type">hb_buffer_t</span></a>.</p></td>
+<td class="parameter_description"><p>an <a class="link" href="harfbuzz-hb-buffer.html#hb-buffer-t"><span class="type">hb_buffer_t</span></a>.</p></td>
 <td class="parameter_annotations"> </td>
 </tr></tbody>
 </table></div>
@@ -2117,13 +2135,13 @@ same cluster number) are reversed again.</p>
 <div class="refsect2">
 <a name="hb-buffer-serialize-glyphs"></a><h3>hb_buffer_serialize_glyphs ()</h3>
 <pre class="programlisting">unsigned <span class="returnvalue">int</span>
-hb_buffer_serialize_glyphs (<em class="parameter"><code><a class="link" href="harfbuzz-hb-buffer.html#hb-buffer-t" title="hb_buffer_t"><span class="type">hb_buffer_t</span></a> *buffer</code></em>,
+hb_buffer_serialize_glyphs (<em class="parameter"><code><a class="link" href="harfbuzz-hb-buffer.html#hb-buffer-t"><span class="type">hb_buffer_t</span></a> *buffer</code></em>,
                             <em class="parameter"><code>unsigned <span class="type">int</span> start</code></em>,
                             <em class="parameter"><code>unsigned <span class="type">int</span> end</code></em>,
                             <em class="parameter"><code><span class="type">char</span> *buf</code></em>,
                             <em class="parameter"><code>unsigned <span class="type">int</span> buf_size</code></em>,
                             <em class="parameter"><code>unsigned <span class="type">int</span> *buf_consumed</code></em>,
-                            <em class="parameter"><code><a class="link" href="harfbuzz-hb-font.html#hb-font-t" title="hb_font_t"><span class="type">hb_font_t</span></a> *font</code></em>,
+                            <em class="parameter"><code><a class="link" href="harfbuzz-hb-font.html#hb-font-t"><span class="type">hb_font_t</span></a> *font</code></em>,
                             <em class="parameter"><code><a class="link" href="harfbuzz-hb-buffer.html#hb-buffer-serialize-format-t" title="enum hb_buffer_serialize_format_t"><span class="type">hb_buffer_serialize_format_t</span></a> format</code></em>,
                             <em class="parameter"><code><a class="link" href="harfbuzz-hb-buffer.html#hb-buffer-serialize-flags-t" title="enum hb_buffer_serialize_flags_t"><span class="type">hb_buffer_serialize_flags_t</span></a> flags</code></em>);</pre>
 <p>Serializes <em class="parameter"><code>buffer</code></em>
@@ -2131,7 +2149,7 @@ hb_buffer_serialize_glyphs (<em class="parameter"><code><a class="link" href="ha
 useful for showing the contents of the buffer, for example during debugging.
 There are currently two supported serialization formats:</p>
 <div class="refsect3">
-<a name="id-1.3.4.3.7.48.5"></a><h4>text</h4>
+<a name="id-1.3.4.3.11.48.5"></a><h4>text</h4>
 <p>A human-readable, plain text format.
 The serialized glyphs will look something like:</p>
 <p><code class="literal">
@@ -2146,10 +2164,10 @@ The serialized glyphs will look something like:</p>
 <div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: circle; ">
 <li class="listitem"><p>If <a class="link" href="harfbuzz-hb-buffer.html#HB-BUFFER-SERIALIZE-FLAG-NO-CLUSTERS:CAPS"><span class="type">HB_BUFFER_SERIALIZE_FLAG_NO_CLUSTERS</span></a> is not set, <code class="literal">=</code> then <span class="type">hb_glyph_info_t.cluster</span>.</p></li>
 <li class="listitem">
-<p>If <a class="link" href="harfbuzz-hb-buffer.html#HB-BUFFER-SERIALIZE-FLAG-NO-POSITIONS:CAPS"><span class="type">HB_BUFFER_SERIALIZE_FLAG_NO_POSITIONS</span></a> is not set, the <a class="link" href="harfbuzz-hb-buffer.html#hb-glyph-position-t" title="hb_glyph_position_t"><span class="type">hb_glyph_position_t</span></a> in the format:</p>
+<p>If <a class="link" href="harfbuzz-hb-buffer.html#HB-BUFFER-SERIALIZE-FLAG-NO-POSITIONS:CAPS"><span class="type">HB_BUFFER_SERIALIZE_FLAG_NO_POSITIONS</span></a> is not set, the <a class="link" href="harfbuzz-hb-buffer.html#hb-glyph-position-t"><span class="type">hb_glyph_position_t</span></a> in the format:</p>
 <div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: square; ">
-<li class="listitem"><p>If both <a class="link" href="harfbuzz-hb-buffer.html#hb-glyph-position-t.x-offset"><span class="type">hb_glyph_position_t.x_offset</span></a> and <a class="link" href="harfbuzz-hb-buffer.html#hb-glyph-position-t.y-offset"><span class="type">hb_glyph_position_t.y_offset</span></a> are not 0, <code class="literal">@x_offset,y_offset</code>. Then,</p></li>
-<li class="listitem"><p><code class="literal">+x_advance</code>, then <code class="literal">,y_advance</code> if <a class="link" href="harfbuzz-hb-buffer.html#hb-glyph-position-t.y-advance"><span class="type">hb_glyph_position_t.y_advance</span></a> is not 0. Then,</p></li>
+<li class="listitem"><p>If both <span class="type">hb_glyph_position_t.x_offset</span> and <span class="type">hb_glyph_position_t.y_offset</span> are not 0, <code class="literal">@x_offset,y_offset</code>. Then,</p></li>
+<li class="listitem"><p><code class="literal">+x_advance</code>, then <code class="literal">,y_advance</code> if <span class="type">hb_glyph_position_t.y_advance</span> is not 0. Then,</p></li>
 </ul></div>
 </li>
 <li class="listitem"><p>If <a class="link" href="harfbuzz-hb-buffer.html#HB-BUFFER-SERIALIZE-FLAG-GLYPH-EXTENTS:CAPS"><span class="type">HB_BUFFER_SERIALIZE_FLAG_GLYPH_EXTENTS</span></a> is set, the
@@ -2160,7 +2178,7 @@ The serialized glyphs will look something like:</p>
 </ul></div>
 </div>
 <div class="refsect3">
-<a name="id-1.3.4.3.7.48.6"></a><h4>json</h4>
+<a name="id-1.3.4.3.11.48.6"></a><h4>json</h4>
 <p>TODO.</p>
 </div>
 <div class="refsect3">
@@ -2174,7 +2192,7 @@ The serialized glyphs will look something like:</p>
 <tbody>
 <tr>
 <td class="parameter_name"><p>buffer</p></td>
-<td class="parameter_description"><p>an <a class="link" href="harfbuzz-hb-buffer.html#hb-buffer-t" title="hb_buffer_t"><span class="type">hb_buffer_t</span></a> buffer.</p></td>
+<td class="parameter_description"><p>an <a class="link" href="harfbuzz-hb-buffer.html#hb-buffer-t"><span class="type">hb_buffer_t</span></a> buffer.</p></td>
 <td class="parameter_annotations"> </td>
 </tr>
 <tr>
@@ -2203,14 +2221,14 @@ write serialized buffer into. </p></td>
 </tr>
 <tr>
 <td class="parameter_name"><p>buf_consumed</p></td>
-<td class="parameter_description"><p>if not <a href="/usr/share/gtk-doc/html/glib/glib-Standard-Macros.html#NULL:CAPS"><code class="literal">NULL</code></a>, will be set to the number of byes written into <em class="parameter"><code>buf</code></em>
+<td class="parameter_description"><p>if not <code class="literal">NULL</code>, will be set to the number of byes written into <em class="parameter"><code>buf</code></em>
 . </p></td>
 <td class="parameter_annotations"><span class="annotation">[<acronym title="Parameter for returning results. Default is transfer full."><span class="acronym">out</span></acronym>][<acronym title="NULL is OK, both for passing and for returning."><span class="acronym">allow-none</span></acronym>]</span></td>
 </tr>
 <tr>
 <td class="parameter_name"><p>font</p></td>
-<td class="parameter_description"><p>the <a class="link" href="harfbuzz-hb-font.html#hb-font-t" title="hb_font_t"><span class="type">hb_font_t</span></a> used to shape this buffer, needed to
-read glyph names and extents. If <a href="/usr/share/gtk-doc/html/glib/glib-Standard-Macros.html#NULL:CAPS"><code class="literal">NULL</code></a>, and empty font will be used. </p></td>
+<td class="parameter_description"><p>the <a class="link" href="harfbuzz-hb-font.html#hb-font-t"><span class="type">hb_font_t</span></a> used to shape this buffer, needed to
+read glyph names and extents. If <code class="literal">NULL</code>, and empty font will be used. </p></td>
 <td class="parameter_annotations"><span class="annotation">[<acronym title="NULL is OK, both for passing and for returning."><span class="acronym">allow-none</span></acronym>]</span></td>
 </tr>
 <tr>
@@ -2237,11 +2255,11 @@ to serialize.</p></td>
 <div class="refsect2">
 <a name="hb-buffer-deserialize-glyphs"></a><h3>hb_buffer_deserialize_glyphs ()</h3>
 <pre class="programlisting"><a class="link" href="harfbuzz-hb-common.html#hb-bool-t" title="hb_bool_t"><span class="returnvalue">hb_bool_t</span></a>
-hb_buffer_deserialize_glyphs (<em class="parameter"><code><a class="link" href="harfbuzz-hb-buffer.html#hb-buffer-t" title="hb_buffer_t"><span class="type">hb_buffer_t</span></a> *buffer</code></em>,
+hb_buffer_deserialize_glyphs (<em class="parameter"><code><a class="link" href="harfbuzz-hb-buffer.html#hb-buffer-t"><span class="type">hb_buffer_t</span></a> *buffer</code></em>,
                               <em class="parameter"><code>const <span class="type">char</span> *buf</code></em>,
                               <em class="parameter"><code><span class="type">int</span> buf_len</code></em>,
                               <em class="parameter"><code>const <span class="type">char</span> **end_ptr</code></em>,
-                              <em class="parameter"><code><a class="link" href="harfbuzz-hb-font.html#hb-font-t" title="hb_font_t"><span class="type">hb_font_t</span></a> *font</code></em>,
+                              <em class="parameter"><code><a class="link" href="harfbuzz-hb-font.html#hb-font-t"><span class="type">hb_font_t</span></a> *font</code></em>,
                               <em class="parameter"><code><a class="link" href="harfbuzz-hb-buffer.html#hb-buffer-serialize-format-t" title="enum hb_buffer_serialize_format_t"><span class="type">hb_buffer_serialize_format_t</span></a> format</code></em>);</pre>
 <div class="refsect3">
 <a name="hb-buffer-deserialize-glyphs.parameters"></a><h4>Parameters</h4>
@@ -2254,7 +2272,7 @@ hb_buffer_deserialize_glyphs (<em class="parameter"><code><a class="link" href="
 <tbody>
 <tr>
 <td class="parameter_name"><p>buffer</p></td>
-<td class="parameter_description"><p>an <a class="link" href="harfbuzz-hb-buffer.html#hb-buffer-t" title="hb_buffer_t"><span class="type">hb_buffer_t</span></a> buffer.</p></td>
+<td class="parameter_description"><p>an <a class="link" href="harfbuzz-hb-buffer.html#hb-buffer-t"><span class="type">hb_buffer_t</span></a> buffer.</p></td>
 <td class="parameter_annotations"> </td>
 </tr>
 <tr>
@@ -2300,7 +2318,7 @@ hb_buffer_serialize_format_from_string
 <tr>
 <td class="parameter_name"><p>len</p></td>
 <td class="parameter_description"><p>length of <em class="parameter"><code>str</code></em>
-, or -1 if string is <a href="/usr/share/gtk-doc/html/glib/glib-Standard-Macros.html#NULL:CAPS"><code class="literal">NULL</code></a> terminated</p></td>
+, or -1 if string is <code class="literal">NULL</code> terminated</p></td>
 <td class="parameter_annotations"> </td>
 </tr>
 </tbody>
@@ -2318,7 +2336,7 @@ hb_buffer_serialize_format_from_string
 <pre class="programlisting">const <span class="returnvalue">char</span> *
 hb_buffer_serialize_format_to_string (<em class="parameter"><code><a class="link" href="harfbuzz-hb-buffer.html#hb-buffer-serialize-format-t" title="enum hb_buffer_serialize_format_t"><span class="type">hb_buffer_serialize_format_t</span></a> format</code></em>);</pre>
 <p>Converts <em class="parameter"><code>format</code></em>
- to the string corresponding it, or <a href="/usr/share/gtk-doc/html/glib/glib-Standard-Macros.html#NULL:CAPS"><code class="literal">NULL</code></a> if it is not a valid
+ to the string corresponding it, or <code class="literal">NULL</code> if it is not a valid
 <a class="link" href="harfbuzz-hb-buffer.html#hb-buffer-serialize-format-t" title="enum hb_buffer_serialize_format_t"><span class="type">hb_buffer_serialize_format_t</span></a>.</p>
 <div class="refsect3">
 <a name="hb-buffer-serialize-format-to-string.parameters"></a><h4>Parameters</h4>
@@ -2337,7 +2355,7 @@ hb_buffer_serialize_format_to_string (<em class="parameter"><code><a class="link
 </div>
 <div class="refsect3">
 <a name="hb-buffer-serialize-format-to-string.returns"></a><h4>Returns</h4>
-<p>A <a href="/usr/share/gtk-doc/html/glib/glib-Standard-Macros.html#NULL:CAPS"><code class="literal">NULL</code></a> terminated string corresponding to <em class="parameter"><code>format</code></em>
+<p>A <code class="literal">NULL</code> terminated string corresponding to <em class="parameter"><code>format</code></em>
 . Should not be freed. </p>
 <p><span class="annotation">[<acronym title="Don't free data after the code is done."><span class="acronym">transfer none</span></acronym>]</span></p>
 </div>
@@ -2360,9 +2378,9 @@ hb_buffer_serialize_list_formats (<em class="parameter"><code><span class="type"
 <div class="refsect2">
 <a name="hb-segment-properties-equal"></a><h3>hb_segment_properties_equal ()</h3>
 <pre class="programlisting"><a class="link" href="harfbuzz-hb-common.html#hb-bool-t" title="hb_bool_t"><span class="returnvalue">hb_bool_t</span></a>
-hb_segment_properties_equal (<em class="parameter"><code>const <a class="link" href="harfbuzz-hb-buffer.html#hb-segment-properties-t" title="hb_segment_properties_t"><span class="type">hb_segment_properties_t</span></a> *a</code></em>,
-                             <em class="parameter"><code>const <a class="link" href="harfbuzz-hb-buffer.html#hb-segment-properties-t" title="hb_segment_properties_t"><span class="type">hb_segment_properties_t</span></a> *b</code></em>);</pre>
-<p>Checks the equality of two <a class="link" href="harfbuzz-hb-buffer.html#hb-segment-properties-t" title="hb_segment_properties_t"><span class="type">hb_segment_properties_t</span></a>'s.</p>
+hb_segment_properties_equal (<em class="parameter"><code>const <a class="link" href="harfbuzz-hb-buffer.html#hb-segment-properties-t"><span class="type">hb_segment_properties_t</span></a> *a</code></em>,
+                             <em class="parameter"><code>const <a class="link" href="harfbuzz-hb-buffer.html#hb-segment-properties-t"><span class="type">hb_segment_properties_t</span></a> *b</code></em>);</pre>
+<p>Checks the equality of two <a class="link" href="harfbuzz-hb-buffer.html#hb-segment-properties-t"><span class="type">hb_segment_properties_t</span></a>'s.</p>
 <div class="refsect3">
 <a name="hb-segment-properties-equal.parameters"></a><h4>Parameters</h4>
 <div class="informaltable"><table class="informaltable" width="100%" border="0">
@@ -2374,12 +2392,12 @@ hb_segment_properties_equal (<em class="parameter"><code>const <a class="link" h
 <tbody>
 <tr>
 <td class="parameter_name"><p>a</p></td>
-<td class="parameter_description"><p>first <a class="link" href="harfbuzz-hb-buffer.html#hb-segment-properties-t" title="hb_segment_properties_t"><span class="type">hb_segment_properties_t</span></a> to compare.</p></td>
+<td class="parameter_description"><p>first <a class="link" href="harfbuzz-hb-buffer.html#hb-segment-properties-t"><span class="type">hb_segment_properties_t</span></a> to compare.</p></td>
 <td class="parameter_annotations"> </td>
 </tr>
 <tr>
 <td class="parameter_name"><p>b</p></td>
-<td class="parameter_description"><p>second <a class="link" href="harfbuzz-hb-buffer.html#hb-segment-properties-t" title="hb_segment_properties_t"><span class="type">hb_segment_properties_t</span></a> to compare.</p></td>
+<td class="parameter_description"><p>second <a class="link" href="harfbuzz-hb-buffer.html#hb-segment-properties-t"><span class="type">hb_segment_properties_t</span></a> to compare.</p></td>
 <td class="parameter_annotations"> </td>
 </tr>
 </tbody>
@@ -2397,7 +2415,7 @@ equal those of <em class="parameter"><code>b</code></em>
 <div class="refsect2">
 <a name="hb-segment-properties-hash"></a><h3>hb_segment_properties_hash ()</h3>
 <pre class="programlisting">unsigned <span class="returnvalue">int</span>
-hb_segment_properties_hash (<em class="parameter"><code>const <a class="link" href="harfbuzz-hb-buffer.html#hb-segment-properties-t" title="hb_segment_properties_t"><span class="type">hb_segment_properties_t</span></a> *p</code></em>);</pre>
+hb_segment_properties_hash (<em class="parameter"><code>const <a class="link" href="harfbuzz-hb-buffer.html#hb-segment-properties-t"><span class="type">hb_segment_properties_t</span></a> *p</code></em>);</pre>
 <p>Creates a hash representing <em class="parameter"><code>p</code></em>
 .</p>
 <div class="refsect3">
@@ -2410,7 +2428,7 @@ hb_segment_properties_hash (<em class="parameter"><code>const <a class="link" hr
 </colgroup>
 <tbody><tr>
 <td class="parameter_name"><p>p</p></td>
-<td class="parameter_description"><p><a class="link" href="harfbuzz-hb-buffer.html#hb-segment-properties-t" title="hb_segment_properties_t"><span class="type">hb_segment_properties_t</span></a> to hash.</p></td>
+<td class="parameter_description"><p><a class="link" href="harfbuzz-hb-buffer.html#hb-segment-properties-t"><span class="type">hb_segment_properties_t</span></a> to hash.</p></td>
 <td class="parameter_annotations"> </td>
 </tr></tbody>
 </table></div>
@@ -2426,8 +2444,8 @@ hb_segment_properties_hash (<em class="parameter"><code>const <a class="link" hr
 <div class="refsect2">
 <a name="hb-buffer-diff"></a><h3>hb_buffer_diff ()</h3>
 <pre class="programlisting"><a class="link" href="harfbuzz-hb-buffer.html#hb-buffer-diff-flags-t" title="enum hb_buffer_diff_flags_t"><span class="returnvalue">hb_buffer_diff_flags_t</span></a>
-hb_buffer_diff (<em class="parameter"><code><a class="link" href="harfbuzz-hb-buffer.html#hb-buffer-t" title="hb_buffer_t"><span class="type">hb_buffer_t</span></a> *buffer</code></em>,
-                <em class="parameter"><code><a class="link" href="harfbuzz-hb-buffer.html#hb-buffer-t" title="hb_buffer_t"><span class="type">hb_buffer_t</span></a> *reference</code></em>,
+hb_buffer_diff (<em class="parameter"><code><a class="link" href="harfbuzz-hb-buffer.html#hb-buffer-t"><span class="type">hb_buffer_t</span></a> *buffer</code></em>,
+                <em class="parameter"><code><a class="link" href="harfbuzz-hb-buffer.html#hb-buffer-t"><span class="type">hb_buffer_t</span></a> *reference</code></em>,
                 <em class="parameter"><code><a class="link" href="harfbuzz-hb-common.html#hb-codepoint-t" title="hb_codepoint_t"><span class="type">hb_codepoint_t</span></a> dottedcircle_glyph</code></em>,
                 <em class="parameter"><code>unsigned <span class="type">int</span> position_fuzz</code></em>);</pre>
 <p>If dottedcircle_glyph is (hb_codepoint_t) -1 then <a class="link" href="harfbuzz-hb-buffer.html#HB-BUFFER-DIFF-FLAG-DOTTED-CIRCLE-PRESENT:CAPS"><code class="literal">HB_BUFFER_DIFF_FLAG_DOTTED_CIRCLE_PRESENT</code></a>
@@ -2471,7 +2489,7 @@ callers if just comparing two buffers is needed.</p>
 <div class="refsect2">
 <a name="hb-buffer-set-message-func"></a><h3>hb_buffer_set_message_func ()</h3>
 <pre class="programlisting"><span class="returnvalue">void</span>
-hb_buffer_set_message_func (<em class="parameter"><code><a class="link" href="harfbuzz-hb-buffer.html#hb-buffer-t" title="hb_buffer_t"><span class="type">hb_buffer_t</span></a> *buffer</code></em>,
+hb_buffer_set_message_func (<em class="parameter"><code><a class="link" href="harfbuzz-hb-buffer.html#hb-buffer-t"><span class="type">hb_buffer_t</span></a> *buffer</code></em>,
                             <em class="parameter"><code><a class="link" href="harfbuzz-hb-buffer.html#hb-buffer-message-func-t" title="hb_buffer_message_func_t ()"><span class="type">hb_buffer_message_func_t</span></a> func</code></em>,
                             <em class="parameter"><code><span class="type">void</span> *user_data</code></em>,
                             <em class="parameter"><code><a class="link" href="harfbuzz-hb-common.html#hb-destroy-func-t" title="hb_destroy_func_t ()"><span class="type">hb_destroy_func_t</span></a> destroy</code></em>);</pre>
@@ -2486,7 +2504,7 @@ hb_buffer_set_message_func (<em class="parameter"><code><a class="link" href="ha
 <tbody>
 <tr>
 <td class="parameter_name"><p>buffer</p></td>
-<td class="parameter_description"><p>an <a class="link" href="harfbuzz-hb-buffer.html#hb-buffer-t" title="hb_buffer_t"><span class="type">hb_buffer_t</span></a>.</p></td>
+<td class="parameter_description"><p>an <a class="link" href="harfbuzz-hb-buffer.html#hb-buffer-t"><span class="type">hb_buffer_t</span></a>.</p></td>
 <td class="parameter_annotations"> </td>
 </tr>
 <tr>
@@ -2531,8 +2549,8 @@ hb_glyph_info_get_glyph_flags (<em class="parameter"><code>const <span class="ty
 <div class="refsect2">
 <a name="hb-buffer-message-func-t"></a><h3>hb_buffer_message_func_t ()</h3>
 <pre class="programlisting"><a class="link" href="harfbuzz-hb-common.html#hb-bool-t" title="hb_bool_t"><span class="returnvalue">hb_bool_t</span></a>
-<span class="c_punctuation">(</span>*hb_buffer_message_func_t<span class="c_punctuation">)</span> (<em class="parameter"><code><a class="link" href="harfbuzz-hb-buffer.html#hb-buffer-t" title="hb_buffer_t"><span class="type">hb_buffer_t</span></a> *buffer</code></em>,
-                             <em class="parameter"><code><a class="link" href="harfbuzz-hb-font.html#hb-font-t" title="hb_font_t"><span class="type">hb_font_t</span></a> *font</code></em>,
+<span class="c_punctuation">(</span>*hb_buffer_message_func_t<span class="c_punctuation">)</span> (<em class="parameter"><code><a class="link" href="harfbuzz-hb-buffer.html#hb-buffer-t"><span class="type">hb_buffer_t</span></a> *buffer</code></em>,
+                             <em class="parameter"><code><a class="link" href="harfbuzz-hb-font.html#hb-font-t"><span class="type">hb_font_t</span></a> *font</code></em>,
                              <em class="parameter"><code>const <span class="type">char</span> *message</code></em>,
                              <em class="parameter"><code><span class="type">void</span> *user_data</code></em>);</pre>
 </div>
@@ -2607,7 +2625,7 @@ and output glyphs and their information after shaping.</p>
 </div>
 <hr>
 <div class="refsect2">
-<a name="hb-glyph-position-t"></a><h3>hb_glyph_position_t</h3>
+<a name="hb-glyph-position-t-struct"></a><h3>hb_glyph_position_t</h3>
 <pre class="programlisting">typedef struct {
   hb_position_t  x_advance;
   hb_position_t  y_advance;
@@ -2615,9 +2633,9 @@ and output glyphs and their information after shaping.</p>
   hb_position_t  y_offset;
 } hb_glyph_position_t;
 </pre>
-<p>The <a class="link" href="harfbuzz-hb-buffer.html#hb-glyph-position-t" title="hb_glyph_position_t"><span class="type">hb_glyph_position_t</span></a> is the structure that holds the positions of the
+<p>The <a class="link" href="harfbuzz-hb-buffer.html#hb-glyph-position-t"><span class="type">hb_glyph_position_t</span></a> is the structure that holds the positions of the
 glyph in both horizontal and vertical directions. All positions in
-<a class="link" href="harfbuzz-hb-buffer.html#hb-glyph-position-t" title="hb_glyph_position_t"><span class="type">hb_glyph_position_t</span></a> are relative to the current point.</p>
+<a class="link" href="harfbuzz-hb-buffer.html#hb-glyph-position-t"><span class="type">hb_glyph_position_t</span></a> are relative to the current point.</p>
 <div class="refsect3">
 <a name="hb-glyph-position-t.members"></a><h4>Members</h4>
 <div class="informaltable"><table class="informaltable" width="100%" border="0">
@@ -2628,25 +2646,25 @@ glyph in both horizontal and vertical directions. All positions in
 </colgroup>
 <tbody>
 <tr>
-<td class="struct_member_name"><p><a class="link" href="harfbuzz-hb-common.html#hb-position-t" title="hb_position_t"><span class="type">hb_position_t</span></a> <em class="structfield"><code><a name="hb-glyph-position-t.x-advance"></a>x_advance</code></em>;</p></td>
+<td class="struct_member_name"><p><a class="link" href="harfbuzz-hb-common.html#hb-position-t" title="hb_position_t"><span class="type">hb_position_t</span></a> <em class="structfield"><code><a name="hb-glyph-position-t-struct.x-advance"></a>x_advance</code></em>;</p></td>
 <td class="struct_member_description"><p>how much the line advances after drawing this glyph when setting
 text in horizontal direction.</p></td>
 <td class="struct_member_annotations"> </td>
 </tr>
 <tr>
-<td class="struct_member_name"><p><a class="link" href="harfbuzz-hb-common.html#hb-position-t" title="hb_position_t"><span class="type">hb_position_t</span></a> <em class="structfield"><code><a name="hb-glyph-position-t.y-advance"></a>y_advance</code></em>;</p></td>
+<td class="struct_member_name"><p><a class="link" href="harfbuzz-hb-common.html#hb-position-t" title="hb_position_t"><span class="type">hb_position_t</span></a> <em class="structfield"><code><a name="hb-glyph-position-t-struct.y-advance"></a>y_advance</code></em>;</p></td>
 <td class="struct_member_description"><p>how much the line advances after drawing this glyph when setting
 text in vertical direction.</p></td>
 <td class="struct_member_annotations"> </td>
 </tr>
 <tr>
-<td class="struct_member_name"><p><a class="link" href="harfbuzz-hb-common.html#hb-position-t" title="hb_position_t"><span class="type">hb_position_t</span></a> <em class="structfield"><code><a name="hb-glyph-position-t.x-offset"></a>x_offset</code></em>;</p></td>
+<td class="struct_member_name"><p><a class="link" href="harfbuzz-hb-common.html#hb-position-t" title="hb_position_t"><span class="type">hb_position_t</span></a> <em class="structfield"><code><a name="hb-glyph-position-t-struct.x-offset"></a>x_offset</code></em>;</p></td>
 <td class="struct_member_description"><p>how much the glyph moves on the X-axis before drawing it, this
 should not affect how much the line advances.</p></td>
 <td class="struct_member_annotations"> </td>
 </tr>
 <tr>
-<td class="struct_member_name"><p><a class="link" href="harfbuzz-hb-common.html#hb-position-t" title="hb_position_t"><span class="type">hb_position_t</span></a> <em class="structfield"><code><a name="hb-glyph-position-t.y-offset"></a>y_offset</code></em>;</p></td>
+<td class="struct_member_name"><p><a class="link" href="harfbuzz-hb-common.html#hb-position-t" title="hb_position_t"><span class="type">hb_position_t</span></a> <em class="structfield"><code><a name="hb-glyph-position-t-struct.y-offset"></a>y_offset</code></em>;</p></td>
 <td class="struct_member_description"><p>how much the glyph moves on the Y-axis before drawing it, this
 should not affect how much the line advances.</p></td>
 <td class="struct_member_annotations"> </td>
@@ -2821,14 +2839,14 @@ should not affect how much the line advances.</p></td>
 </div>
 <hr>
 <div class="refsect2">
-<a name="hb-segment-properties-t"></a><h3>hb_segment_properties_t</h3>
+<a name="hb-segment-properties-t-struct"></a><h3>hb_segment_properties_t</h3>
 <pre class="programlisting">typedef struct {
   hb_direction_t  direction;
   hb_script_t     script;
   hb_language_t   language;
 } hb_segment_properties_t;
 </pre>
-<p>The structure that holds various text properties of an <a class="link" href="harfbuzz-hb-buffer.html#hb-buffer-t" title="hb_buffer_t"><span class="type">hb_buffer_t</span></a>. Can be
+<p>The structure that holds various text properties of an <a class="link" href="harfbuzz-hb-buffer.html#hb-buffer-t"><span class="type">hb_buffer_t</span></a>. Can be
 set and retrieved using <a class="link" href="harfbuzz-hb-buffer.html#hb-buffer-set-segment-properties" title="hb_buffer_set_segment_properties ()"><code class="function">hb_buffer_set_segment_properties()</code></a> and
 <a class="link" href="harfbuzz-hb-buffer.html#hb-buffer-get-segment-properties" title="hb_buffer_get_segment_properties ()"><code class="function">hb_buffer_get_segment_properties()</code></a>, respectively.</p>
 <div class="refsect3">
@@ -2841,17 +2859,17 @@ set and retrieved using <a class="link" href="harfbuzz-hb-buffer.html#hb-buffer-
 </colgroup>
 <tbody>
 <tr>
-<td class="struct_member_name"><p><a class="link" href="harfbuzz-hb-common.html#hb-direction-t" title="enum hb_direction_t"><span class="type">hb_direction_t</span></a> <em class="structfield"><code><a name="hb-segment-properties-t.direction"></a>direction</code></em>;</p></td>
+<td class="struct_member_name"><p><a class="link" href="harfbuzz-hb-common.html#hb-direction-t" title="enum hb_direction_t"><span class="type">hb_direction_t</span></a> <em class="structfield"><code><a name="hb-segment-properties-t-struct.direction"></a>direction</code></em>;</p></td>
 <td class="struct_member_description"><p>the <a class="link" href="harfbuzz-hb-common.html#hb-direction-t" title="enum hb_direction_t"><span class="type">hb_direction_t</span></a> of the buffer, see <a class="link" href="harfbuzz-hb-buffer.html#hb-buffer-set-direction" title="hb_buffer_set_direction ()"><code class="function">hb_buffer_set_direction()</code></a>.</p></td>
 <td class="struct_member_annotations"> </td>
 </tr>
 <tr>
-<td class="struct_member_name"><p><a class="link" href="harfbuzz-hb-common.html#hb-script-t" title="enum hb_script_t"><span class="type">hb_script_t</span></a> <em class="structfield"><code><a name="hb-segment-properties-t.script"></a>script</code></em>;</p></td>
+<td class="struct_member_name"><p><a class="link" href="harfbuzz-hb-common.html#hb-script-t" title="enum hb_script_t"><span class="type">hb_script_t</span></a> <em class="structfield"><code><a name="hb-segment-properties-t-struct.script"></a>script</code></em>;</p></td>
 <td class="struct_member_description"><p>the <a class="link" href="harfbuzz-hb-common.html#hb-script-t" title="enum hb_script_t"><span class="type">hb_script_t</span></a> of the buffer, see <a class="link" href="harfbuzz-hb-buffer.html#hb-buffer-set-script" title="hb_buffer_set_script ()"><code class="function">hb_buffer_set_script()</code></a>.</p></td>
 <td class="struct_member_annotations"> </td>
 </tr>
 <tr>
-<td class="struct_member_name"><p><a class="link" href="harfbuzz-hb-common.html#hb-language-t" title="hb_language_t"><span class="type">hb_language_t</span></a> <em class="structfield"><code><a name="hb-segment-properties-t.language"></a>language</code></em>;</p></td>
+<td class="struct_member_name"><p><a class="link" href="harfbuzz-hb-common.html#hb-language-t" title="hb_language_t"><span class="type">hb_language_t</span></a> <em class="structfield"><code><a name="hb-segment-properties-t-struct.language"></a>language</code></em>;</p></td>
 <td class="struct_member_description"><p>the <a class="link" href="harfbuzz-hb-common.html#hb-language-t" title="hb_language_t"><span class="type">hb_language_t</span></a> of the buffer, see <a class="link" href="harfbuzz-hb-buffer.html#hb-buffer-set-language" title="hb_buffer_set_language ()"><code class="function">hb_buffer_set_language()</code></a>.</p></td>
 <td class="struct_member_annotations"> </td>
 </tr>
index 7074d2c..9e6e597 100644 (file)
@@ -5,7 +5,7 @@
 <title>hb-common: HarfBuzz Manual</title>
 <meta name="generator" content="DocBook XSL Stylesheets Vsnapshot">
 <link rel="home" href="index.html" title="HarfBuzz Manual">
-<link rel="up" href="ch09.html" title="Core API">
+<link rel="up" href="ch11.html" title="Core API">
 <link rel="prev" href="harfbuzz-hb-buffer.html" title="hb-buffer">
 <link rel="next" href="harfbuzz-hb-deprecated.html" title="hb-deprecated">
 <meta name="generator" content="GTK-Doc V1.29 (XML mode)">
 <table class="navigation" id="top" width="100%" summary="Navigation header" cellpadding="2" cellspacing="5"><tr valign="middle">
 <td width="100%" align="left" class="shortcuts">
 <a href="#" class="shortcut">Top</a><span id="nav_description">  <span class="dim">|</span> 
-                  <a href="#harfbuzz-hb-common.description" class="shortcut">Description</a></span>
+                  <a href="#harfbuzz-hb-common.description" class="shortcut">Description</a></span><span id="nav_hierarchy">  <span class="dim">|</span> 
+                  <a href="#harfbuzz-hb-common.object-hierarchy" class="shortcut">Object Hierarchy</a></span>
 </td>
 <td><a accesskey="h" href="index.html"><img src="home.png" width="16" height="16" border="0" alt="Home"></a></td>
-<td><a accesskey="u" href="ch09.html"><img src="up.png" width="16" height="16" border="0" alt="Up"></a></td>
+<td><a accesskey="u" href="ch11.html"><img src="up.png" width="16" height="16" border="0" alt="Up"></a></td>
 <td><a accesskey="p" href="harfbuzz-hb-buffer.html"><img src="left.png" width="16" height="16" border="0" alt="Prev"></a></td>
 <td><a accesskey="n" href="harfbuzz-hb-deprecated.html"><img src="right.png" width="16" height="16" border="0" alt="Next"></a></td>
 </tr></table>
 </tbody>
 </table></div>
 </div>
-<div class="refsect1">
+<a name="hb-feature-t"></a><a name="hb-user-data-key-t"></a><div class="refsect1">
 <a name="harfbuzz-hb-common.other"></a><h2>Types and Values</h2>
 <div class="informaltable"><table class="informaltable" width="100%" border="0">
 <colgroup>
 </tr>
 <tr>
 <td class="datatype_keyword"> </td>
-<td class="function_name"><a class="link" href="harfbuzz-hb-common.html#hb-feature-t" title="hb_feature_t">hb_feature_t</a></td>
+<td class="function_name"><a class="link" href="harfbuzz-hb-common.html#hb-feature-t-struct" title="hb_feature_t">hb_feature_t</a></td>
 </tr>
 <tr>
 <td class="datatype_keyword"> </td>
 </tr>
 <tr>
 <td class="datatype_keyword"> </td>
-<td class="function_name"><a class="link" href="harfbuzz-hb-common.html#hb-user-data-key-t" title="hb_user_data_key_t">hb_user_data_key_t</a></td>
+<td class="function_name"><a class="link" href="harfbuzz-hb-common.html#hb-user-data-key-t-struct" title="hb_user_data_key_t">hb_user_data_key_t</a></td>
 </tr>
 <tr>
 <td class="datatype_keyword"> </td>
 </table></div>
 </div>
 <div class="refsect1">
+<a name="harfbuzz-hb-common.object-hierarchy"></a><h2>Object Hierarchy</h2>
+<pre class="screen">    <a href="/usr/share/gtk-doc/html/gobject/gobject-Boxed-Types.html">GBoxed</a>
+    <span class="lineart">├──</span> hb_feature_t
+    <span class="lineart">╰──</span> hb_user_data_key_t
+    <a href="/usr/share/gtk-doc/html/gobject/gobject-Enumeration-and-Flag-Types.html">GEnum</a>
+    <span class="lineart">├──</span> hb_direction_t
+    <span class="lineart">╰──</span> hb_script_t
+</pre>
+</div>
+<div class="refsect1">
 <a name="harfbuzz-hb-common.includes"></a><h2>Includes</h2>
 <pre class="synopsis">#include &lt;hb.h&gt;
 </pre>
@@ -445,7 +456,7 @@ ISO 15924 tag. </p></td>
 <tr>
 <td class="parameter_name"><p>len</p></td>
 <td class="parameter_description"><p>length of the <em class="parameter"><code>str</code></em>
-, or -1 if it is <a href="/usr/share/gtk-doc/html/glib/glib-Standard-Macros.html#NULL:CAPS"><code class="literal">NULL</code></a>-terminated.</p></td>
+, or -1 if it is <code class="literal">NULL</code>-terminated.</p></td>
 <td class="parameter_annotations"> </td>
 </tr>
 </tbody>
@@ -473,7 +484,7 @@ hb_script_to_iso15924_tag (<em class="parameter"><code><a class="link" href="har
 </colgroup>
 <tbody><tr>
 <td class="parameter_name"><p>script</p></td>
-<td class="parameter_description"><p>an <span class="type">hb_script_</span> to convert.</p></td>
+<td class="parameter_description"><p>an <a class="link" href="harfbuzz-hb-common.html#hb-script-t" title="enum hb_script_t"><span class="type">hb_script_t</span></a> to convert.</p></td>
 <td class="parameter_annotations"> </td>
 </tr></tbody>
 </table></div>
@@ -518,7 +529,7 @@ a BCP 47 language tag. </p></td>
 <tr>
 <td class="parameter_name"><p>len</p></td>
 <td class="parameter_description"><p>length of the <em class="parameter"><code>str</code></em>
-, or -1 if it is <a href="/usr/share/gtk-doc/html/glib/glib-Standard-Macros.html#NULL:CAPS"><code class="literal">NULL</code></a>-terminated.</p></td>
+, or -1 if it is <code class="literal">NULL</code>-terminated.</p></td>
 <td class="parameter_annotations"> </td>
 </tr>
 </tbody>
@@ -554,7 +565,7 @@ hb_language_to_string (<em class="parameter"><code><a class="link" href="harfbuz
 </div>
 <div class="refsect3">
 <a name="hb-language-to-string.returns"></a><h4>Returns</h4>
-<p>A <a href="/usr/share/gtk-doc/html/glib/glib-Standard-Macros.html#NULL:CAPS"><code class="literal">NULL</code></a>-terminated string representing the <em class="parameter"><code>language</code></em>
+<p>A <code class="literal">NULL</code>-terminated string representing the <em class="parameter"><code>language</code></em>
 . Must not be freed by
 the caller. </p>
 <p><span class="annotation">[<acronym title="Don't free data after the code is done."><span class="acronym">transfer none</span></acronym>]</span></p>
@@ -586,8 +597,8 @@ HarfBuzz itself.</p>
 <pre class="programlisting"><a class="link" href="harfbuzz-hb-common.html#hb-bool-t" title="hb_bool_t"><span class="returnvalue">hb_bool_t</span></a>
 hb_feature_from_string (<em class="parameter"><code>const <span class="type">char</span> *str</code></em>,
                         <em class="parameter"><code><span class="type">int</span> len</code></em>,
-                        <em class="parameter"><code><a class="link" href="harfbuzz-hb-common.html#hb-feature-t" title="hb_feature_t"><span class="type">hb_feature_t</span></a> *feature</code></em>);</pre>
-<p>Parses a string into a <a class="link" href="harfbuzz-hb-common.html#hb-feature-t" title="hb_feature_t"><span class="type">hb_feature_t</span></a>.</p>
+                        <em class="parameter"><code><a class="link" href="harfbuzz-hb-common.html#hb-feature-t"><span class="type">hb_feature_t</span></a> *feature</code></em>);</pre>
+<p>Parses a string into a <a class="link" href="harfbuzz-hb-common.html#hb-feature-t"><span class="type">hb_feature_t</span></a>.</p>
 <p>The format for specifying feature strings follows. All valid CSS
 font-feature-settings values other than 'normal' and the global values are
 also accepted, though not documented below. CSS string escapes are not
@@ -742,12 +753,12 @@ position before the first character is always 0.</p>
 <tr>
 <td class="parameter_name"><p>len</p></td>
 <td class="parameter_description"><p>length of <em class="parameter"><code>str</code></em>
-, or -1 if string is <a href="/usr/share/gtk-doc/html/glib/glib-Standard-Macros.html#NULL:CAPS"><code class="literal">NULL</code></a> terminated</p></td>
+, or -1 if string is <code class="literal">NULL</code> terminated</p></td>
 <td class="parameter_annotations"> </td>
 </tr>
 <tr>
 <td class="parameter_name"><p>feature</p></td>
-<td class="parameter_description"><p>the <a class="link" href="harfbuzz-hb-common.html#hb-feature-t" title="hb_feature_t"><span class="type">hb_feature_t</span></a> to initialize with the parsed values. </p></td>
+<td class="parameter_description"><p>the <a class="link" href="harfbuzz-hb-common.html#hb-feature-t"><span class="type">hb_feature_t</span></a> to initialize with the parsed values. </p></td>
 <td class="parameter_annotations"><span class="annotation">[<acronym title="Parameter for returning results. Default is transfer full."><span class="acronym">out</span></acronym>]</span></td>
 </tr>
 </tbody>
@@ -764,10 +775,10 @@ is successfully parsed, <code class="literal">false</code> otherwise.</p>
 <div class="refsect2">
 <a name="hb-feature-to-string"></a><h3>hb_feature_to_string ()</h3>
 <pre class="programlisting"><span class="returnvalue">void</span>
-hb_feature_to_string (<em class="parameter"><code><a class="link" href="harfbuzz-hb-common.html#hb-feature-t" title="hb_feature_t"><span class="type">hb_feature_t</span></a> *feature</code></em>,
+hb_feature_to_string (<em class="parameter"><code><a class="link" href="harfbuzz-hb-common.html#hb-feature-t"><span class="type">hb_feature_t</span></a> *feature</code></em>,
                       <em class="parameter"><code><span class="type">char</span> *buf</code></em>,
                       <em class="parameter"><code>unsigned <span class="type">int</span> size</code></em>);</pre>
-<p>Converts a <a class="link" href="harfbuzz-hb-common.html#hb-feature-t" title="hb_feature_t"><span class="type">hb_feature_t</span></a> into a <a href="/usr/share/gtk-doc/html/glib/glib-Standard-Macros.html#NULL:CAPS"><code class="literal">NULL</code></a>-terminated string in the format
+<p>Converts a <a class="link" href="harfbuzz-hb-common.html#hb-feature-t"><span class="type">hb_feature_t</span></a> into a <code class="literal">NULL</code>-terminated string in the format
 understood by <a class="link" href="harfbuzz-hb-common.html#hb-feature-from-string" title="hb_feature_from_string ()"><code class="function">hb_feature_from_string()</code></a>. The client in responsible for
 allocating big enough size for <em class="parameter"><code>buf</code></em>
 , 128 bytes is more than enough.</p>
@@ -782,7 +793,7 @@ allocating big enough size for <em class="parameter"><code>buf</code></em>
 <tbody>
 <tr>
 <td class="parameter_name"><p>feature</p></td>
-<td class="parameter_description"><p>an <a class="link" href="harfbuzz-hb-common.html#hb-feature-t" title="hb_feature_t"><span class="type">hb_feature_t</span></a> to convert</p></td>
+<td class="parameter_description"><p>an <a class="link" href="harfbuzz-hb-common.html#hb-feature-t"><span class="type">hb_feature_t</span></a> to convert</p></td>
 <td class="parameter_annotations"> </td>
 </tr>
 <tr>
@@ -946,7 +957,7 @@ hb_variation_to_string (<em class="parameter"><code><a class="link" href="harfbu
 </div>
 <hr>
 <div class="refsect2">
-<a name="hb-feature-t"></a><h3>hb_feature_t</h3>
+<a name="hb-feature-t-struct"></a><h3>hb_feature_t</h3>
 <pre class="programlisting">typedef struct {
   hb_tag_t      tag;
   uint32_t      value;
@@ -954,6 +965,50 @@ hb_variation_to_string (<em class="parameter"><code><a class="link" href="harfbu
   unsigned int  end;
 } hb_feature_t;
 </pre>
+<p>The <a class="link" href="harfbuzz-hb-common.html#hb-feature-t"><span class="type">hb_feature_t</span></a> is the structure that holds information about requested
+feature application. The feature will be applied with the given value to all
+glyphs which are in clusters between <em class="parameter"><code>start</code></em>
+ (inclusive) and <em class="parameter"><code>end</code></em>
+ (exclusive).
+Setting start to <em class="parameter"><code>HB_FEATURE_GLOBAL_START</code></em>
+ and end to <em class="parameter"><code>HB_FEATURE_GLOBAL_END</code></em>
+
+specifies that the feature always applies to the entire buffer.</p>
+<div class="refsect3">
+<a name="hb-feature-t.members"></a><h4>Members</h4>
+<div class="informaltable"><table class="informaltable" width="100%" border="0">
+<colgroup>
+<col width="300px" class="struct_members_name">
+<col class="struct_members_description">
+<col width="200px" class="struct_members_annotations">
+</colgroup>
+<tbody>
+<tr>
+<td class="struct_member_name"><p><a class="link" href="harfbuzz-hb-common.html#hb-tag-t" title="hb_tag_t"><span class="type">hb_tag_t</span></a> <em class="structfield"><code><a name="hb-feature-t-struct.tag"></a>tag</code></em>;</p></td>
+<td class="struct_member_description"><p>a feature tag</p></td>
+<td class="struct_member_annotations"> </td>
+</tr>
+<tr>
+<td class="struct_member_name"><p><span class="type">uint32_t</span> <em class="structfield"><code><a name="hb-feature-t-struct.value"></a>value</code></em>;</p></td>
+<td class="struct_member_description"><p>0 disables the feature, non-zero (usually 1) enables the feature.
+For features implemented as lookup type 3 (like 'salt') the <em class="parameter"><code>value</code></em>
+is a one
+based index into the alternates.</p></td>
+<td class="struct_member_annotations"> </td>
+</tr>
+<tr>
+<td class="struct_member_name"><p>unsigned <span class="type">int</span> <em class="structfield"><code><a name="hb-feature-t-struct.start"></a>start</code></em>;</p></td>
+<td class="struct_member_description"><p>the cluster to start applying this feature setting (inclusive).</p></td>
+<td class="struct_member_annotations"> </td>
+</tr>
+<tr>
+<td class="struct_member_name"><p>unsigned <span class="type">int</span> <em class="structfield"><code><a name="hb-feature-t-struct.end"></a>end</code></em>;</p></td>
+<td class="struct_member_description"><p>the cluster to end applying this feature setting (exclusive).</p></td>
+<td class="struct_member_annotations"> </td>
+</tr>
+</tbody>
+</table></div>
+</div>
 </div>
 <hr>
 <div class="refsect2">
@@ -1041,7 +1096,7 @@ hb_variation_to_string (<em class="parameter"><code><a class="link" href="harfbu
 </div>
 <hr>
 <div class="refsect2">
-<a name="hb-user-data-key-t"></a><h3>hb_user_data_key_t</h3>
+<a name="hb-user-data-key-t-struct"></a><h3>hb_user_data_key_t</h3>
 <pre class="programlisting">typedef struct {
 } hb_user_data_key_t;
 </pre>
index 143871a..3235a3a 100644 (file)
@@ -5,8 +5,8 @@
 <title>hb-coretext: HarfBuzz Manual</title>
 <meta name="generator" content="DocBook XSL Stylesheets Vsnapshot">
 <link rel="home" href="index.html" title="HarfBuzz Manual">
-<link rel="up" href="ch12.html" title="Integration API">
-<link rel="prev" href="ch12.html" title="Integration API">
+<link rel="up" href="ch14.html" title="Integration API">
+<link rel="prev" href="ch14.html" title="Integration API">
 <link rel="next" href="harfbuzz-hb-ft.html" title="hb-ft">
 <meta name="generator" content="GTK-Doc V1.29 (XML mode)">
 <link rel="stylesheet" href="style.css" type="text/css">
@@ -18,8 +18,8 @@
                   <a href="#harfbuzz-hb-coretext.description" class="shortcut">Description</a></span>
 </td>
 <td><a accesskey="h" href="index.html"><img src="home.png" width="16" height="16" border="0" alt="Home"></a></td>
-<td><a accesskey="u" href="ch12.html"><img src="up.png" width="16" height="16" border="0" alt="Up"></a></td>
-<td><a accesskey="p" href="ch12.html"><img src="left.png" width="16" height="16" border="0" alt="Prev"></a></td>
+<td><a accesskey="u" href="ch14.html"><img src="up.png" width="16" height="16" border="0" alt="Up"></a></td>
+<td><a accesskey="p" href="ch14.html"><img src="left.png" width="16" height="16" border="0" alt="Prev"></a></td>
 <td><a accesskey="n" href="harfbuzz-hb-ft.html"><img src="right.png" width="16" height="16" border="0" alt="Next"></a></td>
 </tr></table>
 <div class="refentry">
@@ -41,7 +41,7 @@
 <tbody>
 <tr>
 <td class="function_type">
-<a class="link" href="harfbuzz-hb-face.html#hb-face-t" title="hb_face_t"><span class="returnvalue">hb_face_t</span></a> *
+<a class="link" href="harfbuzz-hb-face.html#hb-face-t"><span class="returnvalue">hb_face_t</span></a> *
 </td>
 <td class="function_name">
 <a class="link" href="harfbuzz-hb-coretext.html#hb-coretext-face-create" title="hb_coretext_face_create ()">hb_coretext_face_create</a> <span class="c_punctuation">()</span>
@@ -49,7 +49,7 @@
 </tr>
 <tr>
 <td class="function_type">
-<a class="link" href="harfbuzz-hb-font.html#hb-font-t" title="hb_font_t"><span class="returnvalue">hb_font_t</span></a> *
+<a class="link" href="harfbuzz-hb-font.html#hb-font-t"><span class="returnvalue">hb_font_t</span></a> *
 </td>
 <td class="function_name">
 <a class="link" href="harfbuzz-hb-coretext.html#hb-coretext-font-create" title="hb_coretext_font_create ()">hb_coretext_font_create</a> <span class="c_punctuation">()</span>
 <a name="harfbuzz-hb-coretext.functions_details"></a><h2>Functions</h2>
 <div class="refsect2">
 <a name="hb-coretext-face-create"></a><h3>hb_coretext_face_create ()</h3>
-<pre class="programlisting"><a class="link" href="harfbuzz-hb-face.html#hb-face-t" title="hb_face_t"><span class="returnvalue">hb_face_t</span></a> *
+<pre class="programlisting"><a class="link" href="harfbuzz-hb-face.html#hb-face-t"><span class="returnvalue">hb_face_t</span></a> *
 hb_coretext_face_create (<em class="parameter"><code><span class="type">CGFontRef</span> cg_font</code></em>);</pre>
 </div>
 <hr>
 <div class="refsect2">
 <a name="hb-coretext-font-create"></a><h3>hb_coretext_font_create ()</h3>
-<pre class="programlisting"><a class="link" href="harfbuzz-hb-font.html#hb-font-t" title="hb_font_t"><span class="returnvalue">hb_font_t</span></a> *
+<pre class="programlisting"><a class="link" href="harfbuzz-hb-font.html#hb-font-t"><span class="returnvalue">hb_font_t</span></a> *
 hb_coretext_font_create (<em class="parameter"><code><span class="type">CTFontRef</span> ct_font</code></em>);</pre>
 </div>
 <hr>
 <div class="refsect2">
 <a name="hb-coretext-face-get-cg-font"></a><h3>hb_coretext_face_get_cg_font ()</h3>
 <pre class="programlisting"><span class="returnvalue">CGFontRef</span>
-hb_coretext_face_get_cg_font (<em class="parameter"><code><a class="link" href="harfbuzz-hb-face.html#hb-face-t" title="hb_face_t"><span class="type">hb_face_t</span></a> *face</code></em>);</pre>
+hb_coretext_face_get_cg_font (<em class="parameter"><code><a class="link" href="harfbuzz-hb-face.html#hb-face-t"><span class="type">hb_face_t</span></a> *face</code></em>);</pre>
 </div>
 <hr>
 <div class="refsect2">
 <a name="hb-coretext-font-get-ct-font"></a><h3>hb_coretext_font_get_ct_font ()</h3>
 <pre class="programlisting"><span class="returnvalue">CTFontRef</span>
-hb_coretext_font_get_ct_font (<em class="parameter"><code><a class="link" href="harfbuzz-hb-font.html#hb-font-t" title="hb_font_t"><span class="type">hb_font_t</span></a> *font</code></em>);</pre>
+hb_coretext_font_get_ct_font (<em class="parameter"><code><a class="link" href="harfbuzz-hb-font.html#hb-font-t"><span class="type">hb_font_t</span></a> *font</code></em>);</pre>
 </div>
 </div>
 <div class="refsect1">
index 428c2a7..2ad43b9 100644 (file)
@@ -5,7 +5,7 @@
 <title>hb-deprecated: HarfBuzz Manual</title>
 <meta name="generator" content="DocBook XSL Stylesheets Vsnapshot">
 <link rel="home" href="index.html" title="HarfBuzz Manual">
-<link rel="up" href="ch09.html" title="Core API">
+<link rel="up" href="ch11.html" title="Core API">
 <link rel="prev" href="harfbuzz-hb-common.html" title="hb-common">
 <link rel="next" href="harfbuzz-hb-face.html" title="hb-face">
 <meta name="generator" content="GTK-Doc V1.29 (XML mode)">
@@ -18,7 +18,7 @@
                   <a href="#harfbuzz-hb-deprecated.description" class="shortcut">Description</a></span>
 </td>
 <td><a accesskey="h" href="index.html"><img src="home.png" width="16" height="16" border="0" alt="Home"></a></td>
-<td><a accesskey="u" href="ch09.html"><img src="up.png" width="16" height="16" border="0" alt="Up"></a></td>
+<td><a accesskey="u" href="ch11.html"><img src="up.png" width="16" height="16" border="0" alt="Up"></a></td>
 <td><a accesskey="p" href="harfbuzz-hb-common.html"><img src="left.png" width="16" height="16" border="0" alt="Prev"></a></td>
 <td><a accesskey="n" href="harfbuzz-hb-face.html"><img src="right.png" width="16" height="16" border="0" alt="Next"></a></td>
 </tr></table>
 <span class="returnvalue">void</span>
 </td>
 <td class="function_name">
-<a class="link" href="harfbuzz-hb-deprecated.html#hb-font-funcs-set-glyph-h-kerning-func" title="hb_font_funcs_set_glyph_h_kerning_func ()">hb_font_funcs_set_glyph_h_kerning_func</a> <span class="c_punctuation">()</span>
-</td>
-</tr>
-<tr>
-<td class="function_type">
-<span class="returnvalue">void</span>
-</td>
-<td class="function_name">
 <a class="link" href="harfbuzz-hb-deprecated.html#hb-font-funcs-set-glyph-v-kerning-func" title="hb_font_funcs_set_glyph_v_kerning_func ()">hb_font_funcs_set_glyph_v_kerning_func</a> <span class="c_punctuation">()</span>
 </td>
 </tr>
 <a class="link" href="harfbuzz-hb-common.html#hb-position-t" title="hb_position_t"><span class="returnvalue">hb_position_t</span></a>
 </td>
 <td class="function_name">
-<a class="link" href="harfbuzz-hb-deprecated.html#hb-font-get-glyph-h-kerning" title="hb_font_get_glyph_h_kerning ()">hb_font_get_glyph_h_kerning</a> <span class="c_punctuation">()</span>
-</td>
-</tr>
-<tr>
-<td class="function_type">
-<span class="returnvalue">void</span>
-</td>
-<td class="function_name">
-<a class="link" href="harfbuzz-hb-deprecated.html#hb-font-get-glyph-kerning-for-direction" title="hb_font_get_glyph_kerning_for_direction ()">hb_font_get_glyph_kerning_for_direction</a> <span class="c_punctuation">()</span>
-</td>
-</tr>
-<tr>
-<td class="function_type">
-<a class="link" href="harfbuzz-hb-common.html#hb-position-t" title="hb_position_t"><span class="returnvalue">hb_position_t</span></a>
-</td>
-<td class="function_name">
-<span class="c_punctuation">(</span><a class="link" href="harfbuzz-hb-deprecated.html#hb-font-get-glyph-kerning-func-t" title="hb_font_get_glyph_kerning_func_t ()">*hb_font_get_glyph_kerning_func_t</a><span class="c_punctuation">)</span> <span class="c_punctuation">()</span>
-</td>
-</tr>
-<tr>
-<td class="function_type">
-<a class="link" href="harfbuzz-hb-common.html#hb-position-t" title="hb_position_t"><span class="returnvalue">hb_position_t</span></a>
-</td>
-<td class="function_name">
 <a class="link" href="harfbuzz-hb-deprecated.html#hb-font-get-glyph-v-kerning" title="hb_font_get_glyph_v_kerning ()">hb_font_get_glyph_v_kerning</a> <span class="c_punctuation">()</span>
 </td>
 </tr>
 </tr>
 <tr>
 <td class="define_keyword">#define</td>
-<td class="function_name"><a class="link" href="harfbuzz-hb-deprecated.html#HB-OT-VAR-NO-AXIS-INDEX:CAPS" title="HB_OT_VAR_NO_AXIS_INDEX">HB_OT_VAR_NO_AXIS_INDEX</a></td>
+<td class="function_name"><a class="link" href="harfbuzz-hb-deprecated.html#HB-MATH-GLYPH-PART-FLAG-EXTENDER:CAPS" title="HB_MATH_GLYPH_PART_FLAG_EXTENDER">HB_MATH_GLYPH_PART_FLAG_EXTENDER</a></td>
 </tr>
 <tr>
 <td class="define_keyword">#define</td>
-<td class="function_name"><a class="link" href="harfbuzz-hb-deprecated.html#HB-UNICODE-MAX-DECOMPOSITION-LEN:CAPS" title="HB_UNICODE_MAX_DECOMPOSITION_LEN">HB_UNICODE_MAX_DECOMPOSITION_LEN</a></td>
+<td class="function_name"><a class="link" href="harfbuzz-hb-deprecated.html#HB-OT-VAR-NO-AXIS-INDEX:CAPS" title="HB_OT_VAR_NO_AXIS_INDEX">HB_OT_VAR_NO_AXIS_INDEX</a></td>
 </tr>
 <tr>
-<td class="typedef_keyword">typedef</td>
-<td class="function_name"><a class="link" href="harfbuzz-hb-deprecated.html#hb-font-get-glyph-h-kerning-func-t" title="hb_font_get_glyph_h_kerning_func_t">hb_font_get_glyph_h_kerning_func_t</a></td>
+<td class="define_keyword">#define</td>
+<td class="function_name"><a class="link" href="harfbuzz-hb-deprecated.html#HB-UNICODE-MAX-DECOMPOSITION-LEN:CAPS" title="HB_UNICODE_MAX_DECOMPOSITION_LEN">HB_UNICODE_MAX_DECOMPOSITION_LEN</a></td>
 </tr>
 <tr>
 <td class="typedef_keyword">typedef</td>
@@ -160,7 +128,7 @@ were deemed unnecessary.</p>
 <div class="refsect2">
 <a name="hb-font-get-glyph-func-t"></a><h3>hb_font_get_glyph_func_t ()</h3>
 <pre class="programlisting"><a class="link" href="harfbuzz-hb-common.html#hb-bool-t" title="hb_bool_t"><span class="returnvalue">hb_bool_t</span></a>
-<span class="c_punctuation">(</span>*hb_font_get_glyph_func_t<span class="c_punctuation">)</span> (<em class="parameter"><code><a class="link" href="harfbuzz-hb-font.html#hb-font-t" title="hb_font_t"><span class="type">hb_font_t</span></a> *font</code></em>,
+<span class="c_punctuation">(</span>*hb_font_get_glyph_func_t<span class="c_punctuation">)</span> (<em class="parameter"><code><a class="link" href="harfbuzz-hb-font.html#hb-font-t"><span class="type">hb_font_t</span></a> *font</code></em>,
                              <em class="parameter"><code><span class="type">void</span> *font_data</code></em>,
                              <em class="parameter"><code><a class="link" href="harfbuzz-hb-common.html#hb-codepoint-t" title="hb_codepoint_t"><span class="type">hb_codepoint_t</span></a> unicode</code></em>,
                              <em class="parameter"><code><a class="link" href="harfbuzz-hb-common.html#hb-codepoint-t" title="hb_codepoint_t"><span class="type">hb_codepoint_t</span></a> variation_selector</code></em>,
@@ -172,23 +140,14 @@ were deemed unnecessary.</p>
 <div class="refsect2">
 <a name="hb-ot-layout-table-find-script"></a><h3>hb_ot_layout_table_find_script ()</h3>
 <pre class="programlisting"><a class="link" href="harfbuzz-hb-common.html#hb-bool-t" title="hb_bool_t"><span class="returnvalue">hb_bool_t</span></a>
-hb_ot_layout_table_find_script (<em class="parameter"><code><a class="link" href="harfbuzz-hb-face.html#hb-face-t" title="hb_face_t"><span class="type">hb_face_t</span></a> *face</code></em>,
+hb_ot_layout_table_find_script (<em class="parameter"><code><a class="link" href="harfbuzz-hb-face.html#hb-face-t"><span class="type">hb_face_t</span></a> *face</code></em>,
                                 <em class="parameter"><code><a class="link" href="harfbuzz-hb-common.html#hb-tag-t" title="hb_tag_t"><span class="type">hb_tag_t</span></a> table_tag</code></em>,
                                 <em class="parameter"><code><a class="link" href="harfbuzz-hb-common.html#hb-tag-t" title="hb_tag_t"><span class="type">hb_tag_t</span></a> script_tag</code></em>,
                                 <em class="parameter"><code>unsigned <span class="type">int</span> *script_index</code></em>);</pre>
-</div>
-<hr>
-<div class="refsect2">
-<a name="hb-font-funcs-set-glyph-h-kerning-func"></a><h3>hb_font_funcs_set_glyph_h_kerning_func ()</h3>
-<pre class="programlisting"><span class="returnvalue">void</span>
-hb_font_funcs_set_glyph_h_kerning_func
-                               (<em class="parameter"><code><a class="link" href="harfbuzz-hb-font.html#hb-font-funcs-t" title="hb_font_funcs_t"><span class="type">hb_font_funcs_t</span></a> *ffuncs</code></em>,
-                                <em class="parameter"><code><a class="link" href="harfbuzz-hb-deprecated.html#hb-font-get-glyph-h-kerning-func-t" title="hb_font_get_glyph_h_kerning_func_t"><span class="type">hb_font_get_glyph_h_kerning_func_t</span></a> func</code></em>,
-                                <em class="parameter"><code><span class="type">void</span> *user_data</code></em>,
-                                <em class="parameter"><code><a class="link" href="harfbuzz-hb-common.html#hb-destroy-func-t" title="hb_destroy_func_t ()"><span class="type">hb_destroy_func_t</span></a> destroy</code></em>);</pre>
-<div class="warning"><p><code class="literal">hb_font_funcs_set_glyph_h_kerning_func</code> has been deprecated since version 2.0.0 and should not be used in newly-written code.</p></div>
+<p>Fetches the index if a given script tag in the specified face's GSUB table
+or GPOS table.</p>
 <div class="refsect3">
-<a name="hb-font-funcs-set-glyph-h-kerning-func.parameters"></a><h4>Parameters</h4>
+<a name="hb-ot-layout-table-find-script.parameters"></a><h4>Parameters</h4>
 <div class="informaltable"><table class="informaltable" width="100%" border="0">
 <colgroup>
 <col width="150px" class="parameters_name">
@@ -197,26 +156,39 @@ hb_font_funcs_set_glyph_h_kerning_func
 </colgroup>
 <tbody>
 <tr>
-<td class="parameter_name"><p>ffuncs</p></td>
-<td class="parameter_description"><p>font functions.</p></td>
+<td class="parameter_name"><p>face</p></td>
+<td class="parameter_description"><p><a class="link" href="harfbuzz-hb-face.html#hb-face-t"><span class="type">hb_face_t</span></a> to work upon</p></td>
 <td class="parameter_annotations"> </td>
 </tr>
 <tr>
-<td class="parameter_name"><p>func</p></td>
-<td class="parameter_description"><p>. </p></td>
-<td class="parameter_annotations"><span class="annotation">[<acronym title="This parameter is a 'user_data', for callbacks; many bindings can pass NULL here."><span class="acronym">closure</span></acronym> user_data][<acronym title="This parameter is a 'destroy_data', for callbacks."><span class="acronym">destroy</span></acronym> destroy][<acronym title="The callback is valid until the GDestroyNotify argument is called."><span class="acronym">scope notified</span></acronym>]</span></td>
+<td class="parameter_name"><p>table_tag</p></td>
+<td class="parameter_description"><p>HB_OT_TAG_GSUB or HB_OT_TAG_GPOS</p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+<tr>
+<td class="parameter_name"><p>script_tag</p></td>
+<td class="parameter_description"><p><a class="link" href="harfbuzz-hb-common.html#hb-tag-t" title="hb_tag_t"><span class="type">hb_tag_t</span></a> of the script tag requested</p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+<tr>
+<td class="parameter_name"><p>script_index</p></td>
+<td class="parameter_description"><p>The index of the requested script tag. </p></td>
+<td class="parameter_annotations"><span class="annotation">[<acronym title="Parameter for returning results. Default is transfer full."><span class="acronym">out</span></acronym>]</span></td>
 </tr>
 </tbody>
 </table></div>
 </div>
-<p class="since">Since: <a class="link" href="api-index-0-9-2.html#api-index-0.9.2">0.9.2</a></p>
+<div class="refsect3">
+<a name="hb-ot-layout-table-find-script.returns"></a><h4>Returns</h4>
+<p> true if the script is found, false otherwise</p>
+</div>
 </div>
 <hr>
 <div class="refsect2">
 <a name="hb-font-funcs-set-glyph-v-kerning-func"></a><h3>hb_font_funcs_set_glyph_v_kerning_func ()</h3>
 <pre class="programlisting"><span class="returnvalue">void</span>
 hb_font_funcs_set_glyph_v_kerning_func
-                               (<em class="parameter"><code><a class="link" href="harfbuzz-hb-font.html#hb-font-funcs-t" title="hb_font_funcs_t"><span class="type">hb_font_funcs_t</span></a> *ffuncs</code></em>,
+                               (<em class="parameter"><code><a class="link" href="harfbuzz-hb-font.html#hb-font-funcs-t"><span class="type">hb_font_funcs_t</span></a> *ffuncs</code></em>,
                                 <em class="parameter"><code><a class="link" href="harfbuzz-hb-deprecated.html#hb-font-get-glyph-v-kerning-func-t" title="hb_font_get_glyph_v_kerning_func_t"><span class="type">hb_font_get_glyph_v_kerning_func_t</span></a> func</code></em>,
                                 <em class="parameter"><code><span class="type">void</span> *user_data</code></em>,
                                 <em class="parameter"><code><a class="link" href="harfbuzz-hb-common.html#hb-destroy-func-t" title="hb_destroy_func_t ()"><span class="type">hb_destroy_func_t</span></a> destroy</code></em>);</pre>
@@ -247,86 +219,9 @@ hb_font_funcs_set_glyph_v_kerning_func
 </div>
 <hr>
 <div class="refsect2">
-<a name="hb-font-get-glyph-h-kerning"></a><h3>hb_font_get_glyph_h_kerning ()</h3>
-<pre class="programlisting"><a class="link" href="harfbuzz-hb-common.html#hb-position-t" title="hb_position_t"><span class="returnvalue">hb_position_t</span></a>
-hb_font_get_glyph_h_kerning (<em class="parameter"><code><a class="link" href="harfbuzz-hb-font.html#hb-font-t" title="hb_font_t"><span class="type">hb_font_t</span></a> *font</code></em>,
-                             <em class="parameter"><code><a class="link" href="harfbuzz-hb-common.html#hb-codepoint-t" title="hb_codepoint_t"><span class="type">hb_codepoint_t</span></a> left_glyph</code></em>,
-                             <em class="parameter"><code><a class="link" href="harfbuzz-hb-common.html#hb-codepoint-t" title="hb_codepoint_t"><span class="type">hb_codepoint_t</span></a> right_glyph</code></em>);</pre>
-<div class="warning"><p><code class="literal">hb_font_get_glyph_h_kerning</code> has been deprecated since version 2.0.0 and should not be used in newly-written code.</p></div>
-<div class="refsect3">
-<a name="hb-font-get-glyph-h-kerning.parameters"></a><h4>Parameters</h4>
-<div class="informaltable"><table class="informaltable" width="100%" border="0">
-<colgroup>
-<col width="150px" class="parameters_name">
-<col class="parameters_description">
-<col width="200px" class="parameters_annotations">
-</colgroup>
-<tbody><tr>
-<td class="parameter_name"><p>font</p></td>
-<td class="parameter_description"><p>a font.</p></td>
-<td class="parameter_annotations"> </td>
-</tr></tbody>
-</table></div>
-</div>
-<p class="since">Since: <a class="link" href="api-index-0-9-2.html#api-index-0.9.2">0.9.2</a></p>
-</div>
-<hr>
-<div class="refsect2">
-<a name="hb-font-get-glyph-kerning-for-direction"></a><h3>hb_font_get_glyph_kerning_for_direction ()</h3>
-<pre class="programlisting"><span class="returnvalue">void</span>
-hb_font_get_glyph_kerning_for_direction
-                               (<em class="parameter"><code><a class="link" href="harfbuzz-hb-font.html#hb-font-t" title="hb_font_t"><span class="type">hb_font_t</span></a> *font</code></em>,
-                                <em class="parameter"><code><a class="link" href="harfbuzz-hb-common.html#hb-codepoint-t" title="hb_codepoint_t"><span class="type">hb_codepoint_t</span></a> first_glyph</code></em>,
-                                <em class="parameter"><code><a class="link" href="harfbuzz-hb-common.html#hb-codepoint-t" title="hb_codepoint_t"><span class="type">hb_codepoint_t</span></a> second_glyph</code></em>,
-                                <em class="parameter"><code><a class="link" href="harfbuzz-hb-common.html#hb-direction-t" title="enum hb_direction_t"><span class="type">hb_direction_t</span></a> direction</code></em>,
-                                <em class="parameter"><code><a class="link" href="harfbuzz-hb-common.html#hb-position-t" title="hb_position_t"><span class="type">hb_position_t</span></a> *x</code></em>,
-                                <em class="parameter"><code><a class="link" href="harfbuzz-hb-common.html#hb-position-t" title="hb_position_t"><span class="type">hb_position_t</span></a> *y</code></em>);</pre>
-<div class="warning"><p><code class="literal">hb_font_get_glyph_kerning_for_direction</code> has been deprecated since version 2.0.0 and should not be used in newly-written code.</p></div>
-<div class="refsect3">
-<a name="hb-font-get-glyph-kerning-for-direction.parameters"></a><h4>Parameters</h4>
-<div class="informaltable"><table class="informaltable" width="100%" border="0">
-<colgroup>
-<col width="150px" class="parameters_name">
-<col class="parameters_description">
-<col width="200px" class="parameters_annotations">
-</colgroup>
-<tbody>
-<tr>
-<td class="parameter_name"><p>font</p></td>
-<td class="parameter_description"><p>a font.</p></td>
-<td class="parameter_annotations"> </td>
-</tr>
-<tr>
-<td class="parameter_name"><p>x</p></td>
-<td class="parameter_description"><p>. </p></td>
-<td class="parameter_annotations"><span class="annotation">[<acronym title="Parameter for returning results. Default is transfer full."><span class="acronym">out</span></acronym>]</span></td>
-</tr>
-<tr>
-<td class="parameter_name"><p>y</p></td>
-<td class="parameter_description"><p>. </p></td>
-<td class="parameter_annotations"><span class="annotation">[<acronym title="Parameter for returning results. Default is transfer full."><span class="acronym">out</span></acronym>]</span></td>
-</tr>
-</tbody>
-</table></div>
-</div>
-<p class="since">Since: <a class="link" href="api-index-0-9-2.html#api-index-0.9.2">0.9.2</a></p>
-</div>
-<hr>
-<div class="refsect2">
-<a name="hb-font-get-glyph-kerning-func-t"></a><h3>hb_font_get_glyph_kerning_func_t ()</h3>
-<pre class="programlisting"><a class="link" href="harfbuzz-hb-common.html#hb-position-t" title="hb_position_t"><span class="returnvalue">hb_position_t</span></a>
-<span class="c_punctuation">(</span>*hb_font_get_glyph_kerning_func_t<span class="c_punctuation">)</span> (<em class="parameter"><code><a class="link" href="harfbuzz-hb-font.html#hb-font-t" title="hb_font_t"><span class="type">hb_font_t</span></a> *font</code></em>,
-                                     <em class="parameter"><code><span class="type">void</span> *font_data</code></em>,
-                                     <em class="parameter"><code><a class="link" href="harfbuzz-hb-common.html#hb-codepoint-t" title="hb_codepoint_t"><span class="type">hb_codepoint_t</span></a> first_glyph</code></em>,
-                                     <em class="parameter"><code><a class="link" href="harfbuzz-hb-common.html#hb-codepoint-t" title="hb_codepoint_t"><span class="type">hb_codepoint_t</span></a> second_glyph</code></em>,
-                                     <em class="parameter"><code><span class="type">void</span> *user_data</code></em>);</pre>
-<div class="warning"><p><code class="literal">hb_font_get_glyph_kerning_func_t</code> is deprecated and should not be used in newly-written code.</p></div>
-</div>
-<hr>
-<div class="refsect2">
 <a name="hb-font-get-glyph-v-kerning"></a><h3>hb_font_get_glyph_v_kerning ()</h3>
 <pre class="programlisting"><a class="link" href="harfbuzz-hb-common.html#hb-position-t" title="hb_position_t"><span class="returnvalue">hb_position_t</span></a>
-hb_font_get_glyph_v_kerning (<em class="parameter"><code><a class="link" href="harfbuzz-hb-font.html#hb-font-t" title="hb_font_t"><span class="type">hb_font_t</span></a> *font</code></em>,
+hb_font_get_glyph_v_kerning (<em class="parameter"><code><a class="link" href="harfbuzz-hb-font.html#hb-font-t"><span class="type">hb_font_t</span></a> *font</code></em>,
                              <em class="parameter"><code><a class="link" href="harfbuzz-hb-common.html#hb-codepoint-t" title="hb_codepoint_t"><span class="type">hb_codepoint_t</span></a> top_glyph</code></em>,
                              <em class="parameter"><code><a class="link" href="harfbuzz-hb-common.html#hb-codepoint-t" title="hb_codepoint_t"><span class="type">hb_codepoint_t</span></a> bottom_glyph</code></em>);</pre>
 <div class="warning"><p><code class="literal">hb_font_get_glyph_v_kerning</code> has been deprecated since version 2.0.0 and should not be used in newly-written code.</p></div>
@@ -372,6 +267,13 @@ hb_font_get_glyph_v_kerning (<em class="parameter"><code><a class="link" href="h
 </div>
 <hr>
 <div class="refsect2">
+<a name="HB-MATH-GLYPH-PART-FLAG-EXTENDER:CAPS"></a><h3>HB_MATH_GLYPH_PART_FLAG_EXTENDER</h3>
+<pre class="programlisting">#define HB_MATH_GLYPH_PART_FLAG_EXTENDER HB_OT_MATH_GLYPH_PART_FLAG_EXTENDER
+</pre>
+<div class="warning"><p><code class="literal">HB_MATH_GLYPH_PART_FLAG_EXTENDER</code> is deprecated and should not be used in newly-written code.</p></div>
+</div>
+<hr>
+<div class="refsect2">
 <a name="HB-OT-VAR-NO-AXIS-INDEX:CAPS"></a><h3>HB_OT_VAR_NO_AXIS_INDEX</h3>
 <pre class="programlisting">#define HB_OT_VAR_NO_AXIS_INDEX            0xFFFFFFFFu
 </pre>
@@ -388,13 +290,6 @@ hb_font_get_glyph_v_kerning (<em class="parameter"><code><a class="link" href="h
 </div>
 <hr>
 <div class="refsect2">
-<a name="hb-font-get-glyph-h-kerning-func-t"></a><h3>hb_font_get_glyph_h_kerning_func_t</h3>
-<pre class="programlisting">typedef hb_font_get_glyph_kerning_func_t hb_font_get_glyph_h_kerning_func_t;
-</pre>
-<div class="warning"><p><code class="literal">hb_font_get_glyph_h_kerning_func_t</code> is deprecated and should not be used in newly-written code.</p></div>
-</div>
-<hr>
-<div class="refsect2">
 <a name="hb-font-get-glyph-v-kerning-func-t"></a><h3>hb_font_get_glyph_v_kerning_func_t</h3>
 <pre class="programlisting">typedef hb_font_get_glyph_kerning_func_t hb_font_get_glyph_v_kerning_func_t;
 </pre>
index e32b160..b5ecebe 100644 (file)
@@ -5,7 +5,7 @@
 <title>hb-face: HarfBuzz Manual</title>
 <meta name="generator" content="DocBook XSL Stylesheets Vsnapshot">
 <link rel="home" href="index.html" title="HarfBuzz Manual">
-<link rel="up" href="ch09.html" title="Core API">
+<link rel="up" href="ch11.html" title="Core API">
 <link rel="prev" href="harfbuzz-hb-deprecated.html" title="hb-deprecated">
 <link rel="next" href="harfbuzz-hb-font.html" title="hb-font">
 <meta name="generator" content="GTK-Doc V1.29 (XML mode)">
 <table class="navigation" id="top" width="100%" summary="Navigation header" cellpadding="2" cellspacing="5"><tr valign="middle">
 <td width="100%" align="left" class="shortcuts">
 <a href="#" class="shortcut">Top</a><span id="nav_description">  <span class="dim">|</span> 
-                  <a href="#harfbuzz-hb-face.description" class="shortcut">Description</a></span>
+                  <a href="#harfbuzz-hb-face.description" class="shortcut">Description</a></span><span id="nav_hierarchy">  <span class="dim">|</span> 
+                  <a href="#harfbuzz-hb-face.object-hierarchy" class="shortcut">Object Hierarchy</a></span>
 </td>
 <td><a accesskey="h" href="index.html"><img src="home.png" width="16" height="16" border="0" alt="Home"></a></td>
-<td><a accesskey="u" href="ch09.html"><img src="up.png" width="16" height="16" border="0" alt="Up"></a></td>
+<td><a accesskey="u" href="ch11.html"><img src="up.png" width="16" height="16" border="0" alt="Up"></a></td>
 <td><a accesskey="p" href="harfbuzz-hb-deprecated.html"><img src="left.png" width="16" height="16" border="0" alt="Prev"></a></td>
 <td><a accesskey="n" href="harfbuzz-hb-font.html"><img src="right.png" width="16" height="16" border="0" alt="Next"></a></td>
 </tr></table>
@@ -48,7 +49,7 @@
 </tr>
 <tr>
 <td class="function_type">
-<a class="link" href="harfbuzz-hb-face.html#hb-face-t" title="hb_face_t"><span class="returnvalue">hb_face_t</span></a> *
+<a class="link" href="harfbuzz-hb-face.html#hb-face-t"><span class="returnvalue">hb_face_t</span></a> *
 </td>
 <td class="function_name">
 <a class="link" href="harfbuzz-hb-face.html#hb-face-create" title="hb_face_create ()">hb_face_create</a> <span class="c_punctuation">()</span>
@@ -56,7 +57,7 @@
 </tr>
 <tr>
 <td class="function_type">
-<a class="link" href="harfbuzz-hb-face.html#hb-face-t" title="hb_face_t"><span class="returnvalue">hb_face_t</span></a> *
+<a class="link" href="harfbuzz-hb-face.html#hb-face-t"><span class="returnvalue">hb_face_t</span></a> *
 </td>
 <td class="function_name">
 <a class="link" href="harfbuzz-hb-face.html#hb-face-create-for-tables" title="hb_face_create_for_tables ()">hb_face_create_for_tables</a> <span class="c_punctuation">()</span>
@@ -72,7 +73,7 @@
 </tr>
 <tr>
 <td class="function_type">
-<a class="link" href="harfbuzz-hb-face.html#hb-face-t" title="hb_face_t"><span class="returnvalue">hb_face_t</span></a> *
+<a class="link" href="harfbuzz-hb-face.html#hb-face-t"><span class="returnvalue">hb_face_t</span></a> *
 </td>
 <td class="function_name">
 <a class="link" href="harfbuzz-hb-face.html#hb-face-get-empty" title="hb_face_get_empty ()">hb_face_get_empty</a> <span class="c_punctuation">()</span>
 </tr>
 <tr>
 <td class="function_type">
-<a class="link" href="harfbuzz-hb-face.html#hb-face-t" title="hb_face_t"><span class="returnvalue">hb_face_t</span></a> *
+<a class="link" href="harfbuzz-hb-face.html#hb-face-t"><span class="returnvalue">hb_face_t</span></a> *
 </td>
 <td class="function_name">
 <a class="link" href="harfbuzz-hb-face.html#hb-face-reference" title="hb_face_reference ()">hb_face_reference</a> <span class="c_punctuation">()</span>
 </tr>
 <tr>
 <td class="function_type">
-<a class="link" href="harfbuzz-hb-blob.html#hb-blob-t" title="hb_blob_t"><span class="returnvalue">hb_blob_t</span></a> *
+<a class="link" href="harfbuzz-hb-blob.html#hb-blob-t"><span class="returnvalue">hb_blob_t</span></a> *
 </td>
 <td class="function_name">
 <a class="link" href="harfbuzz-hb-face.html#hb-face-reference-blob" title="hb_face_reference_blob ()">hb_face_reference_blob</a> <span class="c_punctuation">()</span>
 </tr>
 <tr>
 <td class="function_type">
-<a class="link" href="harfbuzz-hb-blob.html#hb-blob-t" title="hb_blob_t"><span class="returnvalue">hb_blob_t</span></a> *
+<a class="link" href="harfbuzz-hb-blob.html#hb-blob-t"><span class="returnvalue">hb_blob_t</span></a> *
 </td>
 <td class="function_name">
 <a class="link" href="harfbuzz-hb-face.html#hb-face-reference-table" title="hb_face_reference_table ()">hb_face_reference_table</a> <span class="c_punctuation">()</span>
 </tr>
 <tr>
 <td class="function_type">
-<a class="link" href="harfbuzz-hb-face.html#hb-face-t" title="hb_face_t"><span class="returnvalue">hb_face_t</span></a> *
+<a class="link" href="harfbuzz-hb-face.html#hb-face-t"><span class="returnvalue">hb_face_t</span></a> *
 </td>
 <td class="function_name">
 <a class="link" href="harfbuzz-hb-face.html#hb-face-builder-create" title="hb_face_builder_create ()">hb_face_builder_create</a> <span class="c_punctuation">()</span>
 </tbody>
 </table></div>
 </div>
-<div class="refsect1">
+<a name="hb-face-t"></a><div class="refsect1">
 <a name="harfbuzz-hb-face.other"></a><h2>Types and Values</h2>
 <div class="informaltable"><table class="informaltable" width="100%" border="0">
 <colgroup>
 </colgroup>
 <tbody><tr>
 <td class="typedef_keyword">typedef</td>
-<td class="function_name"><a class="link" href="harfbuzz-hb-face.html#hb-face-t" title="hb_face_t">hb_face_t</a></td>
+<td class="function_name"><a class="link" href="harfbuzz-hb-face.html#hb-face-t">hb_face_t</a></td>
 </tr></tbody>
 </table></div>
 </div>
 <div class="refsect1">
+<a name="harfbuzz-hb-face.object-hierarchy"></a><h2>Object Hierarchy</h2>
+<pre class="screen">    <a href="/usr/share/gtk-doc/html/gobject/gobject-Boxed-Types.html">GBoxed</a>
+    <span class="lineart">╰──</span> hb_face_t
+</pre>
+</div>
+<div class="refsect1">
 <a name="harfbuzz-hb-face.includes"></a><h2>Includes</h2>
 <pre class="synopsis">#include &lt;hb.h&gt;
 </pre>
@@ -259,7 +266,7 @@ Font faces are used to create fonts.</p>
 <div class="refsect2">
 <a name="hb-face-count"></a><h3>hb_face_count ()</h3>
 <pre class="programlisting">unsigned <span class="returnvalue">int</span>
-hb_face_count (<em class="parameter"><code><a class="link" href="harfbuzz-hb-blob.html#hb-blob-t" title="hb_blob_t"><span class="type">hb_blob_t</span></a> *blob</code></em>);</pre>
+hb_face_count (<em class="parameter"><code><a class="link" href="harfbuzz-hb-blob.html#hb-blob-t"><span class="type">hb_blob_t</span></a> *blob</code></em>);</pre>
 <p>Get number of faces in a blob.</p>
 <div class="refsect3">
 <a name="hb-face-count.parameters"></a><h4>Parameters</h4>
@@ -286,8 +293,8 @@ hb_face_count (<em class="parameter"><code><a class="link" href="harfbuzz-hb-blo
 <hr>
 <div class="refsect2">
 <a name="hb-face-create"></a><h3>hb_face_create ()</h3>
-<pre class="programlisting"><a class="link" href="harfbuzz-hb-face.html#hb-face-t" title="hb_face_t"><span class="returnvalue">hb_face_t</span></a> *
-hb_face_create (<em class="parameter"><code><a class="link" href="harfbuzz-hb-blob.html#hb-blob-t" title="hb_blob_t"><span class="type">hb_blob_t</span></a> *blob</code></em>,
+<pre class="programlisting"><a class="link" href="harfbuzz-hb-face.html#hb-face-t"><span class="returnvalue">hb_face_t</span></a> *
+hb_face_create (<em class="parameter"><code><a class="link" href="harfbuzz-hb-blob.html#hb-blob-t"><span class="type">hb_blob_t</span></a> *blob</code></em>,
                 <em class="parameter"><code>unsigned <span class="type">int</span> index</code></em>);</pre>
 <p><span class="annotation">[Xconstructor]</span></p>
 <div class="refsect3">
@@ -300,7 +307,7 @@ hb_face_create (<em class="parameter"><code><a class="link" href="harfbuzz-hb-bl
 <hr>
 <div class="refsect2">
 <a name="hb-face-create-for-tables"></a><h3>hb_face_create_for_tables ()</h3>
-<pre class="programlisting"><a class="link" href="harfbuzz-hb-face.html#hb-face-t" title="hb_face_t"><span class="returnvalue">hb_face_t</span></a> *
+<pre class="programlisting"><a class="link" href="harfbuzz-hb-face.html#hb-face-t"><span class="returnvalue">hb_face_t</span></a> *
 hb_face_create_for_tables (<em class="parameter"><code><a class="link" href="harfbuzz-hb-font.html#hb-reference-table-func-t" title="hb_reference_table_func_t ()"><span class="type">hb_reference_table_func_t</span></a> reference_table_func</code></em>,
                            <em class="parameter"><code><span class="type">void</span> *user_data</code></em>,
                            <em class="parameter"><code><a class="link" href="harfbuzz-hb-common.html#hb-destroy-func-t" title="hb_destroy_func_t ()"><span class="type">hb_destroy_func_t</span></a> destroy</code></em>);</pre>
@@ -329,7 +336,7 @@ hb_face_create_for_tables (<em class="parameter"><code><a class="link" href="har
 <div class="refsect2">
 <a name="hb-face-destroy"></a><h3>hb_face_destroy ()</h3>
 <pre class="programlisting"><span class="returnvalue">void</span>
-hb_face_destroy (<em class="parameter"><code><a class="link" href="harfbuzz-hb-face.html#hb-face-t" title="hb_face_t"><span class="type">hb_face_t</span></a> *face</code></em>);</pre>
+hb_face_destroy (<em class="parameter"><code><a class="link" href="harfbuzz-hb-face.html#hb-face-t"><span class="type">hb_face_t</span></a> *face</code></em>);</pre>
 <p><span class="annotation">[<acronym title="Exposed in C code, not necessarily available in other languages."><span class="acronym">skip</span></acronym>]</span></p>
 <div class="refsect3">
 <a name="hb-face-destroy.parameters"></a><h4>Parameters</h4>
@@ -351,7 +358,7 @@ hb_face_destroy (<em class="parameter"><code><a class="link" href="harfbuzz-hb-f
 <hr>
 <div class="refsect2">
 <a name="hb-face-get-empty"></a><h3>hb_face_get_empty ()</h3>
-<pre class="programlisting"><a class="link" href="harfbuzz-hb-face.html#hb-face-t" title="hb_face_t"><span class="returnvalue">hb_face_t</span></a> *
+<pre class="programlisting"><a class="link" href="harfbuzz-hb-face.html#hb-face-t"><span class="returnvalue">hb_face_t</span></a> *
 hb_face_get_empty (<em class="parameter"><code><span class="type">void</span></code></em>);</pre>
 <div class="refsect3">
 <a name="hb-face-get-empty.returns"></a><h4>Returns</h4>
@@ -363,7 +370,7 @@ hb_face_get_empty (<em class="parameter"><code><span class="type">void</span></c
 <div class="refsect2">
 <a name="hb-face-get-table-tags"></a><h3>hb_face_get_table_tags ()</h3>
 <pre class="programlisting">unsigned <span class="returnvalue">int</span>
-hb_face_get_table_tags (<em class="parameter"><code>const <a class="link" href="harfbuzz-hb-face.html#hb-face-t" title="hb_face_t"><span class="type">hb_face_t</span></a> *face</code></em>,
+hb_face_get_table_tags (<em class="parameter"><code>const <a class="link" href="harfbuzz-hb-face.html#hb-face-t"><span class="type">hb_face_t</span></a> *face</code></em>,
                         <em class="parameter"><code>unsigned <span class="type">int</span> start_offset</code></em>,
                         <em class="parameter"><code>unsigned <span class="type">int</span> *table_count</code></em>,
                         <em class="parameter"><code><a class="link" href="harfbuzz-hb-common.html#hb-tag-t" title="hb_tag_t"><span class="type">hb_tag_t</span></a> *table_tags</code></em>);</pre>
@@ -411,7 +418,7 @@ array, output number of items written.</p></td>
 <div class="refsect2">
 <a name="hb-face-get-glyph-count"></a><h3>hb_face_get_glyph_count ()</h3>
 <pre class="programlisting">unsigned <span class="returnvalue">int</span>
-hb_face_get_glyph_count (<em class="parameter"><code>const <a class="link" href="harfbuzz-hb-face.html#hb-face-t" title="hb_face_t"><span class="type">hb_face_t</span></a> *face</code></em>);</pre>
+hb_face_get_glyph_count (<em class="parameter"><code>const <a class="link" href="harfbuzz-hb-face.html#hb-face-t"><span class="type">hb_face_t</span></a> *face</code></em>);</pre>
 <div class="refsect3">
 <a name="hb-face-get-glyph-count.parameters"></a><h4>Parameters</h4>
 <div class="informaltable"><table class="informaltable" width="100%" border="0">
@@ -433,7 +440,7 @@ hb_face_get_glyph_count (<em class="parameter"><code>const <a class="link" href=
 <div class="refsect2">
 <a name="hb-face-get-index"></a><h3>hb_face_get_index ()</h3>
 <pre class="programlisting">unsigned <span class="returnvalue">int</span>
-hb_face_get_index (<em class="parameter"><code>const <a class="link" href="harfbuzz-hb-face.html#hb-face-t" title="hb_face_t"><span class="type">hb_face_t</span></a> *face</code></em>);</pre>
+hb_face_get_index (<em class="parameter"><code>const <a class="link" href="harfbuzz-hb-face.html#hb-face-t"><span class="type">hb_face_t</span></a> *face</code></em>);</pre>
 <div class="refsect3">
 <a name="hb-face-get-index.parameters"></a><h4>Parameters</h4>
 <div class="informaltable"><table class="informaltable" width="100%" border="0">
@@ -455,7 +462,7 @@ hb_face_get_index (<em class="parameter"><code>const <a class="link" href="harfb
 <div class="refsect2">
 <a name="hb-face-get-upem"></a><h3>hb_face_get_upem ()</h3>
 <pre class="programlisting">unsigned <span class="returnvalue">int</span>
-hb_face_get_upem (<em class="parameter"><code>const <a class="link" href="harfbuzz-hb-face.html#hb-face-t" title="hb_face_t"><span class="type">hb_face_t</span></a> *face</code></em>);</pre>
+hb_face_get_upem (<em class="parameter"><code>const <a class="link" href="harfbuzz-hb-face.html#hb-face-t"><span class="type">hb_face_t</span></a> *face</code></em>);</pre>
 <div class="refsect3">
 <a name="hb-face-get-upem.parameters"></a><h4>Parameters</h4>
 <div class="informaltable"><table class="informaltable" width="100%" border="0">
@@ -477,8 +484,8 @@ hb_face_get_upem (<em class="parameter"><code>const <a class="link" href="harfbu
 <div class="refsect2">
 <a name="hb-face-get-user-data"></a><h3>hb_face_get_user_data ()</h3>
 <pre class="programlisting"><span class="returnvalue">void</span> *
-hb_face_get_user_data (<em class="parameter"><code>const <a class="link" href="harfbuzz-hb-face.html#hb-face-t" title="hb_face_t"><span class="type">hb_face_t</span></a> *face</code></em>,
-                       <em class="parameter"><code><a class="link" href="harfbuzz-hb-common.html#hb-user-data-key-t" title="hb_user_data_key_t"><span class="type">hb_user_data_key_t</span></a> *key</code></em>);</pre>
+hb_face_get_user_data (<em class="parameter"><code>const <a class="link" href="harfbuzz-hb-face.html#hb-face-t"><span class="type">hb_face_t</span></a> *face</code></em>,
+                       <em class="parameter"><code><a class="link" href="harfbuzz-hb-common.html#hb-user-data-key-t"><span class="type">hb_user_data_key_t</span></a> *key</code></em>);</pre>
 <p><span class="annotation">[<acronym title="Exposed in C code, not necessarily available in other languages."><span class="acronym">skip</span></acronym>]</span></p>
 <div class="refsect3">
 <a name="hb-face-get-user-data.parameters"></a><h4>Parameters</h4>
@@ -506,7 +513,7 @@ hb_face_get_user_data (<em class="parameter"><code>const <a class="link" href="h
 <div class="refsect2">
 <a name="hb-face-is-immutable"></a><h3>hb_face_is_immutable ()</h3>
 <pre class="programlisting"><a class="link" href="harfbuzz-hb-common.html#hb-bool-t" title="hb_bool_t"><span class="returnvalue">hb_bool_t</span></a>
-hb_face_is_immutable (<em class="parameter"><code>const <a class="link" href="harfbuzz-hb-face.html#hb-face-t" title="hb_face_t"><span class="type">hb_face_t</span></a> *face</code></em>);</pre>
+hb_face_is_immutable (<em class="parameter"><code>const <a class="link" href="harfbuzz-hb-face.html#hb-face-t"><span class="type">hb_face_t</span></a> *face</code></em>);</pre>
 <div class="refsect3">
 <a name="hb-face-is-immutable.parameters"></a><h4>Parameters</h4>
 <div class="informaltable"><table class="informaltable" width="100%" border="0">
@@ -528,7 +535,7 @@ hb_face_is_immutable (<em class="parameter"><code>const <a class="link" href="ha
 <div class="refsect2">
 <a name="hb-face-make-immutable"></a><h3>hb_face_make_immutable ()</h3>
 <pre class="programlisting"><span class="returnvalue">void</span>
-hb_face_make_immutable (<em class="parameter"><code><a class="link" href="harfbuzz-hb-face.html#hb-face-t" title="hb_face_t"><span class="type">hb_face_t</span></a> *face</code></em>);</pre>
+hb_face_make_immutable (<em class="parameter"><code><a class="link" href="harfbuzz-hb-face.html#hb-face-t"><span class="type">hb_face_t</span></a> *face</code></em>);</pre>
 <div class="refsect3">
 <a name="hb-face-make-immutable.parameters"></a><h4>Parameters</h4>
 <div class="informaltable"><table class="informaltable" width="100%" border="0">
@@ -549,8 +556,8 @@ hb_face_make_immutable (<em class="parameter"><code><a class="link" href="harfbu
 <hr>
 <div class="refsect2">
 <a name="hb-face-reference"></a><h3>hb_face_reference ()</h3>
-<pre class="programlisting"><a class="link" href="harfbuzz-hb-face.html#hb-face-t" title="hb_face_t"><span class="returnvalue">hb_face_t</span></a> *
-hb_face_reference (<em class="parameter"><code><a class="link" href="harfbuzz-hb-face.html#hb-face-t" title="hb_face_t"><span class="type">hb_face_t</span></a> *face</code></em>);</pre>
+<pre class="programlisting"><a class="link" href="harfbuzz-hb-face.html#hb-face-t"><span class="returnvalue">hb_face_t</span></a> *
+hb_face_reference (<em class="parameter"><code><a class="link" href="harfbuzz-hb-face.html#hb-face-t"><span class="type">hb_face_t</span></a> *face</code></em>);</pre>
 <p><span class="annotation">[<acronym title="Exposed in C code, not necessarily available in other languages."><span class="acronym">skip</span></acronym>]</span></p>
 <div class="refsect3">
 <a name="hb-face-reference.parameters"></a><h4>Parameters</h4>
@@ -572,8 +579,8 @@ hb_face_reference (<em class="parameter"><code><a class="link" href="harfbuzz-hb
 <hr>
 <div class="refsect2">
 <a name="hb-face-reference-blob"></a><h3>hb_face_reference_blob ()</h3>
-<pre class="programlisting"><a class="link" href="harfbuzz-hb-blob.html#hb-blob-t" title="hb_blob_t"><span class="returnvalue">hb_blob_t</span></a> *
-hb_face_reference_blob (<em class="parameter"><code><a class="link" href="harfbuzz-hb-face.html#hb-face-t" title="hb_face_t"><span class="type">hb_face_t</span></a> *face</code></em>);</pre>
+<pre class="programlisting"><a class="link" href="harfbuzz-hb-blob.html#hb-blob-t"><span class="returnvalue">hb_blob_t</span></a> *
+hb_face_reference_blob (<em class="parameter"><code><a class="link" href="harfbuzz-hb-face.html#hb-face-t"><span class="type">hb_face_t</span></a> *face</code></em>);</pre>
 <div class="refsect3">
 <a name="hb-face-reference-blob.parameters"></a><h4>Parameters</h4>
 <div class="informaltable"><table class="informaltable" width="100%" border="0">
@@ -599,8 +606,8 @@ hb_face_reference_blob (<em class="parameter"><code><a class="link" href="harfbu
 <hr>
 <div class="refsect2">
 <a name="hb-face-reference-table"></a><h3>hb_face_reference_table ()</h3>
-<pre class="programlisting"><a class="link" href="harfbuzz-hb-blob.html#hb-blob-t" title="hb_blob_t"><span class="returnvalue">hb_blob_t</span></a> *
-hb_face_reference_table (<em class="parameter"><code>const <a class="link" href="harfbuzz-hb-face.html#hb-face-t" title="hb_face_t"><span class="type">hb_face_t</span></a> *face</code></em>,
+<pre class="programlisting"><a class="link" href="harfbuzz-hb-blob.html#hb-blob-t"><span class="returnvalue">hb_blob_t</span></a> *
+hb_face_reference_table (<em class="parameter"><code>const <a class="link" href="harfbuzz-hb-face.html#hb-face-t"><span class="type">hb_face_t</span></a> *face</code></em>,
                          <em class="parameter"><code><a class="link" href="harfbuzz-hb-common.html#hb-tag-t" title="hb_tag_t"><span class="type">hb_tag_t</span></a> tag</code></em>);</pre>
 <div class="refsect3">
 <a name="hb-face-reference-table.parameters"></a><h4>Parameters</h4>
@@ -628,7 +635,7 @@ hb_face_reference_table (<em class="parameter"><code>const <a class="link" href=
 <div class="refsect2">
 <a name="hb-face-set-glyph-count"></a><h3>hb_face_set_glyph_count ()</h3>
 <pre class="programlisting"><span class="returnvalue">void</span>
-hb_face_set_glyph_count (<em class="parameter"><code><a class="link" href="harfbuzz-hb-face.html#hb-face-t" title="hb_face_t"><span class="type">hb_face_t</span></a> *face</code></em>,
+hb_face_set_glyph_count (<em class="parameter"><code><a class="link" href="harfbuzz-hb-face.html#hb-face-t"><span class="type">hb_face_t</span></a> *face</code></em>,
                          <em class="parameter"><code>unsigned <span class="type">int</span> glyph_count</code></em>);</pre>
 <div class="refsect3">
 <a name="hb-face-set-glyph-count.parameters"></a><h4>Parameters</h4>
@@ -651,7 +658,7 @@ hb_face_set_glyph_count (<em class="parameter"><code><a class="link" href="harfb
 <div class="refsect2">
 <a name="hb-face-set-index"></a><h3>hb_face_set_index ()</h3>
 <pre class="programlisting"><span class="returnvalue">void</span>
-hb_face_set_index (<em class="parameter"><code><a class="link" href="harfbuzz-hb-face.html#hb-face-t" title="hb_face_t"><span class="type">hb_face_t</span></a> *face</code></em>,
+hb_face_set_index (<em class="parameter"><code><a class="link" href="harfbuzz-hb-face.html#hb-face-t"><span class="type">hb_face_t</span></a> *face</code></em>,
                    <em class="parameter"><code>unsigned <span class="type">int</span> index</code></em>);</pre>
 <div class="refsect3">
 <a name="hb-face-set-index.parameters"></a><h4>Parameters</h4>
@@ -674,7 +681,7 @@ hb_face_set_index (<em class="parameter"><code><a class="link" href="harfbuzz-hb
 <div class="refsect2">
 <a name="hb-face-set-upem"></a><h3>hb_face_set_upem ()</h3>
 <pre class="programlisting"><span class="returnvalue">void</span>
-hb_face_set_upem (<em class="parameter"><code><a class="link" href="harfbuzz-hb-face.html#hb-face-t" title="hb_face_t"><span class="type">hb_face_t</span></a> *face</code></em>,
+hb_face_set_upem (<em class="parameter"><code><a class="link" href="harfbuzz-hb-face.html#hb-face-t"><span class="type">hb_face_t</span></a> *face</code></em>,
                   <em class="parameter"><code>unsigned <span class="type">int</span> upem</code></em>);</pre>
 <div class="refsect3">
 <a name="hb-face-set-upem.parameters"></a><h4>Parameters</h4>
@@ -697,8 +704,8 @@ hb_face_set_upem (<em class="parameter"><code><a class="link" href="harfbuzz-hb-
 <div class="refsect2">
 <a name="hb-face-set-user-data"></a><h3>hb_face_set_user_data ()</h3>
 <pre class="programlisting"><a class="link" href="harfbuzz-hb-common.html#hb-bool-t" title="hb_bool_t"><span class="returnvalue">hb_bool_t</span></a>
-hb_face_set_user_data (<em class="parameter"><code><a class="link" href="harfbuzz-hb-face.html#hb-face-t" title="hb_face_t"><span class="type">hb_face_t</span></a> *face</code></em>,
-                       <em class="parameter"><code><a class="link" href="harfbuzz-hb-common.html#hb-user-data-key-t" title="hb_user_data_key_t"><span class="type">hb_user_data_key_t</span></a> *key</code></em>,
+hb_face_set_user_data (<em class="parameter"><code><a class="link" href="harfbuzz-hb-face.html#hb-face-t"><span class="type">hb_face_t</span></a> *face</code></em>,
+                       <em class="parameter"><code><a class="link" href="harfbuzz-hb-common.html#hb-user-data-key-t"><span class="type">hb_user_data_key_t</span></a> *key</code></em>,
                        <em class="parameter"><code><span class="type">void</span> *data</code></em>,
                        <em class="parameter"><code><a class="link" href="harfbuzz-hb-common.html#hb-destroy-func-t" title="hb_destroy_func_t ()"><span class="type">hb_destroy_func_t</span></a> destroy</code></em>,
                        <em class="parameter"><code><a class="link" href="harfbuzz-hb-common.html#hb-bool-t" title="hb_bool_t"><span class="type">hb_bool_t</span></a> replace</code></em>);</pre>
@@ -724,8 +731,8 @@ hb_face_set_user_data (<em class="parameter"><code><a class="link" href="harfbuz
 <div class="refsect2">
 <a name="hb-face-collect-unicodes"></a><h3>hb_face_collect_unicodes ()</h3>
 <pre class="programlisting"><span class="returnvalue">void</span>
-hb_face_collect_unicodes (<em class="parameter"><code><a class="link" href="harfbuzz-hb-face.html#hb-face-t" title="hb_face_t"><span class="type">hb_face_t</span></a> *face</code></em>,
-                          <em class="parameter"><code><a class="link" href="harfbuzz-hb-set.html#hb-set-t" title="hb_set_t"><span class="type">hb_set_t</span></a> *out</code></em>);</pre>
+hb_face_collect_unicodes (<em class="parameter"><code><a class="link" href="harfbuzz-hb-face.html#hb-face-t"><span class="type">hb_face_t</span></a> *face</code></em>,
+                          <em class="parameter"><code><a class="link" href="harfbuzz-hb-set.html#hb-set-t"><span class="type">hb_set_t</span></a> *out</code></em>);</pre>
 <div class="refsect3">
 <a name="hb-face-collect-unicodes.parameters"></a><h4>Parameters</h4>
 <div class="informaltable"><table class="informaltable" width="100%" border="0">
@@ -755,8 +762,8 @@ to.</p></td>
 <div class="refsect2">
 <a name="hb-face-collect-variation-selectors"></a><h3>hb_face_collect_variation_selectors ()</h3>
 <pre class="programlisting"><span class="returnvalue">void</span>
-hb_face_collect_variation_selectors (<em class="parameter"><code><a class="link" href="harfbuzz-hb-face.html#hb-face-t" title="hb_face_t"><span class="type">hb_face_t</span></a> *face</code></em>,
-                                     <em class="parameter"><code><a class="link" href="harfbuzz-hb-set.html#hb-set-t" title="hb_set_t"><span class="type">hb_set_t</span></a> *out</code></em>);</pre>
+hb_face_collect_variation_selectors (<em class="parameter"><code><a class="link" href="harfbuzz-hb-face.html#hb-face-t"><span class="type">hb_face_t</span></a> *face</code></em>,
+                                     <em class="parameter"><code><a class="link" href="harfbuzz-hb-set.html#hb-set-t"><span class="type">hb_set_t</span></a> *out</code></em>);</pre>
 <div class="refsect3">
 <a name="hb-face-collect-variation-selectors.parameters"></a><h4>Parameters</h4>
 <div class="informaltable"><table class="informaltable" width="100%" border="0">
@@ -786,9 +793,9 @@ to.</p></td>
 <div class="refsect2">
 <a name="hb-face-collect-variation-unicodes"></a><h3>hb_face_collect_variation_unicodes ()</h3>
 <pre class="programlisting"><span class="returnvalue">void</span>
-hb_face_collect_variation_unicodes (<em class="parameter"><code><a class="link" href="harfbuzz-hb-face.html#hb-face-t" title="hb_face_t"><span class="type">hb_face_t</span></a> *face</code></em>,
+hb_face_collect_variation_unicodes (<em class="parameter"><code><a class="link" href="harfbuzz-hb-face.html#hb-face-t"><span class="type">hb_face_t</span></a> *face</code></em>,
                                     <em class="parameter"><code><a class="link" href="harfbuzz-hb-common.html#hb-codepoint-t" title="hb_codepoint_t"><span class="type">hb_codepoint_t</span></a> variation_selector</code></em>,
-                                    <em class="parameter"><code><a class="link" href="harfbuzz-hb-set.html#hb-set-t" title="hb_set_t"><span class="type">hb_set_t</span></a> *out</code></em>);</pre>
+                                    <em class="parameter"><code><a class="link" href="harfbuzz-hb-set.html#hb-set-t"><span class="type">hb_set_t</span></a> *out</code></em>);</pre>
 <div class="refsect3">
 <a name="hb-face-collect-variation-unicodes.parameters"></a><h4>Parameters</h4>
 <div class="informaltable"><table class="informaltable" width="100%" border="0">
@@ -818,9 +825,9 @@ to.</p></td>
 <hr>
 <div class="refsect2">
 <a name="hb-face-builder-create"></a><h3>hb_face_builder_create ()</h3>
-<pre class="programlisting"><a class="link" href="harfbuzz-hb-face.html#hb-face-t" title="hb_face_t"><span class="returnvalue">hb_face_t</span></a> *
+<pre class="programlisting"><a class="link" href="harfbuzz-hb-face.html#hb-face-t"><span class="returnvalue">hb_face_t</span></a> *
 hb_face_builder_create (<em class="parameter"><code><span class="type">void</span></code></em>);</pre>
-<p>Creates a <a class="link" href="harfbuzz-hb-face.html#hb-face-t" title="hb_face_t"><span class="type">hb_face_t</span></a> that can be used with <a class="link" href="harfbuzz-hb-face.html#hb-face-builder-add-table" title="hb_face_builder_add_table ()"><code class="function">hb_face_builder_add_table()</code></a>.
+<p>Creates a <a class="link" href="harfbuzz-hb-face.html#hb-face-t"><span class="type">hb_face_t</span></a> that can be used with <a class="link" href="harfbuzz-hb-face.html#hb-face-builder-add-table" title="hb_face_builder_add_table ()"><code class="function">hb_face_builder_add_table()</code></a>.
 After tables are added to the face, it can be compiled to a binary
 font file by calling <a class="link" href="harfbuzz-hb-face.html#hb-face-reference-blob" title="hb_face_reference_blob ()"><code class="function">hb_face_reference_blob()</code></a>.</p>
 <div class="refsect3">
@@ -834,9 +841,9 @@ font file by calling <a class="link" href="harfbuzz-hb-face.html#hb-face-referen
 <div class="refsect2">
 <a name="hb-face-builder-add-table"></a><h3>hb_face_builder_add_table ()</h3>
 <pre class="programlisting"><a class="link" href="harfbuzz-hb-common.html#hb-bool-t" title="hb_bool_t"><span class="returnvalue">hb_bool_t</span></a>
-hb_face_builder_add_table (<em class="parameter"><code><a class="link" href="harfbuzz-hb-face.html#hb-face-t" title="hb_face_t"><span class="type">hb_face_t</span></a> *face</code></em>,
+hb_face_builder_add_table (<em class="parameter"><code><a class="link" href="harfbuzz-hb-face.html#hb-face-t"><span class="type">hb_face_t</span></a> *face</code></em>,
                            <em class="parameter"><code><a class="link" href="harfbuzz-hb-common.html#hb-tag-t" title="hb_tag_t"><span class="type">hb_tag_t</span></a> tag</code></em>,
-                           <em class="parameter"><code><a class="link" href="harfbuzz-hb-blob.html#hb-blob-t" title="hb_blob_t"><span class="type">hb_blob_t</span></a> *blob</code></em>);</pre>
+                           <em class="parameter"><code><a class="link" href="harfbuzz-hb-blob.html#hb-blob-t"><span class="type">hb_blob_t</span></a> *blob</code></em>);</pre>
 <p>Add table for <em class="parameter"><code>tag</code></em>
  with data provided by <em class="parameter"><code>blob</code></em>
  to the face.  <em class="parameter"><code>face</code></em>
index 5c9785f..4cc59b3 100644 (file)
@@ -5,7 +5,7 @@
 <title>hb-font: HarfBuzz Manual</title>
 <meta name="generator" content="DocBook XSL Stylesheets Vsnapshot">
 <link rel="home" href="index.html" title="HarfBuzz Manual">
-<link rel="up" href="ch09.html" title="Core API">
+<link rel="up" href="ch11.html" title="Core API">
 <link rel="prev" href="harfbuzz-hb-face.html" title="hb-face">
 <link rel="next" href="harfbuzz-hb-map.html" title="hb-map">
 <meta name="generator" content="GTK-Doc V1.29 (XML mode)">
 <table class="navigation" id="top" width="100%" summary="Navigation header" cellpadding="2" cellspacing="5"><tr valign="middle">
 <td width="100%" align="left" class="shortcuts">
 <a href="#" class="shortcut">Top</a><span id="nav_description">  <span class="dim">|</span> 
-                  <a href="#harfbuzz-hb-font.description" class="shortcut">Description</a></span>
+                  <a href="#harfbuzz-hb-font.description" class="shortcut">Description</a></span><span id="nav_hierarchy">  <span class="dim">|</span> 
+                  <a href="#harfbuzz-hb-font.object-hierarchy" class="shortcut">Object Hierarchy</a></span>
 </td>
 <td><a accesskey="h" href="index.html"><img src="home.png" width="16" height="16" border="0" alt="Home"></a></td>
-<td><a accesskey="u" href="ch09.html"><img src="up.png" width="16" height="16" border="0" alt="Up"></a></td>
+<td><a accesskey="u" href="ch11.html"><img src="up.png" width="16" height="16" border="0" alt="Up"></a></td>
 <td><a accesskey="p" href="harfbuzz-hb-face.html"><img src="left.png" width="16" height="16" border="0" alt="Prev"></a></td>
 <td><a accesskey="n" href="harfbuzz-hb-map.html"><img src="right.png" width="16" height="16" border="0" alt="Next"></a></td>
 </tr></table>
@@ -49,7 +50,7 @@
 </tr>
 <tr>
 <td class="function_type">
-<a class="link" href="harfbuzz-hb-font.html#hb-font-t" title="hb_font_t"><span class="returnvalue">hb_font_t</span></a> *
+<a class="link" href="harfbuzz-hb-font.html#hb-font-t"><span class="returnvalue">hb_font_t</span></a> *
 </td>
 <td class="function_name">
 <a class="link" href="harfbuzz-hb-font.html#hb-font-create" title="hb_font_create ()">hb_font_create</a> <span class="c_punctuation">()</span>
@@ -57,7 +58,7 @@
 </tr>
 <tr>
 <td class="function_type">
-<a class="link" href="harfbuzz-hb-font.html#hb-font-t" title="hb_font_t"><span class="returnvalue">hb_font_t</span></a> *
+<a class="link" href="harfbuzz-hb-font.html#hb-font-t"><span class="returnvalue">hb_font_t</span></a> *
 </td>
 <td class="function_name">
 <a class="link" href="harfbuzz-hb-font.html#hb-font-create-sub-font" title="hb_font_create_sub_font ()">hb_font_create_sub_font</a> <span class="c_punctuation">()</span>
@@ -73,7 +74,7 @@
 </tr>
 <tr>
 <td class="function_type">
-<a class="link" href="harfbuzz-hb-font.html#hb-font-funcs-t" title="hb_font_funcs_t"><span class="returnvalue">hb_font_funcs_t</span></a> *
+<a class="link" href="harfbuzz-hb-font.html#hb-font-funcs-t"><span class="returnvalue">hb_font_funcs_t</span></a> *
 </td>
 <td class="function_name">
 <a class="link" href="harfbuzz-hb-font.html#hb-font-funcs-create" title="hb_font_funcs_create ()">hb_font_funcs_create</a> <span class="c_punctuation">()</span>
@@ -89,7 +90,7 @@
 </tr>
 <tr>
 <td class="function_type">
-<a class="link" href="harfbuzz-hb-font.html#hb-font-funcs-t" title="hb_font_funcs_t"><span class="returnvalue">hb_font_funcs_t</span></a> *
+<a class="link" href="harfbuzz-hb-font.html#hb-font-funcs-t"><span class="returnvalue">hb_font_funcs_t</span></a> *
 </td>
 <td class="function_name">
 <a class="link" href="harfbuzz-hb-font.html#hb-font-funcs-get-empty" title="hb_font_funcs_get_empty ()">hb_font_funcs_get_empty</a> <span class="c_punctuation">()</span>
 </tr>
 <tr>
 <td class="function_type">
-<a class="link" href="harfbuzz-hb-font.html#hb-font-funcs-t" title="hb_font_funcs_t"><span class="returnvalue">hb_font_funcs_t</span></a> *
+<a class="link" href="harfbuzz-hb-font.html#hb-font-funcs-t"><span class="returnvalue">hb_font_funcs_t</span></a> *
 </td>
 <td class="function_name">
 <a class="link" href="harfbuzz-hb-font.html#hb-font-funcs-reference" title="hb_font_funcs_reference ()">hb_font_funcs_reference</a> <span class="c_punctuation">()</span>
 <span class="returnvalue">void</span>
 </td>
 <td class="function_name">
+<a class="link" href="harfbuzz-hb-font.html#hb-font-funcs-set-glyph-h-kerning-func" title="hb_font_funcs_set_glyph_h_kerning_func ()">hb_font_funcs_set_glyph_h_kerning_func</a> <span class="c_punctuation">()</span>
+</td>
+</tr>
+<tr>
+<td class="function_type">
+<span class="returnvalue">void</span>
+</td>
+<td class="function_name">
 <a class="link" href="harfbuzz-hb-font.html#hb-font-funcs-set-glyph-h-origin-func" title="hb_font_funcs_set_glyph_h_origin_func ()">hb_font_funcs_set_glyph_h_origin_func</a> <span class="c_punctuation">()</span>
 </td>
 </tr>
 </tr>
 <tr>
 <td class="function_type">
-<a class="link" href="harfbuzz-hb-font.html#hb-font-t" title="hb_font_t"><span class="returnvalue">hb_font_t</span></a> *
+<a class="link" href="harfbuzz-hb-font.html#hb-font-t"><span class="returnvalue">hb_font_t</span></a> *
 </td>
 <td class="function_name">
 <a class="link" href="harfbuzz-hb-font.html#hb-font-get-empty" title="hb_font_get_empty ()">hb_font_get_empty</a> <span class="c_punctuation">()</span>
 </tr>
 <tr>
 <td class="function_type">
-<a class="link" href="harfbuzz-hb-face.html#hb-face-t" title="hb_face_t"><span class="returnvalue">hb_face_t</span></a> *
+<a class="link" href="harfbuzz-hb-face.html#hb-face-t"><span class="returnvalue">hb_face_t</span></a> *
 </td>
 <td class="function_name">
 <a class="link" href="harfbuzz-hb-font.html#hb-font-get-face" title="hb_font_get_face ()">hb_font_get_face</a> <span class="c_punctuation">()</span>
 </tr>
 <tr>
 <td class="function_type">
+<a class="link" href="harfbuzz-hb-common.html#hb-position-t" title="hb_position_t"><span class="returnvalue">hb_position_t</span></a>
+</td>
+<td class="function_name">
+<a class="link" href="harfbuzz-hb-font.html#hb-font-get-glyph-h-kerning" title="hb_font_get_glyph_h_kerning ()">hb_font_get_glyph_h_kerning</a> <span class="c_punctuation">()</span>
+</td>
+</tr>
+<tr>
+<td class="function_type">
 <a class="link" href="harfbuzz-hb-common.html#hb-bool-t" title="hb_bool_t"><span class="returnvalue">hb_bool_t</span></a>
 </td>
 <td class="function_name">
 </tr>
 <tr>
 <td class="function_type">
+<span class="returnvalue">void</span>
+</td>
+<td class="function_name">
+<a class="link" href="harfbuzz-hb-font.html#hb-font-get-glyph-kerning-for-direction" title="hb_font_get_glyph_kerning_for_direction ()">hb_font_get_glyph_kerning_for_direction</a> <span class="c_punctuation">()</span>
+</td>
+</tr>
+<tr>
+<td class="function_type">
+<a class="link" href="harfbuzz-hb-common.html#hb-position-t" title="hb_position_t"><span class="returnvalue">hb_position_t</span></a>
+</td>
+<td class="function_name">
+<span class="c_punctuation">(</span><a class="link" href="harfbuzz-hb-font.html#hb-font-get-glyph-kerning-func-t" title="hb_font_get_glyph_kerning_func_t ()">*hb_font_get_glyph_kerning_func_t</a><span class="c_punctuation">)</span> <span class="c_punctuation">()</span>
+</td>
+</tr>
+<tr>
+<td class="function_type">
 <a class="link" href="harfbuzz-hb-common.html#hb-bool-t" title="hb_bool_t"><span class="returnvalue">hb_bool_t</span></a>
 </td>
 <td class="function_name">
 </td>
 </tr>
 <tr>
+<td class="function_type">unsigned <span class="returnvalue">int</span>
+</td>
+<td class="function_name">
+<a class="link" href="harfbuzz-hb-font.html#hb-font-get-nominal-glyphs" title="hb_font_get_nominal_glyphs ()">hb_font_get_nominal_glyphs</a> <span class="c_punctuation">()</span>
+</td>
+</tr>
+<tr>
 <td class="function_type">
-<a class="link" href="harfbuzz-hb-font.html#hb-font-t" title="hb_font_t"><span class="returnvalue">hb_font_t</span></a> *
+<a class="link" href="harfbuzz-hb-font.html#hb-font-t"><span class="returnvalue">hb_font_t</span></a> *
 </td>
 <td class="function_name">
 <a class="link" href="harfbuzz-hb-font.html#hb-font-get-parent" title="hb_font_get_parent ()">hb_font_get_parent</a> <span class="c_punctuation">()</span>
 </tr>
 <tr>
 <td class="function_type">
-<a class="link" href="harfbuzz-hb-font.html#hb-font-t" title="hb_font_t"><span class="returnvalue">hb_font_t</span></a> *
+<a class="link" href="harfbuzz-hb-font.html#hb-font-t"><span class="returnvalue">hb_font_t</span></a> *
 </td>
 <td class="function_name">
 <a class="link" href="harfbuzz-hb-font.html#hb-font-reference" title="hb_font_reference ()">hb_font_reference</a> <span class="c_punctuation">()</span>
 <span class="returnvalue">void</span>
 </td>
 <td class="function_name">
+<a class="link" href="harfbuzz-hb-font.html#hb-font-set-var-named-instance" title="hb_font_set_var_named_instance ()">hb_font_set_var_named_instance</a> <span class="c_punctuation">()</span>
+</td>
+</tr>
+<tr>
+<td class="function_type">
+<span class="returnvalue">void</span>
+</td>
+<td class="function_name">
 <a class="link" href="harfbuzz-hb-font.html#hb-font-subtract-glyph-origin-for-direction" title="hb_font_subtract_glyph_origin_for_direction ()">hb_font_subtract_glyph_origin_for_direction</a> <span class="c_punctuation">()</span>
 </td>
 </tr>
 <tr>
 <td class="function_type">
-<a class="link" href="harfbuzz-hb-blob.html#hb-blob-t" title="hb_blob_t"><span class="returnvalue">hb_blob_t</span></a> *
+<a class="link" href="harfbuzz-hb-blob.html#hb-blob-t"><span class="returnvalue">hb_blob_t</span></a> *
 </td>
 <td class="function_name">
 <span class="c_punctuation">(</span><a class="link" href="harfbuzz-hb-font.html#hb-reference-table-func-t" title="hb_reference_table_func_t ()">*hb_reference_table_func_t</a><span class="c_punctuation">)</span> <span class="c_punctuation">()</span>
 </tbody>
 </table></div>
 </div>
-<div class="refsect1">
+<a name="hb-font-funcs-t"></a><a name="hb-font-t"></a><div class="refsect1">
 <a name="harfbuzz-hb-font.other"></a><h2>Types and Values</h2>
 <div class="informaltable"><table class="informaltable" width="100%" border="0">
 <colgroup>
 <tbody>
 <tr>
 <td class="typedef_keyword">typedef</td>
-<td class="function_name"><a class="link" href="harfbuzz-hb-font.html#hb-font-funcs-t" title="hb_font_funcs_t">hb_font_funcs_t</a></td>
+<td class="function_name"><a class="link" href="harfbuzz-hb-font.html#hb-font-funcs-t">hb_font_funcs_t</a></td>
 </tr>
 <tr>
 <td class="typedef_keyword">typedef</td>
 </tr>
 <tr>
 <td class="typedef_keyword">typedef</td>
+<td class="function_name"><a class="link" href="harfbuzz-hb-font.html#hb-font-get-glyph-h-kerning-func-t" title="hb_font_get_glyph_h_kerning_func_t">hb_font_get_glyph_h_kerning_func_t</a></td>
+</tr>
+<tr>
+<td class="typedef_keyword">typedef</td>
 <td class="function_name"><a class="link" href="harfbuzz-hb-font.html#hb-font-get-glyph-h-origin-func-t" title="hb_font_get_glyph_h_origin_func_t">hb_font_get_glyph_h_origin_func_t</a></td>
 </tr>
 <tr>
 </tr>
 <tr>
 <td class="typedef_keyword">typedef</td>
-<td class="function_name"><a class="link" href="harfbuzz-hb-font.html#hb-font-t" title="hb_font_t">hb_font_t</a></td>
+<td class="function_name"><a class="link" href="harfbuzz-hb-font.html#hb-font-t">hb_font_t</a></td>
 </tr>
 <tr>
 <td class="typedef_keyword">typedef</td>
 </table></div>
 </div>
 <div class="refsect1">
+<a name="harfbuzz-hb-font.object-hierarchy"></a><h2>Object Hierarchy</h2>
+<pre class="screen">    <a href="/usr/share/gtk-doc/html/gobject/gobject-Boxed-Types.html">GBoxed</a>
+    <span class="lineart">├──</span> hb_font_funcs_t
+    <span class="lineart">╰──</span> hb_font_t
+</pre>
+</div>
+<div class="refsect1">
 <a name="harfbuzz-hb-font.includes"></a><h2>Includes</h2>
 <pre class="synopsis">#include &lt;hb.h&gt;
 </pre>
@@ -782,7 +841,7 @@ Fonts are created from font faces, and are used as input to
 <a name="hb-font-add-glyph-origin-for-direction"></a><h3>hb_font_add_glyph_origin_for_direction ()</h3>
 <pre class="programlisting"><span class="returnvalue">void</span>
 hb_font_add_glyph_origin_for_direction
-                               (<em class="parameter"><code><a class="link" href="harfbuzz-hb-font.html#hb-font-t" title="hb_font_t"><span class="type">hb_font_t</span></a> *font</code></em>,
+                               (<em class="parameter"><code><a class="link" href="harfbuzz-hb-font.html#hb-font-t"><span class="type">hb_font_t</span></a> *font</code></em>,
                                 <em class="parameter"><code><a class="link" href="harfbuzz-hb-common.html#hb-codepoint-t" title="hb_codepoint_t"><span class="type">hb_codepoint_t</span></a> glyph</code></em>,
                                 <em class="parameter"><code><a class="link" href="harfbuzz-hb-common.html#hb-direction-t" title="enum hb_direction_t"><span class="type">hb_direction_t</span></a> direction</code></em>,
                                 <em class="parameter"><code><a class="link" href="harfbuzz-hb-common.html#hb-position-t" title="hb_position_t"><span class="type">hb_position_t</span></a> *x</code></em>,
@@ -819,8 +878,8 @@ hb_font_add_glyph_origin_for_direction
 <hr>
 <div class="refsect2">
 <a name="hb-font-create"></a><h3>hb_font_create ()</h3>
-<pre class="programlisting"><a class="link" href="harfbuzz-hb-font.html#hb-font-t" title="hb_font_t"><span class="returnvalue">hb_font_t</span></a> *
-hb_font_create (<em class="parameter"><code><a class="link" href="harfbuzz-hb-face.html#hb-face-t" title="hb_face_t"><span class="type">hb_face_t</span></a> *face</code></em>);</pre>
+<pre class="programlisting"><a class="link" href="harfbuzz-hb-font.html#hb-font-t"><span class="returnvalue">hb_font_t</span></a> *
+hb_font_create (<em class="parameter"><code><a class="link" href="harfbuzz-hb-face.html#hb-face-t"><span class="type">hb_face_t</span></a> *face</code></em>);</pre>
 <p><span class="annotation">[Xconstructor]</span></p>
 <div class="refsect3">
 <a name="hb-font-create.parameters"></a><h4>Parameters</h4>
@@ -847,8 +906,8 @@ hb_font_create (<em class="parameter"><code><a class="link" href="harfbuzz-hb-fa
 <hr>
 <div class="refsect2">
 <a name="hb-font-create-sub-font"></a><h3>hb_font_create_sub_font ()</h3>
-<pre class="programlisting"><a class="link" href="harfbuzz-hb-font.html#hb-font-t" title="hb_font_t"><span class="returnvalue">hb_font_t</span></a> *
-hb_font_create_sub_font (<em class="parameter"><code><a class="link" href="harfbuzz-hb-font.html#hb-font-t" title="hb_font_t"><span class="type">hb_font_t</span></a> *parent</code></em>);</pre>
+<pre class="programlisting"><a class="link" href="harfbuzz-hb-font.html#hb-font-t"><span class="returnvalue">hb_font_t</span></a> *
+hb_font_create_sub_font (<em class="parameter"><code><a class="link" href="harfbuzz-hb-font.html#hb-font-t"><span class="type">hb_font_t</span></a> *parent</code></em>);</pre>
 <div class="refsect3">
 <a name="hb-font-create-sub-font.parameters"></a><h4>Parameters</h4>
 <div class="informaltable"><table class="informaltable" width="100%" border="0">
@@ -875,7 +934,7 @@ hb_font_create_sub_font (<em class="parameter"><code><a class="link" href="harfb
 <div class="refsect2">
 <a name="hb-font-destroy"></a><h3>hb_font_destroy ()</h3>
 <pre class="programlisting"><span class="returnvalue">void</span>
-hb_font_destroy (<em class="parameter"><code><a class="link" href="harfbuzz-hb-font.html#hb-font-t" title="hb_font_t"><span class="type">hb_font_t</span></a> *font</code></em>);</pre>
+hb_font_destroy (<em class="parameter"><code><a class="link" href="harfbuzz-hb-font.html#hb-font-t"><span class="type">hb_font_t</span></a> *font</code></em>);</pre>
 <p><span class="annotation">[<acronym title="Exposed in C code, not necessarily available in other languages."><span class="acronym">skip</span></acronym>]</span></p>
 <div class="refsect3">
 <a name="hb-font-destroy.parameters"></a><h4>Parameters</h4>
@@ -897,7 +956,7 @@ hb_font_destroy (<em class="parameter"><code><a class="link" href="harfbuzz-hb-f
 <hr>
 <div class="refsect2">
 <a name="hb-font-funcs-create"></a><h3>hb_font_funcs_create ()</h3>
-<pre class="programlisting"><a class="link" href="harfbuzz-hb-font.html#hb-font-funcs-t" title="hb_font_funcs_t"><span class="returnvalue">hb_font_funcs_t</span></a> *
+<pre class="programlisting"><a class="link" href="harfbuzz-hb-font.html#hb-font-funcs-t"><span class="returnvalue">hb_font_funcs_t</span></a> *
 hb_font_funcs_create (<em class="parameter"><code><span class="type">void</span></code></em>);</pre>
 <p><span class="annotation">[Xconstructor]</span></p>
 <div class="refsect3">
@@ -911,7 +970,7 @@ hb_font_funcs_create (<em class="parameter"><code><span class="type">void</span>
 <div class="refsect2">
 <a name="hb-font-funcs-destroy"></a><h3>hb_font_funcs_destroy ()</h3>
 <pre class="programlisting"><span class="returnvalue">void</span>
-hb_font_funcs_destroy (<em class="parameter"><code><a class="link" href="harfbuzz-hb-font.html#hb-font-funcs-t" title="hb_font_funcs_t"><span class="type">hb_font_funcs_t</span></a> *ffuncs</code></em>);</pre>
+hb_font_funcs_destroy (<em class="parameter"><code><a class="link" href="harfbuzz-hb-font.html#hb-font-funcs-t"><span class="type">hb_font_funcs_t</span></a> *ffuncs</code></em>);</pre>
 <p><span class="annotation">[<acronym title="Exposed in C code, not necessarily available in other languages."><span class="acronym">skip</span></acronym>]</span></p>
 <div class="refsect3">
 <a name="hb-font-funcs-destroy.parameters"></a><h4>Parameters</h4>
@@ -933,7 +992,7 @@ hb_font_funcs_destroy (<em class="parameter"><code><a class="link" href="harfbuz
 <hr>
 <div class="refsect2">
 <a name="hb-font-funcs-get-empty"></a><h3>hb_font_funcs_get_empty ()</h3>
-<pre class="programlisting"><a class="link" href="harfbuzz-hb-font.html#hb-font-funcs-t" title="hb_font_funcs_t"><span class="returnvalue">hb_font_funcs_t</span></a> *
+<pre class="programlisting"><a class="link" href="harfbuzz-hb-font.html#hb-font-funcs-t"><span class="returnvalue">hb_font_funcs_t</span></a> *
 hb_font_funcs_get_empty (<em class="parameter"><code><span class="type">void</span></code></em>);</pre>
 <div class="refsect3">
 <a name="hb-font-funcs-get-empty.returns"></a><h4>Returns</h4>
@@ -946,8 +1005,8 @@ hb_font_funcs_get_empty (<em class="parameter"><code><span class="type">void</sp
 <div class="refsect2">
 <a name="hb-font-funcs-get-user-data"></a><h3>hb_font_funcs_get_user_data ()</h3>
 <pre class="programlisting"><span class="returnvalue">void</span> *
-hb_font_funcs_get_user_data (<em class="parameter"><code><a class="link" href="harfbuzz-hb-font.html#hb-font-funcs-t" title="hb_font_funcs_t"><span class="type">hb_font_funcs_t</span></a> *ffuncs</code></em>,
-                             <em class="parameter"><code><a class="link" href="harfbuzz-hb-common.html#hb-user-data-key-t" title="hb_user_data_key_t"><span class="type">hb_user_data_key_t</span></a> *key</code></em>);</pre>
+hb_font_funcs_get_user_data (<em class="parameter"><code><a class="link" href="harfbuzz-hb-font.html#hb-font-funcs-t"><span class="type">hb_font_funcs_t</span></a> *ffuncs</code></em>,
+                             <em class="parameter"><code><a class="link" href="harfbuzz-hb-common.html#hb-user-data-key-t"><span class="type">hb_user_data_key_t</span></a> *key</code></em>);</pre>
 <p><span class="annotation">[<acronym title="Exposed in C code, not necessarily available in other languages."><span class="acronym">skip</span></acronym>]</span></p>
 <div class="refsect3">
 <a name="hb-font-funcs-get-user-data.parameters"></a><h4>Parameters</h4>
@@ -975,7 +1034,7 @@ hb_font_funcs_get_user_data (<em class="parameter"><code><a class="link" href="h
 <div class="refsect2">
 <a name="hb-font-funcs-is-immutable"></a><h3>hb_font_funcs_is_immutable ()</h3>
 <pre class="programlisting"><a class="link" href="harfbuzz-hb-common.html#hb-bool-t" title="hb_bool_t"><span class="returnvalue">hb_bool_t</span></a>
-hb_font_funcs_is_immutable (<em class="parameter"><code><a class="link" href="harfbuzz-hb-font.html#hb-font-funcs-t" title="hb_font_funcs_t"><span class="type">hb_font_funcs_t</span></a> *ffuncs</code></em>);</pre>
+hb_font_funcs_is_immutable (<em class="parameter"><code><a class="link" href="harfbuzz-hb-font.html#hb-font-funcs-t"><span class="type">hb_font_funcs_t</span></a> *ffuncs</code></em>);</pre>
 <div class="refsect3">
 <a name="hb-font-funcs-is-immutable.parameters"></a><h4>Parameters</h4>
 <div class="informaltable"><table class="informaltable" width="100%" border="0">
@@ -997,7 +1056,7 @@ hb_font_funcs_is_immutable (<em class="parameter"><code><a class="link" href="ha
 <div class="refsect2">
 <a name="hb-font-funcs-make-immutable"></a><h3>hb_font_funcs_make_immutable ()</h3>
 <pre class="programlisting"><span class="returnvalue">void</span>
-hb_font_funcs_make_immutable (<em class="parameter"><code><a class="link" href="harfbuzz-hb-font.html#hb-font-funcs-t" title="hb_font_funcs_t"><span class="type">hb_font_funcs_t</span></a> *ffuncs</code></em>);</pre>
+hb_font_funcs_make_immutable (<em class="parameter"><code><a class="link" href="harfbuzz-hb-font.html#hb-font-funcs-t"><span class="type">hb_font_funcs_t</span></a> *ffuncs</code></em>);</pre>
 <div class="refsect3">
 <a name="hb-font-funcs-make-immutable.parameters"></a><h4>Parameters</h4>
 <div class="informaltable"><table class="informaltable" width="100%" border="0">
@@ -1018,8 +1077,8 @@ hb_font_funcs_make_immutable (<em class="parameter"><code><a class="link" href="
 <hr>
 <div class="refsect2">
 <a name="hb-font-funcs-reference"></a><h3>hb_font_funcs_reference ()</h3>
-<pre class="programlisting"><a class="link" href="harfbuzz-hb-font.html#hb-font-funcs-t" title="hb_font_funcs_t"><span class="returnvalue">hb_font_funcs_t</span></a> *
-hb_font_funcs_reference (<em class="parameter"><code><a class="link" href="harfbuzz-hb-font.html#hb-font-funcs-t" title="hb_font_funcs_t"><span class="type">hb_font_funcs_t</span></a> *ffuncs</code></em>);</pre>
+<pre class="programlisting"><a class="link" href="harfbuzz-hb-font.html#hb-font-funcs-t"><span class="returnvalue">hb_font_funcs_t</span></a> *
+hb_font_funcs_reference (<em class="parameter"><code><a class="link" href="harfbuzz-hb-font.html#hb-font-funcs-t"><span class="type">hb_font_funcs_t</span></a> *ffuncs</code></em>);</pre>
 <p><span class="annotation">[<acronym title="Exposed in C code, not necessarily available in other languages."><span class="acronym">skip</span></acronym>]</span></p>
 <div class="refsect3">
 <a name="hb-font-funcs-reference.parameters"></a><h4>Parameters</h4>
@@ -1043,7 +1102,7 @@ hb_font_funcs_reference (<em class="parameter"><code><a class="link" href="harfb
 <a name="hb-font-funcs-set-glyph-contour-point-func"></a><h3>hb_font_funcs_set_glyph_contour_point_func ()</h3>
 <pre class="programlisting"><span class="returnvalue">void</span>
 hb_font_funcs_set_glyph_contour_point_func
-                               (<em class="parameter"><code><a class="link" href="harfbuzz-hb-font.html#hb-font-funcs-t" title="hb_font_funcs_t"><span class="type">hb_font_funcs_t</span></a> *ffuncs</code></em>,
+                               (<em class="parameter"><code><a class="link" href="harfbuzz-hb-font.html#hb-font-funcs-t"><span class="type">hb_font_funcs_t</span></a> *ffuncs</code></em>,
                                 <em class="parameter"><code><a class="link" href="harfbuzz-hb-font.html#hb-font-get-glyph-contour-point-func-t" title="hb_font_get_glyph_contour_point_func_t ()"><span class="type">hb_font_get_glyph_contour_point_func_t</span></a> func</code></em>,
                                 <em class="parameter"><code><span class="type">void</span> *user_data</code></em>,
                                 <em class="parameter"><code><a class="link" href="harfbuzz-hb-common.html#hb-destroy-func-t" title="hb_destroy_func_t ()"><span class="type">hb_destroy_func_t</span></a> destroy</code></em>);</pre>
@@ -1075,7 +1134,7 @@ hb_font_funcs_set_glyph_contour_point_func
 <div class="refsect2">
 <a name="hb-font-funcs-set-glyph-extents-func"></a><h3>hb_font_funcs_set_glyph_extents_func ()</h3>
 <pre class="programlisting"><span class="returnvalue">void</span>
-hb_font_funcs_set_glyph_extents_func (<em class="parameter"><code><a class="link" href="harfbuzz-hb-font.html#hb-font-funcs-t" title="hb_font_funcs_t"><span class="type">hb_font_funcs_t</span></a> *ffuncs</code></em>,
+hb_font_funcs_set_glyph_extents_func (<em class="parameter"><code><a class="link" href="harfbuzz-hb-font.html#hb-font-funcs-t"><span class="type">hb_font_funcs_t</span></a> *ffuncs</code></em>,
                                       <em class="parameter"><code><a class="link" href="harfbuzz-hb-font.html#hb-font-get-glyph-extents-func-t" title="hb_font_get_glyph_extents_func_t ()"><span class="type">hb_font_get_glyph_extents_func_t</span></a> func</code></em>,
                                       <em class="parameter"><code><span class="type">void</span> *user_data</code></em>,
                                       <em class="parameter"><code><a class="link" href="harfbuzz-hb-common.html#hb-destroy-func-t" title="hb_destroy_func_t ()"><span class="type">hb_destroy_func_t</span></a> destroy</code></em>);</pre>
@@ -1108,7 +1167,7 @@ hb_font_funcs_set_glyph_extents_func (<em class="parameter"><code><a class="link
 <a name="hb-font-funcs-set-glyph-from-name-func"></a><h3>hb_font_funcs_set_glyph_from_name_func ()</h3>
 <pre class="programlisting"><span class="returnvalue">void</span>
 hb_font_funcs_set_glyph_from_name_func
-                               (<em class="parameter"><code><a class="link" href="harfbuzz-hb-font.html#hb-font-funcs-t" title="hb_font_funcs_t"><span class="type">hb_font_funcs_t</span></a> *ffuncs</code></em>,
+                               (<em class="parameter"><code><a class="link" href="harfbuzz-hb-font.html#hb-font-funcs-t"><span class="type">hb_font_funcs_t</span></a> *ffuncs</code></em>,
                                 <em class="parameter"><code><a class="link" href="harfbuzz-hb-font.html#hb-font-get-glyph-from-name-func-t" title="hb_font_get_glyph_from_name_func_t ()"><span class="type">hb_font_get_glyph_from_name_func_t</span></a> func</code></em>,
                                 <em class="parameter"><code><span class="type">void</span> *user_data</code></em>,
                                 <em class="parameter"><code><a class="link" href="harfbuzz-hb-common.html#hb-destroy-func-t" title="hb_destroy_func_t ()"><span class="type">hb_destroy_func_t</span></a> destroy</code></em>);</pre>
@@ -1141,7 +1200,7 @@ hb_font_funcs_set_glyph_from_name_func
 <a name="hb-font-funcs-set-glyph-h-advance-func"></a><h3>hb_font_funcs_set_glyph_h_advance_func ()</h3>
 <pre class="programlisting"><span class="returnvalue">void</span>
 hb_font_funcs_set_glyph_h_advance_func
-                               (<em class="parameter"><code><a class="link" href="harfbuzz-hb-font.html#hb-font-funcs-t" title="hb_font_funcs_t"><span class="type">hb_font_funcs_t</span></a> *ffuncs</code></em>,
+                               (<em class="parameter"><code><a class="link" href="harfbuzz-hb-font.html#hb-font-funcs-t"><span class="type">hb_font_funcs_t</span></a> *ffuncs</code></em>,
                                 <em class="parameter"><code><a class="link" href="harfbuzz-hb-font.html#hb-font-get-glyph-h-advance-func-t" title="hb_font_get_glyph_h_advance_func_t"><span class="type">hb_font_get_glyph_h_advance_func_t</span></a> func</code></em>,
                                 <em class="parameter"><code><span class="type">void</span> *user_data</code></em>,
                                 <em class="parameter"><code><a class="link" href="harfbuzz-hb-common.html#hb-destroy-func-t" title="hb_destroy_func_t ()"><span class="type">hb_destroy_func_t</span></a> destroy</code></em>);</pre>
@@ -1174,7 +1233,7 @@ hb_font_funcs_set_glyph_h_advance_func
 <a name="hb-font-funcs-set-glyph-h-advances-func"></a><h3>hb_font_funcs_set_glyph_h_advances_func ()</h3>
 <pre class="programlisting"><span class="returnvalue">void</span>
 hb_font_funcs_set_glyph_h_advances_func
-                               (<em class="parameter"><code><a class="link" href="harfbuzz-hb-font.html#hb-font-funcs-t" title="hb_font_funcs_t"><span class="type">hb_font_funcs_t</span></a> *ffuncs</code></em>,
+                               (<em class="parameter"><code><a class="link" href="harfbuzz-hb-font.html#hb-font-funcs-t"><span class="type">hb_font_funcs_t</span></a> *ffuncs</code></em>,
                                 <em class="parameter"><code><a class="link" href="harfbuzz-hb-font.html#hb-font-get-glyph-h-advances-func-t" title="hb_font_get_glyph_h_advances_func_t"><span class="type">hb_font_get_glyph_h_advances_func_t</span></a> func</code></em>,
                                 <em class="parameter"><code><span class="type">void</span> *user_data</code></em>,
                                 <em class="parameter"><code><a class="link" href="harfbuzz-hb-common.html#hb-destroy-func-t" title="hb_destroy_func_t ()"><span class="type">hb_destroy_func_t</span></a> destroy</code></em>);</pre>
@@ -1204,9 +1263,42 @@ hb_font_funcs_set_glyph_h_advances_func
 </div>
 <hr>
 <div class="refsect2">
+<a name="hb-font-funcs-set-glyph-h-kerning-func"></a><h3>hb_font_funcs_set_glyph_h_kerning_func ()</h3>
+<pre class="programlisting"><span class="returnvalue">void</span>
+hb_font_funcs_set_glyph_h_kerning_func
+                               (<em class="parameter"><code><a class="link" href="harfbuzz-hb-font.html#hb-font-funcs-t"><span class="type">hb_font_funcs_t</span></a> *ffuncs</code></em>,
+                                <em class="parameter"><code><a class="link" href="harfbuzz-hb-font.html#hb-font-get-glyph-h-kerning-func-t" title="hb_font_get_glyph_h_kerning_func_t"><span class="type">hb_font_get_glyph_h_kerning_func_t</span></a> func</code></em>,
+                                <em class="parameter"><code><span class="type">void</span> *user_data</code></em>,
+                                <em class="parameter"><code><a class="link" href="harfbuzz-hb-common.html#hb-destroy-func-t" title="hb_destroy_func_t ()"><span class="type">hb_destroy_func_t</span></a> destroy</code></em>);</pre>
+<div class="refsect3">
+<a name="hb-font-funcs-set-glyph-h-kerning-func.parameters"></a><h4>Parameters</h4>
+<div class="informaltable"><table class="informaltable" width="100%" border="0">
+<colgroup>
+<col width="150px" class="parameters_name">
+<col class="parameters_description">
+<col width="200px" class="parameters_annotations">
+</colgroup>
+<tbody>
+<tr>
+<td class="parameter_name"><p>ffuncs</p></td>
+<td class="parameter_description"><p>font functions.</p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+<tr>
+<td class="parameter_name"><p>func</p></td>
+<td class="parameter_description"><p>. </p></td>
+<td class="parameter_annotations"><span class="annotation">[<acronym title="This parameter is a 'user_data', for callbacks; many bindings can pass NULL here."><span class="acronym">closure</span></acronym> user_data][<acronym title="This parameter is a 'destroy_data', for callbacks."><span class="acronym">destroy</span></acronym> destroy][<acronym title="The callback is valid until the GDestroyNotify argument is called."><span class="acronym">scope notified</span></acronym>]</span></td>
+</tr>
+</tbody>
+</table></div>
+</div>
+<p class="since">Since: <a class="link" href="api-index-0-9-2.html#api-index-0.9.2">0.9.2</a></p>
+</div>
+<hr>
+<div class="refsect2">
 <a name="hb-font-funcs-set-glyph-h-origin-func"></a><h3>hb_font_funcs_set_glyph_h_origin_func ()</h3>
 <pre class="programlisting"><span class="returnvalue">void</span>
-hb_font_funcs_set_glyph_h_origin_func (<em class="parameter"><code><a class="link" href="harfbuzz-hb-font.html#hb-font-funcs-t" title="hb_font_funcs_t"><span class="type">hb_font_funcs_t</span></a> *ffuncs</code></em>,
+hb_font_funcs_set_glyph_h_origin_func (<em class="parameter"><code><a class="link" href="harfbuzz-hb-font.html#hb-font-funcs-t"><span class="type">hb_font_funcs_t</span></a> *ffuncs</code></em>,
                                        <em class="parameter"><code><a class="link" href="harfbuzz-hb-font.html#hb-font-get-glyph-h-origin-func-t" title="hb_font_get_glyph_h_origin_func_t"><span class="type">hb_font_get_glyph_h_origin_func_t</span></a> func</code></em>,
                                        <em class="parameter"><code><span class="type">void</span> *user_data</code></em>,
                                        <em class="parameter"><code><a class="link" href="harfbuzz-hb-common.html#hb-destroy-func-t" title="hb_destroy_func_t ()"><span class="type">hb_destroy_func_t</span></a> destroy</code></em>);</pre>
@@ -1238,7 +1330,7 @@ hb_font_funcs_set_glyph_h_origin_func (<em class="parameter"><code><a class="lin
 <div class="refsect2">
 <a name="hb-font-funcs-set-glyph-name-func"></a><h3>hb_font_funcs_set_glyph_name_func ()</h3>
 <pre class="programlisting"><span class="returnvalue">void</span>
-hb_font_funcs_set_glyph_name_func (<em class="parameter"><code><a class="link" href="harfbuzz-hb-font.html#hb-font-funcs-t" title="hb_font_funcs_t"><span class="type">hb_font_funcs_t</span></a> *ffuncs</code></em>,
+hb_font_funcs_set_glyph_name_func (<em class="parameter"><code><a class="link" href="harfbuzz-hb-font.html#hb-font-funcs-t"><span class="type">hb_font_funcs_t</span></a> *ffuncs</code></em>,
                                    <em class="parameter"><code><a class="link" href="harfbuzz-hb-font.html#hb-font-get-glyph-name-func-t" title="hb_font_get_glyph_name_func_t ()"><span class="type">hb_font_get_glyph_name_func_t</span></a> func</code></em>,
                                    <em class="parameter"><code><span class="type">void</span> *user_data</code></em>,
                                    <em class="parameter"><code><a class="link" href="harfbuzz-hb-common.html#hb-destroy-func-t" title="hb_destroy_func_t ()"><span class="type">hb_destroy_func_t</span></a> destroy</code></em>);</pre>
@@ -1271,7 +1363,7 @@ hb_font_funcs_set_glyph_name_func (<em class="parameter"><code><a class="link" h
 <a name="hb-font-funcs-set-glyph-v-advance-func"></a><h3>hb_font_funcs_set_glyph_v_advance_func ()</h3>
 <pre class="programlisting"><span class="returnvalue">void</span>
 hb_font_funcs_set_glyph_v_advance_func
-                               (<em class="parameter"><code><a class="link" href="harfbuzz-hb-font.html#hb-font-funcs-t" title="hb_font_funcs_t"><span class="type">hb_font_funcs_t</span></a> *ffuncs</code></em>,
+                               (<em class="parameter"><code><a class="link" href="harfbuzz-hb-font.html#hb-font-funcs-t"><span class="type">hb_font_funcs_t</span></a> *ffuncs</code></em>,
                                 <em class="parameter"><code><a class="link" href="harfbuzz-hb-font.html#hb-font-get-glyph-v-advance-func-t" title="hb_font_get_glyph_v_advance_func_t"><span class="type">hb_font_get_glyph_v_advance_func_t</span></a> func</code></em>,
                                 <em class="parameter"><code><span class="type">void</span> *user_data</code></em>,
                                 <em class="parameter"><code><a class="link" href="harfbuzz-hb-common.html#hb-destroy-func-t" title="hb_destroy_func_t ()"><span class="type">hb_destroy_func_t</span></a> destroy</code></em>);</pre>
@@ -1304,7 +1396,7 @@ hb_font_funcs_set_glyph_v_advance_func
 <a name="hb-font-funcs-set-glyph-v-advances-func"></a><h3>hb_font_funcs_set_glyph_v_advances_func ()</h3>
 <pre class="programlisting"><span class="returnvalue">void</span>
 hb_font_funcs_set_glyph_v_advances_func
-                               (<em class="parameter"><code><a class="link" href="harfbuzz-hb-font.html#hb-font-funcs-t" title="hb_font_funcs_t"><span class="type">hb_font_funcs_t</span></a> *ffuncs</code></em>,
+                               (<em class="parameter"><code><a class="link" href="harfbuzz-hb-font.html#hb-font-funcs-t"><span class="type">hb_font_funcs_t</span></a> *ffuncs</code></em>,
                                 <em class="parameter"><code><a class="link" href="harfbuzz-hb-font.html#hb-font-get-glyph-v-advances-func-t" title="hb_font_get_glyph_v_advances_func_t"><span class="type">hb_font_get_glyph_v_advances_func_t</span></a> func</code></em>,
                                 <em class="parameter"><code><span class="type">void</span> *user_data</code></em>,
                                 <em class="parameter"><code><a class="link" href="harfbuzz-hb-common.html#hb-destroy-func-t" title="hb_destroy_func_t ()"><span class="type">hb_destroy_func_t</span></a> destroy</code></em>);</pre>
@@ -1336,7 +1428,7 @@ hb_font_funcs_set_glyph_v_advances_func
 <div class="refsect2">
 <a name="hb-font-funcs-set-glyph-v-origin-func"></a><h3>hb_font_funcs_set_glyph_v_origin_func ()</h3>
 <pre class="programlisting"><span class="returnvalue">void</span>
-hb_font_funcs_set_glyph_v_origin_func (<em class="parameter"><code><a class="link" href="harfbuzz-hb-font.html#hb-font-funcs-t" title="hb_font_funcs_t"><span class="type">hb_font_funcs_t</span></a> *ffuncs</code></em>,
+hb_font_funcs_set_glyph_v_origin_func (<em class="parameter"><code><a class="link" href="harfbuzz-hb-font.html#hb-font-funcs-t"><span class="type">hb_font_funcs_t</span></a> *ffuncs</code></em>,
                                        <em class="parameter"><code><a class="link" href="harfbuzz-hb-font.html#hb-font-get-glyph-v-origin-func-t" title="hb_font_get_glyph_v_origin_func_t"><span class="type">hb_font_get_glyph_v_origin_func_t</span></a> func</code></em>,
                                        <em class="parameter"><code><span class="type">void</span> *user_data</code></em>,
                                        <em class="parameter"><code><a class="link" href="harfbuzz-hb-common.html#hb-destroy-func-t" title="hb_destroy_func_t ()"><span class="type">hb_destroy_func_t</span></a> destroy</code></em>);</pre>
@@ -1368,7 +1460,7 @@ hb_font_funcs_set_glyph_v_origin_func (<em class="parameter"><code><a class="lin
 <div class="refsect2">
 <a name="hb-font-funcs-set-nominal-glyph-func"></a><h3>hb_font_funcs_set_nominal_glyph_func ()</h3>
 <pre class="programlisting"><span class="returnvalue">void</span>
-hb_font_funcs_set_nominal_glyph_func (<em class="parameter"><code><a class="link" href="harfbuzz-hb-font.html#hb-font-funcs-t" title="hb_font_funcs_t"><span class="type">hb_font_funcs_t</span></a> *ffuncs</code></em>,
+hb_font_funcs_set_nominal_glyph_func (<em class="parameter"><code><a class="link" href="harfbuzz-hb-font.html#hb-font-funcs-t"><span class="type">hb_font_funcs_t</span></a> *ffuncs</code></em>,
                                       <em class="parameter"><code><a class="link" href="harfbuzz-hb-font.html#hb-font-get-nominal-glyph-func-t" title="hb_font_get_nominal_glyph_func_t ()"><span class="type">hb_font_get_nominal_glyph_func_t</span></a> func</code></em>,
                                       <em class="parameter"><code><span class="type">void</span> *user_data</code></em>,
                                       <em class="parameter"><code><a class="link" href="harfbuzz-hb-common.html#hb-destroy-func-t" title="hb_destroy_func_t ()"><span class="type">hb_destroy_func_t</span></a> destroy</code></em>);</pre>
@@ -1400,7 +1492,7 @@ hb_font_funcs_set_nominal_glyph_func (<em class="parameter"><code><a class="link
 <div class="refsect2">
 <a name="hb-font-funcs-set-nominal-glyphs-func"></a><h3>hb_font_funcs_set_nominal_glyphs_func ()</h3>
 <pre class="programlisting"><span class="returnvalue">void</span>
-hb_font_funcs_set_nominal_glyphs_func (<em class="parameter"><code><a class="link" href="harfbuzz-hb-font.html#hb-font-funcs-t" title="hb_font_funcs_t"><span class="type">hb_font_funcs_t</span></a> *ffuncs</code></em>,
+hb_font_funcs_set_nominal_glyphs_func (<em class="parameter"><code><a class="link" href="harfbuzz-hb-font.html#hb-font-funcs-t"><span class="type">hb_font_funcs_t</span></a> *ffuncs</code></em>,
                                        <em class="parameter"><code><span class="type">hb_font_get_nominal_glyphs_func_t</span> func</code></em>,
                                        <em class="parameter"><code><span class="type">void</span> *user_data</code></em>,
                                        <em class="parameter"><code><a class="link" href="harfbuzz-hb-common.html#hb-destroy-func-t" title="hb_destroy_func_t ()"><span class="type">hb_destroy_func_t</span></a> destroy</code></em>);</pre>
@@ -1432,8 +1524,8 @@ hb_font_funcs_set_nominal_glyphs_func (<em class="parameter"><code><a class="lin
 <div class="refsect2">
 <a name="hb-font-funcs-set-user-data"></a><h3>hb_font_funcs_set_user_data ()</h3>
 <pre class="programlisting"><a class="link" href="harfbuzz-hb-common.html#hb-bool-t" title="hb_bool_t"><span class="returnvalue">hb_bool_t</span></a>
-hb_font_funcs_set_user_data (<em class="parameter"><code><a class="link" href="harfbuzz-hb-font.html#hb-font-funcs-t" title="hb_font_funcs_t"><span class="type">hb_font_funcs_t</span></a> *ffuncs</code></em>,
-                             <em class="parameter"><code><a class="link" href="harfbuzz-hb-common.html#hb-user-data-key-t" title="hb_user_data_key_t"><span class="type">hb_user_data_key_t</span></a> *key</code></em>,
+hb_font_funcs_set_user_data (<em class="parameter"><code><a class="link" href="harfbuzz-hb-font.html#hb-font-funcs-t"><span class="type">hb_font_funcs_t</span></a> *ffuncs</code></em>,
+                             <em class="parameter"><code><a class="link" href="harfbuzz-hb-common.html#hb-user-data-key-t"><span class="type">hb_user_data_key_t</span></a> *key</code></em>,
                              <em class="parameter"><code><span class="type">void</span> *data</code></em>,
                              <em class="parameter"><code><a class="link" href="harfbuzz-hb-common.html#hb-destroy-func-t" title="hb_destroy_func_t ()"><span class="type">hb_destroy_func_t</span></a> destroy</code></em>,
                              <em class="parameter"><code><a class="link" href="harfbuzz-hb-common.html#hb-bool-t" title="hb_bool_t"><span class="type">hb_bool_t</span></a> replace</code></em>);</pre>
@@ -1460,7 +1552,7 @@ hb_font_funcs_set_user_data (<em class="parameter"><code><a class="link" href="h
 <a name="hb-font-funcs-set-variation-glyph-func"></a><h3>hb_font_funcs_set_variation_glyph_func ()</h3>
 <pre class="programlisting"><span class="returnvalue">void</span>
 hb_font_funcs_set_variation_glyph_func
-                               (<em class="parameter"><code><a class="link" href="harfbuzz-hb-font.html#hb-font-funcs-t" title="hb_font_funcs_t"><span class="type">hb_font_funcs_t</span></a> *ffuncs</code></em>,
+                               (<em class="parameter"><code><a class="link" href="harfbuzz-hb-font.html#hb-font-funcs-t"><span class="type">hb_font_funcs_t</span></a> *ffuncs</code></em>,
                                 <em class="parameter"><code><a class="link" href="harfbuzz-hb-font.html#hb-font-get-variation-glyph-func-t" title="hb_font_get_variation_glyph_func_t ()"><span class="type">hb_font_get_variation_glyph_func_t</span></a> func</code></em>,
                                 <em class="parameter"><code><span class="type">void</span> *user_data</code></em>,
                                 <em class="parameter"><code><a class="link" href="harfbuzz-hb-common.html#hb-destroy-func-t" title="hb_destroy_func_t ()"><span class="type">hb_destroy_func_t</span></a> destroy</code></em>);</pre>
@@ -1491,7 +1583,7 @@ hb_font_funcs_set_variation_glyph_func
 <hr>
 <div class="refsect2">
 <a name="hb-font-get-empty"></a><h3>hb_font_get_empty ()</h3>
-<pre class="programlisting"><a class="link" href="harfbuzz-hb-font.html#hb-font-t" title="hb_font_t"><span class="returnvalue">hb_font_t</span></a> *
+<pre class="programlisting"><a class="link" href="harfbuzz-hb-font.html#hb-font-t"><span class="returnvalue">hb_font_t</span></a> *
 hb_font_get_empty (<em class="parameter"><code><span class="type">void</span></code></em>);</pre>
 <div class="refsect3">
 <a name="hb-font-get-empty.returns"></a><h4>Returns</h4>
@@ -1502,8 +1594,8 @@ hb_font_get_empty (<em class="parameter"><code><span class="type">void</span></c
 <hr>
 <div class="refsect2">
 <a name="hb-font-get-face"></a><h3>hb_font_get_face ()</h3>
-<pre class="programlisting"><a class="link" href="harfbuzz-hb-face.html#hb-face-t" title="hb_face_t"><span class="returnvalue">hb_face_t</span></a> *
-hb_font_get_face (<em class="parameter"><code><a class="link" href="harfbuzz-hb-font.html#hb-font-t" title="hb_font_t"><span class="type">hb_font_t</span></a> *font</code></em>);</pre>
+<pre class="programlisting"><a class="link" href="harfbuzz-hb-face.html#hb-face-t"><span class="returnvalue">hb_face_t</span></a> *
+hb_font_get_face (<em class="parameter"><code><a class="link" href="harfbuzz-hb-font.html#hb-font-t"><span class="type">hb_font_t</span></a> *font</code></em>);</pre>
 <div class="refsect3">
 <a name="hb-font-get-face.parameters"></a><h4>Parameters</h4>
 <div class="informaltable"><table class="informaltable" width="100%" border="0">
@@ -1530,7 +1622,7 @@ hb_font_get_face (<em class="parameter"><code><a class="link" href="harfbuzz-hb-
 <div class="refsect2">
 <a name="hb-font-get-glyph"></a><h3>hb_font_get_glyph ()</h3>
 <pre class="programlisting"><a class="link" href="harfbuzz-hb-common.html#hb-bool-t" title="hb_bool_t"><span class="returnvalue">hb_bool_t</span></a>
-hb_font_get_glyph (<em class="parameter"><code><a class="link" href="harfbuzz-hb-font.html#hb-font-t" title="hb_font_t"><span class="type">hb_font_t</span></a> *font</code></em>,
+hb_font_get_glyph (<em class="parameter"><code><a class="link" href="harfbuzz-hb-font.html#hb-font-t"><span class="type">hb_font_t</span></a> *font</code></em>,
                    <em class="parameter"><code><a class="link" href="harfbuzz-hb-common.html#hb-codepoint-t" title="hb_codepoint_t"><span class="type">hb_codepoint_t</span></a> unicode</code></em>,
                    <em class="parameter"><code><a class="link" href="harfbuzz-hb-common.html#hb-codepoint-t" title="hb_codepoint_t"><span class="type">hb_codepoint_t</span></a> variation_selector</code></em>,
                    <em class="parameter"><code><a class="link" href="harfbuzz-hb-common.html#hb-codepoint-t" title="hb_codepoint_t"><span class="type">hb_codepoint_t</span></a> *glyph</code></em>);</pre>
@@ -1563,7 +1655,7 @@ hb_font_get_glyph (<em class="parameter"><code><a class="link" href="harfbuzz-hb
 <a name="hb-font-get-glyph-advance-for-direction"></a><h3>hb_font_get_glyph_advance_for_direction ()</h3>
 <pre class="programlisting"><span class="returnvalue">void</span>
 hb_font_get_glyph_advance_for_direction
-                               (<em class="parameter"><code><a class="link" href="harfbuzz-hb-font.html#hb-font-t" title="hb_font_t"><span class="type">hb_font_t</span></a> *font</code></em>,
+                               (<em class="parameter"><code><a class="link" href="harfbuzz-hb-font.html#hb-font-t"><span class="type">hb_font_t</span></a> *font</code></em>,
                                 <em class="parameter"><code><a class="link" href="harfbuzz-hb-common.html#hb-codepoint-t" title="hb_codepoint_t"><span class="type">hb_codepoint_t</span></a> glyph</code></em>,
                                 <em class="parameter"><code><a class="link" href="harfbuzz-hb-common.html#hb-direction-t" title="enum hb_direction_t"><span class="type">hb_direction_t</span></a> direction</code></em>,
                                 <em class="parameter"><code><a class="link" href="harfbuzz-hb-common.html#hb-position-t" title="hb_position_t"><span class="type">hb_position_t</span></a> *x</code></em>,
@@ -1601,7 +1693,7 @@ hb_font_get_glyph_advance_for_direction
 <div class="refsect2">
 <a name="hb-font-get-glyph-advance-func-t"></a><h3>hb_font_get_glyph_advance_func_t ()</h3>
 <pre class="programlisting"><a class="link" href="harfbuzz-hb-common.html#hb-position-t" title="hb_position_t"><span class="returnvalue">hb_position_t</span></a>
-<span class="c_punctuation">(</span>*hb_font_get_glyph_advance_func_t<span class="c_punctuation">)</span> (<em class="parameter"><code><a class="link" href="harfbuzz-hb-font.html#hb-font-t" title="hb_font_t"><span class="type">hb_font_t</span></a> *font</code></em>,
+<span class="c_punctuation">(</span>*hb_font_get_glyph_advance_func_t<span class="c_punctuation">)</span> (<em class="parameter"><code><a class="link" href="harfbuzz-hb-font.html#hb-font-t"><span class="type">hb_font_t</span></a> *font</code></em>,
                                      <em class="parameter"><code><span class="type">void</span> *font_data</code></em>,
                                      <em class="parameter"><code><a class="link" href="harfbuzz-hb-common.html#hb-codepoint-t" title="hb_codepoint_t"><span class="type">hb_codepoint_t</span></a> glyph</code></em>,
                                      <em class="parameter"><code><span class="type">void</span> *user_data</code></em>);</pre>
@@ -1611,7 +1703,7 @@ hb_font_get_glyph_advance_for_direction
 <a name="hb-font-get-glyph-advances-for-direction"></a><h3>hb_font_get_glyph_advances_for_direction ()</h3>
 <pre class="programlisting"><span class="returnvalue">void</span>
 hb_font_get_glyph_advances_for_direction
-                               (<em class="parameter"><code><a class="link" href="harfbuzz-hb-font.html#hb-font-t" title="hb_font_t"><span class="type">hb_font_t</span></a> *font</code></em>,
+                               (<em class="parameter"><code><a class="link" href="harfbuzz-hb-font.html#hb-font-t"><span class="type">hb_font_t</span></a> *font</code></em>,
                                 <em class="parameter"><code><a class="link" href="harfbuzz-hb-common.html#hb-direction-t" title="enum hb_direction_t"><span class="type">hb_direction_t</span></a> direction</code></em>,
                                 <em class="parameter"><code>unsigned <span class="type">int</span> count</code></em>,
                                 <em class="parameter"><code>const <a class="link" href="harfbuzz-hb-common.html#hb-codepoint-t" title="hb_codepoint_t"><span class="type">hb_codepoint_t</span></a> *first_glyph</code></em>,
@@ -1639,7 +1731,7 @@ hb_font_get_glyph_advances_for_direction
 <div class="refsect2">
 <a name="hb-font-get-glyph-advances-func-t"></a><h3>hb_font_get_glyph_advances_func_t ()</h3>
 <pre class="programlisting"><span class="returnvalue">void</span>
-<span class="c_punctuation">(</span>*hb_font_get_glyph_advances_func_t<span class="c_punctuation">)</span> (<em class="parameter"><code><a class="link" href="harfbuzz-hb-font.html#hb-font-t" title="hb_font_t"><span class="type">hb_font_t</span></a> *font</code></em>,
+<span class="c_punctuation">(</span>*hb_font_get_glyph_advances_func_t<span class="c_punctuation">)</span> (<em class="parameter"><code><a class="link" href="harfbuzz-hb-font.html#hb-font-t"><span class="type">hb_font_t</span></a> *font</code></em>,
                                       <em class="parameter"><code><span class="type">void</span> *font_data</code></em>,
                                       <em class="parameter"><code>unsigned <span class="type">int</span> count</code></em>,
                                       <em class="parameter"><code>const <a class="link" href="harfbuzz-hb-common.html#hb-codepoint-t" title="hb_codepoint_t"><span class="type">hb_codepoint_t</span></a> *first_glyph</code></em>,
@@ -1652,7 +1744,7 @@ hb_font_get_glyph_advances_for_direction
 <div class="refsect2">
 <a name="hb-font-get-glyph-contour-point"></a><h3>hb_font_get_glyph_contour_point ()</h3>
 <pre class="programlisting"><a class="link" href="harfbuzz-hb-common.html#hb-bool-t" title="hb_bool_t"><span class="returnvalue">hb_bool_t</span></a>
-hb_font_get_glyph_contour_point (<em class="parameter"><code><a class="link" href="harfbuzz-hb-font.html#hb-font-t" title="hb_font_t"><span class="type">hb_font_t</span></a> *font</code></em>,
+hb_font_get_glyph_contour_point (<em class="parameter"><code><a class="link" href="harfbuzz-hb-font.html#hb-font-t"><span class="type">hb_font_t</span></a> *font</code></em>,
                                  <em class="parameter"><code><a class="link" href="harfbuzz-hb-common.html#hb-codepoint-t" title="hb_codepoint_t"><span class="type">hb_codepoint_t</span></a> glyph</code></em>,
                                  <em class="parameter"><code>unsigned <span class="type">int</span> point_index</code></em>,
                                  <em class="parameter"><code><a class="link" href="harfbuzz-hb-common.html#hb-position-t" title="hb_position_t"><span class="type">hb_position_t</span></a> *x</code></em>,
@@ -1691,7 +1783,7 @@ hb_font_get_glyph_contour_point (<em class="parameter"><code><a class="link" hre
 <a name="hb-font-get-glyph-contour-point-for-origin"></a><h3>hb_font_get_glyph_contour_point_for_origin ()</h3>
 <pre class="programlisting"><a class="link" href="harfbuzz-hb-common.html#hb-bool-t" title="hb_bool_t"><span class="returnvalue">hb_bool_t</span></a>
 hb_font_get_glyph_contour_point_for_origin
-                               (<em class="parameter"><code><a class="link" href="harfbuzz-hb-font.html#hb-font-t" title="hb_font_t"><span class="type">hb_font_t</span></a> *font</code></em>,
+                               (<em class="parameter"><code><a class="link" href="harfbuzz-hb-font.html#hb-font-t"><span class="type">hb_font_t</span></a> *font</code></em>,
                                 <em class="parameter"><code><a class="link" href="harfbuzz-hb-common.html#hb-codepoint-t" title="hb_codepoint_t"><span class="type">hb_codepoint_t</span></a> glyph</code></em>,
                                 <em class="parameter"><code>unsigned <span class="type">int</span> point_index</code></em>,
                                 <em class="parameter"><code><a class="link" href="harfbuzz-hb-common.html#hb-direction-t" title="enum hb_direction_t"><span class="type">hb_direction_t</span></a> direction</code></em>,
@@ -1731,7 +1823,7 @@ hb_font_get_glyph_contour_point_for_origin
 <a name="hb-font-get-glyph-contour-point-func-t"></a><h3>hb_font_get_glyph_contour_point_func_t ()</h3>
 <pre class="programlisting"><a class="link" href="harfbuzz-hb-common.html#hb-bool-t" title="hb_bool_t"><span class="returnvalue">hb_bool_t</span></a>
 <span class="c_punctuation">(</span>*hb_font_get_glyph_contour_point_func_t<span class="c_punctuation">)</span>
-                               (<em class="parameter"><code><a class="link" href="harfbuzz-hb-font.html#hb-font-t" title="hb_font_t"><span class="type">hb_font_t</span></a> *font</code></em>,
+                               (<em class="parameter"><code><a class="link" href="harfbuzz-hb-font.html#hb-font-t"><span class="type">hb_font_t</span></a> *font</code></em>,
                                 <em class="parameter"><code><span class="type">void</span> *font_data</code></em>,
                                 <em class="parameter"><code><a class="link" href="harfbuzz-hb-common.html#hb-codepoint-t" title="hb_codepoint_t"><span class="type">hb_codepoint_t</span></a> glyph</code></em>,
                                 <em class="parameter"><code>unsigned <span class="type">int</span> point_index</code></em>,
@@ -1743,7 +1835,7 @@ hb_font_get_glyph_contour_point_for_origin
 <div class="refsect2">
 <a name="hb-font-get-glyph-extents"></a><h3>hb_font_get_glyph_extents ()</h3>
 <pre class="programlisting"><a class="link" href="harfbuzz-hb-common.html#hb-bool-t" title="hb_bool_t"><span class="returnvalue">hb_bool_t</span></a>
-hb_font_get_glyph_extents (<em class="parameter"><code><a class="link" href="harfbuzz-hb-font.html#hb-font-t" title="hb_font_t"><span class="type">hb_font_t</span></a> *font</code></em>,
+hb_font_get_glyph_extents (<em class="parameter"><code><a class="link" href="harfbuzz-hb-font.html#hb-font-t"><span class="type">hb_font_t</span></a> *font</code></em>,
                            <em class="parameter"><code><a class="link" href="harfbuzz-hb-common.html#hb-codepoint-t" title="hb_codepoint_t"><span class="type">hb_codepoint_t</span></a> glyph</code></em>,
                            <em class="parameter"><code><span class="type">hb_glyph_extents_t</span> *extents</code></em>);</pre>
 <div class="refsect3">
@@ -1774,7 +1866,7 @@ hb_font_get_glyph_extents (<em class="parameter"><code><a class="link" href="har
 <div class="refsect2">
 <a name="hb-font-get-glyph-extents-for-origin"></a><h3>hb_font_get_glyph_extents_for_origin ()</h3>
 <pre class="programlisting"><a class="link" href="harfbuzz-hb-common.html#hb-bool-t" title="hb_bool_t"><span class="returnvalue">hb_bool_t</span></a>
-hb_font_get_glyph_extents_for_origin (<em class="parameter"><code><a class="link" href="harfbuzz-hb-font.html#hb-font-t" title="hb_font_t"><span class="type">hb_font_t</span></a> *font</code></em>,
+hb_font_get_glyph_extents_for_origin (<em class="parameter"><code><a class="link" href="harfbuzz-hb-font.html#hb-font-t"><span class="type">hb_font_t</span></a> *font</code></em>,
                                       <em class="parameter"><code><a class="link" href="harfbuzz-hb-common.html#hb-codepoint-t" title="hb_codepoint_t"><span class="type">hb_codepoint_t</span></a> glyph</code></em>,
                                       <em class="parameter"><code><a class="link" href="harfbuzz-hb-common.html#hb-direction-t" title="enum hb_direction_t"><span class="type">hb_direction_t</span></a> direction</code></em>,
                                       <em class="parameter"><code><span class="type">hb_glyph_extents_t</span> *extents</code></em>);</pre>
@@ -1806,7 +1898,7 @@ hb_font_get_glyph_extents_for_origin (<em class="parameter"><code><a class="link
 <div class="refsect2">
 <a name="hb-font-get-glyph-extents-func-t"></a><h3>hb_font_get_glyph_extents_func_t ()</h3>
 <pre class="programlisting"><a class="link" href="harfbuzz-hb-common.html#hb-bool-t" title="hb_bool_t"><span class="returnvalue">hb_bool_t</span></a>
-<span class="c_punctuation">(</span>*hb_font_get_glyph_extents_func_t<span class="c_punctuation">)</span> (<em class="parameter"><code><a class="link" href="harfbuzz-hb-font.html#hb-font-t" title="hb_font_t"><span class="type">hb_font_t</span></a> *font</code></em>,
+<span class="c_punctuation">(</span>*hb_font_get_glyph_extents_func_t<span class="c_punctuation">)</span> (<em class="parameter"><code><a class="link" href="harfbuzz-hb-font.html#hb-font-t"><span class="type">hb_font_t</span></a> *font</code></em>,
                                      <em class="parameter"><code><span class="type">void</span> *font_data</code></em>,
                                      <em class="parameter"><code><a class="link" href="harfbuzz-hb-common.html#hb-codepoint-t" title="hb_codepoint_t"><span class="type">hb_codepoint_t</span></a> glyph</code></em>,
                                      <em class="parameter"><code><span class="type">hb_glyph_extents_t</span> *extents</code></em>,
@@ -1816,7 +1908,7 @@ hb_font_get_glyph_extents_for_origin (<em class="parameter"><code><a class="link
 <div class="refsect2">
 <a name="hb-font-get-glyph-from-name"></a><h3>hb_font_get_glyph_from_name ()</h3>
 <pre class="programlisting"><a class="link" href="harfbuzz-hb-common.html#hb-bool-t" title="hb_bool_t"><span class="returnvalue">hb_bool_t</span></a>
-hb_font_get_glyph_from_name (<em class="parameter"><code><a class="link" href="harfbuzz-hb-font.html#hb-font-t" title="hb_font_t"><span class="type">hb_font_t</span></a> *font</code></em>,
+hb_font_get_glyph_from_name (<em class="parameter"><code><a class="link" href="harfbuzz-hb-font.html#hb-font-t"><span class="type">hb_font_t</span></a> *font</code></em>,
                              <em class="parameter"><code>const <span class="type">char</span> *name</code></em>,
                              <em class="parameter"><code><span class="type">int</span> len</code></em>,
                              <em class="parameter"><code><a class="link" href="harfbuzz-hb-common.html#hb-codepoint-t" title="hb_codepoint_t"><span class="type">hb_codepoint_t</span></a> *glyph</code></em>);</pre>
@@ -1853,7 +1945,7 @@ hb_font_get_glyph_from_name (<em class="parameter"><code><a class="link" href="h
 <div class="refsect2">
 <a name="hb-font-get-glyph-from-name-func-t"></a><h3>hb_font_get_glyph_from_name_func_t ()</h3>
 <pre class="programlisting"><a class="link" href="harfbuzz-hb-common.html#hb-bool-t" title="hb_bool_t"><span class="returnvalue">hb_bool_t</span></a>
-<span class="c_punctuation">(</span>*hb_font_get_glyph_from_name_func_t<span class="c_punctuation">)</span> (<em class="parameter"><code><a class="link" href="harfbuzz-hb-font.html#hb-font-t" title="hb_font_t"><span class="type">hb_font_t</span></a> *font</code></em>,
+<span class="c_punctuation">(</span>*hb_font_get_glyph_from_name_func_t<span class="c_punctuation">)</span> (<em class="parameter"><code><a class="link" href="harfbuzz-hb-font.html#hb-font-t"><span class="type">hb_font_t</span></a> *font</code></em>,
                                        <em class="parameter"><code><span class="type">void</span> *font_data</code></em>,
                                        <em class="parameter"><code>const <span class="type">char</span> *name</code></em>,
                                        <em class="parameter"><code><span class="type">int</span> len</code></em>);</pre>
@@ -1862,7 +1954,7 @@ hb_font_get_glyph_from_name (<em class="parameter"><code><a class="link" href="h
 <div class="refsect2">
 <a name="hb-font-get-glyph-h-advance"></a><h3>hb_font_get_glyph_h_advance ()</h3>
 <pre class="programlisting"><a class="link" href="harfbuzz-hb-common.html#hb-position-t" title="hb_position_t"><span class="returnvalue">hb_position_t</span></a>
-hb_font_get_glyph_h_advance (<em class="parameter"><code><a class="link" href="harfbuzz-hb-font.html#hb-font-t" title="hb_font_t"><span class="type">hb_font_t</span></a> *font</code></em>,
+hb_font_get_glyph_h_advance (<em class="parameter"><code><a class="link" href="harfbuzz-hb-font.html#hb-font-t"><span class="type">hb_font_t</span></a> *font</code></em>,
                              <em class="parameter"><code><a class="link" href="harfbuzz-hb-common.html#hb-codepoint-t" title="hb_codepoint_t"><span class="type">hb_codepoint_t</span></a> glyph</code></em>);</pre>
 <div class="refsect3">
 <a name="hb-font-get-glyph-h-advance.parameters"></a><h4>Parameters</h4>
@@ -1885,7 +1977,7 @@ hb_font_get_glyph_h_advance (<em class="parameter"><code><a class="link" href="h
 <div class="refsect2">
 <a name="hb-font-get-glyph-h-advances"></a><h3>hb_font_get_glyph_h_advances ()</h3>
 <pre class="programlisting"><span class="returnvalue">void</span>
-hb_font_get_glyph_h_advances (<em class="parameter"><code><a class="link" href="harfbuzz-hb-font.html#hb-font-t" title="hb_font_t"><span class="type">hb_font_t</span></a> *font</code></em>,
+hb_font_get_glyph_h_advances (<em class="parameter"><code><a class="link" href="harfbuzz-hb-font.html#hb-font-t"><span class="type">hb_font_t</span></a> *font</code></em>,
                               <em class="parameter"><code>unsigned <span class="type">int</span> count</code></em>,
                               <em class="parameter"><code>const <a class="link" href="harfbuzz-hb-common.html#hb-codepoint-t" title="hb_codepoint_t"><span class="type">hb_codepoint_t</span></a> *first_glyph</code></em>,
                               <em class="parameter"><code><span class="type">unsigned </span> glyph_stride</code></em>,
@@ -1910,9 +2002,33 @@ hb_font_get_glyph_h_advances (<em class="parameter"><code><a class="link" href="
 </div>
 <hr>
 <div class="refsect2">
+<a name="hb-font-get-glyph-h-kerning"></a><h3>hb_font_get_glyph_h_kerning ()</h3>
+<pre class="programlisting"><a class="link" href="harfbuzz-hb-common.html#hb-position-t" title="hb_position_t"><span class="returnvalue">hb_position_t</span></a>
+hb_font_get_glyph_h_kerning (<em class="parameter"><code><a class="link" href="harfbuzz-hb-font.html#hb-font-t"><span class="type">hb_font_t</span></a> *font</code></em>,
+                             <em class="parameter"><code><a class="link" href="harfbuzz-hb-common.html#hb-codepoint-t" title="hb_codepoint_t"><span class="type">hb_codepoint_t</span></a> left_glyph</code></em>,
+                             <em class="parameter"><code><a class="link" href="harfbuzz-hb-common.html#hb-codepoint-t" title="hb_codepoint_t"><span class="type">hb_codepoint_t</span></a> right_glyph</code></em>);</pre>
+<div class="refsect3">
+<a name="hb-font-get-glyph-h-kerning.parameters"></a><h4>Parameters</h4>
+<div class="informaltable"><table class="informaltable" width="100%" border="0">
+<colgroup>
+<col width="150px" class="parameters_name">
+<col class="parameters_description">
+<col width="200px" class="parameters_annotations">
+</colgroup>
+<tbody><tr>
+<td class="parameter_name"><p>font</p></td>
+<td class="parameter_description"><p>a font.</p></td>
+<td class="parameter_annotations"> </td>
+</tr></tbody>
+</table></div>
+</div>
+<p class="since">Since: <a class="link" href="api-index-0-9-2.html#api-index-0.9.2">0.9.2</a></p>
+</div>
+<hr>
+<div class="refsect2">
 <a name="hb-font-get-glyph-h-origin"></a><h3>hb_font_get_glyph_h_origin ()</h3>
 <pre class="programlisting"><a class="link" href="harfbuzz-hb-common.html#hb-bool-t" title="hb_bool_t"><span class="returnvalue">hb_bool_t</span></a>
-hb_font_get_glyph_h_origin (<em class="parameter"><code><a class="link" href="harfbuzz-hb-font.html#hb-font-t" title="hb_font_t"><span class="type">hb_font_t</span></a> *font</code></em>,
+hb_font_get_glyph_h_origin (<em class="parameter"><code><a class="link" href="harfbuzz-hb-font.html#hb-font-t"><span class="type">hb_font_t</span></a> *font</code></em>,
                             <em class="parameter"><code><a class="link" href="harfbuzz-hb-common.html#hb-codepoint-t" title="hb_codepoint_t"><span class="type">hb_codepoint_t</span></a> glyph</code></em>,
                             <em class="parameter"><code><a class="link" href="harfbuzz-hb-common.html#hb-position-t" title="hb_position_t"><span class="type">hb_position_t</span></a> *x</code></em>,
                             <em class="parameter"><code><a class="link" href="harfbuzz-hb-common.html#hb-position-t" title="hb_position_t"><span class="type">hb_position_t</span></a> *y</code></em>);</pre>
@@ -1947,9 +2063,59 @@ hb_font_get_glyph_h_origin (<em class="parameter"><code><a class="link" href="ha
 </div>
 <hr>
 <div class="refsect2">
+<a name="hb-font-get-glyph-kerning-for-direction"></a><h3>hb_font_get_glyph_kerning_for_direction ()</h3>
+<pre class="programlisting"><span class="returnvalue">void</span>
+hb_font_get_glyph_kerning_for_direction
+                               (<em class="parameter"><code><a class="link" href="harfbuzz-hb-font.html#hb-font-t"><span class="type">hb_font_t</span></a> *font</code></em>,
+                                <em class="parameter"><code><a class="link" href="harfbuzz-hb-common.html#hb-codepoint-t" title="hb_codepoint_t"><span class="type">hb_codepoint_t</span></a> first_glyph</code></em>,
+                                <em class="parameter"><code><a class="link" href="harfbuzz-hb-common.html#hb-codepoint-t" title="hb_codepoint_t"><span class="type">hb_codepoint_t</span></a> second_glyph</code></em>,
+                                <em class="parameter"><code><a class="link" href="harfbuzz-hb-common.html#hb-direction-t" title="enum hb_direction_t"><span class="type">hb_direction_t</span></a> direction</code></em>,
+                                <em class="parameter"><code><a class="link" href="harfbuzz-hb-common.html#hb-position-t" title="hb_position_t"><span class="type">hb_position_t</span></a> *x</code></em>,
+                                <em class="parameter"><code><a class="link" href="harfbuzz-hb-common.html#hb-position-t" title="hb_position_t"><span class="type">hb_position_t</span></a> *y</code></em>);</pre>
+<div class="refsect3">
+<a name="hb-font-get-glyph-kerning-for-direction.parameters"></a><h4>Parameters</h4>
+<div class="informaltable"><table class="informaltable" width="100%" border="0">
+<colgroup>
+<col width="150px" class="parameters_name">
+<col class="parameters_description">
+<col width="200px" class="parameters_annotations">
+</colgroup>
+<tbody>
+<tr>
+<td class="parameter_name"><p>font</p></td>
+<td class="parameter_description"><p>a font.</p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+<tr>
+<td class="parameter_name"><p>x</p></td>
+<td class="parameter_description"><p>. </p></td>
+<td class="parameter_annotations"><span class="annotation">[<acronym title="Parameter for returning results. Default is transfer full."><span class="acronym">out</span></acronym>]</span></td>
+</tr>
+<tr>
+<td class="parameter_name"><p>y</p></td>
+<td class="parameter_description"><p>. </p></td>
+<td class="parameter_annotations"><span class="annotation">[<acronym title="Parameter for returning results. Default is transfer full."><span class="acronym">out</span></acronym>]</span></td>
+</tr>
+</tbody>
+</table></div>
+</div>
+<p class="since">Since: <a class="link" href="api-index-0-9-2.html#api-index-0.9.2">0.9.2</a></p>
+</div>
+<hr>
+<div class="refsect2">
+<a name="hb-font-get-glyph-kerning-func-t"></a><h3>hb_font_get_glyph_kerning_func_t ()</h3>
+<pre class="programlisting"><a class="link" href="harfbuzz-hb-common.html#hb-position-t" title="hb_position_t"><span class="returnvalue">hb_position_t</span></a>
+<span class="c_punctuation">(</span>*hb_font_get_glyph_kerning_func_t<span class="c_punctuation">)</span> (<em class="parameter"><code><a class="link" href="harfbuzz-hb-font.html#hb-font-t"><span class="type">hb_font_t</span></a> *font</code></em>,
+                                     <em class="parameter"><code><span class="type">void</span> *font_data</code></em>,
+                                     <em class="parameter"><code><a class="link" href="harfbuzz-hb-common.html#hb-codepoint-t" title="hb_codepoint_t"><span class="type">hb_codepoint_t</span></a> first_glyph</code></em>,
+                                     <em class="parameter"><code><a class="link" href="harfbuzz-hb-common.html#hb-codepoint-t" title="hb_codepoint_t"><span class="type">hb_codepoint_t</span></a> second_glyph</code></em>,
+                                     <em class="parameter"><code><span class="type">void</span> *user_data</code></em>);</pre>
+</div>
+<hr>
+<div class="refsect2">
 <a name="hb-font-get-glyph-name"></a><h3>hb_font_get_glyph_name ()</h3>
 <pre class="programlisting"><a class="link" href="harfbuzz-hb-common.html#hb-bool-t" title="hb_bool_t"><span class="returnvalue">hb_bool_t</span></a>
-hb_font_get_glyph_name (<em class="parameter"><code><a class="link" href="harfbuzz-hb-font.html#hb-font-t" title="hb_font_t"><span class="type">hb_font_t</span></a> *font</code></em>,
+hb_font_get_glyph_name (<em class="parameter"><code><a class="link" href="harfbuzz-hb-font.html#hb-font-t"><span class="type">hb_font_t</span></a> *font</code></em>,
                         <em class="parameter"><code><a class="link" href="harfbuzz-hb-common.html#hb-codepoint-t" title="hb_codepoint_t"><span class="type">hb_codepoint_t</span></a> glyph</code></em>,
                         <em class="parameter"><code><span class="type">char</span> *name</code></em>,
                         <em class="parameter"><code>unsigned <span class="type">int</span> size</code></em>);</pre>
@@ -1981,7 +2147,7 @@ hb_font_get_glyph_name (<em class="parameter"><code><a class="link" href="harfbu
 <div class="refsect2">
 <a name="hb-font-get-glyph-name-func-t"></a><h3>hb_font_get_glyph_name_func_t ()</h3>
 <pre class="programlisting"><a class="link" href="harfbuzz-hb-common.html#hb-bool-t" title="hb_bool_t"><span class="returnvalue">hb_bool_t</span></a>
-<span class="c_punctuation">(</span>*hb_font_get_glyph_name_func_t<span class="c_punctuation">)</span> (<em class="parameter"><code><a class="link" href="harfbuzz-hb-font.html#hb-font-t" title="hb_font_t"><span class="type">hb_font_t</span></a> *font</code></em>,
+<span class="c_punctuation">(</span>*hb_font_get_glyph_name_func_t<span class="c_punctuation">)</span> (<em class="parameter"><code><a class="link" href="harfbuzz-hb-font.html#hb-font-t"><span class="type">hb_font_t</span></a> *font</code></em>,
                                   <em class="parameter"><code><span class="type">void</span> *font_data</code></em>,
                                   <em class="parameter"><code><a class="link" href="harfbuzz-hb-common.html#hb-codepoint-t" title="hb_codepoint_t"><span class="type">hb_codepoint_t</span></a> glyph</code></em>,
                                   <em class="parameter"><code><span class="type">char</span> *name</code></em>,
@@ -1993,7 +2159,7 @@ hb_font_get_glyph_name (<em class="parameter"><code><a class="link" href="harfbu
 <a name="hb-font-get-glyph-origin-for-direction"></a><h3>hb_font_get_glyph_origin_for_direction ()</h3>
 <pre class="programlisting"><span class="returnvalue">void</span>
 hb_font_get_glyph_origin_for_direction
-                               (<em class="parameter"><code><a class="link" href="harfbuzz-hb-font.html#hb-font-t" title="hb_font_t"><span class="type">hb_font_t</span></a> *font</code></em>,
+                               (<em class="parameter"><code><a class="link" href="harfbuzz-hb-font.html#hb-font-t"><span class="type">hb_font_t</span></a> *font</code></em>,
                                 <em class="parameter"><code><a class="link" href="harfbuzz-hb-common.html#hb-codepoint-t" title="hb_codepoint_t"><span class="type">hb_codepoint_t</span></a> glyph</code></em>,
                                 <em class="parameter"><code><a class="link" href="harfbuzz-hb-common.html#hb-direction-t" title="enum hb_direction_t"><span class="type">hb_direction_t</span></a> direction</code></em>,
                                 <em class="parameter"><code><a class="link" href="harfbuzz-hb-common.html#hb-position-t" title="hb_position_t"><span class="type">hb_position_t</span></a> *x</code></em>,
@@ -2031,7 +2197,7 @@ hb_font_get_glyph_origin_for_direction
 <div class="refsect2">
 <a name="hb-font-get-glyph-origin-func-t"></a><h3>hb_font_get_glyph_origin_func_t ()</h3>
 <pre class="programlisting"><a class="link" href="harfbuzz-hb-common.html#hb-bool-t" title="hb_bool_t"><span class="returnvalue">hb_bool_t</span></a>
-<span class="c_punctuation">(</span>*hb_font_get_glyph_origin_func_t<span class="c_punctuation">)</span> (<em class="parameter"><code><a class="link" href="harfbuzz-hb-font.html#hb-font-t" title="hb_font_t"><span class="type">hb_font_t</span></a> *font</code></em>,
+<span class="c_punctuation">(</span>*hb_font_get_glyph_origin_func_t<span class="c_punctuation">)</span> (<em class="parameter"><code><a class="link" href="harfbuzz-hb-font.html#hb-font-t"><span class="type">hb_font_t</span></a> *font</code></em>,
                                     <em class="parameter"><code><span class="type">void</span> *font_data</code></em>,
                                     <em class="parameter"><code><a class="link" href="harfbuzz-hb-common.html#hb-codepoint-t" title="hb_codepoint_t"><span class="type">hb_codepoint_t</span></a> glyph</code></em>,
                                     <em class="parameter"><code><a class="link" href="harfbuzz-hb-common.html#hb-position-t" title="hb_position_t"><span class="type">hb_position_t</span></a> *x</code></em>,
@@ -2042,7 +2208,7 @@ hb_font_get_glyph_origin_for_direction
 <div class="refsect2">
 <a name="hb-font-get-glyph-v-advance"></a><h3>hb_font_get_glyph_v_advance ()</h3>
 <pre class="programlisting"><a class="link" href="harfbuzz-hb-common.html#hb-position-t" title="hb_position_t"><span class="returnvalue">hb_position_t</span></a>
-hb_font_get_glyph_v_advance (<em class="parameter"><code><a class="link" href="harfbuzz-hb-font.html#hb-font-t" title="hb_font_t"><span class="type">hb_font_t</span></a> *font</code></em>,
+hb_font_get_glyph_v_advance (<em class="parameter"><code><a class="link" href="harfbuzz-hb-font.html#hb-font-t"><span class="type">hb_font_t</span></a> *font</code></em>,
                              <em class="parameter"><code><a class="link" href="harfbuzz-hb-common.html#hb-codepoint-t" title="hb_codepoint_t"><span class="type">hb_codepoint_t</span></a> glyph</code></em>);</pre>
 <div class="refsect3">
 <a name="hb-font-get-glyph-v-advance.parameters"></a><h4>Parameters</h4>
@@ -2065,7 +2231,7 @@ hb_font_get_glyph_v_advance (<em class="parameter"><code><a class="link" href="h
 <div class="refsect2">
 <a name="hb-font-get-glyph-v-advances"></a><h3>hb_font_get_glyph_v_advances ()</h3>
 <pre class="programlisting"><span class="returnvalue">void</span>
-hb_font_get_glyph_v_advances (<em class="parameter"><code><a class="link" href="harfbuzz-hb-font.html#hb-font-t" title="hb_font_t"><span class="type">hb_font_t</span></a> *font</code></em>,
+hb_font_get_glyph_v_advances (<em class="parameter"><code><a class="link" href="harfbuzz-hb-font.html#hb-font-t"><span class="type">hb_font_t</span></a> *font</code></em>,
                               <em class="parameter"><code>unsigned <span class="type">int</span> count</code></em>,
                               <em class="parameter"><code>const <a class="link" href="harfbuzz-hb-common.html#hb-codepoint-t" title="hb_codepoint_t"><span class="type">hb_codepoint_t</span></a> *first_glyph</code></em>,
                               <em class="parameter"><code><span class="type">unsigned </span> glyph_stride</code></em>,
@@ -2092,7 +2258,7 @@ hb_font_get_glyph_v_advances (<em class="parameter"><code><a class="link" href="
 <div class="refsect2">
 <a name="hb-font-get-glyph-v-origin"></a><h3>hb_font_get_glyph_v_origin ()</h3>
 <pre class="programlisting"><a class="link" href="harfbuzz-hb-common.html#hb-bool-t" title="hb_bool_t"><span class="returnvalue">hb_bool_t</span></a>
-hb_font_get_glyph_v_origin (<em class="parameter"><code><a class="link" href="harfbuzz-hb-font.html#hb-font-t" title="hb_font_t"><span class="type">hb_font_t</span></a> *font</code></em>,
+hb_font_get_glyph_v_origin (<em class="parameter"><code><a class="link" href="harfbuzz-hb-font.html#hb-font-t"><span class="type">hb_font_t</span></a> *font</code></em>,
                             <em class="parameter"><code><a class="link" href="harfbuzz-hb-common.html#hb-codepoint-t" title="hb_codepoint_t"><span class="type">hb_codepoint_t</span></a> glyph</code></em>,
                             <em class="parameter"><code><a class="link" href="harfbuzz-hb-common.html#hb-position-t" title="hb_position_t"><span class="type">hb_position_t</span></a> *x</code></em>,
                             <em class="parameter"><code><a class="link" href="harfbuzz-hb-common.html#hb-position-t" title="hb_position_t"><span class="type">hb_position_t</span></a> *y</code></em>);</pre>
@@ -2129,7 +2295,7 @@ hb_font_get_glyph_v_origin (<em class="parameter"><code><a class="link" href="ha
 <div class="refsect2">
 <a name="hb-font-get-nominal-glyph"></a><h3>hb_font_get_nominal_glyph ()</h3>
 <pre class="programlisting"><a class="link" href="harfbuzz-hb-common.html#hb-bool-t" title="hb_bool_t"><span class="returnvalue">hb_bool_t</span></a>
-hb_font_get_nominal_glyph (<em class="parameter"><code><a class="link" href="harfbuzz-hb-font.html#hb-font-t" title="hb_font_t"><span class="type">hb_font_t</span></a> *font</code></em>,
+hb_font_get_nominal_glyph (<em class="parameter"><code><a class="link" href="harfbuzz-hb-font.html#hb-font-t"><span class="type">hb_font_t</span></a> *font</code></em>,
                            <em class="parameter"><code><a class="link" href="harfbuzz-hb-common.html#hb-codepoint-t" title="hb_codepoint_t"><span class="type">hb_codepoint_t</span></a> unicode</code></em>,
                            <em class="parameter"><code><a class="link" href="harfbuzz-hb-common.html#hb-codepoint-t" title="hb_codepoint_t"><span class="type">hb_codepoint_t</span></a> *glyph</code></em>);</pre>
 <div class="refsect3">
@@ -2160,7 +2326,7 @@ hb_font_get_nominal_glyph (<em class="parameter"><code><a class="link" href="har
 <div class="refsect2">
 <a name="hb-font-get-nominal-glyph-func-t"></a><h3>hb_font_get_nominal_glyph_func_t ()</h3>
 <pre class="programlisting"><a class="link" href="harfbuzz-hb-common.html#hb-bool-t" title="hb_bool_t"><span class="returnvalue">hb_bool_t</span></a>
-<span class="c_punctuation">(</span>*hb_font_get_nominal_glyph_func_t<span class="c_punctuation">)</span> (<em class="parameter"><code><a class="link" href="harfbuzz-hb-font.html#hb-font-t" title="hb_font_t"><span class="type">hb_font_t</span></a> *font</code></em>,
+<span class="c_punctuation">(</span>*hb_font_get_nominal_glyph_func_t<span class="c_punctuation">)</span> (<em class="parameter"><code><a class="link" href="harfbuzz-hb-font.html#hb-font-t"><span class="type">hb_font_t</span></a> *font</code></em>,
                                      <em class="parameter"><code><span class="type">void</span> *font_data</code></em>,
                                      <em class="parameter"><code><a class="link" href="harfbuzz-hb-common.html#hb-codepoint-t" title="hb_codepoint_t"><span class="type">hb_codepoint_t</span></a> unicode</code></em>,
                                      <em class="parameter"><code><a class="link" href="harfbuzz-hb-common.html#hb-codepoint-t" title="hb_codepoint_t"><span class="type">hb_codepoint_t</span></a> *glyph</code></em>,
@@ -2168,9 +2334,36 @@ hb_font_get_nominal_glyph (<em class="parameter"><code><a class="link" href="har
 </div>
 <hr>
 <div class="refsect2">
+<a name="hb-font-get-nominal-glyphs"></a><h3>hb_font_get_nominal_glyphs ()</h3>
+<pre class="programlisting">unsigned <span class="returnvalue">int</span>
+hb_font_get_nominal_glyphs (<em class="parameter"><code><a class="link" href="harfbuzz-hb-font.html#hb-font-t"><span class="type">hb_font_t</span></a> *font</code></em>,
+                            <em class="parameter"><code>unsigned <span class="type">int</span> count</code></em>,
+                            <em class="parameter"><code>const <a class="link" href="harfbuzz-hb-common.html#hb-codepoint-t" title="hb_codepoint_t"><span class="type">hb_codepoint_t</span></a> *first_unicode</code></em>,
+                            <em class="parameter"><code>unsigned <span class="type">int</span> unicode_stride</code></em>,
+                            <em class="parameter"><code><a class="link" href="harfbuzz-hb-common.html#hb-codepoint-t" title="hb_codepoint_t"><span class="type">hb_codepoint_t</span></a> *first_glyph</code></em>,
+                            <em class="parameter"><code>unsigned <span class="type">int</span> glyph_stride</code></em>);</pre>
+<div class="refsect3">
+<a name="hb-font-get-nominal-glyphs.parameters"></a><h4>Parameters</h4>
+<div class="informaltable"><table class="informaltable" width="100%" border="0">
+<colgroup>
+<col width="150px" class="parameters_name">
+<col class="parameters_description">
+<col width="200px" class="parameters_annotations">
+</colgroup>
+<tbody><tr>
+<td class="parameter_name"><p>font</p></td>
+<td class="parameter_description"><p>a font.</p></td>
+<td class="parameter_annotations"> </td>
+</tr></tbody>
+</table></div>
+</div>
+<p class="since">Since: 2.6.3</p>
+</div>
+<hr>
+<div class="refsect2">
 <a name="hb-font-get-parent"></a><h3>hb_font_get_parent ()</h3>
-<pre class="programlisting"><a class="link" href="harfbuzz-hb-font.html#hb-font-t" title="hb_font_t"><span class="returnvalue">hb_font_t</span></a> *
-hb_font_get_parent (<em class="parameter"><code><a class="link" href="harfbuzz-hb-font.html#hb-font-t" title="hb_font_t"><span class="type">hb_font_t</span></a> *font</code></em>);</pre>
+<pre class="programlisting"><a class="link" href="harfbuzz-hb-font.html#hb-font-t"><span class="returnvalue">hb_font_t</span></a> *
+hb_font_get_parent (<em class="parameter"><code><a class="link" href="harfbuzz-hb-font.html#hb-font-t"><span class="type">hb_font_t</span></a> *font</code></em>);</pre>
 <div class="refsect3">
 <a name="hb-font-get-parent.parameters"></a><h4>Parameters</h4>
 <div class="informaltable"><table class="informaltable" width="100%" border="0">
@@ -2197,7 +2390,7 @@ hb_font_get_parent (<em class="parameter"><code><a class="link" href="harfbuzz-h
 <div class="refsect2">
 <a name="hb-font-get-ppem"></a><h3>hb_font_get_ppem ()</h3>
 <pre class="programlisting"><span class="returnvalue">void</span>
-hb_font_get_ppem (<em class="parameter"><code><a class="link" href="harfbuzz-hb-font.html#hb-font-t" title="hb_font_t"><span class="type">hb_font_t</span></a> *font</code></em>,
+hb_font_get_ppem (<em class="parameter"><code><a class="link" href="harfbuzz-hb-font.html#hb-font-t"><span class="type">hb_font_t</span></a> *font</code></em>,
                   <em class="parameter"><code>unsigned <span class="type">int</span> *x_ppem</code></em>,
                   <em class="parameter"><code>unsigned <span class="type">int</span> *y_ppem</code></em>);</pre>
 <div class="refsect3">
@@ -2233,7 +2426,7 @@ hb_font_get_ppem (<em class="parameter"><code><a class="link" href="harfbuzz-hb-
 <div class="refsect2">
 <a name="hb-font-get-ptem"></a><h3>hb_font_get_ptem ()</h3>
 <pre class="programlisting"><span class="returnvalue">float</span>
-hb_font_get_ptem (<em class="parameter"><code><a class="link" href="harfbuzz-hb-font.html#hb-font-t" title="hb_font_t"><span class="type">hb_font_t</span></a> *font</code></em>);</pre>
+hb_font_get_ptem (<em class="parameter"><code><a class="link" href="harfbuzz-hb-font.html#hb-font-t"><span class="type">hb_font_t</span></a> *font</code></em>);</pre>
 <p>Gets the "point size" of the font.  A value of 0 means unset.</p>
 <div class="refsect3">
 <a name="hb-font-get-ptem.parameters"></a><h4>Parameters</h4>
@@ -2260,7 +2453,7 @@ hb_font_get_ptem (<em class="parameter"><code><a class="link" href="harfbuzz-hb-
 <div class="refsect2">
 <a name="hb-font-get-scale"></a><h3>hb_font_get_scale ()</h3>
 <pre class="programlisting"><span class="returnvalue">void</span>
-hb_font_get_scale (<em class="parameter"><code><a class="link" href="harfbuzz-hb-font.html#hb-font-t" title="hb_font_t"><span class="type">hb_font_t</span></a> *font</code></em>,
+hb_font_get_scale (<em class="parameter"><code><a class="link" href="harfbuzz-hb-font.html#hb-font-t"><span class="type">hb_font_t</span></a> *font</code></em>,
                    <em class="parameter"><code><span class="type">int</span> *x_scale</code></em>,
                    <em class="parameter"><code><span class="type">int</span> *y_scale</code></em>);</pre>
 <div class="refsect3">
@@ -2296,8 +2489,8 @@ hb_font_get_scale (<em class="parameter"><code><a class="link" href="harfbuzz-hb
 <div class="refsect2">
 <a name="hb-font-get-user-data"></a><h3>hb_font_get_user_data ()</h3>
 <pre class="programlisting"><span class="returnvalue">void</span> *
-hb_font_get_user_data (<em class="parameter"><code><a class="link" href="harfbuzz-hb-font.html#hb-font-t" title="hb_font_t"><span class="type">hb_font_t</span></a> *font</code></em>,
-                       <em class="parameter"><code><a class="link" href="harfbuzz-hb-common.html#hb-user-data-key-t" title="hb_user_data_key_t"><span class="type">hb_user_data_key_t</span></a> *key</code></em>);</pre>
+hb_font_get_user_data (<em class="parameter"><code><a class="link" href="harfbuzz-hb-font.html#hb-font-t"><span class="type">hb_font_t</span></a> *font</code></em>,
+                       <em class="parameter"><code><a class="link" href="harfbuzz-hb-common.html#hb-user-data-key-t"><span class="type">hb_user_data_key_t</span></a> *key</code></em>);</pre>
 <p><span class="annotation">[<acronym title="Exposed in C code, not necessarily available in other languages."><span class="acronym">skip</span></acronym>]</span></p>
 <div class="refsect3">
 <a name="hb-font-get-user-data.parameters"></a><h4>Parameters</h4>
@@ -2325,7 +2518,7 @@ hb_font_get_user_data (<em class="parameter"><code><a class="link" href="harfbuz
 <div class="refsect2">
 <a name="hb-font-get-variation-glyph"></a><h3>hb_font_get_variation_glyph ()</h3>
 <pre class="programlisting"><a class="link" href="harfbuzz-hb-common.html#hb-bool-t" title="hb_bool_t"><span class="returnvalue">hb_bool_t</span></a>
-hb_font_get_variation_glyph (<em class="parameter"><code><a class="link" href="harfbuzz-hb-font.html#hb-font-t" title="hb_font_t"><span class="type">hb_font_t</span></a> *font</code></em>,
+hb_font_get_variation_glyph (<em class="parameter"><code><a class="link" href="harfbuzz-hb-font.html#hb-font-t"><span class="type">hb_font_t</span></a> *font</code></em>,
                              <em class="parameter"><code><a class="link" href="harfbuzz-hb-common.html#hb-codepoint-t" title="hb_codepoint_t"><span class="type">hb_codepoint_t</span></a> unicode</code></em>,
                              <em class="parameter"><code><a class="link" href="harfbuzz-hb-common.html#hb-codepoint-t" title="hb_codepoint_t"><span class="type">hb_codepoint_t</span></a> variation_selector</code></em>,
                              <em class="parameter"><code><a class="link" href="harfbuzz-hb-common.html#hb-codepoint-t" title="hb_codepoint_t"><span class="type">hb_codepoint_t</span></a> *glyph</code></em>);</pre>
@@ -2357,7 +2550,7 @@ hb_font_get_variation_glyph (<em class="parameter"><code><a class="link" href="h
 <div class="refsect2">
 <a name="hb-font-get-variation-glyph-func-t"></a><h3>hb_font_get_variation_glyph_func_t ()</h3>
 <pre class="programlisting"><a class="link" href="harfbuzz-hb-common.html#hb-bool-t" title="hb_bool_t"><span class="returnvalue">hb_bool_t</span></a>
-<span class="c_punctuation">(</span>*hb_font_get_variation_glyph_func_t<span class="c_punctuation">)</span> (<em class="parameter"><code><a class="link" href="harfbuzz-hb-font.html#hb-font-t" title="hb_font_t"><span class="type">hb_font_t</span></a> *font</code></em>,
+<span class="c_punctuation">(</span>*hb_font_get_variation_glyph_func_t<span class="c_punctuation">)</span> (<em class="parameter"><code><a class="link" href="harfbuzz-hb-font.html#hb-font-t"><span class="type">hb_font_t</span></a> *font</code></em>,
                                        <em class="parameter"><code><span class="type">void</span> *font_data</code></em>,
                                        <em class="parameter"><code><a class="link" href="harfbuzz-hb-common.html#hb-codepoint-t" title="hb_codepoint_t"><span class="type">hb_codepoint_t</span></a> unicode</code></em>,
                                        <em class="parameter"><code><a class="link" href="harfbuzz-hb-common.html#hb-codepoint-t" title="hb_codepoint_t"><span class="type">hb_codepoint_t</span></a> variation_selector</code></em>,
@@ -2368,7 +2561,7 @@ hb_font_get_variation_glyph (<em class="parameter"><code><a class="link" href="h
 <div class="refsect2">
 <a name="hb-font-get-var-coords-normalized"></a><h3>hb_font_get_var_coords_normalized ()</h3>
 <pre class="programlisting">const <span class="returnvalue">int</span> *
-hb_font_get_var_coords_normalized (<em class="parameter"><code><a class="link" href="harfbuzz-hb-font.html#hb-font-t" title="hb_font_t"><span class="type">hb_font_t</span></a> *font</code></em>,
+hb_font_get_var_coords_normalized (<em class="parameter"><code><a class="link" href="harfbuzz-hb-font.html#hb-font-t"><span class="type">hb_font_t</span></a> *font</code></em>,
                                    <em class="parameter"><code>unsigned <span class="type">int</span> *length</code></em>);</pre>
 <p>Return value is valid as long as variation coordinates of the font
 are not modified.</p>
@@ -2378,7 +2571,7 @@ are not modified.</p>
 <div class="refsect2">
 <a name="hb-font-glyph-from-string"></a><h3>hb_font_glyph_from_string ()</h3>
 <pre class="programlisting"><a class="link" href="harfbuzz-hb-common.html#hb-bool-t" title="hb_bool_t"><span class="returnvalue">hb_bool_t</span></a>
-hb_font_glyph_from_string (<em class="parameter"><code><a class="link" href="harfbuzz-hb-font.html#hb-font-t" title="hb_font_t"><span class="type">hb_font_t</span></a> *font</code></em>,
+hb_font_glyph_from_string (<em class="parameter"><code><a class="link" href="harfbuzz-hb-font.html#hb-font-t"><span class="type">hb_font_t</span></a> *font</code></em>,
                            <em class="parameter"><code>const <span class="type">char</span> *s</code></em>,
                            <em class="parameter"><code><span class="type">int</span> len</code></em>,
                            <em class="parameter"><code><a class="link" href="harfbuzz-hb-common.html#hb-codepoint-t" title="hb_codepoint_t"><span class="type">hb_codepoint_t</span></a> *glyph</code></em>);</pre>
@@ -2415,7 +2608,7 @@ hb_font_glyph_from_string (<em class="parameter"><code><a class="link" href="har
 <div class="refsect2">
 <a name="hb-font-glyph-to-string"></a><h3>hb_font_glyph_to_string ()</h3>
 <pre class="programlisting"><span class="returnvalue">void</span>
-hb_font_glyph_to_string (<em class="parameter"><code><a class="link" href="harfbuzz-hb-font.html#hb-font-t" title="hb_font_t"><span class="type">hb_font_t</span></a> *font</code></em>,
+hb_font_glyph_to_string (<em class="parameter"><code><a class="link" href="harfbuzz-hb-font.html#hb-font-t"><span class="type">hb_font_t</span></a> *font</code></em>,
                          <em class="parameter"><code><a class="link" href="harfbuzz-hb-common.html#hb-codepoint-t" title="hb_codepoint_t"><span class="type">hb_codepoint_t</span></a> glyph</code></em>,
                          <em class="parameter"><code><span class="type">char</span> *s</code></em>,
                          <em class="parameter"><code>unsigned <span class="type">int</span> size</code></em>);</pre>
@@ -2447,7 +2640,7 @@ hb_font_glyph_to_string (<em class="parameter"><code><a class="link" href="harfb
 <div class="refsect2">
 <a name="hb-font-is-immutable"></a><h3>hb_font_is_immutable ()</h3>
 <pre class="programlisting"><a class="link" href="harfbuzz-hb-common.html#hb-bool-t" title="hb_bool_t"><span class="returnvalue">hb_bool_t</span></a>
-hb_font_is_immutable (<em class="parameter"><code><a class="link" href="harfbuzz-hb-font.html#hb-font-t" title="hb_font_t"><span class="type">hb_font_t</span></a> *font</code></em>);</pre>
+hb_font_is_immutable (<em class="parameter"><code><a class="link" href="harfbuzz-hb-font.html#hb-font-t"><span class="type">hb_font_t</span></a> *font</code></em>);</pre>
 <div class="refsect3">
 <a name="hb-font-is-immutable.parameters"></a><h4>Parameters</h4>
 <div class="informaltable"><table class="informaltable" width="100%" border="0">
@@ -2469,7 +2662,7 @@ hb_font_is_immutable (<em class="parameter"><code><a class="link" href="harfbuzz
 <div class="refsect2">
 <a name="hb-font-make-immutable"></a><h3>hb_font_make_immutable ()</h3>
 <pre class="programlisting"><span class="returnvalue">void</span>
-hb_font_make_immutable (<em class="parameter"><code><a class="link" href="harfbuzz-hb-font.html#hb-font-t" title="hb_font_t"><span class="type">hb_font_t</span></a> *font</code></em>);</pre>
+hb_font_make_immutable (<em class="parameter"><code><a class="link" href="harfbuzz-hb-font.html#hb-font-t"><span class="type">hb_font_t</span></a> *font</code></em>);</pre>
 <div class="refsect3">
 <a name="hb-font-make-immutable.parameters"></a><h4>Parameters</h4>
 <div class="informaltable"><table class="informaltable" width="100%" border="0">
@@ -2490,8 +2683,8 @@ hb_font_make_immutable (<em class="parameter"><code><a class="link" href="harfbu
 <hr>
 <div class="refsect2">
 <a name="hb-font-reference"></a><h3>hb_font_reference ()</h3>
-<pre class="programlisting"><a class="link" href="harfbuzz-hb-font.html#hb-font-t" title="hb_font_t"><span class="returnvalue">hb_font_t</span></a> *
-hb_font_reference (<em class="parameter"><code><a class="link" href="harfbuzz-hb-font.html#hb-font-t" title="hb_font_t"><span class="type">hb_font_t</span></a> *font</code></em>);</pre>
+<pre class="programlisting"><a class="link" href="harfbuzz-hb-font.html#hb-font-t"><span class="returnvalue">hb_font_t</span></a> *
+hb_font_reference (<em class="parameter"><code><a class="link" href="harfbuzz-hb-font.html#hb-font-t"><span class="type">hb_font_t</span></a> *font</code></em>);</pre>
 <p><span class="annotation">[<acronym title="Exposed in C code, not necessarily available in other languages."><span class="acronym">skip</span></acronym>]</span></p>
 <div class="refsect3">
 <a name="hb-font-reference.parameters"></a><h4>Parameters</h4>
@@ -2519,8 +2712,8 @@ hb_font_reference (<em class="parameter"><code><a class="link" href="harfbuzz-hb
 <div class="refsect2">
 <a name="hb-font-set-face"></a><h3>hb_font_set_face ()</h3>
 <pre class="programlisting"><span class="returnvalue">void</span>
-hb_font_set_face (<em class="parameter"><code><a class="link" href="harfbuzz-hb-font.html#hb-font-t" title="hb_font_t"><span class="type">hb_font_t</span></a> *font</code></em>,
-                  <em class="parameter"><code><a class="link" href="harfbuzz-hb-face.html#hb-face-t" title="hb_face_t"><span class="type">hb_face_t</span></a> *face</code></em>);</pre>
+hb_font_set_face (<em class="parameter"><code><a class="link" href="harfbuzz-hb-font.html#hb-font-t"><span class="type">hb_font_t</span></a> *font</code></em>,
+                  <em class="parameter"><code><a class="link" href="harfbuzz-hb-face.html#hb-face-t"><span class="type">hb_face_t</span></a> *face</code></em>);</pre>
 <p>Sets font-face of <em class="parameter"><code>font</code></em>
 .</p>
 <div class="refsect3">
@@ -2551,8 +2744,8 @@ hb_font_set_face (<em class="parameter"><code><a class="link" href="harfbuzz-hb-
 <div class="refsect2">
 <a name="hb-font-set-funcs"></a><h3>hb_font_set_funcs ()</h3>
 <pre class="programlisting"><span class="returnvalue">void</span>
-hb_font_set_funcs (<em class="parameter"><code><a class="link" href="harfbuzz-hb-font.html#hb-font-t" title="hb_font_t"><span class="type">hb_font_t</span></a> *font</code></em>,
-                   <em class="parameter"><code><a class="link" href="harfbuzz-hb-font.html#hb-font-funcs-t" title="hb_font_funcs_t"><span class="type">hb_font_funcs_t</span></a> *klass</code></em>,
+hb_font_set_funcs (<em class="parameter"><code><a class="link" href="harfbuzz-hb-font.html#hb-font-t"><span class="type">hb_font_t</span></a> *font</code></em>,
+                   <em class="parameter"><code><a class="link" href="harfbuzz-hb-font.html#hb-font-funcs-t"><span class="type">hb_font_funcs_t</span></a> *klass</code></em>,
                    <em class="parameter"><code><span class="type">void</span> *font_data</code></em>,
                    <em class="parameter"><code><a class="link" href="harfbuzz-hb-common.html#hb-destroy-func-t" title="hb_destroy_func_t ()"><span class="type">hb_destroy_func_t</span></a> destroy</code></em>);</pre>
 <div class="refsect3">
@@ -2583,7 +2776,7 @@ hb_font_set_funcs (<em class="parameter"><code><a class="link" href="harfbuzz-hb
 <div class="refsect2">
 <a name="hb-font-set-funcs-data"></a><h3>hb_font_set_funcs_data ()</h3>
 <pre class="programlisting"><span class="returnvalue">void</span>
-hb_font_set_funcs_data (<em class="parameter"><code><a class="link" href="harfbuzz-hb-font.html#hb-font-t" title="hb_font_t"><span class="type">hb_font_t</span></a> *font</code></em>,
+hb_font_set_funcs_data (<em class="parameter"><code><a class="link" href="harfbuzz-hb-font.html#hb-font-t"><span class="type">hb_font_t</span></a> *font</code></em>,
                         <em class="parameter"><code><span class="type">void</span> *font_data</code></em>,
                         <em class="parameter"><code><a class="link" href="harfbuzz-hb-common.html#hb-destroy-func-t" title="hb_destroy_func_t ()"><span class="type">hb_destroy_func_t</span></a> destroy</code></em>);</pre>
 <div class="refsect3">
@@ -2614,8 +2807,8 @@ hb_font_set_funcs_data (<em class="parameter"><code><a class="link" href="harfbu
 <div class="refsect2">
 <a name="hb-font-set-parent"></a><h3>hb_font_set_parent ()</h3>
 <pre class="programlisting"><span class="returnvalue">void</span>
-hb_font_set_parent (<em class="parameter"><code><a class="link" href="harfbuzz-hb-font.html#hb-font-t" title="hb_font_t"><span class="type">hb_font_t</span></a> *font</code></em>,
-                    <em class="parameter"><code><a class="link" href="harfbuzz-hb-font.html#hb-font-t" title="hb_font_t"><span class="type">hb_font_t</span></a> *parent</code></em>);</pre>
+hb_font_set_parent (<em class="parameter"><code><a class="link" href="harfbuzz-hb-font.html#hb-font-t"><span class="type">hb_font_t</span></a> *font</code></em>,
+                    <em class="parameter"><code><a class="link" href="harfbuzz-hb-font.html#hb-font-t"><span class="type">hb_font_t</span></a> *parent</code></em>);</pre>
 <p>Sets parent font of <em class="parameter"><code>font</code></em>
 .</p>
 <div class="refsect3">
@@ -2646,7 +2839,7 @@ hb_font_set_parent (<em class="parameter"><code><a class="link" href="harfbuzz-h
 <div class="refsect2">
 <a name="hb-font-set-ppem"></a><h3>hb_font_set_ppem ()</h3>
 <pre class="programlisting"><span class="returnvalue">void</span>
-hb_font_set_ppem (<em class="parameter"><code><a class="link" href="harfbuzz-hb-font.html#hb-font-t" title="hb_font_t"><span class="type">hb_font_t</span></a> *font</code></em>,
+hb_font_set_ppem (<em class="parameter"><code><a class="link" href="harfbuzz-hb-font.html#hb-font-t"><span class="type">hb_font_t</span></a> *font</code></em>,
                   <em class="parameter"><code>unsigned <span class="type">int</span> x_ppem</code></em>,
                   <em class="parameter"><code>unsigned <span class="type">int</span> y_ppem</code></em>);</pre>
 <div class="refsect3">
@@ -2670,7 +2863,7 @@ hb_font_set_ppem (<em class="parameter"><code><a class="link" href="harfbuzz-hb-
 <div class="refsect2">
 <a name="hb-font-set-ptem"></a><h3>hb_font_set_ptem ()</h3>
 <pre class="programlisting"><span class="returnvalue">void</span>
-hb_font_set_ptem (<em class="parameter"><code><a class="link" href="harfbuzz-hb-font.html#hb-font-t" title="hb_font_t"><span class="type">hb_font_t</span></a> *font</code></em>,
+hb_font_set_ptem (<em class="parameter"><code><a class="link" href="harfbuzz-hb-font.html#hb-font-t"><span class="type">hb_font_t</span></a> *font</code></em>,
                   <em class="parameter"><code><span class="type">float</span> ptem</code></em>);</pre>
 <p>Sets "point size" of the font.  Set to 0 to unset.</p>
 <p>There are 72 points in an inch.</p>
@@ -2702,7 +2895,7 @@ hb_font_set_ptem (<em class="parameter"><code><a class="link" href="harfbuzz-hb-
 <div class="refsect2">
 <a name="hb-font-set-scale"></a><h3>hb_font_set_scale ()</h3>
 <pre class="programlisting"><span class="returnvalue">void</span>
-hb_font_set_scale (<em class="parameter"><code><a class="link" href="harfbuzz-hb-font.html#hb-font-t" title="hb_font_t"><span class="type">hb_font_t</span></a> *font</code></em>,
+hb_font_set_scale (<em class="parameter"><code><a class="link" href="harfbuzz-hb-font.html#hb-font-t"><span class="type">hb_font_t</span></a> *font</code></em>,
                    <em class="parameter"><code><span class="type">int</span> x_scale</code></em>,
                    <em class="parameter"><code><span class="type">int</span> y_scale</code></em>);</pre>
 <div class="refsect3">
@@ -2726,8 +2919,8 @@ hb_font_set_scale (<em class="parameter"><code><a class="link" href="harfbuzz-hb
 <div class="refsect2">
 <a name="hb-font-set-user-data"></a><h3>hb_font_set_user_data ()</h3>
 <pre class="programlisting"><a class="link" href="harfbuzz-hb-common.html#hb-bool-t" title="hb_bool_t"><span class="returnvalue">hb_bool_t</span></a>
-hb_font_set_user_data (<em class="parameter"><code><a class="link" href="harfbuzz-hb-font.html#hb-font-t" title="hb_font_t"><span class="type">hb_font_t</span></a> *font</code></em>,
-                       <em class="parameter"><code><a class="link" href="harfbuzz-hb-common.html#hb-user-data-key-t" title="hb_user_data_key_t"><span class="type">hb_user_data_key_t</span></a> *key</code></em>,
+hb_font_set_user_data (<em class="parameter"><code><a class="link" href="harfbuzz-hb-font.html#hb-font-t"><span class="type">hb_font_t</span></a> *font</code></em>,
+                       <em class="parameter"><code><a class="link" href="harfbuzz-hb-common.html#hb-user-data-key-t"><span class="type">hb_user_data_key_t</span></a> *key</code></em>,
                        <em class="parameter"><code><span class="type">void</span> *data</code></em>,
                        <em class="parameter"><code><a class="link" href="harfbuzz-hb-common.html#hb-destroy-func-t" title="hb_destroy_func_t ()"><span class="type">hb_destroy_func_t</span></a> destroy</code></em>,
                        <em class="parameter"><code><a class="link" href="harfbuzz-hb-common.html#hb-bool-t" title="hb_bool_t"><span class="type">hb_bool_t</span></a> replace</code></em>);</pre>
@@ -2753,7 +2946,7 @@ hb_font_set_user_data (<em class="parameter"><code><a class="link" href="harfbuz
 <div class="refsect2">
 <a name="hb-font-set-variations"></a><h3>hb_font_set_variations ()</h3>
 <pre class="programlisting"><span class="returnvalue">void</span>
-hb_font_set_variations (<em class="parameter"><code><a class="link" href="harfbuzz-hb-font.html#hb-font-t" title="hb_font_t"><span class="type">hb_font_t</span></a> *font</code></em>,
+hb_font_set_variations (<em class="parameter"><code><a class="link" href="harfbuzz-hb-font.html#hb-font-t"><span class="type">hb_font_t</span></a> *font</code></em>,
                         <em class="parameter"><code>const <a class="link" href="harfbuzz-hb-common.html#hb-variation-t" title="hb_variation_t"><span class="type">hb_variation_t</span></a> *variations</code></em>,
                         <em class="parameter"><code>unsigned <span class="type">int</span> variations_length</code></em>);</pre>
 <p class="since">Since: <a class="link" href="api-index-1-4-2.html#api-index-1.4.2">1.4.2</a></p>
@@ -2762,7 +2955,7 @@ hb_font_set_variations (<em class="parameter"><code><a class="link" href="harfbu
 <div class="refsect2">
 <a name="hb-font-set-var-coords-design"></a><h3>hb_font_set_var_coords_design ()</h3>
 <pre class="programlisting"><span class="returnvalue">void</span>
-hb_font_set_var_coords_design (<em class="parameter"><code><a class="link" href="harfbuzz-hb-font.html#hb-font-t" title="hb_font_t"><span class="type">hb_font_t</span></a> *font</code></em>,
+hb_font_set_var_coords_design (<em class="parameter"><code><a class="link" href="harfbuzz-hb-font.html#hb-font-t"><span class="type">hb_font_t</span></a> *font</code></em>,
                                <em class="parameter"><code>const <span class="type">float</span> *coords</code></em>,
                                <em class="parameter"><code>unsigned <span class="type">int</span> coords_length</code></em>);</pre>
 <p class="since">Since: <a class="link" href="api-index-1-4-2.html#api-index-1.4.2">1.4.2</a></p>
@@ -2771,17 +2964,48 @@ hb_font_set_var_coords_design (<em class="parameter"><code><a class="link" href=
 <div class="refsect2">
 <a name="hb-font-set-var-coords-normalized"></a><h3>hb_font_set_var_coords_normalized ()</h3>
 <pre class="programlisting"><span class="returnvalue">void</span>
-hb_font_set_var_coords_normalized (<em class="parameter"><code><a class="link" href="harfbuzz-hb-font.html#hb-font-t" title="hb_font_t"><span class="type">hb_font_t</span></a> *font</code></em>,
+hb_font_set_var_coords_normalized (<em class="parameter"><code><a class="link" href="harfbuzz-hb-font.html#hb-font-t"><span class="type">hb_font_t</span></a> *font</code></em>,
                                    <em class="parameter"><code>const <span class="type">int</span> *coords</code></em>,
                                    <em class="parameter"><code>unsigned <span class="type">int</span> coords_length</code></em>);</pre>
 <p class="since">Since: <a class="link" href="api-index-1-4-2.html#api-index-1.4.2">1.4.2</a></p>
 </div>
 <hr>
 <div class="refsect2">
+<a name="hb-font-set-var-named-instance"></a><h3>hb_font_set_var_named_instance ()</h3>
+<pre class="programlisting"><span class="returnvalue">void</span>
+hb_font_set_var_named_instance (<em class="parameter"><code><a class="link" href="harfbuzz-hb-font.html#hb-font-t"><span class="type">hb_font_t</span></a> *font</code></em>,
+                                <em class="parameter"><code><span class="type">unsigned </span> instance_index</code></em>);</pre>
+<p>Sets design coords of a font from a named instance index.</p>
+<div class="refsect3">
+<a name="hb-font-set-var-named-instance.parameters"></a><h4>Parameters</h4>
+<div class="informaltable"><table class="informaltable" width="100%" border="0">
+<colgroup>
+<col width="150px" class="parameters_name">
+<col class="parameters_description">
+<col width="200px" class="parameters_annotations">
+</colgroup>
+<tbody>
+<tr>
+<td class="parameter_name"><p>font</p></td>
+<td class="parameter_description"><p>a font.</p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+<tr>
+<td class="parameter_name"><p>instance_index</p></td>
+<td class="parameter_description"><p>named instance index.</p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+</tbody>
+</table></div>
+</div>
+<p class="since">Since: <a class="link" href="api-index-2-6-0.html#api-index-2.6.0">2.6.0</a></p>
+</div>
+<hr>
+<div class="refsect2">
 <a name="hb-font-subtract-glyph-origin-for-direction"></a><h3>hb_font_subtract_glyph_origin_for_direction ()</h3>
 <pre class="programlisting"><span class="returnvalue">void</span>
 hb_font_subtract_glyph_origin_for_direction
-                               (<em class="parameter"><code><a class="link" href="harfbuzz-hb-font.html#hb-font-t" title="hb_font_t"><span class="type">hb_font_t</span></a> *font</code></em>,
+                               (<em class="parameter"><code><a class="link" href="harfbuzz-hb-font.html#hb-font-t"><span class="type">hb_font_t</span></a> *font</code></em>,
                                 <em class="parameter"><code><a class="link" href="harfbuzz-hb-common.html#hb-codepoint-t" title="hb_codepoint_t"><span class="type">hb_codepoint_t</span></a> glyph</code></em>,
                                 <em class="parameter"><code><a class="link" href="harfbuzz-hb-common.html#hb-direction-t" title="enum hb_direction_t"><span class="type">hb_direction_t</span></a> direction</code></em>,
                                 <em class="parameter"><code><a class="link" href="harfbuzz-hb-common.html#hb-position-t" title="hb_position_t"><span class="type">hb_position_t</span></a> *x</code></em>,
@@ -2818,8 +3042,8 @@ hb_font_subtract_glyph_origin_for_direction
 <hr>
 <div class="refsect2">
 <a name="hb-reference-table-func-t"></a><h3>hb_reference_table_func_t ()</h3>
-<pre class="programlisting"><a class="link" href="harfbuzz-hb-blob.html#hb-blob-t" title="hb_blob_t"><span class="returnvalue">hb_blob_t</span></a> *
-<span class="c_punctuation">(</span>*hb_reference_table_func_t<span class="c_punctuation">)</span> (<em class="parameter"><code><a class="link" href="harfbuzz-hb-face.html#hb-face-t" title="hb_face_t"><span class="type">hb_face_t</span></a> *face</code></em>,
+<pre class="programlisting"><a class="link" href="harfbuzz-hb-blob.html#hb-blob-t"><span class="returnvalue">hb_blob_t</span></a> *
+<span class="c_punctuation">(</span>*hb_reference_table_func_t<span class="c_punctuation">)</span> (<em class="parameter"><code><a class="link" href="harfbuzz-hb-face.html#hb-face-t"><span class="type">hb_face_t</span></a> *face</code></em>,
                               <em class="parameter"><code><a class="link" href="harfbuzz-hb-common.html#hb-tag-t" title="hb_tag_t"><span class="type">hb_tag_t</span></a> tag</code></em>,
                               <em class="parameter"><code><span class="type">void</span> *user_data</code></em>);</pre>
 </div>
@@ -2827,7 +3051,7 @@ hb_font_subtract_glyph_origin_for_direction
 <div class="refsect2">
 <a name="hb-font-funcs-set-font-h-extents-func"></a><h3>hb_font_funcs_set_font_h_extents_func ()</h3>
 <pre class="programlisting"><span class="returnvalue">void</span>
-hb_font_funcs_set_font_h_extents_func (<em class="parameter"><code><a class="link" href="harfbuzz-hb-font.html#hb-font-funcs-t" title="hb_font_funcs_t"><span class="type">hb_font_funcs_t</span></a> *ffuncs</code></em>,
+hb_font_funcs_set_font_h_extents_func (<em class="parameter"><code><a class="link" href="harfbuzz-hb-font.html#hb-font-funcs-t"><span class="type">hb_font_funcs_t</span></a> *ffuncs</code></em>,
                                        <em class="parameter"><code><a class="link" href="harfbuzz-hb-font.html#hb-font-get-font-h-extents-func-t" title="hb_font_get_font_h_extents_func_t"><span class="type">hb_font_get_font_h_extents_func_t</span></a> func</code></em>,
                                        <em class="parameter"><code><span class="type">void</span> *user_data</code></em>,
                                        <em class="parameter"><code><a class="link" href="harfbuzz-hb-common.html#hb-destroy-func-t" title="hb_destroy_func_t ()"><span class="type">hb_destroy_func_t</span></a> destroy</code></em>);</pre>
@@ -2859,7 +3083,7 @@ hb_font_funcs_set_font_h_extents_func (<em class="parameter"><code><a class="lin
 <div class="refsect2">
 <a name="hb-font-funcs-set-font-v-extents-func"></a><h3>hb_font_funcs_set_font_v_extents_func ()</h3>
 <pre class="programlisting"><span class="returnvalue">void</span>
-hb_font_funcs_set_font_v_extents_func (<em class="parameter"><code><a class="link" href="harfbuzz-hb-font.html#hb-font-funcs-t" title="hb_font_funcs_t"><span class="type">hb_font_funcs_t</span></a> *ffuncs</code></em>,
+hb_font_funcs_set_font_v_extents_func (<em class="parameter"><code><a class="link" href="harfbuzz-hb-font.html#hb-font-funcs-t"><span class="type">hb_font_funcs_t</span></a> *ffuncs</code></em>,
                                        <em class="parameter"><code><a class="link" href="harfbuzz-hb-font.html#hb-font-get-font-v-extents-func-t" title="hb_font_get_font_v_extents_func_t"><span class="type">hb_font_get_font_v_extents_func_t</span></a> func</code></em>,
                                        <em class="parameter"><code><span class="type">void</span> *user_data</code></em>,
                                        <em class="parameter"><code><a class="link" href="harfbuzz-hb-common.html#hb-destroy-func-t" title="hb_destroy_func_t ()"><span class="type">hb_destroy_func_t</span></a> destroy</code></em>);</pre>
@@ -2891,7 +3115,7 @@ hb_font_funcs_set_font_v_extents_func (<em class="parameter"><code><a class="lin
 <div class="refsect2">
 <a name="hb-font-get-extents-for-direction"></a><h3>hb_font_get_extents_for_direction ()</h3>
 <pre class="programlisting"><span class="returnvalue">void</span>
-hb_font_get_extents_for_direction (<em class="parameter"><code><a class="link" href="harfbuzz-hb-font.html#hb-font-t" title="hb_font_t"><span class="type">hb_font_t</span></a> *font</code></em>,
+hb_font_get_extents_for_direction (<em class="parameter"><code><a class="link" href="harfbuzz-hb-font.html#hb-font-t"><span class="type">hb_font_t</span></a> *font</code></em>,
                                    <em class="parameter"><code><a class="link" href="harfbuzz-hb-common.html#hb-direction-t" title="enum hb_direction_t"><span class="type">hb_direction_t</span></a> direction</code></em>,
                                    <em class="parameter"><code><span class="type">hb_font_extents_t</span> *extents</code></em>);</pre>
 <div class="refsect3">
@@ -2922,7 +3146,7 @@ hb_font_get_extents_for_direction (<em class="parameter"><code><a class="link" h
 <div class="refsect2">
 <a name="hb-font-get-font-extents-func-t"></a><h3>hb_font_get_font_extents_func_t ()</h3>
 <pre class="programlisting"><a class="link" href="harfbuzz-hb-common.html#hb-bool-t" title="hb_bool_t"><span class="returnvalue">hb_bool_t</span></a>
-<span class="c_punctuation">(</span>*hb_font_get_font_extents_func_t<span class="c_punctuation">)</span> (<em class="parameter"><code><a class="link" href="harfbuzz-hb-font.html#hb-font-t" title="hb_font_t"><span class="type">hb_font_t</span></a> *font</code></em>,
+<span class="c_punctuation">(</span>*hb_font_get_font_extents_func_t<span class="c_punctuation">)</span> (<em class="parameter"><code><a class="link" href="harfbuzz-hb-font.html#hb-font-t"><span class="type">hb_font_t</span></a> *font</code></em>,
                                     <em class="parameter"><code><span class="type">void</span> *font_data</code></em>,
                                     <em class="parameter"><code><span class="type">hb_font_extents_t</span> *extents</code></em>,
                                     <em class="parameter"><code><span class="type">void</span> *user_data</code></em>);</pre>
@@ -2931,7 +3155,7 @@ hb_font_get_extents_for_direction (<em class="parameter"><code><a class="link" h
 <div class="refsect2">
 <a name="hb-font-get-h-extents"></a><h3>hb_font_get_h_extents ()</h3>
 <pre class="programlisting"><a class="link" href="harfbuzz-hb-common.html#hb-bool-t" title="hb_bool_t"><span class="returnvalue">hb_bool_t</span></a>
-hb_font_get_h_extents (<em class="parameter"><code><a class="link" href="harfbuzz-hb-font.html#hb-font-t" title="hb_font_t"><span class="type">hb_font_t</span></a> *font</code></em>,
+hb_font_get_h_extents (<em class="parameter"><code><a class="link" href="harfbuzz-hb-font.html#hb-font-t"><span class="type">hb_font_t</span></a> *font</code></em>,
                        <em class="parameter"><code><span class="type">hb_font_extents_t</span> *extents</code></em>);</pre>
 <div class="refsect3">
 <a name="hb-font-get-h-extents.parameters"></a><h4>Parameters</h4>
@@ -2961,7 +3185,7 @@ hb_font_get_h_extents (<em class="parameter"><code><a class="link" href="harfbuz
 <div class="refsect2">
 <a name="hb-font-get-v-extents"></a><h3>hb_font_get_v_extents ()</h3>
 <pre class="programlisting"><a class="link" href="harfbuzz-hb-common.html#hb-bool-t" title="hb_bool_t"><span class="returnvalue">hb_bool_t</span></a>
-hb_font_get_v_extents (<em class="parameter"><code><a class="link" href="harfbuzz-hb-font.html#hb-font-t" title="hb_font_t"><span class="type">hb_font_t</span></a> *font</code></em>,
+hb_font_get_v_extents (<em class="parameter"><code><a class="link" href="harfbuzz-hb-font.html#hb-font-t"><span class="type">hb_font_t</span></a> *font</code></em>,
                        <em class="parameter"><code><span class="type">hb_font_extents_t</span> *extents</code></em>);</pre>
 <div class="refsect3">
 <a name="hb-font-get-v-extents.parameters"></a><h4>Parameters</h4>
@@ -3009,6 +3233,12 @@ hb_font_get_v_extents (<em class="parameter"><code><a class="link" href="harfbuz
 </div>
 <hr>
 <div class="refsect2">
+<a name="hb-font-get-glyph-h-kerning-func-t"></a><h3>hb_font_get_glyph_h_kerning_func_t</h3>
+<pre class="programlisting">typedef hb_font_get_glyph_kerning_func_t hb_font_get_glyph_h_kerning_func_t;
+</pre>
+</div>
+<hr>
+<div class="refsect2">
 <a name="hb-font-get-glyph-h-origin-func-t"></a><h3>hb_font_get_glyph_h_origin_func_t</h3>
 <pre class="programlisting">typedef hb_font_get_glyph_origin_func_t hb_font_get_glyph_h_origin_func_t;
 </pre>
index dbc1f41..06884b7 100644 (file)
@@ -5,7 +5,7 @@
 <title>hb-ft: HarfBuzz Manual</title>
 <meta name="generator" content="DocBook XSL Stylesheets Vsnapshot">
 <link rel="home" href="index.html" title="HarfBuzz Manual">
-<link rel="up" href="ch12.html" title="Integration API">
+<link rel="up" href="ch14.html" title="Integration API">
 <link rel="prev" href="harfbuzz-hb-coretext.html" title="hb-coretext">
 <link rel="next" href="harfbuzz-hb-glib.html" title="hb-glib">
 <meta name="generator" content="GTK-Doc V1.29 (XML mode)">
@@ -18,7 +18,7 @@
                   <a href="#harfbuzz-hb-ft.description" class="shortcut">Description</a></span>
 </td>
 <td><a accesskey="h" href="index.html"><img src="home.png" width="16" height="16" border="0" alt="Home"></a></td>
-<td><a accesskey="u" href="ch12.html"><img src="up.png" width="16" height="16" border="0" alt="Up"></a></td>
+<td><a accesskey="u" href="ch14.html"><img src="up.png" width="16" height="16" border="0" alt="Up"></a></td>
 <td><a accesskey="p" href="harfbuzz-hb-coretext.html"><img src="left.png" width="16" height="16" border="0" alt="Prev"></a></td>
 <td><a accesskey="n" href="harfbuzz-hb-glib.html"><img src="right.png" width="16" height="16" border="0" alt="Next"></a></td>
 </tr></table>
@@ -41,7 +41,7 @@
 <tbody>
 <tr>
 <td class="function_type">
-<a class="link" href="harfbuzz-hb-face.html#hb-face-t" title="hb_face_t"><span class="returnvalue">hb_face_t</span></a> *
+<a class="link" href="harfbuzz-hb-face.html#hb-face-t"><span class="returnvalue">hb_face_t</span></a> *
 </td>
 <td class="function_name">
 <a class="link" href="harfbuzz-hb-ft.html#hb-ft-face-create" title="hb_ft_face_create ()">hb_ft_face_create</a> <span class="c_punctuation">()</span>
@@ -49,7 +49,7 @@
 </tr>
 <tr>
 <td class="function_type">
-<a class="link" href="harfbuzz-hb-face.html#hb-face-t" title="hb_face_t"><span class="returnvalue">hb_face_t</span></a> *
+<a class="link" href="harfbuzz-hb-face.html#hb-face-t"><span class="returnvalue">hb_face_t</span></a> *
 </td>
 <td class="function_name">
 <a class="link" href="harfbuzz-hb-ft.html#hb-ft-face-create-cached" title="hb_ft_face_create_cached ()">hb_ft_face_create_cached</a> <span class="c_punctuation">()</span>
@@ -57,7 +57,7 @@
 </tr>
 <tr>
 <td class="function_type">
-<a class="link" href="harfbuzz-hb-face.html#hb-face-t" title="hb_face_t"><span class="returnvalue">hb_face_t</span></a> *
+<a class="link" href="harfbuzz-hb-face.html#hb-face-t"><span class="returnvalue">hb_face_t</span></a> *
 </td>
 <td class="function_name">
 <a class="link" href="harfbuzz-hb-ft.html#hb-ft-face-create-referenced" title="hb_ft_face_create_referenced ()">hb_ft_face_create_referenced</a> <span class="c_punctuation">()</span>
@@ -65,7 +65,7 @@
 </tr>
 <tr>
 <td class="function_type">
-<a class="link" href="harfbuzz-hb-font.html#hb-font-t" title="hb_font_t"><span class="returnvalue">hb_font_t</span></a> *
+<a class="link" href="harfbuzz-hb-font.html#hb-font-t"><span class="returnvalue">hb_font_t</span></a> *
 </td>
 <td class="function_name">
 <a class="link" href="harfbuzz-hb-ft.html#hb-ft-font-create" title="hb_ft_font_create ()">hb_ft_font_create</a> <span class="c_punctuation">()</span>
@@ -73,7 +73,7 @@
 </tr>
 <tr>
 <td class="function_type">
-<a class="link" href="harfbuzz-hb-font.html#hb-font-t" title="hb_font_t"><span class="returnvalue">hb_font_t</span></a> *
+<a class="link" href="harfbuzz-hb-font.html#hb-font-t"><span class="returnvalue">hb_font_t</span></a> *
 </td>
 <td class="function_name">
 <a class="link" href="harfbuzz-hb-ft.html#hb-ft-font-create-referenced" title="hb_ft_font_create_referenced ()">hb_ft_font_create_referenced</a> <span class="c_punctuation">()</span>
@@ -136,7 +136,7 @@ font data.</p>
 <a name="harfbuzz-hb-ft.functions_details"></a><h2>Functions</h2>
 <div class="refsect2">
 <a name="hb-ft-face-create"></a><h3>hb_ft_face_create ()</h3>
-<pre class="programlisting"><a class="link" href="harfbuzz-hb-face.html#hb-face-t" title="hb_face_t"><span class="returnvalue">hb_face_t</span></a> *
+<pre class="programlisting"><a class="link" href="harfbuzz-hb-face.html#hb-face-t"><span class="returnvalue">hb_face_t</span></a> *
 hb_ft_face_create (<em class="parameter"><code><span class="type">FT_Face</span> ft_face</code></em>,
                    <em class="parameter"><code><a class="link" href="harfbuzz-hb-common.html#hb-destroy-func-t" title="hb_destroy_func_t ()"><span class="type">hb_destroy_func_t</span></a> destroy</code></em>);</pre>
 <div class="refsect3">
@@ -164,7 +164,7 @@ hb_ft_face_create (<em class="parameter"><code><span class="type">FT_Face</span>
 <hr>
 <div class="refsect2">
 <a name="hb-ft-face-create-cached"></a><h3>hb_ft_face_create_cached ()</h3>
-<pre class="programlisting"><a class="link" href="harfbuzz-hb-face.html#hb-face-t" title="hb_face_t"><span class="returnvalue">hb_face_t</span></a> *
+<pre class="programlisting"><a class="link" href="harfbuzz-hb-face.html#hb-face-t"><span class="returnvalue">hb_face_t</span></a> *
 hb_ft_face_create_cached (<em class="parameter"><code><span class="type">FT_Face</span> ft_face</code></em>);</pre>
 <div class="refsect3">
 <a name="hb-ft-face-create-cached.returns"></a><h4>Returns</h4>
@@ -176,7 +176,7 @@ hb_ft_face_create_cached (<em class="parameter"><code><span class="type">FT_Face
 <hr>
 <div class="refsect2">
 <a name="hb-ft-face-create-referenced"></a><h3>hb_ft_face_create_referenced ()</h3>
-<pre class="programlisting"><a class="link" href="harfbuzz-hb-face.html#hb-face-t" title="hb_face_t"><span class="returnvalue">hb_face_t</span></a> *
+<pre class="programlisting"><a class="link" href="harfbuzz-hb-face.html#hb-face-t"><span class="returnvalue">hb_face_t</span></a> *
 hb_ft_face_create_referenced (<em class="parameter"><code><span class="type">FT_Face</span> ft_face</code></em>);</pre>
 <div class="refsect3">
 <a name="hb-ft-face-create-referenced.returns"></a><h4>Returns</h4>
@@ -188,7 +188,7 @@ hb_ft_face_create_referenced (<em class="parameter"><code><span class="type">FT_
 <hr>
 <div class="refsect2">
 <a name="hb-ft-font-create"></a><h3>hb_ft_font_create ()</h3>
-<pre class="programlisting"><a class="link" href="harfbuzz-hb-font.html#hb-font-t" title="hb_font_t"><span class="returnvalue">hb_font_t</span></a> *
+<pre class="programlisting"><a class="link" href="harfbuzz-hb-font.html#hb-font-t"><span class="returnvalue">hb_font_t</span></a> *
 hb_ft_font_create (<em class="parameter"><code><span class="type">FT_Face</span> ft_face</code></em>,
                    <em class="parameter"><code><a class="link" href="harfbuzz-hb-common.html#hb-destroy-func-t" title="hb_destroy_func_t ()"><span class="type">hb_destroy_func_t</span></a> destroy</code></em>);</pre>
 <div class="refsect3">
@@ -216,7 +216,7 @@ hb_ft_font_create (<em class="parameter"><code><span class="type">FT_Face</span>
 <hr>
 <div class="refsect2">
 <a name="hb-ft-font-create-referenced"></a><h3>hb_ft_font_create_referenced ()</h3>
-<pre class="programlisting"><a class="link" href="harfbuzz-hb-font.html#hb-font-t" title="hb_font_t"><span class="returnvalue">hb_font_t</span></a> *
+<pre class="programlisting"><a class="link" href="harfbuzz-hb-font.html#hb-font-t"><span class="returnvalue">hb_font_t</span></a> *
 hb_ft_font_create_referenced (<em class="parameter"><code><span class="type">FT_Face</span> ft_face</code></em>);</pre>
 <div class="refsect3">
 <a name="hb-ft-font-create-referenced.returns"></a><h4>Returns</h4>
@@ -229,19 +229,19 @@ hb_ft_font_create_referenced (<em class="parameter"><code><span class="type">FT_
 <div class="refsect2">
 <a name="hb-ft-font-changed"></a><h3>hb_ft_font_changed ()</h3>
 <pre class="programlisting"><span class="returnvalue">void</span>
-hb_ft_font_changed (<em class="parameter"><code><a class="link" href="harfbuzz-hb-font.html#hb-font-t" title="hb_font_t"><span class="type">hb_font_t</span></a> *font</code></em>);</pre>
+hb_ft_font_changed (<em class="parameter"><code><a class="link" href="harfbuzz-hb-font.html#hb-font-t"><span class="type">hb_font_t</span></a> *font</code></em>);</pre>
 </div>
 <hr>
 <div class="refsect2">
 <a name="hb-ft-font-get-face"></a><h3>hb_ft_font_get_face ()</h3>
 <pre class="programlisting"><span class="returnvalue">FT_Face</span>
-hb_ft_font_get_face (<em class="parameter"><code><a class="link" href="harfbuzz-hb-font.html#hb-font-t" title="hb_font_t"><span class="type">hb_font_t</span></a> *font</code></em>);</pre>
+hb_ft_font_get_face (<em class="parameter"><code><a class="link" href="harfbuzz-hb-font.html#hb-font-t"><span class="type">hb_font_t</span></a> *font</code></em>);</pre>
 </div>
 <hr>
 <div class="refsect2">
 <a name="hb-ft-font-set-load-flags"></a><h3>hb_ft_font_set_load_flags ()</h3>
 <pre class="programlisting"><span class="returnvalue">void</span>
-hb_ft_font_set_load_flags (<em class="parameter"><code><a class="link" href="harfbuzz-hb-font.html#hb-font-t" title="hb_font_t"><span class="type">hb_font_t</span></a> *font</code></em>,
+hb_ft_font_set_load_flags (<em class="parameter"><code><a class="link" href="harfbuzz-hb-font.html#hb-font-t"><span class="type">hb_font_t</span></a> *font</code></em>,
                            <em class="parameter"><code><span class="type">int</span> load_flags</code></em>);</pre>
 <p class="since">Since: <a class="link" href="api-index-1-0-5.html#api-index-1.0.5">1.0.5</a></p>
 </div>
@@ -249,14 +249,14 @@ hb_ft_font_set_load_flags (<em class="parameter"><code><a class="link" href="har
 <div class="refsect2">
 <a name="hb-ft-font-get-load-flags"></a><h3>hb_ft_font_get_load_flags ()</h3>
 <pre class="programlisting"><span class="returnvalue">int</span>
-hb_ft_font_get_load_flags (<em class="parameter"><code><a class="link" href="harfbuzz-hb-font.html#hb-font-t" title="hb_font_t"><span class="type">hb_font_t</span></a> *font</code></em>);</pre>
+hb_ft_font_get_load_flags (<em class="parameter"><code><a class="link" href="harfbuzz-hb-font.html#hb-font-t"><span class="type">hb_font_t</span></a> *font</code></em>);</pre>
 <p class="since">Since: <a class="link" href="api-index-1-0-5.html#api-index-1.0.5">1.0.5</a></p>
 </div>
 <hr>
 <div class="refsect2">
 <a name="hb-ft-font-set-funcs"></a><h3>hb_ft_font_set_funcs ()</h3>
 <pre class="programlisting"><span class="returnvalue">void</span>
-hb_ft_font_set_funcs (<em class="parameter"><code><a class="link" href="harfbuzz-hb-font.html#hb-font-t" title="hb_font_t"><span class="type">hb_font_t</span></a> *font</code></em>);</pre>
+hb_ft_font_set_funcs (<em class="parameter"><code><a class="link" href="harfbuzz-hb-font.html#hb-font-t"><span class="type">hb_font_t</span></a> *font</code></em>);</pre>
 </div>
 </div>
 <div class="refsect1">
index 2cfc4f2..2cbf3bd 100644 (file)
@@ -5,7 +5,7 @@
 <title>hb-glib: HarfBuzz Manual</title>
 <meta name="generator" content="DocBook XSL Stylesheets Vsnapshot">
 <link rel="home" href="index.html" title="HarfBuzz Manual">
-<link rel="up" href="ch12.html" title="Integration API">
+<link rel="up" href="ch14.html" title="Integration API">
 <link rel="prev" href="harfbuzz-hb-ft.html" title="hb-ft">
 <link rel="next" href="harfbuzz-hb-gobject.html" title="hb-gobject">
 <meta name="generator" content="GTK-Doc V1.29 (XML mode)">
@@ -18,7 +18,7 @@
                   <a href="#harfbuzz-hb-glib.description" class="shortcut">Description</a></span>
 </td>
 <td><a accesskey="h" href="index.html"><img src="home.png" width="16" height="16" border="0" alt="Home"></a></td>
-<td><a accesskey="u" href="ch12.html"><img src="up.png" width="16" height="16" border="0" alt="Up"></a></td>
+<td><a accesskey="u" href="ch14.html"><img src="up.png" width="16" height="16" border="0" alt="Up"></a></td>
 <td><a accesskey="p" href="harfbuzz-hb-ft.html"><img src="left.png" width="16" height="16" border="0" alt="Prev"></a></td>
 <td><a accesskey="n" href="harfbuzz-hb-gobject.html"><img src="right.png" width="16" height="16" border="0" alt="Next"></a></td>
 </tr></table>
@@ -41,7 +41,7 @@
 <tbody>
 <tr>
 <td class="function_type">
-<a class="link" href="harfbuzz-hb-unicode.html#hb-unicode-funcs-t" title="hb_unicode_funcs_t"><span class="returnvalue">hb_unicode_funcs_t</span></a> *
+<a class="link" href="harfbuzz-hb-unicode.html#hb-unicode-funcs-t"><span class="returnvalue">hb_unicode_funcs_t</span></a> *
 </td>
 <td class="function_name">
 <a class="link" href="harfbuzz-hb-glib.html#hb-glib-get-unicode-funcs" title="hb_glib_get_unicode_funcs ()">hb_glib_get_unicode_funcs</a> <span class="c_punctuation">()</span>
@@ -49,7 +49,7 @@
 </tr>
 <tr>
 <td class="function_type">
-<a href="/usr/share/gtk-doc/html/glib/glib-Unicode-Manipulation.html#GUnicodeScript"><span class="returnvalue">GUnicodeScript</span></a>
+<span class="returnvalue">GUnicodeScript</span>
 </td>
 <td class="function_name">
 <a class="link" href="harfbuzz-hb-glib.html#hb-glib-script-from-script" title="hb_glib_script_from_script ()">hb_glib_script_from_script</a> <span class="c_punctuation">()</span>
@@ -65,7 +65,7 @@
 </tr>
 <tr>
 <td class="function_type">
-<a class="link" href="harfbuzz-hb-blob.html#hb-blob-t" title="hb_blob_t"><span class="returnvalue">hb_blob_t</span></a> *
+<a class="link" href="harfbuzz-hb-blob.html#hb-blob-t"><span class="returnvalue">hb_blob_t</span></a> *
 </td>
 <td class="function_name">
 <a class="link" href="harfbuzz-hb-glib.html#hb-glib-blob-create" title="hb_glib_blob_create ()">hb_glib_blob_create</a> <span class="c_punctuation">()</span>
 <a name="harfbuzz-hb-glib.functions_details"></a><h2>Functions</h2>
 <div class="refsect2">
 <a name="hb-glib-get-unicode-funcs"></a><h3>hb_glib_get_unicode_funcs ()</h3>
-<pre class="programlisting"><a class="link" href="harfbuzz-hb-unicode.html#hb-unicode-funcs-t" title="hb_unicode_funcs_t"><span class="returnvalue">hb_unicode_funcs_t</span></a> *
+<pre class="programlisting"><a class="link" href="harfbuzz-hb-unicode.html#hb-unicode-funcs-t"><span class="returnvalue">hb_unicode_funcs_t</span></a> *
 hb_glib_get_unicode_funcs (<em class="parameter"><code><span class="type">void</span></code></em>);</pre>
 </div>
 <hr>
 <div class="refsect2">
 <a name="hb-glib-script-from-script"></a><h3>hb_glib_script_from_script ()</h3>
-<pre class="programlisting"><a href="/usr/share/gtk-doc/html/glib/glib-Unicode-Manipulation.html#GUnicodeScript"><span class="returnvalue">GUnicodeScript</span></a>
+<pre class="programlisting"><span class="returnvalue">GUnicodeScript</span>
 hb_glib_script_from_script (<em class="parameter"><code><a class="link" href="harfbuzz-hb-common.html#hb-script-t" title="enum hb_script_t"><span class="type">hb_script_t</span></a> script</code></em>);</pre>
 </div>
 <hr>
 <div class="refsect2">
 <a name="hb-glib-script-to-script"></a><h3>hb_glib_script_to_script ()</h3>
 <pre class="programlisting"><a class="link" href="harfbuzz-hb-common.html#hb-script-t" title="enum hb_script_t"><span class="returnvalue">hb_script_t</span></a>
-hb_glib_script_to_script (<em class="parameter"><code><a href="/usr/share/gtk-doc/html/glib/glib-Unicode-Manipulation.html#GUnicodeScript"><span class="type">GUnicodeScript</span></a> script</code></em>);</pre>
+hb_glib_script_to_script (<em class="parameter"><code><span class="type">GUnicodeScript</span> script</code></em>);</pre>
 </div>
 <hr>
 <div class="refsect2">
 <a name="hb-glib-blob-create"></a><h3>hb_glib_blob_create ()</h3>
-<pre class="programlisting"><a class="link" href="harfbuzz-hb-blob.html#hb-blob-t" title="hb_blob_t"><span class="returnvalue">hb_blob_t</span></a> *
-hb_glib_blob_create (<em class="parameter"><code><a href="/usr/share/gtk-doc/html/glib/glib-Byte-Arrays.html#GBytes"><span class="type">GBytes</span></a> *gbytes</code></em>);</pre>
+<pre class="programlisting"><a class="link" href="harfbuzz-hb-blob.html#hb-blob-t"><span class="returnvalue">hb_blob_t</span></a> *
+hb_glib_blob_create (<em class="parameter"><code><span class="type">GBytes</span> *gbytes</code></em>);</pre>
 <p class="since">Since: <a class="link" href="api-index-0-9-38.html#api-index-0.9.38">0.9.38</a></p>
 </div>
 </div>
index 60558e8..a733126 100644 (file)
@@ -5,7 +5,7 @@
 <title>hb-gobject: HarfBuzz Manual</title>
 <meta name="generator" content="DocBook XSL Stylesheets Vsnapshot">
 <link rel="home" href="index.html" title="HarfBuzz Manual">
-<link rel="up" href="ch12.html" title="Integration API">
+<link rel="up" href="ch14.html" title="Integration API">
 <link rel="prev" href="harfbuzz-hb-glib.html" title="hb-glib">
 <link rel="next" href="harfbuzz-hb-graphite2.html" title="hb-graphite2">
 <meta name="generator" content="GTK-Doc V1.29 (XML mode)">
@@ -18,7 +18,7 @@
                   <a href="#harfbuzz-hb-gobject.description" class="shortcut">Description</a></span>
 </td>
 <td><a accesskey="h" href="index.html"><img src="home.png" width="16" height="16" border="0" alt="Home"></a></td>
-<td><a accesskey="u" href="ch12.html"><img src="up.png" width="16" height="16" border="0" alt="Up"></a></td>
+<td><a accesskey="u" href="ch14.html"><img src="up.png" width="16" height="16" border="0" alt="Up"></a></td>
 <td><a accesskey="p" href="harfbuzz-hb-glib.html"><img src="left.png" width="16" height="16" border="0" alt="Prev"></a></td>
 <td><a accesskey="n" href="harfbuzz-hb-graphite2.html"><img src="right.png" width="16" height="16" border="0" alt="Next"></a></td>
 </tr></table>
 <td class="gallery_image" valign="top" align="right"></td>
 </tr></table></div>
 <div class="refsect1">
+<a name="harfbuzz-hb-gobject.functions"></a><h2>Functions</h2>
+<div class="informaltable"><table class="informaltable" width="100%" border="0">
+<colgroup>
+<col width="150px" class="functions_return">
+<col class="functions_name">
+</colgroup>
+<tbody>
+<tr>
+<td class="function_type">
+<span class="returnvalue">GType</span>
+</td>
+<td class="function_name">
+<a class="link" href="harfbuzz-hb-gobject.html#hb-gobject-blob-get-type" title="hb_gobject_blob_get_type ()">hb_gobject_blob_get_type</a> <span class="c_punctuation">()</span>
+</td>
+</tr>
+<tr>
+<td class="function_type">
+<span class="returnvalue">GType</span>
+</td>
+<td class="function_name">
+<a class="link" href="harfbuzz-hb-gobject.html#hb-gobject-buffer-content-type-get-type" title="hb_gobject_buffer_content_type_get_type ()">hb_gobject_buffer_content_type_get_type</a> <span class="c_punctuation">()</span>
+</td>
+</tr>
+<tr>
+<td class="function_type">
+<span class="returnvalue">GType</span>
+</td>
+<td class="function_name">
+<a class="link" href="harfbuzz-hb-gobject.html#hb-gobject-buffer-diff-flags-get-type" title="hb_gobject_buffer_diff_flags_get_type ()">hb_gobject_buffer_diff_flags_get_type</a> <span class="c_punctuation">()</span>
+</td>
+</tr>
+<tr>
+<td class="function_type">
+<span class="returnvalue">GType</span>
+</td>
+<td class="function_name">
+<a class="link" href="harfbuzz-hb-gobject.html#hb-gobject-buffer-flags-get-type" title="hb_gobject_buffer_flags_get_type ()">hb_gobject_buffer_flags_get_type</a> <span class="c_punctuation">()</span>
+</td>
+</tr>
+<tr>
+<td class="function_type">
+<span class="returnvalue">GType</span>
+</td>
+<td class="function_name">
+<a class="link" href="harfbuzz-hb-gobject.html#hb-gobject-buffer-get-type" title="hb_gobject_buffer_get_type ()">hb_gobject_buffer_get_type</a> <span class="c_punctuation">()</span>
+</td>
+</tr>
+<tr>
+<td class="function_type">
+<span class="returnvalue">GType</span>
+</td>
+<td class="function_name">
+<a class="link" href="harfbuzz-hb-gobject.html#hb-gobject-buffer-serialize-flags-get-type" title="hb_gobject_buffer_serialize_flags_get_type ()">hb_gobject_buffer_serialize_flags_get_type</a> <span class="c_punctuation">()</span>
+</td>
+</tr>
+<tr>
+<td class="function_type">
+<span class="returnvalue">GType</span>
+</td>
+<td class="function_name">
+<a class="link" href="harfbuzz-hb-gobject.html#hb-gobject-buffer-serialize-format-get-type" title="hb_gobject_buffer_serialize_format_get_type ()">hb_gobject_buffer_serialize_format_get_type</a> <span class="c_punctuation">()</span>
+</td>
+</tr>
+<tr>
+<td class="function_type">
+<span class="returnvalue">GType</span>
+</td>
+<td class="function_name">
+<a class="link" href="harfbuzz-hb-gobject.html#hb-gobject-direction-get-type" title="hb_gobject_direction_get_type ()">hb_gobject_direction_get_type</a> <span class="c_punctuation">()</span>
+</td>
+</tr>
+<tr>
+<td class="function_type">
+<span class="returnvalue">GType</span>
+</td>
+<td class="function_name">
+<a class="link" href="harfbuzz-hb-gobject.html#hb-gobject-face-get-type" title="hb_gobject_face_get_type ()">hb_gobject_face_get_type</a> <span class="c_punctuation">()</span>
+</td>
+</tr>
+<tr>
+<td class="function_type">
+<span class="returnvalue">GType</span>
+</td>
+<td class="function_name">
+<a class="link" href="harfbuzz-hb-gobject.html#hb-gobject-font-funcs-get-type" title="hb_gobject_font_funcs_get_type ()">hb_gobject_font_funcs_get_type</a> <span class="c_punctuation">()</span>
+</td>
+</tr>
+<tr>
+<td class="function_type">
+<span class="returnvalue">GType</span>
+</td>
+<td class="function_name">
+<a class="link" href="harfbuzz-hb-gobject.html#hb-gobject-font-get-type" title="hb_gobject_font_get_type ()">hb_gobject_font_get_type</a> <span class="c_punctuation">()</span>
+</td>
+</tr>
+<tr>
+<td class="function_type">
+<span class="returnvalue">GType</span>
+</td>
+<td class="function_name">
+<a class="link" href="harfbuzz-hb-gobject.html#hb-gobject-glyph-flags-get-type" title="hb_gobject_glyph_flags_get_type ()">hb_gobject_glyph_flags_get_type</a> <span class="c_punctuation">()</span>
+</td>
+</tr>
+<tr>
+<td class="function_type">
+<span class="returnvalue">GType</span>
+</td>
+<td class="function_name">
+<a class="link" href="harfbuzz-hb-gobject.html#hb-gobject-map-get-type" title="hb_gobject_map_get_type ()">hb_gobject_map_get_type</a> <span class="c_punctuation">()</span>
+</td>
+</tr>
+<tr>
+<td class="function_type">
+<span class="returnvalue">GType</span>
+</td>
+<td class="function_name">
+<a class="link" href="harfbuzz-hb-gobject.html#hb-gobject-memory-mode-get-type" title="hb_gobject_memory_mode_get_type ()">hb_gobject_memory_mode_get_type</a> <span class="c_punctuation">()</span>
+</td>
+</tr>
+<tr>
+<td class="function_type">
+<span class="returnvalue">GType</span>
+</td>
+<td class="function_name">
+<a class="link" href="harfbuzz-hb-gobject.html#hb-gobject-ot-color-palette-flags-get-type" title="hb_gobject_ot_color_palette_flags_get_type ()">hb_gobject_ot_color_palette_flags_get_type</a> <span class="c_punctuation">()</span>
+</td>
+</tr>
+<tr>
+<td class="function_type">
+<span class="returnvalue">GType</span>
+</td>
+<td class="function_name">
+<a class="link" href="harfbuzz-hb-gobject.html#hb-gobject-ot-layout-glyph-class-get-type" title="hb_gobject_ot_layout_glyph_class_get_type ()">hb_gobject_ot_layout_glyph_class_get_type</a> <span class="c_punctuation">()</span>
+</td>
+</tr>
+<tr>
+<td class="function_type">
+<span class="returnvalue">GType</span>
+</td>
+<td class="function_name">
+<a class="link" href="harfbuzz-hb-gobject.html#hb-gobject-ot-math-constant-get-type" title="hb_gobject_ot_math_constant_get_type ()">hb_gobject_ot_math_constant_get_type</a> <span class="c_punctuation">()</span>
+</td>
+</tr>
+<tr>
+<td class="function_type">
+<span class="returnvalue">GType</span>
+</td>
+<td class="function_name">
+<a class="link" href="harfbuzz-hb-gobject.html#hb-gobject-ot-math-glyph-part-get-type" title="hb_gobject_ot_math_glyph_part_get_type ()">hb_gobject_ot_math_glyph_part_get_type</a> <span class="c_punctuation">()</span>
+</td>
+</tr>
+<tr>
+<td class="function_type">
+<span class="returnvalue">GType</span>
+</td>
+<td class="function_name">
+<a class="link" href="harfbuzz-hb-gobject.html#hb-gobject-ot-math-glyph-part-flags-get-type" title="hb_gobject_ot_math_glyph_part_flags_get_type ()">hb_gobject_ot_math_glyph_part_flags_get_type</a> <span class="c_punctuation">()</span>
+</td>
+</tr>
+<tr>
+<td class="function_type">
+<span class="returnvalue">GType</span>
+</td>
+<td class="function_name">
+<a class="link" href="harfbuzz-hb-gobject.html#hb-gobject-ot-math-glyph-variant-get-type" title="hb_gobject_ot_math_glyph_variant_get_type ()">hb_gobject_ot_math_glyph_variant_get_type</a> <span class="c_punctuation">()</span>
+</td>
+</tr>
+<tr>
+<td class="function_type">
+<span class="returnvalue">GType</span>
+</td>
+<td class="function_name">
+<a class="link" href="harfbuzz-hb-gobject.html#hb-gobject-ot-math-kern-get-type" title="hb_gobject_ot_math_kern_get_type ()">hb_gobject_ot_math_kern_get_type</a> <span class="c_punctuation">()</span>
+</td>
+</tr>
+<tr>
+<td class="function_type">
+<span class="returnvalue">GType</span>
+</td>
+<td class="function_name">
+<a class="link" href="harfbuzz-hb-gobject.html#hb-gobject-script-get-type" title="hb_gobject_script_get_type ()">hb_gobject_script_get_type</a> <span class="c_punctuation">()</span>
+</td>
+</tr>
+<tr>
+<td class="function_type">
+<span class="returnvalue">GType</span>
+</td>
+<td class="function_name">
+<a class="link" href="harfbuzz-hb-gobject.html#hb-gobject-shape-plan-get-type" title="hb_gobject_shape_plan_get_type ()">hb_gobject_shape_plan_get_type</a> <span class="c_punctuation">()</span>
+</td>
+</tr>
+<tr>
+<td class="function_type">
+<span class="returnvalue">GType</span>
+</td>
+<td class="function_name">
+<a class="link" href="harfbuzz-hb-gobject.html#hb-gobject-unicode-combining-class-get-type" title="hb_gobject_unicode_combining_class_get_type ()">hb_gobject_unicode_combining_class_get_type</a> <span class="c_punctuation">()</span>
+</td>
+</tr>
+<tr>
+<td class="function_type">
+<span class="returnvalue">GType</span>
+</td>
+<td class="function_name">
+<a class="link" href="harfbuzz-hb-gobject.html#hb-gobject-unicode-funcs-get-type" title="hb_gobject_unicode_funcs_get_type ()">hb_gobject_unicode_funcs_get_type</a> <span class="c_punctuation">()</span>
+</td>
+</tr>
+<tr>
+<td class="function_type">
+<span class="returnvalue">GType</span>
+</td>
+<td class="function_name">
+<a class="link" href="harfbuzz-hb-gobject.html#hb-gobject-unicode-general-category-get-type" title="hb_gobject_unicode_general_category_get_type ()">hb_gobject_unicode_general_category_get_type</a> <span class="c_punctuation">()</span>
+</td>
+</tr>
+<tr>
+<td class="function_type">
+<span class="returnvalue">GType</span>
+</td>
+<td class="function_name">
+<a class="link" href="harfbuzz-hb-gobject.html#hb-gobject-buffer-cluster-level-get-type" title="hb_gobject_buffer_cluster_level_get_type ()">hb_gobject_buffer_cluster_level_get_type</a> <span class="c_punctuation">()</span>
+</td>
+</tr>
+<tr>
+<td class="function_type">
+<span class="returnvalue">GType</span>
+</td>
+<td class="function_name">
+<a class="link" href="harfbuzz-hb-gobject.html#hb-gobject-feature-get-type" title="hb_gobject_feature_get_type ()">hb_gobject_feature_get_type</a> <span class="c_punctuation">()</span>
+</td>
+</tr>
+<tr>
+<td class="function_type">
+<span class="returnvalue">GType</span>
+</td>
+<td class="function_name">
+<a class="link" href="harfbuzz-hb-gobject.html#hb-gobject-glyph-info-get-type" title="hb_gobject_glyph_info_get_type ()">hb_gobject_glyph_info_get_type</a> <span class="c_punctuation">()</span>
+</td>
+</tr>
+<tr>
+<td class="function_type">
+<span class="returnvalue">GType</span>
+</td>
+<td class="function_name">
+<a class="link" href="harfbuzz-hb-gobject.html#hb-gobject-glyph-position-get-type" title="hb_gobject_glyph_position_get_type ()">hb_gobject_glyph_position_get_type</a> <span class="c_punctuation">()</span>
+</td>
+</tr>
+<tr>
+<td class="function_type">
+<span class="returnvalue">GType</span>
+</td>
+<td class="function_name">
+<a class="link" href="harfbuzz-hb-gobject.html#hb-gobject-segment-properties-get-type" title="hb_gobject_segment_properties_get_type ()">hb_gobject_segment_properties_get_type</a> <span class="c_punctuation">()</span>
+</td>
+</tr>
+<tr>
+<td class="function_type">
+<span class="returnvalue">GType</span>
+</td>
+<td class="function_name">
+<a class="link" href="harfbuzz-hb-gobject.html#hb-gobject-set-get-type" title="hb_gobject_set_get_type ()">hb_gobject_set_get_type</a> <span class="c_punctuation">()</span>
+</td>
+</tr>
+<tr>
+<td class="function_type">
+<span class="returnvalue">GType</span>
+</td>
+<td class="function_name">
+<a class="link" href="harfbuzz-hb-gobject.html#hb-gobject-user-data-key-get-type" title="hb_gobject_user_data_key_get_type ()">hb_gobject_user_data_key_get_type</a> <span class="c_punctuation">()</span>
+</td>
+</tr>
+</tbody>
+</table></div>
+</div>
+<div class="refsect1">
+<a name="harfbuzz-hb-gobject.other"></a><h2>Types and Values</h2>
+<div class="informaltable"><table class="informaltable" width="100%" border="0">
+<colgroup>
+<col width="150px" class="name">
+<col class="description">
+</colgroup>
+<tbody>
+<tr>
+<td class="define_keyword">#define</td>
+<td class="function_name"><a class="link" href="harfbuzz-hb-gobject.html#HB-GOBJECT-TYPE-BLOB:CAPS" title="HB_GOBJECT_TYPE_BLOB">HB_GOBJECT_TYPE_BLOB</a></td>
+</tr>
+<tr>
+<td class="define_keyword">#define</td>
+<td class="function_name"><a class="link" href="harfbuzz-hb-gobject.html#HB-GOBJECT-TYPE-BUFFER:CAPS" title="HB_GOBJECT_TYPE_BUFFER">HB_GOBJECT_TYPE_BUFFER</a></td>
+</tr>
+<tr>
+<td class="define_keyword">#define</td>
+<td class="function_name"><a class="link" href="harfbuzz-hb-gobject.html#HB-GOBJECT-TYPE-BUFFER-CONTENT-TYPE:CAPS" title="HB_GOBJECT_TYPE_BUFFER_CONTENT_TYPE">HB_GOBJECT_TYPE_BUFFER_CONTENT_TYPE</a></td>
+</tr>
+<tr>
+<td class="define_keyword">#define</td>
+<td class="function_name"><a class="link" href="harfbuzz-hb-gobject.html#HB-GOBJECT-TYPE-BUFFER-DIFF-FLAGS:CAPS" title="HB_GOBJECT_TYPE_BUFFER_DIFF_FLAGS">HB_GOBJECT_TYPE_BUFFER_DIFF_FLAGS</a></td>
+</tr>
+<tr>
+<td class="define_keyword">#define</td>
+<td class="function_name"><a class="link" href="harfbuzz-hb-gobject.html#HB-GOBJECT-TYPE-BUFFER-FLAGS:CAPS" title="HB_GOBJECT_TYPE_BUFFER_FLAGS">HB_GOBJECT_TYPE_BUFFER_FLAGS</a></td>
+</tr>
+<tr>
+<td class="define_keyword">#define</td>
+<td class="function_name"><a class="link" href="harfbuzz-hb-gobject.html#HB-GOBJECT-TYPE-BUFFER-SERIALIZE-FLAGS:CAPS" title="HB_GOBJECT_TYPE_BUFFER_SERIALIZE_FLAGS">HB_GOBJECT_TYPE_BUFFER_SERIALIZE_FLAGS</a></td>
+</tr>
+<tr>
+<td class="define_keyword">#define</td>
+<td class="function_name"><a class="link" href="harfbuzz-hb-gobject.html#HB-GOBJECT-TYPE-BUFFER-SERIALIZE-FORMAT:CAPS" title="HB_GOBJECT_TYPE_BUFFER_SERIALIZE_FORMAT">HB_GOBJECT_TYPE_BUFFER_SERIALIZE_FORMAT</a></td>
+</tr>
+<tr>
+<td class="define_keyword">#define</td>
+<td class="function_name"><a class="link" href="harfbuzz-hb-gobject.html#HB-GOBJECT-TYPE-DIRECTION:CAPS" title="HB_GOBJECT_TYPE_DIRECTION">HB_GOBJECT_TYPE_DIRECTION</a></td>
+</tr>
+<tr>
+<td class="define_keyword">#define</td>
+<td class="function_name"><a class="link" href="harfbuzz-hb-gobject.html#HB-GOBJECT-TYPE-FACE:CAPS" title="HB_GOBJECT_TYPE_FACE">HB_GOBJECT_TYPE_FACE</a></td>
+</tr>
+<tr>
+<td class="define_keyword">#define</td>
+<td class="function_name"><a class="link" href="harfbuzz-hb-gobject.html#HB-GOBJECT-TYPE-FONT:CAPS" title="HB_GOBJECT_TYPE_FONT">HB_GOBJECT_TYPE_FONT</a></td>
+</tr>
+<tr>
+<td class="define_keyword">#define</td>
+<td class="function_name"><a class="link" href="harfbuzz-hb-gobject.html#HB-GOBJECT-TYPE-FONT-FUNCS:CAPS" title="HB_GOBJECT_TYPE_FONT_FUNCS">HB_GOBJECT_TYPE_FONT_FUNCS</a></td>
+</tr>
+<tr>
+<td class="define_keyword">#define</td>
+<td class="function_name"><a class="link" href="harfbuzz-hb-gobject.html#HB-GOBJECT-TYPE-GLYPH-FLAGS:CAPS" title="HB_GOBJECT_TYPE_GLYPH_FLAGS">HB_GOBJECT_TYPE_GLYPH_FLAGS</a></td>
+</tr>
+<tr>
+<td class="define_keyword">#define</td>
+<td class="function_name"><a class="link" href="harfbuzz-hb-gobject.html#HB-GOBJECT-TYPE-MAP:CAPS" title="HB_GOBJECT_TYPE_MAP">HB_GOBJECT_TYPE_MAP</a></td>
+</tr>
+<tr>
+<td class="define_keyword">#define</td>
+<td class="function_name"><a class="link" href="harfbuzz-hb-gobject.html#HB-GOBJECT-TYPE-MEMORY-MODE:CAPS" title="HB_GOBJECT_TYPE_MEMORY_MODE">HB_GOBJECT_TYPE_MEMORY_MODE</a></td>
+</tr>
+<tr>
+<td class="define_keyword">#define</td>
+<td class="function_name"><a class="link" href="harfbuzz-hb-gobject.html#HB-GOBJECT-TYPE-OT-COLOR-PALETTE-FLAGS:CAPS" title="HB_GOBJECT_TYPE_OT_COLOR_PALETTE_FLAGS">HB_GOBJECT_TYPE_OT_COLOR_PALETTE_FLAGS</a></td>
+</tr>
+<tr>
+<td class="define_keyword">#define</td>
+<td class="function_name"><a class="link" href="harfbuzz-hb-gobject.html#HB-GOBJECT-TYPE-OT-LAYOUT-GLYPH-CLASS:CAPS" title="HB_GOBJECT_TYPE_OT_LAYOUT_GLYPH_CLASS">HB_GOBJECT_TYPE_OT_LAYOUT_GLYPH_CLASS</a></td>
+</tr>
+<tr>
+<td class="define_keyword">#define</td>
+<td class="function_name"><a class="link" href="harfbuzz-hb-gobject.html#HB-GOBJECT-TYPE-OT-MATH-CONSTANT:CAPS" title="HB_GOBJECT_TYPE_OT_MATH_CONSTANT">HB_GOBJECT_TYPE_OT_MATH_CONSTANT</a></td>
+</tr>
+<tr>
+<td class="define_keyword">#define</td>
+<td class="function_name"><a class="link" href="harfbuzz-hb-gobject.html#HB-GOBJECT-TYPE-OT-MATH-GLYPH-PART:CAPS" title="HB_GOBJECT_TYPE_OT_MATH_GLYPH_PART">HB_GOBJECT_TYPE_OT_MATH_GLYPH_PART</a></td>
+</tr>
+<tr>
+<td class="define_keyword">#define</td>
+<td class="function_name"><a class="link" href="harfbuzz-hb-gobject.html#HB-GOBJECT-TYPE-OT-MATH-GLYPH-PART-FLAGS:CAPS" title="HB_GOBJECT_TYPE_OT_MATH_GLYPH_PART_FLAGS">HB_GOBJECT_TYPE_OT_MATH_GLYPH_PART_FLAGS</a></td>
+</tr>
+<tr>
+<td class="define_keyword">#define</td>
+<td class="function_name"><a class="link" href="harfbuzz-hb-gobject.html#HB-GOBJECT-TYPE-OT-MATH-GLYPH-VARIANT:CAPS" title="HB_GOBJECT_TYPE_OT_MATH_GLYPH_VARIANT">HB_GOBJECT_TYPE_OT_MATH_GLYPH_VARIANT</a></td>
+</tr>
+<tr>
+<td class="define_keyword">#define</td>
+<td class="function_name"><a class="link" href="harfbuzz-hb-gobject.html#HB-GOBJECT-TYPE-OT-MATH-KERN:CAPS" title="HB_GOBJECT_TYPE_OT_MATH_KERN">HB_GOBJECT_TYPE_OT_MATH_KERN</a></td>
+</tr>
+<tr>
+<td class="define_keyword">#define</td>
+<td class="function_name"><a class="link" href="harfbuzz-hb-gobject.html#HB-GOBJECT-TYPE-SCRIPT:CAPS" title="HB_GOBJECT_TYPE_SCRIPT">HB_GOBJECT_TYPE_SCRIPT</a></td>
+</tr>
+<tr>
+<td class="define_keyword">#define</td>
+<td class="function_name"><a class="link" href="harfbuzz-hb-gobject.html#HB-GOBJECT-TYPE-SHAPE-PLAN:CAPS" title="HB_GOBJECT_TYPE_SHAPE_PLAN">HB_GOBJECT_TYPE_SHAPE_PLAN</a></td>
+</tr>
+<tr>
+<td class="define_keyword">#define</td>
+<td class="function_name"><a class="link" href="harfbuzz-hb-gobject.html#HB-GOBJECT-TYPE-UNICODE-COMBINING-CLASS:CAPS" title="HB_GOBJECT_TYPE_UNICODE_COMBINING_CLASS">HB_GOBJECT_TYPE_UNICODE_COMBINING_CLASS</a></td>
+</tr>
+<tr>
+<td class="define_keyword">#define</td>
+<td class="function_name"><a class="link" href="harfbuzz-hb-gobject.html#HB-GOBJECT-TYPE-UNICODE-FUNCS:CAPS" title="HB_GOBJECT_TYPE_UNICODE_FUNCS">HB_GOBJECT_TYPE_UNICODE_FUNCS</a></td>
+</tr>
+<tr>
+<td class="define_keyword">#define</td>
+<td class="function_name"><a class="link" href="harfbuzz-hb-gobject.html#HB-GOBJECT-TYPE-UNICODE-GENERAL-CATEGORY:CAPS" title="HB_GOBJECT_TYPE_UNICODE_GENERAL_CATEGORY">HB_GOBJECT_TYPE_UNICODE_GENERAL_CATEGORY</a></td>
+</tr>
+<tr>
+<td class="define_keyword">#define</td>
+<td class="function_name"><a class="link" href="harfbuzz-hb-gobject.html#HB-GOBJECT-TYPE-BUFFER-CLUSTER-LEVEL:CAPS" title="HB_GOBJECT_TYPE_BUFFER_CLUSTER_LEVEL">HB_GOBJECT_TYPE_BUFFER_CLUSTER_LEVEL</a></td>
+</tr>
+<tr>
+<td class="define_keyword">#define</td>
+<td class="function_name"><a class="link" href="harfbuzz-hb-gobject.html#HB-GOBJECT-TYPE-FEATURE:CAPS" title="HB_GOBJECT_TYPE_FEATURE">HB_GOBJECT_TYPE_FEATURE</a></td>
+</tr>
+<tr>
+<td class="define_keyword">#define</td>
+<td class="function_name"><a class="link" href="harfbuzz-hb-gobject.html#HB-GOBJECT-TYPE-GLYPH-INFO:CAPS" title="HB_GOBJECT_TYPE_GLYPH_INFO">HB_GOBJECT_TYPE_GLYPH_INFO</a></td>
+</tr>
+<tr>
+<td class="define_keyword">#define</td>
+<td class="function_name"><a class="link" href="harfbuzz-hb-gobject.html#HB-GOBJECT-TYPE-GLYPH-POSITION:CAPS" title="HB_GOBJECT_TYPE_GLYPH_POSITION">HB_GOBJECT_TYPE_GLYPH_POSITION</a></td>
+</tr>
+<tr>
+<td class="define_keyword">#define</td>
+<td class="function_name"><a class="link" href="harfbuzz-hb-gobject.html#HB-GOBJECT-TYPE-SEGMENT-PROPERTIES:CAPS" title="HB_GOBJECT_TYPE_SEGMENT_PROPERTIES">HB_GOBJECT_TYPE_SEGMENT_PROPERTIES</a></td>
+</tr>
+<tr>
+<td class="define_keyword">#define</td>
+<td class="function_name"><a class="link" href="harfbuzz-hb-gobject.html#HB-GOBJECT-TYPE-SET:CAPS" title="HB_GOBJECT_TYPE_SET">HB_GOBJECT_TYPE_SET</a></td>
+</tr>
+<tr>
+<td class="define_keyword">#define</td>
+<td class="function_name"><a class="link" href="harfbuzz-hb-gobject.html#HB-GOBJECT-TYPE-USER-DATA-KEY:CAPS" title="HB_GOBJECT_TYPE_USER_DATA_KEY">HB_GOBJECT_TYPE_USER_DATA_KEY</a></td>
+</tr>
+</tbody>
+</table></div>
+</div>
+<div class="refsect1">
 <a name="harfbuzz-hb-gobject.includes"></a><h2>Includes</h2>
 <pre class="synopsis">#include &lt;hb-gobject.h&gt;
 </pre>
@@ -43,10 +461,421 @@ type data.</p>
 </div>
 <div class="refsect1">
 <a name="harfbuzz-hb-gobject.functions_details"></a><h2>Functions</h2>
-<p></p>
+<div class="refsect2">
+<a name="hb-gobject-blob-get-type"></a><h3>hb_gobject_blob_get_type ()</h3>
+<pre class="programlisting"><span class="returnvalue">GType</span>
+hb_gobject_blob_get_type (<em class="parameter"><code><span class="type">void</span></code></em>);</pre>
+<p class="since">Since: <a class="link" href="api-index-0-9-2.html#api-index-0.9.2">0.9.2</a></p>
+</div>
+<hr>
+<div class="refsect2">
+<a name="hb-gobject-buffer-content-type-get-type"></a><h3>hb_gobject_buffer_content_type_get_type ()</h3>
+<pre class="programlisting"><span class="returnvalue">GType</span>
+hb_gobject_buffer_content_type_get_type
+                               ();</pre>
+</div>
+<hr>
+<div class="refsect2">
+<a name="hb-gobject-buffer-diff-flags-get-type"></a><h3>hb_gobject_buffer_diff_flags_get_type ()</h3>
+<pre class="programlisting"><span class="returnvalue">GType</span>
+hb_gobject_buffer_diff_flags_get_type ();</pre>
+</div>
+<hr>
+<div class="refsect2">
+<a name="hb-gobject-buffer-flags-get-type"></a><h3>hb_gobject_buffer_flags_get_type ()</h3>
+<pre class="programlisting"><span class="returnvalue">GType</span>
+hb_gobject_buffer_flags_get_type ();</pre>
+</div>
+<hr>
+<div class="refsect2">
+<a name="hb-gobject-buffer-get-type"></a><h3>hb_gobject_buffer_get_type ()</h3>
+<pre class="programlisting"><span class="returnvalue">GType</span>
+hb_gobject_buffer_get_type (<em class="parameter"><code><span class="type">void</span></code></em>);</pre>
+<p class="since">Since: <a class="link" href="api-index-0-9-2.html#api-index-0.9.2">0.9.2</a></p>
+</div>
+<hr>
+<div class="refsect2">
+<a name="hb-gobject-buffer-serialize-flags-get-type"></a><h3>hb_gobject_buffer_serialize_flags_get_type ()</h3>
+<pre class="programlisting"><span class="returnvalue">GType</span>
+hb_gobject_buffer_serialize_flags_get_type
+                               ();</pre>
+</div>
+<hr>
+<div class="refsect2">
+<a name="hb-gobject-buffer-serialize-format-get-type"></a><h3>hb_gobject_buffer_serialize_format_get_type ()</h3>
+<pre class="programlisting"><span class="returnvalue">GType</span>
+hb_gobject_buffer_serialize_format_get_type
+                               ();</pre>
+</div>
+<hr>
+<div class="refsect2">
+<a name="hb-gobject-direction-get-type"></a><h3>hb_gobject_direction_get_type ()</h3>
+<pre class="programlisting"><span class="returnvalue">GType</span>
+hb_gobject_direction_get_type ();</pre>
+</div>
+<hr>
+<div class="refsect2">
+<a name="hb-gobject-face-get-type"></a><h3>hb_gobject_face_get_type ()</h3>
+<pre class="programlisting"><span class="returnvalue">GType</span>
+hb_gobject_face_get_type (<em class="parameter"><code><span class="type">void</span></code></em>);</pre>
+<p class="since">Since: <a class="link" href="api-index-0-9-2.html#api-index-0.9.2">0.9.2</a></p>
+</div>
+<hr>
+<div class="refsect2">
+<a name="hb-gobject-font-funcs-get-type"></a><h3>hb_gobject_font_funcs_get_type ()</h3>
+<pre class="programlisting"><span class="returnvalue">GType</span>
+hb_gobject_font_funcs_get_type (<em class="parameter"><code><span class="type">void</span></code></em>);</pre>
+<p class="since">Since: <a class="link" href="api-index-0-9-2.html#api-index-0.9.2">0.9.2</a></p>
+</div>
+<hr>
+<div class="refsect2">
+<a name="hb-gobject-font-get-type"></a><h3>hb_gobject_font_get_type ()</h3>
+<pre class="programlisting"><span class="returnvalue">GType</span>
+hb_gobject_font_get_type (<em class="parameter"><code><span class="type">void</span></code></em>);</pre>
+<p class="since">Since: <a class="link" href="api-index-0-9-2.html#api-index-0.9.2">0.9.2</a></p>
+</div>
+<hr>
+<div class="refsect2">
+<a name="hb-gobject-glyph-flags-get-type"></a><h3>hb_gobject_glyph_flags_get_type ()</h3>
+<pre class="programlisting"><span class="returnvalue">GType</span>
+hb_gobject_glyph_flags_get_type ();</pre>
+</div>
+<hr>
+<div class="refsect2">
+<a name="hb-gobject-map-get-type"></a><h3>hb_gobject_map_get_type ()</h3>
+<pre class="programlisting"><span class="returnvalue">GType</span>
+hb_gobject_map_get_type (<em class="parameter"><code><span class="type">void</span></code></em>);</pre>
+</div>
+<hr>
+<div class="refsect2">
+<a name="hb-gobject-memory-mode-get-type"></a><h3>hb_gobject_memory_mode_get_type ()</h3>
+<pre class="programlisting"><span class="returnvalue">GType</span>
+hb_gobject_memory_mode_get_type ();</pre>
+</div>
+<hr>
+<div class="refsect2">
+<a name="hb-gobject-ot-color-palette-flags-get-type"></a><h3>hb_gobject_ot_color_palette_flags_get_type ()</h3>
+<pre class="programlisting"><span class="returnvalue">GType</span>
+hb_gobject_ot_color_palette_flags_get_type
+                               ();</pre>
+</div>
+<hr>
+<div class="refsect2">
+<a name="hb-gobject-ot-layout-glyph-class-get-type"></a><h3>hb_gobject_ot_layout_glyph_class_get_type ()</h3>
+<pre class="programlisting"><span class="returnvalue">GType</span>
+hb_gobject_ot_layout_glyph_class_get_type
+                               ();</pre>
+</div>
+<hr>
+<div class="refsect2">
+<a name="hb-gobject-ot-math-constant-get-type"></a><h3>hb_gobject_ot_math_constant_get_type ()</h3>
+<pre class="programlisting"><span class="returnvalue">GType</span>
+hb_gobject_ot_math_constant_get_type ();</pre>
+</div>
+<hr>
+<div class="refsect2">
+<a name="hb-gobject-ot-math-glyph-part-get-type"></a><h3>hb_gobject_ot_math_glyph_part_get_type ()</h3>
+<pre class="programlisting"><span class="returnvalue">GType</span>
+hb_gobject_ot_math_glyph_part_get_type
+                               (<em class="parameter"><code><span class="type">void</span></code></em>);</pre>
+</div>
+<hr>
+<div class="refsect2">
+<a name="hb-gobject-ot-math-glyph-part-flags-get-type"></a><h3>hb_gobject_ot_math_glyph_part_flags_get_type ()</h3>
+<pre class="programlisting"><span class="returnvalue">GType</span>
+hb_gobject_ot_math_glyph_part_flags_get_type
+                               ();</pre>
+</div>
+<hr>
+<div class="refsect2">
+<a name="hb-gobject-ot-math-glyph-variant-get-type"></a><h3>hb_gobject_ot_math_glyph_variant_get_type ()</h3>
+<pre class="programlisting"><span class="returnvalue">GType</span>
+hb_gobject_ot_math_glyph_variant_get_type
+                               (<em class="parameter"><code><span class="type">void</span></code></em>);</pre>
+</div>
+<hr>
+<div class="refsect2">
+<a name="hb-gobject-ot-math-kern-get-type"></a><h3>hb_gobject_ot_math_kern_get_type ()</h3>
+<pre class="programlisting"><span class="returnvalue">GType</span>
+hb_gobject_ot_math_kern_get_type ();</pre>
+</div>
+<hr>
+<div class="refsect2">
+<a name="hb-gobject-script-get-type"></a><h3>hb_gobject_script_get_type ()</h3>
+<pre class="programlisting"><span class="returnvalue">GType</span>
+hb_gobject_script_get_type ();</pre>
+</div>
+<hr>
+<div class="refsect2">
+<a name="hb-gobject-shape-plan-get-type"></a><h3>hb_gobject_shape_plan_get_type ()</h3>
+<pre class="programlisting"><span class="returnvalue">GType</span>
+hb_gobject_shape_plan_get_type (<em class="parameter"><code><span class="type">void</span></code></em>);</pre>
+</div>
+<hr>
+<div class="refsect2">
+<a name="hb-gobject-unicode-combining-class-get-type"></a><h3>hb_gobject_unicode_combining_class_get_type ()</h3>
+<pre class="programlisting"><span class="returnvalue">GType</span>
+hb_gobject_unicode_combining_class_get_type
+                               ();</pre>
+</div>
+<hr>
+<div class="refsect2">
+<a name="hb-gobject-unicode-funcs-get-type"></a><h3>hb_gobject_unicode_funcs_get_type ()</h3>
+<pre class="programlisting"><span class="returnvalue">GType</span>
+hb_gobject_unicode_funcs_get_type (<em class="parameter"><code><span class="type">void</span></code></em>);</pre>
+<p class="since">Since: <a class="link" href="api-index-0-9-2.html#api-index-0.9.2">0.9.2</a></p>
+</div>
+<hr>
+<div class="refsect2">
+<a name="hb-gobject-unicode-general-category-get-type"></a><h3>hb_gobject_unicode_general_category_get_type ()</h3>
+<pre class="programlisting"><span class="returnvalue">GType</span>
+hb_gobject_unicode_general_category_get_type
+                               ();</pre>
+</div>
+<hr>
+<div class="refsect2">
+<a name="hb-gobject-buffer-cluster-level-get-type"></a><h3>hb_gobject_buffer_cluster_level_get_type ()</h3>
+<pre class="programlisting"><span class="returnvalue">GType</span>
+hb_gobject_buffer_cluster_level_get_type
+                               ();</pre>
+</div>
+<hr>
+<div class="refsect2">
+<a name="hb-gobject-feature-get-type"></a><h3>hb_gobject_feature_get_type ()</h3>
+<pre class="programlisting"><span class="returnvalue">GType</span>
+hb_gobject_feature_get_type (<em class="parameter"><code><span class="type">void</span></code></em>);</pre>
+</div>
+<hr>
+<div class="refsect2">
+<a name="hb-gobject-glyph-info-get-type"></a><h3>hb_gobject_glyph_info_get_type ()</h3>
+<pre class="programlisting"><span class="returnvalue">GType</span>
+hb_gobject_glyph_info_get_type (<em class="parameter"><code><span class="type">void</span></code></em>);</pre>
+</div>
+<hr>
+<div class="refsect2">
+<a name="hb-gobject-glyph-position-get-type"></a><h3>hb_gobject_glyph_position_get_type ()</h3>
+<pre class="programlisting"><span class="returnvalue">GType</span>
+hb_gobject_glyph_position_get_type (<em class="parameter"><code><span class="type">void</span></code></em>);</pre>
+</div>
+<hr>
+<div class="refsect2">
+<a name="hb-gobject-segment-properties-get-type"></a><h3>hb_gobject_segment_properties_get_type ()</h3>
+<pre class="programlisting"><span class="returnvalue">GType</span>
+hb_gobject_segment_properties_get_type
+                               (<em class="parameter"><code><span class="type">void</span></code></em>);</pre>
+</div>
+<hr>
+<div class="refsect2">
+<a name="hb-gobject-set-get-type"></a><h3>hb_gobject_set_get_type ()</h3>
+<pre class="programlisting"><span class="returnvalue">GType</span>
+hb_gobject_set_get_type (<em class="parameter"><code><span class="type">void</span></code></em>);</pre>
+</div>
+<hr>
+<div class="refsect2">
+<a name="hb-gobject-user-data-key-get-type"></a><h3>hb_gobject_user_data_key_get_type ()</h3>
+<pre class="programlisting"><span class="returnvalue">GType</span>
+hb_gobject_user_data_key_get_type (<em class="parameter"><code><span class="type">void</span></code></em>);</pre>
+</div>
 </div>
 <div class="refsect1">
 <a name="harfbuzz-hb-gobject.other_details"></a><h2>Types and Values</h2>
+<div class="refsect2">
+<a name="HB-GOBJECT-TYPE-BLOB:CAPS"></a><h3>HB_GOBJECT_TYPE_BLOB</h3>
+<pre class="programlisting">#define HB_GOBJECT_TYPE_BLOB (hb_gobject_blob_get_type ())
+</pre>
+</div>
+<hr>
+<div class="refsect2">
+<a name="HB-GOBJECT-TYPE-BUFFER:CAPS"></a><h3>HB_GOBJECT_TYPE_BUFFER</h3>
+<pre class="programlisting">#define HB_GOBJECT_TYPE_BUFFER (hb_gobject_buffer_get_type ())
+</pre>
+</div>
+<hr>
+<div class="refsect2">
+<a name="HB-GOBJECT-TYPE-BUFFER-CONTENT-TYPE:CAPS"></a><h3>HB_GOBJECT_TYPE_BUFFER_CONTENT_TYPE</h3>
+<pre class="programlisting">#define HB_GOBJECT_TYPE_BUFFER_CONTENT_TYPE (hb_gobject_buffer_content_type_get_type ())
+</pre>
+</div>
+<hr>
+<div class="refsect2">
+<a name="HB-GOBJECT-TYPE-BUFFER-DIFF-FLAGS:CAPS"></a><h3>HB_GOBJECT_TYPE_BUFFER_DIFF_FLAGS</h3>
+<pre class="programlisting">#define HB_GOBJECT_TYPE_BUFFER_DIFF_FLAGS (hb_gobject_buffer_diff_flags_get_type ())
+</pre>
+</div>
+<hr>
+<div class="refsect2">
+<a name="HB-GOBJECT-TYPE-BUFFER-FLAGS:CAPS"></a><h3>HB_GOBJECT_TYPE_BUFFER_FLAGS</h3>
+<pre class="programlisting">#define HB_GOBJECT_TYPE_BUFFER_FLAGS (hb_gobject_buffer_flags_get_type ())
+</pre>
+</div>
+<hr>
+<div class="refsect2">
+<a name="HB-GOBJECT-TYPE-BUFFER-SERIALIZE-FLAGS:CAPS"></a><h3>HB_GOBJECT_TYPE_BUFFER_SERIALIZE_FLAGS</h3>
+<pre class="programlisting">#define HB_GOBJECT_TYPE_BUFFER_SERIALIZE_FLAGS (hb_gobject_buffer_serialize_flags_get_type ())
+</pre>
+</div>
+<hr>
+<div class="refsect2">
+<a name="HB-GOBJECT-TYPE-BUFFER-SERIALIZE-FORMAT:CAPS"></a><h3>HB_GOBJECT_TYPE_BUFFER_SERIALIZE_FORMAT</h3>
+<pre class="programlisting">#define HB_GOBJECT_TYPE_BUFFER_SERIALIZE_FORMAT (hb_gobject_buffer_serialize_format_get_type ())
+</pre>
+</div>
+<hr>
+<div class="refsect2">
+<a name="HB-GOBJECT-TYPE-DIRECTION:CAPS"></a><h3>HB_GOBJECT_TYPE_DIRECTION</h3>
+<pre class="programlisting">#define HB_GOBJECT_TYPE_DIRECTION (hb_gobject_direction_get_type ())
+</pre>
+</div>
+<hr>
+<div class="refsect2">
+<a name="HB-GOBJECT-TYPE-FACE:CAPS"></a><h3>HB_GOBJECT_TYPE_FACE</h3>
+<pre class="programlisting">#define HB_GOBJECT_TYPE_FACE (hb_gobject_face_get_type ())
+</pre>
+</div>
+<hr>
+<div class="refsect2">
+<a name="HB-GOBJECT-TYPE-FONT:CAPS"></a><h3>HB_GOBJECT_TYPE_FONT</h3>
+<pre class="programlisting">#define HB_GOBJECT_TYPE_FONT (hb_gobject_font_get_type ())
+</pre>
+</div>
+<hr>
+<div class="refsect2">
+<a name="HB-GOBJECT-TYPE-FONT-FUNCS:CAPS"></a><h3>HB_GOBJECT_TYPE_FONT_FUNCS</h3>
+<pre class="programlisting">#define HB_GOBJECT_TYPE_FONT_FUNCS (hb_gobject_font_funcs_get_type ())
+</pre>
+</div>
+<hr>
+<div class="refsect2">
+<a name="HB-GOBJECT-TYPE-GLYPH-FLAGS:CAPS"></a><h3>HB_GOBJECT_TYPE_GLYPH_FLAGS</h3>
+<pre class="programlisting">#define HB_GOBJECT_TYPE_GLYPH_FLAGS (hb_gobject_glyph_flags_get_type ())
+</pre>
+</div>
+<hr>
+<div class="refsect2">
+<a name="HB-GOBJECT-TYPE-MAP:CAPS"></a><h3>HB_GOBJECT_TYPE_MAP</h3>
+<pre class="programlisting">#define HB_GOBJECT_TYPE_MAP (hb_gobject_map_get_type ())
+</pre>
+</div>
+<hr>
+<div class="refsect2">
+<a name="HB-GOBJECT-TYPE-MEMORY-MODE:CAPS"></a><h3>HB_GOBJECT_TYPE_MEMORY_MODE</h3>
+<pre class="programlisting">#define HB_GOBJECT_TYPE_MEMORY_MODE (hb_gobject_memory_mode_get_type ())
+</pre>
+</div>
+<hr>
+<div class="refsect2">
+<a name="HB-GOBJECT-TYPE-OT-COLOR-PALETTE-FLAGS:CAPS"></a><h3>HB_GOBJECT_TYPE_OT_COLOR_PALETTE_FLAGS</h3>
+<pre class="programlisting">#define HB_GOBJECT_TYPE_OT_COLOR_PALETTE_FLAGS (hb_gobject_ot_color_palette_flags_get_type ())
+</pre>
+</div>
+<hr>
+<div class="refsect2">
+<a name="HB-GOBJECT-TYPE-OT-LAYOUT-GLYPH-CLASS:CAPS"></a><h3>HB_GOBJECT_TYPE_OT_LAYOUT_GLYPH_CLASS</h3>
+<pre class="programlisting">#define HB_GOBJECT_TYPE_OT_LAYOUT_GLYPH_CLASS (hb_gobject_ot_layout_glyph_class_get_type ())
+</pre>
+</div>
+<hr>
+<div class="refsect2">
+<a name="HB-GOBJECT-TYPE-OT-MATH-CONSTANT:CAPS"></a><h3>HB_GOBJECT_TYPE_OT_MATH_CONSTANT</h3>
+<pre class="programlisting">#define HB_GOBJECT_TYPE_OT_MATH_CONSTANT (hb_gobject_ot_math_constant_get_type ())
+</pre>
+</div>
+<hr>
+<div class="refsect2">
+<a name="HB-GOBJECT-TYPE-OT-MATH-GLYPH-PART:CAPS"></a><h3>HB_GOBJECT_TYPE_OT_MATH_GLYPH_PART</h3>
+<pre class="programlisting">#define HB_GOBJECT_TYPE_OT_MATH_GLYPH_PART (hb_gobject_ot_math_glyph_part_get_type ())
+</pre>
+</div>
+<hr>
+<div class="refsect2">
+<a name="HB-GOBJECT-TYPE-OT-MATH-GLYPH-PART-FLAGS:CAPS"></a><h3>HB_GOBJECT_TYPE_OT_MATH_GLYPH_PART_FLAGS</h3>
+<pre class="programlisting">#define HB_GOBJECT_TYPE_OT_MATH_GLYPH_PART_FLAGS (hb_gobject_ot_math_glyph_part_flags_get_type ())
+</pre>
+</div>
+<hr>
+<div class="refsect2">
+<a name="HB-GOBJECT-TYPE-OT-MATH-GLYPH-VARIANT:CAPS"></a><h3>HB_GOBJECT_TYPE_OT_MATH_GLYPH_VARIANT</h3>
+<pre class="programlisting">#define HB_GOBJECT_TYPE_OT_MATH_GLYPH_VARIANT (hb_gobject_ot_math_glyph_variant_get_type ())
+</pre>
+</div>
+<hr>
+<div class="refsect2">
+<a name="HB-GOBJECT-TYPE-OT-MATH-KERN:CAPS"></a><h3>HB_GOBJECT_TYPE_OT_MATH_KERN</h3>
+<pre class="programlisting">#define HB_GOBJECT_TYPE_OT_MATH_KERN (hb_gobject_ot_math_kern_get_type ())
+</pre>
+</div>
+<hr>
+<div class="refsect2">
+<a name="HB-GOBJECT-TYPE-SCRIPT:CAPS"></a><h3>HB_GOBJECT_TYPE_SCRIPT</h3>
+<pre class="programlisting">#define HB_GOBJECT_TYPE_SCRIPT (hb_gobject_script_get_type ())
+</pre>
+</div>
+<hr>
+<div class="refsect2">
+<a name="HB-GOBJECT-TYPE-SHAPE-PLAN:CAPS"></a><h3>HB_GOBJECT_TYPE_SHAPE_PLAN</h3>
+<pre class="programlisting">#define HB_GOBJECT_TYPE_SHAPE_PLAN (hb_gobject_shape_plan_get_type ())
+</pre>
+</div>
+<hr>
+<div class="refsect2">
+<a name="HB-GOBJECT-TYPE-UNICODE-COMBINING-CLASS:CAPS"></a><h3>HB_GOBJECT_TYPE_UNICODE_COMBINING_CLASS</h3>
+<pre class="programlisting">#define HB_GOBJECT_TYPE_UNICODE_COMBINING_CLASS (hb_gobject_unicode_combining_class_get_type ())
+</pre>
+</div>
+<hr>
+<div class="refsect2">
+<a name="HB-GOBJECT-TYPE-UNICODE-FUNCS:CAPS"></a><h3>HB_GOBJECT_TYPE_UNICODE_FUNCS</h3>
+<pre class="programlisting">#define HB_GOBJECT_TYPE_UNICODE_FUNCS (hb_gobject_unicode_funcs_get_type ())
+</pre>
+</div>
+<hr>
+<div class="refsect2">
+<a name="HB-GOBJECT-TYPE-UNICODE-GENERAL-CATEGORY:CAPS"></a><h3>HB_GOBJECT_TYPE_UNICODE_GENERAL_CATEGORY</h3>
+<pre class="programlisting">#define HB_GOBJECT_TYPE_UNICODE_GENERAL_CATEGORY (hb_gobject_unicode_general_category_get_type ())
+</pre>
+</div>
+<hr>
+<div class="refsect2">
+<a name="HB-GOBJECT-TYPE-BUFFER-CLUSTER-LEVEL:CAPS"></a><h3>HB_GOBJECT_TYPE_BUFFER_CLUSTER_LEVEL</h3>
+<pre class="programlisting">#define HB_GOBJECT_TYPE_BUFFER_CLUSTER_LEVEL (hb_gobject_buffer_cluster_level_get_type ())
+</pre>
+</div>
+<hr>
+<div class="refsect2">
+<a name="HB-GOBJECT-TYPE-FEATURE:CAPS"></a><h3>HB_GOBJECT_TYPE_FEATURE</h3>
+<pre class="programlisting">#define HB_GOBJECT_TYPE_FEATURE (hb_gobject_feature_get_type ())
+</pre>
+</div>
+<hr>
+<div class="refsect2">
+<a name="HB-GOBJECT-TYPE-GLYPH-INFO:CAPS"></a><h3>HB_GOBJECT_TYPE_GLYPH_INFO</h3>
+<pre class="programlisting">#define HB_GOBJECT_TYPE_GLYPH_INFO (hb_gobject_glyph_info_get_type ())
+</pre>
+</div>
+<hr>
+<div class="refsect2">
+<a name="HB-GOBJECT-TYPE-GLYPH-POSITION:CAPS"></a><h3>HB_GOBJECT_TYPE_GLYPH_POSITION</h3>
+<pre class="programlisting">#define HB_GOBJECT_TYPE_GLYPH_POSITION (hb_gobject_glyph_position_get_type ())
+</pre>
+</div>
+<hr>
+<div class="refsect2">
+<a name="HB-GOBJECT-TYPE-SEGMENT-PROPERTIES:CAPS"></a><h3>HB_GOBJECT_TYPE_SEGMENT_PROPERTIES</h3>
+<pre class="programlisting">#define HB_GOBJECT_TYPE_SEGMENT_PROPERTIES (hb_gobject_segment_properties_get_type ())
+</pre>
+</div>
+<hr>
+<div class="refsect2">
+<a name="HB-GOBJECT-TYPE-SET:CAPS"></a><h3>HB_GOBJECT_TYPE_SET</h3>
+<pre class="programlisting">#define HB_GOBJECT_TYPE_SET (hb_gobject_set_get_type ())
+</pre>
+</div>
+<hr>
+<div class="refsect2">
+<a name="HB-GOBJECT-TYPE-USER-DATA-KEY:CAPS"></a><h3>HB_GOBJECT_TYPE_USER_DATA_KEY</h3>
+<pre class="programlisting">#define HB_GOBJECT_TYPE_USER_DATA_KEY (hb_gobject_user_data_key_get_type ())
+</pre>
+</div>
 </div>
 </div>
 <div class="footer">
index b6d779b..57a087d 100644 (file)
@@ -5,7 +5,7 @@
 <title>hb-graphite2: HarfBuzz Manual</title>
 <meta name="generator" content="DocBook XSL Stylesheets Vsnapshot">
 <link rel="home" href="index.html" title="HarfBuzz Manual">
-<link rel="up" href="ch12.html" title="Integration API">
+<link rel="up" href="ch14.html" title="Integration API">
 <link rel="prev" href="harfbuzz-hb-gobject.html" title="hb-gobject">
 <link rel="next" href="harfbuzz-hb-icu.html" title="hb-icu">
 <meta name="generator" content="GTK-Doc V1.29 (XML mode)">
@@ -18,7 +18,7 @@
                   <a href="#harfbuzz-hb-graphite2.description" class="shortcut">Description</a></span>
 </td>
 <td><a accesskey="h" href="index.html"><img src="home.png" width="16" height="16" border="0" alt="Home"></a></td>
-<td><a accesskey="u" href="ch12.html"><img src="up.png" width="16" height="16" border="0" alt="Up"></a></td>
+<td><a accesskey="u" href="ch14.html"><img src="up.png" width="16" height="16" border="0" alt="Up"></a></td>
 <td><a accesskey="p" href="harfbuzz-hb-gobject.html"><img src="left.png" width="16" height="16" border="0" alt="Prev"></a></td>
 <td><a accesskey="n" href="harfbuzz-hb-icu.html"><img src="right.png" width="16" height="16" border="0" alt="Next"></a></td>
 </tr></table>
@@ -75,7 +75,7 @@
 <div class="refsect2">
 <a name="hb-graphite2-face-get-gr-face"></a><h3>hb_graphite2_face_get_gr_face ()</h3>
 <pre class="programlisting"><span class="returnvalue">gr_face</span> *
-hb_graphite2_face_get_gr_face (<em class="parameter"><code><a class="link" href="harfbuzz-hb-face.html#hb-face-t" title="hb_face_t"><span class="type">hb_face_t</span></a> *face</code></em>);</pre>
+hb_graphite2_face_get_gr_face (<em class="parameter"><code><a class="link" href="harfbuzz-hb-face.html#hb-face-t"><span class="type">hb_face_t</span></a> *face</code></em>);</pre>
 </div>
 </div>
 <div class="refsect1">
index d1a31de..d89128c 100644 (file)
@@ -5,7 +5,7 @@
 <title>hb-icu: HarfBuzz Manual</title>
 <meta name="generator" content="DocBook XSL Stylesheets Vsnapshot">
 <link rel="home" href="index.html" title="HarfBuzz Manual">
-<link rel="up" href="ch12.html" title="Integration API">
+<link rel="up" href="ch14.html" title="Integration API">
 <link rel="prev" href="harfbuzz-hb-graphite2.html" title="hb-graphite2">
 <link rel="next" href="harfbuzz-hb-uniscribe.html" title="hb-uniscribe">
 <meta name="generator" content="GTK-Doc V1.29 (XML mode)">
@@ -18,7 +18,7 @@
                   <a href="#harfbuzz-hb-icu.description" class="shortcut">Description</a></span>
 </td>
 <td><a accesskey="h" href="index.html"><img src="home.png" width="16" height="16" border="0" alt="Home"></a></td>
-<td><a accesskey="u" href="ch12.html"><img src="up.png" width="16" height="16" border="0" alt="Up"></a></td>
+<td><a accesskey="u" href="ch14.html"><img src="up.png" width="16" height="16" border="0" alt="Up"></a></td>
 <td><a accesskey="p" href="harfbuzz-hb-graphite2.html"><img src="left.png" width="16" height="16" border="0" alt="Prev"></a></td>
 <td><a accesskey="n" href="harfbuzz-hb-uniscribe.html"><img src="right.png" width="16" height="16" border="0" alt="Next"></a></td>
 </tr></table>
@@ -41,7 +41,7 @@
 <tbody>
 <tr>
 <td class="function_type">
-<a class="link" href="harfbuzz-hb-unicode.html#hb-unicode-funcs-t" title="hb_unicode_funcs_t"><span class="returnvalue">hb_unicode_funcs_t</span></a> *
+<a class="link" href="harfbuzz-hb-unicode.html#hb-unicode-funcs-t"><span class="returnvalue">hb_unicode_funcs_t</span></a> *
 </td>
 <td class="function_name">
 <a class="link" href="harfbuzz-hb-icu.html#hb-icu-get-unicode-funcs" title="hb_icu_get_unicode_funcs ()">hb_icu_get_unicode_funcs</a> <span class="c_punctuation">()</span>
@@ -79,7 +79,7 @@
 <a name="harfbuzz-hb-icu.functions_details"></a><h2>Functions</h2>
 <div class="refsect2">
 <a name="hb-icu-get-unicode-funcs"></a><h3>hb_icu_get_unicode_funcs ()</h3>
-<pre class="programlisting"><a class="link" href="harfbuzz-hb-unicode.html#hb-unicode-funcs-t" title="hb_unicode_funcs_t"><span class="returnvalue">hb_unicode_funcs_t</span></a> *
+<pre class="programlisting"><a class="link" href="harfbuzz-hb-unicode.html#hb-unicode-funcs-t"><span class="returnvalue">hb_unicode_funcs_t</span></a> *
 hb_icu_get_unicode_funcs (<em class="parameter"><code><span class="type">void</span></code></em>);</pre>
 </div>
 <hr>
index 1e62513..e54c629 100644 (file)
@@ -5,7 +5,7 @@
 <title>hb-map: HarfBuzz Manual</title>
 <meta name="generator" content="DocBook XSL Stylesheets Vsnapshot">
 <link rel="home" href="index.html" title="HarfBuzz Manual">
-<link rel="up" href="ch09.html" title="Core API">
+<link rel="up" href="ch11.html" title="Core API">
 <link rel="prev" href="harfbuzz-hb-font.html" title="hb-font">
 <link rel="next" href="harfbuzz-hb-set.html" title="hb-set">
 <meta name="generator" content="GTK-Doc V1.29 (XML mode)">
 <table class="navigation" id="top" width="100%" summary="Navigation header" cellpadding="2" cellspacing="5"><tr valign="middle">
 <td width="100%" align="left" class="shortcuts">
 <a href="#" class="shortcut">Top</a><span id="nav_description">  <span class="dim">|</span> 
-                  <a href="#harfbuzz-hb-map.description" class="shortcut">Description</a></span>
+                  <a href="#harfbuzz-hb-map.description" class="shortcut">Description</a></span><span id="nav_hierarchy">  <span class="dim">|</span> 
+                  <a href="#harfbuzz-hb-map.object-hierarchy" class="shortcut">Object Hierarchy</a></span>
 </td>
 <td><a accesskey="h" href="index.html"><img src="home.png" width="16" height="16" border="0" alt="Home"></a></td>
-<td><a accesskey="u" href="ch09.html"><img src="up.png" width="16" height="16" border="0" alt="Up"></a></td>
+<td><a accesskey="u" href="ch11.html"><img src="up.png" width="16" height="16" border="0" alt="Up"></a></td>
 <td><a accesskey="p" href="harfbuzz-hb-font.html"><img src="left.png" width="16" height="16" border="0" alt="Prev"></a></td>
 <td><a accesskey="n" href="harfbuzz-hb-set.html"><img src="right.png" width="16" height="16" border="0" alt="Next"></a></td>
 </tr></table>
@@ -57,7 +58,7 @@
 </tr>
 <tr>
 <td class="function_type">
-<a class="link" href="harfbuzz-hb-map.html#hb-map-t" title="hb_map_t"><span class="returnvalue">hb_map_t</span></a> *
+<a class="link" href="harfbuzz-hb-map.html#hb-map-t"><span class="returnvalue">hb_map_t</span></a> *
 </td>
 <td class="function_name">
 <a class="link" href="harfbuzz-hb-map.html#hb-map-create" title="hb_map_create ()">hb_map_create</a> <span class="c_punctuation">()</span>
@@ -89,7 +90,7 @@
 </tr>
 <tr>
 <td class="function_type">
-<a class="link" href="harfbuzz-hb-map.html#hb-map-t" title="hb_map_t"><span class="returnvalue">hb_map_t</span></a> *
+<a class="link" href="harfbuzz-hb-map.html#hb-map-t"><span class="returnvalue">hb_map_t</span></a> *
 </td>
 <td class="function_name">
 <a class="link" href="harfbuzz-hb-map.html#hb-map-get-empty" title="hb_map_get_empty ()">hb_map_get_empty</a> <span class="c_punctuation">()</span>
 </tr>
 <tr>
 <td class="function_type">
-<a class="link" href="harfbuzz-hb-map.html#hb-map-t" title="hb_map_t"><span class="returnvalue">hb_map_t</span></a> *
+<a class="link" href="harfbuzz-hb-map.html#hb-map-t"><span class="returnvalue">hb_map_t</span></a> *
 </td>
 <td class="function_name">
 <a class="link" href="harfbuzz-hb-map.html#hb-map-reference" title="hb_map_reference ()">hb_map_reference</a> <span class="c_punctuation">()</span>
 </tbody>
 </table></div>
 </div>
-<div class="refsect1">
+<a name="hb-map-t"></a><div class="refsect1">
 <a name="harfbuzz-hb-map.other"></a><h2>Types and Values</h2>
 <div class="informaltable"><table class="informaltable" width="100%" border="0">
 <colgroup>
 </tr>
 <tr>
 <td class="typedef_keyword">typedef</td>
-<td class="function_name"><a class="link" href="harfbuzz-hb-map.html#hb-map-t" title="hb_map_t">hb_map_t</a></td>
+<td class="function_name"><a class="link" href="harfbuzz-hb-map.html#hb-map-t">hb_map_t</a></td>
 </tr>
 </tbody>
 </table></div>
 </div>
 <div class="refsect1">
+<a name="harfbuzz-hb-map.object-hierarchy"></a><h2>Object Hierarchy</h2>
+<pre class="screen">    <a href="/usr/share/gtk-doc/html/gobject/gobject-Boxed-Types.html">GBoxed</a>
+    <span class="lineart">╰──</span> hb_map_t
+</pre>
+</div>
+<div class="refsect1">
 <a name="harfbuzz-hb-map.includes"></a><h2>Includes</h2>
 <pre class="synopsis">#include &lt;hb.h&gt;
 </pre>
@@ -188,7 +195,7 @@ use if desired.</p>
 <div class="refsect2">
 <a name="hb-map-allocation-successful"></a><h3>hb_map_allocation_successful ()</h3>
 <pre class="programlisting"><a class="link" href="harfbuzz-hb-common.html#hb-bool-t" title="hb_bool_t"><span class="returnvalue">hb_bool_t</span></a>
-hb_map_allocation_successful (<em class="parameter"><code>const <a class="link" href="harfbuzz-hb-map.html#hb-map-t" title="hb_map_t"><span class="type">hb_map_t</span></a> *map</code></em>);</pre>
+hb_map_allocation_successful (<em class="parameter"><code>const <a class="link" href="harfbuzz-hb-map.html#hb-map-t"><span class="type">hb_map_t</span></a> *map</code></em>);</pre>
 <div class="refsect3">
 <a name="hb-map-allocation-successful.parameters"></a><h4>Parameters</h4>
 <div class="informaltable"><table class="informaltable" width="100%" border="0">
@@ -210,7 +217,7 @@ hb_map_allocation_successful (<em class="parameter"><code>const <a class="link"
 <div class="refsect2">
 <a name="hb-map-clear"></a><h3>hb_map_clear ()</h3>
 <pre class="programlisting"><span class="returnvalue">void</span>
-hb_map_clear (<em class="parameter"><code><a class="link" href="harfbuzz-hb-map.html#hb-map-t" title="hb_map_t"><span class="type">hb_map_t</span></a> *map</code></em>);</pre>
+hb_map_clear (<em class="parameter"><code><a class="link" href="harfbuzz-hb-map.html#hb-map-t"><span class="type">hb_map_t</span></a> *map</code></em>);</pre>
 <div class="refsect3">
 <a name="hb-map-clear.parameters"></a><h4>Parameters</h4>
 <div class="informaltable"><table class="informaltable" width="100%" border="0">
@@ -231,7 +238,7 @@ hb_map_clear (<em class="parameter"><code><a class="link" href="harfbuzz-hb-map.
 <hr>
 <div class="refsect2">
 <a name="hb-map-create"></a><h3>hb_map_create ()</h3>
-<pre class="programlisting"><a class="link" href="harfbuzz-hb-map.html#hb-map-t" title="hb_map_t"><span class="returnvalue">hb_map_t</span></a> *
+<pre class="programlisting"><a class="link" href="harfbuzz-hb-map.html#hb-map-t"><span class="returnvalue">hb_map_t</span></a> *
 hb_map_create (<em class="parameter"><code><span class="type">void</span></code></em>);</pre>
 <p><span class="annotation">[Xconstructor]</span></p>
 <div class="refsect3">
@@ -245,7 +252,7 @@ hb_map_create (<em class="parameter"><code><span class="type">void</span></code>
 <div class="refsect2">
 <a name="hb-map-del"></a><h3>hb_map_del ()</h3>
 <pre class="programlisting"><span class="returnvalue">void</span>
-hb_map_del (<em class="parameter"><code><a class="link" href="harfbuzz-hb-map.html#hb-map-t" title="hb_map_t"><span class="type">hb_map_t</span></a> *map</code></em>,
+hb_map_del (<em class="parameter"><code><a class="link" href="harfbuzz-hb-map.html#hb-map-t"><span class="type">hb_map_t</span></a> *map</code></em>,
             <em class="parameter"><code><a class="link" href="harfbuzz-hb-common.html#hb-codepoint-t" title="hb_codepoint_t"><span class="type">hb_codepoint_t</span></a> key</code></em>);</pre>
 <div class="refsect3">
 <a name="hb-map-del.parameters"></a><h4>Parameters</h4>
@@ -268,7 +275,7 @@ hb_map_del (<em class="parameter"><code><a class="link" href="harfbuzz-hb-map.ht
 <div class="refsect2">
 <a name="hb-map-destroy"></a><h3>hb_map_destroy ()</h3>
 <pre class="programlisting"><span class="returnvalue">void</span>
-hb_map_destroy (<em class="parameter"><code><a class="link" href="harfbuzz-hb-map.html#hb-map-t" title="hb_map_t"><span class="type">hb_map_t</span></a> *map</code></em>);</pre>
+hb_map_destroy (<em class="parameter"><code><a class="link" href="harfbuzz-hb-map.html#hb-map-t"><span class="type">hb_map_t</span></a> *map</code></em>);</pre>
 <p><span class="annotation">[<acronym title="Exposed in C code, not necessarily available in other languages."><span class="acronym">skip</span></acronym>]</span></p>
 <div class="refsect3">
 <a name="hb-map-destroy.parameters"></a><h4>Parameters</h4>
@@ -291,7 +298,7 @@ hb_map_destroy (<em class="parameter"><code><a class="link" href="harfbuzz-hb-ma
 <div class="refsect2">
 <a name="hb-map-get"></a><h3>hb_map_get ()</h3>
 <pre class="programlisting"><a class="link" href="harfbuzz-hb-common.html#hb-codepoint-t" title="hb_codepoint_t"><span class="returnvalue">hb_codepoint_t</span></a>
-hb_map_get (<em class="parameter"><code>const <a class="link" href="harfbuzz-hb-map.html#hb-map-t" title="hb_map_t"><span class="type">hb_map_t</span></a> *map</code></em>,
+hb_map_get (<em class="parameter"><code>const <a class="link" href="harfbuzz-hb-map.html#hb-map-t"><span class="type">hb_map_t</span></a> *map</code></em>,
             <em class="parameter"><code><a class="link" href="harfbuzz-hb-common.html#hb-codepoint-t" title="hb_codepoint_t"><span class="type">hb_codepoint_t</span></a> key</code></em>);</pre>
 <div class="refsect3">
 <a name="hb-map-get.parameters"></a><h4>Parameters</h4>
@@ -313,7 +320,7 @@ hb_map_get (<em class="parameter"><code>const <a class="link" href="harfbuzz-hb-
 <hr>
 <div class="refsect2">
 <a name="hb-map-get-empty"></a><h3>hb_map_get_empty ()</h3>
-<pre class="programlisting"><a class="link" href="harfbuzz-hb-map.html#hb-map-t" title="hb_map_t"><span class="returnvalue">hb_map_t</span></a> *
+<pre class="programlisting"><a class="link" href="harfbuzz-hb-map.html#hb-map-t"><span class="returnvalue">hb_map_t</span></a> *
 hb_map_get_empty (<em class="parameter"><code><span class="type">void</span></code></em>);</pre>
 <div class="refsect3">
 <a name="hb-map-get-empty.returns"></a><h4>Returns</h4>
@@ -326,7 +333,7 @@ hb_map_get_empty (<em class="parameter"><code><span class="type">void</span></co
 <div class="refsect2">
 <a name="hb-map-get-population"></a><h3>hb_map_get_population ()</h3>
 <pre class="programlisting">unsigned <span class="returnvalue">int</span>
-hb_map_get_population (<em class="parameter"><code>const <a class="link" href="harfbuzz-hb-map.html#hb-map-t" title="hb_map_t"><span class="type">hb_map_t</span></a> *map</code></em>);</pre>
+hb_map_get_population (<em class="parameter"><code>const <a class="link" href="harfbuzz-hb-map.html#hb-map-t"><span class="type">hb_map_t</span></a> *map</code></em>);</pre>
 <div class="refsect3">
 <a name="hb-map-get-population.parameters"></a><h4>Parameters</h4>
 <div class="informaltable"><table class="informaltable" width="100%" border="0">
@@ -348,8 +355,8 @@ hb_map_get_population (<em class="parameter"><code>const <a class="link" href="h
 <div class="refsect2">
 <a name="hb-map-get-user-data"></a><h3>hb_map_get_user_data ()</h3>
 <pre class="programlisting"><span class="returnvalue">void</span> *
-hb_map_get_user_data (<em class="parameter"><code><a class="link" href="harfbuzz-hb-map.html#hb-map-t" title="hb_map_t"><span class="type">hb_map_t</span></a> *map</code></em>,
-                      <em class="parameter"><code><a class="link" href="harfbuzz-hb-common.html#hb-user-data-key-t" title="hb_user_data_key_t"><span class="type">hb_user_data_key_t</span></a> *key</code></em>);</pre>
+hb_map_get_user_data (<em class="parameter"><code><a class="link" href="harfbuzz-hb-map.html#hb-map-t"><span class="type">hb_map_t</span></a> *map</code></em>,
+                      <em class="parameter"><code><a class="link" href="harfbuzz-hb-common.html#hb-user-data-key-t"><span class="type">hb_user_data_key_t</span></a> *key</code></em>);</pre>
 <p><span class="annotation">[<acronym title="Exposed in C code, not necessarily available in other languages."><span class="acronym">skip</span></acronym>]</span></p>
 <div class="refsect3">
 <a name="hb-map-get-user-data.parameters"></a><h4>Parameters</h4>
@@ -377,7 +384,7 @@ hb_map_get_user_data (<em class="parameter"><code><a class="link" href="harfbuzz
 <div class="refsect2">
 <a name="hb-map-has"></a><h3>hb_map_has ()</h3>
 <pre class="programlisting"><a class="link" href="harfbuzz-hb-common.html#hb-bool-t" title="hb_bool_t"><span class="returnvalue">hb_bool_t</span></a>
-hb_map_has (<em class="parameter"><code>const <a class="link" href="harfbuzz-hb-map.html#hb-map-t" title="hb_map_t"><span class="type">hb_map_t</span></a> *map</code></em>,
+hb_map_has (<em class="parameter"><code>const <a class="link" href="harfbuzz-hb-map.html#hb-map-t"><span class="type">hb_map_t</span></a> *map</code></em>,
             <em class="parameter"><code><a class="link" href="harfbuzz-hb-common.html#hb-codepoint-t" title="hb_codepoint_t"><span class="type">hb_codepoint_t</span></a> key</code></em>);</pre>
 <div class="refsect3">
 <a name="hb-map-has.parameters"></a><h4>Parameters</h4>
@@ -400,7 +407,7 @@ hb_map_has (<em class="parameter"><code>const <a class="link" href="harfbuzz-hb-
 <div class="refsect2">
 <a name="hb-map-is-empty"></a><h3>hb_map_is_empty ()</h3>
 <pre class="programlisting"><a class="link" href="harfbuzz-hb-common.html#hb-bool-t" title="hb_bool_t"><span class="returnvalue">hb_bool_t</span></a>
-hb_map_is_empty (<em class="parameter"><code>const <a class="link" href="harfbuzz-hb-map.html#hb-map-t" title="hb_map_t"><span class="type">hb_map_t</span></a> *map</code></em>);</pre>
+hb_map_is_empty (<em class="parameter"><code>const <a class="link" href="harfbuzz-hb-map.html#hb-map-t"><span class="type">hb_map_t</span></a> *map</code></em>);</pre>
 <div class="refsect3">
 <a name="hb-map-is-empty.parameters"></a><h4>Parameters</h4>
 <div class="informaltable"><table class="informaltable" width="100%" border="0">
@@ -421,8 +428,8 @@ hb_map_is_empty (<em class="parameter"><code>const <a class="link" href="harfbuz
 <hr>
 <div class="refsect2">
 <a name="hb-map-reference"></a><h3>hb_map_reference ()</h3>
-<pre class="programlisting"><a class="link" href="harfbuzz-hb-map.html#hb-map-t" title="hb_map_t"><span class="returnvalue">hb_map_t</span></a> *
-hb_map_reference (<em class="parameter"><code><a class="link" href="harfbuzz-hb-map.html#hb-map-t" title="hb_map_t"><span class="type">hb_map_t</span></a> *map</code></em>);</pre>
+<pre class="programlisting"><a class="link" href="harfbuzz-hb-map.html#hb-map-t"><span class="returnvalue">hb_map_t</span></a> *
+hb_map_reference (<em class="parameter"><code><a class="link" href="harfbuzz-hb-map.html#hb-map-t"><span class="type">hb_map_t</span></a> *map</code></em>);</pre>
 <p><span class="annotation">[<acronym title="Exposed in C code, not necessarily available in other languages."><span class="acronym">skip</span></acronym>]</span></p>
 <div class="refsect3">
 <a name="hb-map-reference.parameters"></a><h4>Parameters</h4>
@@ -450,7 +457,7 @@ hb_map_reference (<em class="parameter"><code><a class="link" href="harfbuzz-hb-
 <div class="refsect2">
 <a name="hb-map-set"></a><h3>hb_map_set ()</h3>
 <pre class="programlisting"><span class="returnvalue">void</span>
-hb_map_set (<em class="parameter"><code><a class="link" href="harfbuzz-hb-map.html#hb-map-t" title="hb_map_t"><span class="type">hb_map_t</span></a> *map</code></em>,
+hb_map_set (<em class="parameter"><code><a class="link" href="harfbuzz-hb-map.html#hb-map-t"><span class="type">hb_map_t</span></a> *map</code></em>,
             <em class="parameter"><code><a class="link" href="harfbuzz-hb-common.html#hb-codepoint-t" title="hb_codepoint_t"><span class="type">hb_codepoint_t</span></a> key</code></em>,
             <em class="parameter"><code><a class="link" href="harfbuzz-hb-common.html#hb-codepoint-t" title="hb_codepoint_t"><span class="type">hb_codepoint_t</span></a> value</code></em>);</pre>
 <div class="refsect3">
@@ -474,8 +481,8 @@ hb_map_set (<em class="parameter"><code><a class="link" href="harfbuzz-hb-map.ht
 <div class="refsect2">
 <a name="hb-map-set-user-data"></a><h3>hb_map_set_user_data ()</h3>
 <pre class="programlisting"><a class="link" href="harfbuzz-hb-common.html#hb-bool-t" title="hb_bool_t"><span class="returnvalue">hb_bool_t</span></a>
-hb_map_set_user_data (<em class="parameter"><code><a class="link" href="harfbuzz-hb-map.html#hb-map-t" title="hb_map_t"><span class="type">hb_map_t</span></a> *map</code></em>,
-                      <em class="parameter"><code><a class="link" href="harfbuzz-hb-common.html#hb-user-data-key-t" title="hb_user_data_key_t"><span class="type">hb_user_data_key_t</span></a> *key</code></em>,
+hb_map_set_user_data (<em class="parameter"><code><a class="link" href="harfbuzz-hb-map.html#hb-map-t"><span class="type">hb_map_t</span></a> *map</code></em>,
+                      <em class="parameter"><code><a class="link" href="harfbuzz-hb-common.html#hb-user-data-key-t"><span class="type">hb_user_data_key_t</span></a> *key</code></em>,
                       <em class="parameter"><code><span class="type">void</span> *data</code></em>,
                       <em class="parameter"><code><a class="link" href="harfbuzz-hb-common.html#hb-destroy-func-t" title="hb_destroy_func_t ()"><span class="type">hb_destroy_func_t</span></a> destroy</code></em>,
                       <em class="parameter"><code><a class="link" href="harfbuzz-hb-common.html#hb-bool-t" title="hb_bool_t"><span class="type">hb_bool_t</span></a> replace</code></em>);</pre>
index 0d230e0..ed364e4 100644 (file)
@@ -5,8 +5,8 @@
 <title>hb-ot-color: HarfBuzz Manual</title>
 <meta name="generator" content="DocBook XSL Stylesheets Vsnapshot">
 <link rel="home" href="index.html" title="HarfBuzz Manual">
-<link rel="up" href="ch10.html" title="OpenType API">
-<link rel="prev" href="ch10.html" title="OpenType API">
+<link rel="up" href="ch12.html" title="OpenType API">
+<link rel="prev" href="ch12.html" title="OpenType API">
 <link rel="next" href="harfbuzz-hb-ot-font.html" title="hb-ot-font">
 <meta name="generator" content="GTK-Doc V1.29 (XML mode)">
 <link rel="stylesheet" href="style.css" type="text/css">
 <table class="navigation" id="top" width="100%" summary="Navigation header" cellpadding="2" cellspacing="5"><tr valign="middle">
 <td width="100%" align="left" class="shortcuts">
 <a href="#" class="shortcut">Top</a><span id="nav_description">  <span class="dim">|</span> 
-                  <a href="#harfbuzz-hb-ot-color.description" class="shortcut">Description</a></span>
+                  <a href="#harfbuzz-hb-ot-color.description" class="shortcut">Description</a></span><span id="nav_hierarchy">  <span class="dim">|</span> 
+                  <a href="#harfbuzz-hb-ot-color.object-hierarchy" class="shortcut">Object Hierarchy</a></span>
 </td>
 <td><a accesskey="h" href="index.html"><img src="home.png" width="16" height="16" border="0" alt="Home"></a></td>
-<td><a accesskey="u" href="ch10.html"><img src="up.png" width="16" height="16" border="0" alt="Up"></a></td>
-<td><a accesskey="p" href="ch10.html"><img src="left.png" width="16" height="16" border="0" alt="Prev"></a></td>
+<td><a accesskey="u" href="ch12.html"><img src="up.png" width="16" height="16" border="0" alt="Up"></a></td>
+<td><a accesskey="p" href="ch12.html"><img src="left.png" width="16" height="16" border="0" alt="Prev"></a></td>
 <td><a accesskey="n" href="harfbuzz-hb-ot-font.html"><img src="right.png" width="16" height="16" border="0" alt="Next"></a></td>
 </tr></table>
 <div class="refentry">
 </td>
 </tr>
 <tr>
-<td class="define_keyword">#define</td>
+<td class="function_type">
+<span class="returnvalue">uint8_t</span>
+</td>
 <td class="function_name">
-<a class="link" href="harfbuzz-hb-ot-color.html#hb-color-get-alpha" title="hb_color_get_alpha()">hb_color_get_alpha</a><span class="c_punctuation">()</span>
+<a class="link" href="harfbuzz-hb-ot-color.html#hb-color-get-alpha" title="hb_color_get_alpha ()">hb_color_get_alpha</a> <span class="c_punctuation">()</span>
 </td>
 </tr>
 <tr>
-<td class="define_keyword">#define</td>
+<td class="function_type">
+<span class="returnvalue">uint8_t</span>
+</td>
 <td class="function_name">
-<a class="link" href="harfbuzz-hb-ot-color.html#hb-color-get-blue" title="hb_color_get_blue()">hb_color_get_blue</a><span class="c_punctuation">()</span>
+<a class="link" href="harfbuzz-hb-ot-color.html#hb-color-get-blue" title="hb_color_get_blue ()">hb_color_get_blue</a> <span class="c_punctuation">()</span>
 </td>
 </tr>
 <tr>
-<td class="define_keyword">#define</td>
+<td class="function_type">
+<span class="returnvalue">uint8_t</span>
+</td>
 <td class="function_name">
-<a class="link" href="harfbuzz-hb-ot-color.html#hb-color-get-green" title="hb_color_get_green()">hb_color_get_green</a><span class="c_punctuation">()</span>
+<a class="link" href="harfbuzz-hb-ot-color.html#hb-color-get-green" title="hb_color_get_green ()">hb_color_get_green</a> <span class="c_punctuation">()</span>
 </td>
 </tr>
 <tr>
-<td class="define_keyword">#define</td>
+<td class="function_type">
+<span class="returnvalue">uint8_t</span>
+</td>
 <td class="function_name">
-<a class="link" href="harfbuzz-hb-ot-color.html#hb-color-get-red" title="hb_color_get_red()">hb_color_get_red</a><span class="c_punctuation">()</span>
+<a class="link" href="harfbuzz-hb-ot-color.html#hb-color-get-red" title="hb_color_get_red ()">hb_color_get_red</a> <span class="c_punctuation">()</span>
 </td>
 </tr>
 <tr>
@@ -78,7 +87,7 @@
 </tr>
 <tr>
 <td class="function_type">
-<a class="link" href="harfbuzz-hb-blob.html#hb-blob-t" title="hb_blob_t"><span class="returnvalue">hb_blob_t</span></a> *
+<a class="link" href="harfbuzz-hb-blob.html#hb-blob-t"><span class="returnvalue">hb_blob_t</span></a> *
 </td>
 <td class="function_name">
 <a class="link" href="harfbuzz-hb-ot-color.html#hb-ot-color-glyph-reference-png" title="hb_ot_color_glyph_reference_png ()">hb_ot_color_glyph_reference_png</a> <span class="c_punctuation">()</span>
@@ -86,7 +95,7 @@
 </tr>
 <tr>
 <td class="function_type">
-<a class="link" href="harfbuzz-hb-blob.html#hb-blob-t" title="hb_blob_t"><span class="returnvalue">hb_blob_t</span></a> *
+<a class="link" href="harfbuzz-hb-blob.html#hb-blob-t"><span class="returnvalue">hb_blob_t</span></a> *
 </td>
 <td class="function_name">
 <a class="link" href="harfbuzz-hb-ot-color.html#hb-ot-color-glyph-reference-svg" title="hb_ot_color_glyph_reference_svg ()">hb_ot_color_glyph_reference_svg</a> <span class="c_punctuation">()</span>
 </table></div>
 </div>
 <div class="refsect1">
+<a name="harfbuzz-hb-ot-color.object-hierarchy"></a><h2>Object Hierarchy</h2>
+<pre class="screen">    <a href="/usr/share/gtk-doc/html/gobject/gobject-Enumeration-and-Flag-Types.html">GFlags</a>
+    <span class="lineart">╰──</span> hb_ot_color_palette_flags_t
+</pre>
+</div>
+<div class="refsect1">
 <a name="harfbuzz-hb-ot-color.includes"></a><h2>Includes</h2>
 <pre class="synopsis">#include &lt;hb-ot.h&gt;
 </pre>
 <div class="refsect1">
 <a name="harfbuzz-hb-ot-color.description"></a><h2>Description</h2>
 <p>Functions for fetching color-font information from OpenType font faces.</p>
+<p>HarfBuzz supports <code class="literal">COLR</code>/<code class="literal">CPAL</code>, <code class="literal">sbix</code>, <code class="literal">CBDT</code>, and <code class="literal">SVG</code> color fonts.</p>
 </div>
 <div class="refsect1">
 <a name="harfbuzz-hb-ot-color.functions_details"></a><h2>Functions</h2>
 </div>
 <hr>
 <div class="refsect2">
-<a name="hb-color-get-alpha"></a><h3>hb_color_get_alpha()</h3>
-<pre class="programlisting">#define hb_color_get_alpha(color) ((color) &amp; 0xFF)
-</pre>
+<a name="hb-color-get-alpha"></a><h3>hb_color_get_alpha ()</h3>
+<pre class="programlisting"><span class="returnvalue">uint8_t</span>
+hb_color_get_alpha (<em class="parameter"><code><a class="link" href="harfbuzz-hb-ot-color.html#hb-color-t" title="hb_color_t"><span class="type">hb_color_t</span></a> color</code></em>);</pre>
+<div class="refsect3">
+<a name="hb-color-get-alpha.returns"></a><h4>Returns</h4>
+<p> Alpha channel value of the given color</p>
+</div>
 <p class="since">Since: <a class="link" href="api-index-2-1-0.html#api-index-2.1.0">2.1.0</a></p>
 </div>
 <hr>
 <div class="refsect2">
-<a name="hb-color-get-blue"></a><h3>hb_color_get_blue()</h3>
-<pre class="programlisting">#define hb_color_get_blue(color) (((color) &gt;&gt; 24) &amp; 0xFF)
-</pre>
+<a name="hb-color-get-blue"></a><h3>hb_color_get_blue ()</h3>
+<pre class="programlisting"><span class="returnvalue">uint8_t</span>
+hb_color_get_blue (<em class="parameter"><code><a class="link" href="harfbuzz-hb-ot-color.html#hb-color-t" title="hb_color_t"><span class="type">hb_color_t</span></a> color</code></em>);</pre>
+<div class="refsect3">
+<a name="hb-color-get-blue.returns"></a><h4>Returns</h4>
+<p> Blue channel value of the given color</p>
+</div>
 <p class="since">Since: <a class="link" href="api-index-2-1-0.html#api-index-2.1.0">2.1.0</a></p>
 </div>
 <hr>
 <div class="refsect2">
-<a name="hb-color-get-green"></a><h3>hb_color_get_green()</h3>
-<pre class="programlisting">#define hb_color_get_green(color) (((color) &gt;&gt; 16) &amp; 0xFF)
-</pre>
+<a name="hb-color-get-green"></a><h3>hb_color_get_green ()</h3>
+<pre class="programlisting"><span class="returnvalue">uint8_t</span>
+hb_color_get_green (<em class="parameter"><code><a class="link" href="harfbuzz-hb-ot-color.html#hb-color-t" title="hb_color_t"><span class="type">hb_color_t</span></a> color</code></em>);</pre>
+<div class="refsect3">
+<a name="hb-color-get-green.returns"></a><h4>Returns</h4>
+<p> Green channel value of the given color</p>
+</div>
 <p class="since">Since: <a class="link" href="api-index-2-1-0.html#api-index-2.1.0">2.1.0</a></p>
 </div>
 <hr>
 <div class="refsect2">
-<a name="hb-color-get-red"></a><h3>hb_color_get_red()</h3>
-<pre class="programlisting">#define hb_color_get_red(color)            (((color) &gt;&gt; 8) &amp; 0xFF)
-</pre>
+<a name="hb-color-get-red"></a><h3>hb_color_get_red ()</h3>
+<pre class="programlisting"><span class="returnvalue">uint8_t</span>
+hb_color_get_red (<em class="parameter"><code><a class="link" href="harfbuzz-hb-ot-color.html#hb-color-t" title="hb_color_t"><span class="type">hb_color_t</span></a> color</code></em>);</pre>
+<div class="refsect3">
+<a name="hb-color-get-red.returns"></a><h4>Returns</h4>
+<p> Red channel value of the given color</p>
+</div>
 <p class="since">Since: <a class="link" href="api-index-2-1-0.html#api-index-2.1.0">2.1.0</a></p>
 </div>
 <hr>
 <div class="refsect2">
 <a name="hb-ot-color-glyph-get-layers"></a><h3>hb_ot_color_glyph_get_layers ()</h3>
 <pre class="programlisting">unsigned <span class="returnvalue">int</span>
-hb_ot_color_glyph_get_layers (<em class="parameter"><code><a class="link" href="harfbuzz-hb-face.html#hb-face-t" title="hb_face_t"><span class="type">hb_face_t</span></a> *face</code></em>,
+hb_ot_color_glyph_get_layers (<em class="parameter"><code><a class="link" href="harfbuzz-hb-face.html#hb-face-t"><span class="type">hb_face_t</span></a> *face</code></em>,
                               <em class="parameter"><code><a class="link" href="harfbuzz-hb-common.html#hb-codepoint-t" title="hb_codepoint_t"><span class="type">hb_codepoint_t</span></a> glyph</code></em>,
                               <em class="parameter"><code>unsigned <span class="type">int</span> start_offset</code></em>,
-                              <em class="parameter"><code>unsigned <span class="type">int</span> *count</code></em>,
+                              <em class="parameter"><code>unsigned <span class="type">int</span> *layer_count</code></em>,
                               <em class="parameter"><code><span class="type">hb_ot_color_layer_t</span> *layers</code></em>);</pre>
+<p>Fetches a list of all color layers for the specified glyph index in the specified
+face. The list returned will begin at the offset provided.</p>
 <div class="refsect3">
 <a name="hb-ot-color-glyph-get-layers.parameters"></a><h4>Parameters</h4>
 <div class="informaltable"><table class="informaltable" width="100%" border="0">
@@ -248,46 +282,49 @@ hb_ot_color_glyph_get_layers (<em class="parameter"><code><a class="link" href="
 <tbody>
 <tr>
 <td class="parameter_name"><p>face</p></td>
-<td class="parameter_description"><p>a font face.</p></td>
+<td class="parameter_description"><p><a class="link" href="harfbuzz-hb-face.html#hb-face-t"><span class="type">hb_face_t</span></a> to work upon</p></td>
 <td class="parameter_annotations"> </td>
 </tr>
 <tr>
 <td class="parameter_name"><p>glyph</p></td>
-<td class="parameter_description"><p>a layered color glyph id.</p></td>
+<td class="parameter_description"><p>The glyph index to query</p></td>
 <td class="parameter_annotations"> </td>
 </tr>
 <tr>
 <td class="parameter_name"><p>start_offset</p></td>
-<td class="parameter_description"><p>starting offset of layers.</p></td>
+<td class="parameter_description"><p>offset of the first layer to retrieve</p></td>
 <td class="parameter_annotations"> </td>
 </tr>
 <tr>
-<td class="parameter_name"><p>count</p></td>
-<td class="parameter_description"><p>gets number of layers available to be written on buffer
-and returns number of written layers. </p></td>
+<td class="parameter_name"><p>layer_count</p></td>
+<td class="parameter_description"><p>Input = the maximum number of layers to return;
+Output = the actual number of layers returned (may be zero). </p></td>
 <td class="parameter_annotations"><span class="annotation">[<acronym title="Parameter for input and for returning results. Default is transfer full."><span class="acronym">inout</span></acronym>][<acronym title="NULL may be passed instead of a pointer to a location."><span class="acronym">optional</span></acronym>]</span></td>
 </tr>
 <tr>
 <td class="parameter_name"><p>layers</p></td>
-<td class="parameter_description"><p>layers buffer to buffer. </p></td>
-<td class="parameter_annotations"><span class="annotation">[<acronym title="Parameter points to an array of items."><span class="acronym">array</span></acronym> length=count][<acronym title="Parameter for returning results. Default is transfer full."><span class="acronym">out</span></acronym>][<acronym title="NULL may be passed instead of a pointer to a location."><span class="acronym">optional</span></acronym>]</span></td>
+<td class="parameter_description"><p>The array of layers found. </p></td>
+<td class="parameter_annotations"><span class="annotation">[<acronym title="Parameter for returning results. Default is transfer full."><span class="acronym">out</span></acronym>][<acronym title="Parameter points to an array of items."><span class="acronym">array</span></acronym> length=layer_count][<acronym title="NULL may be passed as the value in, out, in-out; or as a return value."><span class="acronym">nullable</span></acronym>]</span></td>
 </tr>
 </tbody>
 </table></div>
 </div>
 <div class="refsect3">
 <a name="hb-ot-color-glyph-get-layers.returns"></a><h4>Returns</h4>
-<p> Total number of layers a layered color glyph have.</p>
+<p> Total number of layers available for the glyph index queried</p>
 </div>
 <p class="since">Since: <a class="link" href="api-index-2-1-0.html#api-index-2.1.0">2.1.0</a></p>
 </div>
 <hr>
 <div class="refsect2">
 <a name="hb-ot-color-glyph-reference-png"></a><h3>hb_ot_color_glyph_reference_png ()</h3>
-<pre class="programlisting"><a class="link" href="harfbuzz-hb-blob.html#hb-blob-t" title="hb_blob_t"><span class="returnvalue">hb_blob_t</span></a> *
-hb_ot_color_glyph_reference_png (<em class="parameter"><code><a class="link" href="harfbuzz-hb-font.html#hb-font-t" title="hb_font_t"><span class="type">hb_font_t</span></a> *font</code></em>,
+<pre class="programlisting"><a class="link" href="harfbuzz-hb-blob.html#hb-blob-t"><span class="returnvalue">hb_blob_t</span></a> *
+hb_ot_color_glyph_reference_png (<em class="parameter"><code><a class="link" href="harfbuzz-hb-font.html#hb-font-t"><span class="type">hb_font_t</span></a> *font</code></em>,
                                  <em class="parameter"><code><a class="link" href="harfbuzz-hb-common.html#hb-codepoint-t" title="hb_codepoint_t"><span class="type">hb_codepoint_t</span></a> glyph</code></em>);</pre>
-<p>Get PNG image for a glyph.</p>
+<p>Fetches the PNG image for a glyph. This function takes a font object, not a face object,
+as input. To get an optimally sized PNG blob, the UPEM value must be set on the <em class="parameter"><code>font</code></em>
+
+object. If UPEM is unset, the blob returned will be the largest PNG available.</p>
 <div class="refsect3">
 <a name="hb-ot-color-glyph-reference-png.parameters"></a><h4>Parameters</h4>
 <div class="informaltable"><table class="informaltable" width="100%" border="0">
@@ -299,14 +336,12 @@ hb_ot_color_glyph_reference_png (<em class="parameter"><code><a class="link" hre
 <tbody>
 <tr>
 <td class="parameter_name"><p>font</p></td>
-<td class="parameter_description"><p>a font object, not face. upem should be set on
-that font object if one wants to get optimal png blob, otherwise
-return the biggest one</p></td>
+<td class="parameter_description"><p><a class="link" href="harfbuzz-hb-font.html#hb-font-t"><span class="type">hb_font_t</span></a> to work upon</p></td>
 <td class="parameter_annotations"> </td>
 </tr>
 <tr>
 <td class="parameter_name"><p>glyph</p></td>
-<td class="parameter_description"><p>a glyph index.</p></td>
+<td class="parameter_description"><p>a glyph index</p></td>
 <td class="parameter_annotations"> </td>
 </tr>
 </tbody>
@@ -314,7 +349,7 @@ return the biggest one</p></td>
 </div>
 <div class="refsect3">
 <a name="hb-ot-color-glyph-reference-png.returns"></a><h4>Returns</h4>
-<p>respective PNG blob of the glyph, if available. </p>
+<p>An <a class="link" href="harfbuzz-hb-blob.html#hb-blob-t"><span class="type">hb_blob_t</span></a> containing the PNG image for the glyph, if available. </p>
 <p><span class="annotation">[<acronym title="Free data after the code is done."><span class="acronym">transfer full</span></acronym>]</span></p>
 </div>
 <p class="since">Since: <a class="link" href="api-index-2-1-0.html#api-index-2.1.0">2.1.0</a></p>
@@ -322,10 +357,10 @@ return the biggest one</p></td>
 <hr>
 <div class="refsect2">
 <a name="hb-ot-color-glyph-reference-svg"></a><h3>hb_ot_color_glyph_reference_svg ()</h3>
-<pre class="programlisting"><a class="link" href="harfbuzz-hb-blob.html#hb-blob-t" title="hb_blob_t"><span class="returnvalue">hb_blob_t</span></a> *
-hb_ot_color_glyph_reference_svg (<em class="parameter"><code><a class="link" href="harfbuzz-hb-face.html#hb-face-t" title="hb_face_t"><span class="type">hb_face_t</span></a> *face</code></em>,
+<pre class="programlisting"><a class="link" href="harfbuzz-hb-blob.html#hb-blob-t"><span class="returnvalue">hb_blob_t</span></a> *
+hb_ot_color_glyph_reference_svg (<em class="parameter"><code><a class="link" href="harfbuzz-hb-face.html#hb-face-t"><span class="type">hb_face_t</span></a> *face</code></em>,
                                  <em class="parameter"><code><a class="link" href="harfbuzz-hb-common.html#hb-codepoint-t" title="hb_codepoint_t"><span class="type">hb_codepoint_t</span></a> glyph</code></em>);</pre>
-<p>Get SVG document for a glyph. The blob may be either plain text or gzip-encoded.</p>
+<p>Fetches the SVG document for a glyph. The blob may be either plain text or gzip-encoded.</p>
 <div class="refsect3">
 <a name="hb-ot-color-glyph-reference-svg.parameters"></a><h4>Parameters</h4>
 <div class="informaltable"><table class="informaltable" width="100%" border="0">
@@ -337,12 +372,12 @@ hb_ot_color_glyph_reference_svg (<em class="parameter"><code><a class="link" hre
 <tbody>
 <tr>
 <td class="parameter_name"><p>face</p></td>
-<td class="parameter_description"><p>a font face.</p></td>
+<td class="parameter_description"><p><a class="link" href="harfbuzz-hb-face.html#hb-face-t"><span class="type">hb_face_t</span></a> to work upon</p></td>
 <td class="parameter_annotations"> </td>
 </tr>
 <tr>
 <td class="parameter_name"><p>glyph</p></td>
-<td class="parameter_description"><p>a svg glyph index.</p></td>
+<td class="parameter_description"><p>a svg glyph index</p></td>
 <td class="parameter_annotations"> </td>
 </tr>
 </tbody>
@@ -350,7 +385,7 @@ hb_ot_color_glyph_reference_svg (<em class="parameter"><code><a class="link" hre
 </div>
 <div class="refsect3">
 <a name="hb-ot-color-glyph-reference-svg.returns"></a><h4>Returns</h4>
-<p>respective svg blob of the glyph, if available. </p>
+<p>An <a class="link" href="harfbuzz-hb-blob.html#hb-blob-t"><span class="type">hb_blob_t</span></a> containing the SVG document of the glyph, if available. </p>
 <p><span class="annotation">[<acronym title="Free data after the code is done."><span class="acronym">transfer full</span></acronym>]</span></p>
 </div>
 <p class="since">Since: <a class="link" href="api-index-2-1-0.html#api-index-2.1.0">2.1.0</a></p>
@@ -359,7 +394,8 @@ hb_ot_color_glyph_reference_svg (<em class="parameter"><code><a class="link" hre
 <div class="refsect2">
 <a name="hb-ot-color-has-layers"></a><h3>hb_ot_color_has_layers ()</h3>
 <pre class="programlisting"><a class="link" href="harfbuzz-hb-common.html#hb-bool-t" title="hb_bool_t"><span class="returnvalue">hb_bool_t</span></a>
-hb_ot_color_has_layers (<em class="parameter"><code><a class="link" href="harfbuzz-hb-face.html#hb-face-t" title="hb_face_t"><span class="type">hb_face_t</span></a> *face</code></em>);</pre>
+hb_ot_color_has_layers (<em class="parameter"><code><a class="link" href="harfbuzz-hb-face.html#hb-face-t"><span class="type">hb_face_t</span></a> *face</code></em>);</pre>
+<p>Tests whether a face includes any <code class="literal">COLR</code> color layers.</p>
 <div class="refsect3">
 <a name="hb-ot-color-has-layers.parameters"></a><h4>Parameters</h4>
 <div class="informaltable"><table class="informaltable" width="100%" border="0">
@@ -370,14 +406,14 @@ hb_ot_color_has_layers (<em class="parameter"><code><a class="link" href="harfbu
 </colgroup>
 <tbody><tr>
 <td class="parameter_name"><p>face</p></td>
-<td class="parameter_description"><p>a font face.</p></td>
+<td class="parameter_description"><p><a class="link" href="harfbuzz-hb-face.html#hb-face-t"><span class="type">hb_face_t</span></a> to work upon</p></td>
 <td class="parameter_annotations"> </td>
 </tr></tbody>
 </table></div>
 </div>
 <div class="refsect3">
 <a name="hb-ot-color-has-layers.returns"></a><h4>Returns</h4>
-<p> whether COLR table is available.</p>
+<p> true if data found, false otherwise</p>
 </div>
 <p class="since">Since: <a class="link" href="api-index-2-1-0.html#api-index-2.1.0">2.1.0</a></p>
 </div>
@@ -385,7 +421,8 @@ hb_ot_color_has_layers (<em class="parameter"><code><a class="link" href="harfbu
 <div class="refsect2">
 <a name="hb-ot-color-has-palettes"></a><h3>hb_ot_color_has_palettes ()</h3>
 <pre class="programlisting"><a class="link" href="harfbuzz-hb-common.html#hb-bool-t" title="hb_bool_t"><span class="returnvalue">hb_bool_t</span></a>
-hb_ot_color_has_palettes (<em class="parameter"><code><a class="link" href="harfbuzz-hb-face.html#hb-face-t" title="hb_face_t"><span class="type">hb_face_t</span></a> *face</code></em>);</pre>
+hb_ot_color_has_palettes (<em class="parameter"><code><a class="link" href="harfbuzz-hb-face.html#hb-face-t"><span class="type">hb_face_t</span></a> *face</code></em>);</pre>
+<p>Tests whether a face includes a <code class="literal">CPAL</code> color-palette table.</p>
 <div class="refsect3">
 <a name="hb-ot-color-has-palettes.parameters"></a><h4>Parameters</h4>
 <div class="informaltable"><table class="informaltable" width="100%" border="0">
@@ -396,14 +433,14 @@ hb_ot_color_has_palettes (<em class="parameter"><code><a class="link" href="harf
 </colgroup>
 <tbody><tr>
 <td class="parameter_name"><p>face</p></td>
-<td class="parameter_description"><p>a font face.</p></td>
+<td class="parameter_description"><p><a class="link" href="harfbuzz-hb-face.html#hb-face-t"><span class="type">hb_face_t</span></a> to work upon</p></td>
 <td class="parameter_annotations"> </td>
 </tr></tbody>
 </table></div>
 </div>
 <div class="refsect3">
 <a name="hb-ot-color-has-palettes.returns"></a><h4>Returns</h4>
-<p> whether CPAL table is available.</p>
+<p> true if data found, false otherwise</p>
 </div>
 <p class="since">Since: <a class="link" href="api-index-2-1-0.html#api-index-2.1.0">2.1.0</a></p>
 </div>
@@ -411,10 +448,8 @@ hb_ot_color_has_palettes (<em class="parameter"><code><a class="link" href="harf
 <div class="refsect2">
 <a name="hb-ot-color-has-png"></a><h3>hb_ot_color_has_png ()</h3>
 <pre class="programlisting"><a class="link" href="harfbuzz-hb-common.html#hb-bool-t" title="hb_bool_t"><span class="returnvalue">hb_bool_t</span></a>
-hb_ot_color_has_png (<em class="parameter"><code><a class="link" href="harfbuzz-hb-face.html#hb-face-t" title="hb_face_t"><span class="type">hb_face_t</span></a> *face</code></em>);</pre>
-<p>Check whether <em class="parameter"><code>face</code></em>
- has PNG glyph images (either CBDT or sbix tables).</p>
-<p>Returns true if available, false otherwise.</p>
+hb_ot_color_has_png (<em class="parameter"><code><a class="link" href="harfbuzz-hb-face.html#hb-face-t"><span class="type">hb_face_t</span></a> *face</code></em>);</pre>
+<p>Tests whether a face has PNG glyph images (either in <code class="literal">CBDT</code> or <code class="literal">sbix</code> tables).</p>
 <div class="refsect3">
 <a name="hb-ot-color-has-png.parameters"></a><h4>Parameters</h4>
 <div class="informaltable"><table class="informaltable" width="100%" border="0">
@@ -425,21 +460,23 @@ hb_ot_color_has_png (<em class="parameter"><code><a class="link" href="harfbuzz-
 </colgroup>
 <tbody><tr>
 <td class="parameter_name"><p>face</p></td>
-<td class="parameter_description"><p>a font face.</p></td>
+<td class="parameter_description"><p><a class="link" href="harfbuzz-hb-face.html#hb-face-t"><span class="type">hb_face_t</span></a> to work upon</p></td>
 <td class="parameter_annotations"> </td>
 </tr></tbody>
 </table></div>
 </div>
+<div class="refsect3">
+<a name="hb-ot-color-has-png.returns"></a><h4>Returns</h4>
+<p> true if data found, false otherwise</p>
+</div>
 <p class="since">Since: <a class="link" href="api-index-2-1-0.html#api-index-2.1.0">2.1.0</a></p>
 </div>
 <hr>
 <div class="refsect2">
 <a name="hb-ot-color-has-svg"></a><h3>hb_ot_color_has_svg ()</h3>
 <pre class="programlisting"><a class="link" href="harfbuzz-hb-common.html#hb-bool-t" title="hb_bool_t"><span class="returnvalue">hb_bool_t</span></a>
-hb_ot_color_has_svg (<em class="parameter"><code><a class="link" href="harfbuzz-hb-face.html#hb-face-t" title="hb_face_t"><span class="type">hb_face_t</span></a> *face</code></em>);</pre>
-<p>Check whether <em class="parameter"><code>face</code></em>
- has SVG glyph images.</p>
-<p>Returns true if available, false otherwise.</p>
+hb_ot_color_has_svg (<em class="parameter"><code><a class="link" href="harfbuzz-hb-face.html#hb-face-t"><span class="type">hb_face_t</span></a> *face</code></em>);</pre>
+<p>Tests whether a face includes any <code class="literal">SVG</code> glyph images.</p>
 <div class="refsect3">
 <a name="hb-ot-color-has-svg.parameters"></a><h4>Parameters</h4>
 <div class="informaltable"><table class="informaltable" width="100%" border="0">
@@ -450,19 +487,27 @@ hb_ot_color_has_svg (<em class="parameter"><code><a class="link" href="harfbuzz-
 </colgroup>
 <tbody><tr>
 <td class="parameter_name"><p>face</p></td>
-<td class="parameter_description"><p>a font face.</p></td>
+<td class="parameter_description"><p><a class="link" href="harfbuzz-hb-face.html#hb-face-t"><span class="type">hb_face_t</span></a> to work upon.</p></td>
 <td class="parameter_annotations"> </td>
 </tr></tbody>
 </table></div>
 </div>
+<div class="refsect3">
+<a name="hb-ot-color-has-svg.returns"></a><h4>Returns</h4>
+<p> true if data found, false otherwise.</p>
+</div>
 <p class="since">Since: <a class="link" href="api-index-2-1-0.html#api-index-2.1.0">2.1.0</a></p>
 </div>
 <hr>
 <div class="refsect2">
 <a name="hb-ot-color-palette-color-get-name-id"></a><h3>hb_ot_color_palette_color_get_name_id ()</h3>
 <pre class="programlisting"><a class="link" href="harfbuzz-hb-ot-name.html#hb-ot-name-id-t" title="hb_ot_name_id_t"><span class="returnvalue">hb_ot_name_id_t</span></a>
-hb_ot_color_palette_color_get_name_id (<em class="parameter"><code><a class="link" href="harfbuzz-hb-face.html#hb-face-t" title="hb_face_t"><span class="type">hb_face_t</span></a> *face</code></em>,
+hb_ot_color_palette_color_get_name_id (<em class="parameter"><code><a class="link" href="harfbuzz-hb-face.html#hb-face-t"><span class="type">hb_face_t</span></a> *face</code></em>,
                                        <em class="parameter"><code>unsigned <span class="type">int</span> color_index</code></em>);</pre>
+<p>Fetches the <code class="literal">name</code> table Name ID that provides display names for
+the specificed color in a face's <code class="literal">CPAL</code> color palette. </p>
+<p>Display names can be generic (e.g., "Background") or specific
+(e.g., "Eye color").</p>
 <div class="refsect3">
 <a name="hb-ot-color-palette-color-get-name-id.parameters"></a><h4>Parameters</h4>
 <div class="informaltable"><table class="informaltable" width="100%" border="0">
@@ -474,12 +519,12 @@ hb_ot_color_palette_color_get_name_id (<em class="parameter"><code><a class="lin
 <tbody>
 <tr>
 <td class="parameter_name"><p>face</p></td>
-<td class="parameter_description"><p>a font face.</p></td>
+<td class="parameter_description"><p><a class="link" href="harfbuzz-hb-face.html#hb-face-t"><span class="type">hb_face_t</span></a> to work upon</p></td>
 <td class="parameter_annotations"> </td>
 </tr>
 <tr>
 <td class="parameter_name"><p>color_index</p></td>
-<td class="parameter_description"><p>palette entry index.</p></td>
+<td class="parameter_description"><p>The index of the color</p></td>
 <td class="parameter_annotations"> </td>
 </tr>
 </tbody>
@@ -487,7 +532,7 @@ hb_ot_color_palette_color_get_name_id (<em class="parameter"><code><a class="lin
 </div>
 <div class="refsect3">
 <a name="hb-ot-color-palette-color-get-name-id.returns"></a><h4>Returns</h4>
-<p> Name ID associated with a palette entry, e.g. eye color</p>
+<p> the Name ID found for the color.</p>
 </div>
 <p class="since">Since: <a class="link" href="api-index-2-1-0.html#api-index-2.1.0">2.1.0</a></p>
 </div>
@@ -495,12 +540,19 @@ hb_ot_color_palette_color_get_name_id (<em class="parameter"><code><a class="lin
 <div class="refsect2">
 <a name="hb-ot-color-palette-get-colors"></a><h3>hb_ot_color_palette_get_colors ()</h3>
 <pre class="programlisting">unsigned <span class="returnvalue">int</span>
-hb_ot_color_palette_get_colors (<em class="parameter"><code><a class="link" href="harfbuzz-hb-face.html#hb-face-t" title="hb_face_t"><span class="type">hb_face_t</span></a> *face</code></em>,
+hb_ot_color_palette_get_colors (<em class="parameter"><code><a class="link" href="harfbuzz-hb-face.html#hb-face-t"><span class="type">hb_face_t</span></a> *face</code></em>,
                                 <em class="parameter"><code>unsigned <span class="type">int</span> palette_index</code></em>,
                                 <em class="parameter"><code>unsigned <span class="type">int</span> start_offset</code></em>,
                                 <em class="parameter"><code>unsigned <span class="type">int</span> *color_count</code></em>,
                                 <em class="parameter"><code><a class="link" href="harfbuzz-hb-ot-color.html#hb-color-t" title="hb_color_t"><span class="type">hb_color_t</span></a> *colors</code></em>);</pre>
-<p>Retrieves the colors in a color palette.</p>
+<p>Fetches a list of the colors in a color palette.</p>
+<p>After calling this function, <em class="parameter"><code>colors</code></em>
+ will be filled with the palette
+colors. If <em class="parameter"><code>colors</code></em>
+ is NULL, the function will just return the number
+of total colors without storing any actual colors; this can be used
+for allocating a buffer of suitable size before calling
+<a class="link" href="harfbuzz-hb-ot-color.html#hb-ot-color-palette-get-colors" title="hb_ot_color_palette_get_colors ()"><code class="function">hb_ot_color_palette_get_colors()</code></a> a second time.</p>
 <div class="refsect3">
 <a name="hb-ot-color-palette-get-colors.parameters"></a><h4>Parameters</h4>
 <div class="informaltable"><table class="informaltable" width="100%" border="0">
@@ -512,47 +564,36 @@ hb_ot_color_palette_get_colors (<em class="parameter"><code><a class="link" href
 <tbody>
 <tr>
 <td class="parameter_name"><p>face</p></td>
-<td class="parameter_description"><p>a font face.</p></td>
+<td class="parameter_description"><p><a class="link" href="harfbuzz-hb-face.html#hb-face-t"><span class="type">hb_face_t</span></a> to work upon</p></td>
 <td class="parameter_annotations"> </td>
 </tr>
 <tr>
 <td class="parameter_name"><p>palette_index</p></td>
-<td class="parameter_description"><p>the index of the color palette whose colors
-are being requested.</p></td>
+<td class="parameter_description"><p>the index of the color palette to query</p></td>
 <td class="parameter_annotations"> </td>
 </tr>
 <tr>
 <td class="parameter_name"><p>start_offset</p></td>
-<td class="parameter_description"><p>the index of the first color being requested.</p></td>
+<td class="parameter_description"><p>offset of the first color to retrieve</p></td>
 <td class="parameter_annotations"> </td>
 </tr>
 <tr>
 <td class="parameter_name"><p>color_count</p></td>
-<td class="parameter_description"><p>on input, how many colors
-can be maximally stored into the <em class="parameter"><code>colors</code></em>
-array;
-on output, how many colors were actually stored. </p></td>
+<td class="parameter_description"><p>Input = the maximum number of colors to return;
+Output = the actual number of colors returned (may be zero). </p></td>
 <td class="parameter_annotations"><span class="annotation">[<acronym title="Parameter for input and for returning results. Default is transfer full."><span class="acronym">inout</span></acronym>][<acronym title="NULL may be passed instead of a pointer to a location."><span class="acronym">optional</span></acronym>]</span></td>
 </tr>
 <tr>
 <td class="parameter_name"><p>colors</p></td>
-<td class="parameter_description"><p>an array of <a class="link" href="harfbuzz-hb-ot-color.html#hb-color-t" title="hb_color_t"><span class="type">hb_color_t</span></a> records. After calling
-this function, <em class="parameter"><code>colors</code></em>
-will be filled with
-the palette colors. If <em class="parameter"><code>colors</code></em>
-is NULL, the function
-will just return the number of total colors
-without storing any actual colors; this can be used
-for allocating a buffer of suitable size before calling
-<a class="link" href="harfbuzz-hb-ot-color.html#hb-ot-color-palette-get-colors" title="hb_ot_color_palette_get_colors ()"><code class="function">hb_ot_color_palette_get_colors()</code></a> a second time. </p></td>
-<td class="parameter_annotations"><span class="annotation">[<acronym title="Parameter points to an array of items."><span class="acronym">array</span></acronym> length=color_count][<acronym title="Parameter for returning results. Default is transfer full."><span class="acronym">out</span></acronym>][<acronym title="NULL may be passed instead of a pointer to a location."><span class="acronym">optional</span></acronym>]</span></td>
+<td class="parameter_description"><p>The array of <a class="link" href="harfbuzz-hb-ot-color.html#hb-color-t" title="hb_color_t"><span class="type">hb_color_t</span></a> records found. </p></td>
+<td class="parameter_annotations"><span class="annotation">[<acronym title="Parameter for returning results. Default is transfer full."><span class="acronym">out</span></acronym>][<acronym title="Parameter points to an array of items."><span class="acronym">array</span></acronym> length=color_count][<acronym title="NULL may be passed as the value in, out, in-out; or as a return value."><span class="acronym">nullable</span></acronym>]</span></td>
 </tr>
 </tbody>
 </table></div>
 </div>
 <div class="refsect3">
 <a name="hb-ot-color-palette-get-colors.returns"></a><h4>Returns</h4>
-<p> the total number of colors in the palette.</p>
+<p> the total number of colors in the palette</p>
 </div>
 <p class="since">Since: <a class="link" href="api-index-2-1-0.html#api-index-2.1.0">2.1.0</a></p>
 </div>
@@ -560,7 +601,8 @@ for allocating a buffer of suitable size before calling
 <div class="refsect2">
 <a name="hb-ot-color-palette-get-count"></a><h3>hb_ot_color_palette_get_count ()</h3>
 <pre class="programlisting">unsigned <span class="returnvalue">int</span>
-hb_ot_color_palette_get_count (<em class="parameter"><code><a class="link" href="harfbuzz-hb-face.html#hb-face-t" title="hb_face_t"><span class="type">hb_face_t</span></a> *face</code></em>);</pre>
+hb_ot_color_palette_get_count (<em class="parameter"><code><a class="link" href="harfbuzz-hb-face.html#hb-face-t"><span class="type">hb_face_t</span></a> *face</code></em>);</pre>
+<p>Fetches the number of color palettes in a face.</p>
 <div class="refsect3">
 <a name="hb-ot-color-palette-get-count.parameters"></a><h4>Parameters</h4>
 <div class="informaltable"><table class="informaltable" width="100%" border="0">
@@ -571,17 +613,14 @@ hb_ot_color_palette_get_count (<em class="parameter"><code><a class="link" href=
 </colgroup>
 <tbody><tr>
 <td class="parameter_name"><p>face</p></td>
-<td class="parameter_description"><p>a font face.</p></td>
+<td class="parameter_description"><p><a class="link" href="harfbuzz-hb-face.html#hb-face-t"><span class="type">hb_face_t</span></a> to work upon</p></td>
 <td class="parameter_annotations"> </td>
 </tr></tbody>
 </table></div>
 </div>
 <div class="refsect3">
 <a name="hb-ot-color-palette-get-count.returns"></a><h4>Returns</h4>
-<p> the number of color palettes in <em class="parameter"><code>face</code></em>
-, or zero if <em class="parameter"><code>face</code></em>
-has
-no colors.</p>
+<p> the number of palettes found</p>
 </div>
 <p class="since">Since: <a class="link" href="api-index-2-1-0.html#api-index-2.1.0">2.1.0</a></p>
 </div>
@@ -589,8 +628,9 @@ no colors.</p>
 <div class="refsect2">
 <a name="hb-ot-color-palette-get-flags"></a><h3>hb_ot_color_palette_get_flags ()</h3>
 <pre class="programlisting"><a class="link" href="harfbuzz-hb-ot-color.html#hb-ot-color-palette-flags-t" title="enum hb_ot_color_palette_flags_t"><span class="returnvalue">hb_ot_color_palette_flags_t</span></a>
-hb_ot_color_palette_get_flags (<em class="parameter"><code><a class="link" href="harfbuzz-hb-face.html#hb-face-t" title="hb_face_t"><span class="type">hb_face_t</span></a> *face</code></em>,
+hb_ot_color_palette_get_flags (<em class="parameter"><code><a class="link" href="harfbuzz-hb-face.html#hb-face-t"><span class="type">hb_face_t</span></a> *face</code></em>,
                                <em class="parameter"><code>unsigned <span class="type">int</span> palette_index</code></em>);</pre>
+<p>Fetches the flags defined for a color palette.</p>
 <div class="refsect3">
 <a name="hb-ot-color-palette-get-flags.parameters"></a><h4>Parameters</h4>
 <div class="informaltable"><table class="informaltable" width="100%" border="0">
@@ -602,12 +642,12 @@ hb_ot_color_palette_get_flags (<em class="parameter"><code><a class="link" href=
 <tbody>
 <tr>
 <td class="parameter_name"><p>face</p></td>
-<td class="parameter_description"><p>a font face</p></td>
+<td class="parameter_description"><p><a class="link" href="harfbuzz-hb-face.html#hb-face-t"><span class="type">hb_face_t</span></a> to work upon</p></td>
 <td class="parameter_annotations"> </td>
 </tr>
 <tr>
 <td class="parameter_name"><p>palette_index</p></td>
-<td class="parameter_description"><p>the index of the color palette whose flags are being requested</p></td>
+<td class="parameter_description"><p>The index of the color palette</p></td>
 <td class="parameter_annotations"> </td>
 </tr>
 </tbody>
@@ -615,7 +655,7 @@ hb_ot_color_palette_get_flags (<em class="parameter"><code><a class="link" href=
 </div>
 <div class="refsect3">
 <a name="hb-ot-color-palette-get-flags.returns"></a><h4>Returns</h4>
-<p> the flags for the requested color palette.</p>
+<p> the <a class="link" href="harfbuzz-hb-ot-color.html#hb-ot-color-palette-flags-t" title="enum hb_ot_color_palette_flags_t"><span class="type">hb_ot_color_palette_flags_t</span></a> of the requested color palette</p>
 </div>
 <p class="since">Since: <a class="link" href="api-index-2-1-0.html#api-index-2.1.0">2.1.0</a></p>
 </div>
@@ -623,10 +663,12 @@ hb_ot_color_palette_get_flags (<em class="parameter"><code><a class="link" href=
 <div class="refsect2">
 <a name="hb-ot-color-palette-get-name-id"></a><h3>hb_ot_color_palette_get_name_id ()</h3>
 <pre class="programlisting"><a class="link" href="harfbuzz-hb-ot-name.html#hb-ot-name-id-t" title="hb_ot_name_id_t"><span class="returnvalue">hb_ot_name_id_t</span></a>
-hb_ot_color_palette_get_name_id (<em class="parameter"><code><a class="link" href="harfbuzz-hb-face.html#hb-face-t" title="hb_face_t"><span class="type">hb_face_t</span></a> *face</code></em>,
+hb_ot_color_palette_get_name_id (<em class="parameter"><code><a class="link" href="harfbuzz-hb-face.html#hb-face-t"><span class="type">hb_face_t</span></a> *face</code></em>,
                                  <em class="parameter"><code>unsigned <span class="type">int</span> palette_index</code></em>);</pre>
-<p>Retrieves the name id of a color palette. For example, a color font can
-have themed palettes like "Spring", "Summer", "Fall", and "Winter".</p>
+<p>Fetches the <code class="literal">name</code> table Name ID that provides display names for
+a <code class="literal">CPAL</code> color palette. </p>
+<p>Palette display names can be generic (e.g., "Default") or provide
+specific, themed names (e.g., "Spring", "Summer", "Fall", and "Winter").</p>
 <div class="refsect3">
 <a name="hb-ot-color-palette-get-name-id.parameters"></a><h4>Parameters</h4>
 <div class="informaltable"><table class="informaltable" width="100%" border="0">
@@ -638,12 +680,12 @@ have themed palettes like "Spring", "Summer", "Fall", and "Winter".</p>
 <tbody>
 <tr>
 <td class="parameter_name"><p>face</p></td>
-<td class="parameter_description"><p>a font face.</p></td>
+<td class="parameter_description"><p><a class="link" href="harfbuzz-hb-face.html#hb-face-t"><span class="type">hb_face_t</span></a> to work upon</p></td>
 <td class="parameter_annotations"> </td>
 </tr>
 <tr>
 <td class="parameter_name"><p>palette_index</p></td>
-<td class="parameter_description"><p>the index of the color palette whose name is being requested.</p></td>
+<td class="parameter_description"><p>The index of the color palette </p></td>
 <td class="parameter_annotations"> </td>
 </tr>
 </tbody>
@@ -651,8 +693,7 @@ have themed palettes like "Spring", "Summer", "Fall", and "Winter".</p>
 </div>
 <div class="refsect3">
 <a name="hb-ot-color-palette-get-name-id.returns"></a><h4>Returns</h4>
-<p> an identifier within <em class="parameter"><code>face</code></em>
-'s <code class="literal">name</code> table.
+<p> the Named ID found for the palette.
 If the requested palette has no name the result is <span class="type">HB_OT_NAME_ID_INVALID</span>.</p>
 </div>
 <p class="since">Since: <a class="link" href="api-index-2-1-0.html#api-index-2.1.0">2.1.0</a></p>
@@ -682,7 +723,7 @@ If the requested palette has no name the result is <span class="type">HB_OT_NAME
 <tr>
 <td class="enum_member_name"><p><a name="HB-OT-COLOR-PALETTE-FLAG-DEFAULT:CAPS"></a>HB_OT_COLOR_PALETTE_FLAG_DEFAULT</p></td>
 <td class="enum_member_description">
-<p>default indicating that there is nothing special
+<p>Default indicating that there is nothing special
   to note about a color palette.</p>
 </td>
 <td class="enum_member_annotations"> </td>
@@ -690,7 +731,7 @@ If the requested palette has no name the result is <span class="type">HB_OT_NAME
 <tr>
 <td class="enum_member_name"><p><a name="HB-OT-COLOR-PALETTE-FLAG-USABLE-WITH-LIGHT-BACKGROUND:CAPS"></a>HB_OT_COLOR_PALETTE_FLAG_USABLE_WITH_LIGHT_BACKGROUND</p></td>
 <td class="enum_member_description">
-<p>flag indicating that the color
+<p>Flag indicating that the color
   palette is appropriate to use when displaying the font on a light background such as white.</p>
 </td>
 <td class="enum_member_annotations"> </td>
@@ -698,7 +739,7 @@ If the requested palette has no name the result is <span class="type">HB_OT_NAME
 <tr>
 <td class="enum_member_name"><p><a name="HB-OT-COLOR-PALETTE-FLAG-USABLE-WITH-DARK-BACKGROUND:CAPS"></a>HB_OT_COLOR_PALETTE_FLAG_USABLE_WITH_DARK_BACKGROUND</p></td>
 <td class="enum_member_description">
-<p>flag indicating that the color
+<p>Flag indicating that the color
   palette is appropriate to use when displaying the font on a dark background such as black.</p>
 </td>
 <td class="enum_member_annotations"> </td>
index 6c955ca..635c7f3 100644 (file)
@@ -5,7 +5,7 @@
 <title>hb-ot-font: HarfBuzz Manual</title>
 <meta name="generator" content="DocBook XSL Stylesheets Vsnapshot">
 <link rel="home" href="index.html" title="HarfBuzz Manual">
-<link rel="up" href="ch10.html" title="OpenType API">
+<link rel="up" href="ch12.html" title="OpenType API">
 <link rel="prev" href="harfbuzz-hb-ot-color.html" title="hb-ot-color">
 <link rel="next" href="harfbuzz-hb-ot-layout.html" title="hb-ot-layout">
 <meta name="generator" content="GTK-Doc V1.29 (XML mode)">
@@ -18,7 +18,7 @@
                   <a href="#harfbuzz-hb-ot-font.description" class="shortcut">Description</a></span>
 </td>
 <td><a accesskey="h" href="index.html"><img src="home.png" width="16" height="16" border="0" alt="Home"></a></td>
-<td><a accesskey="u" href="ch10.html"><img src="up.png" width="16" height="16" border="0" alt="Up"></a></td>
+<td><a accesskey="u" href="ch12.html"><img src="up.png" width="16" height="16" border="0" alt="Up"></a></td>
 <td><a accesskey="p" href="harfbuzz-hb-ot-color.html"><img src="left.png" width="16" height="16" border="0" alt="Prev"></a></td>
 <td><a accesskey="n" href="harfbuzz-hb-ot-layout.html"><img src="right.png" width="16" height="16" border="0" alt="Next"></a></td>
 </tr></table>
@@ -64,7 +64,7 @@ never need to call these functions directly.</p>
 <div class="refsect2">
 <a name="hb-ot-font-set-funcs"></a><h3>hb_ot_font_set_funcs ()</h3>
 <pre class="programlisting"><span class="returnvalue">void</span>
-hb_ot_font_set_funcs (<em class="parameter"><code><a class="link" href="harfbuzz-hb-font.html#hb-font-t" title="hb_font_t"><span class="type">hb_font_t</span></a> *font</code></em>);</pre>
+hb_ot_font_set_funcs (<em class="parameter"><code><a class="link" href="harfbuzz-hb-font.html#hb-font-t"><span class="type">hb_font_t</span></a> *font</code></em>);</pre>
 <p class="since">Since: <a class="link" href="api-index-0-9-28.html#api-index-0.9.28">0.9.28</a></p>
 </div>
 </div>
index 76be161..ab5d19f 100644 (file)
@@ -5,7 +5,7 @@
 <title>hb-ot-layout: HarfBuzz Manual</title>
 <meta name="generator" content="DocBook XSL Stylesheets Vsnapshot">
 <link rel="home" href="index.html" title="HarfBuzz Manual">
-<link rel="up" href="ch10.html" title="OpenType API">
+<link rel="up" href="ch12.html" title="OpenType API">
 <link rel="prev" href="harfbuzz-hb-ot-font.html" title="hb-ot-font">
 <link rel="next" href="harfbuzz-hb-ot-math.html" title="hb-ot-math">
 <meta name="generator" content="GTK-Doc V1.29 (XML mode)">
 <table class="navigation" id="top" width="100%" summary="Navigation header" cellpadding="2" cellspacing="5"><tr valign="middle">
 <td width="100%" align="left" class="shortcuts">
 <a href="#" class="shortcut">Top</a><span id="nav_description">  <span class="dim">|</span> 
-                  <a href="#harfbuzz-hb-ot-layout.description" class="shortcut">Description</a></span>
+                  <a href="#harfbuzz-hb-ot-layout.description" class="shortcut">Description</a></span><span id="nav_hierarchy">  <span class="dim">|</span> 
+                  <a href="#harfbuzz-hb-ot-layout.object-hierarchy" class="shortcut">Object Hierarchy</a></span>
 </td>
 <td><a accesskey="h" href="index.html"><img src="home.png" width="16" height="16" border="0" alt="Home"></a></td>
-<td><a accesskey="u" href="ch10.html"><img src="up.png" width="16" height="16" border="0" alt="Up"></a></td>
+<td><a accesskey="u" href="ch12.html"><img src="up.png" width="16" height="16" border="0" alt="Up"></a></td>
 <td><a accesskey="p" href="harfbuzz-hb-ot-font.html"><img src="left.png" width="16" height="16" border="0" alt="Prev"></a></td>
 <td><a accesskey="n" href="harfbuzz-hb-ot-math.html"><img src="right.png" width="16" height="16" border="0" alt="Next"></a></td>
 </tr></table>
 </tr>
 <tr>
 <td class="function_type">
+<a class="link" href="harfbuzz-hb-common.html#hb-bool-t" title="hb_bool_t"><span class="returnvalue">hb_bool_t</span></a>
+</td>
+<td class="function_name">
+<a class="link" href="harfbuzz-hb-ot-layout.html#hb-ot-layout-get-baseline" title="hb_ot_layout_get_baseline ()">hb_ot_layout_get_baseline</a> <span class="c_punctuation">()</span>
+</td>
+</tr>
+<tr>
+<td class="function_type">
 <a class="link" href="harfbuzz-hb-ot-layout.html#hb-ot-layout-glyph-class-t" title="enum hb_ot_layout_glyph_class_t"><span class="returnvalue">hb_ot_layout_glyph_class_t</span></a>
 </td>
 <td class="function_name">
 </tr>
 <tr>
 <td class="datatype_keyword">enum</td>
+<td class="function_name"><a class="link" href="harfbuzz-hb-ot-layout.html#hb-ot-layout-baseline-tag-t" title="enum hb_ot_layout_baseline_tag_t">hb_ot_layout_baseline_tag_t</a></td>
+</tr>
+<tr>
+<td class="datatype_keyword">enum</td>
 <td class="function_name"><a class="link" href="harfbuzz-hb-ot-layout.html#hb-ot-layout-glyph-class-t" title="enum hb_ot_layout_glyph_class_t">hb_ot_layout_glyph_class_t</a></td>
 </tr>
 </tbody>
 </table></div>
 </div>
 <div class="refsect1">
+<a name="harfbuzz-hb-ot-layout.object-hierarchy"></a><h2>Object Hierarchy</h2>
+<pre class="screen">    <a href="/usr/share/gtk-doc/html/gobject/gobject-Enumeration-and-Flag-Types.html">GEnum</a>
+    <span class="lineart">├──</span> hb_ot_layout_baseline_tag_t
+    <span class="lineart">╰──</span> hb_ot_layout_glyph_class_t
+</pre>
+</div>
+<div class="refsect1">
 <a name="harfbuzz-hb-ot-layout.includes"></a><h2>Includes</h2>
 <pre class="synopsis">#include &lt;hb-ot.h&gt;
 </pre>
@@ -527,38 +547,137 @@ and
 <div class="refsect2">
 <a name="hb-ot-layout-collect-lookups"></a><h3>hb_ot_layout_collect_lookups ()</h3>
 <pre class="programlisting"><span class="returnvalue">void</span>
-hb_ot_layout_collect_lookups (<em class="parameter"><code><a class="link" href="harfbuzz-hb-face.html#hb-face-t" title="hb_face_t"><span class="type">hb_face_t</span></a> *face</code></em>,
+hb_ot_layout_collect_lookups (<em class="parameter"><code><a class="link" href="harfbuzz-hb-face.html#hb-face-t"><span class="type">hb_face_t</span></a> *face</code></em>,
                               <em class="parameter"><code><a class="link" href="harfbuzz-hb-common.html#hb-tag-t" title="hb_tag_t"><span class="type">hb_tag_t</span></a> table_tag</code></em>,
                               <em class="parameter"><code>const <a class="link" href="harfbuzz-hb-common.html#hb-tag-t" title="hb_tag_t"><span class="type">hb_tag_t</span></a> *scripts</code></em>,
                               <em class="parameter"><code>const <a class="link" href="harfbuzz-hb-common.html#hb-tag-t" title="hb_tag_t"><span class="type">hb_tag_t</span></a> *languages</code></em>,
                               <em class="parameter"><code>const <a class="link" href="harfbuzz-hb-common.html#hb-tag-t" title="hb_tag_t"><span class="type">hb_tag_t</span></a> *features</code></em>,
-                              <em class="parameter"><code><a class="link" href="harfbuzz-hb-set.html#hb-set-t" title="hb_set_t"><span class="type">hb_set_t</span></a> *lookup_indexes</code></em>);</pre>
+                              <em class="parameter"><code><a class="link" href="harfbuzz-hb-set.html#hb-set-t"><span class="type">hb_set_t</span></a> *lookup_indexes</code></em>);</pre>
+<p>Fetches a list of all feature-lookup indexes in the specified face's GSUB
+table or GPOS table, underneath the specified scripts, languages, and
+features. If no list of scripts is provided, all scripts will be queried.
+If no list of languages is provided, all languages will be queried. If no
+list of features is provided, all features will be queried.</p>
+<div class="refsect3">
+<a name="hb-ot-layout-collect-lookups.parameters"></a><h4>Parameters</h4>
+<div class="informaltable"><table class="informaltable" width="100%" border="0">
+<colgroup>
+<col width="150px" class="parameters_name">
+<col class="parameters_description">
+<col width="200px" class="parameters_annotations">
+</colgroup>
+<tbody>
+<tr>
+<td class="parameter_name"><p>face</p></td>
+<td class="parameter_description"><p><a class="link" href="harfbuzz-hb-face.html#hb-face-t"><span class="type">hb_face_t</span></a> to work upon</p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+<tr>
+<td class="parameter_name"><p>table_tag</p></td>
+<td class="parameter_description"><p>HB_OT_TAG_GSUB or HB_OT_TAG_GPOS</p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+<tr>
+<td class="parameter_name"><p>scripts</p></td>
+<td class="parameter_description"><p>The array of scripts to collect lookups for</p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+<tr>
+<td class="parameter_name"><p>languages</p></td>
+<td class="parameter_description"><p>The array of languages to collect lookups for</p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+<tr>
+<td class="parameter_name"><p>features</p></td>
+<td class="parameter_description"><p>The array of features to collect lookups for</p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+<tr>
+<td class="parameter_name"><p>lookup_indexes</p></td>
+<td class="parameter_description"><p>The array of lookup indexes found for the query. </p></td>
+<td class="parameter_annotations"><span class="annotation">[<acronym title="Parameter for returning results. Default is transfer full."><span class="acronym">out</span></acronym>]</span></td>
+</tr>
+</tbody>
+</table></div>
+</div>
 <p class="since">Since: <a class="link" href="api-index-0-9-8.html#api-index-0.9.8">0.9.8</a></p>
 </div>
 <hr>
 <div class="refsect2">
 <a name="hb-ot-layout-collect-features"></a><h3>hb_ot_layout_collect_features ()</h3>
 <pre class="programlisting"><span class="returnvalue">void</span>
-hb_ot_layout_collect_features (<em class="parameter"><code><a class="link" href="harfbuzz-hb-face.html#hb-face-t" title="hb_face_t"><span class="type">hb_face_t</span></a> *face</code></em>,
+hb_ot_layout_collect_features (<em class="parameter"><code><a class="link" href="harfbuzz-hb-face.html#hb-face-t"><span class="type">hb_face_t</span></a> *face</code></em>,
                                <em class="parameter"><code><a class="link" href="harfbuzz-hb-common.html#hb-tag-t" title="hb_tag_t"><span class="type">hb_tag_t</span></a> table_tag</code></em>,
                                <em class="parameter"><code>const <a class="link" href="harfbuzz-hb-common.html#hb-tag-t" title="hb_tag_t"><span class="type">hb_tag_t</span></a> *scripts</code></em>,
                                <em class="parameter"><code>const <a class="link" href="harfbuzz-hb-common.html#hb-tag-t" title="hb_tag_t"><span class="type">hb_tag_t</span></a> *languages</code></em>,
                                <em class="parameter"><code>const <a class="link" href="harfbuzz-hb-common.html#hb-tag-t" title="hb_tag_t"><span class="type">hb_tag_t</span></a> *features</code></em>,
-                               <em class="parameter"><code><a class="link" href="harfbuzz-hb-set.html#hb-set-t" title="hb_set_t"><span class="type">hb_set_t</span></a> *feature_indexes</code></em>);</pre>
+                               <em class="parameter"><code><a class="link" href="harfbuzz-hb-set.html#hb-set-t"><span class="type">hb_set_t</span></a> *feature_indexes</code></em>);</pre>
+<p>Fetches a list of all feature indexes in the specified face's GSUB table
+or GPOS table, underneath the specified scripts, languages, and features.
+If no list of scripts is provided, all scripts will be queried. If no list
+of languages is provided, all languages will be queried. If no list of
+features is provided, all features will be queried.</p>
+<div class="refsect3">
+<a name="hb-ot-layout-collect-features.parameters"></a><h4>Parameters</h4>
+<div class="informaltable"><table class="informaltable" width="100%" border="0">
+<colgroup>
+<col width="150px" class="parameters_name">
+<col class="parameters_description">
+<col width="200px" class="parameters_annotations">
+</colgroup>
+<tbody>
+<tr>
+<td class="parameter_name"><p>face</p></td>
+<td class="parameter_description"><p><a class="link" href="harfbuzz-hb-face.html#hb-face-t"><span class="type">hb_face_t</span></a> to work upon</p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+<tr>
+<td class="parameter_name"><p>table_tag</p></td>
+<td class="parameter_description"><p>HB_OT_TAG_GSUB or HB_OT_TAG_GPOS</p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+<tr>
+<td class="parameter_name"><p>scripts</p></td>
+<td class="parameter_description"><p>The array of scripts to collect features for</p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+<tr>
+<td class="parameter_name"><p>languages</p></td>
+<td class="parameter_description"><p>The array of languages to collect features for</p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+<tr>
+<td class="parameter_name"><p>features</p></td>
+<td class="parameter_description"><p>The array of features to collect</p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+<tr>
+<td class="parameter_name"><p>feature_indexes</p></td>
+<td class="parameter_description"><p>The array of feature indexes found for the query. </p></td>
+<td class="parameter_annotations"><span class="annotation">[<acronym title="Parameter for returning results. Default is transfer full."><span class="acronym">out</span></acronym>]</span></td>
+</tr>
+</tbody>
+</table></div>
+</div>
 <p class="since">Since: <a class="link" href="api-index-1-8-5.html#api-index-1.8.5">1.8.5</a></p>
 </div>
 <hr>
 <div class="refsect2">
 <a name="hb-ot-layout-feature-get-characters"></a><h3>hb_ot_layout_feature_get_characters ()</h3>
 <pre class="programlisting">unsigned <span class="returnvalue">int</span>
-hb_ot_layout_feature_get_characters (<em class="parameter"><code><a class="link" href="harfbuzz-hb-face.html#hb-face-t" title="hb_face_t"><span class="type">hb_face_t</span></a> *face</code></em>,
+hb_ot_layout_feature_get_characters (<em class="parameter"><code><a class="link" href="harfbuzz-hb-face.html#hb-face-t"><span class="type">hb_face_t</span></a> *face</code></em>,
                                      <em class="parameter"><code><a class="link" href="harfbuzz-hb-common.html#hb-tag-t" title="hb_tag_t"><span class="type">hb_tag_t</span></a> table_tag</code></em>,
                                      <em class="parameter"><code>unsigned <span class="type">int</span> feature_index</code></em>,
                                      <em class="parameter"><code>unsigned <span class="type">int</span> start_offset</code></em>,
                                      <em class="parameter"><code>unsigned <span class="type">int</span> *char_count</code></em>,
                                      <em class="parameter"><code><a class="link" href="harfbuzz-hb-common.html#hb-codepoint-t" title="hb_codepoint_t"><span class="type">hb_codepoint_t</span></a> *characters</code></em>);</pre>
-<p>Fetches characters listed by designer under feature parameters for "Character
-Variant" ("cvXX") features.</p>
+<p>Fetches a list of the characters defined as having a variant under the specified
+"Character Variant" ("cvXX") feature tag.</p>
+<div class="note">Note: If the char_count output value is equal to its input value, then there
+      is a chance there were more characters defined under the feature tag than were
+      returned. This function can be called with incrementally larger start_offset
+      until the char_count output value is lower than its input value, or the size
+      of the characters array can be increased.</div>
 <div class="refsect3">
 <a name="hb-ot-layout-feature-get-characters.parameters"></a><h4>Parameters</h4>
 <div class="informaltable"><table class="informaltable" width="100%" border="0">
@@ -570,7 +689,7 @@ Variant" ("cvXX") features.</p>
 <tbody>
 <tr>
 <td class="parameter_name"><p>face</p></td>
-<td class="parameter_description"><p><a class="link" href="harfbuzz-hb-face.html#hb-face-t" title="hb_face_t"><span class="type">hb_face_t</span></a> to work upon</p></td>
+<td class="parameter_description"><p><a class="link" href="harfbuzz-hb-face.html#hb-face-t"><span class="type">hb_face_t</span></a> to work upon</p></td>
 <td class="parameter_annotations"> </td>
 </tr>
 <tr>
@@ -585,23 +704,20 @@ Variant" ("cvXX") features.</p>
 </tr>
 <tr>
 <td class="parameter_name"><p>start_offset</p></td>
-<td class="parameter_description"><p>In case the resulting char_count was equal to its input value, there
-is a chance there were more characters on the tag so this API can be
-called with an offset till resulting char_count gets to a number
-lower than input buffer (or consider using just a bigger buffer for
-one shot copying).</p></td>
+<td class="parameter_description"><p>offset of the first character to retrieve</p></td>
 <td class="parameter_annotations"> </td>
 </tr>
 <tr>
 <td class="parameter_name"><p>char_count</p></td>
-<td class="parameter_description"><p>The count of characters for which this feature
-provides glyph variants. (May be zero.). </p></td>
+<td class="parameter_description"><p>Input = the maximum number of characters to return;
+Output = the actual number of characters returned (may be zero). </p></td>
 <td class="parameter_annotations"><span class="annotation">[<acronym title="Parameter for input and for returning results. Default is transfer full."><span class="acronym">inout</span></acronym>][<acronym title="NULL is OK, both for passing and for returning."><span class="acronym">allow-none</span></acronym>]</span></td>
 </tr>
 <tr>
 <td class="parameter_name"><p>characters</p></td>
-<td class="parameter_description"><p>A buffer pointer. The Unicode codepoints
-of the characters for which this feature provides glyph variants. </p></td>
+<td class="parameter_description"><p>A buffer pointer.
+The Unicode codepoints of the characters for which this feature provides
+glyph variants. </p></td>
 <td class="parameter_annotations"><span class="annotation">[<acronym title="Out parameter, where caller must allocate storage."><span class="acronym">out caller-allocates</span></acronym>][<acronym title="Parameter points to an array of items."><span class="acronym">array</span></acronym> length=char_count]</span></td>
 </tr>
 </tbody>
@@ -617,19 +733,65 @@ of the characters for which this feature provides glyph variants. </p></td>
 <div class="refsect2">
 <a name="hb-ot-layout-feature-get-lookups"></a><h3>hb_ot_layout_feature_get_lookups ()</h3>
 <pre class="programlisting">unsigned <span class="returnvalue">int</span>
-hb_ot_layout_feature_get_lookups (<em class="parameter"><code><a class="link" href="harfbuzz-hb-face.html#hb-face-t" title="hb_face_t"><span class="type">hb_face_t</span></a> *face</code></em>,
+hb_ot_layout_feature_get_lookups (<em class="parameter"><code><a class="link" href="harfbuzz-hb-face.html#hb-face-t"><span class="type">hb_face_t</span></a> *face</code></em>,
                                   <em class="parameter"><code><a class="link" href="harfbuzz-hb-common.html#hb-tag-t" title="hb_tag_t"><span class="type">hb_tag_t</span></a> table_tag</code></em>,
                                   <em class="parameter"><code>unsigned <span class="type">int</span> feature_index</code></em>,
                                   <em class="parameter"><code>unsigned <span class="type">int</span> start_offset</code></em>,
                                   <em class="parameter"><code>unsigned <span class="type">int</span> *lookup_count</code></em>,
                                   <em class="parameter"><code>unsigned <span class="type">int</span> *lookup_indexes</code></em>);</pre>
+<p>Fetches a list of all lookups enumerated for the specified feature, in
+the specified face's GSUB table or GPOS table. The list returned will
+begin at the offset provided.</p>
+<div class="refsect3">
+<a name="hb-ot-layout-feature-get-lookups.parameters"></a><h4>Parameters</h4>
+<div class="informaltable"><table class="informaltable" width="100%" border="0">
+<colgroup>
+<col width="150px" class="parameters_name">
+<col class="parameters_description">
+<col width="200px" class="parameters_annotations">
+</colgroup>
+<tbody>
+<tr>
+<td class="parameter_name"><p>face</p></td>
+<td class="parameter_description"><p><a class="link" href="harfbuzz-hb-face.html#hb-face-t"><span class="type">hb_face_t</span></a> to work upon</p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+<tr>
+<td class="parameter_name"><p>table_tag</p></td>
+<td class="parameter_description"><p>HB_OT_TAG_GSUB or HB_OT_TAG_GPOS</p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+<tr>
+<td class="parameter_name"><p>feature_index</p></td>
+<td class="parameter_description"><p>The index of the requested feature</p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+<tr>
+<td class="parameter_name"><p>start_offset</p></td>
+<td class="parameter_description"><p>offset of the first lookup to retrieve</p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+<tr>
+<td class="parameter_name"><p>lookup_count</p></td>
+<td class="parameter_description"><p>Input = the maximum number of lookups to return;
+Output = the actual number of lookups returned (may be zero). </p></td>
+<td class="parameter_annotations"><span class="annotation">[<acronym title="Parameter for input and for returning results. Default is transfer full."><span class="acronym">inout</span></acronym>][<acronym title="NULL is OK, both for passing and for returning."><span class="acronym">allow-none</span></acronym>]</span></td>
+</tr>
+<tr>
+<td class="parameter_name"><p>lookup_indexes</p></td>
+<td class="parameter_description"><p>The array of lookup indexes found for the query. </p></td>
+<td class="parameter_annotations"><span class="annotation">[<acronym title="Parameter for returning results. Default is transfer full."><span class="acronym">out</span></acronym>][<acronym title="Parameter points to an array of items."><span class="acronym">array</span></acronym> length=lookup_count]</span></td>
+</tr>
+</tbody>
+</table></div>
+</div>
 <p class="since">Since: <a class="link" href="api-index-0-9-7.html#api-index-0.9.7">0.9.7</a></p>
 </div>
 <hr>
 <div class="refsect2">
 <a name="hb-ot-layout-feature-get-name-ids"></a><h3>hb_ot_layout_feature_get_name_ids ()</h3>
 <pre class="programlisting"><a class="link" href="harfbuzz-hb-common.html#hb-bool-t" title="hb_bool_t"><span class="returnvalue">hb_bool_t</span></a>
-hb_ot_layout_feature_get_name_ids (<em class="parameter"><code><a class="link" href="harfbuzz-hb-face.html#hb-face-t" title="hb_face_t"><span class="type">hb_face_t</span></a> *face</code></em>,
+hb_ot_layout_feature_get_name_ids (<em class="parameter"><code><a class="link" href="harfbuzz-hb-face.html#hb-face-t"><span class="type">hb_face_t</span></a> *face</code></em>,
                                    <em class="parameter"><code><a class="link" href="harfbuzz-hb-common.html#hb-tag-t" title="hb_tag_t"><span class="type">hb_tag_t</span></a> table_tag</code></em>,
                                    <em class="parameter"><code>unsigned <span class="type">int</span> feature_index</code></em>,
                                    <em class="parameter"><code><a class="link" href="harfbuzz-hb-ot-name.html#hb-ot-name-id-t" title="hb_ot_name_id_t"><span class="type">hb_ot_name_id_t</span></a> *label_id</code></em>,
@@ -650,7 +812,7 @@ hb_ot_layout_feature_get_name_ids (<em class="parameter"><code><a class="link" h
 <tbody>
 <tr>
 <td class="parameter_name"><p>face</p></td>
-<td class="parameter_description"><p><a class="link" href="harfbuzz-hb-face.html#hb-face-t" title="hb_face_t"><span class="type">hb_face_t</span></a> to work upon</p></td>
+<td class="parameter_description"><p><a class="link" href="harfbuzz-hb-face.html#hb-face-t"><span class="type">hb_face_t</span></a> to work upon</p></td>
 <td class="parameter_annotations"> </td>
 </tr>
 <tr>
@@ -708,69 +870,376 @@ parameters. (Must be zero if numParameters is zero.). </p></td>
 <a name="hb-ot-layout-feature-with-variations-get-lookups"></a><h3>hb_ot_layout_feature_with_variations_get_lookups ()</h3>
 <pre class="programlisting">unsigned <span class="returnvalue">int</span>
 hb_ot_layout_feature_with_variations_get_lookups
-                               (<em class="parameter"><code><a class="link" href="harfbuzz-hb-face.html#hb-face-t" title="hb_face_t"><span class="type">hb_face_t</span></a> *face</code></em>,
+                               (<em class="parameter"><code><a class="link" href="harfbuzz-hb-face.html#hb-face-t"><span class="type">hb_face_t</span></a> *face</code></em>,
                                 <em class="parameter"><code><a class="link" href="harfbuzz-hb-common.html#hb-tag-t" title="hb_tag_t"><span class="type">hb_tag_t</span></a> table_tag</code></em>,
                                 <em class="parameter"><code>unsigned <span class="type">int</span> feature_index</code></em>,
                                 <em class="parameter"><code>unsigned <span class="type">int</span> variations_index</code></em>,
                                 <em class="parameter"><code>unsigned <span class="type">int</span> start_offset</code></em>,
                                 <em class="parameter"><code>unsigned <span class="type">int</span> *lookup_count</code></em>,
                                 <em class="parameter"><code>unsigned <span class="type">int</span> *lookup_indexes</code></em>);</pre>
+<p>Fetches a list of all lookups enumerated for the specified feature, in
+the specified face's GSUB table or GPOS table, enabled at the specified
+variations index. The list returned will begin at the offset provided.</p>
+<div class="refsect3">
+<a name="hb-ot-layout-feature-with-variations-get-lookups.parameters"></a><h4>Parameters</h4>
+<div class="informaltable"><table class="informaltable" width="100%" border="0">
+<colgroup>
+<col width="150px" class="parameters_name">
+<col class="parameters_description">
+<col width="200px" class="parameters_annotations">
+</colgroup>
+<tbody>
+<tr>
+<td class="parameter_name"><p>face</p></td>
+<td class="parameter_description"><p><a class="link" href="harfbuzz-hb-face.html#hb-face-t"><span class="type">hb_face_t</span></a> to work upon</p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+<tr>
+<td class="parameter_name"><p>table_tag</p></td>
+<td class="parameter_description"><p>HB_OT_TAG_GSUB or HB_OT_TAG_GPOS</p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+<tr>
+<td class="parameter_name"><p>feature_index</p></td>
+<td class="parameter_description"><p>The index of the feature to query</p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+<tr>
+<td class="parameter_name"><p>variations_index</p></td>
+<td class="parameter_description"><p>The index of the feature variation to query</p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+<tr>
+<td class="parameter_name"><p>start_offset</p></td>
+<td class="parameter_description"><p>offset of the first lookup to retrieve</p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+<tr>
+<td class="parameter_name"><p>lookup_count</p></td>
+<td class="parameter_description"><p>Input = the maximum number of lookups to return;
+Output = the actual number of lookups returned (may be zero). </p></td>
+<td class="parameter_annotations"><span class="annotation">[<acronym title="Parameter for input and for returning results. Default is transfer full."><span class="acronym">inout</span></acronym>][<acronym title="NULL is OK, both for passing and for returning."><span class="acronym">allow-none</span></acronym>]</span></td>
+</tr>
+<tr>
+<td class="parameter_name"><p>lookup_indexes</p></td>
+<td class="parameter_description"><p>The array of lookups found for the query. </p></td>
+<td class="parameter_annotations"><span class="annotation">[<acronym title="Parameter for returning results. Default is transfer full."><span class="acronym">out</span></acronym>][<acronym title="Parameter points to an array of items."><span class="acronym">array</span></acronym> length=lookup_count]</span></td>
+</tr>
+</tbody>
+</table></div>
+</div>
 </div>
 <hr>
 <div class="refsect2">
 <a name="hb-ot-layout-get-attach-points"></a><h3>hb_ot_layout_get_attach_points ()</h3>
 <pre class="programlisting">unsigned <span class="returnvalue">int</span>
-hb_ot_layout_get_attach_points (<em class="parameter"><code><a class="link" href="harfbuzz-hb-face.html#hb-face-t" title="hb_face_t"><span class="type">hb_face_t</span></a> *face</code></em>,
+hb_ot_layout_get_attach_points (<em class="parameter"><code><a class="link" href="harfbuzz-hb-face.html#hb-face-t"><span class="type">hb_face_t</span></a> *face</code></em>,
                                 <em class="parameter"><code><a class="link" href="harfbuzz-hb-common.html#hb-codepoint-t" title="hb_codepoint_t"><span class="type">hb_codepoint_t</span></a> glyph</code></em>,
                                 <em class="parameter"><code>unsigned <span class="type">int</span> start_offset</code></em>,
                                 <em class="parameter"><code>unsigned <span class="type">int</span> *point_count</code></em>,
                                 <em class="parameter"><code>unsigned <span class="type">int</span> *point_array</code></em>);</pre>
+<p>Fetches a list of all attachment points for the specified glyph in the GDEF
+table of the face. The list returned will begin at the offset provided.</p>
+<p>Useful if the client program wishes to cache the list.</p>
+<div class="refsect3">
+<a name="hb-ot-layout-get-attach-points.parameters"></a><h4>Parameters</h4>
+<div class="informaltable"><table class="informaltable" width="100%" border="0">
+<colgroup>
+<col width="150px" class="parameters_name">
+<col class="parameters_description">
+<col width="200px" class="parameters_annotations">
+</colgroup>
+<tbody>
+<tr>
+<td class="parameter_name"><p>face</p></td>
+<td class="parameter_description"><p>The <a class="link" href="harfbuzz-hb-face.html#hb-face-t"><span class="type">hb_face_t</span></a> to work on</p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+<tr>
+<td class="parameter_name"><p>glyph</p></td>
+<td class="parameter_description"><p>The <a class="link" href="harfbuzz-hb-common.html#hb-codepoint-t" title="hb_codepoint_t"><span class="type">hb_codepoint_t</span></a> code point to query</p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+<tr>
+<td class="parameter_name"><p>start_offset</p></td>
+<td class="parameter_description"><p>offset of the first attachment point to retrieve</p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+<tr>
+<td class="parameter_name"><p>point_count</p></td>
+<td class="parameter_description"><p>Input = the maximum number of attachment points to return;
+Output = the actual number of attachment points returned (may be zero). </p></td>
+<td class="parameter_annotations"><span class="annotation">[<acronym title="Parameter for input and for returning results. Default is transfer full."><span class="acronym">inout</span></acronym>][<acronym title="NULL is OK, both for passing and for returning."><span class="acronym">allow-none</span></acronym>]</span></td>
+</tr>
+<tr>
+<td class="parameter_name"><p>point_array</p></td>
+<td class="parameter_description"><p>The array of attachment points found for the query. </p></td>
+<td class="parameter_annotations"><span class="annotation">[<acronym title="Parameter for returning results. Default is transfer full."><span class="acronym">out</span></acronym>][<acronym title="Parameter points to an array of items."><span class="acronym">array</span></acronym> length=point_count]</span></td>
+</tr>
+</tbody>
+</table></div>
+</div>
+</div>
+<hr>
+<div class="refsect2">
+<a name="hb-ot-layout-get-baseline"></a><h3>hb_ot_layout_get_baseline ()</h3>
+<pre class="programlisting"><a class="link" href="harfbuzz-hb-common.html#hb-bool-t" title="hb_bool_t"><span class="returnvalue">hb_bool_t</span></a>
+hb_ot_layout_get_baseline (<em class="parameter"><code><a class="link" href="harfbuzz-hb-font.html#hb-font-t"><span class="type">hb_font_t</span></a> *font</code></em>,
+                           <em class="parameter"><code><a class="link" href="harfbuzz-hb-ot-layout.html#hb-ot-layout-baseline-tag-t" title="enum hb_ot_layout_baseline_tag_t"><span class="type">hb_ot_layout_baseline_tag_t</span></a> baseline_tag</code></em>,
+                           <em class="parameter"><code><a class="link" href="harfbuzz-hb-common.html#hb-direction-t" title="enum hb_direction_t"><span class="type">hb_direction_t</span></a> direction</code></em>,
+                           <em class="parameter"><code><a class="link" href="harfbuzz-hb-common.html#hb-tag-t" title="hb_tag_t"><span class="type">hb_tag_t</span></a> script_tag</code></em>,
+                           <em class="parameter"><code><a class="link" href="harfbuzz-hb-common.html#hb-tag-t" title="hb_tag_t"><span class="type">hb_tag_t</span></a> language_tag</code></em>,
+                           <em class="parameter"><code><a class="link" href="harfbuzz-hb-common.html#hb-position-t" title="hb_position_t"><span class="type">hb_position_t</span></a> *coord</code></em>);</pre>
+<p>Fetches a baseline value from the face.</p>
+<div class="refsect3">
+<a name="hb-ot-layout-get-baseline.parameters"></a><h4>Parameters</h4>
+<div class="informaltable"><table class="informaltable" width="100%" border="0">
+<colgroup>
+<col width="150px" class="parameters_name">
+<col class="parameters_description">
+<col width="200px" class="parameters_annotations">
+</colgroup>
+<tbody>
+<tr>
+<td class="parameter_name"><p>font</p></td>
+<td class="parameter_description"><p>a font</p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+<tr>
+<td class="parameter_name"><p>baseline_tag</p></td>
+<td class="parameter_description"><p>a baseline tag</p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+<tr>
+<td class="parameter_name"><p>direction</p></td>
+<td class="parameter_description"><p>text direction.</p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+<tr>
+<td class="parameter_name"><p>script_tag</p></td>
+<td class="parameter_description"><p>script tag.</p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+<tr>
+<td class="parameter_name"><p>language_tag</p></td>
+<td class="parameter_description"><p>language tag.</p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+<tr>
+<td class="parameter_name"><p>coord</p></td>
+<td class="parameter_description"><p>baseline value if found. </p></td>
+<td class="parameter_annotations"><span class="annotation">[<acronym title="Parameter for returning results. Default is transfer full."><span class="acronym">out</span></acronym>]</span></td>
+</tr>
+</tbody>
+</table></div>
+</div>
+<div class="refsect3">
+<a name="hb-ot-layout-get-baseline.returns"></a><h4>Returns</h4>
+<p> if found baseline value in the the font.</p>
+</div>
+<p class="since">Since: <a class="link" href="api-index-2-6-0.html#api-index-2.6.0">2.6.0</a></p>
 </div>
 <hr>
 <div class="refsect2">
 <a name="hb-ot-layout-get-glyph-class"></a><h3>hb_ot_layout_get_glyph_class ()</h3>
 <pre class="programlisting"><a class="link" href="harfbuzz-hb-ot-layout.html#hb-ot-layout-glyph-class-t" title="enum hb_ot_layout_glyph_class_t"><span class="returnvalue">hb_ot_layout_glyph_class_t</span></a>
-hb_ot_layout_get_glyph_class (<em class="parameter"><code><a class="link" href="harfbuzz-hb-face.html#hb-face-t" title="hb_face_t"><span class="type">hb_face_t</span></a> *face</code></em>,
+hb_ot_layout_get_glyph_class (<em class="parameter"><code><a class="link" href="harfbuzz-hb-face.html#hb-face-t"><span class="type">hb_face_t</span></a> *face</code></em>,
                               <em class="parameter"><code><a class="link" href="harfbuzz-hb-common.html#hb-codepoint-t" title="hb_codepoint_t"><span class="type">hb_codepoint_t</span></a> glyph</code></em>);</pre>
+<p>Fetches the GDEF class of the requested glyph in the specified face.</p>
+<div class="refsect3">
+<a name="hb-ot-layout-get-glyph-class.parameters"></a><h4>Parameters</h4>
+<div class="informaltable"><table class="informaltable" width="100%" border="0">
+<colgroup>
+<col width="150px" class="parameters_name">
+<col class="parameters_description">
+<col width="200px" class="parameters_annotations">
+</colgroup>
+<tbody>
+<tr>
+<td class="parameter_name"><p>face</p></td>
+<td class="parameter_description"><p>The <a class="link" href="harfbuzz-hb-face.html#hb-face-t"><span class="type">hb_face_t</span></a> to work on</p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+<tr>
+<td class="parameter_name"><p>glyph</p></td>
+<td class="parameter_description"><p>The <a class="link" href="harfbuzz-hb-common.html#hb-codepoint-t" title="hb_codepoint_t"><span class="type">hb_codepoint_t</span></a> code point to query</p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+</tbody>
+</table></div>
+</div>
+<div class="refsect3">
+<a name="hb-ot-layout-get-glyph-class.returns"></a><h4>Returns</h4>
+<p> The <a class="link" href="harfbuzz-hb-ot-layout.html#hb-ot-layout-glyph-class-t" title="enum hb_ot_layout_glyph_class_t"><span class="type">hb_ot_layout_glyph_class_t</span></a> glyph class of the given code
+point in the GDEF table of the face.</p>
+</div>
 <p class="since">Since: <a class="link" href="api-index-0-9-7.html#api-index-0.9.7">0.9.7</a></p>
 </div>
 <hr>
 <div class="refsect2">
 <a name="hb-ot-layout-get-glyphs-in-class"></a><h3>hb_ot_layout_get_glyphs_in_class ()</h3>
 <pre class="programlisting"><span class="returnvalue">void</span>
-hb_ot_layout_get_glyphs_in_class (<em class="parameter"><code><a class="link" href="harfbuzz-hb-face.html#hb-face-t" title="hb_face_t"><span class="type">hb_face_t</span></a> *face</code></em>,
+hb_ot_layout_get_glyphs_in_class (<em class="parameter"><code><a class="link" href="harfbuzz-hb-face.html#hb-face-t"><span class="type">hb_face_t</span></a> *face</code></em>,
                                   <em class="parameter"><code><a class="link" href="harfbuzz-hb-ot-layout.html#hb-ot-layout-glyph-class-t" title="enum hb_ot_layout_glyph_class_t"><span class="type">hb_ot_layout_glyph_class_t</span></a> klass</code></em>,
-                                  <em class="parameter"><code><a class="link" href="harfbuzz-hb-set.html#hb-set-t" title="hb_set_t"><span class="type">hb_set_t</span></a> *glyphs</code></em>);</pre>
+                                  <em class="parameter"><code><a class="link" href="harfbuzz-hb-set.html#hb-set-t"><span class="type">hb_set_t</span></a> *glyphs</code></em>);</pre>
+<p>Retrieves the set of all glyphs from the face that belong to the requested
+glyph class in the face's GDEF table.</p>
+<div class="refsect3">
+<a name="hb-ot-layout-get-glyphs-in-class.parameters"></a><h4>Parameters</h4>
+<div class="informaltable"><table class="informaltable" width="100%" border="0">
+<colgroup>
+<col width="150px" class="parameters_name">
+<col class="parameters_description">
+<col width="200px" class="parameters_annotations">
+</colgroup>
+<tbody>
+<tr>
+<td class="parameter_name"><p>face</p></td>
+<td class="parameter_description"><p>The <a class="link" href="harfbuzz-hb-face.html#hb-face-t"><span class="type">hb_face_t</span></a> to work on</p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+<tr>
+<td class="parameter_name"><p>klass</p></td>
+<td class="parameter_description"><p>The <a class="link" href="harfbuzz-hb-ot-layout.html#hb-ot-layout-glyph-class-t" title="enum hb_ot_layout_glyph_class_t"><span class="type">hb_ot_layout_glyph_class_t</span></a> GDEF class to retrieve</p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+<tr>
+<td class="parameter_name"><p>glyphs</p></td>
+<td class="parameter_description"><p>The <a class="link" href="harfbuzz-hb-set.html#hb-set-t"><span class="type">hb_set_t</span></a> set of all glyphs belonging to the requested
+class. </p></td>
+<td class="parameter_annotations"><span class="annotation">[<acronym title="Parameter for returning results. Default is transfer full."><span class="acronym">out</span></acronym>]</span></td>
+</tr>
+</tbody>
+</table></div>
+</div>
 <p class="since">Since: <a class="link" href="api-index-0-9-7.html#api-index-0.9.7">0.9.7</a></p>
 </div>
 <hr>
 <div class="refsect2">
 <a name="hb-ot-layout-get-ligature-carets"></a><h3>hb_ot_layout_get_ligature_carets ()</h3>
 <pre class="programlisting">unsigned <span class="returnvalue">int</span>
-hb_ot_layout_get_ligature_carets (<em class="parameter"><code><a class="link" href="harfbuzz-hb-font.html#hb-font-t" title="hb_font_t"><span class="type">hb_font_t</span></a> *font</code></em>,
+hb_ot_layout_get_ligature_carets (<em class="parameter"><code><a class="link" href="harfbuzz-hb-font.html#hb-font-t"><span class="type">hb_font_t</span></a> *font</code></em>,
                                   <em class="parameter"><code><a class="link" href="harfbuzz-hb-common.html#hb-direction-t" title="enum hb_direction_t"><span class="type">hb_direction_t</span></a> direction</code></em>,
                                   <em class="parameter"><code><a class="link" href="harfbuzz-hb-common.html#hb-codepoint-t" title="hb_codepoint_t"><span class="type">hb_codepoint_t</span></a> glyph</code></em>,
                                   <em class="parameter"><code>unsigned <span class="type">int</span> start_offset</code></em>,
                                   <em class="parameter"><code>unsigned <span class="type">int</span> *caret_count</code></em>,
                                   <em class="parameter"><code><a class="link" href="harfbuzz-hb-common.html#hb-position-t" title="hb_position_t"><span class="type">hb_position_t</span></a> *caret_array</code></em>);</pre>
-</div>
-<hr>
-<div class="refsect2">
-<a name="hb-ot-layout-get-size-params"></a><h3>hb_ot_layout_get_size_params ()</h3>
-<pre class="programlisting"><a class="link" href="harfbuzz-hb-common.html#hb-bool-t" title="hb_bool_t"><span class="returnvalue">hb_bool_t</span></a>
-hb_ot_layout_get_size_params (<em class="parameter"><code><a class="link" href="harfbuzz-hb-face.html#hb-face-t" title="hb_face_t"><span class="type">hb_face_t</span></a> *face</code></em>,
-                              <em class="parameter"><code>unsigned <span class="type">int</span> *design_size</code></em>,
-                              <em class="parameter"><code>unsigned <span class="type">int</span> *subfamily_id</code></em>,
-                              <em class="parameter"><code><a class="link" href="harfbuzz-hb-ot-name.html#hb-ot-name-id-t" title="hb_ot_name_id_t"><span class="type">hb_ot_name_id_t</span></a> *subfamily_name_id</code></em>,
-                              <em class="parameter"><code>unsigned <span class="type">int</span> *range_start</code></em>,
-                              <em class="parameter"><code>unsigned <span class="type">int</span> *range_end</code></em>);</pre>
-<p class="since">Since: <a class="link" href="api-index-0-9-10.html#api-index-0.9.10">0.9.10</a></p>
-</div>
-<hr>
+<p>Fetches a list of the caret positions defined for a ligature glyph in the GDEF
+table of the font. The list returned will begin at the offset provided.</p>
+<div class="refsect3">
+<a name="hb-ot-layout-get-ligature-carets.parameters"></a><h4>Parameters</h4>
+<div class="informaltable"><table class="informaltable" width="100%" border="0">
+<colgroup>
+<col width="150px" class="parameters_name">
+<col class="parameters_description">
+<col width="200px" class="parameters_annotations">
+</colgroup>
+<tbody>
+<tr>
+<td class="parameter_name"><p>font</p></td>
+<td class="parameter_description"><p>The <a class="link" href="harfbuzz-hb-font.html#hb-font-t"><span class="type">hb_font_t</span></a> to work on</p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+<tr>
+<td class="parameter_name"><p>direction</p></td>
+<td class="parameter_description"><p>The <a class="link" href="harfbuzz-hb-common.html#hb-direction-t" title="enum hb_direction_t"><span class="type">hb_direction_t</span></a> text direction to use</p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+<tr>
+<td class="parameter_name"><p>glyph</p></td>
+<td class="parameter_description"><p>The <a class="link" href="harfbuzz-hb-common.html#hb-codepoint-t" title="hb_codepoint_t"><span class="type">hb_codepoint_t</span></a> code point to query</p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+<tr>
+<td class="parameter_name"><p>start_offset</p></td>
+<td class="parameter_description"><p>offset of the first caret position to retrieve</p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+<tr>
+<td class="parameter_name"><p>caret_count</p></td>
+<td class="parameter_description"><p>Input = the maximum number of caret positions to return;
+Output = the actual number of caret positions returned (may be zero). </p></td>
+<td class="parameter_annotations"><span class="annotation">[<acronym title="Parameter for input and for returning results. Default is transfer full."><span class="acronym">inout</span></acronym>][<acronym title="NULL is OK, both for passing and for returning."><span class="acronym">allow-none</span></acronym>]</span></td>
+</tr>
+<tr>
+<td class="parameter_name"><p>caret_array</p></td>
+<td class="parameter_description"><p>The array of caret positions found for the query. </p></td>
+<td class="parameter_annotations"><span class="annotation">[<acronym title="Parameter for returning results. Default is transfer full."><span class="acronym">out</span></acronym>][<acronym title="Parameter points to an array of items."><span class="acronym">array</span></acronym> length=caret_count]</span></td>
+</tr>
+</tbody>
+</table></div>
+</div>
+</div>
+<hr>
+<div class="refsect2">
+<a name="hb-ot-layout-get-size-params"></a><h3>hb_ot_layout_get_size_params ()</h3>
+<pre class="programlisting"><a class="link" href="harfbuzz-hb-common.html#hb-bool-t" title="hb_bool_t"><span class="returnvalue">hb_bool_t</span></a>
+hb_ot_layout_get_size_params (<em class="parameter"><code><a class="link" href="harfbuzz-hb-face.html#hb-face-t"><span class="type">hb_face_t</span></a> *face</code></em>,
+                              <em class="parameter"><code>unsigned <span class="type">int</span> *design_size</code></em>,
+                              <em class="parameter"><code>unsigned <span class="type">int</span> *subfamily_id</code></em>,
+                              <em class="parameter"><code><a class="link" href="harfbuzz-hb-ot-name.html#hb-ot-name-id-t" title="hb_ot_name_id_t"><span class="type">hb_ot_name_id_t</span></a> *subfamily_name_id</code></em>,
+                              <em class="parameter"><code>unsigned <span class="type">int</span> *range_start</code></em>,
+                              <em class="parameter"><code>unsigned <span class="type">int</span> *range_end</code></em>);</pre>
+<p>Fetches optical-size feature data (i.e., the <code class="literal">size</code> feature from GPOS). Note that
+the subfamily_id and the subfamily name string (accessible via the subfamily_name_id)
+as used here are defined as pertaining only to fonts within a font family that differ
+specifically in their respective size ranges; other ways to differentiate fonts within
+a subfamily are not covered by the <code class="literal">size</code> feature.</p>
+<p>For more information on this distinction, see the <code class="literal">size</code> documentation at
+https://docs.microsoft.com/en-us/typography/opentype/spec/features_pt<span class="type">tag-39size39</span></p>
+<div class="refsect3">
+<a name="hb-ot-layout-get-size-params.parameters"></a><h4>Parameters</h4>
+<div class="informaltable"><table class="informaltable" width="100%" border="0">
+<colgroup>
+<col width="150px" class="parameters_name">
+<col class="parameters_description">
+<col width="200px" class="parameters_annotations">
+</colgroup>
+<tbody>
+<tr>
+<td class="parameter_name"><p>face</p></td>
+<td class="parameter_description"><p><a class="link" href="harfbuzz-hb-face.html#hb-face-t"><span class="type">hb_face_t</span></a> to work upon</p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+<tr>
+<td class="parameter_name"><p>design_size</p></td>
+<td class="parameter_description"><p>The design size of the face. </p></td>
+<td class="parameter_annotations"><span class="annotation">[<acronym title="Parameter for returning results. Default is transfer full."><span class="acronym">out</span></acronym>]</span></td>
+</tr>
+<tr>
+<td class="parameter_name"><p>subfamily_id</p></td>
+<td class="parameter_description"><p>The identifier of the face within the font subfamily. </p></td>
+<td class="parameter_annotations"><span class="annotation">[<acronym title="Parameter for returning results. Default is transfer full."><span class="acronym">out</span></acronym>]</span></td>
+</tr>
+<tr>
+<td class="parameter_name"><p>subfamily_name_id</p></td>
+<td class="parameter_description"><p>The ‘name’ table name ID of the face within the font subfamily. </p></td>
+<td class="parameter_annotations"><span class="annotation">[<acronym title="Parameter for returning results. Default is transfer full."><span class="acronym">out</span></acronym>]</span></td>
+</tr>
+<tr>
+<td class="parameter_name"><p>range_start</p></td>
+<td class="parameter_description"><p>The minimum size of the recommended size range for the face. </p></td>
+<td class="parameter_annotations"><span class="annotation">[<acronym title="Parameter for returning results. Default is transfer full."><span class="acronym">out</span></acronym>]</span></td>
+</tr>
+<tr>
+<td class="parameter_name"><p>range_end</p></td>
+<td class="parameter_description"><p>The maximum size of the recommended size range for the face. </p></td>
+<td class="parameter_annotations"><span class="annotation">[<acronym title="Parameter for returning results. Default is transfer full."><span class="acronym">out</span></acronym>]</span></td>
+</tr>
+</tbody>
+</table></div>
+</div>
+<div class="refsect3">
+<a name="hb-ot-layout-get-size-params.returns"></a><h4>Returns</h4>
+<p> true if data found, false otherwise</p>
+</div>
+<p class="since">Since: <a class="link" href="api-index-0-9-10.html#api-index-0.9.10">0.9.10</a></p>
+</div>
+<hr>
 <div class="refsect2">
 <a name="hb-ot-layout-glyph-sequence-func-t"></a><h3>hb_ot_layout_glyph_sequence_func_t ()</h3>
 <pre class="programlisting"><a class="link" href="harfbuzz-hb-common.html#hb-bool-t" title="hb_bool_t"><span class="returnvalue">hb_bool_t</span></a>
-<span class="c_punctuation">(</span>*hb_ot_layout_glyph_sequence_func_t<span class="c_punctuation">)</span> (<em class="parameter"><code><a class="link" href="harfbuzz-hb-font.html#hb-font-t" title="hb_font_t"><span class="type">hb_font_t</span></a> *font</code></em>,
+<span class="c_punctuation">(</span>*hb_ot_layout_glyph_sequence_func_t<span class="c_punctuation">)</span> (<em class="parameter"><code><a class="link" href="harfbuzz-hb-font.html#hb-font-t"><span class="type">hb_font_t</span></a> *font</code></em>,
                                        <em class="parameter"><code><a class="link" href="harfbuzz-hb-common.html#hb-tag-t" title="hb_tag_t"><span class="type">hb_tag_t</span></a> table_tag</code></em>,
                                        <em class="parameter"><code>unsigned <span class="type">int</span> lookup_index</code></em>,
                                        <em class="parameter"><code>const <span class="type">hb_ot_layout_glyph_sequence_t</span> *sequence</code></em>,
@@ -780,81 +1249,387 @@ hb_ot_layout_get_size_params (<em class="parameter"><code><a class="link" href="
 <div class="refsect2">
 <a name="hb-ot-layout-has-glyph-classes"></a><h3>hb_ot_layout_has_glyph_classes ()</h3>
 <pre class="programlisting"><a class="link" href="harfbuzz-hb-common.html#hb-bool-t" title="hb_bool_t"><span class="returnvalue">hb_bool_t</span></a>
-hb_ot_layout_has_glyph_classes (<em class="parameter"><code><a class="link" href="harfbuzz-hb-face.html#hb-face-t" title="hb_face_t"><span class="type">hb_face_t</span></a> *face</code></em>);</pre>
+hb_ot_layout_has_glyph_classes (<em class="parameter"><code><a class="link" href="harfbuzz-hb-face.html#hb-face-t"><span class="type">hb_face_t</span></a> *face</code></em>);</pre>
+<p>Tests whether a face has any glyph classes defined in its GDEF table.</p>
+<div class="refsect3">
+<a name="hb-ot-layout-has-glyph-classes.parameters"></a><h4>Parameters</h4>
+<div class="informaltable"><table class="informaltable" width="100%" border="0">
+<colgroup>
+<col width="150px" class="parameters_name">
+<col class="parameters_description">
+<col width="200px" class="parameters_annotations">
+</colgroup>
+<tbody><tr>
+<td class="parameter_name"><p>face</p></td>
+<td class="parameter_description"><p><a class="link" href="harfbuzz-hb-face.html#hb-face-t"><span class="type">hb_face_t</span></a> to work upon</p></td>
+<td class="parameter_annotations"> </td>
+</tr></tbody>
+</table></div>
+</div>
+<div class="refsect3">
+<a name="hb-ot-layout-has-glyph-classes.returns"></a><h4>Returns</h4>
+<p> true if data found, false otherwise</p>
+</div>
 </div>
 <hr>
 <div class="refsect2">
 <a name="hb-ot-layout-has-positioning"></a><h3>hb_ot_layout_has_positioning ()</h3>
 <pre class="programlisting"><a class="link" href="harfbuzz-hb-common.html#hb-bool-t" title="hb_bool_t"><span class="returnvalue">hb_bool_t</span></a>
-hb_ot_layout_has_positioning (<em class="parameter"><code><a class="link" href="harfbuzz-hb-face.html#hb-face-t" title="hb_face_t"><span class="type">hb_face_t</span></a> *face</code></em>);</pre>
+hb_ot_layout_has_positioning (<em class="parameter"><code><a class="link" href="harfbuzz-hb-face.html#hb-face-t"><span class="type">hb_face_t</span></a> *face</code></em>);</pre>
+<div class="refsect3">
+<a name="hb-ot-layout-has-positioning.parameters"></a><h4>Parameters</h4>
+<div class="informaltable"><table class="informaltable" width="100%" border="0">
+<colgroup>
+<col width="150px" class="parameters_name">
+<col class="parameters_description">
+<col width="200px" class="parameters_annotations">
+</colgroup>
+<tbody><tr>
+<td class="parameter_name"><p>face</p></td>
+<td class="parameter_description"><p><a class="link" href="harfbuzz-hb-face.html#hb-face-t"><span class="type">hb_face_t</span></a> to work upon</p></td>
+<td class="parameter_annotations"> </td>
+</tr></tbody>
+</table></div>
+</div>
+<div class="refsect3">
+<a name="hb-ot-layout-has-positioning.returns"></a><h4>Returns</h4>
+<p> true if the face has GPOS data, false otherwise</p>
+</div>
 </div>
 <hr>
 <div class="refsect2">
 <a name="hb-ot-layout-has-substitution"></a><h3>hb_ot_layout_has_substitution ()</h3>
 <pre class="programlisting"><a class="link" href="harfbuzz-hb-common.html#hb-bool-t" title="hb_bool_t"><span class="returnvalue">hb_bool_t</span></a>
-hb_ot_layout_has_substitution (<em class="parameter"><code><a class="link" href="harfbuzz-hb-face.html#hb-face-t" title="hb_face_t"><span class="type">hb_face_t</span></a> *face</code></em>);</pre>
+hb_ot_layout_has_substitution (<em class="parameter"><code><a class="link" href="harfbuzz-hb-face.html#hb-face-t"><span class="type">hb_face_t</span></a> *face</code></em>);</pre>
+<p>Tests whether the specified face includes any GSUB substitutions.</p>
+<div class="refsect3">
+<a name="hb-ot-layout-has-substitution.parameters"></a><h4>Parameters</h4>
+<div class="informaltable"><table class="informaltable" width="100%" border="0">
+<colgroup>
+<col width="150px" class="parameters_name">
+<col class="parameters_description">
+<col width="200px" class="parameters_annotations">
+</colgroup>
+<tbody><tr>
+<td class="parameter_name"><p>face</p></td>
+<td class="parameter_description"><p><a class="link" href="harfbuzz-hb-face.html#hb-face-t"><span class="type">hb_face_t</span></a> to work upon</p></td>
+<td class="parameter_annotations"> </td>
+</tr></tbody>
+</table></div>
+</div>
+<div class="refsect3">
+<a name="hb-ot-layout-has-substitution.returns"></a><h4>Returns</h4>
+<p> true if data found, false otherwise</p>
+</div>
 </div>
 <hr>
 <div class="refsect2">
 <a name="hb-ot-layout-language-find-feature"></a><h3>hb_ot_layout_language_find_feature ()</h3>
 <pre class="programlisting"><a class="link" href="harfbuzz-hb-common.html#hb-bool-t" title="hb_bool_t"><span class="returnvalue">hb_bool_t</span></a>
-hb_ot_layout_language_find_feature (<em class="parameter"><code><a class="link" href="harfbuzz-hb-face.html#hb-face-t" title="hb_face_t"><span class="type">hb_face_t</span></a> *face</code></em>,
+hb_ot_layout_language_find_feature (<em class="parameter"><code><a class="link" href="harfbuzz-hb-face.html#hb-face-t"><span class="type">hb_face_t</span></a> *face</code></em>,
                                     <em class="parameter"><code><a class="link" href="harfbuzz-hb-common.html#hb-tag-t" title="hb_tag_t"><span class="type">hb_tag_t</span></a> table_tag</code></em>,
                                     <em class="parameter"><code>unsigned <span class="type">int</span> script_index</code></em>,
                                     <em class="parameter"><code>unsigned <span class="type">int</span> language_index</code></em>,
                                     <em class="parameter"><code><a class="link" href="harfbuzz-hb-common.html#hb-tag-t" title="hb_tag_t"><span class="type">hb_tag_t</span></a> feature_tag</code></em>,
                                     <em class="parameter"><code>unsigned <span class="type">int</span> *feature_index</code></em>);</pre>
+<p>Fetches the index of a given feature tag in the specified face's GSUB table
+or GPOS table, underneath the specified script and language.</p>
+<div class="refsect3">
+<a name="hb-ot-layout-language-find-feature.parameters"></a><h4>Parameters</h4>
+<div class="informaltable"><table class="informaltable" width="100%" border="0">
+<colgroup>
+<col width="150px" class="parameters_name">
+<col class="parameters_description">
+<col width="200px" class="parameters_annotations">
+</colgroup>
+<tbody>
+<tr>
+<td class="parameter_name"><p>face</p></td>
+<td class="parameter_description"><p><a class="link" href="harfbuzz-hb-face.html#hb-face-t"><span class="type">hb_face_t</span></a> to work upon</p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+<tr>
+<td class="parameter_name"><p>table_tag</p></td>
+<td class="parameter_description"><p>HB_OT_TAG_GSUB or HB_OT_TAG_GPOS</p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+<tr>
+<td class="parameter_name"><p>script_index</p></td>
+<td class="parameter_description"><p>The index of the requested script tag</p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+<tr>
+<td class="parameter_name"><p>language_index</p></td>
+<td class="parameter_description"><p>The index of the requested language tag</p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+<tr>
+<td class="parameter_name"><p>feature_tag</p></td>
+<td class="parameter_description"><p><a class="link" href="harfbuzz-hb-common.html#hb-tag-t" title="hb_tag_t"><span class="type">hb_tag_t</span></a> of the feature tag requested</p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+<tr>
+<td class="parameter_name"><p>feature_index</p></td>
+<td class="parameter_description"><p>The index of the requested feature. </p></td>
+<td class="parameter_annotations"><span class="annotation">[<acronym title="Parameter for returning results. Default is transfer full."><span class="acronym">out</span></acronym>]</span></td>
+</tr>
+</tbody>
+</table></div>
+</div>
+<div class="refsect3">
+<a name="hb-ot-layout-language-find-feature.returns"></a><h4>Returns</h4>
+<p> true if the feature is found, false otherwise</p>
+</div>
 </div>
 <hr>
 <div class="refsect2">
 <a name="hb-ot-layout-language-get-feature-indexes"></a><h3>hb_ot_layout_language_get_feature_indexes ()</h3>
 <pre class="programlisting">unsigned <span class="returnvalue">int</span>
 hb_ot_layout_language_get_feature_indexes
-                               (<em class="parameter"><code><a class="link" href="harfbuzz-hb-face.html#hb-face-t" title="hb_face_t"><span class="type">hb_face_t</span></a> *face</code></em>,
+                               (<em class="parameter"><code><a class="link" href="harfbuzz-hb-face.html#hb-face-t"><span class="type">hb_face_t</span></a> *face</code></em>,
                                 <em class="parameter"><code><a class="link" href="harfbuzz-hb-common.html#hb-tag-t" title="hb_tag_t"><span class="type">hb_tag_t</span></a> table_tag</code></em>,
                                 <em class="parameter"><code>unsigned <span class="type">int</span> script_index</code></em>,
                                 <em class="parameter"><code>unsigned <span class="type">int</span> language_index</code></em>,
                                 <em class="parameter"><code>unsigned <span class="type">int</span> start_offset</code></em>,
                                 <em class="parameter"><code>unsigned <span class="type">int</span> *feature_count</code></em>,
                                 <em class="parameter"><code>unsigned <span class="type">int</span> *feature_indexes</code></em>);</pre>
+<p>Fetches a list of all features in the specified face's GSUB table
+or GPOS table, underneath the specified script and language. The list
+returned will begin at the offset provided.</p>
+<div class="refsect3">
+<a name="hb-ot-layout-language-get-feature-indexes.parameters"></a><h4>Parameters</h4>
+<div class="informaltable"><table class="informaltable" width="100%" border="0">
+<colgroup>
+<col width="150px" class="parameters_name">
+<col class="parameters_description">
+<col width="200px" class="parameters_annotations">
+</colgroup>
+<tbody>
+<tr>
+<td class="parameter_name"><p>face</p></td>
+<td class="parameter_description"><p><a class="link" href="harfbuzz-hb-face.html#hb-face-t"><span class="type">hb_face_t</span></a> to work upon</p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+<tr>
+<td class="parameter_name"><p>table_tag</p></td>
+<td class="parameter_description"><p>HB_OT_TAG_GSUB or HB_OT_TAG_GPOS</p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+<tr>
+<td class="parameter_name"><p>script_index</p></td>
+<td class="parameter_description"><p>The index of the requested script tag</p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+<tr>
+<td class="parameter_name"><p>language_index</p></td>
+<td class="parameter_description"><p>The index of the requested language tag</p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+<tr>
+<td class="parameter_name"><p>start_offset</p></td>
+<td class="parameter_description"><p>offset of the first feature tag to retrieve</p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+<tr>
+<td class="parameter_name"><p>feature_count</p></td>
+<td class="parameter_description"><p>Input = the maximum number of feature tags to return;
+Output: the actual number of feature tags returned (may be zero). </p></td>
+<td class="parameter_annotations"><span class="annotation">[<acronym title="Parameter for input and for returning results. Default is transfer full."><span class="acronym">inout</span></acronym>][<acronym title="NULL is OK, both for passing and for returning."><span class="acronym">allow-none</span></acronym>]</span></td>
+</tr>
+<tr>
+<td class="parameter_name"><p>feature_indexes</p></td>
+<td class="parameter_description"><p>The array of feature indexes found for the query. </p></td>
+<td class="parameter_annotations"><span class="annotation">[<acronym title="Parameter for returning results. Default is transfer full."><span class="acronym">out</span></acronym>][<acronym title="Parameter points to an array of items."><span class="acronym">array</span></acronym> length=feature_count]</span></td>
+</tr>
+</tbody>
+</table></div>
+</div>
 </div>
 <hr>
 <div class="refsect2">
 <a name="hb-ot-layout-language-get-feature-tags"></a><h3>hb_ot_layout_language_get_feature_tags ()</h3>
 <pre class="programlisting">unsigned <span class="returnvalue">int</span>
 hb_ot_layout_language_get_feature_tags
-                               (<em class="parameter"><code><a class="link" href="harfbuzz-hb-face.html#hb-face-t" title="hb_face_t"><span class="type">hb_face_t</span></a> *face</code></em>,
+                               (<em class="parameter"><code><a class="link" href="harfbuzz-hb-face.html#hb-face-t"><span class="type">hb_face_t</span></a> *face</code></em>,
                                 <em class="parameter"><code><a class="link" href="harfbuzz-hb-common.html#hb-tag-t" title="hb_tag_t"><span class="type">hb_tag_t</span></a> table_tag</code></em>,
                                 <em class="parameter"><code>unsigned <span class="type">int</span> script_index</code></em>,
                                 <em class="parameter"><code>unsigned <span class="type">int</span> language_index</code></em>,
                                 <em class="parameter"><code>unsigned <span class="type">int</span> start_offset</code></em>,
                                 <em class="parameter"><code>unsigned <span class="type">int</span> *feature_count</code></em>,
                                 <em class="parameter"><code><a class="link" href="harfbuzz-hb-common.html#hb-tag-t" title="hb_tag_t"><span class="type">hb_tag_t</span></a> *feature_tags</code></em>);</pre>
+<p>Fetches a list of all features in the specified face's GSUB table
+or GPOS table, underneath the specified script and language. The list
+returned will begin at the offset provided.</p>
+<div class="refsect3">
+<a name="hb-ot-layout-language-get-feature-tags.parameters"></a><h4>Parameters</h4>
+<div class="informaltable"><table class="informaltable" width="100%" border="0">
+<colgroup>
+<col width="150px" class="parameters_name">
+<col class="parameters_description">
+<col width="200px" class="parameters_annotations">
+</colgroup>
+<tbody>
+<tr>
+<td class="parameter_name"><p>face</p></td>
+<td class="parameter_description"><p><a class="link" href="harfbuzz-hb-face.html#hb-face-t"><span class="type">hb_face_t</span></a> to work upon</p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+<tr>
+<td class="parameter_name"><p>table_tag</p></td>
+<td class="parameter_description"><p>HB_OT_TAG_GSUB or HB_OT_TAG_GPOS</p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+<tr>
+<td class="parameter_name"><p>script_index</p></td>
+<td class="parameter_description"><p>The index of the requested script tag</p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+<tr>
+<td class="parameter_name"><p>language_index</p></td>
+<td class="parameter_description"><p>The index of the requested language tag</p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+<tr>
+<td class="parameter_name"><p>start_offset</p></td>
+<td class="parameter_description"><p>offset of the first feature tag to retrieve</p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+<tr>
+<td class="parameter_name"><p>feature_count</p></td>
+<td class="parameter_description"><p>Input = the maximum number of feature tags to return;
+Output = the actual number of feature tags returned (may be zero). </p></td>
+<td class="parameter_annotations"><span class="annotation">[<acronym title="Parameter for input and for returning results. Default is transfer full."><span class="acronym">inout</span></acronym>][<acronym title="NULL is OK, both for passing and for returning."><span class="acronym">allow-none</span></acronym>]</span></td>
+</tr>
+<tr>
+<td class="parameter_name"><p>feature_tags</p></td>
+<td class="parameter_description"><p>The array of <a class="link" href="harfbuzz-hb-common.html#hb-tag-t" title="hb_tag_t"><span class="type">hb_tag_t</span></a> feature tags found for the query. </p></td>
+<td class="parameter_annotations"><span class="annotation">[<acronym title="Parameter for returning results. Default is transfer full."><span class="acronym">out</span></acronym>][<acronym title="Parameter points to an array of items."><span class="acronym">array</span></acronym> length=feature_count]</span></td>
+</tr>
+</tbody>
+</table></div>
+</div>
 </div>
 <hr>
 <div class="refsect2">
 <a name="hb-ot-layout-language-get-required-feature"></a><h3>hb_ot_layout_language_get_required_feature ()</h3>
 <pre class="programlisting"><a class="link" href="harfbuzz-hb-common.html#hb-bool-t" title="hb_bool_t"><span class="returnvalue">hb_bool_t</span></a>
 hb_ot_layout_language_get_required_feature
-                               (<em class="parameter"><code><a class="link" href="harfbuzz-hb-face.html#hb-face-t" title="hb_face_t"><span class="type">hb_face_t</span></a> *face</code></em>,
+                               (<em class="parameter"><code><a class="link" href="harfbuzz-hb-face.html#hb-face-t"><span class="type">hb_face_t</span></a> *face</code></em>,
                                 <em class="parameter"><code><a class="link" href="harfbuzz-hb-common.html#hb-tag-t" title="hb_tag_t"><span class="type">hb_tag_t</span></a> table_tag</code></em>,
                                 <em class="parameter"><code>unsigned <span class="type">int</span> script_index</code></em>,
                                 <em class="parameter"><code>unsigned <span class="type">int</span> language_index</code></em>,
                                 <em class="parameter"><code>unsigned <span class="type">int</span> *feature_index</code></em>,
                                 <em class="parameter"><code><a class="link" href="harfbuzz-hb-common.html#hb-tag-t" title="hb_tag_t"><span class="type">hb_tag_t</span></a> *feature_tag</code></em>);</pre>
+<p>Fetches the tag of a requested feature index in the given face's GSUB or GPOS table,
+underneath the specified script and language.</p>
+<div class="refsect3">
+<a name="hb-ot-layout-language-get-required-feature.parameters"></a><h4>Parameters</h4>
+<div class="informaltable"><table class="informaltable" width="100%" border="0">
+<colgroup>
+<col width="150px" class="parameters_name">
+<col class="parameters_description">
+<col width="200px" class="parameters_annotations">
+</colgroup>
+<tbody>
+<tr>
+<td class="parameter_name"><p>face</p></td>
+<td class="parameter_description"><p><a class="link" href="harfbuzz-hb-face.html#hb-face-t"><span class="type">hb_face_t</span></a> to work upon</p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+<tr>
+<td class="parameter_name"><p>table_tag</p></td>
+<td class="parameter_description"><p>HB_OT_TAG_GSUB or HB_OT_TAG_GPOS</p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+<tr>
+<td class="parameter_name"><p>script_index</p></td>
+<td class="parameter_description"><p>The index of the requested script tag</p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+<tr>
+<td class="parameter_name"><p>language_index</p></td>
+<td class="parameter_description"><p>The index of the requested language tag</p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+<tr>
+<td class="parameter_name"><p>feature_index</p></td>
+<td class="parameter_description"><p>The index of the requested feature</p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+<tr>
+<td class="parameter_name"><p>feature_tag</p></td>
+<td class="parameter_description"><p>The <a class="link" href="harfbuzz-hb-common.html#hb-tag-t" title="hb_tag_t"><span class="type">hb_tag_t</span></a> of the requested feature. </p></td>
+<td class="parameter_annotations"><span class="annotation">[<acronym title="Parameter for returning results. Default is transfer full."><span class="acronym">out</span></acronym>]</span></td>
+</tr>
+</tbody>
+</table></div>
+</div>
+<div class="refsect3">
+<a name="hb-ot-layout-language-get-required-feature.returns"></a><h4>Returns</h4>
+<p> true if the feature is found, false otherwise</p>
+</div>
 <p class="since">Since: <a class="link" href="api-index-0-9-30.html#api-index-0.9.30">0.9.30</a></p>
 </div>
 <hr>
 <div class="refsect2">
 <a name="hb-ot-layout-lookup-collect-glyphs"></a><h3>hb_ot_layout_lookup_collect_glyphs ()</h3>
 <pre class="programlisting"><span class="returnvalue">void</span>
-hb_ot_layout_lookup_collect_glyphs (<em class="parameter"><code><a class="link" href="harfbuzz-hb-face.html#hb-face-t" title="hb_face_t"><span class="type">hb_face_t</span></a> *face</code></em>,
+hb_ot_layout_lookup_collect_glyphs (<em class="parameter"><code><a class="link" href="harfbuzz-hb-face.html#hb-face-t"><span class="type">hb_face_t</span></a> *face</code></em>,
                                     <em class="parameter"><code><a class="link" href="harfbuzz-hb-common.html#hb-tag-t" title="hb_tag_t"><span class="type">hb_tag_t</span></a> table_tag</code></em>,
                                     <em class="parameter"><code>unsigned <span class="type">int</span> lookup_index</code></em>,
-                                    <em class="parameter"><code><a class="link" href="harfbuzz-hb-set.html#hb-set-t" title="hb_set_t"><span class="type">hb_set_t</span></a> *glyphs_before</code></em>,
-                                    <em class="parameter"><code><a class="link" href="harfbuzz-hb-set.html#hb-set-t" title="hb_set_t"><span class="type">hb_set_t</span></a> *glyphs_input</code></em>,
-                                    <em class="parameter"><code><a class="link" href="harfbuzz-hb-set.html#hb-set-t" title="hb_set_t"><span class="type">hb_set_t</span></a> *glyphs_after</code></em>,
-                                    <em class="parameter"><code><a class="link" href="harfbuzz-hb-set.html#hb-set-t" title="hb_set_t"><span class="type">hb_set_t</span></a> *glyphs_output</code></em>);</pre>
+                                    <em class="parameter"><code><a class="link" href="harfbuzz-hb-set.html#hb-set-t"><span class="type">hb_set_t</span></a> *glyphs_before</code></em>,
+                                    <em class="parameter"><code><a class="link" href="harfbuzz-hb-set.html#hb-set-t"><span class="type">hb_set_t</span></a> *glyphs_input</code></em>,
+                                    <em class="parameter"><code><a class="link" href="harfbuzz-hb-set.html#hb-set-t"><span class="type">hb_set_t</span></a> *glyphs_after</code></em>,
+                                    <em class="parameter"><code><a class="link" href="harfbuzz-hb-set.html#hb-set-t"><span class="type">hb_set_t</span></a> *glyphs_output</code></em>);</pre>
+<p>Fetches a list of all glyphs affected by the specified lookup in the
+specified face's GSUB table or GPOS table.</p>
+<div class="refsect3">
+<a name="hb-ot-layout-lookup-collect-glyphs.parameters"></a><h4>Parameters</h4>
+<div class="informaltable"><table class="informaltable" width="100%" border="0">
+<colgroup>
+<col width="150px" class="parameters_name">
+<col class="parameters_description">
+<col width="200px" class="parameters_annotations">
+</colgroup>
+<tbody>
+<tr>
+<td class="parameter_name"><p>face</p></td>
+<td class="parameter_description"><p><a class="link" href="harfbuzz-hb-face.html#hb-face-t"><span class="type">hb_face_t</span></a> to work upon</p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+<tr>
+<td class="parameter_name"><p>table_tag</p></td>
+<td class="parameter_description"><p>HB_OT_TAG_GSUB or HB_OT_TAG_GPOS</p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+<tr>
+<td class="parameter_name"><p>lookup_index</p></td>
+<td class="parameter_description"><p>The index of the feature lookup to query</p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+<tr>
+<td class="parameter_name"><p>glyphs_before</p></td>
+<td class="parameter_description"><p>Array of glyphs preceding the substitution range. </p></td>
+<td class="parameter_annotations"><span class="annotation">[<acronym title="Parameter for returning results. Default is transfer full."><span class="acronym">out</span></acronym>]</span></td>
+</tr>
+<tr>
+<td class="parameter_name"><p>glyphs_input</p></td>
+<td class="parameter_description"><p>Array of input glyphs that would be substituted by the lookup. </p></td>
+<td class="parameter_annotations"><span class="annotation">[<acronym title="Parameter for returning results. Default is transfer full."><span class="acronym">out</span></acronym>]</span></td>
+</tr>
+<tr>
+<td class="parameter_name"><p>glyphs_after</p></td>
+<td class="parameter_description"><p>Array of glyphs following the substition range. </p></td>
+<td class="parameter_annotations"><span class="annotation">[<acronym title="Parameter for returning results. Default is transfer full."><span class="acronym">out</span></acronym>]</span></td>
+</tr>
+<tr>
+<td class="parameter_name"><p>glyphs_output</p></td>
+<td class="parameter_description"><p>Array of glyphs that would be the substitued output of the lookup. </p></td>
+<td class="parameter_annotations"><span class="annotation">[<acronym title="Parameter for returning results. Default is transfer full."><span class="acronym">out</span></acronym>]</span></td>
+</tr>
+</tbody>
+</table></div>
+</div>
 <p class="since">Since: <a class="link" href="api-index-0-9-7.html#api-index-0.9.7">0.9.7</a></p>
 </div>
 <hr>
@@ -862,9 +1637,38 @@ hb_ot_layout_lookup_collect_glyphs (<em class="parameter"><code><a class="link"
 <a name="hb-ot-layout-lookup-substitute-closure"></a><h3>hb_ot_layout_lookup_substitute_closure ()</h3>
 <pre class="programlisting"><span class="returnvalue">void</span>
 hb_ot_layout_lookup_substitute_closure
-                               (<em class="parameter"><code><a class="link" href="harfbuzz-hb-face.html#hb-face-t" title="hb_face_t"><span class="type">hb_face_t</span></a> *face</code></em>,
+                               (<em class="parameter"><code><a class="link" href="harfbuzz-hb-face.html#hb-face-t"><span class="type">hb_face_t</span></a> *face</code></em>,
                                 <em class="parameter"><code>unsigned <span class="type">int</span> lookup_index</code></em>,
-                                <em class="parameter"><code><a class="link" href="harfbuzz-hb-set.html#hb-set-t" title="hb_set_t"><span class="type">hb_set_t</span></a> *glyphs</code></em>);</pre>
+                                <em class="parameter"><code><a class="link" href="harfbuzz-hb-set.html#hb-set-t"><span class="type">hb_set_t</span></a> *glyphs</code></em>);</pre>
+<p>Compute the transitive closure of glyphs needed for a
+specified lookup.</p>
+<div class="refsect3">
+<a name="hb-ot-layout-lookup-substitute-closure.parameters"></a><h4>Parameters</h4>
+<div class="informaltable"><table class="informaltable" width="100%" border="0">
+<colgroup>
+<col width="150px" class="parameters_name">
+<col class="parameters_description">
+<col width="200px" class="parameters_annotations">
+</colgroup>
+<tbody>
+<tr>
+<td class="parameter_name"><p>face</p></td>
+<td class="parameter_description"><p><a class="link" href="harfbuzz-hb-face.html#hb-face-t"><span class="type">hb_face_t</span></a> to work upon</p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+<tr>
+<td class="parameter_name"><p>lookup_index</p></td>
+<td class="parameter_description"><p>index of the feature lookup to query</p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+<tr>
+<td class="parameter_name"><p>glyphs</p></td>
+<td class="parameter_description"><p>Array of glyphs comprising the transitive closure of the lookup. </p></td>
+<td class="parameter_annotations"><span class="annotation">[<acronym title="Parameter for returning results. Default is transfer full."><span class="acronym">out</span></acronym>]</span></td>
+</tr>
+</tbody>
+</table></div>
+</div>
 <p class="since">Since: <a class="link" href="api-index-0-9-7.html#api-index-0.9.7">0.9.7</a></p>
 </div>
 <hr>
@@ -872,45 +1676,208 @@ hb_ot_layout_lookup_substitute_closure
 <a name="hb-ot-layout-lookups-substitute-closure"></a><h3>hb_ot_layout_lookups_substitute_closure ()</h3>
 <pre class="programlisting"><span class="returnvalue">void</span>
 hb_ot_layout_lookups_substitute_closure
-                               (<em class="parameter"><code><a class="link" href="harfbuzz-hb-face.html#hb-face-t" title="hb_face_t"><span class="type">hb_face_t</span></a> *face</code></em>,
-                                <em class="parameter"><code>const <a class="link" href="harfbuzz-hb-set.html#hb-set-t" title="hb_set_t"><span class="type">hb_set_t</span></a> *lookups</code></em>,
-                                <em class="parameter"><code><a class="link" href="harfbuzz-hb-set.html#hb-set-t" title="hb_set_t"><span class="type">hb_set_t</span></a> *glyphs</code></em>);</pre>
+                               (<em class="parameter"><code><a class="link" href="harfbuzz-hb-face.html#hb-face-t"><span class="type">hb_face_t</span></a> *face</code></em>,
+                                <em class="parameter"><code>const <a class="link" href="harfbuzz-hb-set.html#hb-set-t"><span class="type">hb_set_t</span></a> *lookups</code></em>,
+                                <em class="parameter"><code><a class="link" href="harfbuzz-hb-set.html#hb-set-t"><span class="type">hb_set_t</span></a> *glyphs</code></em>);</pre>
 <p>Compute the transitive closure of glyphs needed for all of the
 provided lookups.</p>
+<div class="refsect3">
+<a name="hb-ot-layout-lookups-substitute-closure.parameters"></a><h4>Parameters</h4>
+<div class="informaltable"><table class="informaltable" width="100%" border="0">
+<colgroup>
+<col width="150px" class="parameters_name">
+<col class="parameters_description">
+<col width="200px" class="parameters_annotations">
+</colgroup>
+<tbody>
+<tr>
+<td class="parameter_name"><p>face</p></td>
+<td class="parameter_description"><p><a class="link" href="harfbuzz-hb-face.html#hb-face-t"><span class="type">hb_face_t</span></a> to work upon</p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+<tr>
+<td class="parameter_name"><p>lookups</p></td>
+<td class="parameter_description"><p>The set of lookups to query</p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+<tr>
+<td class="parameter_name"><p>glyphs</p></td>
+<td class="parameter_description"><p>Array of glyphs comprising the transitive closure of the lookups. </p></td>
+<td class="parameter_annotations"><span class="annotation">[<acronym title="Parameter for returning results. Default is transfer full."><span class="acronym">out</span></acronym>]</span></td>
+</tr>
+</tbody>
+</table></div>
+</div>
 <p class="since">Since: <a class="link" href="api-index-1-8-1.html#api-index-1.8.1">1.8.1</a></p>
 </div>
 <hr>
 <div class="refsect2">
 <a name="hb-ot-layout-lookup-would-substitute"></a><h3>hb_ot_layout_lookup_would_substitute ()</h3>
 <pre class="programlisting"><a class="link" href="harfbuzz-hb-common.html#hb-bool-t" title="hb_bool_t"><span class="returnvalue">hb_bool_t</span></a>
-hb_ot_layout_lookup_would_substitute (<em class="parameter"><code><a class="link" href="harfbuzz-hb-face.html#hb-face-t" title="hb_face_t"><span class="type">hb_face_t</span></a> *face</code></em>,
+hb_ot_layout_lookup_would_substitute (<em class="parameter"><code><a class="link" href="harfbuzz-hb-face.html#hb-face-t"><span class="type">hb_face_t</span></a> *face</code></em>,
                                       <em class="parameter"><code>unsigned <span class="type">int</span> lookup_index</code></em>,
                                       <em class="parameter"><code>const <a class="link" href="harfbuzz-hb-common.html#hb-codepoint-t" title="hb_codepoint_t"><span class="type">hb_codepoint_t</span></a> *glyphs</code></em>,
                                       <em class="parameter"><code>unsigned <span class="type">int</span> glyphs_length</code></em>,
                                       <em class="parameter"><code><a class="link" href="harfbuzz-hb-common.html#hb-bool-t" title="hb_bool_t"><span class="type">hb_bool_t</span></a> zero_context</code></em>);</pre>
+<p>Tests whether a specified lookup in the specified face would
+trigger a substitution on the given glyph sequence.</p>
+<div class="refsect3">
+<a name="hb-ot-layout-lookup-would-substitute.parameters"></a><h4>Parameters</h4>
+<div class="informaltable"><table class="informaltable" width="100%" border="0">
+<colgroup>
+<col width="150px" class="parameters_name">
+<col class="parameters_description">
+<col width="200px" class="parameters_annotations">
+</colgroup>
+<tbody>
+<tr>
+<td class="parameter_name"><p>face</p></td>
+<td class="parameter_description"><p><a class="link" href="harfbuzz-hb-face.html#hb-face-t"><span class="type">hb_face_t</span></a> to work upon</p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+<tr>
+<td class="parameter_name"><p>lookup_index</p></td>
+<td class="parameter_description"><p>The index of the lookup to query</p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+<tr>
+<td class="parameter_name"><p>glyphs</p></td>
+<td class="parameter_description"><p>The sequence of glyphs to query for substitution</p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+<tr>
+<td class="parameter_name"><p>glyphs_length</p></td>
+<td class="parameter_description"><p>The length of the glyph sequence</p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+<tr>
+<td class="parameter_name"><p>zero_context</p></td>
+<td class="parameter_description"><p><a class="link" href="harfbuzz-hb-common.html#hb-bool-t" title="hb_bool_t"><span class="type">hb_bool_t</span></a> indicating whether substitutions should be context-free</p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+</tbody>
+</table></div>
+</div>
+<div class="refsect3">
+<a name="hb-ot-layout-lookup-would-substitute.returns"></a><h4>Returns</h4>
+<p> true if a substitution would be triggered, false otherwise</p>
+</div>
 <p class="since">Since: <a class="link" href="api-index-0-9-7.html#api-index-0.9.7">0.9.7</a></p>
 </div>
 <hr>
 <div class="refsect2">
 <a name="hb-ot-layout-script-get-language-tags"></a><h3>hb_ot_layout_script_get_language_tags ()</h3>
 <pre class="programlisting">unsigned <span class="returnvalue">int</span>
-hb_ot_layout_script_get_language_tags (<em class="parameter"><code><a class="link" href="harfbuzz-hb-face.html#hb-face-t" title="hb_face_t"><span class="type">hb_face_t</span></a> *face</code></em>,
+hb_ot_layout_script_get_language_tags (<em class="parameter"><code><a class="link" href="harfbuzz-hb-face.html#hb-face-t"><span class="type">hb_face_t</span></a> *face</code></em>,
                                        <em class="parameter"><code><a class="link" href="harfbuzz-hb-common.html#hb-tag-t" title="hb_tag_t"><span class="type">hb_tag_t</span></a> table_tag</code></em>,
                                        <em class="parameter"><code>unsigned <span class="type">int</span> script_index</code></em>,
                                        <em class="parameter"><code>unsigned <span class="type">int</span> start_offset</code></em>,
                                        <em class="parameter"><code>unsigned <span class="type">int</span> *language_count</code></em>,
                                        <em class="parameter"><code><a class="link" href="harfbuzz-hb-common.html#hb-tag-t" title="hb_tag_t"><span class="type">hb_tag_t</span></a> *language_tags</code></em>);</pre>
+<p>Fetches a list of language tags in the given face's GSUB or GPOS table, underneath
+the specified script index. The list returned will begin at the offset provided.</p>
+<div class="refsect3">
+<a name="hb-ot-layout-script-get-language-tags.parameters"></a><h4>Parameters</h4>
+<div class="informaltable"><table class="informaltable" width="100%" border="0">
+<colgroup>
+<col width="150px" class="parameters_name">
+<col class="parameters_description">
+<col width="200px" class="parameters_annotations">
+</colgroup>
+<tbody>
+<tr>
+<td class="parameter_name"><p>face</p></td>
+<td class="parameter_description"><p><a class="link" href="harfbuzz-hb-face.html#hb-face-t"><span class="type">hb_face_t</span></a> to work upon</p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+<tr>
+<td class="parameter_name"><p>table_tag</p></td>
+<td class="parameter_description"><p>HB_OT_TAG_GSUB or HB_OT_TAG_GPOS</p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+<tr>
+<td class="parameter_name"><p>script_index</p></td>
+<td class="parameter_description"><p>The index of the requested script tag</p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+<tr>
+<td class="parameter_name"><p>start_offset</p></td>
+<td class="parameter_description"><p>offset of the first language tag to retrieve</p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+<tr>
+<td class="parameter_name"><p>language_count</p></td>
+<td class="parameter_description"><p>Input = the maximum number of language tags to return;
+Output = the actual number of language tags returned (may be zero). </p></td>
+<td class="parameter_annotations"><span class="annotation">[<acronym title="Parameter for input and for returning results. Default is transfer full."><span class="acronym">inout</span></acronym>][<acronym title="NULL is OK, both for passing and for returning."><span class="acronym">allow-none</span></acronym>]</span></td>
+</tr>
+<tr>
+<td class="parameter_name"><p>language_tags</p></td>
+<td class="parameter_description"><p>Array of language tags found in the table. </p></td>
+<td class="parameter_annotations"><span class="annotation">[<acronym title="Parameter for returning results. Default is transfer full."><span class="acronym">out</span></acronym>][<acronym title="Parameter points to an array of items."><span class="acronym">array</span></acronym> length=language_count]</span></td>
+</tr>
+</tbody>
+</table></div>
+</div>
 </div>
 <hr>
 <div class="refsect2">
 <a name="hb-ot-layout-script-select-language"></a><h3>hb_ot_layout_script_select_language ()</h3>
 <pre class="programlisting"><a class="link" href="harfbuzz-hb-common.html#hb-bool-t" title="hb_bool_t"><span class="returnvalue">hb_bool_t</span></a>
-hb_ot_layout_script_select_language (<em class="parameter"><code><a class="link" href="harfbuzz-hb-face.html#hb-face-t" title="hb_face_t"><span class="type">hb_face_t</span></a> *face</code></em>,
+hb_ot_layout_script_select_language (<em class="parameter"><code><a class="link" href="harfbuzz-hb-face.html#hb-face-t"><span class="type">hb_face_t</span></a> *face</code></em>,
                                      <em class="parameter"><code><a class="link" href="harfbuzz-hb-common.html#hb-tag-t" title="hb_tag_t"><span class="type">hb_tag_t</span></a> table_tag</code></em>,
                                      <em class="parameter"><code>unsigned <span class="type">int</span> script_index</code></em>,
                                      <em class="parameter"><code>unsigned <span class="type">int</span> language_count</code></em>,
                                      <em class="parameter"><code>const <a class="link" href="harfbuzz-hb-common.html#hb-tag-t" title="hb_tag_t"><span class="type">hb_tag_t</span></a> *language_tags</code></em>,
                                      <em class="parameter"><code>unsigned <span class="type">int</span> *language_index</code></em>);</pre>
+<p>Fetches the index of a given language tag in the specified face's GSUB table
+or GPOS table, underneath the specified script index.</p>
+<div class="refsect3">
+<a name="hb-ot-layout-script-select-language.parameters"></a><h4>Parameters</h4>
+<div class="informaltable"><table class="informaltable" width="100%" border="0">
+<colgroup>
+<col width="150px" class="parameters_name">
+<col class="parameters_description">
+<col width="200px" class="parameters_annotations">
+</colgroup>
+<tbody>
+<tr>
+<td class="parameter_name"><p>face</p></td>
+<td class="parameter_description"><p><a class="link" href="harfbuzz-hb-face.html#hb-face-t"><span class="type">hb_face_t</span></a> to work upon</p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+<tr>
+<td class="parameter_name"><p>table_tag</p></td>
+<td class="parameter_description"><p>HB_OT_TAG_GSUB or HB_OT_TAG_GPOS</p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+<tr>
+<td class="parameter_name"><p>script_index</p></td>
+<td class="parameter_description"><p>The index of the requested script tag</p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+<tr>
+<td class="parameter_name"><p>language_count</p></td>
+<td class="parameter_description"><p>The number of languages in the specified script</p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+<tr>
+<td class="parameter_name"><p>language_tags</p></td>
+<td class="parameter_description"><p>The array of language tags</p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+<tr>
+<td class="parameter_name"><p>language_index</p></td>
+<td class="parameter_description"><p>The index of the requested language. </p></td>
+<td class="parameter_annotations"><span class="annotation">[<acronym title="Parameter for returning results. Default is transfer full."><span class="acronym">out</span></acronym>]</span></td>
+</tr>
+</tbody>
+</table></div>
+</div>
+<div class="refsect3">
+<a name="hb-ot-layout-script-select-language.returns"></a><h4>Returns</h4>
+<p> true if the language tag is found, false otherwise</p>
+</div>
 <p class="since">Since: <a class="link" href="api-index-2-0-0.html#api-index-2.0.0">2.0.0</a></p>
 </div>
 <hr>
@@ -918,59 +1885,243 @@ hb_ot_layout_script_select_language (<em class="parameter"><code><a class="link"
 <a name="hb-ot-layout-table-find-feature-variations"></a><h3>hb_ot_layout_table_find_feature_variations ()</h3>
 <pre class="programlisting"><a class="link" href="harfbuzz-hb-common.html#hb-bool-t" title="hb_bool_t"><span class="returnvalue">hb_bool_t</span></a>
 hb_ot_layout_table_find_feature_variations
-                               (<em class="parameter"><code><a class="link" href="harfbuzz-hb-face.html#hb-face-t" title="hb_face_t"><span class="type">hb_face_t</span></a> *face</code></em>,
+                               (<em class="parameter"><code><a class="link" href="harfbuzz-hb-face.html#hb-face-t"><span class="type">hb_face_t</span></a> *face</code></em>,
                                 <em class="parameter"><code><a class="link" href="harfbuzz-hb-common.html#hb-tag-t" title="hb_tag_t"><span class="type">hb_tag_t</span></a> table_tag</code></em>,
                                 <em class="parameter"><code>const <span class="type">int</span> *coords</code></em>,
                                 <em class="parameter"><code>unsigned <span class="type">int</span> num_coords</code></em>,
                                 <em class="parameter"><code>unsigned <span class="type">int</span> *variations_index</code></em>);</pre>
+<p>Fetches a list of feature variations in the specified face's GSUB table
+or GPOS table, at the specified variation coordinates.</p>
+<div class="refsect3">
+<a name="hb-ot-layout-table-find-feature-variations.parameters"></a><h4>Parameters</h4>
+<div class="informaltable"><table class="informaltable" width="100%" border="0">
+<colgroup>
+<col width="150px" class="parameters_name">
+<col class="parameters_description">
+<col width="200px" class="parameters_annotations">
+</colgroup>
+<tbody>
+<tr>
+<td class="parameter_name"><p>face</p></td>
+<td class="parameter_description"><p><a class="link" href="harfbuzz-hb-face.html#hb-face-t"><span class="type">hb_face_t</span></a> to work upon</p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+<tr>
+<td class="parameter_name"><p>table_tag</p></td>
+<td class="parameter_description"><p>HB_OT_TAG_GSUB or HB_OT_TAG_GPOS</p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+<tr>
+<td class="parameter_name"><p>coords</p></td>
+<td class="parameter_description"><p>The variation coordinates to query</p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+<tr>
+<td class="parameter_name"><p>num_coords</p></td>
+<td class="parameter_description"><p>The number of variation coorinates</p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+<tr>
+<td class="parameter_name"><p>variations_index</p></td>
+<td class="parameter_description"><p>The array of feature variations found for the query. </p></td>
+<td class="parameter_annotations"><span class="annotation">[<acronym title="Parameter for returning results. Default is transfer full."><span class="acronym">out</span></acronym>]</span></td>
+</tr>
+</tbody>
+</table></div>
+</div>
 </div>
 <hr>
 <div class="refsect2">
 <a name="hb-ot-layout-table-get-feature-tags"></a><h3>hb_ot_layout_table_get_feature_tags ()</h3>
 <pre class="programlisting">unsigned <span class="returnvalue">int</span>
-hb_ot_layout_table_get_feature_tags (<em class="parameter"><code><a class="link" href="harfbuzz-hb-face.html#hb-face-t" title="hb_face_t"><span class="type">hb_face_t</span></a> *face</code></em>,
+hb_ot_layout_table_get_feature_tags (<em class="parameter"><code><a class="link" href="harfbuzz-hb-face.html#hb-face-t"><span class="type">hb_face_t</span></a> *face</code></em>,
                                      <em class="parameter"><code><a class="link" href="harfbuzz-hb-common.html#hb-tag-t" title="hb_tag_t"><span class="type">hb_tag_t</span></a> table_tag</code></em>,
                                      <em class="parameter"><code>unsigned <span class="type">int</span> start_offset</code></em>,
                                      <em class="parameter"><code>unsigned <span class="type">int</span> *feature_count</code></em>,
                                      <em class="parameter"><code><a class="link" href="harfbuzz-hb-common.html#hb-tag-t" title="hb_tag_t"><span class="type">hb_tag_t</span></a> *feature_tags</code></em>);</pre>
+<p>Fetches a list of all feature tags in the given face's GSUB or GPOS table.</p>
+<div class="refsect3">
+<a name="hb-ot-layout-table-get-feature-tags.parameters"></a><h4>Parameters</h4>
+<div class="informaltable"><table class="informaltable" width="100%" border="0">
+<colgroup>
+<col width="150px" class="parameters_name">
+<col class="parameters_description">
+<col width="200px" class="parameters_annotations">
+</colgroup>
+<tbody>
+<tr>
+<td class="parameter_name"><p>face</p></td>
+<td class="parameter_description"><p><a class="link" href="harfbuzz-hb-face.html#hb-face-t"><span class="type">hb_face_t</span></a> to work upon</p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+<tr>
+<td class="parameter_name"><p>table_tag</p></td>
+<td class="parameter_description"><p>HB_OT_TAG_GSUB or HB_OT_TAG_GPOS</p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+<tr>
+<td class="parameter_name"><p>start_offset</p></td>
+<td class="parameter_description"><p>offset of the first feature tag to retrieve</p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+<tr>
+<td class="parameter_name"><p>feature_count</p></td>
+<td class="parameter_description"><p>Input = the maximum number of feature tags to return;
+Output = the actual number of feature tags returned (may be zero). </p></td>
+<td class="parameter_annotations"><span class="annotation">[<acronym title="Parameter for input and for returning results. Default is transfer full."><span class="acronym">inout</span></acronym>][<acronym title="NULL is OK, both for passing and for returning."><span class="acronym">allow-none</span></acronym>]</span></td>
+</tr>
+<tr>
+<td class="parameter_name"><p>feature_tags</p></td>
+<td class="parameter_description"><p>Array of feature tags found in the table. </p></td>
+<td class="parameter_annotations"><span class="annotation">[<acronym title="Parameter for returning results. Default is transfer full."><span class="acronym">out</span></acronym>][<acronym title="Parameter points to an array of items."><span class="acronym">array</span></acronym> length=feature_count]</span></td>
+</tr>
+</tbody>
+</table></div>
+</div>
 </div>
 <hr>
 <div class="refsect2">
 <a name="hb-ot-layout-table-get-script-tags"></a><h3>hb_ot_layout_table_get_script_tags ()</h3>
 <pre class="programlisting">unsigned <span class="returnvalue">int</span>
-hb_ot_layout_table_get_script_tags (<em class="parameter"><code><a class="link" href="harfbuzz-hb-face.html#hb-face-t" title="hb_face_t"><span class="type">hb_face_t</span></a> *face</code></em>,
+hb_ot_layout_table_get_script_tags (<em class="parameter"><code><a class="link" href="harfbuzz-hb-face.html#hb-face-t"><span class="type">hb_face_t</span></a> *face</code></em>,
                                     <em class="parameter"><code><a class="link" href="harfbuzz-hb-common.html#hb-tag-t" title="hb_tag_t"><span class="type">hb_tag_t</span></a> table_tag</code></em>,
                                     <em class="parameter"><code>unsigned <span class="type">int</span> start_offset</code></em>,
                                     <em class="parameter"><code>unsigned <span class="type">int</span> *script_count</code></em>,
                                     <em class="parameter"><code><a class="link" href="harfbuzz-hb-common.html#hb-tag-t" title="hb_tag_t"><span class="type">hb_tag_t</span></a> *script_tags</code></em>);</pre>
+<p>Fetches a list of all scripts enumerated in the specified face's GSUB table
+or GPOS table. The list returned will begin at the offset provided.</p>
+<div class="refsect3">
+<a name="hb-ot-layout-table-get-script-tags.parameters"></a><h4>Parameters</h4>
+<div class="informaltable"><table class="informaltable" width="100%" border="0">
+<colgroup>
+<col width="150px" class="parameters_name">
+<col class="parameters_description">
+<col width="200px" class="parameters_annotations">
+</colgroup>
+<tbody>
+<tr>
+<td class="parameter_name"><p>face</p></td>
+<td class="parameter_description"><p><a class="link" href="harfbuzz-hb-face.html#hb-face-t"><span class="type">hb_face_t</span></a> to work upon</p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+<tr>
+<td class="parameter_name"><p>table_tag</p></td>
+<td class="parameter_description"><p>HB_OT_TAG_GSUB or HB_OT_TAG_GPOS</p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+<tr>
+<td class="parameter_name"><p>start_offset</p></td>
+<td class="parameter_description"><p>offset of the first script tag to retrieve</p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+<tr>
+<td class="parameter_name"><p>script_count</p></td>
+<td class="parameter_description"><p>Input = the maximum number of script tags to return;
+Output = the actual number of script tags returned (may be zero). </p></td>
+<td class="parameter_annotations"><span class="annotation">[<acronym title="Parameter for input and for returning results. Default is transfer full."><span class="acronym">inout</span></acronym>][<acronym title="NULL is OK, both for passing and for returning."><span class="acronym">allow-none</span></acronym>]</span></td>
+</tr>
+<tr>
+<td class="parameter_name"><p>script_tags</p></td>
+<td class="parameter_description"><p>The array of <a class="link" href="harfbuzz-hb-common.html#hb-tag-t" title="hb_tag_t"><span class="type">hb_tag_t</span></a> script tags found for the query. </p></td>
+<td class="parameter_annotations"><span class="annotation">[<acronym title="Parameter for returning results. Default is transfer full."><span class="acronym">out</span></acronym>][<acronym title="Parameter points to an array of items."><span class="acronym">array</span></acronym> length=script_count]</span></td>
+</tr>
+</tbody>
+</table></div>
+</div>
 </div>
 <hr>
 <div class="refsect2">
 <a name="hb-ot-layout-table-get-lookup-count"></a><h3>hb_ot_layout_table_get_lookup_count ()</h3>
 <pre class="programlisting">unsigned <span class="returnvalue">int</span>
-hb_ot_layout_table_get_lookup_count (<em class="parameter"><code><a class="link" href="harfbuzz-hb-face.html#hb-face-t" title="hb_face_t"><span class="type">hb_face_t</span></a> *face</code></em>,
+hb_ot_layout_table_get_lookup_count (<em class="parameter"><code><a class="link" href="harfbuzz-hb-face.html#hb-face-t"><span class="type">hb_face_t</span></a> *face</code></em>,
                                      <em class="parameter"><code><a class="link" href="harfbuzz-hb-common.html#hb-tag-t" title="hb_tag_t"><span class="type">hb_tag_t</span></a> table_tag</code></em>);</pre>
+<p>Fetches the total number of lookups enumerated in the specified
+face's GSUB table or GPOS table.</p>
+<div class="refsect3">
+<a name="hb-ot-layout-table-get-lookup-count.parameters"></a><h4>Parameters</h4>
+<div class="informaltable"><table class="informaltable" width="100%" border="0">
+<colgroup>
+<col width="150px" class="parameters_name">
+<col class="parameters_description">
+<col width="200px" class="parameters_annotations">
+</colgroup>
+<tbody>
+<tr>
+<td class="parameter_name"><p>face</p></td>
+<td class="parameter_description"><p><a class="link" href="harfbuzz-hb-face.html#hb-face-t"><span class="type">hb_face_t</span></a> to work upon</p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+<tr>
+<td class="parameter_name"><p>table_tag</p></td>
+<td class="parameter_description"><p>HB_OT_TAG_GSUB or HB_OT_TAG_GPOS</p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+</tbody>
+</table></div>
+</div>
 <p class="since">Since: <a class="link" href="api-index-0-9-22.html#api-index-0.9.22">0.9.22</a></p>
 </div>
 <hr>
 <div class="refsect2">
 <a name="hb-ot-layout-table-select-script"></a><h3>hb_ot_layout_table_select_script ()</h3>
 <pre class="programlisting"><a class="link" href="harfbuzz-hb-common.html#hb-bool-t" title="hb_bool_t"><span class="returnvalue">hb_bool_t</span></a>
-hb_ot_layout_table_select_script (<em class="parameter"><code><a class="link" href="harfbuzz-hb-face.html#hb-face-t" title="hb_face_t"><span class="type">hb_face_t</span></a> *face</code></em>,
+hb_ot_layout_table_select_script (<em class="parameter"><code><a class="link" href="harfbuzz-hb-face.html#hb-face-t"><span class="type">hb_face_t</span></a> *face</code></em>,
                                   <em class="parameter"><code><a class="link" href="harfbuzz-hb-common.html#hb-tag-t" title="hb_tag_t"><span class="type">hb_tag_t</span></a> table_tag</code></em>,
                                   <em class="parameter"><code>unsigned <span class="type">int</span> script_count</code></em>,
                                   <em class="parameter"><code>const <a class="link" href="harfbuzz-hb-common.html#hb-tag-t" title="hb_tag_t"><span class="type">hb_tag_t</span></a> *script_tags</code></em>,
                                   <em class="parameter"><code>unsigned <span class="type">int</span> *script_index</code></em>,
                                   <em class="parameter"><code><a class="link" href="harfbuzz-hb-common.html#hb-tag-t" title="hb_tag_t"><span class="type">hb_tag_t</span></a> *chosen_script</code></em>);</pre>
+<div class="refsect3">
+<a name="hb-ot-layout-table-select-script.parameters"></a><h4>Parameters</h4>
+<div class="informaltable"><table class="informaltable" width="100%" border="0">
+<colgroup>
+<col width="150px" class="parameters_name">
+<col class="parameters_description">
+<col width="200px" class="parameters_annotations">
+</colgroup>
+<tbody>
+<tr>
+<td class="parameter_name"><p>face</p></td>
+<td class="parameter_description"><p><a class="link" href="harfbuzz-hb-face.html#hb-face-t"><span class="type">hb_face_t</span></a> to work upon</p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+<tr>
+<td class="parameter_name"><p>table_tag</p></td>
+<td class="parameter_description"><p>HB_OT_TAG_GSUB or HB_OT_TAG_GPOS</p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+<tr>
+<td class="parameter_name"><p>script_count</p></td>
+<td class="parameter_description"><p>Number of script tags in the array</p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+<tr>
+<td class="parameter_name"><p>script_tags</p></td>
+<td class="parameter_description"><p>Array of <a class="link" href="harfbuzz-hb-common.html#hb-tag-t" title="hb_tag_t"><span class="type">hb_tag_t</span></a> script tags</p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+<tr>
+<td class="parameter_name"><p>script_index</p></td>
+<td class="parameter_description"><p>The index of the requested script. </p></td>
+<td class="parameter_annotations"><span class="annotation">[<acronym title="Parameter for returning results. Default is transfer full."><span class="acronym">out</span></acronym>]</span></td>
+</tr>
+<tr>
+<td class="parameter_name"><p>chosen_script</p></td>
+<td class="parameter_description"><p><a class="link" href="harfbuzz-hb-common.html#hb-tag-t" title="hb_tag_t"><span class="type">hb_tag_t</span></a> of the requested script. </p></td>
+<td class="parameter_annotations"><span class="annotation">[<acronym title="Parameter for returning results. Default is transfer full."><span class="acronym">out</span></acronym>]</span></td>
+</tr>
+</tbody>
+</table></div>
+</div>
 <p class="since">Since: <a class="link" href="api-index-2-0-0.html#api-index-2.0.0">2.0.0</a></p>
 </div>
 <hr>
 <div class="refsect2">
 <a name="hb-ot-shape-plan-collect-lookups"></a><h3>hb_ot_shape_plan_collect_lookups ()</h3>
 <pre class="programlisting"><span class="returnvalue">void</span>
-hb_ot_shape_plan_collect_lookups (<em class="parameter"><code><a class="link" href="harfbuzz-hb-shape-plan.html#hb-shape-plan-t" title="hb_shape_plan_t"><span class="type">hb_shape_plan_t</span></a> *shape_plan</code></em>,
+hb_ot_shape_plan_collect_lookups (<em class="parameter"><code><a class="link" href="harfbuzz-hb-shape-plan.html#hb-shape-plan-t"><span class="type">hb_shape_plan_t</span></a> *shape_plan</code></em>,
                                   <em class="parameter"><code><a class="link" href="harfbuzz-hb-common.html#hb-tag-t" title="hb_tag_t"><span class="type">hb_tag_t</span></a> table_tag</code></em>,
-                                  <em class="parameter"><code><a class="link" href="harfbuzz-hb-set.html#hb-set-t" title="hb_set_t"><span class="type">hb_set_t</span></a> *lookup_indexes</code></em>);</pre>
+                                  <em class="parameter"><code><a class="link" href="harfbuzz-hb-set.html#hb-set-t"><span class="type">hb_set_t</span></a> *lookup_indexes</code></em>);</pre>
 <p class="since">Since: <a class="link" href="api-index-0-9-7.html#api-index-0.9.7">0.9.7</a></p>
 </div>
 <hr>
@@ -978,11 +2129,54 @@ hb_ot_shape_plan_collect_lookups (<em class="parameter"><code><a class="link" hr
 <a name="hb-ot-layout-language-get-required-feature-index"></a><h3>hb_ot_layout_language_get_required_feature_index ()</h3>
 <pre class="programlisting"><a class="link" href="harfbuzz-hb-common.html#hb-bool-t" title="hb_bool_t"><span class="returnvalue">hb_bool_t</span></a>
 hb_ot_layout_language_get_required_feature_index
-                               (<em class="parameter"><code><a class="link" href="harfbuzz-hb-face.html#hb-face-t" title="hb_face_t"><span class="type">hb_face_t</span></a> *face</code></em>,
+                               (<em class="parameter"><code><a class="link" href="harfbuzz-hb-face.html#hb-face-t"><span class="type">hb_face_t</span></a> *face</code></em>,
                                 <em class="parameter"><code><a class="link" href="harfbuzz-hb-common.html#hb-tag-t" title="hb_tag_t"><span class="type">hb_tag_t</span></a> table_tag</code></em>,
                                 <em class="parameter"><code>unsigned <span class="type">int</span> script_index</code></em>,
                                 <em class="parameter"><code>unsigned <span class="type">int</span> language_index</code></em>,
                                 <em class="parameter"><code>unsigned <span class="type">int</span> *feature_index</code></em>);</pre>
+<p>Fetches the index of a requested feature in the given face's GSUB or GPOS table,
+underneath the specified script and language.</p>
+<div class="refsect3">
+<a name="hb-ot-layout-language-get-required-feature-index.parameters"></a><h4>Parameters</h4>
+<div class="informaltable"><table class="informaltable" width="100%" border="0">
+<colgroup>
+<col width="150px" class="parameters_name">
+<col class="parameters_description">
+<col width="200px" class="parameters_annotations">
+</colgroup>
+<tbody>
+<tr>
+<td class="parameter_name"><p>face</p></td>
+<td class="parameter_description"><p><a class="link" href="harfbuzz-hb-face.html#hb-face-t"><span class="type">hb_face_t</span></a> to work upon</p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+<tr>
+<td class="parameter_name"><p>table_tag</p></td>
+<td class="parameter_description"><p>HB_OT_TAG_GSUB or HB_OT_TAG_GPOS</p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+<tr>
+<td class="parameter_name"><p>script_index</p></td>
+<td class="parameter_description"><p>The index of the requested script tag</p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+<tr>
+<td class="parameter_name"><p>language_index</p></td>
+<td class="parameter_description"><p>The index of the requested language tag</p></td>
+<td class="parameter_annotations"> </td>
+</tr>
+<tr>
+<td class="parameter_name"><p>feature_index</p></td>
+<td class="parameter_description"><p>The index of the requested feature. </p></td>
+<td class="parameter_annotations"><span class="annotation">[<acronym title="Parameter for returning results. Default is transfer full."><span class="acronym">out</span></acronym>]</span></td>
+</tr>
+</tbody>
+</table></div>
+</div>
+<div class="refsect3">
+<a name="hb-ot-layout-language-get-required-feature-index.returns"></a><h4>Returns</h4>
+<p> true if the feature is found, false otherwise</p>
+</div>
 </div>
 </div>
 <div class="refsect1">
@@ -1068,7 +2262,90 @@ hb_ot_layout_language_get_required_feature_index
 </div>
 <hr>
 <div class="refsect2">
+<a name="hb-ot-layout-baseline-tag-t"></a><h3>enum hb_ot_layout_baseline_tag_t</h3>
+<p>Baseline tags from https://docs.microsoft.com/en-us/typography/opentype/spec/baselinetags</p>
+<div class="refsect3">
+<a name="hb-ot-layout-baseline-tag-t.members"></a><h4>Members</h4>
+<div class="informaltable"><table class="informaltable" width="100%" border="0">
+<colgroup>
+<col width="300px" class="enum_members_name">
+<col class="enum_members_description">
+<col width="200px" class="enum_members_annotations">
+</colgroup>
+<tbody>
+<tr>
+<td class="enum_member_name"><p><a name="HB-OT-LAYOUT-BASELINE-TAG-ROMAN:CAPS"></a>HB_OT_LAYOUT_BASELINE_TAG_ROMAN</p></td>
+<td class="enum_member_description">
+<p>The baseline used by alphabetic scripts such as Latin, Cyrillic and Greek.
+In vertical writing mode, the alphabetic baseline for characters rotated 90 degrees clockwise.
+(This would not apply to alphabetic characters that remain upright in vertical writing mode, since these
+characters are not rotated.)</p>
+</td>
+<td class="enum_member_annotations"> </td>
+</tr>
+<tr>
+<td class="enum_member_name"><p><a name="HB-OT-LAYOUT-BASELINE-TAG-HANGING:CAPS"></a>HB_OT_LAYOUT_BASELINE_TAG_HANGING</p></td>
+<td class="enum_member_description">
+<p>The hanging baseline. In horizontal direction, this is the horizontal
+line from which syllables seem, to hang in Tibetan and other similar scripts. In vertical writing mode,
+for Tibetan (or some other similar script) characters rotated 90 degrees clockwise.</p>
+</td>
+<td class="enum_member_annotations"> </td>
+</tr>
+<tr>
+<td class="enum_member_name"><p><a name="HB-OT-LAYOUT-BASELINE-TAG-IDEO-FACE-BOTTOM-OR-LEFT:CAPS"></a>HB_OT_LAYOUT_BASELINE_TAG_IDEO_FACE_BOTTOM_OR_LEFT</p></td>
+<td class="enum_member_description">
+<p>Ideographic character face bottom or left edge,
+if the direction is horizontal or vertical, respectively.</p>
+</td>
+<td class="enum_member_annotations"> </td>
+</tr>
+<tr>
+<td class="enum_member_name"><p><a name="HB-OT-LAYOUT-BASELINE-TAG-IDEO-FACE-TOP-OR-RIGHT:CAPS"></a>HB_OT_LAYOUT_BASELINE_TAG_IDEO_FACE_TOP_OR_RIGHT</p></td>
+<td class="enum_member_description">
+<p>Ideographic character face top or right edge,
+if the direction is horizontal or vertical, respectively.</p>
+</td>
+<td class="enum_member_annotations"> </td>
+</tr>
+<tr>
+<td class="enum_member_name"><p><a name="HB-OT-LAYOUT-BASELINE-TAG-IDEO-EMBOX-BOTTOM-OR-LEFT:CAPS"></a>HB_OT_LAYOUT_BASELINE_TAG_IDEO_EMBOX_BOTTOM_OR_LEFT</p></td>
+<td class="enum_member_description">
+<p>Ideographic em-box bottom or left edge,
+if the direction is horizontal or vertical, respectively.</p>
+</td>
+<td class="enum_member_annotations"> </td>
+</tr>
+<tr>
+<td class="enum_member_name"><p><a name="HB-OT-LAYOUT-BASELINE-TAG-IDEO-EMBOX-TOP-OR-RIGHT:CAPS"></a>HB_OT_LAYOUT_BASELINE_TAG_IDEO_EMBOX_TOP_OR_RIGHT</p></td>
+<td class="enum_member_description">
+<p>Ideographic em-box top or right edge baseline,
+if the direction is horizontal or vertical, respectively.</p>
+</td>
+<td class="enum_member_annotations"> </td>
+</tr>
+<tr>
+<td class="enum_member_name"><p><a name="HB-OT-LAYOUT-BASELINE-TAG-MATH:CAPS"></a>HB_OT_LAYOUT_BASELINE_TAG_MATH</p></td>
+<td class="enum_member_description">
+<p>The baseline about which mathematical characters are centered.
+In vertical writing mode when mathematical characters rotated 90 degrees clockwise, are centered.</p>
+</td>
+<td class="enum_member_annotations"> </td>
+</tr>
+<tr>
+<td class="enum_member_name"><p><a name="HB-OT-LAYOUT-BASELINE-TAG-MAX-VALUE:CAPS"></a>_HB_OT_LAYOUT_BASELINE_TAG_MAX_VALUE</p></td>
+<td> </td>
+<td> </td>
+</tr>
+</tbody>
+</table></div>
+</div>
+<p class="since">Since: <a class="link" href="api-index-2-6-0.html#api-index-2.6.0">2.6.0</a></p>
+</div>
+<hr>
+<div class="refsect2">
 <a name="hb-ot-layout-glyph-class-t"></a><h3>enum hb_ot_layout_glyph_class_t</h3>
+<p>The GDEF classes defined for glyphs.</p>
 <div class="refsect3">
 <a name="hb-ot-layout-glyph-class-t.members"></a><h4>Members</h4>
 <div class="informaltable"><table class="informaltable" width="100%" border="0">
@@ -1080,28 +2357,38 @@ hb_ot_layout_language_get_required_feature_index
 <tbody>
 <tr>
 <td class="enum_member_name"><p><a name="HB-OT-LAYOUT-GLYPH-CLASS-UNCLASSIFIED:CAPS"></a>HB_OT_LAYOUT_GLYPH_CLASS_UNCLASSIFIED</p></td>
-<td> </td>
-<td> </td>
+<td class="enum_member_description">
+<p>Glyphs not matching the other classifications</p>
+</td>
+<td class="enum_member_annotations"> </td>
 </tr>
 <tr>
 <td class="enum_member_name"><p><a name="HB-OT-LAYOUT-GLYPH-CLASS-BASE-GLYPH:CAPS"></a>HB_OT_LAYOUT_GLYPH_CLASS_BASE_GLYPH</p></td>
-<td> </td>
-<td> </td>
+<td class="enum_member_description">
+<p>Spacing, single characters, capable of accepting marks</p>
+</td>
+<td class="enum_member_annotations"> </td>
 </tr>
 <tr>
 <td class="enum_member_name"><p><a name="HB-OT-LAYOUT-GLYPH-CLASS-LIGATURE:CAPS"></a>HB_OT_LAYOUT_GLYPH_CLASS_LIGATURE</p></td>
-<td> </td>
-<td> </td>
+<td class="enum_member_description">
+<p>Glyphs that represent ligation of multiple characters</p>
+</td>
+<td class="enum_member_annotations"> </td>
 </tr>
 <tr>
 <td class="enum_member_name"><p><a name="HB-OT-LAYOUT-GLYPH-CLASS-MARK:CAPS"></a>HB_OT_LAYOUT_GLYPH_CLASS_MARK</p></td>
-<td> </td>
-<td> </td>
+<td class="enum_member_description">
+<p>Non-spacing, combining glyphs that represent marks</p>
+</td>
+<td class="enum_member_annotations"> </td>
 </tr>
 <tr>
 <td class="enum_member_name"><p><a name="HB-OT-LAYOUT-GLYPH-CLASS-COMPONENT:CAPS"></a>HB_OT_LAYOUT_GLYPH_CLASS_COMPONENT</p></td>
-<td> </td>
-<td> </td>
+<td class="enum_member_description">
+<p>Spacing glyphs that represent part of a single character</p>
+</td>
+<td class="enum_member_annotations"> </td>
 </tr>
 </tbody>
 </table></div>
index 679acde..45476dd 100644 (file)
@@ -5,7 +5,7 @@
 <title>hb-ot-math: HarfBuzz Manual</title>
 <meta name="generator" content="DocBook XSL Stylesheets Vsnapshot">
 <link rel="home" href="index.html" title="HarfBuzz Manual">
-<link rel="up" href="ch10.html" title="OpenType API">
+<link rel="up" href="ch12.html" title="OpenType API">
 <link rel="prev" href="harfbuzz-hb-ot-layout.html" title="hb-ot-layout">
 <link rel="next" href="harfbuzz-hb-ot-name.html" title="hb-ot-name">
 <meta name="generator" content="GTK-Doc V1.29 (XML mode)">
 <table class="navigation" id="top" width="100%" summary="Navigation header" cellpadding="2" cellspacing="5"><tr valign="middle">
 <td width="100%" align="left" class="shortcuts">
 <a href="#" class="shortcut">Top</a><span id="nav_description">  <span class="dim">|</span> 
-                  <a href="#harfbuzz-hb-ot-math.description" class="shortcut">Description</a></span>
+                  <a href="#harfbuzz-hb-ot-math.description" class="shortcut">Description</a></span><span id="nav_hierarchy">  <span class="dim">|</span> 
+                  <a href="#harfbuzz-hb-ot-math.object-hierarchy" class="shortcut">Object Hierarchy</a></span>
 </td>
 <td><a accesskey="h" href="index.html"><img src="home.png" width="16" height="16" border="0" alt="Home"></a></td>
-<td><a accesskey="u" href="ch10.html"><img src="up.png" width="16" height="16" border="0" alt="Up"></a></td>
+<td><a accesskey="u" href="ch12.html"><img src="up.png" width="16" height="16" border="0" alt="Up"></a></td>
 <td><a accesskey="p" href="harfbuzz-hb-ot-layout.html"><img src="left.png" width="16" height="16" border="0" alt="Prev"></a></td>
 <td><a accesskey="n" href="harfbuzz-hb-ot-name.html"><img src="right.png" width="16" height="16" border="0" alt="Next"></a></td>
 </tr></table>
 </tbody>
 </table></div>
 </div>
-<div class="refsect1">
+<a name="hb-ot-math-glyph-variant-t"></a><a name="hb-ot-math-glyph-part-t"></a><div class="refsect1">
 <a name="harfbuzz-hb-ot-math.other"></a><h2>Types and Values</h2>
 <div class="informaltable"><table class="informaltable" width="100%" border="0">
 <colgroup>
 </tr>
 <tr>
 <td class="datatype_keyword"> </td>
-<td class="function_name"><a class="link" href="harfbuzz-hb-ot-math.html#hb-ot-math-glyph-variant-t" title="hb_ot_math_glyph_variant_t">hb_ot_math_glyph_variant_t</a></td>
+<td class="function_name"><a class="link" href="harfbuzz-hb-ot-math.html#hb-ot-math-glyph-variant-t-struct" title="hb_ot_math_glyph_variant_t">hb_ot_math_glyph_variant_t</a></td>
 </tr>
 <tr>
 <td class="datatype_keyword">enum</td>
 </tr>
 <tr>
 <td class="datatype_keyword"> </td>
-<td class="function_name"><a class="link" href="harfbuzz-hb-ot-math.html#hb-ot-math-glyph-part-t" title="hb_ot_math_glyph_part_t">hb_ot_math_glyph_part_t</a></td>
+<td class="function_name"><a class="link" href="harfbuzz-hb-ot-math.html#hb-ot-math-glyph-part-t-struct" title="hb_ot_math_glyph_part_t">hb_ot_math_glyph_part_t</a></td>
 </tr>
 </tbody>
 </table></div>
 </div>
 <div class="refsect1">
+<a name="harfbuzz-hb-ot-math.object-hierarchy"></a><h2>Object Hierarchy</h2>
+<pre class="screen">    <a href="/usr/share/gtk-doc/html/gobject/gobject-Boxed-Types.html">GBoxed</a>
+    <span class="lineart">├──</span> hb_ot_math_glyph_part_t
+    <span class="lineart">╰──</span> hb_ot_math_glyph_variant_t
+    <a href="/usr/share/gtk-doc/html/gobject/gobject-Enumeration-and-Flag-Types.html">GEnum</a>
+    <span class="lineart">├──</span> hb_ot_math_constant_t
+    <span class="lineart">╰──</span> hb_ot_math_kern_t
+    <a href="/usr/share/gtk-doc/html/gobject/gobject-Enumeration-and-Flag-Types.html">GFlags</a>
+    <span class="lineart">╰──</span> hb_ot_math_glyph_part_flags_t
+</pre>
+</div>
+<div class="refsect1">
 <a name="harfbuzz-hb-ot-math.includes"></a><h2>Includes</h2>
 <pre class="synopsis">#include &lt;hb-ot.h&gt;
 </pre>
 <div class="refsect1">
 <a name="harfbuzz-hb-ot-math.description"></a><h2>Description</h2>
 <p>Functions for fetching mathematics layout data from OpenType fonts.</p>
+<p>HarfBuzz itself does not implement a math layout solution. The
+functions and types provided can be used by client programs to access
+the font data necessary for typesetting OpenType Math layout.</p>
 </div>
 <div class="refsect1">
 <a name="harfbuzz-hb-ot-math.functions_details"></a><h2>Functions</h2>
 <div class="refsect2">
 <a name="hb-ot-math-has-data"></a><h3>hb_ot_math_has_data ()</h3>
 <pre class="programlisting"><a class="link" href="harfbuzz-hb-common.html#hb-bool-t" title="hb_bool_t"><span class="returnvalue">hb_bool_t</span></a>
-hb_ot_math_has_data (<em class="parameter"><code><a class="link" href="harfbuzz-hb-face.html#hb-face-t" title="hb_face_t"><span class="type">hb_face_t</span></a> *face</code></em>);</pre>
-<p>This function allows to verify the presence of an OpenType MATH table on the
-face.</p>
+hb_ot_math_has_data (<em class="parameter"><code><a class="link" href="harfbuzz-hb-face.html#hb-face-t"><span class="type">hb_face_t</span></a> *face</code></em>);</pre>
+<p>Tests whether a face has a <code class="literal">MATH</code> table.</p>
 <div class="refsect3">
 <a name="hb-ot-math-has-data.parameters"></a><h4>Parameters</h4>
 <div class="informaltable"><table class="informaltable" width="100%" border="0">
@@ -178,14 +193,14 @@ face.</p>
 </colgroup>
 <tbody><tr>
 <td class="parameter_name"><p>face</p></td>
-<td class="parameter_description"><p><a class="link" href="harfbuzz-hb-face.html#hb-face-t" title="hb_face_t"><span class="type">hb_face_t</span></a> to test</p></td>
+<td class="parameter_description"><p><a class="link" href="harfbuzz-hb-face.html#hb-face-t"><span class="type">hb_face_t</span></a> to test</p></td>
 <td class="parameter_annotations"> </td>
 </tr></tbody>
 </table></div>
 </div>
 <div class="refsect3">
 <a name="hb-ot-math-has-data.returns"></a><h4>Returns</h4>
-<p> true if face has a MATH table, false otherwise</p>
+<p> true if the table is found, false otherwise</p>
 </div>
 <p class="since">Since: <a class="link" href="api-index-1-3-3.html#api-index-1.3.3">1.3.3</a></p>
 </div>
@@ -193,13 +208,14 @@ face.</p>
 <div class="refsect2">
 <a name="hb-ot-math-get-constant"></a><h3>hb_ot_math_get_constant ()</h3>
 <pre class="programlisting"><a class="link" href="harfbuzz-hb-common.html#hb-position-t" title="hb_position_t"><span class="returnvalue">hb_position_t</span></a>
-hb_ot_math_get_constant (<em class="parameter"><code><a class="link" href="harfbuzz-hb-font.html#hb-font-t" title="hb_font_t"><span class="type">hb_font_t</span></a> *font</code></em>,
+hb_ot_math_get_constant (<em class="parameter"><code><a class="link" href="harfbuzz-hb-font.html#hb-font-t"><span class="type">hb_font_t</span></a> *font</code></em>,
                          <em class="parameter"><code><a class="link" href="harfbuzz-hb-ot-math.html#hb-ot-math-constant-t" title="enum hb_ot_math_constant_t"><span class="type">hb_ot_math_constant_t</span></a> constant</code></em>);</pre>
-<p>This function returns the requested math constants as a <a class="link" href="harfbuzz-hb-common.html#hb-position-t" title="hb_position_t"><span class="type">hb_position_t</span></a>.
-If the request constant is HB_OT_MATH_CONSTANT_SCRIPT_PERCENT_SCALE_DOWN,
-HB_OT_MATH_CONSTANT_SCRIPT_SCRIPT_PERCENT_SCALE_DOWN or
-HB_OT_MATH_CONSTANT_SCRIPT_PERCENT_SCALE_DOWN then the return value is
-actually an integer between 0 and 100 representing that percentage.</p>
+<p>Fetches the specified math constant. For most constants, the value returned
+is an <a class="link" href="harfbuzz-hb-common.html#hb-position-t" title="hb_position_t"><span class="type">hb_position_t</span></a>.</p>
+<p>However, if the requested constant is <a class="link" href="harfbuzz-hb-ot-math.html#HB-OT-MATH-CONSTANT-SCRIPT-PERCENT-SCALE-DOWN:CAPS"><span class="type">HB_OT_MATH_CONSTANT_SCRIPT_PERCENT_SCALE_DOWN</span></a>,
+<a class="link" href="harfbuzz-hb-ot-math.html#HB-OT-MATH-CONSTANT-SCRIPT-SCRIPT-PERCENT-SCALE-DOWN:CAPS"><span class="type">HB_OT_MATH_CONSTANT_SCRIPT_SCRIPT_PERCENT_SCALE_DOWN</span></a> or
+<a class="link" href="harfbuzz-hb-ot-math.html#HB-OT-MATH-CONSTANT-SCRIPT-PERCENT-SCALE-DOWN:CAPS"><span class="type">HB_OT_MATH_CONSTANT_SCRIPT_PERCENT_SCALE_DOWN</span></a>, then the return value is
+an integer between 0 and 100 representing that percentage.</p>
 <div class="refsect3">
 <a name="hb-ot-math-get-constant.parameters"></a><h4>Parameters</h4>
 <div class="informaltable"><table class="informaltable" width="100%" border="0">
@@ -211,7 +227,7 @@ actually an integer between 0 and 100 representing that percentage.</p>
 <tbody>
 <tr>
 <td class="parameter_name"><p>font</p></td>
-<td class="parameter_description"><p><a class="link" href="harfbuzz-hb-font.html#hb-font-t" title="hb_font_t"><span class="type">hb_font_t</span></a> from which to retrieve the value</p></td>
+<td class="parameter_description"><p><a class="link" href="harfbuzz-hb-font.html#hb-font-t"><span class="type">hb_font_t</span></a> to work upon</p></td>
 <td class="parameter_annotations"> </td>
 </tr>
 <tr>
@@ -224,7 +240,7 @@ actually an integer between 0 and 100 representing that percentage.</p>
 </div>
 <div class="refsect3">
 <a name="hb-ot-math-get-constant.returns"></a><h4>Returns</h4>
-<p> the requested constant or 0</p>
+<p> the requested constant or zero</p>
 </div>
 <p class="since">Since: <a class="link" href="api-index-1-3-3.html#api-index-1.3.3">1.3.3</a></p>
 </div>
@@ -233,8 +249,10 @@ actually an integer between 0 and 100 representing that percentage.</p>
 <a name="hb-ot-math-get-glyph-italics-correction"></a><h3>hb_ot_math_get_glyph_italics_correction ()</h3>
 <pre class="programlisting"><a class="link" href="harfbuzz-hb-common.html#hb-position-t" title="hb_position_t"><span class="returnvalue">hb_position_t</span></a>
 hb_ot_math_get_glyph_italics_correction
-                               (<em class="parameter"><code><a class="link" href="harfbuzz-hb-font.html#hb-font-t" title="hb_font_t"><span class="type">hb_font_t</span></a> *font</code></em>,
+                               (<em class="parameter"><code><a class="link" href="harfbuzz-hb-font.html#hb-font-t"><span class="type">hb_font_t</span></a> *font</code></em>,
                                 <em class="parameter"><code><a class="link" href="harfbuzz-hb-common.html#hb-codepoint-t" title="hb_codepoint_t"><span class="type">hb_codepoint_t</span></a> glyph</code></em>);</pre>
+<p>Fetches an italics-correction value (if one exists) for the specified
+glyph index.</p>
 <div class="refsect3">
 <a name="hb-ot-math-get-glyph-italics-correction.parameters"></a><h4>Parameters</h4>
 <div class="informaltable"><table class="informaltable" width="100%" border="0">
@@ -246,12 +264,12 @@ hb_ot_math_get_glyph_italics_correction
 <tbody>
 <tr>
 <td class="parameter_name"><p>font</p></td>
-<td class="parameter_description"><p><a class="link" href="harfbuzz-hb-font.html#hb-font-t" title="hb_font_t"><span class="type">hb_font_t</span></a> from which to retrieve the value</p></td>
+<td class="parameter_description"><p><a class="link" href="harfbuzz-hb-font.html#hb-font-t"><span class="type">hb_font_t</span></a> to work upon</p></td>
 <td class="parameter_annotations"> </td>
 </tr>
 <tr>
 <td class="parameter_name"><p>glyph</p></td>
-<td class="parameter_description"><p>glyph index from which to retrieve the value</p></td>
+<td class="parameter_description"><p>The glyph index from which to retrieve the value</p></td>
 <td class="parameter_annotations"> </td>
 </tr>
 </tbody>
@@ -259,7 +277,7 @@ hb_ot_math_get_glyph_italics_correction
 </div>
 <div class="refsect3">
 <a name="hb-ot-math-get-glyph-italics-correction.returns"></a><h4>Returns</h4>
-<p> the italics correction of the glyph or 0</p>
+<p> the italics correction of the glyph or zero</p>
 </div>
 <p class="since">Since: <a class="link" href="api-index-1-3-3.html#api-index-1.3.3">1.3.3</a></p>
 </div>
@@ -268,8 +286,16 @@ hb_ot_math_get_glyph_italics_correction
 <a name="hb-ot-math-get-glyph-top-accent-attachment"></a><h3>hb_ot_math_get_glyph_top_accent_attachment ()</h3>
 <pre class="programlisting"><a class="link" href="harfbuzz-hb-common.html#hb-position-t" title="hb_position_t"><span class="returnvalue">hb_position_t</span></a>
 hb_ot_math_get_glyph_top_accent_attachment
-                               (<em class="parameter"><code><a class="link" href="harfbuzz-hb-font.html#hb-font-t" title="hb_font_t"><span class="type">hb_font_t</span></a> *font</code></em>,
+                               (<em class="parameter"><code><a class="link" href="harfbuzz-hb-font.html#hb-font-t"><span class="type">hb_font_t</span></a> *font</code></em>,
                                 <em class="parameter"><code><a class="link" href="harfbuzz-hb-common.html#hb-codepoint-t" title="hb_codepoint_t"><span class="type">hb_codepoint_t</span></a> glyph</code></em>);</pre>
+<p>Fetches a top-accent-attachment value (if one exists) for the specified
+glyph index.</p>
+<p>For any glyph that does not have a top-accent-attachment value - that is,
+a glyph not covered by the <code class="literal">MathTopAccentAttachment</code> table (or, when
+<em class="parameter"><code>font</code></em>
+ has no <code class="literal">MathTopAccentAttachment</code> table or no <code class="literal">MATH</code> table, any
+glyph) - the function synthesizes a value, returning the position at
+one-half the glyph's advance width.</p>
 <div class="refsect3">
 <a name="hb-ot-math-get-glyph-top-accent-attachment.parameters"></a><h4>Parameters</h4>
 <div class="informaltable"><table class="informaltable" width="100%" border="0">
@@ -281,12 +307,12 @@ hb_ot_math_get_glyph_top_accent_attachment
 <tbody>
 <tr>
 <td class="parameter_name"><p>font</p></td>
-<td class="parameter_description"><p><a class="link" href="harfbuzz-hb-font.html#hb-font-t" title="hb_font_t"><span class="type">hb_font_t</span></a> from which to retrieve the value</p></td>
+<td class="parameter_description"><p><a class="link" href="harfbuzz-hb-font.html#hb-font-t"><span class="type">hb_font_t</span></a> to work upon</p></td>
 <td class="parameter_annotations"> </td>
 </tr>
 <tr>
 <td class="parameter_name"><p>glyph</p></td>
-<td class="parameter_description"><p>glyph index from which to retrieve the value</p></td>
+<td class="parameter_description"><p>The glyph index from which to retrieve the value</p></td>
 <td class="parameter_annotations"> </td>
 </tr>
 </tbody>
@@ -294,7 +320,9 @@ hb_ot_math_get_glyph_top_accent_attachment
 </div>
 <div class="refsect3">
 <a name="hb-ot-math-get-glyph-top-accent-attachment.returns"></a><h4>Returns</h4>
-<p> the top accent attachment of the glyph or 0</p>
+<p> the top accent attachment of the glyph or 0.5 * the advance
+width of <em class="parameter"><code>glyph</code></em>
+</p>
 </div>
 <p class="since">Since: <a class="link" href="api-index-1-3-3.html#api-index-1.3.3">1.3.3</a></p>
 </div>
@@ -302,15 +330,18 @@ hb_ot_math_get_glyph_top_accent_attachment
 <div class="refsect2">
 <a name="hb-ot-math-get-glyph-kerning"></a><h3>hb_ot_math_get_glyph_kerning ()</h3>
 <pre class="programlisting"><a class="link" href="harfbuzz-hb-common.html#hb-position-t" title="hb_position_t"><span class="returnvalue">hb_position_t</span></a>
-hb_ot_math_get_glyph_kerning (<em class="parameter"><code><a class="link" href="harfbuzz-hb-font.html#hb-font-t" title="hb_font_t"><span class="type">hb_font_t</span></a> *font</code></em>,
+hb_ot_math_get_glyph_kerning (<em class="parameter"><code><a class="link" href="harfbuzz-hb-font.html#hb-font-t"><span class="type">hb_font_t</span></a> *font</code></em>,
                               <em class="parameter"><code><a class="link" href="harfbuzz-hb-common.html#hb-codepoint-t" title="hb_codepoint_t"><span class="type">hb_codepoint_t</span></a> glyph</code></em>,
                               <em class="parameter"><code><a class="link" href="harfbuzz-hb-ot-math.html#hb-ot-math-kern-t" title="enum hb_ot_math_kern_t"><span class="type">hb_ot_math_kern_t</span></a> kern</code></em>,
                               <em class="parameter"><code><a class="link" href="harfbuzz-hb-common.html#hb-position-t" title="hb_position_t"><span class="type">hb_position_t</span></a> correction_height</code></em>);</pre>
-<p>This function tries to retrieve the MathKern table for the specified font,
-glyph and <a class="link" href="harfbuzz-hb-ot-math.html#hb-ot-math-kern-t" title="enum hb_ot_math_kern_t"><span class="type">hb_ot_math_kern_t</span></a>. Then it browses the list of heights from the
-MathKern table to find one value that is greater or equal to specified
-correction_height. If one is found the corresponding value from the list of
-kerns is returned and otherwise the last kern value is returned.</p>
+<p>Fetches the math kerning (cut-ins) value for the specified font, glyph index, and
+<em class="parameter"><code>kern</code></em>
+. </p>
+<p>If the MathKern table is found, the function examines it to find a height
+value that is greater or equal to <em class="parameter"><code>correction_height</code></em>
+. If such a height
+value is found, corresponding kerning value from the table is returned. If
+no such height value is found, the last kerning value is returned.</p>
 <div class="refsect3">
 <a name="hb-ot-math-get-glyph-kerning.parameters"></a><h4>Parameters</h4>
 <div class="informaltable"><table class="informaltable" width="100%" border="0">
@@ -322,17 +353,17 @@ kerns is returned and otherwise the last kern value is returned.</p>
 <tbody>
 <tr>
 <td class="parameter_name"><p>font</p></td>
-<td class="parameter_description"><p><a class="link" href="harfbuzz-hb-font.html#hb-font-t" title="hb_font_t"><span class="type">hb_font_t</span></a> from which to retrieve the value</p></td>
+<td class="parameter_description"><p><a class="link" href="harfbuzz-hb-font.html#hb-font-t"><span class="type">hb_font_t</span></a> to work upon</p></td>
 <td class="parameter_annotations"> </td>
 </tr>
 <tr>
 <td class="parameter_name"><p>glyph</p></td>
-<td class="parameter_description"><p>glyph index from which to retrieve the value</p></td>
+<td class="parameter_description"><p>The glyph index from which to retrieve the value</p></td>
 <td class="parameter_annotations"> </td>
 </tr>
 <tr>
 <td class="parameter_name"><p>kern</p></td>
-<td class="parameter_description"><p>the <a class="link" href="harfbuzz-hb-ot-math.html#hb-ot-math-kern-t" title="enum hb_ot_math_kern_t"><span class="type">hb_ot_math_kern_t</span></a> from which to retrieve the value</p></td>
+<td class="parameter_description"><p>The <a class="link" href="harfbuzz-hb-ot-math.html#hb-ot-math-kern-t" title="enum hb_ot_math_kern_t"><span class="type">hb_ot_math_kern_t</span></a> from which to retrieve the value</p></td>
 <td class="parameter_annotations"> </td>
 </tr>
 <tr>
@@ -345,7 +376,7 @@ kerns is returned and otherwise the last kern value is returned.</p>
 </div>
 <div class="refsect3">
 <a name="hb-ot-math-get-glyph-kerning.returns"></a><h4>Returns</h4>
-<p> requested kerning or 0</p>
+<p> requested kerning value or zero</p>
 </div>
 <p class="since">Since: <a class="link" href="api-index-1-3-3.html#api-index-1.3.3">1.3.3</a></p>
 </div>
@@ -353,8 +384,9 @@ kerns is returned and otherwise the last kern value is returned.</p>
 <div class="refsect2">
 <a name="hb-ot-math-is-glyph-extended-shape"></a><h3>hb_ot_math_is_glyph_extended_shape ()</h3>
 <pre class="programlisting"><a class="link" href="harfbuzz-hb-common.html#hb-bool-t" title="hb_bool_t"><span class="returnvalue">hb_bool_t</span></a>
-hb_ot_math_is_glyph_extended_shape (<em class="parameter"><code><a class="link" href="harfbuzz-hb-face.html#hb-face-t" title="hb_face_t"><span class="type">hb_face_t</span></a> *face</code></em>,
+hb_ot_math_is_glyph_extended_shape (<em class="parameter"><code><a class="link" href="harfbuzz-hb-face.html#hb-face-t"><span class="type">hb_face_t</span></a> *face</code></em>,
                                     <em class="parameter"><code><a class="link" href="harfbuzz-hb-common.html#hb-codepoint-t" title="hb_codepoint_t"><span class="type">hb_codepoint_t</span></a> glyph</code></em>);</pre>
+<p>Tests whether the given glyph index is an extended shape in the face.</p>
 <div class="refsect3">
 <a name="hb-ot-math-is-glyph-extended-shape.parameters"></a><h4>Parameters</h4>
 <div class="informaltable"><table class="informaltable" width="100%" border="0">
@@ -366,12 +398,12 @@ hb_ot_math_is_glyph_extended_shape (<em class="parameter"><code><a class="link"
 <tbody>
 <tr>
 <td class="parameter_name"><p>face</p></td>
-<td class="parameter_description"><p>a <a class="link" href="harfbuzz-hb-face.html#hb-face-t" title="hb_face_t"><span class="type">hb_face_t</span></a> to test</p></td>
+<td class="parameter_description"><p><a class="link" href="harfbuzz-hb-face.html#hb-face-t"><span class="type">hb_face_t</span></a> to work upon</p></td>
 <td class="parameter_annotations"> </td>
 </tr>
 <tr>
 <td class="parameter_name"><p>glyph</p></td>
-<td class="parameter_description"><p>a glyph index to test</p></td>
+<td class="parameter_description"><p>The glyph index to test</p></td>
 <td class="parameter_annotations"> </td>
 </tr>
 </tbody>
@@ -387,16 +419,19 @@ hb_ot_math_is_glyph_extended_shape (<em class="parameter"><code><a class="link"
 <div class="refsect2">
 <a name="hb-ot-math-get-glyph-variants"></a><h3>hb_ot_math_get_glyph_variants ()</h3>
 <pre class="programlisting">unsigned <span class="returnvalue">int</span>
-hb_ot_math_get_glyph_variants (<em class="parameter"><code><a class="link" href="harfbuzz-hb-font.html#hb-font-t" title="hb_font_t"><span class="type">hb_font_t</span></a> *font</code></em>,
+hb_ot_math_get_glyph_variants (<em class="parameter"><code><a class="link" href="harfbuzz-hb-font.html#hb-font-t"><span class="type">hb_font_t</span></a> *font</code></em>,
                                <em class="parameter"><code><a class="link" href="harfbuzz-hb-common.html#hb-codepoint-t" title="hb_codepoint_t"><span class="type">hb_codepoint_t</span></a> glyph</code></em>,
                                <em class="parameter"><code><a class="link" href="harfbuzz-hb-common.html#hb-direction-t" title="enum hb_direction_t"><span class="type">hb_direction_t</span></a> direction</code></em>,
                                <em class="parameter"><code>unsigned <span class="type">int</span> start_offset</code></em>,
                                <em class="parameter"><code>unsigned <span class="type">int</span> *variants_count</code></em>,
-                               <em class="parameter"><code><a class="link" href="harfbuzz-hb-ot-math.html#hb-ot-math-glyph-variant-t" title="hb_ot_math_glyph_variant_t"><span class="type">hb_ot_math_glyph_variant_t</span></a> *variants</code></em>);</pre>
-<p>This function tries to retrieve the MathGlyphConstruction for the specified
-font, glyph and direction. Note that only the value of
-<a class="link" href="harfbuzz-hb-common.html#HB-DIRECTION-IS-HORIZONTAL:CAPS" title="HB_DIRECTION_IS_HORIZONTAL()"><span class="type">HB_DIRECTION_IS_HORIZONTAL</span></a> is considered. It provides the corresponding list
-of size variants as an array of hb_ot_math_glyph_variant_t structs.</p>
+                               <em class="parameter"><code><a class="link" href="harfbuzz-hb-ot-math.html#hb-ot-math-glyph-variant-t"><span class="type">hb_ot_math_glyph_variant_t</span></a> *variants</code></em>);</pre>
+<p>Fetches the MathGlyphConstruction for the specified font, glyph index, and
+direction. The corresponding list of size variants is returned as a list of
+<a class="link" href="harfbuzz-hb-ot-math.html#hb-ot-math-glyph-variant-t"><span class="type">hb_ot_math_glyph_variant_t</span></a> structs.</p>
+<div class="note">The <em class="parameter"><code>direction</code></em> parameter is only used to select between horizontal
+or vertical directions for the construction. Even though all <a class="link" href="harfbuzz-hb-common.html#hb-direction-t" title="enum hb_direction_t"><span class="type">hb_direction_t</span></a>
+values are accepted, only the result of <a class="link" href="harfbuzz-hb-common.html#HB-DIRECTION-IS-HORIZONTAL:CAPS" title="HB_DIRECTION_IS_HORIZONTAL()"><span class="type">HB_DIRECTION_IS_HORIZONTAL</span></a> is
+considered.</div>
 <div class="refsect3">
 <a name="hb-ot-math-get-glyph-variants.parameters"></a><h4>Parameters</h4>
 <div class="informaltable"><table class="informaltable" width="100%" border="0">
@@ -408,17 +443,17 @@ of size variants as an array of hb_ot_math_glyph_variant_t structs.</p>
 <tbody>
 <tr>
 <td class="parameter_name"><p>font</p></td>
-<td class="parameter_description"><p><a class="link" href="harfbuzz-hb-font.html#hb-font-t" title="hb_font_t"><span class="type">hb_font_t</span></a> from which to retrieve the values</p></td>
+<td class="parameter_description"><p><a class="link" href="harfbuzz-hb-font.html#hb-font-t"><span class="type">hb_font_t</span></a> to work upon</p></td>
 <td class="parameter_annotations"> </td>
 </tr>
 <tr>
 <td class="parameter_name"><p>glyph</p></td>
-<td class="parameter_description"><p>index of the glyph to stretch</p></td>
+<td class="parameter_description"><p>The index of the glyph to stretch</p></td>
 <td class="parameter_annotations"> </td>
 </tr>
 <tr>
 <td class="parameter_name"><p>direction</p></td>
-<td class="parameter_description"><p>direction of the stretching</p></td>
+<td class="parameter_description"><p>The direction of the stretching (horizontal or vertical)</p></td>
 <td class="parameter_annotations"> </td>
 </tr>
 <tr>
@@ -428,22 +463,21 @@ of size variants as an array of hb_ot_math_glyph_variant_t structs.</p>
 </tr>
 <tr>
 <td class="parameter_name"><p>variants_count</p></td>
-<td class="parameter_description"><p>maximum number of variants to retrieve after start_offset
-(IN) and actual number of variants retrieved (OUT)</p></td>
-<td class="parameter_annotations"> </td>
+<td class="parameter_description"><p>Input = the maximum number of variants to return;
+Output = the actual number of variants returned. </p></td>
+<td class="parameter_annotations"><span class="annotation">[<acronym title="Parameter for input and for returning results. Default is transfer full."><span class="acronym">inout</span></acronym>]</span></td>
 </tr>
 <tr>
 <td class="parameter_name"><p>variants</p></td>
-<td class="parameter_description"><p>array of size at least <em class="parameter"><code>variants_count</code></em>
-to store the result</p></td>
-<td class="parameter_annotations"> </td>
+<td class="parameter_description"><p>array of variants returned. </p></td>
+<td class="parameter_annotations"><span class="annotation">[<acronym title="Parameter for returning results. Default is transfer full."><span class="acronym">out</span></acronym>][<acronym title="Parameter points to an array of items."><span class="acronym">array</span></acronym> length=variants_count]</span></td>
 </tr>
 </tbody>
 </table></div>
 </div>
 <div class="refsect3">
 <a name="hb-ot-math-get-glyph-variants.returns"></a><h4>Returns</h4>
-<p> the total number of size variants available or 0</p>
+<p> the total number of size variants available or zero</p>
 </div>
 <p class="since">Since: <a class="link" href="api-index-1-3-3.html#api-index-1.3.3">1.3.3</a></p>
 </div>
@@ -451,12 +485,15 @@ to store the result</p></td>
 <div class="refsect2">
 <a name="hb-ot-math-get-min-connector-overlap"></a><h3>hb_ot_math_get_min_connector_overlap ()</h3>
 <pre class="programlisting"><a class="link" href="harfbuzz-hb-common.html#hb-position-t" title="hb_position_t"><span class="returnvalue">hb_position_t</span></a>
-hb_ot_math_get_min_connector_overlap (<em class="parameter"><code><a class="link" href="harfbuzz-hb-font.html#hb-font-t" title="hb_font_t"><span class="type">hb_font_t</span></a> *font</code></em>,
+hb_ot_math_get_min_connector_overlap (<em class="parameter"><code><a class="link" href="harfbuzz-hb-font.html#hb-font-t"><span class="type">hb_font_t</span></a> *font</code></em>,
                                       <em class="parameter"><code><a class="link" href="harfbuzz-hb-common.html#hb-direction-t" title="enum hb_direction_t"><span class="type">hb_direction_t</span></a> direction</code></em>);</pre>
-<p>This function tries to retrieve the MathVariants table for the specified
-font and returns the minimum overlap of connecting glyphs to draw a glyph
-assembly in the specified direction. Note that only the value of
-<a class="link" href="harfbuzz-hb-common.html#HB-DIRECTION-IS-HORIZONTAL:CAPS" title="HB_DIRECTION_IS_HORIZONTAL()"><span class="type">HB_DIRECTION_IS_HORIZONTAL</span></a> is considered.</p>
+<p>Fetches the MathVariants table for the specified font and returns the
+minimum overlap of connecting glyphs that are required to draw a glyph
+assembly in the specified direction.</p>
+<div class="note">The <em class="parameter"><code>direction</code></em> parameter is only used to select between horizontal
+or vertical directions for the construction. Even though all <a class="link" href="harfbuzz-hb-common.html#hb-direction-t" title="enum hb_direction_t"><span class="type">hb_direction_t</span></a>
+values are accepted, only the result of <a class="link" href="harfbuzz-hb-common.html#HB-DIRECTION-IS-HORIZONTAL:CAPS" title="HB_DIRECTION_IS_HORIZONTAL()"><span class="type">HB_DIRECTION_IS_HORIZONTAL</span></a> is
+considered.</div>
 <div class="refsect3">
 <a name="hb-ot-math-get-min-connector-overlap.parameters"></a><h4>Parameters</h4>
 <div class="informaltable"><table class="informaltable" width="100%" border="0">
@@ -468,12 +505,12 @@ assembly in the specified direction. Note that only the value of
 <tbody>
 <tr>
 <td class="parameter_name"><p>font</p></td>
-<td class="parameter_description"><p><a class="link" href="harfbuzz-hb-font.html#hb-font-t" title="hb_font_t"><span class="type">hb_font_t</span></a> from which to retrieve the value</p></td>
+<td class="parameter_description"><p><a class="link" href="harfbuzz-hb-font.html#hb-font-t"><span class="type">hb_font_t</span></a> to work upon</p></td>
 <td class="parameter_annotations"> </td>
 </tr>
 <tr>
 <td class="parameter_name"><p>direction</p></td>
-<td class="parameter_description"><p>direction of the stretching</p></td>
+<td class="parameter_description"><p>direction of the stretching (horizontal or vertical)</p></td>
 <td class="parameter_annotations"> </td>
 </tr>
 </tbody>
@@ -481,7 +518,7 @@ assembly in the specified direction. Note that only the value of
 </div>
 <div class="refsect3">
 <a name="hb-ot-math-get-min-connector-overlap.returns"></a><h4>Returns</h4>
-<p> requested min connector overlap or 0</p>
+<p> requested minimum connector overlap or zero</p>
 </div>
 <p class="since">Since: <a class="link" href="api-index-1-3-3.html#api-index-1.3.3">1.3.3</a></p>
 </div>
@@ -489,17 +526,21 @@ assembly in the specified direction. Note that only the value of
 <div class="refsect2">
 <a name="hb-ot-math-get-glyph-assembly"></a><h3>hb_ot_math_get_glyph_assembly ()</h3>
 <pre class="programlisting">unsigned <span class="returnvalue">int</span>
-hb_ot_math_get_glyph_assembly (<em class="parameter"><code><a class="link" href="harfbuzz-hb-font.html#hb-font-t" title="hb_font_t"><span class="type">hb_font_t</span></a> *font</code></em>,
+hb_ot_math_get_glyph_assembly (<em class="parameter"><code><a class="link" href="harfbuzz-hb-font.html#hb-font-t"><span class="type">hb_font_t</span></a> *font</code></em>,
                                <em class="parameter"><code><a class="link" href="harfbuzz-hb-common.html#hb-codepoint-t" title="hb_codepoint_t"><span class="type">hb_codepoint_t</span></a> glyph</code></em>,
                                <em class="parameter"><code><a class="link" href="harfbuzz-hb-common.html#hb-direction-t" title="enum hb_direction_t"><span class="type">hb_direction_t</span></a> direction</code></em>,
                                <em class="parameter"><code>unsigned <span class="type">int</span> start_offset</code></em>,
                                <em class="parameter"><code>unsigned <span class="type">int</span> *parts_count</code></em>,
-                               <em class="parameter"><code><a class="link" href="harfbuzz-hb-ot-math.html#hb-ot-math-glyph-part-t" title="hb_ot_math_glyph_part_t"><span class="type">hb_ot_math_glyph_part_t</span></a> *parts</code></em>,
+                               <em class="parameter"><code><a class="link" href="harfbuzz-hb-ot-math.html#hb-ot-math-glyph-part-t"><span class="type">hb_ot_math_glyph_part_t</span></a> *parts</code></em>,
                                <em class="parameter"><code><a class="link" href="harfbuzz-hb-common.html#hb-position-t" title="hb_position_t"><span class="type">hb_position_t</span></a> *italics_correction</code></em>);</pre>
-<p>This function tries to retrieve the GlyphAssembly for the specified font,
-glyph and direction. Note that only the value of <a class="link" href="harfbuzz-hb-common.html#HB-DIRECTION-IS-HORIZONTAL:CAPS" title="HB_DIRECTION_IS_HORIZONTAL()"><span class="type">HB_DIRECTION_IS_HORIZONTAL</span></a>
-is considered. It provides the information necessary to draw the glyph
-assembly as an array of <a class="link" href="harfbuzz-hb-ot-math.html#hb-ot-math-glyph-part-t" title="hb_ot_math_glyph_part_t"><span class="type">hb_ot_math_glyph_part_t</span></a>.</p>
+<p>Fetches the GlyphAssembly for the specified font, glyph index, and direction.
+Returned are a list of <a class="link" href="harfbuzz-hb-ot-math.html#hb-ot-math-glyph-part-t"><span class="type">hb_ot_math_glyph_part_t</span></a> glyph parts that can be
+used to draw the glyph and an italics-correction value (if one is defined
+in the font).</p>
+<div class="note">The <em class="parameter"><code>direction</code></em> parameter is only used to select between horizontal
+or vertical directions for the construction. Even though all <a class="link" href="harfbuzz-hb-common.html#hb-direction-t" title="enum hb_direction_t"><span class="type">hb_direction_t</span></a>
+values are accepted, only the result of <a class="link" href="harfbuzz-hb-common.html#HB-DIRECTION-IS-HORIZONTAL:CAPS" title="HB_DIRECTION_IS_HORIZONTAL()"><span class="type">HB_DIRECTION_IS_HORIZONTAL</span></a> is
+considered.</div>
 <div class="refsect3">
 <a name="hb-ot-math-get-glyph-assembly.parameters"></a><h4>Parameters</h4>
 <div class="informaltable"><table class="informaltable" width="100%" border="0">
@@ -511,17 +552,17 @@ assembly as an array of <a class="link" href="harfbuzz-hb-ot-math.html#hb-ot-mat
 <tbody>
 <tr>
 <td class="parameter_name"><p>font</p></td>
-<td class="parameter_description"><p><a class="link" href="harfbuzz-hb-font.html#hb-font-t" title="hb_font_t"><span class="type">hb_font_t</span></a> from which to retrieve the values</p></td>
+<td class="parameter_description"><p><a class="link" href="harfbuzz-hb-font.html#hb-font-t"><span class="type">hb_font_t</span></a> to work upon</p></td>
 <td class="parameter_annotations"> </td>
 </tr>
 <tr>
 <td class="parameter_name"><p>glyph</p></td>
-<td class="parameter_description"><p>index of the glyph to stretch</p></td>
+<td class="parameter_description"><p>The index of the glyph to stretch</p></td>
 <td class="parameter_annotations"> </td>
 </tr>
 <tr>
 <td class="parameter_name"><p>direction</p></td>
-<td class="parameter_description"><p>direction of the stretching</p></td>
+<td class="parameter_description"><p>direction of the stretching (horizontal or vertical)</p></td>
 <td class="parameter_annotations"> </td>
 </tr>
 <tr>
@@ -531,20 +572,19 @@ assembly as an array of <a class="link" href="harfbuzz-hb-ot-math.html#hb-ot-mat
 </tr>
 <tr>
 <td class="parameter_name"><p>parts_count</p></td>
-<td class="parameter_description"><p>maximum number of glyph parts to retrieve after start_offset
-(IN) and actual number of parts retrieved (OUT)</p></td>
-<td class="parameter_annotations"> </td>
+<td class="parameter_description"><p>Input = maximum number of glyph parts to return;
+Output = actual number of parts returned. </p></td>
+<td class="parameter_annotations"><span class="annotation">[<acronym title="Parameter for input and for returning results. Default is transfer full."><span class="acronym">inout</span></acronym>]</span></td>
 </tr>
 <tr>
 <td class="parameter_name"><p>parts</p></td>
-<td class="parameter_description"><p>array of size at least <em class="parameter"><code>parts_count</code></em>
-to store the result</p></td>
-<td class="parameter_annotations"> </td>
+<td class="parameter_description"><p>the glyph parts returned. </p></td>
+<td class="parameter_annotations"><span class="annotation">[<acronym title="Parameter for returning results. Default is transfer full."><span class="acronym">out</span></acronym>][<acronym title="Parameter points to an array of items."><span class="acronym">array</span></acronym> length=parts_count]</span></td>
 </tr>
 <tr>
 <td class="parameter_name"><p>italics_correction</p></td>
-<td class="parameter_description"><p>italic correction of the glyph assembly</p></td>
-<td class="parameter_annotations"> </td>
+<td class="parameter_description"><p>italics correction of the glyph assembly. </p></td>
+<td class="parameter_annotations"><span class="annotation">[<acronym title="Parameter for returning results. Default is transfer full."><span class="acronym">out</span></acronym>]</span></td>
 </tr>
 </tbody>
 </table></div>
@@ -572,6 +612,8 @@ to store the result</p></td>
 <hr>
 <div class="refsect2">
 <a name="hb-ot-math-constant-t"></a><h3>enum hb_ot_math_constant_t</h3>
+<p>The 'MATH' table constants specified at
+https://docs.microsoft.com/en-us/typography/opentype/spec/math</p>
 <div class="refsect3">
 <a name="hb-ot-math-constant-t.members"></a><h4>Members</h4>
 <div class="informaltable"><table class="informaltable" width="100%" border="0">
@@ -869,6 +911,8 @@ to store the result</p></td>
 <hr>
 <div class="refsect2">
 <a name="hb-ot-math-kern-t"></a><h3>enum hb_ot_math_kern_t</h3>
+<p>The math kerning-table types defined for the four corners
+of a glyph.</p>
 <div class="refsect3">
 <a name="hb-ot-math-kern-t.members"></a><h4>Members</h4>
 <div class="informaltable"><table class="informaltable" width="100%" border="0">
@@ -905,17 +949,41 @@ to store the result</p></td>
 </div>
 <hr>
 <div class="refsect2">
-<a name="hb-ot-math-glyph-variant-t"></a><h3>hb_ot_math_glyph_variant_t</h3>
+<a name="hb-ot-math-glyph-variant-t-struct"></a><h3>hb_ot_math_glyph_variant_t</h3>
 <pre class="programlisting">typedef struct {
   hb_codepoint_t glyph;
   hb_position_t advance;
 } hb_ot_math_glyph_variant_t;
 </pre>
+<p>Data type to hold math-variant information for a glyph.</p>
+<div class="refsect3">
+<a name="hb-ot-math-glyph-variant-t.members"></a><h4>Members</h4>
+<div class="informaltable"><table class="informaltable" width="100%" border="0">
+<colgroup>
+<col width="300px" class="struct_members_name">
+<col class="struct_members_description">
+<col width="200px" class="struct_members_annotations">
+</colgroup>
+<tbody>
+<tr>
+<td class="struct_member_name"><p><a class="link" href="harfbuzz-hb-common.html#hb-codepoint-t" title="hb_codepoint_t"><span class="type">hb_codepoint_t</span></a> <em class="structfield"><code><a name="hb-ot-math-glyph-variant-t-struct.glyph"></a>glyph</code></em>;</p></td>
+<td class="struct_member_description"><p>The glyph index of the variant</p></td>
+<td class="struct_member_annotations"> </td>
+</tr>
+<tr>
+<td class="struct_member_name"><p><a class="link" href="harfbuzz-hb-common.html#hb-position-t" title="hb_position_t"><span class="type">hb_position_t</span></a> <em class="structfield"><code><a name="hb-ot-math-glyph-variant-t-struct.advance"></a>advance</code></em>;</p></td>
+<td class="struct_member_description"><p>The advance width of the variant</p></td>
+<td class="struct_member_annotations"> </td>
+</tr>
+</tbody>
+</table></div>
+</div>
 <p class="since">Since: <a class="link" href="api-index-1-3-3.html#api-index-1.3.3">1.3.3</a></p>
 </div>
 <hr>
 <div class="refsect2">
 <a name="hb-ot-math-glyph-part-flags-t"></a><h3>enum hb_ot_math_glyph_part_flags_t</h3>
+<p>Flags for math glyph parts.</p>
 <div class="refsect3">
 <a name="hb-ot-math-glyph-part-flags-t.members"></a><h4>Members</h4>
 <div class="informaltable"><table class="informaltable" width="100%" border="0">
@@ -925,7 +993,7 @@ to store the result</p></td>
 <col width="200px" class="enum_members_annotations">
 </colgroup>
 <tbody><tr>
-<td class="enum_member_name"><p><a name="HB-MATH-GLYPH-PART-FLAG-EXTENDER:CAPS"></a>HB_MATH_GLYPH_PART_FLAG_EXTENDER</p></td>
+<td class="enum_member_name"><p><a name="HB-OT-MATH-GLYPH-PART-FLAG-EXTENDER:CAPS"></a>HB_OT_MATH_GLYPH_PART_FLAG_EXTENDER</p></td>
 <td> </td>
 <td> </td>
 </tr></tbody>
@@ -935,7 +1003,7 @@ to store the result</p></td>
 </div>
 <hr>
 <div class="refsect2">
-<a name="hb-ot-math-glyph-part-t"></a><h3>hb_ot_math_glyph_part_t</h3>
+<a name="hb-ot-math-glyph-part-t-struct"></a><h3>hb_ot_math_glyph_part_t</h3>
 <pre class="programlisting">typedef struct {
   hb_codepoint_t glyph;
   hb_position_t start_connector_length;
@@ -944,6 +1012,46 @@ to store the result</p></td>
   hb_ot_math_glyph_part_flags_t flags;
 } hb_ot_math_glyph_part_t;
 </pre>
+<p>Data type to hold information for a "part" component of a math-variant glyph.
+Large variants for stretchable math glyphs (such as parentheses) can be constructed
+on the fly from parts.</p>
+<div class="refsect3">
+<a name="hb-ot-math-glyph-part-t.members"></a><h4>Members</h4>
+<div class="informaltable"><table class="informaltable" width="100%" border="0">
+<colgroup>
+<col width="300px" class="struct_members_name">
+<col class="struct_members_description">
+<col width="200px" class="struct_members_annotations">
+</colgroup>
+<tbody>
+<tr>
+<td class="struct_member_name"><p><a class="link" href="harfbuzz-hb-common.html#hb-codepoint-t" title="hb_codepoint_t"><span class="type">hb_codepoint_t</span></a> <em class="structfield"><code><a name="hb-ot-math-glyph-part-t-struct.glyph"></a>glyph</code></em>;</p></td>
+<td class="struct_member_description"><p>The glyph index of the variant part</p></td>
+<td class="struct_member_annotations"> </td>
+</tr>
+<tr>
+<td class="struct_member_name"><p><a class="link" href="harfbuzz-hb-common.html#hb-position-t" title="hb_position_t"><span class="type">hb_position_t</span></a> <em class="structfield"><code><a name="hb-ot-math-glyph-part-t-struct.start-connector-length"></a>start_connector_length</code></em>;</p></td>
+<td class="struct_member_description"><p>The length of the connector on the starting side of the variant part</p></td>
+<td class="struct_member_annotations"> </td>
+</tr>
+<tr>
+<td class="struct_member_name"><p><a class="link" href="harfbuzz-hb-common.html#hb-position-t" title="hb_position_t"><span class="type">hb_position_t</span></a> <em class="structfield"><code><a name="hb-ot-math-glyph-part-t-struct.end-connector-length"></a>end_connector_length</code></em>;</p></td>
+<td class="struct_member_description"><p>The length of the connector on the ending side of the variant part</p></td>
+<td class="struct_member_annotations"> </td>
+</tr>
+<tr>
+<td class="struct_member_name"><p><a class="link" href="harfbuzz-hb-common.html#hb-position-t" title="hb_position_t"><span class="type">hb_position_t</span></a> <em class="structfield"><code><a name="hb-ot-math-glyph-part-t-struct.full-advance"></a>full_advance</code></em>;</p></td>
+<td class="struct_member_description"><p>The total advance of the part</p></td>
+<td class="struct_member_annotations"> </td>
+</tr>
+<tr>
+<td class="struct_member_name"><p><a class="link" href="harfbuzz-hb-ot-math.html#hb-ot-math-glyph-part-flags-t" title="enum hb_ot_math_glyph_part_flags_t"><span class="type">hb_ot_math_glyph_part_flags_t</span></a> <em class="structfield"><code><a name="hb-ot-math-glyph-part-t-struct.flags"></a>flags</code></em>;</p></td>
+<td class="struct_member_description"><p><a class="link" href="harfbuzz-hb-ot-math.html#hb-ot-math-glyph-part-flags-t" title="enum hb_ot_math_glyph_part_flags_t"><span class="type">hb_ot_math_glyph_part_flags_t</span></a> flags for the part</p></td>
+<td class="struct_member_annotations"> </td>
+</tr>
+</tbody>
+</table></div>
+</div>
 <p class="since">Since: <a class="link" href="api-index-1-3-3.html#api-index-1.3.3">1.3.3</a></p>
 </div>
 </div>
index 1087a86..3fbf48d 100644 (file)
@@ -5,7 +5,7 @@
 <title>hb-ot-name: HarfBuzz Manual</title>
 <meta name="generator" content="DocBook XSL Stylesheets Vsnapshot">
 <link rel="home" href="index.html" title="HarfBuzz Manual">
-<link rel="up" href="ch10.html" title="OpenType API">
+<link rel="up" href="ch12.html" title="OpenType API">
 <link rel="prev" href="harfbuzz-hb-ot-math.html" title="hb-ot-math">
 <link rel="next" href="harfbuzz-hb-ot-shape.html" title="hb-ot-shape">
 <meta name="generator" content="GTK-Doc V1.29 (XML mode)">
@@ -18,7 +18,7 @@
                   <a href="#harfbuzz-hb-ot-name.description" class="shortcut">Description</a></span>
 </td>
 <td><a accesskey="h" href="index.html"><img src="home.png" width="16" height="16" border="0" alt="Home"></a></td>
-<td><a accesskey="u" href="ch10.html"><img src="up.png" width="16" height="16" border="0" alt="Up"></a></td>
+<td><a accesskey="u" href="ch12.html"><img src="up.png" width="16" height="16" border="0" alt="Up"></a></td>
 <td><a accesskey="p" href="harfbuzz-hb-ot-math.html"><img src="left.png" width="16" height="16" border="0" alt="Prev"></a></td>
 <td><a accesskey="n" href="harfbuzz-hb-ot-shape.html"><img src="right.png" width="16" height="16" border="0" alt="Next"></a></td>
 </tr></table>
@@ -97,7 +97,7 @@
 <div class="refsect2">
 <a name="hb-ot-name-list-names"></a><h3>hb_ot_name_list_names ()</h3>
 <pre class="programlisting">const <span class="returnvalue">hb_ot_name_entry_t</span> *
-hb_ot_name_list_names (<em class="parameter"><code><a class="link" href="harfbuzz-hb-face.html#hb-face-t" title="hb_face_t"><span class="type">hb_face_t</span></a> *face</code></em>,
+hb_ot_name_list_names (<em class="parameter"><code><a class="link" href="harfbuzz-hb-face.html#hb-face-t"><span class="type">hb_face_t</span></a> *face</code></em>,
                        <em class="parameter"><code>unsigned <span class="type">int</span> *num_entries</code></em>);</pre>
 <p>Enumerates all available name IDs and language combinations. Returned
 array is owned by the <em class="parameter"><code>face</code></em>
@@ -137,7 +137,7 @@ used as long as <em class="parameter"><code>face</code></em>
 <div class="refsect2">
 <a name="hb-ot-name-get-utf16"></a><h3>hb_ot_name_get_utf16 ()</h3>
 <pre class="programlisting">unsigned <span class="returnvalue">int</span>
-hb_ot_name_get_utf16 (<em class="parameter"><code><a class="link" href="harfbuzz-hb-face.html#hb-face-t" title="hb_face_t"><span class="type">hb_face_t</span></a> *face</code></em>,
+hb_ot_name_get_utf16 (<em class="parameter"><code><a class="link" href="harfbuzz-hb-face.html#hb-face-t"><span class="type">hb_face_t</span></a> *face</code></em>,
                       <em class="parameter"><code><a class="link" href="harfbuzz-hb-ot-name.html#hb-ot-name-id-t" title="hb_ot_name_id_t"><span class="type">hb_ot_name_id_t</span></a> name_id</code></em>,
                       <em class="parameter"><code><a class="link" href="harfbuzz-hb-common.html#hb-language-t" title="hb_language_t"><span class="type">hb_language_t</span></a> language</code></em>,
                       <em class="parameter"><code>unsigned <span class="type">int</span> *text_size</code></em>,
@@ -195,7 +195,7 @@ text written to buffer. </p></td>
 <div class="refsect2">
 <a name="hb-ot-name-get-utf32"></a><h3>hb_ot_name_get_utf32 ()</h3>
 <pre class="programlisting">unsigned <span class="returnvalue">int</span>
-hb_ot_name_get_utf32 (<em class="parameter"><code><a class="link" href="harfbuzz-hb-face.html#hb-face-t" title="hb_face_t"><span class="type">hb_face_t</span></a> *face</code></em>,
+hb_ot_name_get_utf32 (<em class="parameter"><code><a class="link" href="harfbuzz-hb-face.html#hb-face-t"><span class="type">hb_face_t</span></a> *face</code></em>,
                       <em class="parameter"><code><a class="link" href="harfbuzz-hb-ot-name.html#hb-ot-name-id-t" title="hb_ot_name_id_t"><span class="type">hb_ot_name_id_t</span></a> name_id</code></em>,
                       <em class="parameter"><code><a class="link" href="harfbuzz-hb-common.html#hb-language-t" title="hb_language_t"><span class="type">hb_language_t</span></a> language</code></em>,
                       <em class="parameter"><code>unsigned <span class="type">int</span> *text_size</code></em>,
@@ -253,7 +253,7 @@ text written to buffer. </p></td>
 <div class="refsect2">
 <a name="hb-ot-name-get-utf8"></a><h3>hb_ot_name_get_utf8 ()</h3>
 <pre class="programlisting">unsigned <span class="returnvalue">int</span>
-hb_ot_name_get_utf8 (<em class="parameter"><code><a class="link" href="harfbuzz-hb-face.html#hb-face-t" title="hb_face_t"><span class="type">hb_face_t</span></a> *face</code></em>,
+hb_ot_name_get_utf8 (<em class="parameter"><code><a class="link" href="harfbuzz-hb-face.html#hb-face-t"><span class="type">hb_face_t</span></a> *face</code></em>,
                      <em class="parameter"><code><a class="link" href="harfbuzz-hb-ot-name.html#hb-ot-name-id-t" title="hb_ot_name_id_t"><span class="type">hb_ot_name_id_t</span></a> name_id</code></em>,
                      <em class="parameter"><code><a class="link" href="harfbuzz-hb-common.html#hb-language-t" title="hb_language_t"><span class="type">hb_language_t</span></a> language</code></em>,
                      <em class="parameter"><code>unsigned <span class="type">int</span> *text_size</code></em>,
index 5814dfe..56d06c9 100644 (file)
@@ -5,7 +5,7 @@
 <title>hb-ot-shape: HarfBuzz Manual</title>
 <meta name="generator" content="DocBook XSL Stylesheets Vsnapshot">
 <link rel="home" href="index.html" title="HarfBuzz Manual">
-<link rel="up" href="ch10.html" title="OpenType API">
+<link rel="up" href="ch12.html" title="OpenType API">
 <link rel="prev" href="harfbuzz-hb-ot-name.html" title="hb-ot-name">
 <link rel="next" href="harfbuzz-hb-ot-var.html" title="hb-ot-var">
 <meta name="generator" content="GTK-Doc V1.29 (XML mode)">
@@ -18,7 +18,7 @@
                   <a href="#harfbuzz-hb-ot-shape.description" class="shortcut">Description</a></span>
 </td>
 <td><a accesskey="h" href="index.html"><img src="home.png" width="16" height="16" border="0" alt="Home"></a></td>
-<td><a accesskey="u" href="ch10.html"><img src="up.png" width="16" height="16" border="0" alt="Up"></a></td>
+<td><a accesskey="u" href="ch12.html"><img src="up.png" width="16" height="16" border="0" alt="Up"></a></td>
 <td><a accesskey="p" href="harfbuzz-hb-ot-name.html"><img src="left.png" width="16" height="16" border="0" alt="Prev"></a></td>
 <td><a accesskey="n" href="harfbuzz-hb-ot-var.html"><img src="right.png" width="16" height="16" border="0" alt="Next"></a></td>
 </tr></table>
 <div class="refsect2">
 <a name="hb-ot-shape-glyphs-closure"></a><h3>hb_ot_shape_glyphs_closure ()</h3>
 <pre class="programlisting"><span class="returnvalue">void</span>
-hb_ot_shape_glyphs_closure (<em class="parameter"><code><a class="link" href="harfbuzz-hb-font.html#hb-font-t" title="hb_font_t"><span class="type">hb_font_t</span></a> *font</code></em>,
-                            <em class="parameter"><code><a class="link" href="harfbuzz-hb-buffer.html#hb-buffer-t" title="hb_buffer_t"><span class="type">hb_buffer_t</span></a> *buffer</code></em>,
-                            <em class="parameter"><code>const <a class="link" href="harfbuzz-hb-common.html#hb-feature-t" title="hb_feature_t"><span class="type">hb_feature_t</span></a> *features</code></em>,
+hb_ot_shape_glyphs_closure (<em class="parameter"><code><a class="link" href="harfbuzz-hb-font.html#hb-font-t"><span class="type">hb_font_t</span></a> *font</code></em>,
+                            <em class="parameter"><code><a class="link" href="harfbuzz-hb-buffer.html#hb-buffer-t"><span class="type">hb_buffer_t</span></a> *buffer</code></em>,
+                            <em class="parameter"><code>const <a class="link" href="harfbuzz-hb-common.html#hb-feature-t"><span class="type">hb_feature_t</span></a> *features</code></em>,
                             <em class="parameter"><code>unsigned <span class="type">int</span> num_features</code></em>,
-                            <em class="parameter"><code><a class="link" href="harfbuzz-hb-set.html#hb-set-t" title="hb_set_t"><span class="type">hb_set_t</span></a> *glyphs</code></em>);</pre>
+                            <em class="parameter"><code><a class="link" href="harfbuzz-hb-set.html#hb-set-t"><span class="type">hb_set_t</span></a> *glyphs</code></em>);</pre>
 <p class="since">Since: <a class="link" href="api-index-0-9-2.html#api-index-0.9.2">0.9.2</a></p>
 </div>
 </div>
index f65fd8d..11fee9b 100644 (file)
@@ -5,9 +5,9 @@
 <title>hb-ot-var: HarfBuzz Manual</title>
 <meta name="generator" content="DocBook XSL Stylesheets Vsnapshot">
 <link rel="home" href="index.html" title="HarfBuzz Manual">
-<link rel="up" href="ch10.html" title="OpenType API">
+<link rel="up" href="ch12.html" title="OpenType API">
 <link rel="prev" href="harfbuzz-hb-ot-shape.html" title="hb-ot-shape">
-<link rel="next" href="ch11.html" title="Apple Advanced Typography API">
+<link rel="next" href="ch13.html" title="Apple Advanced Typography API">
 <meta name="generator" content="GTK-Doc V1.29 (XML mode)">
 <link rel="stylesheet" href="style.css" type="text/css">
 </head>
 <table class="navigation" id="top" width="100%" summary="Navigation header" cellpadding="2" cellspacing="5"><tr valign="middle">
 <td width="100%" align="left" class="shortcuts">
 <a href="#" class="shortcut">Top</a><span id="nav_description">  <span class="dim">|</span> 
-                  <a href="#harfbuzz-hb-ot-var.description" class="shortcut">Description</a></span>
+                  <a href="#harfbuzz-hb-ot-var.description" class="shortcut">Description</a></span><span id="nav_hierarchy">  <span class="dim">|</span> 
+                  <a href="#harfbuzz-hb-ot-var.object-hierarchy" class="shortcut">Object Hierarchy</a></span>
 </td>
 <td><a accesskey="h" href="index.html"><img src="home.png" width="16" height="16" border="0" alt="Home"></a></td>
-<td><a accesskey="u" href="ch10.html"><img src="up.png" width="16" height="16" border="0" alt="Up"></a></td>
+<td><a accesskey="u" href="ch12.html"><img src="up.png" width="16" height="16" border="0" alt="Up"></a></td>
 <td><a accesskey="p" href="harfbuzz-hb-ot-shape.html"><img src="left.png" width="16" height="16" border="0" alt="Prev"></a></td>
-<td><a accesskey="n" href="ch11.html"><img src="right.png" width="16" height="16" border="0" alt="Next"></a></td>
+<td><a accesskey="n" href="ch13.html"><img src="right.png" width="16" height="16" border="0" alt="Next"></a></td>
 </tr></table>
 <div class="refentry">
 <a name="harfbuzz-hb-ot-var"></a><div class="titlepage"></div>
 </table></div>
 </div>
 <div class="refsect1">
+<a name="harfbuzz-hb-ot-var.object-hierarchy"></a><h2>Object Hierarchy</h2>
+<pre class="screen">    <a href="/usr/share/gtk-doc/html/gobject/gobject-Enumeration-and-Flag-Types.html">GFlags</a>
+    <span class="lineart">╰──</span> hb_ot_var_axis_flags_t
+</pre>
+</div>
+<div class="refsect1">
 <a name="harfbuzz-hb-ot-var.includes"></a><h2>Includes</h2>
 <pre class="synopsis">#include &lt;hb-ot.h&gt;
 </pre>
 <div class="refsect2">
 <a name="hb-ot-var-has-data"></a><h3>hb_ot_var_has_data ()</h3>
 <pre class="programlisting"><a class="link" href="harfbuzz-hb-common.html#hb-bool-t" title="hb_bool_t"><span class="returnvalue">hb_bool_t</span></a>
-hb_ot_var_has_data (<em class="parameter"><code><a class="link" href="harfbuzz-hb-face.html#hb-face-t" title="hb_face_t"><span class="type">hb_face_t</span></a> *face</code></em>);</pre>
+hb_ot_var_has_data (<em class="parameter"><code><a class="link" href="harfbuzz-hb-face.html#hb-face-t"><span class="type">hb_face_t</span></a> *face</code></em>);</pre>
 <p>This function allows to verify the presence of OpenType variation data on the face.</p>
 <div class="refsect3">
 <a name="hb-ot-var-has-data.parameters"></a><h4>Parameters</h4>
@@ -179,7 +186,7 @@ hb_ot_var_has_data (<em class="parameter"><code><a class="link" href="harfbuzz-h
 </colgroup>
 <tbody><tr>
 <td class="parameter_name"><p>face</p></td>
-<td class="parameter_description"><p><a class="link" href="harfbuzz-hb-face.html#hb-face-t" title="hb_face_t"><span class="type">hb_face_t</span></a> to test</p></td>
+<td class="parameter_description"><p><a class="link" href="harfbuzz-hb-face.html#hb-face-t"><span class="type">hb_face_t</span></a> to test</p></td>
 <td class="parameter_annotations"> </td>
 </tr></tbody>
 </table></div>
@@ -194,7 +201,7 @@ hb_ot_var_has_data (<em class="parameter"><code><a class="link" href="harfbuzz-h
 <div class="refsect2">
 <a name="hb-ot-var-find-axis-info"></a><h3>hb_ot_var_find_axis_info ()</h3>
 <pre class="programlisting"><a class="link" href="harfbuzz-hb-common.html#hb-bool-t" title="hb_bool_t"><span class="returnvalue">hb_bool_t</span></a>
-hb_ot_var_find_axis_info (<em class="parameter"><code><a class="link" href="harfbuzz-hb-face.html#hb-face-t" title="hb_face_t"><span class="type">hb_face_t</span></a> *face</code></em>,
+hb_ot_var_find_axis_info (<em class="parameter"><code><a class="link" href="harfbuzz-hb-face.html#hb-face-t"><span class="type">hb_face_t</span></a> *face</code></em>,
                           <em class="parameter"><code><a class="link" href="harfbuzz-hb-common.html#hb-tag-t" title="hb_tag_t"><span class="type">hb_tag_t</span></a> axis_tag</code></em>,
                           <em class="parameter"><code><span class="type">hb_ot_var_axis_info_t</span> *axis_info</code></em>);</pre>
 <p class="since">Since: <a class="link" href="api-index-2-2-0.html#api-index-2.2.0">2.2.0</a></p>
@@ -203,14 +210,14 @@ hb_ot_var_find_axis_info (<em class="parameter"><code><a class="link" href="harf
 <div class="refsect2">
 <a name="hb-ot-var-get-axis-count"></a><h3>hb_ot_var_get_axis_count ()</h3>
 <pre class="programlisting">unsigned <span class="returnvalue">int</span>
-hb_ot_var_get_axis_count (<em class="parameter"><code><a class="link" href="harfbuzz-hb-face.html#hb-face-t" title="hb_face_t"><span class="type">hb_face_t</span></a> *face</code></em>);</pre>
+hb_ot_var_get_axis_count (<em class="parameter"><code><a class="link" href="harfbuzz-hb-face.html#hb-face-t"><span class="type">hb_face_t</span></a> *face</code></em>);</pre>
 <p class="since">Since: <a class="link" href="api-index-1-4-2.html#api-index-1.4.2">1.4.2</a></p>
 </div>
 <hr>
 <div class="refsect2">
 <a name="hb-ot-var-get-axis-infos"></a><h3>hb_ot_var_get_axis_infos ()</h3>
 <pre class="programlisting">unsigned <span class="returnvalue">int</span>
-hb_ot_var_get_axis_infos (<em class="parameter"><code><a class="link" href="harfbuzz-hb-face.html#hb-face-t" title="hb_face_t"><span class="type">hb_face_t</span></a> *face</code></em>,
+hb_ot_var_get_axis_infos (<em class="parameter"><code><a class="link" href="harfbuzz-hb-face.html#hb-face-t"><span class="type">hb_face_t</span></a> *face</code></em>,
                           <em class="parameter"><code>unsigned <span class="type">int</span> start_offset</code></em>,
                           <em class="parameter"><code>unsigned <span class="type">int</span> *axes_count</code></em>,
                           <em class="parameter"><code><span class="type">hb_ot_var_axis_info_t</span> *axes_array</code></em>);</pre>
@@ -220,14 +227,14 @@ hb_ot_var_get_axis_infos (<em class="parameter"><code><a class="link" href="harf
 <div class="refsect2">
 <a name="hb-ot-var-get-named-instance-count"></a><h3>hb_ot_var_get_named_instance_count ()</h3>
 <pre class="programlisting">unsigned <span class="returnvalue">int</span>
-hb_ot_var_get_named_instance_count (<em class="parameter"><code><a class="link" href="harfbuzz-hb-face.html#hb-face-t" title="hb_face_t"><span class="type">hb_face_t</span></a> *face</code></em>);</pre>
+hb_ot_var_get_named_instance_count (<em class="parameter"><code><a class="link" href="harfbuzz-hb-face.html#hb-face-t"><span class="type">hb_face_t</span></a> *face</code></em>);</pre>
 </div>
 <hr>
 <div class="refsect2">
 <a name="hb-ot-var-named-instance-get-subfamily-name-id"></a><h3>hb_ot_var_named_instance_get_subfamily_name_id ()</h3>
 <pre class="programlisting"><a class="link" href="harfbuzz-hb-ot-name.html#hb-ot-name-id-t" title="hb_ot_name_id_t"><span class="returnvalue">hb_ot_name_id_t</span></a>
 hb_ot_var_named_instance_get_subfamily_name_id
-                               (<em class="parameter"><code><a class="link" href="harfbuzz-hb-face.html#hb-face-t" title="hb_face_t"><span class="type">hb_face_t</span></a> *face</code></em>,
+                               (<em class="parameter"><code><a class="link" href="harfbuzz-hb-face.html#hb-face-t"><span class="type">hb_face_t</span></a> *face</code></em>,
                                 <em class="parameter"><code>unsigned <span class="type">int</span> instance_index</code></em>);</pre>
 </div>
 <hr>
@@ -235,7 +242,7 @@ hb_ot_var_named_instance_get_subfamily_name_id
 <a name="hb-ot-var-named-instance-get-postscript-name-id"></a><h3>hb_ot_var_named_instance_get_postscript_name_id ()</h3>
 <pre class="programlisting"><a class="link" href="harfbuzz-hb-ot-name.html#hb-ot-name-id-t" title="hb_ot_name_id_t"><span class="returnvalue">hb_ot_name_id_t</span></a>
 hb_ot_var_named_instance_get_postscript_name_id
-                               (<em class="parameter"><code><a class="link" href="harfbuzz-hb-face.html#hb-face-t" title="hb_face_t"><span class="type">hb_face_t</span></a> *face</code></em>,
+                               (<em class="parameter"><code><a class="link" href="harfbuzz-hb-face.html#hb-face-t"><span class="type">hb_face_t</span></a> *face</code></em>,
                                 <em class="parameter"><code>unsigned <span class="type">int</span> instance_index</code></em>);</pre>
 </div>
 <hr>
@@ -243,7 +250,7 @@ hb_ot_var_named_instance_get_postscript_name_id
 <a name="hb-ot-var-named-instance-get-design-coords"></a><h3>hb_ot_var_named_instance_get_design_coords ()</h3>
 <pre class="programlisting">unsigned <span class="returnvalue">int</span>
 hb_ot_var_named_instance_get_design_coords
-                               (<em class="parameter"><code><a class="link" href="harfbuzz-hb-face.html#hb-face-t" title="hb_face_t"><span class="type">hb_face_t</span></a> *face</code></em>,
+                               (<em class="parameter"><code><a class="link" href="harfbuzz-hb-face.html#hb-face-t"><span class="type">hb_face_t</span></a> *face</code></em>,
                                 <em class="parameter"><code>unsigned <span class="type">int</span> instance_index</code></em>,
                                 <em class="parameter"><code>unsigned <span class="type">int</span> *coords_length</code></em>,
                                 <em class="parameter"><code><span class="type">float</span> *coords</code></em>);</pre>
@@ -252,7 +259,7 @@ hb_ot_var_named_instance_get_design_coords
 <div class="refsect2">
 <a name="hb-ot-var-normalize-variations"></a><h3>hb_ot_var_normalize_variations ()</h3>
 <pre class="programlisting"><span class="returnvalue">void</span>
-hb_ot_var_normalize_variations (<em class="parameter"><code><a class="link" href="harfbuzz-hb-face.html#hb-face-t" title="hb_face_t"><span class="type">hb_face_t</span></a> *face</code></em>,
+hb_ot_var_normalize_variations (<em class="parameter"><code><a class="link" href="harfbuzz-hb-face.html#hb-face-t"><span class="type">hb_face_t</span></a> *face</code></em>,
                                 <em class="parameter"><code>const <a class="link" href="harfbuzz-hb-common.html#hb-variation-t" title="hb_variation_t"><span class="type">hb_variation_t</span></a> *variations</code></em>,
                                 <em class="parameter"><code>unsigned <span class="type">int</span> variations_length</code></em>,
                                 <em class="parameter"><code><span class="type">int</span> *coords</code></em>,
@@ -263,7 +270,7 @@ hb_ot_var_normalize_variations (<em class="parameter"><code><a class="link" href
 <div class="refsect2">
 <a name="hb-ot-var-normalize-coords"></a><h3>hb_ot_var_normalize_coords ()</h3>
 <pre class="programlisting"><span class="returnvalue">void</span>
-hb_ot_var_normalize_coords (<em class="parameter"><code><a class="link" href="harfbuzz-hb-face.html#hb-face-t" title="hb_face_t"><span class="type">hb_face_t</span></a> *face</code></em>,
+hb_ot_var_normalize_coords (<em class="parameter"><code><a class="link" href="harfbuzz-hb-face.html#hb-face-t"><span class="type">hb_face_t</span></a> *face</code></em>,
                             <em class="parameter"><code>unsigned <span class="type">int</span> coords_length</code></em>,
                             <em class="parameter"><code>const <span class="type">float</span> *design_coords</code></em>,
                             <em class="parameter"><code><span class="type">int</span> *normalized_coords</code></em>);</pre>
index 7607ab2..8c2c408 100644 (file)
@@ -5,7 +5,7 @@
 <title>hb-set: HarfBuzz Manual</title>
 <meta name="generator" content="DocBook XSL Stylesheets Vsnapshot">
 <link rel="home" href="index.html" title="HarfBuzz Manual">
-<link rel="up" href="ch09.html" title="Core API">
+<link rel="up" href="ch11.html" title="Core API">
 <link rel="prev" href="harfbuzz-hb-map.html" title="hb-map">
 <link rel="next" href="harfbuzz-hb-shape-plan.html" title="hb-shape-plan">
 <meta name="generator" content="GTK-Doc V1.29 (XML mode)">
 <table class="navigation" id="top" width="100%" summary="Navigation header" cellpadding="2" cellspacing="5"><tr valign="middle">
 <td width="100%" align="left" class="shortcuts">
 <a href="#" class="shortcut">Top</a><span id="nav_description">  <span class="dim">|</span> 
-                  <a href="#harfbuzz-hb-set.description" class="shortcut">Description</a></span>
+                  <a href="#harfbuzz-hb-set.description" class="shortcut">Description</a></span><span id="nav_hierarchy">  <span class="dim">|</span> 
+                  <a href="#harfbuzz-hb-set.object-hierarchy" class="shortcut">Object Hierarchy</a></span>
 </td>
 <td><a accesskey="h" href="index.html"><img src="home.png" width="16" height="16" border="0" alt="Home"></a></td>
-<td><a accesskey="u" href="ch09.html"><img src="up.png" width="16" height="16" border="0" alt="Up"></a></td>
+<td><a accesskey="u" href="ch11.html"><img src="up.png" width="16" height="16" border="0" alt="Up"></a></td>
 <td><a accesskey="p" href="harfbuzz-hb-map.html"><img src="left.png" width="16" height="16" border="0" alt="Prev"></a></td>
 <td><a accesskey="n" href="harfbuzz-hb-shape-plan.html"><img src="right.png" width="16" height="16" border="0" alt="Next"></a></td>
 </tr></table>
@@ -73,7 +74,7 @@
 </tr>
 <tr>
 <td class="function_type">
-<a class="link" href="harfbuzz-hb-set.html#hb-set-t" title="hb_set_t"><span class="returnvalue">hb_set_t</span></a> *
+<a class="link" href="harfbuzz-hb-set.html#hb-set-t"><span class="returnvalue">hb_set_t</span></a> *
 </td>
 <td class="function_name">
 <a class="link" href="harfbuzz-hb-set.html#hb-set-create" title="hb_set_create ()">hb_set_create</a> <span class="c_punctuation">()</span>
 </tr>
 <tr>
 <td class="function_type">
-<a class="link" href="harfbuzz-hb-set.html#hb-set-t" title="hb_set_t"><span class="returnvalue">hb_set_t</span></a> *
+<a class="link" href="harfbuzz-hb-set.html#hb-set-t"><span class="returnvalue">hb_set_t</span></a> *
 </td>
 <td class="function_name">
 <a class="link" href="harfbuzz-hb-set.html#hb-set-get-empty" title="hb_set_get_empty ()">hb_set_get_empty</a> <span class="c_punctuation">()</span>
 </tr>
 <tr>
 <td class="function_type">
-<a class="link" href="harfbuzz-hb-set.html#hb-set-t" title="hb_set_t"><span class="returnvalue">hb_set_t</span></a> *
+<a class="link" href="harfbuzz-hb-set.html#hb-set-t"><span class="returnvalue">hb_set_t</span></a> *
 </td>
 <td class="function_name">
 <a class="link" href="harfbuzz-hb-set.html#hb-set-reference" title="hb_set_reference ()">hb_set_reference</a> <span class="c_punctuation">()</span>
 </tbody>
 </table></div>
 </div>
-<div class="refsect1">
+<a name="hb-set-t"></a><div class="refsect1">
 <a name="harfbuzz-hb-set.other"></a><h2>Types and Values</h2>
 <div class="informaltable"><table class="informaltable" width="100%" border="0">
 <colgroup>
 </tr>
 <tr>
 <td class="typedef_keyword">typedef</td>
-<td class="function_name"><a class="link" href="harfbuzz-hb-set.html#hb-set-t" title="hb_set_t">hb_set_t</a></td>
+<td class="function_name"><a class="link" href="harfbuzz-hb-set.html#hb-set-t">hb_set_t</a></td>
 </tr>
 </tbody>
 </table></div>
 </div>
 <div class="refsect1">
+<a name="harfbuzz-hb-set.object-hierarchy"></a><h2>Object Hierarchy</h2>
+<pre class="screen">    <a href="/usr/share/gtk-doc/html/gobject/gobject-Boxed-Types.html">GBoxed</a>
+    <span class="lineart">╰──</span> hb_set_t
+</pre>
+</div>
+<div class="refsect1">
 <a name="harfbuzz-hb-set.includes"></a><h2>Includes</h2>
 <pre class="synopsis">#include &lt;hb.h&gt;
 </pre>
@@ -300,7 +307,7 @@ or other integer values.</p>
 <div class="refsect2">
 <a name="hb-set-add"></a><h3>hb_set_add ()</h3>
 <pre class="programlisting"><span class="returnvalue">void</span>
-hb_set_add (<em class="parameter"><code><a class="link" href="harfbuzz-hb-set.html#hb-set-t" title="hb_set_t"><span class="type">hb_set_t</span></a> *set</code></em>,
+hb_set_add (<em class="parameter"><code><a class="link" href="harfbuzz-hb-set.html#hb-set-t"><span class="type">hb_set_t</span></a> *set</code></em>,
             <em class="parameter"><code><a class="link" href="harfbuzz-hb-common.html#hb-codepoint-t" title="hb_codepoint_t"><span class="type">hb_codepoint_t</span></a> codepoint</code></em>);</pre>
 <div class="refsect3">
 <a name="hb-set-add.parameters"></a><h4>Parameters</h4>
@@ -323,7 +330,7 @@ hb_set_add (<em class="parameter"><code><a class="link" href="harfbuzz-hb-set.ht
 <div class="refsect2">
 <a name="hb-set-add-range"></a><h3>hb_set_add_range ()</h3>
 <pre class="programlisting"><span class="returnvalue">void</span>
-hb_set_add_range (<em class="parameter"><code><a class="link" href="harfbuzz-hb-set.html#hb-set-t" title="hb_set_t"><span class="type">hb_set_t</span></a> *set</code></em>,
+hb_set_add_range (<em class="parameter"><code><a class="link" href="harfbuzz-hb-set.html#hb-set-t"><span class="type">hb_set_t</span></a> *set</code></em>,
                   <em class="parameter"><code><a class="link" href="harfbuzz-hb-common.html#hb-codepoint-t" title="hb_codepoint_t"><span class="type">hb_codepoint_t</span></a> first</code></em>,
                   <em class="parameter"><code><a class="link" href="harfbuzz-hb-common.html#hb-codepoint-t" title="hb_codepoint_t"><span class="type">hb_codepoint_t</span></a> last</code></em>);</pre>
 <div class="refsect3">
@@ -347,7 +354,7 @@ hb_set_add_range (<em class="parameter"><code><a class="link" href="harfbuzz-hb-
 <div class="refsect2">
 <a name="hb-set-allocation-successful"></a><h3>hb_set_allocation_successful ()</h3>
 <pre class="programlisting"><a class="link" href="harfbuzz-hb-common.html#hb-bool-t" title="hb_bool_t"><span class="returnvalue">hb_bool_t</span></a>
-hb_set_allocation_successful (<em class="parameter"><code>const <a class="link" href="harfbuzz-hb-set.html#hb-set-t" title="hb_set_t"><span class="type">hb_set_t</span></a> *set</code></em>);</pre>
+hb_set_allocation_successful (<em class="parameter"><code>const <a class="link" href="harfbuzz-hb-set.html#hb-set-t"><span class="type">hb_set_t</span></a> *set</code></em>);</pre>
 <div class="refsect3">
 <a name="hb-set-allocation-successful.parameters"></a><h4>Parameters</h4>
 <div class="informaltable"><table class="informaltable" width="100%" border="0">
@@ -369,7 +376,7 @@ hb_set_allocation_successful (<em class="parameter"><code>const <a class="link"
 <div class="refsect2">
 <a name="hb-set-clear"></a><h3>hb_set_clear ()</h3>
 <pre class="programlisting"><span class="returnvalue">void</span>
-hb_set_clear (<em class="parameter"><code><a class="link" href="harfbuzz-hb-set.html#hb-set-t" title="hb_set_t"><span class="type">hb_set_t</span></a> *set</code></em>);</pre>
+hb_set_clear (<em class="parameter"><code><a class="link" href="harfbuzz-hb-set.html#hb-set-t"><span class="type">hb_set_t</span></a> *set</code></em>);</pre>
 <div class="refsect3">
 <a name="hb-set-clear.parameters"></a><h4>Parameters</h4>
 <div class="informaltable"><table class="informaltable" width="100%" border="0">
@@ -390,7 +397,7 @@ hb_set_clear (<em class="parameter"><code><a class="link" href="harfbuzz-hb-set.
 <hr>
 <div class="refsect2">
 <a name="hb-set-create"></a><h3>hb_set_create ()</h3>
-<pre class="programlisting"><a class="link" href="harfbuzz-hb-set.html#hb-set-t" title="hb_set_t"><span class="returnvalue">hb_set_t</span></a> *
+<pre class="programlisting"><a class="link" href="harfbuzz-hb-set.html#hb-set-t"><span class="returnvalue">hb_set_t</span></a> *
 hb_set_create (<em class="parameter"><code><span class="type">void</span></code></em>);</pre>
 <p><span class="annotation">[Xconstructor]</span></p>
 <div class="refsect3">
@@ -404,7 +411,7 @@ hb_set_create (<em class="parameter"><code><span class="type">void</span></code>
 <div class="refsect2">
 <a name="hb-set-del"></a><h3>hb_set_del ()</h3>
 <pre class="programlisting"><span class="returnvalue">void</span>
-hb_set_del (<em class="parameter"><code><a class="link" href="harfbuzz-hb-set.html#hb-set-t" title="hb_set_t"><span class="type">hb_set_t</span></a> *set</code></em>,
+hb_set_del (<em class="parameter"><code><a class="link" href="harfbuzz-hb-set.html#hb-set-t"><span class="type">hb_set_t</span></a> *set</code></em>,
             <em class="parameter"><code><a class="link" href="harfbuzz-hb-common.html#hb-codepoint-t" title="hb_codepoint_t"><span class="type">hb_codepoint_t</span></a> codepoint</code></em>);</pre>
 <div class="refsect3">
 <a name="hb-set-del.parameters"></a><h4>Parameters</h4>
@@ -427,7 +434,7 @@ hb_set_del (<em class="parameter"><code><a class="link" href="harfbuzz-hb-set.ht
 <div class="refsect2">
 <a name="hb-set-del-range"></a><h3>hb_set_del_range ()</h3>
 <pre class="programlisting"><span class="returnvalue">void</span>
-hb_set_del_range (<em class="parameter"><code><a class="link" href="harfbuzz-hb-set.html#hb-set-t" title="hb_set_t"><span class="type">hb_set_t</span></a> *set</code></em>,
+hb_set_del_range (<em class="parameter"><code><a class="link" href="harfbuzz-hb-set.html#hb-set-t"><span class="type">hb_set_t</span></a> *set</code></em>,
                   <em class="parameter"><code><a class="link" href="harfbuzz-hb-common.html#hb-codepoint-t" title="hb_codepoint_t"><span class="type">hb_codepoint_t</span></a> first</code></em>,
                   <em class="parameter"><code><a class="link" href="harfbuzz-hb-common.html#hb-codepoint-t" title="hb_codepoint_t"><span class="type">hb_codepoint_t</span></a> last</code></em>);</pre>
 <div class="refsect3">
@@ -451,7 +458,7 @@ hb_set_del_range (<em class="parameter"><code><a class="link" href="harfbuzz-hb-
 <div class="refsect2">
 <a name="hb-set-destroy"></a><h3>hb_set_destroy ()</h3>
 <pre class="programlisting"><span class="returnvalue">void</span>
-hb_set_destroy (<em class="parameter"><code><a class="link" href="harfbuzz-hb-set.html#hb-set-t" title="hb_set_t"><span class="type">hb_set_t</span></a> *set</code></em>);</pre>
+hb_set_destroy (<em class="parameter"><code><a class="link" href="harfbuzz-hb-set.html#hb-set-t"><span class="type">hb_set_t</span></a> *set</code></em>);</pre>
 <p><span class="annotation">[<acronym title="Exposed in C code, not necessarily available in other languages."><span class="acronym">skip</span></acronym>]</span></p>
 <div class="refsect3">
 <a name="hb-set-destroy.parameters"></a><h4>Parameters</h4>
@@ -473,7 +480,7 @@ hb_set_destroy (<em class="parameter"><code><a class="link" href="harfbuzz-hb-se
 <hr>
 <div class="refsect2">
 <a name="hb-set-get-empty"></a><h3>hb_set_get_empty ()</h3>
-<pre class="programlisting"><a class="link" href="harfbuzz-hb-set.html#hb-set-t" title="hb_set_t"><span class="returnvalue">hb_set_t</span></a> *
+<pre class="programlisting"><a class="link" href="harfbuzz-hb-set.html#hb-set-t"><span class="returnvalue">hb_set_t</span></a> *
 hb_set_get_empty (<em class="parameter"><code><span class="type">void</span></code></em>);</pre>
 <div class="refsect3">
 <a name="hb-set-get-empty.returns"></a><h4>Returns</h4>
@@ -486,7 +493,7 @@ hb_set_get_empty (<em class="parameter"><code><span class="type">void</span></co
 <div class="refsect2">
 <a name="hb-set-get-max"></a><h3>hb_set_get_max ()</h3>
 <pre class="programlisting"><a class="link" href="harfbuzz-hb-common.html#hb-codepoint-t" title="hb_codepoint_t"><span class="returnvalue">hb_codepoint_t</span></a>
-hb_set_get_max (<em class="parameter"><code>const <a class="link" href="harfbuzz-hb-set.html#hb-set-t" title="hb_set_t"><span class="type">hb_set_t</span></a> *set</code></em>);</pre>
+hb_set_get_max (<em class="parameter"><code>const <a class="link" href="harfbuzz-hb-set.html#hb-set-t"><span class="type">hb_set_t</span></a> *set</code></em>);</pre>
 <p>Finds the maximum number in the set.</p>
 <div class="refsect3">
 <a name="hb-set-get-max.parameters"></a><h4>Parameters</h4>
@@ -513,7 +520,7 @@ hb_set_get_max (<em class="parameter"><code>const <a class="link" href="harfbuzz
 <div class="refsect2">
 <a name="hb-set-get-min"></a><h3>hb_set_get_min ()</h3>
 <pre class="programlisting"><a class="link" href="harfbuzz-hb-common.html#hb-codepoint-t" title="hb_codepoint_t"><span class="returnvalue">hb_codepoint_t</span></a>
-hb_set_get_min (<em class="parameter"><code>const <a class="link" href="harfbuzz-hb-set.html#hb-set-t" title="hb_set_t"><span class="type">hb_set_t</span></a> *set</code></em>);</pre>
+hb_set_get_min (<em class="parameter"><code>const <a class="link" href="harfbuzz-hb-set.html#hb-set-t"><span class="type">hb_set_t</span></a> *set</code></em>);</pre>
 <p>Finds the minimum number in the set.</p>
 <div class="refsect3">
 <a name="hb-set-get-min.parameters"></a><h4>Parameters</h4>
@@ -540,7 +547,7 @@ hb_set_get_min (<em class="parameter"><code>const <a class="link" href="harfbuzz
 <div class="refsect2">
 <a name="hb-set-get-population"></a><h3>hb_set_get_population ()</h3>
 <pre class="programlisting">unsigned <span class="returnvalue">int</span>
-hb_set_get_population (<em class="parameter"><code>const <a class="link" href="harfbuzz-hb-set.html#hb-set-t" title="hb_set_t"><span class="type">hb_set_t</span></a> *set</code></em>);</pre>
+hb_set_get_population (<em class="parameter"><code>const <a class="link" href="harfbuzz-hb-set.html#hb-set-t"><span class="type">hb_set_t</span></a> *set</code></em>);</pre>
 <p>Returns the number of numbers in the set.</p>
 <div class="refsect3">
 <a name="hb-set-get-population.parameters"></a><h4>Parameters</h4>
@@ -567,8 +574,8 @@ hb_set_get_population (<em class="parameter"><code>const <a class="link" href="h
 <div class="refsect2">
 <a name="hb-set-get-user-data"></a><h3>hb_set_get_user_data ()</h3>
 <pre class="programlisting"><span class="returnvalue">void</span> *
-hb_set_get_user_data (<em class="parameter"><code><a class="link" href="harfbuzz-hb-set.html#hb-set-t" title="hb_set_t"><span class="type">hb_set_t</span></a> *set</code></em>,
-                      <em class="parameter"><code><a class="link" href="harfbuzz-hb-common.html#hb-user-data-key-t" title="hb_user_data_key_t"><span class="type">hb_user_data_key_t</span></a> *key</code></em>);</pre>
+hb_set_get_user_data (<em class="parameter"><code><a class="link" href="harfbuzz-hb-set.html#hb-set-t"><span class="type">hb_set_t</span></a> *set</code></em>,
+                      <em class="parameter"><code><a class="link" href="harfbuzz-hb-common.html#hb-user-data-key-t"><span class="type">hb_user_data_key_t</span></a> *key</code></em>);</pre>
 <p><span class="annotation">[<acronym title="Exposed in C code, not necessarily available in other languages."><span class="acronym">skip</span></acronym>]</span></p>
 <div class="refsect3">
 <a name="hb-set-get-user-data.parameters"></a><h4>Parameters</h4>
@@ -596,7 +603,7 @@ hb_set_get_user_data (<em class="parameter"><code><a class="link" href="harfbuzz
 <div class="refsect2">
 <a name="hb-set-has"></a><h3>hb_set_has ()</h3>
 <pre class="programlisting"><a class="link" href="harfbuzz-hb-common.html#hb-bool-t" title="hb_bool_t"><span class="returnvalue">hb_bool_t</span></a>
-hb_set_has (<em class="parameter"><code>const <a class="link" href="harfbuzz-hb-set.html#hb-set-t" title="hb_set_t"><span class="type">hb_set_t</span></a> *set</code></em>,
+hb_set_has (<em class="parameter"><code>const <a class="link" href="harfbuzz-hb-set.html#hb-set-t"><span class="type">hb_set_t</span></a> *set</code></em>,
             <em class="parameter"><code><a class="link" href="harfbuzz-hb-common.html#hb-codepoint-t" title="hb_codepoint_t"><span class="type">hb_codepoint_t</span></a> codepoint</code></em>);</pre>
 <div class="refsect3">
 <a name="hb-set-has.parameters"></a><h4>Parameters</h4>
@@ -619,8 +626,8 @@ hb_set_has (<em class="parameter"><code>const <a class="link" href="harfbuzz-hb-
 <div class="refsect2">
 <a name="hb-set-intersect"></a><h3>hb_set_intersect ()</h3>
 <pre class="programlisting"><span class="returnvalue">void</span>
-hb_set_intersect (<em class="parameter"><code><a class="link" href="harfbuzz-hb-set.html#hb-set-t" title="hb_set_t"><span class="type">hb_set_t</span></a> *set</code></em>,
-                  <em class="parameter"><code>const <a class="link" href="harfbuzz-hb-set.html#hb-set-t" title="hb_set_t"><span class="type">hb_set_t</span></a> *other</code></em>);</pre>
+hb_set_intersect (<em class="parameter"><code><a class="link" href="harfbuzz-hb-set.html#hb-set-t"><span class="type">hb_set_t</span></a> *set</code></em>,
+                  <em class="parameter"><code>const <a class="link" href="harfbuzz-hb-set.html#hb-set-t"><span class="type">hb_set_t</span></a> *other</code></em>);</pre>
 <div class="refsect3">
 <a name="hb-set-intersect.parameters"></a><h4>Parameters</h4>
 <div class="informaltable"><table class="informaltable" width="100%" border="0">
@@ -642,7 +649,7 @@ hb_set_intersect (<em class="parameter"><code><a class="link" href="harfbuzz-hb-
 <div class="refsect2">
 <a name="hb-set-is-empty"></a><h3>hb_set_is_empty ()</h3>
 <pre class="programlisting"><a class="link" href="harfbuzz-hb-common.html#hb-bool-t" title="hb_bool_t"><span class="returnvalue">hb_bool_t</span></a>
-hb_set_is_empty (<em class="parameter"><code>const <a class="link" href="harfbuzz-hb-set.html#hb-set-t" title="hb_set_t"><span class="type">hb_set_t</span></a> *set</code></em>);</pre>
+hb_set_is_empty (<em class="parameter"><code>const <a class="link" href="harfbuzz-hb-set.html#hb-set-t"><span class="type">hb_set_t</span></a> *set</code></em>);</pre>
 <div class="refsect3">
 <a name="hb-set-is-empty.parameters"></a><h4>Parameters</h4>
 <div class="informaltable"><table class="informaltable" width="100%" border="0">
@@ -664,8 +671,8 @@ hb_set_is_empty (<em class="parameter"><code>const <a class="link" href="harfbuz
 <div class="refsect2">
 <a name="hb-set-is-equal"></a><h3>hb_set_is_equal ()</h3>
 <pre class="programlisting"><a class="link" href="harfbuzz-hb-common.html#hb-bool-t" title="hb_bool_t"><span class="returnvalue">hb_bool_t</span></a>
-hb_set_is_equal (<em class="parameter"><code>const <a class="link" href="harfbuzz-hb-set.html#hb-set-t" title="hb_set_t"><span class="type">hb_set_t</span></a> *set</code></em>,
-                 <em class="parameter"><code>const <a class="link" href="harfbuzz-hb-set.html#hb-set-t" title="hb_set_t"><span class="type">hb_set_t</span></a> *other</code></em>);</pre>
+hb_set_is_equal (<em class="parameter"><code>const <a class="link" href="harfbuzz-hb-set.html#hb-set-t"><span class="type">hb_set_t</span></a> *set</code></em>,
+                 <em class="parameter"><code>const <a class="link" href="harfbuzz-hb-set.html#hb-set-t"><span class="type">hb_set_t</span></a> *other</code></em>);</pre>
 <div class="refsect3">
 <a name="hb-set-is-equal.parameters"></a><h4>Parameters</h4>
 <div class="informaltable"><table class="informaltable" width="100%" border="0">
@@ -690,7 +697,7 @@ hb_set_is_equal (<em class="parameter"><code>const <a class="link" href="harfbuz
 </div>
 <div class="refsect3">
 <a name="hb-set-is-equal.returns"></a><h4>Returns</h4>
-<p> <a href="/usr/share/gtk-doc/html/glib/glib-Standard-Macros.html#TRUE:CAPS"><code class="literal">TRUE</code></a> if the two sets are equal, <a href="/usr/share/gtk-doc/html/glib/glib-Standard-Macros.html#FALSE:CAPS"><code class="literal">FALSE</code></a> otherwise.</p>
+<p> <code class="literal">TRUE</code> if the two sets are equal, <code class="literal">FALSE</code> otherwise.</p>
 </div>
 <p class="since">Since: <a class="link" href="api-index-0-9-7.html#api-index-0.9.7">0.9.7</a></p>
 </div>
@@ -698,8 +705,8 @@ hb_set_is_equal (<em class="parameter"><code>const <a class="link" href="harfbuz
 <div class="refsect2">
 <a name="hb-set-is-subset"></a><h3>hb_set_is_subset ()</h3>
 <pre class="programlisting"><a class="link" href="harfbuzz-hb-common.html#hb-bool-t" title="hb_bool_t"><span class="returnvalue">hb_bool_t</span></a>
-hb_set_is_subset (<em class="parameter"><code>const <a class="link" href="harfbuzz-hb-set.html#hb-set-t" title="hb_set_t"><span class="type">hb_set_t</span></a> *set</code></em>,
-                  <em class="parameter"><code>const <a class="link" href="harfbuzz-hb-set.html#hb-set-t" title="hb_set_t"><span class="type">hb_set_t</span></a> *larger_set</code></em>);</pre>
+hb_set_is_subset (<em class="parameter"><code>const <a class="link" href="harfbuzz-hb-set.html#hb-set-t"><span class="type">hb_set_t</span></a> *set</code></em>,
+                  <em class="parameter"><code>const <a class="link" href="harfbuzz-hb-set.html#hb-set-t"><span class="type">hb_set_t</span></a> *larger_set</code></em>);</pre>
 <div class="refsect3">
 <a name="hb-set-is-subset.parameters"></a><h4>Parameters</h4>
 <div class="informaltable"><table class="informaltable" width="100%" border="0">
@@ -724,9 +731,9 @@ hb_set_is_subset (<em class="parameter"><code>const <a class="link" href="harfbu
 </div>
 <div class="refsect3">
 <a name="hb-set-is-subset.returns"></a><h4>Returns</h4>
-<p> <a href="/usr/share/gtk-doc/html/glib/glib-Standard-Macros.html#TRUE:CAPS"><code class="literal">TRUE</code></a> if the <em class="parameter"><code>set</code></em>
+<p> <code class="literal">TRUE</code> if the <em class="parameter"><code>set</code></em>
 is a subset of (or equal to) <em class="parameter"><code>larger_set</code></em>
-, <a href="/usr/share/gtk-doc/html/glib/glib-Standard-Macros.html#FALSE:CAPS"><code class="literal">FALSE</code></a> otherwise.</p>
+, <code class="literal">FALSE</code> otherwise.</p>
 </div>
 <p class="since">Since: <a class="link" href="api-index-1-8-1.html#api-index-1.8.1">1.8.1</a></p>
 </div>
@@ -734,7 +741,7 @@ is a subset of (or equal to) <em class="parameter"><code>larger_set</code></em>
 <div class="refsect2">
 <a name="hb-set-next"></a><h3>hb_set_next ()</h3>
 <pre class="programlisting"><a class="link" href="harfbuzz-hb-common.html#hb-bool-t" title="hb_bool_t"><span class="returnvalue">hb_bool_t</span></a>
-hb_set_next (<em class="parameter"><code>const <a class="link" href="harfbuzz-hb-set.html#hb-set-t" title="hb_set_t"><span class="type">hb_set_t</span></a> *set</code></em>,
+hb_set_next (<em class="parameter"><code>const <a class="link" href="harfbuzz-hb-set.html#hb-set-t"><span class="type">hb_set_t</span></a> *set</code></em>,
              <em class="parameter"><code><a class="link" href="harfbuzz-hb-common.html#hb-codepoint-t" title="hb_codepoint_t"><span class="type">hb_codepoint_t</span></a> *codepoint</code></em>);</pre>
 <p>Gets the next number in <em class="parameter"><code>set</code></em>
  that is greater than current value of <em class="parameter"><code>codepoint</code></em>
@@ -773,7 +780,7 @@ hb_set_next (<em class="parameter"><code>const <a class="link" href="harfbuzz-hb
 <div class="refsect2">
 <a name="hb-set-next-range"></a><h3>hb_set_next_range ()</h3>
 <pre class="programlisting"><a class="link" href="harfbuzz-hb-common.html#hb-bool-t" title="hb_bool_t"><span class="returnvalue">hb_bool_t</span></a>
-hb_set_next_range (<em class="parameter"><code>const <a class="link" href="harfbuzz-hb-set.html#hb-set-t" title="hb_set_t"><span class="type">hb_set_t</span></a> *set</code></em>,
+hb_set_next_range (<em class="parameter"><code>const <a class="link" href="harfbuzz-hb-set.html#hb-set-t"><span class="type">hb_set_t</span></a> *set</code></em>,
                    <em class="parameter"><code><a class="link" href="harfbuzz-hb-common.html#hb-codepoint-t" title="hb_codepoint_t"><span class="type">hb_codepoint_t</span></a> *first</code></em>,
                    <em class="parameter"><code><a class="link" href="harfbuzz-hb-common.html#hb-codepoint-t" title="hb_codepoint_t"><span class="type">hb_codepoint_t</span></a> *last</code></em>);</pre>
 <p>Gets the next consecutive range of numbers in <em class="parameter"><code>set</code></em>
@@ -819,10 +826,10 @@ are greater than current value of <em class="parameter"><code>last</code></em>
 <div class="refsect2">
 <a name="hb-set-previous"></a><h3>hb_set_previous ()</h3>
 <pre class="programlisting"><a class="link" href="harfbuzz-hb-common.html#hb-bool-t" title="hb_bool_t"><span class="returnvalue">hb_bool_t</span></a>
-hb_set_previous (<em class="parameter"><code>const <a class="link" href="harfbuzz-hb-set.html#hb-set-t" title="hb_set_t"><span class="type">hb_set_t</span></a> *set</code></em>,
+hb_set_previous (<em class="parameter"><code>const <a class="link" href="harfbuzz-hb-set.html#hb-set-t"><span class="type">hb_set_t</span></a> *set</code></em>,
                  <em class="parameter"><code><a class="link" href="harfbuzz-hb-common.html#hb-codepoint-t" title="hb_codepoint_t"><span class="type">hb_codepoint_t</span></a> *codepoint</code></em>);</pre>
 <p>Gets the previous number in <em class="parameter"><code>set</code></em>
- that is slower than current value of <em class="parameter"><code>codepoint</code></em>
+ that is lower than current value of <em class="parameter"><code>codepoint</code></em>
 .</p>
 <p>Set <em class="parameter"><code>codepoint</code></em>
  to <a class="link" href="harfbuzz-hb-set.html#HB-SET-VALUE-INVALID:CAPS" title="HB_SET_VALUE_INVALID"><code class="literal">HB_SET_VALUE_INVALID</code></a> to get started.</p>
@@ -858,12 +865,12 @@ hb_set_previous (<em class="parameter"><code>const <a class="link" href="harfbuz
 <div class="refsect2">
 <a name="hb-set-previous-range"></a><h3>hb_set_previous_range ()</h3>
 <pre class="programlisting"><a class="link" href="harfbuzz-hb-common.html#hb-bool-t" title="hb_bool_t"><span class="returnvalue">hb_bool_t</span></a>
-hb_set_previous_range (<em class="parameter"><code>const <a class="link" href="harfbuzz-hb-set.html#hb-set-t" title="hb_set_t"><span class="type">hb_set_t</span></a> *set</code></em>,
+hb_set_previous_range (<em class="parameter"><code>const <a class="link" href="harfbuzz-hb-set.html#hb-set-t"><span class="type">hb_set_t</span></a> *set</code></em>,
                        <em class="parameter"><code><a class="link" href="harfbuzz-hb-common.html#hb-codepoint-t" title="hb_codepoint_t"><span class="type">hb_codepoint_t</span></a> *first</code></em>,
                        <em class="parameter"><code><a class="link" href="harfbuzz-hb-common.html#hb-codepoint-t" title="hb_codepoint_t"><span class="type">hb_codepoint_t</span></a> *last</code></em>);</pre>
 <p>Gets the previous consecutive range of numbers in <em class="parameter"><code>set</code></em>
  that
-are greater than current value of <em class="parameter"><code>last</code></em>
+are less than current value of <em class="parameter"><code>first</code></em>
 .</p>
 <p>Set <em class="parameter"><code>first</code></em>
  to <a class="link" href="harfbuzz-hb-set.html#HB-SET-VALUE-INVALID:CAPS" title="HB_SET_VALUE_INVALID"><code class="literal">HB_SET_VALUE_INVALID</code></a> to get started.</p>
@@ -903,8 +910,8 @@ are greater than current value of <em class="parameter"><code>last</code></em>
 <hr>
 <div class="refsect2">
 <a name="hb-set-reference"></a><h3>hb_set_reference ()</h3>
-<pre class="programlisting"><a class="link" href="harfbuzz-hb-set.html#hb-set-t" title="hb_set_t"><span class="returnvalue">hb_set_t</span></a> *
-hb_set_reference (<em class="parameter"><code><a class="link" href="harfbuzz-hb-set.html#hb-set-t" title="hb_set_t"><span class="type">hb_set_t</span></a> *set</code></em>);</pre>
+<pre class="programlisting"><a class="link" href="harfbuzz-hb-set.html#hb-set-t"><span class="returnvalue">hb_set_t</span></a> *
+hb_set_reference (<em class="parameter"><code><a class="link" href="harfbuzz-hb-set.html#hb-set-t"><span class="type">hb_set_t</span></a> *set</code></em>);</pre>
 <p><span class="annotation">[<acronym title="Exposed in C code, not necessarily available in other languages."><span class="acronym">skip</span></acronym>]</span></p>
 <div class="refsect3">
 <a name="hb-set-reference.parameters"></a><h4>Parameters</h4>
@@ -932,8 +939,8 @@ hb_set_reference (<em class="parameter"><code><a class="link" href="harfbuzz-hb-
 <div class="refsect2">
 <a name="hb-set-set"></a><h3>hb_set_set ()</h3>
 <pre class="programlisting"><span class="returnvalue">void</span>
-hb_set_set (<em class="parameter"><code><a class="link" href="harfbuzz-hb-set.html#hb-set-t" title="hb_set_t"><span class="type">hb_set_t</span></a> *set</code></em>,
-            <em class="parameter"><code>const <a class="link" href="harfbuzz-hb-set.html#hb-set-t" title="hb_set_t"><span class="type">hb_set_t</span></a> *other</code></em>);</pre>
+hb_set_set (<em class="parameter"><code><a class="link" href="harfbuzz-hb-set.html#hb-set-t"><span class="type">hb_set_t</span></a> *set</code></em>,
+            <em class="parameter"><code>const <a class="link" href="harfbuzz-hb-set.html#hb-set-t"><span class="type">hb_set_t</span></a> *other</code></em>);</pre>
 <div class="refsect3">
 <a name="hb-set-set.parameters"></a><h4>Parameters</h4>
 <div class="informaltable"><table class="informaltable" width="100%" border="0">
@@ -955,8 +962,8 @@ hb_set_set (<em class="parameter"><code><a class="link" href="harfbuzz-hb-set.ht
 <div class="refsect2">
 <a name="hb-set-set-user-data"></a><h3>hb_set_set_user_data ()</h3>
 <pre class="programlisting"><a class="link" href="harfbuzz-hb-common.html#hb-bool-t" title="hb_bool_t"><span class="returnvalue">hb_bool_t</span></a>
-hb_set_set_user_data (<em class="parameter"><code><a class="link" href="harfbuzz-hb-set.html#hb-set-t" title="hb_set_t"><span class="type">hb_set_t</span></a> *set</code></em>,
-                      <em class="parameter"><code><a class="link" href="harfbuzz-hb-common.html#hb-user-data-key-t" title="hb_user_data_key_t"><span class="type">hb_user_data_key_t</span></a> *key</code></em>,
+hb_set_set_user_data (<em class="parameter"><code><a class="link" href="harfbuzz-hb-set.html#hb-set-t"><span class="type">hb_set_t</span></a> *set</code></em>,
+                      <em class="parameter"><code><a class="link" href="harfbuzz-hb-common.html#hb-user-data-key-t"><span class="type">hb_user_data_key_t</span></a> *key</code></em>,
                       <em class="parameter"><code><span class="type">void</span> *data</code></em>,
                       <em class="parameter"><code><a class="link" href="harfbuzz-hb-common.html#hb-destroy-func-t" title="hb_destroy_func_t ()"><span class="type">hb_destroy_func_t</span></a> destroy</code></em>,
                       <em class="parameter"><code><a class="link" href="harfbuzz-hb-common.html#hb-bool-t" title="hb_bool_t"><span class="type">hb_bool_t</span></a> replace</code></em>);</pre>
@@ -982,8 +989,8 @@ hb_set_set_user_data (<em class="parameter"><code><a class="link" href="harfbuzz
 <div class="refsect2">
 <a name="hb-set-subtract"></a><h3>hb_set_subtract ()</h3>
 <pre class="programlisting"><span class="returnvalue">void</span>
-hb_set_subtract (<em class="parameter"><code><a class="link" href="harfbuzz-hb-set.html#hb-set-t" title="hb_set_t"><span class="type">hb_set_t</span></a> *set</code></em>,
-                 <em class="parameter"><code>const <a class="link" href="harfbuzz-hb-set.html#hb-set-t" title="hb_set_t"><span class="type">hb_set_t</span></a> *other</code></em>);</pre>
+hb_set_subtract (<em class="parameter"><code><a class="link" href="harfbuzz-hb-set.html#hb-set-t"><span class="type">hb_set_t</span></a> *set</code></em>,
+                 <em class="parameter"><code>const <a class="link" href="harfbuzz-hb-set.html#hb-set-t"><span class="type">hb_set_t</span></a> *other</code></em>);</pre>
 <div class="refsect3">
 <a name="hb-set-subtract.parameters"></a><h4>Parameters</h4>
 <div class="informaltable"><table class="informaltable" width="100%" border="0">
@@ -1005,8 +1012,8 @@ hb_set_subtract (<em class="parameter"><code><a class="link" href="harfbuzz-hb-s
 <div class="refsect2">
 <a name="hb-set-symmetric-difference"></a><h3>hb_set_symmetric_difference ()</h3>
 <pre class="programlisting"><span class="returnvalue">void</span>
-hb_set_symmetric_difference (<em class="parameter"><code><a class="link" href="harfbuzz-hb-set.html#hb-set-t" title="hb_set_t"><span class="type">hb_set_t</span></a> *set</code></em>,
-                             <em class="parameter"><code>const <a class="link" href="harfbuzz-hb-set.html#hb-set-t" title="hb_set_t"><span class="type">hb_set_t</span></a> *other</code></em>);</pre>
+hb_set_symmetric_difference (<em class="parameter"><code><a class="link" href="harfbuzz-hb-set.html#hb-set-t"><span class="type">hb_set_t</span></a> *set</code></em>,
+                             <em class="parameter"><code>const <a class="link" href="harfbuzz-hb-set.html#hb-set-t"><span class="type">hb_set_t</span></a> *other</code></em>);</pre>
 <div class="refsect3">
 <a name="hb-set-symmetric-difference.parameters"></a><h4>Parameters</h4>
 <div class="informaltable"><table class="informaltable" width="100%" border="0">
@@ -1028,8 +1035,8 @@ hb_set_symmetric_difference (<em class="parameter"><code><a class="link" href="h
 <div class="refsect2">
 <a name="hb-set-union"></a><h3>hb_set_union ()</h3>
 <pre class="programlisting"><span class="returnvalue">void</span>
-hb_set_union (<em class="parameter"><code><a class="link" href="harfbuzz-hb-set.html#hb-set-t" title="hb_set_t"><span class="type">hb_set_t</span></a> *set</code></em>,
-              <em class="parameter"><code>const <a class="link" href="harfbuzz-hb-set.html#hb-set-t" title="hb_set_t"><span class="type">hb_set_t</span></a> *other</code></em>);</pre>
+hb_set_union (<em class="parameter"><code><a class="link" href="harfbuzz-hb-set.html#hb-set-t"><span class="type">hb_set_t</span></a> *set</code></em>,
+              <em class="parameter"><code>const <a class="link" href="harfbuzz-hb-set.html#hb-set-t"><span class="type">hb_set_t</span></a> *other</code></em>);</pre>
 <div class="refsect3">
 <a name="hb-set-union.parameters"></a><h4>Parameters</h4>
 <div class="informaltable"><table class="informaltable" width="100%" border="0">
index e9c3501..577c556 100644 (file)
@@ -5,7 +5,7 @@
 <title>hb-shape-plan: HarfBuzz Manual</title>
 <meta name="generator" content="DocBook XSL Stylesheets Vsnapshot">
 <link rel="home" href="index.html" title="HarfBuzz Manual">
-<link rel="up" href="ch09.html" title="Core API">
+<link rel="up" href="ch11.html" title="Core API">
 <link rel="prev" href="harfbuzz-hb-set.html" title="hb-set">
 <link rel="next" href="harfbuzz-hb-shape.html" title="hb-shape">
 <meta name="generator" content="GTK-Doc V1.29 (XML mode)">
 <table class="navigation" id="top" width="100%" summary="Navigation header" cellpadding="2" cellspacing="5"><tr valign="middle">
 <td width="100%" align="left" class="shortcuts">
 <a href="#" class="shortcut">Top</a><span id="nav_description">  <span class="dim">|</span> 
-                  <a href="#harfbuzz-hb-shape-plan.description" class="shortcut">Description</a></span>
+                  <a href="#harfbuzz-hb-shape-plan.description" class="shortcut">Description</a></span><span id="nav_hierarchy">  <span class="dim">|</span> 
+                  <a href="#harfbuzz-hb-shape-plan.object-hierarchy" class="shortcut">Object Hierarchy</a></span>
 </td>
 <td><a accesskey="h" href="index.html"><img src="home.png" width="16" height="16" border="0" alt="Home"></a></td>
-<td><a accesskey="u" href="ch09.html"><img src="up.png" width="16" height="16" border="0" alt="Up"></a></td>
+<td><a accesskey="u" href="ch11.html"><img src="up.png" width="16" height="16" border="0" alt="Up"></a></td>
 <td><a accesskey="p" href="harfbuzz-hb-set.html"><img src="left.png" width="16" height="16" border="0" alt="Prev"></a></td>
 <td><a accesskey="n" href="harfbuzz-hb-shape.html"><img src="right.png" width="16" height="16" border="0" alt="Next"></a></td>
 </tr></table>
@@ -41,7 +42,7 @@
 <tbody>
 <tr>
 <td class="function_type">
-<a class="link" href="harfbuzz-hb-shape-plan.html#hb-shape-plan-t" title="hb_shape_plan_t"><span class="returnvalue">hb_shape_plan_t</span></a> *
+<a class="link" href="harfbuzz-hb-shape-plan.html#hb-shape-plan-t"><span class="returnvalue">hb_shape_plan_t</span></a> *
 </td>
 <td class="function_name">
 <a class="link" href="harfbuzz-hb-shape-plan.html#hb-shape-plan-create" title="hb_shape_plan_create ()">hb_shape_plan_create</a> <span class="c_punctuation">()</span>
@@ -49,7 +50,7 @@
 </tr>
 <tr>
 <td class="function_type">
-<a class="link" href="harfbuzz-hb-shape-plan.html#hb-shape-plan-t" title="hb_shape_plan_t"><span class="returnvalue">hb_shape_plan_t</span></a> *
+<a class="link" href="harfbuzz-hb-shape-plan.html#hb-shape-plan-t"><span class="returnvalue">hb_shape_plan_t</span></a> *
 </td>
 <td class="function_name">
 <a class="link" href="harfbuzz-hb-shape-plan.html#hb-shape-plan-create-cached" title="hb_shape_plan_create_cached ()">hb_shape_plan_create_cached</a> <span class="c_punctuation">()</span>
@@ -57,7 +58,7 @@
 </tr>
 <tr>
 <td class="function_type">
-<a class="link" href="harfbuzz-hb-shape-plan.html#hb-shape-plan-t" title="hb_shape_plan_t"><span class="returnvalue">hb_shape_plan_t</span></a> *
+<a class="link" href="harfbuzz-hb-shape-plan.html#hb-shape-plan-t"><span class="returnvalue">hb_shape_plan_t</span></a> *
 </td>
 <td class="function_name">
 <a class="link" href="harfbuzz-hb-shape-plan.html#hb-shape-plan-create2" title="hb_shape_plan_create2 ()">hb_shape_plan_create2</a> <span class="c_punctuation">()</span>
@@ -65,7 +66,7 @@
 </tr>
 <tr>
 <td class="function_type">
-<a class="link" href="harfbuzz-hb-shape-plan.html#hb-shape-plan-t" title="hb_shape_plan_t"><span class="returnvalue">hb_shape_plan_t</span></a> *
+<a class="link" href="harfbuzz-hb-shape-plan.html#hb-shape-plan-t"><span class="returnvalue">hb_shape_plan_t</span></a> *
 </td>
 <td class="function_name">
 <a class="link" href="harfbuzz-hb-shape-plan.html#hb-shape-plan-create-cached2" title="hb_shape_plan_create_cached2 ()">hb_shape_plan_create_cached2</a> <span class="c_punctuation">()</span>
@@ -89,7 +90,7 @@
 </tr>
 <tr>
 <td class="function_type">
-<a class="link" href="harfbuzz-hb-shape-plan.html#hb-shape-plan-t" title="hb_shape_plan_t"><span class="returnvalue">hb_shape_plan_t</span></a> *
+<a class="link" href="harfbuzz-hb-shape-plan.html#hb-shape-plan-t"><span class="returnvalue">hb_shape_plan_t</span></a> *
 </td>
 <td class="function_name">
 <a class="link" href="harfbuzz-hb-shape-plan.html#hb-shape-plan-get-empty" title="hb_shape_plan_get_empty ()">hb_shape_plan_get_empty</a> <span class="c_punctuation">()</span>
 </tr>
 <tr>
 <td class="function_type">
-<a class="link" href="harfbuzz-hb-shape-plan.html#hb-shape-plan-t" title="hb_shape_plan_t"><span class="returnvalue">hb_shape_plan_t</span></a> *
+<a class="link" href="harfbuzz-hb-shape-plan.html#hb-shape-plan-t"><span class="returnvalue">hb_shape_plan_t</span></a> *
 </td>
 <td class="function_name">
 <a class="link" href="harfbuzz-hb-shape-plan.html#hb-shape-plan-reference" title="hb_shape_plan_reference ()">hb_shape_plan_reference</a> <span class="c_punctuation">()</span>
 </tbody>
 </table></div>
 </div>
-<div class="refsect1">
+<a name="hb-shape-plan-t"></a><div class="refsect1">
 <a name="harfbuzz-hb-shape-plan.other"></a><h2>Types and Values</h2>
 <div class="informaltable"><table class="informaltable" width="100%" border="0">
 <colgroup>
 </colgroup>
 <tbody><tr>
 <td class="typedef_keyword">typedef</td>
-<td class="function_name"><a class="link" href="harfbuzz-hb-shape-plan.html#hb-shape-plan-t" title="hb_shape_plan_t">hb_shape_plan_t</a></td>
+<td class="function_name"><a class="link" href="harfbuzz-hb-shape-plan.html#hb-shape-plan-t">hb_shape_plan_t</a></td>
 </tr></tbody>
 </table></div>
 </div>
 <div class="refsect1">
+<a name="harfbuzz-hb-shape-plan.object-hierarchy"></a><h2>Object Hierarchy</h2>
+<pre class="screen">    <a href="/usr/share/gtk-doc/html/gobject/gobject-Boxed-Types.html">GBoxed</a>
+    <span class="lineart">╰──</span> hb_shape_plan_t
+</pre>
+</div>
+<div class="refsect1">
 <a name="harfbuzz-hb-shape-plan.includes"></a><h2>Includes</h2>
 <pre class="synopsis">#include &lt;hb.h&gt;
 </pre>
@@ -158,10 +165,10 @@ Most client would not need to deal with shape plans directly.</p>
 <a name="harfbuzz-hb-shape-plan.functions_details"></a><h2>Functions</h2>
 <div class="refsect2">
 <a name="hb-shape-plan-create"></a><h3>hb_shape_plan_create ()</h3>
-<pre class="programlisting"><a class="link" href="harfbuzz-hb-shape-plan.html#hb-shape-plan-t" title="hb_shape_plan_t"><span class="returnvalue">hb_shape_plan_t</span></a> *
-hb_shape_plan_create (<em class="parameter"><code><a class="link" href="harfbuzz-hb-face.html#hb-face-t" title="hb_face_t"><span class="type">hb_face_t</span></a> *face</code></em>,
-                      <em class="parameter"><code>const <a class="link" href="harfbuzz-hb-buffer.html#hb-segment-properties-t" title="hb_segment_properties_t"><span class="type">hb_segment_properties_t</span></a> *props</code></em>,
-                      <em class="parameter"><code>const <a class="link" href="harfbuzz-hb-common.html#hb-feature-t" title="hb_feature_t"><span class="type">hb_feature_t</span></a> *user_features</code></em>,
+<pre class="programlisting"><a class="link" href="harfbuzz-hb-shape-plan.html#hb-shape-plan-t"><span class="returnvalue">hb_shape_plan_t</span></a> *
+hb_shape_plan_create (<em class="parameter"><code><a class="link" href="harfbuzz-hb-face.html#hb-face-t"><span class="type">hb_face_t</span></a> *face</code></em>,
+                      <em class="parameter"><code>const <a class="link" href="harfbuzz-hb-buffer.html#hb-segment-properties-t"><span class="type">hb_segment_properties_t</span></a> *props</code></em>,
+                      <em class="parameter"><code>const <a class="link" href="harfbuzz-hb-common.html#hb-feature-t"><span class="type">hb_feature_t</span></a> *user_features</code></em>,
                       <em class="parameter"><code>unsigned <span class="type">int</span> num_user_features</code></em>,
                       <em class="parameter"><code>const <span class="type">char</span> * const *shaper_list</code></em>);</pre>
 <p><span class="annotation">[Xconstructor]</span></p>
@@ -197,10 +204,10 @@ hb_shape_plan_create (<em class="parameter"><code><a class="link" href="harfbuzz
 <hr>
 <div class="refsect2">
 <a name="hb-shape-plan-create-cached"></a><h3>hb_shape_plan_create_cached ()</h3>
-<pre class="programlisting"><a class="link" href="harfbuzz-hb-shape-plan.html#hb-shape-plan-t" title="hb_shape_plan_t"><span class="returnvalue">hb_shape_plan_t</span></a> *
-hb_shape_plan_create_cached (<em class="parameter"><code><a class="link" href="harfbuzz-hb-face.html#hb-face-t" title="hb_face_t"><span class="type">hb_face_t</span></a> *face</code></em>,
-                             <em class="parameter"><code>const <a class="link" href="harfbuzz-hb-buffer.html#hb-segment-properties-t" title="hb_segment_properties_t"><span class="type">hb_segment_properties_t</span></a> *props</code></em>,
-                             <em class="parameter"><code>const <a class="link" href="harfbuzz-hb-common.html#hb-feature-t" title="hb_feature_t"><span class="type">hb_feature_t</span></a> *user_features</code></em>,
+<pre class="programlisting"><a class="link" href="harfbuzz-hb-shape-plan.html#hb-shape-plan-t"><span class="returnvalue">hb_shape_plan_t</span></a> *
+hb_shape_plan_create_cached (<em class="parameter"><code><a class="link" href="harfbuzz-hb-face.html#hb-face-t"><span class="type">hb_face_t</span></a> *face</code></em>,
+                             <em class="parameter"><code>const <a class="link" href="harfbuzz-hb-buffer.html#hb-segment-properties-t"><span class="type">hb_segment_properties_t</span></a> *props</code></em>,
+                             <em class="parameter"><code>const <a class="link" href="harfbuzz-hb-common.html#hb-feature-t"><span class="type">hb_feature_t</span></a> *user_features</code></em>,
                              <em class="parameter"><code>unsigned <span class="type">int</span> num_user_features</code></em>,
                              <em class="parameter"><code>const <span class="type">char</span> * const *shaper_list</code></em>);</pre>
 <div class="refsect3">
@@ -235,10 +242,10 @@ hb_shape_plan_create_cached (<em class="parameter"><code><a class="link" href="h
 <hr>
 <div class="refsect2">
 <a name="hb-shape-plan-create2"></a><h3>hb_shape_plan_create2 ()</h3>
-<pre class="programlisting"><a class="link" href="harfbuzz-hb-shape-plan.html#hb-shape-plan-t" title="hb_shape_plan_t"><span class="returnvalue">hb_shape_plan_t</span></a> *
-hb_shape_plan_create2 (<em class="parameter"><code><a class="link" href="harfbuzz-hb-face.html#hb-face-t" title="hb_face_t"><span class="type">hb_face_t</span></a> *face</code></em>,
-                       <em class="parameter"><code>const <a class="link" href="harfbuzz-hb-buffer.html#hb-segment-properties-t" title="hb_segment_properties_t"><span class="type">hb_segment_properties_t</span></a> *props</code></em>,
-                       <em class="parameter"><code>const <a class="link" href="harfbuzz-hb-common.html#hb-feature-t" title="hb_feature_t"><span class="type">hb_feature_t</span></a> *user_features</code></em>,
+<pre class="programlisting"><a class="link" href="harfbuzz-hb-shape-plan.html#hb-shape-plan-t"><span class="returnvalue">hb_shape_plan_t</span></a> *
+hb_shape_plan_create2 (<em class="parameter"><code><a class="link" href="harfbuzz-hb-face.html#hb-face-t"><span class="type">hb_face_t</span></a> *face</code></em>,
+                       <em class="parameter"><code>const <a class="link" href="harfbuzz-hb-buffer.html#hb-segment-properties-t"><span class="type">hb_segment_properties_t</span></a> *props</code></em>,
+                       <em class="parameter"><code>const <a class="link" href="harfbuzz-hb-common.html#hb-feature-t"><span class="type">hb_feature_t</span></a> *user_features</code></em>,
                        <em class="parameter"><code>unsigned <span class="type">int</span> num_user_features</code></em>,
                        <em class="parameter"><code>const <span class="type">int</span> *coords</code></em>,
                        <em class="parameter"><code>unsigned <span class="type">int</span> num_coords</code></em>,
@@ -247,10 +254,10 @@ hb_shape_plan_create2 (<em class="parameter"><code><a class="link" href="harfbuz
 <hr>
 <div class="refsect2">
 <a name="hb-shape-plan-create-cached2"></a><h3>hb_shape_plan_create_cached2 ()</h3>
-<pre class="programlisting"><a class="link" href="harfbuzz-hb-shape-plan.html#hb-shape-plan-t" title="hb_shape_plan_t"><span class="returnvalue">hb_shape_plan_t</span></a> *
-hb_shape_plan_create_cached2 (<em class="parameter"><code><a class="link" href="harfbuzz-hb-face.html#hb-face-t" title="hb_face_t"><span class="type">hb_face_t</span></a> *face</code></em>,
-                              <em class="parameter"><code>const <a class="link" href="harfbuzz-hb-buffer.html#hb-segment-properties-t" title="hb_segment_properties_t"><span class="type">hb_segment_properties_t</span></a> *props</code></em>,
-                              <em class="parameter"><code>const <a class="link" href="harfbuzz-hb-common.html#hb-feature-t" title="hb_feature_t"><span class="type">hb_feature_t</span></a> *user_features</code></em>,
+<pre class="programlisting"><a class="link" href="harfbuzz-hb-shape-plan.html#hb-shape-plan-t"><span class="returnvalue">hb_shape_plan_t</span></a> *
+hb_shape_plan_create_cached2 (<em class="parameter"><code><a class="link" href="harfbuzz-hb-face.html#hb-face-t"><span class="type">hb_face_t</span></a> *face</code></em>,
+                              <em class="parameter"><code>const <a class="link" href="harfbuzz-hb-buffer.html#hb-segment-properties-t"><span class="type">hb_segment_properties_t</span></a> *props</code></em>,
+                              <em class="parameter"><code>const <a class="link" href="harfbuzz-hb-common.html#hb-feature-t"><span class="type">hb_feature_t</span></a> *user_features</code></em>,
                               <em class="parameter"><code>unsigned <span class="type">int</span> num_user_features</code></em>,
                               <em class="parameter"><code>const <span class="type">int</span> *coords</code></em>,
                               <em class="parameter"><code>unsigned <span class="type">int</span> num_coords</code></em>,
@@ -260,7 +267,7 @@ hb_shape_plan_create_cached2 (<em class="parameter"><code><a class="link" href="
 <div class="refsect2">
 <a name="hb-shape-plan-destroy"></a><h3>hb_shape_plan_destroy ()</h3>
 <pre class="programlisting"><span class="returnvalue">void</span>
-hb_shape_plan_destroy (<em class="parameter"><code><a class="link" href="harfbuzz-hb-shape-plan.html#hb-shape-plan-t" title="hb_shape_plan_t"><span class="type">hb_shape_plan_t</span></a> *shape_plan</code></em>);</pre>
+hb_shape_plan_destroy (<em class="parameter"><code><a class="link" href="harfbuzz-hb-shape-plan.html#hb-shape-plan-t"><span class="type">hb_shape_plan_t</span></a> *shape_plan</code></em>);</pre>
 <p><span class="annotation">[<acronym title="Exposed in C code, not necessarily available in other languages."><span class="acronym">skip</span></acronym>]</span></p>
 <div class="refsect3">
 <a name="hb-shape-plan-destroy.parameters"></a><h4>Parameters</h4>
@@ -283,10 +290,10 @@ hb_shape_plan_destroy (<em class="parameter"><code><a class="link" href="harfbuz
 <div class="refsect2">
 <a name="hb-shape-plan-execute"></a><h3>hb_shape_plan_execute ()</h3>
 <pre class="programlisting"><a class="link" href="harfbuzz-hb-common.html#hb-bool-t" title="hb_bool_t"><span class="returnvalue">hb_bool_t</span></a>
-hb_shape_plan_execute (<em class="parameter"><code><a class="link" href="harfbuzz-hb-shape-plan.html#hb-shape-plan-t" title="hb_shape_plan_t"><span class="type">hb_shape_plan_t</span></a> *shape_plan</code></em>,
-                       <em class="parameter"><code><a class="link" href="harfbuzz-hb-font.html#hb-font-t" title="hb_font_t"><span class="type">hb_font_t</span></a> *font</code></em>,
-                       <em class="parameter"><code><a class="link" href="harfbuzz-hb-buffer.html#hb-buffer-t" title="hb_buffer_t"><span class="type">hb_buffer_t</span></a> *buffer</code></em>,
-                       <em class="parameter"><code>const <a class="link" href="harfbuzz-hb-common.html#hb-feature-t" title="hb_feature_t"><span class="type">hb_feature_t</span></a> *features</code></em>,
+hb_shape_plan_execute (<em class="parameter"><code><a class="link" href="harfbuzz-hb-shape-plan.html#hb-shape-plan-t"><span class="type">hb_shape_plan_t</span></a> *shape_plan</code></em>,
+                       <em class="parameter"><code><a class="link" href="harfbuzz-hb-font.html#hb-font-t"><span class="type">hb_font_t</span></a> *font</code></em>,
+                       <em class="parameter"><code><a class="link" href="harfbuzz-hb-buffer.html#hb-buffer-t"><span class="type">hb_buffer_t</span></a> *buffer</code></em>,
+                       <em class="parameter"><code>const <a class="link" href="harfbuzz-hb-common.html#hb-feature-t"><span class="type">hb_feature_t</span></a> *features</code></em>,
                        <em class="parameter"><code>unsigned <span class="type">int</span> num_features</code></em>);</pre>
 <div class="refsect3">
 <a name="hb-shape-plan-execute.parameters"></a><h4>Parameters</h4>
@@ -325,7 +332,7 @@ hb_shape_plan_execute (<em class="parameter"><code><a class="link" href="harfbuz
 <hr>
 <div class="refsect2">
 <a name="hb-shape-plan-get-empty"></a><h3>hb_shape_plan_get_empty ()</h3>
-<pre class="programlisting"><a class="link" href="harfbuzz-hb-shape-plan.html#hb-shape-plan-t" title="hb_shape_plan_t"><span class="returnvalue">hb_shape_plan_t</span></a> *
+<pre class="programlisting"><a class="link" href="harfbuzz-hb-shape-plan.html#hb-shape-plan-t"><span class="returnvalue">hb_shape_plan_t</span></a> *
 hb_shape_plan_get_empty (<em class="parameter"><code><span class="type">void</span></code></em>);</pre>
 <div class="refsect3">
 <a name="hb-shape-plan-get-empty.returns"></a><h4>Returns</h4>
@@ -338,7 +345,7 @@ hb_shape_plan_get_empty (<em class="parameter"><code><span class="type">void</sp
 <div class="refsect2">
 <a name="hb-shape-plan-get-shaper"></a><h3>hb_shape_plan_get_shaper ()</h3>
 <pre class="programlisting">const <span class="returnvalue">char</span> *
-hb_shape_plan_get_shaper (<em class="parameter"><code><a class="link" href="harfbuzz-hb-shape-plan.html#hb-shape-plan-t" title="hb_shape_plan_t"><span class="type">hb_shape_plan_t</span></a> *shape_plan</code></em>);</pre>
+hb_shape_plan_get_shaper (<em class="parameter"><code><a class="link" href="harfbuzz-hb-shape-plan.html#hb-shape-plan-t"><span class="type">hb_shape_plan_t</span></a> *shape_plan</code></em>);</pre>
 <div class="refsect3">
 <a name="hb-shape-plan-get-shaper.parameters"></a><h4>Parameters</h4>
 <div class="informaltable"><table class="informaltable" width="100%" border="0">
@@ -365,8 +372,8 @@ hb_shape_plan_get_shaper (<em class="parameter"><code><a class="link" href="harf
 <div class="refsect2">
 <a name="hb-shape-plan-get-user-data"></a><h3>hb_shape_plan_get_user_data ()</h3>
 <pre class="programlisting"><span class="returnvalue">void</span> *
-hb_shape_plan_get_user_data (<em class="parameter"><code><a class="link" href="harfbuzz-hb-shape-plan.html#hb-shape-plan-t" title="hb_shape_plan_t"><span class="type">hb_shape_plan_t</span></a> *shape_plan</code></em>,
-                             <em class="parameter"><code><a class="link" href="harfbuzz-hb-common.html#hb-user-data-key-t" title="hb_user_data_key_t"><span class="type">hb_user_data_key_t</span></a> *key</code></em>);</pre>
+hb_shape_plan_get_user_data (<em class="parameter"><code><a class="link" href="harfbuzz-hb-shape-plan.html#hb-shape-plan-t"><span class="type">hb_shape_plan_t</span></a> *shape_plan</code></em>,
+                             <em class="parameter"><code><a class="link" href="harfbuzz-hb-common.html#hb-user-data-key-t"><span class="type">hb_user_data_key_t</span></a> *key</code></em>);</pre>
 <p><span class="annotation">[<acronym title="Exposed in C code, not necessarily available in other languages."><span class="acronym">skip</span></acronym>]</span></p>
 <div class="refsect3">
 <a name="hb-shape-plan-get-user-data.parameters"></a><h4>Parameters</h4>
@@ -393,8 +400,8 @@ hb_shape_plan_get_user_data (<em class="parameter"><code><a class="link" href="h
 <hr>
 <div class="refsect2">
 <a name="hb-shape-plan-reference"></a><h3>hb_shape_plan_reference ()</h3>
-<pre class="programlisting"><a class="link" href="harfbuzz-hb-shape-plan.html#hb-shape-plan-t" title="hb_shape_plan_t"><span class="returnvalue">hb_shape_plan_t</span></a> *
-hb_shape_plan_reference (<em class="parameter"><code><a class="link" href="harfbuzz-hb-shape-plan.html#hb-shape-plan-t" title="hb_shape_plan_t"><span class="type">hb_shape_plan_t</span></a> *shape_plan</code></em>);</pre>
+<pre class="programlisting"><a class="link" href="harfbuzz-hb-shape-plan.html#hb-shape-plan-t"><span class="returnvalue">hb_shape_plan_t</span></a> *
+hb_shape_plan_reference (<em class="parameter"><code><a class="link" href="harfbuzz-hb-shape-plan.html#hb-shape-plan-t"><span class="type">hb_shape_plan_t</span></a> *shape_plan</code></em>);</pre>
 <p><span class="annotation">[<acronym title="Exposed in C code, not necessarily available in other languages."><span class="acronym">skip</span></acronym>]</span></p>
 <div class="refsect3">
 <a name="hb-shape-plan-reference.parameters"></a><h4>Parameters</h4>
@@ -422,8 +429,8 @@ hb_shape_plan_reference (<em class="parameter"><code><a class="link" href="harfb
 <div class="refsect2">
 <a name="hb-shape-plan-set-user-data"></a><h3>hb_shape_plan_set_user_data ()</h3>
 <pre class="programlisting"><a class="link" href="harfbuzz-hb-common.html#hb-bool-t" title="hb_bool_t"><span class="returnvalue">hb_bool_t</span></a>
-hb_shape_plan_set_user_data (<em class="parameter"><code><a class="link" href="harfbuzz-hb-shape-plan.html#hb-shape-plan-t" title="hb_shape_plan_t"><span class="type">hb_shape_plan_t</span></a> *shape_plan</code></em>,
-                             <em class="parameter"><code><a class="link" href="harfbuzz-hb-common.html#hb-user-data-key-t" title="hb_user_data_key_t"><span class="type">hb_user_data_key_t</span></a> *key</code></em>,
+hb_shape_plan_set_user_data (<em class="parameter"><code><a class="link" href="harfbuzz-hb-shape-plan.html#hb-shape-plan-t"><span class="type">hb_shape_plan_t</span></a> *shape_plan</code></em>,
+                             <em class="parameter"><code><a class="link" href="harfbuzz-hb-common.html#hb-user-data-key-t"><span class="type">hb_user_data_key_t</span></a> *key</code></em>,
                              <em class="parameter"><code><span class="type">void</span> *data</code></em>,
                              <em class="parameter"><code><a class="link" href="harfbuzz-hb-common.html#hb-destroy-func-t" title="hb_destroy_func_t ()"><span class="type">hb_destroy_func_t</span></a> destroy</code></em>,
                              <em class="parameter"><code><a class="link" href="harfbuzz-hb-common.html#hb-bool-t" title="hb_bool_t"><span class="type">hb_bool_t</span></a> replace</code></em>);</pre>
index 0785017..d61f3ea 100644 (file)
@@ -5,7 +5,7 @@
 <title>hb-shape: HarfBuzz Manual</title>
 <meta name="generator" content="DocBook XSL Stylesheets Vsnapshot">
 <link rel="home" href="index.html" title="HarfBuzz Manual">
-<link rel="up" href="ch09.html" title="Core API">
+<link rel="up" href="ch11.html" title="Core API">
 <link rel="prev" href="harfbuzz-hb-shape-plan.html" title="hb-shape-plan">
 <link rel="next" href="harfbuzz-hb-unicode.html" title="hb-unicode">
 <meta name="generator" content="GTK-Doc V1.29 (XML mode)">
@@ -18,7 +18,7 @@
                   <a href="#harfbuzz-hb-shape.description" class="shortcut">Description</a></span>
 </td>
 <td><a accesskey="h" href="index.html"><img src="home.png" width="16" height="16" border="0" alt="Home"></a></td>
-<td><a accesskey="u" href="ch09.html"><img src="up.png" width="16" height="16" border="0" alt="Up"></a></td>
+<td><a accesskey="u" href="ch11.html"><img src="up.png" width="16" height="16" border="0" alt="Up"></a></td>
 <td><a accesskey="p" href="harfbuzz-hb-shape-plan.html"><img src="left.png" width="16" height="16" border="0" alt="Prev"></a></td>
 <td><a accesskey="n" href="harfbuzz-hb-unicode.html"><img src="right.png" width="16" height="16" border="0" alt="Next"></a></td>
 </tr></table>
@@ -82,16 +82,19 @@ contains the output glyphs and their positions.</p>
 <div class="refsect2">
 <a name="hb-shape"></a><h3>hb_shape ()</h3>
 <pre class="programlisting"><span class="returnvalue">void</span>
-hb_shape (<em class="parameter"><code><a class="link" href="harfbuzz-hb-font.html#hb-font-t" title="hb_font_t"><span class="type">hb_font_t</span></a> *font</code></em>,
-          <em class="parameter"><code><a class="link" href="harfbuzz-hb-buffer.html#hb-buffer-t" title="hb_buffer_t"><span class="type">hb_buffer_t</span></a> *buffer</code></em>,
-          <em class="parameter"><code>const <a class="link" href="harfbuzz-hb-common.html#hb-feature-t" title="hb_feature_t"><span class="type">hb_feature_t</span></a> *features</code></em>,
+hb_shape (<em class="parameter"><code><a class="link" href="harfbuzz-hb-font.html#hb-font-t"><span class="type">hb_font_t</span></a> *font</code></em>,
+          <em class="parameter"><code><a class="link" href="harfbuzz-hb-buffer.html#hb-buffer-t"><span class="type">hb_buffer_t</span></a> *buffer</code></em>,
+          <em class="parameter"><code>const <a class="link" href="harfbuzz-hb-common.html#hb-feature-t"><span class="type">hb_feature_t</span></a> *features</code></em>,
           <em class="parameter"><code>unsigned <span class="type">int</span> num_features</code></em>);</pre>
 <p>Shapes <em class="parameter"><code>buffer</code></em>
  using <em class="parameter"><code>font</code></em>
  turning its Unicode characters content to
 positioned glyphs. If <em class="parameter"><code>features</code></em>
- is not <a href="/usr/share/gtk-doc/html/glib/glib-Standard-Macros.html#NULL:CAPS"><code class="literal">NULL</code></a>, it will be used to control the
-features applied during shaping.</p>
+ is not <code class="literal">NULL</code>, it will be used to control the
+features applied during shaping. If two <em class="parameter"><code>features</code></em>
+ have the same tag but
+overlapping ranges the value of the feature with the higher index takes
+precedence.</p>
 <div class="refsect3">
 <a name="hb-shape.parameters"></a><h4>Parameters</h4>
 <div class="informaltable"><table class="informaltable" width="100%" border="0">
@@ -103,18 +106,18 @@ features applied during shaping.</p>
 <tbody>
 <tr>
 <td class="parameter_name"><p>font</p></td>
-<td class="parameter_description"><p>an <a class="link" href="harfbuzz-hb-font.html#hb-font-t" title="hb_font_t"><span class="type">hb_font_t</span></a> to use for shaping</p></td>
+<td class="parameter_description"><p>an <a class="link" href="harfbuzz-hb-font.html#hb-font-t"><span class="type">hb_font_t</span></a> to use for shaping</p></td>
 <td class="parameter_annotations"> </td>
 </tr>
 <tr>
 <td class="parameter_name"><p>buffer</p></td>
-<td class="parameter_description"><p>an <a class="link" href="harfbuzz-hb-buffer.html#hb-buffer-t" title="hb_buffer_t"><span class="type">hb_buffer_t</span></a> to shape</p></td>
+<td class="parameter_description"><p>an <a class="link" href="harfbuzz-hb-buffer.html#hb-buffer-t"><span class="type">hb_buffer_t</span></a> to shape</p></td>
 <td class="parameter_annotations"> </td>
 </tr>
 <tr>
 <td class="parameter_name"><p>features</p></td>
 <td class="parameter_description"><p>an array of user
-specified <a class="link" href="harfbuzz-hb-common.html#hb-feature-t" title="hb_feature_t"><span class="type">hb_feature_t</span></a> or <a href="/usr/share/gtk-doc/html/glib/glib-Standard-Macros.html#NULL:CAPS"><code class="literal">NULL</code></a>. </p></td>
+specified <a class="link" href="harfbuzz-hb-common.html#hb-feature-t"><span class="type">hb_feature_t</span></a> or <code class="literal">NULL</code>. </p></td>
 <td class="parameter_annotations"><span class="annotation">[<acronym title="Parameter points to an array of items."><span class="acronym">array</span></acronym> length=num_features][<acronym title="NULL is OK, both for passing and for returning."><span class="acronym">allow-none</span></acronym>]</span></td>
 </tr>
 <tr>
@@ -132,13 +135,13 @@ array</p></td>
 <div class="refsect2">
 <a name="hb-shape-full"></a><h3>hb_shape_full ()</h3>
 <pre class="programlisting"><a class="link" href="harfbuzz-hb-common.html#hb-bool-t" title="hb_bool_t"><span class="returnvalue">hb_bool_t</span></a>
-hb_shape_full (<em class="parameter"><code><a class="link" href="harfbuzz-hb-font.html#hb-font-t" title="hb_font_t"><span class="type">hb_font_t</span></a> *font</code></em>,
-               <em class="parameter"><code><a class="link" href="harfbuzz-hb-buffer.html#hb-buffer-t" title="hb_buffer_t"><span class="type">hb_buffer_t</span></a> *buffer</code></em>,
-               <em class="parameter"><code>const <a class="link" href="harfbuzz-hb-common.html#hb-feature-t" title="hb_feature_t"><span class="type">hb_feature_t</span></a> *features</code></em>,
+hb_shape_full (<em class="parameter"><code><a class="link" href="harfbuzz-hb-font.html#hb-font-t"><span class="type">hb_font_t</span></a> *font</code></em>,
+               <em class="parameter"><code><a class="link" href="harfbuzz-hb-buffer.html#hb-buffer-t"><span class="type">hb_buffer_t</span></a> *buffer</code></em>,
+               <em class="parameter"><code>const <a class="link" href="harfbuzz-hb-common.html#hb-feature-t"><span class="type">hb_feature_t</span></a> *features</code></em>,
                <em class="parameter"><code>unsigned <span class="type">int</span> num_features</code></em>,
                <em class="parameter"><code>const <span class="type">char</span> * const *shaper_list</code></em>);</pre>
 <p>See <a class="link" href="harfbuzz-hb-shape.html#hb-shape" title="hb_shape ()"><code class="function">hb_shape()</code></a> for details. If <em class="parameter"><code>shaper_list</code></em>
- is not <a href="/usr/share/gtk-doc/html/glib/glib-Standard-Macros.html#NULL:CAPS"><code class="literal">NULL</code></a>, the specified
+ is not <code class="literal">NULL</code>, the specified
 shapers will be used in the given order, otherwise the default shapers list
 will be used.</p>
 <div class="refsect3">
@@ -152,18 +155,18 @@ will be used.</p>
 <tbody>
 <tr>
 <td class="parameter_name"><p>font</p></td>
-<td class="parameter_description"><p>an <a class="link" href="harfbuzz-hb-font.html#hb-font-t" title="hb_font_t"><span class="type">hb_font_t</span></a> to use for shaping</p></td>
+<td class="parameter_description"><p>an <a class="link" href="harfbuzz-hb-font.html#hb-font-t"><span class="type">hb_font_t</span></a> to use for shaping</p></td>
 <td class="parameter_annotations"> </td>
 </tr>
 <tr>
 <td class="parameter_name"><p>buffer</p></td>
-<td class="parameter_description"><p>an <a class="link" href="harfbuzz-hb-buffer.html#hb-buffer-t" title="hb_buffer_t"><span class="type">hb_buffer_t</span></a> to shape</p></td>
+<td class="parameter_description"><p>an <a class="link" href="harfbuzz-hb-buffer.html#hb-buffer-t"><span class="type">hb_buffer_t</span></a> to shape</p></td>
 <td class="parameter_annotations"> </td>
 </tr>
 <tr>
 <td class="parameter_name"><p>features</p></td>
 <td class="parameter_description"><p>an array of user
-specified <a class="link" href="harfbuzz-hb-common.html#hb-feature-t" title="hb_feature_t"><span class="type">hb_feature_t</span></a> or <a href="/usr/share/gtk-doc/html/glib/glib-Standard-Macros.html#NULL:CAPS"><code class="literal">NULL</code></a>. </p></td>
+specified <a class="link" href="harfbuzz-hb-common.html#hb-feature-t"><span class="type">hb_feature_t</span></a> or <code class="literal">NULL</code>. </p></td>
 <td class="parameter_annotations"><span class="annotation">[<acronym title="Parameter points to an array of items."><span class="acronym">array</span></acronym> length=num_features][<acronym title="NULL is OK, both for passing and for returning."><span class="acronym">allow-none</span></acronym>]</span></td>
 </tr>
 <tr>
@@ -174,8 +177,8 @@ array</p></td>
 </tr>
 <tr>
 <td class="parameter_name"><p>shaper_list</p></td>
-<td class="parameter_description"><p>a <a href="/usr/share/gtk-doc/html/glib/glib-Standard-Macros.html#NULL:CAPS"><code class="literal">NULL</code></a>-terminated
-array of shapers to use or <a href="/usr/share/gtk-doc/html/glib/glib-Standard-Macros.html#NULL:CAPS"><code class="literal">NULL</code></a>. </p></td>
+<td class="parameter_description"><p>a <code class="literal">NULL</code>-terminated
+array of shapers to use or <code class="literal">NULL</code>. </p></td>
 <td class="parameter_annotations"><span class="annotation">[<acronym title="Parameter points to an array of items."><span class="acronym">array</span></acronym> zero-terminated=1][<acronym title="NULL is OK, both for passing and for returning."><span class="acronym">allow-none</span></acronym>]</span></td>
 </tr>
 </tbody>
index 51a72c6..2762f3c 100644 (file)
@@ -5,7 +5,7 @@
 <title>hb-unicode: HarfBuzz Manual</title>
 <meta name="generator" content="DocBook XSL Stylesheets Vsnapshot">
 <link rel="home" href="index.html" title="HarfBuzz Manual">
-<link rel="up" href="ch09.html" title="Core API">
+<link rel="up" href="ch11.html" title="Core API">
 <link rel="prev" href="harfbuzz-hb-shape.html" title="hb-shape">
 <link rel="next" href="harfbuzz-hb-version.html" title="hb-version">
 <meta name="generator" content="GTK-Doc V1.29 (XML mode)">
 <table class="navigation" id="top" width="100%" summary="Navigation header" cellpadding="2" cellspacing="5"><tr valign="middle">
 <td width="100%" align="left" class="shortcuts">
 <a href="#" class="shortcut">Top</a><span id="nav_description">  <span class="dim">|</span> 
-                  <a href="#harfbuzz-hb-unicode.description" class="shortcut">Description</a></span>
+                  <a href="#harfbuzz-hb-unicode.description" class="shortcut">Description</a></span><span id="nav_hierarchy">  <span class="dim">|</span> 
+                  <a href="#harfbuzz-hb-unicode.object-hierarchy" class="shortcut">Object Hierarchy</a></span>
 </td>
 <td><a accesskey="h" href="index.html"><img src="home.png" width="16" height="16" border="0" alt="Home"></a></td>
-<td><a accesskey="u" href="ch09.html"><img src="up.png" width="16" height="16" border="0" alt="Up"></a></td>
+<td><a accesskey="u" href="ch11.html"><img src="up.png" width="16" height="16" border="0" alt="Up"></a></td>
 <td><a accesskey="p" href="harfbuzz-hb-shape.html"><img src="left.png" width="16" height="16" border="0" alt="Prev"></a></td>
 <td><a accesskey="n" href="harfbuzz-hb-version.html"><img src="right.png" width="16" height="16" border="0" alt="Next"></a></td>
 </tr></table>
@@ -89,7 +90,7 @@
 </tr>
 <tr>
 <td class="function_type">
-<a class="link" href="harfbuzz-hb-unicode.html#hb-unicode-funcs-t" title="hb_unicode_funcs_t"><span class="returnvalue">hb_unicode_funcs_t</span></a> *
+<a class="link" href="harfbuzz-hb-unicode.html#hb-unicode-funcs-t"><span class="returnvalue">hb_unicode_funcs_t</span></a> *
 </td>
 <td class="function_name">
 <a class="link" href="harfbuzz-hb-unicode.html#hb-unicode-funcs-create" title="hb_unicode_funcs_create ()">hb_unicode_funcs_create</a> <span class="c_punctuation">()</span>
 </tr>
 <tr>
 <td class="function_type">
-<a class="link" href="harfbuzz-hb-unicode.html#hb-unicode-funcs-t" title="hb_unicode_funcs_t"><span class="returnvalue">hb_unicode_funcs_t</span></a> *
+<a class="link" href="harfbuzz-hb-unicode.html#hb-unicode-funcs-t"><span class="returnvalue">hb_unicode_funcs_t</span></a> *
 </td>
 <td class="function_name">
 <a class="link" href="harfbuzz-hb-unicode.html#hb-unicode-funcs-get-default" title="hb_unicode_funcs_get_default ()">hb_unicode_funcs_get_default</a> <span class="c_punctuation">()</span>
 </tr>
 <tr>
 <td class="function_type">
-<a class="link" href="harfbuzz-hb-unicode.html#hb-unicode-funcs-t" title="hb_unicode_funcs_t"><span class="returnvalue">hb_unicode_funcs_t</span></a> *
+<a class="link" href="harfbuzz-hb-unicode.html#hb-unicode-funcs-t"><span class="returnvalue">hb_unicode_funcs_t</span></a> *
 </td>
 <td class="function_name">
 <a class="link" href="harfbuzz-hb-unicode.html#hb-unicode-funcs-get-empty" title="hb_unicode_funcs_get_empty ()">hb_unicode_funcs_get_empty</a> <span class="c_punctuation">()</span>
 </tr>
 <tr>
 <td class="function_type">
-<a class="link" href="harfbuzz-hb-unicode.html#hb-unicode-funcs-t" title="hb_unicode_funcs_t"><span class="returnvalue">hb_unicode_funcs_t</span></a> *
+<a class="link" href="harfbuzz-hb-unicode.html#hb-unicode-funcs-t"><span class="returnvalue">hb_unicode_funcs_t</span></a> *
 </td>
 <td class="function_name">
 <a class="link" href="harfbuzz-hb-unicode.html#hb-unicode-funcs-get-parent" title="hb_unicode_funcs_get_parent ()">hb_unicode_funcs_get_parent</a> <span class="c_punctuation">()</span>
 </tr>
 <tr>
 <td class="function_type">
-<a class="link" href="harfbuzz-hb-unicode.html#hb-unicode-funcs-t" title="hb_unicode_funcs_t"><span class="returnvalue">hb_unicode_funcs_t</span></a> *
+<a class="link" href="harfbuzz-hb-unicode.html#hb-unicode-funcs-t"><span class="returnvalue">hb_unicode_funcs_t</span></a> *
 </td>
 <td class="function_name">
 <a class="link" href="harfbuzz-hb-unicode.html#hb-unicode-funcs-reference" title="hb_unicode_funcs_reference ()">hb_unicode_funcs_reference</a> <span class="c_punctuation">()</span>
 </tbody>
 </table></div>
 </div>
-<div class="refsect1">
+<a name="hb-unicode-funcs-t"></a><div class="refsect1">
 <a name="harfbuzz-hb-unicode.other"></a><h2>Types and Values</h2>
 <div class="informaltable"><table class="informaltable" width="100%" border="0">
 <colgroup>
 </tr>
 <tr>
 <td class="typedef_keyword">typedef</td>
-<td class="function_name"><a class="link" href="harfbuzz-hb-unicode.html#hb-unicode-funcs-t" title="hb_unicode_funcs_t">hb_unicode_funcs_t</a></td>
+<td class="function_name"><a class="link" href="harfbuzz-hb-unicode.html#hb-unicode-funcs-t">hb_unicode_funcs_t</a></td>
 </tr>
 <tr>
 <td class="datatype_keyword">enum</td>
 </table></div>
 </div>
 <div class="refsect1">
+<a name="harfbuzz-hb-unicode.object-hierarchy"></a><h2>Object Hierarchy</h2>
+<pre class="screen">    <a href="/usr/share/gtk-doc/html/gobject/gobject-Boxed-Types.html">GBoxed</a>
+    <span class="lineart">╰──</span> hb_unicode_funcs_t
+    <a href="/usr/share/gtk-doc/html/gobject/gobject-Enumeration-and-Flag-Types.html">GEnum</a>
+    <span class="lineart">├──</span> hb_unicode_combining_class_t
+    <span class="lineart">╰──</span> hb_unicode_general_category_t
+</pre>
+</div>
+<div class="refsect1">
 <a name="harfbuzz-hb-unicode.includes"></a><h2>Includes</h2>
 <pre class="synopsis">#include &lt;hb.h&gt;
 </pre>
@@ -311,7 +321,7 @@ properties, such as General Category, Script, Combining Class, etc.</p>
 <div class="refsect2">
 <a name="hb-unicode-combining-class"></a><h3>hb_unicode_combining_class ()</h3>
 <pre class="programlisting"><a class="link" href="harfbuzz-hb-unicode.html#hb-unicode-combining-class-t" title="enum hb_unicode_combining_class_t"><span class="returnvalue">hb_unicode_combining_class_t</span></a>
-hb_unicode_combining_class (<em class="parameter"><code><a class="link" href="harfbuzz-hb-unicode.html#hb-unicode-funcs-t" title="hb_unicode_funcs_t"><span class="type">hb_unicode_funcs_t</span></a> *ufuncs</code></em>,
+hb_unicode_combining_class (<em class="parameter"><code><a class="link" href="harfbuzz-hb-unicode.html#hb-unicode-funcs-t"><span class="type">hb_unicode_funcs_t</span></a> *ufuncs</code></em>,
                             <em class="parameter"><code><a class="link" href="harfbuzz-hb-common.html#hb-codepoint-t" title="hb_codepoint_t"><span class="type">hb_codepoint_t</span></a> unicode</code></em>);</pre>
 <p class="since">Since: <a class="link" href="api-index-0-9-2.html#api-index-0.9.2">0.9.2</a></p>
 </div>
@@ -319,7 +329,7 @@ hb_unicode_combining_class (<em class="parameter"><code><a class="link" href="ha
 <div class="refsect2">
 <a name="hb-unicode-combining-class-func-t"></a><h3>hb_unicode_combining_class_func_t ()</h3>
 <pre class="programlisting"><a class="link" href="harfbuzz-hb-unicode.html#hb-unicode-combining-class-t" title="enum hb_unicode_combining_class_t"><span class="returnvalue">hb_unicode_combining_class_t</span></a>
-<span class="c_punctuation">(</span>*hb_unicode_combining_class_func_t<span class="c_punctuation">)</span> (<em class="parameter"><code><a class="link" href="harfbuzz-hb-unicode.html#hb-unicode-funcs-t" title="hb_unicode_funcs_t"><span class="type">hb_unicode_funcs_t</span></a> *ufuncs</code></em>,
+<span class="c_punctuation">(</span>*hb_unicode_combining_class_func_t<span class="c_punctuation">)</span> (<em class="parameter"><code><a class="link" href="harfbuzz-hb-unicode.html#hb-unicode-funcs-t"><span class="type">hb_unicode_funcs_t</span></a> *ufuncs</code></em>,
                                       <em class="parameter"><code><a class="link" href="harfbuzz-hb-common.html#hb-codepoint-t" title="hb_codepoint_t"><span class="type">hb_codepoint_t</span></a> unicode</code></em>,
                                       <em class="parameter"><code><span class="type">void</span> *user_data</code></em>);</pre>
 </div>
@@ -327,7 +337,7 @@ hb_unicode_combining_class (<em class="parameter"><code><a class="link" href="ha
 <div class="refsect2">
 <a name="hb-unicode-compose"></a><h3>hb_unicode_compose ()</h3>
 <pre class="programlisting"><a class="link" href="harfbuzz-hb-common.html#hb-bool-t" title="hb_bool_t"><span class="returnvalue">hb_bool_t</span></a>
-hb_unicode_compose (<em class="parameter"><code><a class="link" href="harfbuzz-hb-unicode.html#hb-unicode-funcs-t" title="hb_unicode_funcs_t"><span class="type">hb_unicode_funcs_t</span></a> *ufuncs</code></em>,
+hb_unicode_compose (<em class="parameter"><code><a class="link" href="harfbuzz-hb-unicode.html#hb-unicode-funcs-t"><span class="type">hb_unicode_funcs_t</span></a> *ufuncs</code></em>,
                     <em class="parameter"><code><a class="link" href="harfbuzz-hb-common.html#hb-codepoint-t" title="hb_codepoint_t"><span class="type">hb_codepoint_t</span></a> a</code></em>,
                     <em class="parameter"><code><a class="link" href="harfbuzz-hb-common.html#hb-codepoint-t" title="hb_codepoint_t"><span class="type">hb_codepoint_t</span></a> b</code></em>,
                     <em class="parameter"><code><a class="link" href="harfbuzz-hb-common.html#hb-codepoint-t" title="hb_codepoint_t"><span class="type">hb_codepoint_t</span></a> *ab</code></em>);</pre>
@@ -359,7 +369,7 @@ hb_unicode_compose (<em class="parameter"><code><a class="link" href="harfbuzz-h
 <div class="refsect2">
 <a name="hb-unicode-compose-func-t"></a><h3>hb_unicode_compose_func_t ()</h3>
 <pre class="programlisting"><a class="link" href="harfbuzz-hb-common.html#hb-bool-t" title="hb_bool_t"><span class="returnvalue">hb_bool_t</span></a>
-<span class="c_punctuation">(</span>*hb_unicode_compose_func_t<span class="c_punctuation">)</span> (<em class="parameter"><code><a class="link" href="harfbuzz-hb-unicode.html#hb-unicode-funcs-t" title="hb_unicode_funcs_t"><span class="type">hb_unicode_funcs_t</span></a> *ufuncs</code></em>,
+<span class="c_punctuation">(</span>*hb_unicode_compose_func_t<span class="c_punctuation">)</span> (<em class="parameter"><code><a class="link" href="harfbuzz-hb-unicode.html#hb-unicode-funcs-t"><span class="type">hb_unicode_funcs_t</span></a> *ufuncs</code></em>,
                               <em class="parameter"><code><a class="link" href="harfbuzz-hb-common.html#hb-codepoint-t" title="hb_codepoint_t"><span class="type">hb_codepoint_t</span></a> a</code></em>,
                               <em class="parameter"><code><a class="link" href="harfbuzz-hb-common.html#hb-codepoint-t" title="hb_codepoint_t"><span class="type">hb_codepoint_t</span></a> b</code></em>,
                               <em class="parameter"><code><a class="link" href="harfbuzz-hb-common.html#hb-codepoint-t" title="hb_codepoint_t"><span class="type">hb_codepoint_t</span></a> *ab</code></em>,
@@ -369,7 +379,7 @@ hb_unicode_compose (<em class="parameter"><code><a class="link" href="harfbuzz-h
 <div class="refsect2">
 <a name="hb-unicode-decompose"></a><h3>hb_unicode_decompose ()</h3>
 <pre class="programlisting"><a class="link" href="harfbuzz-hb-common.html#hb-bool-t" title="hb_bool_t"><span class="returnvalue">hb_bool_t</span></a>
-hb_unicode_decompose (<em class="parameter"><code><a class="link" href="harfbuzz-hb-unicode.html#hb-unicode-funcs-t" title="hb_unicode_funcs_t"><span class="type">hb_unicode_funcs_t</span></a> *ufuncs</code></em>,
+hb_unicode_decompose (<em class="parameter"><code><a class="link" href="harfbuzz-hb-unicode.html#hb-unicode-funcs-t"><span class="type">hb_unicode_funcs_t</span></a> *ufuncs</code></em>,
                       <em class="parameter"><code><a class="link" href="harfbuzz-hb-common.html#hb-codepoint-t" title="hb_codepoint_t"><span class="type">hb_codepoint_t</span></a> ab</code></em>,
                       <em class="parameter"><code><a class="link" href="harfbuzz-hb-common.html#hb-codepoint-t" title="hb_codepoint_t"><span class="type">hb_codepoint_t</span></a> *a</code></em>,
                       <em class="parameter"><code><a class="link" href="harfbuzz-hb-common.html#hb-codepoint-t" title="hb_codepoint_t"><span class="type">hb_codepoint_t</span></a> *b</code></em>);</pre>
@@ -406,7 +416,7 @@ hb_unicode_decompose (<em class="parameter"><code><a class="link" href="harfbuzz
 <div class="refsect2">
 <a name="hb-unicode-decompose-func-t"></a><h3>hb_unicode_decompose_func_t ()</h3>
 <pre class="programlisting"><a class="link" href="harfbuzz-hb-common.html#hb-bool-t" title="hb_bool_t"><span class="returnvalue">hb_bool_t</span></a>
-<span class="c_punctuation">(</span>*hb_unicode_decompose_func_t<span class="c_punctuation">)</span> (<em class="parameter"><code><a class="link" href="harfbuzz-hb-unicode.html#hb-unicode-funcs-t" title="hb_unicode_funcs_t"><span class="type">hb_unicode_funcs_t</span></a> *ufuncs</code></em>,
+<span class="c_punctuation">(</span>*hb_unicode_decompose_func_t<span class="c_punctuation">)</span> (<em class="parameter"><code><a class="link" href="harfbuzz-hb-unicode.html#hb-unicode-funcs-t"><span class="type">hb_unicode_funcs_t</span></a> *ufuncs</code></em>,
                                 <em class="parameter"><code><a class="link" href="harfbuzz-hb-common.html#hb-codepoint-t" title="hb_codepoint_t"><span class="type">hb_codepoint_t</span></a> ab</code></em>,
                                 <em class="parameter"><code><a class="link" href="harfbuzz-hb-common.html#hb-codepoint-t" title="hb_codepoint_t"><span class="type">hb_codepoint_t</span></a> *a</code></em>,
                                 <em class="parameter"><code><a class="link" href="harfbuzz-hb-common.html#hb-codepoint-t" title="hb_codepoint_t"><span class="type">hb_codepoint_t</span></a> *b</code></em>,
@@ -415,8 +425,8 @@ hb_unicode_decompose (<em class="parameter"><code><a class="link" href="harfbuzz
 <hr>
 <div class="refsect2">
 <a name="hb-unicode-funcs-create"></a><h3>hb_unicode_funcs_create ()</h3>
-<pre class="programlisting"><a class="link" href="harfbuzz-hb-unicode.html#hb-unicode-funcs-t" title="hb_unicode_funcs_t"><span class="returnvalue">hb_unicode_funcs_t</span></a> *
-hb_unicode_funcs_create (<em class="parameter"><code><a class="link" href="harfbuzz-hb-unicode.html#hb-unicode-funcs-t" title="hb_unicode_funcs_t"><span class="type">hb_unicode_funcs_t</span></a> *parent</code></em>);</pre>
+<pre class="programlisting"><a class="link" href="harfbuzz-hb-unicode.html#hb-unicode-funcs-t"><span class="returnvalue">hb_unicode_funcs_t</span></a> *
+hb_unicode_funcs_create (<em class="parameter"><code><a class="link" href="harfbuzz-hb-unicode.html#hb-unicode-funcs-t"><span class="type">hb_unicode_funcs_t</span></a> *parent</code></em>);</pre>
 <p><span class="annotation">[Xconstructor]</span></p>
 <div class="refsect3">
 <a name="hb-unicode-funcs-create.parameters"></a><h4>Parameters</h4>
@@ -444,7 +454,7 @@ hb_unicode_funcs_create (<em class="parameter"><code><a class="link" href="harfb
 <div class="refsect2">
 <a name="hb-unicode-funcs-destroy"></a><h3>hb_unicode_funcs_destroy ()</h3>
 <pre class="programlisting"><span class="returnvalue">void</span>
-hb_unicode_funcs_destroy (<em class="parameter"><code><a class="link" href="harfbuzz-hb-unicode.html#hb-unicode-funcs-t" title="hb_unicode_funcs_t"><span class="type">hb_unicode_funcs_t</span></a> *ufuncs</code></em>);</pre>
+hb_unicode_funcs_destroy (<em class="parameter"><code><a class="link" href="harfbuzz-hb-unicode.html#hb-unicode-funcs-t"><span class="type">hb_unicode_funcs_t</span></a> *ufuncs</code></em>);</pre>
 <p><span class="annotation">[<acronym title="Exposed in C code, not necessarily available in other languages."><span class="acronym">skip</span></acronym>]</span></p>
 <div class="refsect3">
 <a name="hb-unicode-funcs-destroy.parameters"></a><h4>Parameters</h4>
@@ -466,13 +476,13 @@ hb_unicode_funcs_destroy (<em class="parameter"><code><a class="link" href="harf
 <hr>
 <div class="refsect2">
 <a name="hb-unicode-funcs-get-default"></a><h3>hb_unicode_funcs_get_default ()</h3>
-<pre class="programlisting"><a class="link" href="harfbuzz-hb-unicode.html#hb-unicode-funcs-t" title="hb_unicode_funcs_t"><span class="returnvalue">hb_unicode_funcs_t</span></a> *
+<pre class="programlisting"><a class="link" href="harfbuzz-hb-unicode.html#hb-unicode-funcs-t"><span class="returnvalue">hb_unicode_funcs_t</span></a> *
 hb_unicode_funcs_get_default (<em class="parameter"><code><span class="type">void</span></code></em>);</pre>
 </div>
 <hr>
 <div class="refsect2">
 <a name="hb-unicode-funcs-get-empty"></a><h3>hb_unicode_funcs_get_empty ()</h3>
-<pre class="programlisting"><a class="link" href="harfbuzz-hb-unicode.html#hb-unicode-funcs-t" title="hb_unicode_funcs_t"><span class="returnvalue">hb_unicode_funcs_t</span></a> *
+<pre class="programlisting"><a class="link" href="harfbuzz-hb-unicode.html#hb-unicode-funcs-t"><span class="returnvalue">hb_unicode_funcs_t</span></a> *
 hb_unicode_funcs_get_empty (<em class="parameter"><code><span class="type">void</span></code></em>);</pre>
 <div class="refsect3">
 <a name="hb-unicode-funcs-get-empty.returns"></a><h4>Returns</h4>
@@ -484,8 +494,8 @@ hb_unicode_funcs_get_empty (<em class="parameter"><code><span class="type">void<
 <hr>
 <div class="refsect2">
 <a name="hb-unicode-funcs-get-parent"></a><h3>hb_unicode_funcs_get_parent ()</h3>
-<pre class="programlisting"><a class="link" href="harfbuzz-hb-unicode.html#hb-unicode-funcs-t" title="hb_unicode_funcs_t"><span class="returnvalue">hb_unicode_funcs_t</span></a> *
-hb_unicode_funcs_get_parent (<em class="parameter"><code><a class="link" href="harfbuzz-hb-unicode.html#hb-unicode-funcs-t" title="hb_unicode_funcs_t"><span class="type">hb_unicode_funcs_t</span></a> *ufuncs</code></em>);</pre>
+<pre class="programlisting"><a class="link" href="harfbuzz-hb-unicode.html#hb-unicode-funcs-t"><span class="returnvalue">hb_unicode_funcs_t</span></a> *
+hb_unicode_funcs_get_parent (<em class="parameter"><code><a class="link" href="harfbuzz-hb-unicode.html#hb-unicode-funcs-t"><span class="type">hb_unicode_funcs_t</span></a> *ufuncs</code></em>);</pre>
 <div class="refsect3">
 <a name="hb-unicode-funcs-get-parent.parameters"></a><h4>Parameters</h4>
 <div class="informaltable"><table class="informaltable" width="100%" border="0">
@@ -507,8 +517,8 @@ hb_unicode_funcs_get_parent (<em class="parameter"><code><a class="link" href="h
 <div class="refsect2">
 <a name="hb-unicode-funcs-get-user-data"></a><h3>hb_unicode_funcs_get_user_data ()</h3>
 <pre class="programlisting"><span class="returnvalue">void</span> *
-hb_unicode_funcs_get_user_data (<em class="parameter"><code><a class="link" href="harfbuzz-hb-unicode.html#hb-unicode-funcs-t" title="hb_unicode_funcs_t"><span class="type">hb_unicode_funcs_t</span></a> *ufuncs</code></em>,
-                                <em class="parameter"><code><a class="link" href="harfbuzz-hb-common.html#hb-user-data-key-t" title="hb_user_data_key_t"><span class="type">hb_user_data_key_t</span></a> *key</code></em>);</pre>
+hb_unicode_funcs_get_user_data (<em class="parameter"><code><a class="link" href="harfbuzz-hb-unicode.html#hb-unicode-funcs-t"><span class="type">hb_unicode_funcs_t</span></a> *ufuncs</code></em>,
+                                <em class="parameter"><code><a class="link" href="harfbuzz-hb-common.html#hb-user-data-key-t"><span class="type">hb_user_data_key_t</span></a> *key</code></em>);</pre>
 <p><span class="annotation">[<acronym title="Exposed in C code, not necessarily available in other languages."><span class="acronym">skip</span></acronym>]</span></p>
 <div class="refsect3">
 <a name="hb-unicode-funcs-get-user-data.parameters"></a><h4>Parameters</h4>
@@ -536,7 +546,7 @@ hb_unicode_funcs_get_user_data (<em class="parameter"><code><a class="link" href
 <div class="refsect2">
 <a name="hb-unicode-funcs-is-immutable"></a><h3>hb_unicode_funcs_is_immutable ()</h3>
 <pre class="programlisting"><a class="link" href="harfbuzz-hb-common.html#hb-bool-t" title="hb_bool_t"><span class="returnvalue">hb_bool_t</span></a>
-hb_unicode_funcs_is_immutable (<em class="parameter"><code><a class="link" href="harfbuzz-hb-unicode.html#hb-unicode-funcs-t" title="hb_unicode_funcs_t"><span class="type">hb_unicode_funcs_t</span></a> *ufuncs</code></em>);</pre>
+hb_unicode_funcs_is_immutable (<em class="parameter"><code><a class="link" href="harfbuzz-hb-unicode.html#hb-unicode-funcs-t"><span class="type">hb_unicode_funcs_t</span></a> *ufuncs</code></em>);</pre>
 <div class="refsect3">
 <a name="hb-unicode-funcs-is-immutable.parameters"></a><h4>Parameters</h4>
 <div class="informaltable"><table class="informaltable" width="100%" border="0">
@@ -558,7 +568,7 @@ hb_unicode_funcs_is_immutable (<em class="parameter"><code><a class="link" href=
 <div class="refsect2">
 <a name="hb-unicode-funcs-make-immutable"></a><h3>hb_unicode_funcs_make_immutable ()</h3>
 <pre class="programlisting"><span class="returnvalue">void</span>
-hb_unicode_funcs_make_immutable (<em class="parameter"><code><a class="link" href="harfbuzz-hb-unicode.html#hb-unicode-funcs-t" title="hb_unicode_funcs_t"><span class="type">hb_unicode_funcs_t</span></a> *ufuncs</code></em>);</pre>
+hb_unicode_funcs_make_immutable (<em class="parameter"><code><a class="link" href="harfbuzz-hb-unicode.html#hb-unicode-funcs-t"><span class="type">hb_unicode_funcs_t</span></a> *ufuncs</code></em>);</pre>
 <div class="refsect3">
 <a name="hb-unicode-funcs-make-immutable.parameters"></a><h4>Parameters</h4>
 <div class="informaltable"><table class="informaltable" width="100%" border="0">
@@ -579,8 +589,8 @@ hb_unicode_funcs_make_immutable (<em class="parameter"><code><a class="link" hre
 <hr>
 <div class="refsect2">
 <a name="hb-unicode-funcs-reference"></a><h3>hb_unicode_funcs_reference ()</h3>
-<pre class="programlisting"><a class="link" href="harfbuzz-hb-unicode.html#hb-unicode-funcs-t" title="hb_unicode_funcs_t"><span class="returnvalue">hb_unicode_funcs_t</span></a> *
-hb_unicode_funcs_reference (<em class="parameter"><code><a class="link" href="harfbuzz-hb-unicode.html#hb-unicode-funcs-t" title="hb_unicode_funcs_t"><span class="type">hb_unicode_funcs_t</span></a> *ufuncs</code></em>);</pre>
+<pre class="programlisting"><a class="link" href="harfbuzz-hb-unicode.html#hb-unicode-funcs-t"><span class="returnvalue">hb_unicode_funcs_t</span></a> *
+hb_unicode_funcs_reference (<em class="parameter"><code><a class="link" href="harfbuzz-hb-unicode.html#hb-unicode-funcs-t"><span class="type">hb_unicode_funcs_t</span></a> *ufuncs</code></em>);</pre>
 <p><span class="annotation">[<acronym title="Exposed in C code, not necessarily available in other languages."><span class="acronym">skip</span></acronym>]</span></p>
 <div class="refsect3">
 <a name="hb-unicode-funcs-reference.parameters"></a><h4>Parameters</h4>
@@ -609,7 +619,7 @@ hb_unicode_funcs_reference (<em class="parameter"><code><a class="link" href="ha
 <a name="hb-unicode-funcs-set-combining-class-func"></a><h3>hb_unicode_funcs_set_combining_class_func ()</h3>
 <pre class="programlisting"><span class="returnvalue">void</span>
 hb_unicode_funcs_set_combining_class_func
-                               (<em class="parameter"><code><a class="link" href="harfbuzz-hb-unicode.html#hb-unicode-funcs-t" title="hb_unicode_funcs_t"><span class="type">hb_unicode_funcs_t</span></a> *ufuncs</code></em>,
+                               (<em class="parameter"><code><a class="link" href="harfbuzz-hb-unicode.html#hb-unicode-funcs-t"><span class="type">hb_unicode_funcs_t</span></a> *ufuncs</code></em>,
                                 <em class="parameter"><code><a class="link" href="harfbuzz-hb-unicode.html#hb-unicode-combining-class-func-t" title="hb_unicode_combining_class_func_t ()"><span class="type">hb_unicode_combining_class_func_t</span></a> func</code></em>,
                                 <em class="parameter"><code><span class="type">void</span> *user_data</code></em>,
                                 <em class="parameter"><code><a class="link" href="harfbuzz-hb-common.html#hb-destroy-func-t" title="hb_destroy_func_t ()"><span class="type">hb_destroy_func_t</span></a> destroy</code></em>);</pre>
@@ -641,7 +651,7 @@ hb_unicode_funcs_set_combining_class_func
 <div class="refsect2">
 <a name="hb-unicode-funcs-set-compose-func"></a><h3>hb_unicode_funcs_set_compose_func ()</h3>
 <pre class="programlisting"><span class="returnvalue">void</span>
-hb_unicode_funcs_set_compose_func (<em class="parameter"><code><a class="link" href="harfbuzz-hb-unicode.html#hb-unicode-funcs-t" title="hb_unicode_funcs_t"><span class="type">hb_unicode_funcs_t</span></a> *ufuncs</code></em>,
+hb_unicode_funcs_set_compose_func (<em class="parameter"><code><a class="link" href="harfbuzz-hb-unicode.html#hb-unicode-funcs-t"><span class="type">hb_unicode_funcs_t</span></a> *ufuncs</code></em>,
                                    <em class="parameter"><code><a class="link" href="harfbuzz-hb-unicode.html#hb-unicode-compose-func-t" title="hb_unicode_compose_func_t ()"><span class="type">hb_unicode_compose_func_t</span></a> func</code></em>,
                                    <em class="parameter"><code><span class="type">void</span> *user_data</code></em>,
                                    <em class="parameter"><code><a class="link" href="harfbuzz-hb-common.html#hb-destroy-func-t" title="hb_destroy_func_t ()"><span class="type">hb_destroy_func_t</span></a> destroy</code></em>);</pre>
@@ -673,7 +683,7 @@ hb_unicode_funcs_set_compose_func (<em class="parameter"><code><a class="link" h
 <div class="refsect2">
 <a name="hb-unicode-funcs-set-decompose-func"></a><h3>hb_unicode_funcs_set_decompose_func ()</h3>
 <pre class="programlisting"><span class="returnvalue">void</span>
-hb_unicode_funcs_set_decompose_func (<em class="parameter"><code><a class="link" href="harfbuzz-hb-unicode.html#hb-unicode-funcs-t" title="hb_unicode_funcs_t"><span class="type">hb_unicode_funcs_t</span></a> *ufuncs</code></em>,
+hb_unicode_funcs_set_decompose_func (<em class="parameter"><code><a class="link" href="harfbuzz-hb-unicode.html#hb-unicode-funcs-t"><span class="type">hb_unicode_funcs_t</span></a> *ufuncs</code></em>,
                                      <em class="parameter"><code><a class="link" href="harfbuzz-hb-unicode.html#hb-unicode-decompose-func-t" title="hb_unicode_decompose_func_t ()"><span class="type">hb_unicode_decompose_func_t</span></a> func</code></em>,
                                      <em class="parameter"><code><span class="type">void</span> *user_data</code></em>,
                                      <em class="parameter"><code><a class="link" href="harfbuzz-hb-common.html#hb-destroy-func-t" title="hb_destroy_func_t ()"><span class="type">hb_destroy_func_t</span></a> destroy</code></em>);</pre>
@@ -706,7 +716,7 @@ hb_unicode_funcs_set_decompose_func (<em class="parameter"><code><a class="link"
 <a name="hb-unicode-funcs-set-general-category-func"></a><h3>hb_unicode_funcs_set_general_category_func ()</h3>
 <pre class="programlisting"><span class="returnvalue">void</span>
 hb_unicode_funcs_set_general_category_func
-                               (<em class="parameter"><code><a class="link" href="harfbuzz-hb-unicode.html#hb-unicode-funcs-t" title="hb_unicode_funcs_t"><span class="type">hb_unicode_funcs_t</span></a> *ufuncs</code></em>,
+                               (<em class="parameter"><code><a class="link" href="harfbuzz-hb-unicode.html#hb-unicode-funcs-t"><span class="type">hb_unicode_funcs_t</span></a> *ufuncs</code></em>,
                                 <em class="parameter"><code><a class="link" href="harfbuzz-hb-unicode.html#hb-unicode-general-category-func-t" title="hb_unicode_general_category_func_t ()"><span class="type">hb_unicode_general_category_func_t</span></a> func</code></em>,
                                 <em class="parameter"><code><span class="type">void</span> *user_data</code></em>,
                                 <em class="parameter"><code><a class="link" href="harfbuzz-hb-common.html#hb-destroy-func-t" title="hb_destroy_func_t ()"><span class="type">hb_destroy_func_t</span></a> destroy</code></em>);</pre>
@@ -738,7 +748,7 @@ hb_unicode_funcs_set_general_category_func
 <div class="refsect2">
 <a name="hb-unicode-funcs-set-mirroring-func"></a><h3>hb_unicode_funcs_set_mirroring_func ()</h3>
 <pre class="programlisting"><span class="returnvalue">void</span>
-hb_unicode_funcs_set_mirroring_func (<em class="parameter"><code><a class="link" href="harfbuzz-hb-unicode.html#hb-unicode-funcs-t" title="hb_unicode_funcs_t"><span class="type">hb_unicode_funcs_t</span></a> *ufuncs</code></em>,
+hb_unicode_funcs_set_mirroring_func (<em class="parameter"><code><a class="link" href="harfbuzz-hb-unicode.html#hb-unicode-funcs-t"><span class="type">hb_unicode_funcs_t</span></a> *ufuncs</code></em>,
                                      <em class="parameter"><code><a class="link" href="harfbuzz-hb-unicode.html#hb-unicode-mirroring-func-t" title="hb_unicode_mirroring_func_t ()"><span class="type">hb_unicode_mirroring_func_t</span></a> func</code></em>,
                                      <em class="parameter"><code><span class="type">void</span> *user_data</code></em>,
                                      <em class="parameter"><code><a class="link" href="harfbuzz-hb-common.html#hb-destroy-func-t" title="hb_destroy_func_t ()"><span class="type">hb_destroy_func_t</span></a> destroy</code></em>);</pre>
@@ -770,7 +780,7 @@ hb_unicode_funcs_set_mirroring_func (<em class="parameter"><code><a class="link"
 <div class="refsect2">
 <a name="hb-unicode-funcs-set-script-func"></a><h3>hb_unicode_funcs_set_script_func ()</h3>
 <pre class="programlisting"><span class="returnvalue">void</span>
-hb_unicode_funcs_set_script_func (<em class="parameter"><code><a class="link" href="harfbuzz-hb-unicode.html#hb-unicode-funcs-t" title="hb_unicode_funcs_t"><span class="type">hb_unicode_funcs_t</span></a> *ufuncs</code></em>,
+hb_unicode_funcs_set_script_func (<em class="parameter"><code><a class="link" href="harfbuzz-hb-unicode.html#hb-unicode-funcs-t"><span class="type">hb_unicode_funcs_t</span></a> *ufuncs</code></em>,
                                   <em class="parameter"><code><a class="link" href="harfbuzz-hb-unicode.html#hb-unicode-script-func-t" title="hb_unicode_script_func_t ()"><span class="type">hb_unicode_script_func_t</span></a> func</code></em>,
                                   <em class="parameter"><code><span class="type">void</span> *user_data</code></em>,
                                   <em class="parameter"><code><a class="link" href="harfbuzz-hb-common.html#hb-destroy-func-t" title="hb_destroy_func_t ()"><span class="type">hb_destroy_func_t</span></a> destroy</code></em>);</pre>
@@ -802,8 +812,8 @@ hb_unicode_funcs_set_script_func (<em class="parameter"><code><a class="link" hr
 <div class="refsect2">
 <a name="hb-unicode-funcs-set-user-data"></a><h3>hb_unicode_funcs_set_user_data ()</h3>
 <pre class="programlisting"><a class="link" href="harfbuzz-hb-common.html#hb-bool-t" title="hb_bool_t"><span class="returnvalue">hb_bool_t</span></a>
-hb_unicode_funcs_set_user_data (<em class="parameter"><code><a class="link" href="harfbuzz-hb-unicode.html#hb-unicode-funcs-t" title="hb_unicode_funcs_t"><span class="type">hb_unicode_funcs_t</span></a> *ufuncs</code></em>,
-                                <em class="parameter"><code><a class="link" href="harfbuzz-hb-common.html#hb-user-data-key-t" title="hb_user_data_key_t"><span class="type">hb_user_data_key_t</span></a> *key</code></em>,
+hb_unicode_funcs_set_user_data (<em class="parameter"><code><a class="link" href="harfbuzz-hb-unicode.html#hb-unicode-funcs-t"><span class="type">hb_unicode_funcs_t</span></a> *ufuncs</code></em>,
+                                <em class="parameter"><code><a class="link" href="harfbuzz-hb-common.html#hb-user-data-key-t"><span class="type">hb_user_data_key_t</span></a> *key</code></em>,
                                 <em class="parameter"><code><span class="type">void</span> *data</code></em>,
                                 <em class="parameter"><code><a class="link" href="harfbuzz-hb-common.html#hb-destroy-func-t" title="hb_destroy_func_t ()"><span class="type">hb_destroy_func_t</span></a> destroy</code></em>,
                                 <em class="parameter"><code><a class="link" href="harfbuzz-hb-common.html#hb-bool-t" title="hb_bool_t"><span class="type">hb_bool_t</span></a> replace</code></em>);</pre>
@@ -829,7 +839,7 @@ hb_unicode_funcs_set_user_data (<em class="parameter"><code><a class="link" href
 <div class="refsect2">
 <a name="hb-unicode-general-category"></a><h3>hb_unicode_general_category ()</h3>
 <pre class="programlisting"><a class="link" href="harfbuzz-hb-unicode.html#hb-unicode-general-category-t" title="enum hb_unicode_general_category_t"><span class="returnvalue">hb_unicode_general_category_t</span></a>
-hb_unicode_general_category (<em class="parameter"><code><a class="link" href="harfbuzz-hb-unicode.html#hb-unicode-funcs-t" title="hb_unicode_funcs_t"><span class="type">hb_unicode_funcs_t</span></a> *ufuncs</code></em>,
+hb_unicode_general_category (<em class="parameter"><code><a class="link" href="harfbuzz-hb-unicode.html#hb-unicode-funcs-t"><span class="type">hb_unicode_funcs_t</span></a> *ufuncs</code></em>,
                              <em class="parameter"><code><a class="link" href="harfbuzz-hb-common.html#hb-codepoint-t" title="hb_codepoint_t"><span class="type">hb_codepoint_t</span></a> unicode</code></em>);</pre>
 <p class="since">Since: <a class="link" href="api-index-0-9-2.html#api-index-0.9.2">0.9.2</a></p>
 </div>
@@ -837,7 +847,7 @@ hb_unicode_general_category (<em class="parameter"><code><a class="link" href="h
 <div class="refsect2">
 <a name="hb-unicode-general-category-func-t"></a><h3>hb_unicode_general_category_func_t ()</h3>
 <pre class="programlisting"><a class="link" href="harfbuzz-hb-unicode.html#hb-unicode-general-category-t" title="enum hb_unicode_general_category_t"><span class="returnvalue">hb_unicode_general_category_t</span></a>
-<span class="c_punctuation">(</span>*hb_unicode_general_category_func_t<span class="c_punctuation">)</span> (<em class="parameter"><code><a class="link" href="harfbuzz-hb-unicode.html#hb-unicode-funcs-t" title="hb_unicode_funcs_t"><span class="type">hb_unicode_funcs_t</span></a> *ufuncs</code></em>,
+<span class="c_punctuation">(</span>*hb_unicode_general_category_func_t<span class="c_punctuation">)</span> (<em class="parameter"><code><a class="link" href="harfbuzz-hb-unicode.html#hb-unicode-funcs-t"><span class="type">hb_unicode_funcs_t</span></a> *ufuncs</code></em>,
                                        <em class="parameter"><code><a class="link" href="harfbuzz-hb-common.html#hb-codepoint-t" title="hb_codepoint_t"><span class="type">hb_codepoint_t</span></a> unicode</code></em>,
                                        <em class="parameter"><code><span class="type">void</span> *user_data</code></em>);</pre>
 </div>
@@ -845,7 +855,7 @@ hb_unicode_general_category (<em class="parameter"><code><a class="link" href="h
 <div class="refsect2">
 <a name="hb-unicode-mirroring"></a><h3>hb_unicode_mirroring ()</h3>
 <pre class="programlisting"><a class="link" href="harfbuzz-hb-common.html#hb-codepoint-t" title="hb_codepoint_t"><span class="returnvalue">hb_codepoint_t</span></a>
-hb_unicode_mirroring (<em class="parameter"><code><a class="link" href="harfbuzz-hb-unicode.html#hb-unicode-funcs-t" title="hb_unicode_funcs_t"><span class="type">hb_unicode_funcs_t</span></a> *ufuncs</code></em>,
+hb_unicode_mirroring (<em class="parameter"><code><a class="link" href="harfbuzz-hb-unicode.html#hb-unicode-funcs-t"><span class="type">hb_unicode_funcs_t</span></a> *ufuncs</code></em>,
                       <em class="parameter"><code><a class="link" href="harfbuzz-hb-common.html#hb-codepoint-t" title="hb_codepoint_t"><span class="type">hb_codepoint_t</span></a> unicode</code></em>);</pre>
 <p class="since">Since: <a class="link" href="api-index-0-9-2.html#api-index-0.9.2">0.9.2</a></p>
 </div>
@@ -853,7 +863,7 @@ hb_unicode_mirroring (<em class="parameter"><code><a class="link" href="harfbuzz
 <div class="refsect2">
 <a name="hb-unicode-mirroring-func-t"></a><h3>hb_unicode_mirroring_func_t ()</h3>
 <pre class="programlisting"><a class="link" href="harfbuzz-hb-common.html#hb-codepoint-t" title="hb_codepoint_t"><span class="returnvalue">hb_codepoint_t</span></a>
-<span class="c_punctuation">(</span>*hb_unicode_mirroring_func_t<span class="c_punctuation">)</span> (<em class="parameter"><code><a class="link" href="harfbuzz-hb-unicode.html#hb-unicode-funcs-t" title="hb_unicode_funcs_t"><span class="type">hb_unicode_funcs_t</span></a> *ufuncs</code></em>,
+<span class="c_punctuation">(</span>*hb_unicode_mirroring_func_t<span class="c_punctuation">)</span> (<em class="parameter"><code><a class="link" href="harfbuzz-hb-unicode.html#hb-unicode-funcs-t"><span class="type">hb_unicode_funcs_t</span></a> *ufuncs</code></em>,
                                 <em class="parameter"><code><a class="link" href="harfbuzz-hb-common.html#hb-codepoint-t" title="hb_codepoint_t"><span class="type">hb_codepoint_t</span></a> unicode</code></em>,
                                 <em class="parameter"><code><span class="type">void</span> *user_data</code></em>);</pre>
 </div>
@@ -861,7 +871,7 @@ hb_unicode_mirroring (<em class="parameter"><code><a class="link" href="harfbuzz
 <div class="refsect2">
 <a name="hb-unicode-script"></a><h3>hb_unicode_script ()</h3>
 <pre class="programlisting"><a class="link" href="harfbuzz-hb-common.html#hb-script-t" title="enum hb_script_t"><span class="returnvalue">hb_script_t</span></a>
-hb_unicode_script (<em class="parameter"><code><a class="link" href="harfbuzz-hb-unicode.html#hb-unicode-funcs-t" title="hb_unicode_funcs_t"><span class="type">hb_unicode_funcs_t</span></a> *ufuncs</code></em>,
+hb_unicode_script (<em class="parameter"><code><a class="link" href="harfbuzz-hb-unicode.html#hb-unicode-funcs-t"><span class="type">hb_unicode_funcs_t</span></a> *ufuncs</code></em>,
                    <em class="parameter"><code><a class="link" href="harfbuzz-hb-common.html#hb-codepoint-t" title="hb_codepoint_t"><span class="type">hb_codepoint_t</span></a> unicode</code></em>);</pre>
 <p class="since">Since: <a class="link" href="api-index-0-9-2.html#api-index-0.9.2">0.9.2</a></p>
 </div>
@@ -869,7 +879,7 @@ hb_unicode_script (<em class="parameter"><code><a class="link" href="harfbuzz-hb
 <div class="refsect2">
 <a name="hb-unicode-script-func-t"></a><h3>hb_unicode_script_func_t ()</h3>
 <pre class="programlisting"><a class="link" href="harfbuzz-hb-common.html#hb-script-t" title="enum hb_script_t"><span class="returnvalue">hb_script_t</span></a>
-<span class="c_punctuation">(</span>*hb_unicode_script_func_t<span class="c_punctuation">)</span> (<em class="parameter"><code><a class="link" href="harfbuzz-hb-unicode.html#hb-unicode-funcs-t" title="hb_unicode_funcs_t"><span class="type">hb_unicode_funcs_t</span></a> *ufuncs</code></em>,
+<span class="c_punctuation">(</span>*hb_unicode_script_func_t<span class="c_punctuation">)</span> (<em class="parameter"><code><a class="link" href="harfbuzz-hb-unicode.html#hb-unicode-funcs-t"><span class="type">hb_unicode_funcs_t</span></a> *ufuncs</code></em>,
                              <em class="parameter"><code><a class="link" href="harfbuzz-hb-common.html#hb-codepoint-t" title="hb_codepoint_t"><span class="type">hb_codepoint_t</span></a> unicode</code></em>,
                              <em class="parameter"><code><span class="type">void</span> *user_data</code></em>);</pre>
 </div>
index 2b60884..7ad9a1e 100644 (file)
@@ -5,7 +5,7 @@
 <title>hb-uniscribe: HarfBuzz Manual</title>
 <meta name="generator" content="DocBook XSL Stylesheets Vsnapshot">
 <link rel="home" href="index.html" title="HarfBuzz Manual">
-<link rel="up" href="ch12.html" title="Integration API">
+<link rel="up" href="ch14.html" title="Integration API">
 <link rel="prev" href="harfbuzz-hb-icu.html" title="hb-icu">
 <link rel="next" href="api-index-full.html" title="API Index">
 <meta name="generator" content="GTK-Doc V1.29 (XML mode)">
@@ -18,7 +18,7 @@
                   <a href="#harfbuzz-hb-uniscribe.description" class="shortcut">Description</a></span>
 </td>
 <td><a accesskey="h" href="index.html"><img src="home.png" width="16" height="16" border="0" alt="Home"></a></td>
-<td><a accesskey="u" href="ch12.html"><img src="up.png" width="16" height="16" border="0" alt="Up"></a></td>
+<td><a accesskey="u" href="ch14.html"><img src="up.png" width="16" height="16" border="0" alt="Up"></a></td>
 <td><a accesskey="p" href="harfbuzz-hb-icu.html"><img src="left.png" width="16" height="16" border="0" alt="Prev"></a></td>
 <td><a accesskey="n" href="api-index-full.html"><img src="right.png" width="16" height="16" border="0" alt="Next"></a></td>
 </tr></table>
 <div class="refsect2">
 <a name="hb-uniscribe-font-get-hfont"></a><h3>hb_uniscribe_font_get_hfont ()</h3>
 <pre class="programlisting"><span class="returnvalue">HFONT</span>
-hb_uniscribe_font_get_hfont (<em class="parameter"><code><a class="link" href="harfbuzz-hb-font.html#hb-font-t" title="hb_font_t"><span class="type">hb_font_t</span></a> *font</code></em>);</pre>
+hb_uniscribe_font_get_hfont (<em class="parameter"><code><a class="link" href="harfbuzz-hb-font.html#hb-font-t"><span class="type">hb_font_t</span></a> *font</code></em>);</pre>
 </div>
 <hr>
 <div class="refsect2">
 <a name="hb-uniscribe-font-get-logfontw"></a><h3>hb_uniscribe_font_get_logfontw ()</h3>
 <pre class="programlisting"><span class="returnvalue">LOGFONTW</span> *
-hb_uniscribe_font_get_logfontw (<em class="parameter"><code><a class="link" href="harfbuzz-hb-font.html#hb-font-t" title="hb_font_t"><span class="type">hb_font_t</span></a> *font</code></em>);</pre>
+hb_uniscribe_font_get_logfontw (<em class="parameter"><code><a class="link" href="harfbuzz-hb-font.html#hb-font-t"><span class="type">hb_font_t</span></a> *font</code></em>);</pre>
 </div>
 </div>
 <div class="refsect1">
index 54c66aa..2039c3b 100644 (file)
@@ -5,9 +5,9 @@
 <title>hb-version: HarfBuzz Manual</title>
 <meta name="generator" content="DocBook XSL Stylesheets Vsnapshot">
 <link rel="home" href="index.html" title="HarfBuzz Manual">
-<link rel="up" href="ch09.html" title="Core API">
+<link rel="up" href="ch11.html" title="Core API">
 <link rel="prev" href="harfbuzz-hb-unicode.html" title="hb-unicode">
-<link rel="next" href="ch10.html" title="OpenType API">
+<link rel="next" href="ch12.html" title="OpenType API">
 <meta name="generator" content="GTK-Doc V1.29 (XML mode)">
 <link rel="stylesheet" href="style.css" type="text/css">
 </head>
@@ -18,9 +18,9 @@
                   <a href="#harfbuzz-hb-version.description" class="shortcut">Description</a></span>
 </td>
 <td><a accesskey="h" href="index.html"><img src="home.png" width="16" height="16" border="0" alt="Home"></a></td>
-<td><a accesskey="u" href="ch09.html"><img src="up.png" width="16" height="16" border="0" alt="Up"></a></td>
+<td><a accesskey="u" href="ch11.html"><img src="up.png" width="16" height="16" border="0" alt="Up"></a></td>
 <td><a accesskey="p" href="harfbuzz-hb-unicode.html"><img src="left.png" width="16" height="16" border="0" alt="Prev"></a></td>
-<td><a accesskey="n" href="ch10.html"><img src="right.png" width="16" height="16" border="0" alt="Next"></a></td>
+<td><a accesskey="n" href="ch12.html"><img src="right.png" width="16" height="16" border="0" alt="Next"></a></td>
 </tr></table>
 <div class="refentry">
 <a name="harfbuzz-hb-version"></a><div class="titlepage"></div>
@@ -184,19 +184,19 @@ hb_version_string (<em class="parameter"><code><span class="type">void</span></c
 <hr>
 <div class="refsect2">
 <a name="HB-VERSION-MICRO:CAPS"></a><h3>HB_VERSION_MICRO</h3>
-<pre class="programlisting">#define HB_VERSION_MICRO 0
+<pre class="programlisting">#define HB_VERSION_MICRO 4
 </pre>
 </div>
 <hr>
 <div class="refsect2">
 <a name="HB-VERSION-MINOR:CAPS"></a><h3>HB_VERSION_MINOR</h3>
-<pre class="programlisting">#define HB_VERSION_MINOR 4
+<pre class="programlisting">#define HB_VERSION_MINOR 6
 </pre>
 </div>
 <hr>
 <div class="refsect2">
 <a name="HB-VERSION-STRING:CAPS"></a><h3>HB_VERSION_STRING</h3>
-<pre class="programlisting">#define HB_VERSION_STRING "2.4.0"
+<pre class="programlisting">#define HB_VERSION_STRING "2.6.4"
 </pre>
 </div>
 </div>
index 3b9d482..a577faf 100644 (file)
         <sub name="Graphite shaping" link="graphite-shaping.html"/>
         <sub name="AAT shaping" link="aat-shaping.html"/>
       </sub>
+      <sub name="The HarfBuzz object model" link="object-model.html">
+        <sub name="An overview of data types in HarfBuzz" link="object-model.html#object-model-intro"/>
+        <sub name="Objects in HarfBuzz" link="object-model-object-types.html"/>
+        <sub name="Object lifecycle management" link="object-model-lifecycle.html"/>
+        <sub name="User data" link="object-model-user-data.html"/>
+        <sub name="Blobs" link="object-model-blobs.html"/>
+      </sub>
       <sub name="Buffers, language, script and direction" link="buffers-language-script-and-direction.html">
         <sub name="Creating and destroying buffers" link="buffers-language-script-and-direction.html#creating-and-destroying-buffers"/>
         <sub name="Adding text to the buffer" link="adding-text-to-the-buffer.html"/>
         <sub name="Setting buffer properties" link="setting-buffer-properties.html"/>
-        <sub name="What about the other scripts?" link="what-about-the-other-scripts.html"/>
         <sub name="Customizing Unicode functions" link="customizing-unicode-functions.html"/>
       </sub>
-      <sub name="Fonts and faces" link="fonts-and-faces.html">
-        <sub name="Using FreeType" link="fonts-and-faces.html#using-freetype"/>
-        <sub name="Using HarfBuzz's native OpenType implementation" link="using-harfbuzzs-native-opentype-implementation.html"/>
-        <sub name="Using your own font functions" link="using-your-own-font-functions.html"/>
+      <sub name="Fonts, faces, and output" link="fonts-and-faces.html">
+        <sub name="Font and face objects" link="fonts-and-faces.html#fonts-and-faces-objects"/>
+        <sub name="Customizing font functions" link="fonts-and-faces-custom-functions.html"/>
+        <sub name="Font objects and HarfBuzz's native OpenType implementation" link="fonts-and-faces-native-opentype.html"/>
+        <sub name="Working with OpenType Variable Fonts" link="fonts-and-faces-variable.html"/>
+      </sub>
+      <sub name="Shaping and shape plans" link="shaping-and-shape-plans.html">
+        <sub name="Shaping and buffer output" link="shaping-and-shape-plans.html#shaping-buffer-output"/>
+        <sub name="OpenType features" link="shaping-opentype-features.html"/>
+        <sub name="Shaper selection" link="shaping-shaper-selection.html"/>
+        <sub name="Plans and caching" link="shaping-plans-and-caching.html"/>
       </sub>
       <sub name="Clusters" link="clusters.html">
         <sub name="Clusters and shaping" link="clusters.html#clusters-and-shaping"/>
           <sub name="Other considerations in level 2" link="level-2.html#other-considerations-in-level-2"/>
         </sub>
       </sub>
-      <sub name="Shaping and shape plans" link="shaping-and-shape-plans.html">
-        <sub name="OpenType features" link="shaping-and-shape-plans.html#opentype-features"/>
-        <sub name="Plans and caching" link="plans-and-caching.html"/>
+      <sub name="Utilities" link="utilities.html">
+        <sub name="Command-line tools" link="utilities.html#utilities-command-line-tools">
+          <sub name="hb-shape" link="utilities.html#utilities-command-line-hbshape"/>
+          <sub name="hb-view" link="utilities.html#utilities-command-line-hbview"/>
+          <sub name="hb-subset" link="utilities.html#utilities-command-line-hbsubset"/>
+        </sub>
+        <sub name="Common data types and APIs" link="utilities-common-types-apis.html"/>
+        <sub name="UCDN" link="utilities-ucdn.html"/>
       </sub>
-      <sub name="Glyph information" link="pt01.html#glyph-information"/>
     </sub>
     <sub name="Reference manual" link="pt02.html">
-      <sub name="Core API" link="ch09.html">
+      <sub name="Core API" link="ch11.html">
         <sub name="hb-blob" link="harfbuzz-hb-blob.html"/>
         <sub name="hb-buffer" link="harfbuzz-hb-buffer.html"/>
         <sub name="hb-common" link="harfbuzz-hb-common.html"/>
@@ -78,7 +95,7 @@
         <sub name="hb-unicode" link="harfbuzz-hb-unicode.html"/>
         <sub name="hb-version" link="harfbuzz-hb-version.html"/>
       </sub>
-      <sub name="OpenType API" link="ch10.html">
+      <sub name="OpenType API" link="ch12.html">
         <sub name="hb-ot-color" link="harfbuzz-hb-ot-color.html"/>
         <sub name="hb-ot-font" link="harfbuzz-hb-ot-font.html"/>
         <sub name="hb-ot-layout" link="harfbuzz-hb-ot-layout.html"/>
         <sub name="hb-ot-shape" link="harfbuzz-hb-ot-shape.html"/>
         <sub name="hb-ot-var" link="harfbuzz-hb-ot-var.html"/>
       </sub>
-      <sub name="Apple Advanced Typography API" link="ch11.html">
+      <sub name="Apple Advanced Typography API" link="ch13.html">
         <sub name="hb-aat-layout" link="harfbuzz-hb-aat-layout.html"/>
       </sub>
-      <sub name="Integration API" link="ch12.html">
+      <sub name="Integration API" link="ch14.html">
         <sub name="hb-coretext" link="harfbuzz-hb-coretext.html"/>
         <sub name="hb-ft" link="harfbuzz-hb-ft.html"/>
         <sub name="hb-glib" link="harfbuzz-hb-glib.html"/>
       </sub>
       <sub name="API Index" link="api-index-full.html"/>
       <sub name="Index of deprecated API" link="deprecated-api-index.html"/>
+      <sub name="Index of new symbols in 2.6.0" link="api-index-2-6-0.html"/>
+      <sub name="Index of new symbols in 2.5.0" link="api-index-2-5-0.html"/>
+      <sub name="Index of new symbols in 2.4.0" link="api-index-2-4-0.html"/>
+      <sub name="Index of new symbols in 2.3.0" link="api-index-2-3-0.html"/>
       <sub name="Index of new symbols in 2.2.0" link="api-index-2-2-0.html"/>
       <sub name="Index of new symbols in 2.1.0" link="api-index-2-1-0.html"/>
       <sub name="Index of new symbols in 2.0.0" link="api-index-2-0-0.html"/>
       <sub name="Index of new symbols in 1.5.0" link="api-index-1-5-0.html"/>
       <sub name="Index of new symbols in 1.4.3" link="api-index-1-4-3.html"/>
       <sub name="Index of new symbols in 1.4.2" link="api-index-1-4-2.html"/>
-      <sub name="Index of new symbols in 1.4.0" link="api-index-1-4-0.html"/>
       <sub name="Index of new symbols in 1.3.3" link="api-index-1-3-3.html"/>
       <sub name="Index of new symbols in 1.2.3" link="api-index-1-2-3.html"/>
       <sub name="Index of new symbols in 1.1.3" link="api-index-1-1-3.html"/>
     <keyword type="macro" name="HB_BUFFER_REPLACEMENT_CODEPOINT_DEFAULT" link="harfbuzz-hb-buffer.html#HB-BUFFER-REPLACEMENT-CODEPOINT-DEFAULT:CAPS" since="0.9.31"/>
     <keyword type="typedef" name="hb_buffer_t" link="harfbuzz-hb-buffer.html#hb-buffer-t"/>
     <keyword type="enum" name="enum hb_glyph_flags_t" link="harfbuzz-hb-buffer.html#hb-glyph-flags-t" since="1.5.0"/>
-    <keyword type="struct" name="hb_glyph_position_t" link="harfbuzz-hb-buffer.html#hb-glyph-position-t"/>
+    <keyword type="struct" name="hb_glyph_position_t" link="harfbuzz-hb-buffer.html#hb-glyph-position-t-struct"/>
     <keyword type="enum" name="enum hb_buffer_content_type_t" link="harfbuzz-hb-buffer.html#hb-buffer-content-type-t"/>
     <keyword type="enum" name="enum hb_buffer_flags_t" link="harfbuzz-hb-buffer.html#hb-buffer-flags-t" since="0.9.20"/>
     <keyword type="enum" name="enum hb_buffer_cluster_level_t" link="harfbuzz-hb-buffer.html#hb-buffer-cluster-level-t" since="0.9.42"/>
-    <keyword type="struct" name="hb_segment_properties_t" link="harfbuzz-hb-buffer.html#hb-segment-properties-t"/>
+    <keyword type="struct" name="hb_segment_properties_t" link="harfbuzz-hb-buffer.html#hb-segment-properties-t-struct"/>
     <keyword type="enum" name="enum hb_buffer_serialize_format_t" link="harfbuzz-hb-buffer.html#hb-buffer-serialize-format-t" since="0.9.2"/>
     <keyword type="enum" name="enum hb_buffer_serialize_flags_t" link="harfbuzz-hb-buffer.html#hb-buffer-serialize-flags-t" since="0.9.20"/>
     <keyword type="enum" name="enum hb_buffer_diff_flags_t" link="harfbuzz-hb-buffer.html#hb-buffer-diff-flags-t"/>
     <keyword type="typedef" name="hb_codepoint_t" link="harfbuzz-hb-common.html#hb-codepoint-t"/>
     <keyword type="enum" name="enum hb_direction_t" link="harfbuzz-hb-common.html#hb-direction-t"/>
     <keyword type="typedef" name="hb_language_t" link="harfbuzz-hb-common.html#hb-language-t"/>
-    <keyword type="struct" name="hb_feature_t" link="harfbuzz-hb-common.html#hb-feature-t"/>
+    <keyword type="struct" name="hb_feature_t" link="harfbuzz-hb-common.html#hb-feature-t-struct"/>
     <keyword type="struct" name="hb_variation_t" link="harfbuzz-hb-common.html#hb-variation-t" since="1.4.2"/>
     <keyword type="typedef" name="hb_mask_t" link="harfbuzz-hb-common.html#hb-mask-t"/>
     <keyword type="typedef" name="hb_position_t" link="harfbuzz-hb-common.html#hb-position-t"/>
     <keyword type="typedef" name="hb_tag_t" link="harfbuzz-hb-common.html#hb-tag-t"/>
     <keyword type="enum" name="enum hb_script_t" link="harfbuzz-hb-common.html#hb-script-t"/>
-    <keyword type="struct" name="hb_user_data_key_t" link="harfbuzz-hb-common.html#hb-user-data-key-t"/>
+    <keyword type="struct" name="hb_user_data_key_t" link="harfbuzz-hb-common.html#hb-user-data-key-t-struct"/>
     <keyword type="union" name="hb_var_int_t" link="harfbuzz-hb-common.html#hb-var-int-t"/>
     <keyword type="macro" name="HB_TAG_NONE" link="harfbuzz-hb-common.html#HB-TAG-NONE:CAPS"/>
     <keyword type="macro" name="HB_TAG_MAX" link="harfbuzz-hb-common.html#HB-TAG-MAX:CAPS"/>
     <keyword type="macro" name="HB_FEATURE_GLOBAL_START" link="harfbuzz-hb-common.html#HB-FEATURE-GLOBAL-START:CAPS" since="2.0.0"/>
     <keyword type="function" name="hb_font_get_glyph_func_t ()" link="harfbuzz-hb-deprecated.html#hb-font-get-glyph-func-t" deprecated=""/>
     <keyword type="function" name="hb_ot_layout_table_find_script ()" link="harfbuzz-hb-deprecated.html#hb-ot-layout-table-find-script"/>
-    <keyword type="function" name="hb_font_funcs_set_glyph_h_kerning_func ()" link="harfbuzz-hb-deprecated.html#hb-font-funcs-set-glyph-h-kerning-func" deprecated="2.0.0" since="0.9.2"/>
     <keyword type="function" name="hb_font_funcs_set_glyph_v_kerning_func ()" link="harfbuzz-hb-deprecated.html#hb-font-funcs-set-glyph-v-kerning-func" deprecated="2.0.0" since="0.9.2"/>
-    <keyword type="function" name="hb_font_get_glyph_h_kerning ()" link="harfbuzz-hb-deprecated.html#hb-font-get-glyph-h-kerning" deprecated="2.0.0" since="0.9.2"/>
-    <keyword type="function" name="hb_font_get_glyph_kerning_for_direction ()" link="harfbuzz-hb-deprecated.html#hb-font-get-glyph-kerning-for-direction" deprecated="2.0.0" since="0.9.2"/>
-    <keyword type="function" name="hb_font_get_glyph_kerning_func_t ()" link="harfbuzz-hb-deprecated.html#hb-font-get-glyph-kerning-func-t" deprecated=""/>
     <keyword type="function" name="hb_font_get_glyph_v_kerning ()" link="harfbuzz-hb-deprecated.html#hb-font-get-glyph-v-kerning" deprecated="2.0.0" since="0.9.2"/>
     <keyword type="macro" name="HB_BUFFER_FLAGS_DEFAULT" link="harfbuzz-hb-deprecated.html#HB-BUFFER-FLAGS-DEFAULT:CAPS" deprecated=""/>
     <keyword type="macro" name="HB_BUFFER_SERIALIZE_FLAGS_DEFAULT" link="harfbuzz-hb-deprecated.html#HB-BUFFER-SERIALIZE-FLAGS-DEFAULT:CAPS" deprecated=""/>
     <keyword type="macro" name="HB_SCRIPT_CANADIAN_ABORIGINAL" link="harfbuzz-hb-deprecated.html#HB-SCRIPT-CANADIAN-ABORIGINAL:CAPS" deprecated=""/>
+    <keyword type="macro" name="HB_MATH_GLYPH_PART_FLAG_EXTENDER" link="harfbuzz-hb-deprecated.html#HB-MATH-GLYPH-PART-FLAG-EXTENDER:CAPS" deprecated=""/>
     <keyword type="macro" name="HB_OT_VAR_NO_AXIS_INDEX" link="harfbuzz-hb-deprecated.html#HB-OT-VAR-NO-AXIS-INDEX:CAPS" deprecated="2.2.0" since="1.4.2"/>
     <keyword type="macro" name="HB_UNICODE_MAX_DECOMPOSITION_LEN" link="harfbuzz-hb-deprecated.html#HB-UNICODE-MAX-DECOMPOSITION-LEN:CAPS" deprecated="2.0.0"/>
-    <keyword type="typedef" name="hb_font_get_glyph_h_kerning_func_t" link="harfbuzz-hb-deprecated.html#hb-font-get-glyph-h-kerning-func-t" deprecated=""/>
     <keyword type="typedef" name="hb_font_get_glyph_v_kerning_func_t" link="harfbuzz-hb-deprecated.html#hb-font-get-glyph-v-kerning-func-t" deprecated=""/>
     <keyword type="function" name="hb_face_count ()" link="harfbuzz-hb-face.html#hb-face-count" since="1.7.7"/>
     <keyword type="function" name="hb_face_create ()" link="harfbuzz-hb-face.html#hb-face-create" since="0.9.2"/>
     <keyword type="function" name="hb_font_funcs_set_glyph_from_name_func ()" link="harfbuzz-hb-font.html#hb-font-funcs-set-glyph-from-name-func" since="0.9.2"/>
     <keyword type="function" name="hb_font_funcs_set_glyph_h_advance_func ()" link="harfbuzz-hb-font.html#hb-font-funcs-set-glyph-h-advance-func" since="0.9.2"/>
     <keyword type="function" name="hb_font_funcs_set_glyph_h_advances_func ()" link="harfbuzz-hb-font.html#hb-font-funcs-set-glyph-h-advances-func" since="1.8.6"/>
+    <keyword type="function" name="hb_font_funcs_set_glyph_h_kerning_func ()" link="harfbuzz-hb-font.html#hb-font-funcs-set-glyph-h-kerning-func" since="0.9.2"/>
     <keyword type="function" name="hb_font_funcs_set_glyph_h_origin_func ()" link="harfbuzz-hb-font.html#hb-font-funcs-set-glyph-h-origin-func" since="0.9.2"/>
     <keyword type="function" name="hb_font_funcs_set_glyph_name_func ()" link="harfbuzz-hb-font.html#hb-font-funcs-set-glyph-name-func" since="0.9.2"/>
     <keyword type="function" name="hb_font_funcs_set_glyph_v_advance_func ()" link="harfbuzz-hb-font.html#hb-font-funcs-set-glyph-v-advance-func" since="0.9.2"/>
     <keyword type="function" name="hb_font_get_glyph_from_name_func_t ()" link="harfbuzz-hb-font.html#hb-font-get-glyph-from-name-func-t"/>
     <keyword type="function" name="hb_font_get_glyph_h_advance ()" link="harfbuzz-hb-font.html#hb-font-get-glyph-h-advance" since="0.9.2"/>
     <keyword type="function" name="hb_font_get_glyph_h_advances ()" link="harfbuzz-hb-font.html#hb-font-get-glyph-h-advances" since="1.8.6"/>
+    <keyword type="function" name="hb_font_get_glyph_h_kerning ()" link="harfbuzz-hb-font.html#hb-font-get-glyph-h-kerning" since="0.9.2"/>
     <keyword type="function" name="hb_font_get_glyph_h_origin ()" link="harfbuzz-hb-font.html#hb-font-get-glyph-h-origin" since="0.9.2"/>
+    <keyword type="function" name="hb_font_get_glyph_kerning_for_direction ()" link="harfbuzz-hb-font.html#hb-font-get-glyph-kerning-for-direction" since="0.9.2"/>
+    <keyword type="function" name="hb_font_get_glyph_kerning_func_t ()" link="harfbuzz-hb-font.html#hb-font-get-glyph-kerning-func-t"/>
     <keyword type="function" name="hb_font_get_glyph_name ()" link="harfbuzz-hb-font.html#hb-font-get-glyph-name" since="0.9.2"/>
     <keyword type="function" name="hb_font_get_glyph_name_func_t ()" link="harfbuzz-hb-font.html#hb-font-get-glyph-name-func-t"/>
     <keyword type="function" name="hb_font_get_glyph_origin_for_direction ()" link="harfbuzz-hb-font.html#hb-font-get-glyph-origin-for-direction" since="0.9.2"/>
     <keyword type="function" name="hb_font_get_glyph_v_origin ()" link="harfbuzz-hb-font.html#hb-font-get-glyph-v-origin" since="0.9.2"/>
     <keyword type="function" name="hb_font_get_nominal_glyph ()" link="harfbuzz-hb-font.html#hb-font-get-nominal-glyph" since="1.2.3"/>
     <keyword type="function" name="hb_font_get_nominal_glyph_func_t ()" link="harfbuzz-hb-font.html#hb-font-get-nominal-glyph-func-t"/>
+    <keyword type="function" name="hb_font_get_nominal_glyphs ()" link="harfbuzz-hb-font.html#hb-font-get-nominal-glyphs" since="2.6.3"/>
     <keyword type="function" name="hb_font_get_parent ()" link="harfbuzz-hb-font.html#hb-font-get-parent" since="0.9.2"/>
     <keyword type="function" name="hb_font_get_ppem ()" link="harfbuzz-hb-font.html#hb-font-get-ppem" since="0.9.2"/>
     <keyword type="function" name="hb_font_get_ptem ()" link="harfbuzz-hb-font.html#hb-font-get-ptem" since="0.9.2"/>
     <keyword type="function" name="hb_font_set_variations ()" link="harfbuzz-hb-font.html#hb-font-set-variations" since="1.4.2"/>
     <keyword type="function" name="hb_font_set_var_coords_design ()" link="harfbuzz-hb-font.html#hb-font-set-var-coords-design" since="1.4.2"/>
     <keyword type="function" name="hb_font_set_var_coords_normalized ()" link="harfbuzz-hb-font.html#hb-font-set-var-coords-normalized" since="1.4.2"/>
+    <keyword type="function" name="hb_font_set_var_named_instance ()" link="harfbuzz-hb-font.html#hb-font-set-var-named-instance" since="2.6.0"/>
     <keyword type="function" name="hb_font_subtract_glyph_origin_for_direction ()" link="harfbuzz-hb-font.html#hb-font-subtract-glyph-origin-for-direction" since="0.9.2"/>
     <keyword type="function" name="hb_reference_table_func_t ()" link="harfbuzz-hb-font.html#hb-reference-table-func-t"/>
     <keyword type="function" name="hb_font_funcs_set_font_h_extents_func ()" link="harfbuzz-hb-font.html#hb-font-funcs-set-font-h-extents-func" since="1.1.2"/>
     <keyword type="typedef" name="hb_font_funcs_t" link="harfbuzz-hb-font.html#hb-font-funcs-t"/>
     <keyword type="typedef" name="hb_font_get_glyph_h_advance_func_t" link="harfbuzz-hb-font.html#hb-font-get-glyph-h-advance-func-t"/>
     <keyword type="typedef" name="hb_font_get_glyph_h_advances_func_t" link="harfbuzz-hb-font.html#hb-font-get-glyph-h-advances-func-t"/>
+    <keyword type="typedef" name="hb_font_get_glyph_h_kerning_func_t" link="harfbuzz-hb-font.html#hb-font-get-glyph-h-kerning-func-t"/>
     <keyword type="typedef" name="hb_font_get_glyph_h_origin_func_t" link="harfbuzz-hb-font.html#hb-font-get-glyph-h-origin-func-t"/>
     <keyword type="typedef" name="hb_font_get_glyph_v_advance_func_t" link="harfbuzz-hb-font.html#hb-font-get-glyph-v-advance-func-t"/>
     <keyword type="typedef" name="hb_font_get_glyph_v_advances_func_t" link="harfbuzz-hb-font.html#hb-font-get-glyph-v-advances-func-t"/>
     <keyword type="macro" name="HB_VERSION_MINOR" link="harfbuzz-hb-version.html#HB-VERSION-MINOR:CAPS"/>
     <keyword type="macro" name="HB_VERSION_STRING" link="harfbuzz-hb-version.html#HB-VERSION-STRING:CAPS"/>
     <keyword type="macro" name="HB_COLOR()" link="harfbuzz-hb-ot-color.html#HB-COLOR:CAPS"/>
-    <keyword type="macro" name="hb_color_get_alpha()" link="harfbuzz-hb-ot-color.html#hb-color-get-alpha" since="2.1.0"/>
-    <keyword type="macro" name="hb_color_get_blue()" link="harfbuzz-hb-ot-color.html#hb-color-get-blue" since="2.1.0"/>
-    <keyword type="macro" name="hb_color_get_green()" link="harfbuzz-hb-ot-color.html#hb-color-get-green" since="2.1.0"/>
-    <keyword type="macro" name="hb_color_get_red()" link="harfbuzz-hb-ot-color.html#hb-color-get-red" since="2.1.0"/>
+    <keyword type="function" name="hb_color_get_alpha ()" link="harfbuzz-hb-ot-color.html#hb-color-get-alpha" since="2.1.0"/>
+    <keyword type="function" name="hb_color_get_blue ()" link="harfbuzz-hb-ot-color.html#hb-color-get-blue" since="2.1.0"/>
+    <keyword type="function" name="hb_color_get_green ()" link="harfbuzz-hb-ot-color.html#hb-color-get-green" since="2.1.0"/>
+    <keyword type="function" name="hb_color_get_red ()" link="harfbuzz-hb-ot-color.html#hb-color-get-red" since="2.1.0"/>
     <keyword type="function" name="hb_ot_color_glyph_get_layers ()" link="harfbuzz-hb-ot-color.html#hb-ot-color-glyph-get-layers" since="2.1.0"/>
     <keyword type="function" name="hb_ot_color_glyph_reference_png ()" link="harfbuzz-hb-ot-color.html#hb-ot-color-glyph-reference-png" since="2.1.0"/>
     <keyword type="function" name="hb_ot_color_glyph_reference_svg ()" link="harfbuzz-hb-ot-color.html#hb-ot-color-glyph-reference-svg" since="2.1.0"/>
     <keyword type="function" name="hb_ot_layout_feature_get_name_ids ()" link="harfbuzz-hb-ot-layout.html#hb-ot-layout-feature-get-name-ids" since="2.0.0"/>
     <keyword type="function" name="hb_ot_layout_feature_with_variations_get_lookups ()" link="harfbuzz-hb-ot-layout.html#hb-ot-layout-feature-with-variations-get-lookups"/>
     <keyword type="function" name="hb_ot_layout_get_attach_points ()" link="harfbuzz-hb-ot-layout.html#hb-ot-layout-get-attach-points"/>
+    <keyword type="function" name="hb_ot_layout_get_baseline ()" link="harfbuzz-hb-ot-layout.html#hb-ot-layout-get-baseline" since="2.6.0"/>
     <keyword type="function" name="hb_ot_layout_get_glyph_class ()" link="harfbuzz-hb-ot-layout.html#hb-ot-layout-get-glyph-class" since="0.9.7"/>
     <keyword type="function" name="hb_ot_layout_get_glyphs_in_class ()" link="harfbuzz-hb-ot-layout.html#hb-ot-layout-get-glyphs-in-class" since="0.9.7"/>
     <keyword type="function" name="hb_ot_layout_get_ligature_carets ()" link="harfbuzz-hb-ot-layout.html#hb-ot-layout-get-ligature-carets"/>
     <keyword type="macro" name="HB_OT_TAG_GPOS" link="harfbuzz-hb-ot-layout.html#HB-OT-TAG-GPOS:CAPS"/>
     <keyword type="macro" name="HB_OT_TAG_GSUB" link="harfbuzz-hb-ot-layout.html#HB-OT-TAG-GSUB:CAPS"/>
     <keyword type="macro" name="HB_OT_TAG_JSTF" link="harfbuzz-hb-ot-layout.html#HB-OT-TAG-JSTF:CAPS"/>
+    <keyword type="enum" name="enum hb_ot_layout_baseline_tag_t" link="harfbuzz-hb-ot-layout.html#hb-ot-layout-baseline-tag-t" since="2.6.0"/>
     <keyword type="enum" name="enum hb_ot_layout_glyph_class_t" link="harfbuzz-hb-ot-layout.html#hb-ot-layout-glyph-class-t"/>
     <keyword type="function" name="hb_ot_math_has_data ()" link="harfbuzz-hb-ot-math.html#hb-ot-math-has-data" since="1.3.3"/>
     <keyword type="function" name="hb_ot_math_get_constant ()" link="harfbuzz-hb-ot-math.html#hb-ot-math-get-constant" since="1.3.3"/>
     <keyword type="macro" name="HB_OT_MATH_SCRIPT" link="harfbuzz-hb-ot-math.html#HB-OT-MATH-SCRIPT:CAPS"/>
     <keyword type="enum" name="enum hb_ot_math_constant_t" link="harfbuzz-hb-ot-math.html#hb-ot-math-constant-t" since="1.3.3"/>
     <keyword type="enum" name="enum hb_ot_math_kern_t" link="harfbuzz-hb-ot-math.html#hb-ot-math-kern-t" since="1.3.3"/>
-    <keyword type="struct" name="hb_ot_math_glyph_variant_t" link="harfbuzz-hb-ot-math.html#hb-ot-math-glyph-variant-t" since="1.3.3"/>
+    <keyword type="struct" name="hb_ot_math_glyph_variant_t" link="harfbuzz-hb-ot-math.html#hb-ot-math-glyph-variant-t-struct"/>
     <keyword type="enum" name="enum hb_ot_math_glyph_part_flags_t" link="harfbuzz-hb-ot-math.html#hb-ot-math-glyph-part-flags-t" since="1.3.3"/>
-    <keyword type="struct" name="hb_ot_math_glyph_part_t" link="harfbuzz-hb-ot-math.html#hb-ot-math-glyph-part-t" since="1.3.3"/>
+    <keyword type="struct" name="hb_ot_math_glyph_part_t" link="harfbuzz-hb-ot-math.html#hb-ot-math-glyph-part-t-struct"/>
     <keyword type="function" name="hb_ot_name_list_names ()" link="harfbuzz-hb-ot-name.html#hb-ot-name-list-names" since="2.1.0"/>
     <keyword type="function" name="hb_ot_name_get_utf16 ()" link="harfbuzz-hb-ot-name.html#hb-ot-name-get-utf16" since="2.1.0"/>
     <keyword type="function" name="hb_ot_name_get_utf32 ()" link="harfbuzz-hb-ot-name.html#hb-ot-name-get-utf32" since="2.1.0"/>
     <keyword type="function" name="hb_glib_script_from_script ()" link="harfbuzz-hb-glib.html#hb-glib-script-from-script"/>
     <keyword type="function" name="hb_glib_script_to_script ()" link="harfbuzz-hb-glib.html#hb-glib-script-to-script"/>
     <keyword type="function" name="hb_glib_blob_create ()" link="harfbuzz-hb-glib.html#hb-glib-blob-create" since="0.9.38"/>
+    <keyword type="function" name="hb_gobject_blob_get_type ()" link="harfbuzz-hb-gobject.html#hb-gobject-blob-get-type" since="0.9.2"/>
+    <keyword type="function" name="hb_gobject_buffer_content_type_get_type ()" link="harfbuzz-hb-gobject.html#hb-gobject-buffer-content-type-get-type"/>
+    <keyword type="function" name="hb_gobject_buffer_diff_flags_get_type ()" link="harfbuzz-hb-gobject.html#hb-gobject-buffer-diff-flags-get-type"/>
+    <keyword type="function" name="hb_gobject_buffer_flags_get_type ()" link="harfbuzz-hb-gobject.html#hb-gobject-buffer-flags-get-type"/>
+    <keyword type="function" name="hb_gobject_buffer_get_type ()" link="harfbuzz-hb-gobject.html#hb-gobject-buffer-get-type" since="0.9.2"/>
+    <keyword type="function" name="hb_gobject_buffer_serialize_flags_get_type ()" link="harfbuzz-hb-gobject.html#hb-gobject-buffer-serialize-flags-get-type"/>
+    <keyword type="function" name="hb_gobject_buffer_serialize_format_get_type ()" link="harfbuzz-hb-gobject.html#hb-gobject-buffer-serialize-format-get-type"/>
+    <keyword type="function" name="hb_gobject_direction_get_type ()" link="harfbuzz-hb-gobject.html#hb-gobject-direction-get-type"/>
+    <keyword type="function" name="hb_gobject_face_get_type ()" link="harfbuzz-hb-gobject.html#hb-gobject-face-get-type" since="0.9.2"/>
+    <keyword type="function" name="hb_gobject_font_funcs_get_type ()" link="harfbuzz-hb-gobject.html#hb-gobject-font-funcs-get-type" since="0.9.2"/>
+    <keyword type="function" name="hb_gobject_font_get_type ()" link="harfbuzz-hb-gobject.html#hb-gobject-font-get-type" since="0.9.2"/>
+    <keyword type="function" name="hb_gobject_glyph_flags_get_type ()" link="harfbuzz-hb-gobject.html#hb-gobject-glyph-flags-get-type"/>
+    <keyword type="function" name="hb_gobject_map_get_type ()" link="harfbuzz-hb-gobject.html#hb-gobject-map-get-type"/>
+    <keyword type="function" name="hb_gobject_memory_mode_get_type ()" link="harfbuzz-hb-gobject.html#hb-gobject-memory-mode-get-type"/>
+    <keyword type="function" name="hb_gobject_ot_color_palette_flags_get_type ()" link="harfbuzz-hb-gobject.html#hb-gobject-ot-color-palette-flags-get-type"/>
+    <keyword type="function" name="hb_gobject_ot_layout_glyph_class_get_type ()" link="harfbuzz-hb-gobject.html#hb-gobject-ot-layout-glyph-class-get-type"/>
+    <keyword type="function" name="hb_gobject_ot_math_constant_get_type ()" link="harfbuzz-hb-gobject.html#hb-gobject-ot-math-constant-get-type"/>
+    <keyword type="function" name="hb_gobject_ot_math_glyph_part_get_type ()" link="harfbuzz-hb-gobject.html#hb-gobject-ot-math-glyph-part-get-type"/>
+    <keyword type="function" name="hb_gobject_ot_math_glyph_part_flags_get_type ()" link="harfbuzz-hb-gobject.html#hb-gobject-ot-math-glyph-part-flags-get-type"/>
+    <keyword type="function" name="hb_gobject_ot_math_glyph_variant_get_type ()" link="harfbuzz-hb-gobject.html#hb-gobject-ot-math-glyph-variant-get-type"/>
+    <keyword type="function" name="hb_gobject_ot_math_kern_get_type ()" link="harfbuzz-hb-gobject.html#hb-gobject-ot-math-kern-get-type"/>
+    <keyword type="function" name="hb_gobject_script_get_type ()" link="harfbuzz-hb-gobject.html#hb-gobject-script-get-type"/>
+    <keyword type="function" name="hb_gobject_shape_plan_get_type ()" link="harfbuzz-hb-gobject.html#hb-gobject-shape-plan-get-type"/>
+    <keyword type="function" name="hb_gobject_unicode_combining_class_get_type ()" link="harfbuzz-hb-gobject.html#hb-gobject-unicode-combining-class-get-type"/>
+    <keyword type="function" name="hb_gobject_unicode_funcs_get_type ()" link="harfbuzz-hb-gobject.html#hb-gobject-unicode-funcs-get-type" since="0.9.2"/>
+    <keyword type="function" name="hb_gobject_unicode_general_category_get_type ()" link="harfbuzz-hb-gobject.html#hb-gobject-unicode-general-category-get-type"/>
+    <keyword type="function" name="hb_gobject_buffer_cluster_level_get_type ()" link="harfbuzz-hb-gobject.html#hb-gobject-buffer-cluster-level-get-type"/>
+    <keyword type="function" name="hb_gobject_feature_get_type ()" link="harfbuzz-hb-gobject.html#hb-gobject-feature-get-type"/>
+    <keyword type="function" name="hb_gobject_glyph_info_get_type ()" link="harfbuzz-hb-gobject.html#hb-gobject-glyph-info-get-type"/>
+    <keyword type="function" name="hb_gobject_glyph_position_get_type ()" link="harfbuzz-hb-gobject.html#hb-gobject-glyph-position-get-type"/>
+    <keyword type="function" name="hb_gobject_segment_properties_get_type ()" link="harfbuzz-hb-gobject.html#hb-gobject-segment-properties-get-type"/>
+    <keyword type="function" name="hb_gobject_set_get_type ()" link="harfbuzz-hb-gobject.html#hb-gobject-set-get-type"/>
+    <keyword type="function" name="hb_gobject_user_data_key_get_type ()" link="harfbuzz-hb-gobject.html#hb-gobject-user-data-key-get-type"/>
+    <keyword type="macro" name="HB_GOBJECT_TYPE_BLOB" link="harfbuzz-hb-gobject.html#HB-GOBJECT-TYPE-BLOB:CAPS"/>
+    <keyword type="macro" name="HB_GOBJECT_TYPE_BUFFER" link="harfbuzz-hb-gobject.html#HB-GOBJECT-TYPE-BUFFER:CAPS"/>
+    <keyword type="macro" name="HB_GOBJECT_TYPE_BUFFER_CONTENT_TYPE" link="harfbuzz-hb-gobject.html#HB-GOBJECT-TYPE-BUFFER-CONTENT-TYPE:CAPS"/>
+    <keyword type="macro" name="HB_GOBJECT_TYPE_BUFFER_DIFF_FLAGS" link="harfbuzz-hb-gobject.html#HB-GOBJECT-TYPE-BUFFER-DIFF-FLAGS:CAPS"/>
+    <keyword type="macro" name="HB_GOBJECT_TYPE_BUFFER_FLAGS" link="harfbuzz-hb-gobject.html#HB-GOBJECT-TYPE-BUFFER-FLAGS:CAPS"/>
+    <keyword type="macro" name="HB_GOBJECT_TYPE_BUFFER_SERIALIZE_FLAGS" link="harfbuzz-hb-gobject.html#HB-GOBJECT-TYPE-BUFFER-SERIALIZE-FLAGS:CAPS"/>
+    <keyword type="macro" name="HB_GOBJECT_TYPE_BUFFER_SERIALIZE_FORMAT" link="harfbuzz-hb-gobject.html#HB-GOBJECT-TYPE-BUFFER-SERIALIZE-FORMAT:CAPS"/>
+    <keyword type="macro" name="HB_GOBJECT_TYPE_DIRECTION" link="harfbuzz-hb-gobject.html#HB-GOBJECT-TYPE-DIRECTION:CAPS"/>
+    <keyword type="macro" name="HB_GOBJECT_TYPE_FACE" link="harfbuzz-hb-gobject.html#HB-GOBJECT-TYPE-FACE:CAPS"/>
+    <keyword type="macro" name="HB_GOBJECT_TYPE_FONT" link="harfbuzz-hb-gobject.html#HB-GOBJECT-TYPE-FONT:CAPS"/>
+    <keyword type="macro" name="HB_GOBJECT_TYPE_FONT_FUNCS" link="harfbuzz-hb-gobject.html#HB-GOBJECT-TYPE-FONT-FUNCS:CAPS"/>
+    <keyword type="macro" name="HB_GOBJECT_TYPE_GLYPH_FLAGS" link="harfbuzz-hb-gobject.html#HB-GOBJECT-TYPE-GLYPH-FLAGS:CAPS"/>
+    <keyword type="macro" name="HB_GOBJECT_TYPE_MAP" link="harfbuzz-hb-gobject.html#HB-GOBJECT-TYPE-MAP:CAPS"/>
+    <keyword type="macro" name="HB_GOBJECT_TYPE_MEMORY_MODE" link="harfbuzz-hb-gobject.html#HB-GOBJECT-TYPE-MEMORY-MODE:CAPS"/>
+    <keyword type="macro" name="HB_GOBJECT_TYPE_OT_COLOR_PALETTE_FLAGS" link="harfbuzz-hb-gobject.html#HB-GOBJECT-TYPE-OT-COLOR-PALETTE-FLAGS:CAPS"/>
+    <keyword type="macro" name="HB_GOBJECT_TYPE_OT_LAYOUT_GLYPH_CLASS" link="harfbuzz-hb-gobject.html#HB-GOBJECT-TYPE-OT-LAYOUT-GLYPH-CLASS:CAPS"/>
+    <keyword type="macro" name="HB_GOBJECT_TYPE_OT_MATH_CONSTANT" link="harfbuzz-hb-gobject.html#HB-GOBJECT-TYPE-OT-MATH-CONSTANT:CAPS"/>
+    <keyword type="macro" name="HB_GOBJECT_TYPE_OT_MATH_GLYPH_PART" link="harfbuzz-hb-gobject.html#HB-GOBJECT-TYPE-OT-MATH-GLYPH-PART:CAPS"/>
+    <keyword type="macro" name="HB_GOBJECT_TYPE_OT_MATH_GLYPH_PART_FLAGS" link="harfbuzz-hb-gobject.html#HB-GOBJECT-TYPE-OT-MATH-GLYPH-PART-FLAGS:CAPS"/>
+    <keyword type="macro" name="HB_GOBJECT_TYPE_OT_MATH_GLYPH_VARIANT" link="harfbuzz-hb-gobject.html#HB-GOBJECT-TYPE-OT-MATH-GLYPH-VARIANT:CAPS"/>
+    <keyword type="macro" name="HB_GOBJECT_TYPE_OT_MATH_KERN" link="harfbuzz-hb-gobject.html#HB-GOBJECT-TYPE-OT-MATH-KERN:CAPS"/>
+    <keyword type="macro" name="HB_GOBJECT_TYPE_SCRIPT" link="harfbuzz-hb-gobject.html#HB-GOBJECT-TYPE-SCRIPT:CAPS"/>
+    <keyword type="macro" name="HB_GOBJECT_TYPE_SHAPE_PLAN" link="harfbuzz-hb-gobject.html#HB-GOBJECT-TYPE-SHAPE-PLAN:CAPS"/>
+    <keyword type="macro" name="HB_GOBJECT_TYPE_UNICODE_COMBINING_CLASS" link="harfbuzz-hb-gobject.html#HB-GOBJECT-TYPE-UNICODE-COMBINING-CLASS:CAPS"/>
+    <keyword type="macro" name="HB_GOBJECT_TYPE_UNICODE_FUNCS" link="harfbuzz-hb-gobject.html#HB-GOBJECT-TYPE-UNICODE-FUNCS:CAPS"/>
+    <keyword type="macro" name="HB_GOBJECT_TYPE_UNICODE_GENERAL_CATEGORY" link="harfbuzz-hb-gobject.html#HB-GOBJECT-TYPE-UNICODE-GENERAL-CATEGORY:CAPS"/>
+    <keyword type="macro" name="HB_GOBJECT_TYPE_BUFFER_CLUSTER_LEVEL" link="harfbuzz-hb-gobject.html#HB-GOBJECT-TYPE-BUFFER-CLUSTER-LEVEL:CAPS"/>
+    <keyword type="macro" name="HB_GOBJECT_TYPE_FEATURE" link="harfbuzz-hb-gobject.html#HB-GOBJECT-TYPE-FEATURE:CAPS"/>
+    <keyword type="macro" name="HB_GOBJECT_TYPE_GLYPH_INFO" link="harfbuzz-hb-gobject.html#HB-GOBJECT-TYPE-GLYPH-INFO:CAPS"/>
+    <keyword type="macro" name="HB_GOBJECT_TYPE_GLYPH_POSITION" link="harfbuzz-hb-gobject.html#HB-GOBJECT-TYPE-GLYPH-POSITION:CAPS"/>
+    <keyword type="macro" name="HB_GOBJECT_TYPE_SEGMENT_PROPERTIES" link="harfbuzz-hb-gobject.html#HB-GOBJECT-TYPE-SEGMENT-PROPERTIES:CAPS"/>
+    <keyword type="macro" name="HB_GOBJECT_TYPE_SET" link="harfbuzz-hb-gobject.html#HB-GOBJECT-TYPE-SET:CAPS"/>
+    <keyword type="macro" name="HB_GOBJECT_TYPE_USER_DATA_KEY" link="harfbuzz-hb-gobject.html#HB-GOBJECT-TYPE-USER-DATA-KEY:CAPS"/>
     <keyword type="function" name="hb_graphite2_face_get_gr_face ()" link="harfbuzz-hb-graphite2.html#hb-graphite2-face-get-gr-face"/>
     <keyword type="macro" name="HB_GRAPHITE2_TAG_SILF" link="harfbuzz-hb-graphite2.html#HB-GRAPHITE2-TAG-SILF:CAPS"/>
     <keyword type="function" name="hb_icu_get_unicode_funcs ()" link="harfbuzz-hb-icu.html#hb-icu-get-unicode-funcs"/>
     <keyword type="constant" name="HB_OT_COLOR_PALETTE_FLAG_DEFAULT" link="harfbuzz-hb-ot-color.html#HB-OT-COLOR-PALETTE-FLAG-DEFAULT:CAPS"/>
     <keyword type="constant" name="HB_OT_COLOR_PALETTE_FLAG_USABLE_WITH_LIGHT_BACKGROUND" link="harfbuzz-hb-ot-color.html#HB-OT-COLOR-PALETTE-FLAG-USABLE-WITH-LIGHT-BACKGROUND:CAPS"/>
     <keyword type="constant" name="HB_OT_COLOR_PALETTE_FLAG_USABLE_WITH_DARK_BACKGROUND" link="harfbuzz-hb-ot-color.html#HB-OT-COLOR-PALETTE-FLAG-USABLE-WITH-DARK-BACKGROUND:CAPS"/>
+    <keyword type="constant" name="HB_OT_LAYOUT_BASELINE_TAG_ROMAN" link="harfbuzz-hb-ot-layout.html#HB-OT-LAYOUT-BASELINE-TAG-ROMAN:CAPS"/>
+    <keyword type="constant" name="HB_OT_LAYOUT_BASELINE_TAG_HANGING" link="harfbuzz-hb-ot-layout.html#HB-OT-LAYOUT-BASELINE-TAG-HANGING:CAPS"/>
+    <keyword type="constant" name="HB_OT_LAYOUT_BASELINE_TAG_IDEO_FACE_BOTTOM_OR_LEFT" link="harfbuzz-hb-ot-layout.html#HB-OT-LAYOUT-BASELINE-TAG-IDEO-FACE-BOTTOM-OR-LEFT:CAPS"/>
+    <keyword type="constant" name="HB_OT_LAYOUT_BASELINE_TAG_IDEO_FACE_TOP_OR_RIGHT" link="harfbuzz-hb-ot-layout.html#HB-OT-LAYOUT-BASELINE-TAG-IDEO-FACE-TOP-OR-RIGHT:CAPS"/>
+    <keyword type="constant" name="HB_OT_LAYOUT_BASELINE_TAG_IDEO_EMBOX_BOTTOM_OR_LEFT" link="harfbuzz-hb-ot-layout.html#HB-OT-LAYOUT-BASELINE-TAG-IDEO-EMBOX-BOTTOM-OR-LEFT:CAPS"/>
+    <keyword type="constant" name="HB_OT_LAYOUT_BASELINE_TAG_IDEO_EMBOX_TOP_OR_RIGHT" link="harfbuzz-hb-ot-layout.html#HB-OT-LAYOUT-BASELINE-TAG-IDEO-EMBOX-TOP-OR-RIGHT:CAPS"/>
+    <keyword type="constant" name="HB_OT_LAYOUT_BASELINE_TAG_MATH" link="harfbuzz-hb-ot-layout.html#HB-OT-LAYOUT-BASELINE-TAG-MATH:CAPS"/>
+    <keyword type="constant" name="_HB_OT_LAYOUT_BASELINE_TAG_MAX_VALUE" link="harfbuzz-hb-ot-layout.html#HB-OT-LAYOUT-BASELINE-TAG-MAX-VALUE:CAPS"/>
     <keyword type="constant" name="HB_OT_LAYOUT_GLYPH_CLASS_UNCLASSIFIED" link="harfbuzz-hb-ot-layout.html#HB-OT-LAYOUT-GLYPH-CLASS-UNCLASSIFIED:CAPS"/>
     <keyword type="constant" name="HB_OT_LAYOUT_GLYPH_CLASS_BASE_GLYPH" link="harfbuzz-hb-ot-layout.html#HB-OT-LAYOUT-GLYPH-CLASS-BASE-GLYPH:CAPS"/>
     <keyword type="constant" name="HB_OT_LAYOUT_GLYPH_CLASS_LIGATURE" link="harfbuzz-hb-ot-layout.html#HB-OT-LAYOUT-GLYPH-CLASS-LIGATURE:CAPS"/>
     <keyword type="constant" name="HB_OT_MATH_KERN_TOP_LEFT" link="harfbuzz-hb-ot-math.html#HB-OT-MATH-KERN-TOP-LEFT:CAPS"/>
     <keyword type="constant" name="HB_OT_MATH_KERN_BOTTOM_RIGHT" link="harfbuzz-hb-ot-math.html#HB-OT-MATH-KERN-BOTTOM-RIGHT:CAPS"/>
     <keyword type="constant" name="HB_OT_MATH_KERN_BOTTOM_LEFT" link="harfbuzz-hb-ot-math.html#HB-OT-MATH-KERN-BOTTOM-LEFT:CAPS"/>
-    <keyword type="constant" name="HB_MATH_GLYPH_PART_FLAG_EXTENDER" link="harfbuzz-hb-ot-math.html#HB-MATH-GLYPH-PART-FLAG-EXTENDER:CAPS"/>
+    <keyword type="constant" name="HB_OT_MATH_GLYPH_PART_FLAG_EXTENDER" link="harfbuzz-hb-ot-math.html#HB-OT-MATH-GLYPH-PART-FLAG-EXTENDER:CAPS"/>
     <keyword type="constant" name="HB_OT_VAR_AXIS_FLAG_HIDDEN" link="harfbuzz-hb-ot-var.html#HB-OT-VAR-AXIS-FLAG-HIDDEN:CAPS"/>
     <keyword type="constant" name="_HB_OT_VAR_AXIS_FLAG_MAX_VALUE" link="harfbuzz-hb-ot-var.html#HB-OT-VAR-AXIS-FLAG-MAX-VALUE:CAPS"/>
     <keyword type="constant" name="HB_AAT_LAYOUT_FEATURE_TYPE_INVALID" link="harfbuzz-hb-aat-layout.html#HB-AAT-LAYOUT-FEATURE-TYPE-INVALID:CAPS"/>
     <keyword type="constant" name="HB_AAT_LAYOUT_FEATURE_SELECTOR_DEFAULT_CJK_ROMAN" link="harfbuzz-hb-aat-layout.html#HB-AAT-LAYOUT-FEATURE-SELECTOR-DEFAULT-CJK-ROMAN:CAPS"/>
     <keyword type="constant" name="HB_AAT_LAYOUT_FEATURE_SELECTOR_FULL_WIDTH_CJK_ROMAN" link="harfbuzz-hb-aat-layout.html#HB-AAT-LAYOUT-FEATURE-SELECTOR-FULL-WIDTH-CJK-ROMAN:CAPS"/>
     <keyword type="constant" name="_HB_AAT_LAYOUT_FEATURE_SELECTOR_MAX_VALUE" link="harfbuzz-hb-aat-layout.html#HB-AAT-LAYOUT-FEATURE-SELECTOR-MAX-VALUE:CAPS"/>
-    <keyword type="member" name="hb-glyph-position-t.x-advance" link="harfbuzz-hb-buffer.html#hb-glyph-position-t.x-advance"/>
-    <keyword type="member" name="hb-glyph-position-t.y-advance" link="harfbuzz-hb-buffer.html#hb-glyph-position-t.y-advance"/>
-    <keyword type="member" name="hb-glyph-position-t.x-offset" link="harfbuzz-hb-buffer.html#hb-glyph-position-t.x-offset"/>
-    <keyword type="member" name="hb-glyph-position-t.y-offset" link="harfbuzz-hb-buffer.html#hb-glyph-position-t.y-offset"/>
-    <keyword type="member" name="hb-segment-properties-t.direction" link="harfbuzz-hb-buffer.html#hb-segment-properties-t.direction"/>
-    <keyword type="member" name="hb-segment-properties-t.script" link="harfbuzz-hb-buffer.html#hb-segment-properties-t.script"/>
-    <keyword type="member" name="hb-segment-properties-t.language" link="harfbuzz-hb-buffer.html#hb-segment-properties-t.language"/>
+    <keyword type="member" name="hb-glyph-position-t-struct.x-advance" link="harfbuzz-hb-buffer.html#hb-glyph-position-t-struct.x-advance"/>
+    <keyword type="member" name="hb-glyph-position-t-struct.y-advance" link="harfbuzz-hb-buffer.html#hb-glyph-position-t-struct.y-advance"/>
+    <keyword type="member" name="hb-glyph-position-t-struct.x-offset" link="harfbuzz-hb-buffer.html#hb-glyph-position-t-struct.x-offset"/>
+    <keyword type="member" name="hb-glyph-position-t-struct.y-offset" link="harfbuzz-hb-buffer.html#hb-glyph-position-t-struct.y-offset"/>
+    <keyword type="member" name="hb-segment-properties-t-struct.direction" link="harfbuzz-hb-buffer.html#hb-segment-properties-t-struct.direction"/>
+    <keyword type="member" name="hb-segment-properties-t-struct.script" link="harfbuzz-hb-buffer.html#hb-segment-properties-t-struct.script"/>
+    <keyword type="member" name="hb-segment-properties-t-struct.language" link="harfbuzz-hb-buffer.html#hb-segment-properties-t-struct.language"/>
+    <keyword type="member" name="hb-feature-t-struct.tag" link="harfbuzz-hb-common.html#hb-feature-t-struct.tag"/>
+    <keyword type="member" name="hb-feature-t-struct.value" link="harfbuzz-hb-common.html#hb-feature-t-struct.value"/>
+    <keyword type="member" name="hb-feature-t-struct.start" link="harfbuzz-hb-common.html#hb-feature-t-struct.start"/>
+    <keyword type="member" name="hb-feature-t-struct.end" link="harfbuzz-hb-common.html#hb-feature-t-struct.end"/>
+    <keyword type="member" name="hb-ot-math-glyph-variant-t-struct.glyph" link="harfbuzz-hb-ot-math.html#hb-ot-math-glyph-variant-t-struct.glyph"/>
+    <keyword type="member" name="hb-ot-math-glyph-variant-t-struct.advance" link="harfbuzz-hb-ot-math.html#hb-ot-math-glyph-variant-t-struct.advance"/>
+    <keyword type="member" name="hb-ot-math-glyph-part-t-struct.glyph" link="harfbuzz-hb-ot-math.html#hb-ot-math-glyph-part-t-struct.glyph"/>
+    <keyword type="member" name="hb-ot-math-glyph-part-t-struct.start-connector-length" link="harfbuzz-hb-ot-math.html#hb-ot-math-glyph-part-t-struct.start-connector-length"/>
+    <keyword type="member" name="hb-ot-math-glyph-part-t-struct.end-connector-length" link="harfbuzz-hb-ot-math.html#hb-ot-math-glyph-part-t-struct.end-connector-length"/>
+    <keyword type="member" name="hb-ot-math-glyph-part-t-struct.full-advance" link="harfbuzz-hb-ot-math.html#hb-ot-math-glyph-part-t-struct.full-advance"/>
+    <keyword type="member" name="hb-ot-math-glyph-part-t-struct.flags" link="harfbuzz-hb-ot-math.html#hb-ot-math-glyph-part-t-struct.flags"/>
   </functions>
 </book>
index c2fcb4c..12cfdee 100644 (file)
@@ -4,7 +4,7 @@
 <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
 <title>HarfBuzz Manual: HarfBuzz Manual</title>
 <meta name="generator" content="DocBook XSL Stylesheets Vsnapshot">
-<meta name="description" content="HarfBuzz  HarfBuzz is an OpenType text shaping engine. Using the HarfBuzz library allows programs to convert a sequence of Unicode input into properly formatted and positioned glyph output—for any writing system and language. The canonical source-code tree is available at github.com/harfbuzz/harfbuzz and is also available at cgit.freedesktop.org/harfbuzz. See for release tarballs.">
+<meta name="description" content="HarfBuzz  HarfBuzz is an OpenType text shaping engine. Using the HarfBuzz library allows programs to convert a sequence of Unicode input into properly formatted and positioned glyph output—for any writing system and language. The canonical source-code tree is available at github.com/harfbuzz/harfbuzz. See for release tarballs.">
 <link rel="home" href="index.html" title="HarfBuzz Manual">
 <link rel="next" href="pt01.html" title="Part I. User's manual">
 <meta name="generator" content="GTK-Doc V1.29 (XML mode)">
@@ -27,9 +27,7 @@
       </p>
 <p>
        The canonical source-code tree is available at
-        <a class="ulink" href="https://github.com/harfbuzz/harfbuzz" target="_top">github.com/harfbuzz/harfbuzz</a>
-        and is also available at
-        <a class="ulink" href="http://cgit.freedesktop.org/harfbuzz/" target="_top">cgit.freedesktop.org/harfbuzz</a>.
+        <a class="ulink" href="https://github.com/harfbuzz/harfbuzz" target="_top">github.com/harfbuzz/harfbuzz</a>.
        See <a class="xref" href="install-harfbuzz.html#download" title="Downloading HarfBuzz">Downloading HarfBuzz</a> for
        release tarballs.
       </p>
 <dt><span class="section"><a href="graphite-shaping.html">Graphite shaping</a></span></dt>
 <dt><span class="section"><a href="aat-shaping.html">AAT shaping</a></span></dt>
 </dl></dd>
+<dt><span class="chapter"><a href="object-model.html">The HarfBuzz object model</a></span></dt>
+<dd><dl>
+<dt><span class="section"><a href="object-model.html#object-model-intro">An overview of data types in HarfBuzz</a></span></dt>
+<dt><span class="section"><a href="object-model-object-types.html">Objects in HarfBuzz</a></span></dt>
+<dt><span class="section"><a href="object-model-lifecycle.html">Object lifecycle management</a></span></dt>
+<dt><span class="section"><a href="object-model-user-data.html">User data</a></span></dt>
+<dt><span class="section"><a href="object-model-blobs.html">Blobs</a></span></dt>
+</dl></dd>
 <dt><span class="chapter"><a href="buffers-language-script-and-direction.html">Buffers, language, script and direction</a></span></dt>
 <dd><dl>
 <dt><span class="section"><a href="buffers-language-script-and-direction.html#creating-and-destroying-buffers">Creating and destroying buffers</a></span></dt>
 <dt><span class="section"><a href="adding-text-to-the-buffer.html">Adding text to the buffer</a></span></dt>
 <dt><span class="section"><a href="setting-buffer-properties.html">Setting buffer properties</a></span></dt>
-<dt><span class="section"><a href="what-about-the-other-scripts.html">What about the other scripts?</a></span></dt>
 <dt><span class="section"><a href="customizing-unicode-functions.html">Customizing Unicode functions</a></span></dt>
 </dl></dd>
-<dt><span class="chapter"><a href="fonts-and-faces.html">Fonts and faces</a></span></dt>
+<dt><span class="chapter"><a href="fonts-and-faces.html">Fonts, faces, and output</a></span></dt>
+<dd><dl>
+<dt><span class="section"><a href="fonts-and-faces.html#fonts-and-faces-objects">Font and face objects</a></span></dt>
+<dt><span class="section"><a href="fonts-and-faces-custom-functions.html">Customizing font functions</a></span></dt>
+<dt><span class="section"><a href="fonts-and-faces-native-opentype.html">Font objects and HarfBuzz's native OpenType implementation</a></span></dt>
+<dt><span class="section"><a href="fonts-and-faces-variable.html">Working with OpenType Variable Fonts</a></span></dt>
+</dl></dd>
+<dt><span class="chapter"><a href="shaping-and-shape-plans.html">Shaping and shape plans</a></span></dt>
 <dd><dl>
-<dt><span class="section"><a href="fonts-and-faces.html#using-freetype">Using FreeType</a></span></dt>
-<dt><span class="section"><a href="using-harfbuzzs-native-opentype-implementation.html">Using HarfBuzz's native OpenType implementation</a></span></dt>
-<dt><span class="section"><a href="using-your-own-font-functions.html">Using your own font functions</a></span></dt>
+<dt><span class="section"><a href="shaping-and-shape-plans.html#shaping-buffer-output">Shaping and buffer output</a></span></dt>
+<dt><span class="section"><a href="shaping-opentype-features.html">OpenType features</a></span></dt>
+<dt><span class="section"><a href="shaping-shaper-selection.html">Shaper selection</a></span></dt>
+<dt><span class="section"><a href="shaping-plans-and-caching.html">Plans and caching</a></span></dt>
 </dl></dd>
 <dt><span class="chapter"><a href="clusters.html">Clusters</a></span></dt>
 <dd><dl>
 <dt><span class="section"><a href="level-2.html#other-considerations-in-level-2">Other considerations in level 2</a></span></dt>
 </dl></dd>
 </dl></dd>
-<dt><span class="chapter"><a href="shaping-and-shape-plans.html">Shaping and shape plans</a></span></dt>
+<dt><span class="chapter"><a href="utilities.html">Utilities</a></span></dt>
 <dd><dl>
-<dt><span class="section"><a href="shaping-and-shape-plans.html#opentype-features">OpenType features</a></span></dt>
-<dt><span class="section"><a href="plans-and-caching.html">Plans and caching</a></span></dt>
+<dt><span class="section"><a href="utilities.html#utilities-command-line-tools">Command-line tools</a></span></dt>
+<dd><dl>
+<dt><span class="section"><a href="utilities.html#utilities-command-line-hbshape">hb-shape</a></span></dt>
+<dt><span class="section"><a href="utilities.html#utilities-command-line-hbview">hb-view</a></span></dt>
+<dt><span class="section"><a href="utilities.html#utilities-command-line-hbsubset">hb-subset</a></span></dt>
+</dl></dd>
+<dt><span class="section"><a href="utilities-common-types-apis.html">Common data types and APIs</a></span></dt>
+<dt><span class="section"><a href="utilities-ucdn.html">UCDN</a></span></dt>
 </dl></dd>
 </dl></dd>
 <dt><span class="part"><a href="pt02.html">II. Reference manual</a></span></dt>
 <dd><dl>
-<dt><span class="chapter"><a href="ch09.html">Core API</a></span></dt>
+<dt><span class="chapter"><a href="ch11.html">Core API</a></span></dt>
 <dd><dl>
 <dt>
 <span class="refentrytitle"><a href="harfbuzz-hb-blob.html">hb-blob</a></span><span class="refpurpose"> — Binary data containers</span>
 <span class="refentrytitle"><a href="harfbuzz-hb-version.html">hb-version</a></span><span class="refpurpose"> — Information about the version of HarfBuzz in use</span>
 </dt>
 </dl></dd>
-<dt><span class="chapter"><a href="ch10.html">OpenType API</a></span></dt>
+<dt><span class="chapter"><a href="ch12.html">OpenType API</a></span></dt>
 <dd><dl>
 <dt>
 <span class="refentrytitle"><a href="harfbuzz-hb-ot-color.html">hb-ot-color</a></span><span class="refpurpose"> — OpenType Color Fonts</span>
 <span class="refentrytitle"><a href="harfbuzz-hb-ot-var.html">hb-ot-var</a></span><span class="refpurpose"> — OpenType Font Variations</span>
 </dt>
 </dl></dd>
-<dt><span class="chapter"><a href="ch11.html">Apple Advanced Typography API</a></span></dt>
+<dt><span class="chapter"><a href="ch13.html">Apple Advanced Typography API</a></span></dt>
 <dd><dl><dt>
 <span class="refentrytitle"><a href="harfbuzz-hb-aat-layout.html">hb-aat-layout</a></span><span class="refpurpose"> — Apple Advanced Typography Layout</span>
 </dt></dl></dd>
-<dt><span class="chapter"><a href="ch12.html">Integration API</a></span></dt>
+<dt><span class="chapter"><a href="ch14.html">Integration API</a></span></dt>
 <dd><dl>
 <dt>
 <span class="refentrytitle"><a href="harfbuzz-hb-coretext.html">hb-coretext</a></span><span class="refpurpose"> — CoreText integration</span>
index a30f6f6..25670c2 100644 (file)
@@ -7,7 +7,7 @@
 <link rel="home" href="index.html" title="HarfBuzz Manual">
 <link rel="up" href="clusters.html" title="Clusters">
 <link rel="prev" href="the-distinction-between-levels-0-and-1.html" title="The distinction between levels 0 and 1">
-<link rel="next" href="shaping-and-shape-plans.html" title="Shaping and shape plans">
+<link rel="next" href="utilities.html" title="Utilities">
 <meta name="generator" content="GTK-Doc V1.29 (XML mode)">
 <link rel="stylesheet" href="style.css" type="text/css">
 </head>
@@ -17,7 +17,7 @@
 <td><a accesskey="h" href="index.html"><img src="home.png" width="16" height="16" border="0" alt="Home"></a></td>
 <td><a accesskey="u" href="clusters.html"><img src="up.png" width="16" height="16" border="0" alt="Up"></a></td>
 <td><a accesskey="p" href="the-distinction-between-levels-0-and-1.html"><img src="left.png" width="16" height="16" border="0" alt="Prev"></a></td>
-<td><a accesskey="n" href="shaping-and-shape-plans.html"><img src="right.png" width="16" height="16" border="0" alt="Next"></a></td>
+<td><a accesskey="n" href="utilities.html"><img src="right.png" width="16" height="16" border="0" alt="Next"></a></td>
 </tr></table>
 <div class="section">
 <div class="titlepage"><div><div><h2 class="title" style="clear: both">
diff --git a/docs/html/object-model-blobs.html b/docs/html/object-model-blobs.html
new file mode 100644 (file)
index 0000000..dece05f
--- /dev/null
@@ -0,0 +1,56 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>Blobs: HarfBuzz Manual</title>
+<meta name="generator" content="DocBook XSL Stylesheets Vsnapshot">
+<link rel="home" href="index.html" title="HarfBuzz Manual">
+<link rel="up" href="object-model.html" title="The HarfBuzz object model">
+<link rel="prev" href="object-model-user-data.html" title="User data">
+<link rel="next" href="buffers-language-script-and-direction.html" title="Buffers, language, script and direction">
+<meta name="generator" content="GTK-Doc V1.29 (XML mode)">
+<link rel="stylesheet" href="style.css" type="text/css">
+</head>
+<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
+<table class="navigation" id="top" width="100%" summary="Navigation header" cellpadding="2" cellspacing="5"><tr valign="middle">
+<td width="100%" align="left" class="shortcuts"></td>
+<td><a accesskey="h" href="index.html"><img src="home.png" width="16" height="16" border="0" alt="Home"></a></td>
+<td><a accesskey="u" href="object-model.html"><img src="up.png" width="16" height="16" border="0" alt="Up"></a></td>
+<td><a accesskey="p" href="object-model-user-data.html"><img src="left.png" width="16" height="16" border="0" alt="Prev"></a></td>
+<td><a accesskey="n" href="buffers-language-script-and-direction.html"><img src="right.png" width="16" height="16" border="0" alt="Next"></a></td>
+</tr></table>
+<div class="section">
+<div class="titlepage"><div><div><h2 class="title" style="clear: both">
+<a name="object-model-blobs"></a>Blobs</h2></div></div></div>
+<p>
+      While most of HarfBuzz's object types are specific to the
+      shaping process, <span class="emphasis"><em>blobs</em></span> are somewhat
+      different.
+    </p>
+<p>
+      Blobs are an abstraction desgined to negotiate lifecycle and
+      permissions for raw pieces of data.  For example, when you load
+      the raw font data into memory and want to pass it to HarfBuzz,
+      you do so in a <code class="literal">hb_blob_t</code> wrapper.
+    </p>
+<p>
+      This allows you to take advantage of HarffBuzz's
+      reference-counting and <code class="function">destroy</code>
+      callbacks. If you allocated the memory for the data using 
+      <code class="function">malloc()</code>, you would create the blob using
+    </p>
+<pre class="programlisting">
+      hb_blob_create (data, length, HB_MEMORY_MODE_WRITABLE, NULL, free)
+    </pre>
+<p>
+      That way, HarfBuzz will call <code class="function">free()</code> on the
+      allocated memory whenever the blob drops its last reference and
+      is deconstructed.  Consequently, the user code can stop worrying
+      about freeing memory and let the reference-counting machinery
+      take care of that. 
+    </p>
+</div>
+<div class="footer">
+<hr>Generated by GTK-Doc V1.29</div>
+</body>
+</html>
\ No newline at end of file
diff --git a/docs/html/object-model-lifecycle.html b/docs/html/object-model-lifecycle.html
new file mode 100644 (file)
index 0000000..5e9adfd
--- /dev/null
@@ -0,0 +1,97 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>Object lifecycle management: HarfBuzz Manual</title>
+<meta name="generator" content="DocBook XSL Stylesheets Vsnapshot">
+<link rel="home" href="index.html" title="HarfBuzz Manual">
+<link rel="up" href="object-model.html" title="The HarfBuzz object model">
+<link rel="prev" href="object-model-object-types.html" title="Objects in HarfBuzz">
+<link rel="next" href="object-model-user-data.html" title="User data">
+<meta name="generator" content="GTK-Doc V1.29 (XML mode)">
+<link rel="stylesheet" href="style.css" type="text/css">
+</head>
+<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
+<table class="navigation" id="top" width="100%" summary="Navigation header" cellpadding="2" cellspacing="5"><tr valign="middle">
+<td width="100%" align="left" class="shortcuts"></td>
+<td><a accesskey="h" href="index.html"><img src="home.png" width="16" height="16" border="0" alt="Home"></a></td>
+<td><a accesskey="u" href="object-model.html"><img src="up.png" width="16" height="16" border="0" alt="Up"></a></td>
+<td><a accesskey="p" href="object-model-object-types.html"><img src="left.png" width="16" height="16" border="0" alt="Prev"></a></td>
+<td><a accesskey="n" href="object-model-user-data.html"><img src="right.png" width="16" height="16" border="0" alt="Next"></a></td>
+</tr></table>
+<div class="section">
+<div class="titlepage"><div><div><h2 class="title" style="clear: both">
+<a name="object-model-lifecycle"></a>Object lifecycle management</h2></div></div></div>
+<p>
+      Each object type in HarfBuzz provides a
+      <code class="function">create()</code> method. Some object types provide
+      additional variants of <code class="function">create()</code> to handle
+      special cases or to speed up common tasks; those variants are
+      documented in the API reference. For example,
+      <code class="function">hb_blob_create_from_file()</code> constructs a new
+      blob directly from the contents of a file.
+    </p>
+<p>
+      All objects are created with an initial reference count of
+      <code class="literal">1</code>. Client programs can increase the reference
+      count on an object by calling its
+      <code class="function">reference()</code> method. Whenever a client
+      program is finished with an object, it should call its 
+      corresponding <code class="function">destroy()</code> method. The destroy
+      method will decrease the reference count on the object and,
+      whenever the reference count reaches zero, it will also destroy
+      the object and free all of the associated memory.
+    </p>
+<p>
+      All of HarfBuzz's object-lifecycle-management APIs are
+      thread-safe (unless you compiled HarfBuzz from source with the
+      <code class="literal">HB_NO_MT</code> configuration flag), even when the
+      object as a whole is not thread-safe. 
+      It is also permissible to <code class="function">reference()</code> or to 
+      <code class="function">destroy()</code> the <code class="literal">NULL</code>
+      value.
+    </p>
+<p>
+      Some objects are thread-safe after they have been constructed
+      and set up. The general pattern is to
+      <code class="function">create()</code> the object, make a few
+      <code class="function">set_*()</code> calls to set up the
+      object, and then use it without further modification.
+    </p>
+<p>
+      To ensure that such an object is not modified, client programs
+      can explicitly mark an object as immutable. HarfBuzz provides
+      <code class="function">make_immutable()</code> methods to mark an object
+      as immutable and <code class="function">is_immutable()</code> methods to
+      test whether or not an object is immutable. Attempts to use
+      setter functions on immutable objects will fail silently; see the API
+      Reference manual for specifics. 
+    </p>
+<p>
+      Note also that there are no "make mutable" methods. If client
+      programs need to alter an object previously marked as immutable,
+      they will need to make a duplicate of the original.
+    </p>
+<p>
+      Finally, object constructors (and, indeed, as much of the
+      shaping API as possible) will never return
+      <code class="literal">NULL</code>.  Instead, if there is an allocation
+      error, each constructor will return an “empty” object
+      singleton.
+    </p>
+<p>
+      These empty-object singletons are inert and safe (although
+      typically useless) to pass around.  This design choice avoids
+      having to check for <code class="literal">NULL</code> pointers all
+      throughout the code.
+    </p>
+<p>
+      In addition, this “empty” object singleton can also be accessed
+      using the <code class="function">get_empty()</code> method of the object
+      type in question.
+    </p>
+</div>
+<div class="footer">
+<hr>Generated by GTK-Doc V1.29</div>
+</body>
+</html>
\ No newline at end of file
diff --git a/docs/html/object-model-object-types.html b/docs/html/object-model-object-types.html
new file mode 100644 (file)
index 0000000..330511c
--- /dev/null
@@ -0,0 +1,84 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>Objects in HarfBuzz: HarfBuzz Manual</title>
+<meta name="generator" content="DocBook XSL Stylesheets Vsnapshot">
+<link rel="home" href="index.html" title="HarfBuzz Manual">
+<link rel="up" href="object-model.html" title="The HarfBuzz object model">
+<link rel="prev" href="object-model.html" title="The HarfBuzz object model">
+<link rel="next" href="object-model-lifecycle.html" title="Object lifecycle management">
+<meta name="generator" content="GTK-Doc V1.29 (XML mode)">
+<link rel="stylesheet" href="style.css" type="text/css">
+</head>
+<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
+<table class="navigation" id="top" width="100%" summary="Navigation header" cellpadding="2" cellspacing="5"><tr valign="middle">
+<td width="100%" align="left" class="shortcuts"></td>
+<td><a accesskey="h" href="index.html"><img src="home.png" width="16" height="16" border="0" alt="Home"></a></td>
+<td><a accesskey="u" href="object-model.html"><img src="up.png" width="16" height="16" border="0" alt="Up"></a></td>
+<td><a accesskey="p" href="object-model.html"><img src="left.png" width="16" height="16" border="0" alt="Prev"></a></td>
+<td><a accesskey="n" href="object-model-lifecycle.html"><img src="right.png" width="16" height="16" border="0" alt="Next"></a></td>
+</tr></table>
+<div class="section">
+<div class="titlepage"><div><div><h2 class="title" style="clear: both">
+<a name="object-model-object-types"></a>Objects in HarfBuzz</h2></div></div></div>
+<p>
+      <span class="emphasis"><em>Object types:</em></span> Opaque struct types are used
+      for what HarfBuzz loosely calls "objects."  This doesn’t have
+      much to do with the terminology from object-oriented programming
+      (OOP), although some of the concepts are similar.
+    </p>
+<p>
+      In HarfBuzz, all object types provide certain
+      lifecycle-management APIs.  Objects are reference-counted, and
+      constructed with various <code class="function">create()</code> methods, referenced via
+      <code class="function">reference()</code> and dereferenced using
+      <code class="function">destroy()</code>.
+    </p>
+<p>
+      For example,
+      the <code class="literal">hb_buffer_t</code> object has
+      <code class="function">hb_buffer_create()</code> as its constructor,
+      <code class="function">hb_buffer_reference()</code> to reference, and
+      <code class="function">hb_buffer_destroy()</code> to dereference. 
+    </p>
+<p>
+      After construction, each object's properties are accessible only
+      through the setter and getter functions described in the API
+      Reference manual.
+    </p>
+<p>
+      Key object types provided by HarfBuzz include:
+    </p>
+<div class="itemizedlist"><ul class="itemizedlist compact" style="list-style-type: disc; ">
+<li class="listitem"><p>
+         <span class="emphasis"><em>blobs</em></span>, which act as low-level wrappers around binary
+         data. Blobs are typically used to hold the contents of a
+         binary font file.
+       </p></li>
+<li class="listitem"><p>
+         <span class="emphasis"><em>faces</em></span>, which represent typefaces from a
+         font file, but without specific parameters (such as size) set.
+       </p></li>
+<li class="listitem"><p>
+         <span class="emphasis"><em>fonts</em></span>, which represent instances of a
+         face with all of their parameters specified.
+       </p></li>
+<li class="listitem"><p>
+         <span class="emphasis"><em>buffers</em></span>, which hold Unicode code points
+         for characters (before shaping) and the shaped glyph output
+         (after shaping).
+       </p></li>
+<li class="listitem"><p>
+         <span class="emphasis"><em>shape plans</em></span>, which store the settings
+         that HarfBuzz will use when shaping a particular text
+         segment. Shape plans are not generally used by client
+         programs directly, but as we will see in a later chapter,
+         they are still valuable to understand.
+       </p></li>
+</ul></div>
+</div>
+<div class="footer">
+<hr>Generated by GTK-Doc V1.29</div>
+</body>
+</html>
\ No newline at end of file
diff --git a/docs/html/object-model-user-data.html b/docs/html/object-model-user-data.html
new file mode 100644 (file)
index 0000000..9ffd864
--- /dev/null
@@ -0,0 +1,59 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>User data: HarfBuzz Manual</title>
+<meta name="generator" content="DocBook XSL Stylesheets Vsnapshot">
+<link rel="home" href="index.html" title="HarfBuzz Manual">
+<link rel="up" href="object-model.html" title="The HarfBuzz object model">
+<link rel="prev" href="object-model-lifecycle.html" title="Object lifecycle management">
+<link rel="next" href="object-model-blobs.html" title="Blobs">
+<meta name="generator" content="GTK-Doc V1.29 (XML mode)">
+<link rel="stylesheet" href="style.css" type="text/css">
+</head>
+<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
+<table class="navigation" id="top" width="100%" summary="Navigation header" cellpadding="2" cellspacing="5"><tr valign="middle">
+<td width="100%" align="left" class="shortcuts"></td>
+<td><a accesskey="h" href="index.html"><img src="home.png" width="16" height="16" border="0" alt="Home"></a></td>
+<td><a accesskey="u" href="object-model.html"><img src="up.png" width="16" height="16" border="0" alt="Up"></a></td>
+<td><a accesskey="p" href="object-model-lifecycle.html"><img src="left.png" width="16" height="16" border="0" alt="Prev"></a></td>
+<td><a accesskey="n" href="object-model-blobs.html"><img src="right.png" width="16" height="16" border="0" alt="Next"></a></td>
+</tr></table>
+<div class="section">
+<div class="titlepage"><div><div><h2 class="title" style="clear: both">
+<a name="object-model-user-data"></a>User data</h2></div></div></div>
+<p>
+      To better integrate with client programs, HarfBuzz's objects
+      offer a "user data" mechanism that can be used to attach
+      arbitrary data to the object.  User-data attachment can be
+      useful for tying the lifecycles of various pieces of data
+      together, or for creating language bindings. 
+    </p>
+<p>
+      Each object type has a <code class="function">set_user_data()</code>
+      method and a <code class="function">get_user_data()</code> method. The
+      <code class="function">set_user_data()</code> methods take a client-provided
+      <code class="literal">key</code> and a pointer,
+      <code class="literal">user_data</code>, pointing to the data itself. Once
+      the key-data pair has been attached to the object, the
+      <code class="function">get_user_data()</code> method can be called with
+      the key, returning the <code class="function">user_data</code> pointer.
+    </p>
+<p>
+      The <code class="function">set_user_data()</code> methods also support an
+      optional <code class="function">destroy</code> callback. Client programs
+      can set the <code class="function">destroy</code> callback and receive
+      notification from HarfBuzz whenever the object is destructed.
+    </p>
+<p>
+      Finally, each <code class="function">set_user_data()</code> method allows
+      the client program to set a <code class="literal">replace</code> Boolean
+      indicating whether or not the function call should replace any
+      existing <code class="literal">user_data</code>
+      associated with the specified key.
+    </p>
+</div>
+<div class="footer">
+<hr>Generated by GTK-Doc V1.29</div>
+</body>
+</html>
\ No newline at end of file
diff --git a/docs/html/object-model.html b/docs/html/object-model.html
new file mode 100644 (file)
index 0000000..838d320
--- /dev/null
@@ -0,0 +1,73 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>The HarfBuzz object model: HarfBuzz Manual</title>
+<meta name="generator" content="DocBook XSL Stylesheets Vsnapshot">
+<link rel="home" href="index.html" title="HarfBuzz Manual">
+<link rel="up" href="pt01.html" title="Part I. User's manual">
+<link rel="prev" href="aat-shaping.html" title="AAT shaping">
+<link rel="next" href="object-model-object-types.html" title="Objects in HarfBuzz">
+<meta name="generator" content="GTK-Doc V1.29 (XML mode)">
+<link rel="stylesheet" href="style.css" type="text/css">
+</head>
+<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
+<table class="navigation" id="top" width="100%" summary="Navigation header" cellpadding="2" cellspacing="5"><tr valign="middle">
+<td width="100%" align="left" class="shortcuts"></td>
+<td><a accesskey="h" href="index.html"><img src="home.png" width="16" height="16" border="0" alt="Home"></a></td>
+<td><a accesskey="u" href="pt01.html"><img src="up.png" width="16" height="16" border="0" alt="Up"></a></td>
+<td><a accesskey="p" href="aat-shaping.html"><img src="left.png" width="16" height="16" border="0" alt="Prev"></a></td>
+<td><a accesskey="n" href="object-model-object-types.html"><img src="right.png" width="16" height="16" border="0" alt="Next"></a></td>
+</tr></table>
+<div class="chapter">
+<div class="titlepage"><div><div><h2 class="title">
+<a name="object-model"></a>The HarfBuzz object model</h2></div></div></div>
+<div class="toc"><dl class="toc">
+<dt><span class="section"><a href="object-model.html#object-model-intro">An overview of data types in HarfBuzz</a></span></dt>
+<dt><span class="section"><a href="object-model-object-types.html">Objects in HarfBuzz</a></span></dt>
+<dt><span class="section"><a href="object-model-lifecycle.html">Object lifecycle management</a></span></dt>
+<dt><span class="section"><a href="object-model-user-data.html">User data</a></span></dt>
+<dt><span class="section"><a href="object-model-blobs.html">Blobs</a></span></dt>
+</dl></div>
+<div class="section">
+<div class="titlepage"><div><div><h2 class="title" style="clear: both">
+<a name="object-model-intro"></a>An overview of data types in HarfBuzz</h2></div></div></div>
+<p>
+      HarfBuzz features two kinds of data types: non-opaque,
+      pass-by-value types and opaque, heap-allocated types.  This kind
+      of separation is common in C libraries that have to provide
+      API/ABI compatibility (almost) indefinitely. 
+    </p>
+<p>
+      <span class="emphasis"><em>Value types:</em></span> The non-opaque, pass-by-value
+      types include integer types, enums, and small structs.  Exposing
+      a struct in the public API makes it impossible to expand the
+      struct in the future. As such, exposing structs is reserved for
+      cases where it’s extremely inefficient to do otherwise.
+    </p>
+<p>
+      In HarfBuzz, several structs, like <code class="literal">hb_glyph_info_t</code> and
+      <code class="literal">hb_glyph_position_t</code>, fall into that efficiency-sensitive
+      category and are non-opaque.
+    </p>
+<p>
+      For all non-opaque structs where future extensibility may be
+      necessary, reserved members are included to hold space for
+      possible future members.  As such, it’s important to provide
+      <code class="function">equal()</code>, and <code class="function">hash()</code>
+      methods for such structs, allowing users of the API do
+      effectively deal with the type without having to 
+      adapt their code to future changes. 
+    </p>
+<p>
+      Important value types provided by HarfBuzz include the structs
+      for working with Unicode code points, glyphs, and tags for font
+      tables and features, as well as the enums for many Unicode and
+      OpenType properties.
+    </p>
+</div>
+</div>
+<div class="footer">
+<hr>Generated by GTK-Doc V1.29</div>
+</body>
+</html>
\ No newline at end of file
diff --git a/docs/html/plans-and-caching.html b/docs/html/plans-and-caching.html
deleted file mode 100644 (file)
index 7407f1e..0000000
+++ /dev/null
@@ -1,31 +0,0 @@
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
-<html>
-<head>
-<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
-<title>Plans and caching: HarfBuzz Manual</title>
-<meta name="generator" content="DocBook XSL Stylesheets Vsnapshot">
-<link rel="home" href="index.html" title="HarfBuzz Manual">
-<link rel="up" href="shaping-and-shape-plans.html" title="Shaping and shape plans">
-<link rel="prev" href="shaping-and-shape-plans.html" title="Shaping and shape plans">
-<link rel="next" href="pt02.html" title="Part II. Reference manual">
-<meta name="generator" content="GTK-Doc V1.29 (XML mode)">
-<link rel="stylesheet" href="style.css" type="text/css">
-</head>
-<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
-<table class="navigation" id="top" width="100%" summary="Navigation header" cellpadding="2" cellspacing="5"><tr valign="middle">
-<td width="100%" align="left" class="shortcuts"></td>
-<td><a accesskey="h" href="index.html"><img src="home.png" width="16" height="16" border="0" alt="Home"></a></td>
-<td><a accesskey="u" href="shaping-and-shape-plans.html"><img src="up.png" width="16" height="16" border="0" alt="Up"></a></td>
-<td><a accesskey="p" href="shaping-and-shape-plans.html"><img src="left.png" width="16" height="16" border="0" alt="Prev"></a></td>
-<td><a accesskey="n" href="pt02.html"><img src="right.png" width="16" height="16" border="0" alt="Next"></a></td>
-</tr></table>
-<div class="section">
-<div class="titlepage"><div><div><h2 class="title" style="clear: both">
-<a name="plans-and-caching"></a>Plans and caching</h2></div></div></div>
-<p>
-    </p>
-</div>
-<div class="footer">
-<hr>Generated by GTK-Doc V1.29</div>
-</body>
-</html>
\ No newline at end of file
index 90e6f93..9db76e5 100644 (file)
 <dt><span class="section"><a href="graphite-shaping.html">Graphite shaping</a></span></dt>
 <dt><span class="section"><a href="aat-shaping.html">AAT shaping</a></span></dt>
 </dl></dd>
+<dt><span class="chapter"><a href="object-model.html">The HarfBuzz object model</a></span></dt>
+<dd><dl>
+<dt><span class="section"><a href="object-model.html#object-model-intro">An overview of data types in HarfBuzz</a></span></dt>
+<dt><span class="section"><a href="object-model-object-types.html">Objects in HarfBuzz</a></span></dt>
+<dt><span class="section"><a href="object-model-lifecycle.html">Object lifecycle management</a></span></dt>
+<dt><span class="section"><a href="object-model-user-data.html">User data</a></span></dt>
+<dt><span class="section"><a href="object-model-blobs.html">Blobs</a></span></dt>
+</dl></dd>
 <dt><span class="chapter"><a href="buffers-language-script-and-direction.html">Buffers, language, script and direction</a></span></dt>
 <dd><dl>
 <dt><span class="section"><a href="buffers-language-script-and-direction.html#creating-and-destroying-buffers">Creating and destroying buffers</a></span></dt>
 <dt><span class="section"><a href="adding-text-to-the-buffer.html">Adding text to the buffer</a></span></dt>
 <dt><span class="section"><a href="setting-buffer-properties.html">Setting buffer properties</a></span></dt>
-<dt><span class="section"><a href="what-about-the-other-scripts.html">What about the other scripts?</a></span></dt>
 <dt><span class="section"><a href="customizing-unicode-functions.html">Customizing Unicode functions</a></span></dt>
 </dl></dd>
-<dt><span class="chapter"><a href="fonts-and-faces.html">Fonts and faces</a></span></dt>
+<dt><span class="chapter"><a href="fonts-and-faces.html">Fonts, faces, and output</a></span></dt>
+<dd><dl>
+<dt><span class="section"><a href="fonts-and-faces.html#fonts-and-faces-objects">Font and face objects</a></span></dt>
+<dt><span class="section"><a href="fonts-and-faces-custom-functions.html">Customizing font functions</a></span></dt>
+<dt><span class="section"><a href="fonts-and-faces-native-opentype.html">Font objects and HarfBuzz's native OpenType implementation</a></span></dt>
+<dt><span class="section"><a href="fonts-and-faces-variable.html">Working with OpenType Variable Fonts</a></span></dt>
+</dl></dd>
+<dt><span class="chapter"><a href="shaping-and-shape-plans.html">Shaping and shape plans</a></span></dt>
 <dd><dl>
-<dt><span class="section"><a href="fonts-and-faces.html#using-freetype">Using FreeType</a></span></dt>
-<dt><span class="section"><a href="using-harfbuzzs-native-opentype-implementation.html">Using HarfBuzz's native OpenType implementation</a></span></dt>
-<dt><span class="section"><a href="using-your-own-font-functions.html">Using your own font functions</a></span></dt>
+<dt><span class="section"><a href="shaping-and-shape-plans.html#shaping-buffer-output">Shaping and buffer output</a></span></dt>
+<dt><span class="section"><a href="shaping-opentype-features.html">OpenType features</a></span></dt>
+<dt><span class="section"><a href="shaping-shaper-selection.html">Shaper selection</a></span></dt>
+<dt><span class="section"><a href="shaping-plans-and-caching.html">Plans and caching</a></span></dt>
 </dl></dd>
 <dt><span class="chapter"><a href="clusters.html">Clusters</a></span></dt>
 <dd><dl>
 <dt><span class="section"><a href="level-2.html#other-considerations-in-level-2">Other considerations in level 2</a></span></dt>
 </dl></dd>
 </dl></dd>
-<dt><span class="chapter"><a href="shaping-and-shape-plans.html">Shaping and shape plans</a></span></dt>
+<dt><span class="chapter"><a href="utilities.html">Utilities</a></span></dt>
+<dd><dl>
+<dt><span class="section"><a href="utilities.html#utilities-command-line-tools">Command-line tools</a></span></dt>
 <dd><dl>
-<dt><span class="section"><a href="shaping-and-shape-plans.html#opentype-features">OpenType features</a></span></dt>
-<dt><span class="section"><a href="plans-and-caching.html">Plans and caching</a></span></dt>
+<dt><span class="section"><a href="utilities.html#utilities-command-line-hbshape">hb-shape</a></span></dt>
+<dt><span class="section"><a href="utilities.html#utilities-command-line-hbview">hb-view</a></span></dt>
+<dt><span class="section"><a href="utilities.html#utilities-command-line-hbsubset">hb-subset</a></span></dt>
+</dl></dd>
+<dt><span class="section"><a href="utilities-common-types-apis.html">Common data types and APIs</a></span></dt>
+<dt><span class="section"><a href="utilities-ucdn.html">UCDN</a></span></dt>
 </dl></dd>
 </dl>
 </div>
-<div class="sect1">
-<div class="titlepage"><div><div><h2 class="title" style="clear: both">
-<a name="glyph-information"></a>Glyph information</h2></div></div></div>
-<div class="sect2">
-<div class="titlepage"><div><div><h3 class="title">
-<a name="names-and-numbers"></a>Names and numbers</h3></div></div></div>
-<p>
-    </p>
-</div>
-</div>
 </div>
 <div class="footer">
 <hr>Generated by GTK-Doc V1.29</div>
index 33add13..11b2734 100644 (file)
@@ -6,8 +6,8 @@
 <meta name="generator" content="DocBook XSL Stylesheets Vsnapshot">
 <link rel="home" href="index.html" title="HarfBuzz Manual">
 <link rel="up" href="index.html" title="HarfBuzz Manual">
-<link rel="prev" href="plans-and-caching.html" title="Plans and caching">
-<link rel="next" href="ch09.html" title="Core API">
+<link rel="prev" href="utilities-ucdn.html" title="UCDN">
+<link rel="next" href="ch11.html" title="Core API">
 <meta name="generator" content="GTK-Doc V1.29 (XML mode)">
 <link rel="stylesheet" href="style.css" type="text/css">
 </head>
 <td width="100%" align="left" class="shortcuts"></td>
 <td><a accesskey="h" href="index.html"><img src="home.png" width="16" height="16" border="0" alt="Home"></a></td>
 <td><img src="up-insensitive.png" width="16" height="16" border="0"></td>
-<td><a accesskey="p" href="plans-and-caching.html"><img src="left.png" width="16" height="16" border="0" alt="Prev"></a></td>
-<td><a accesskey="n" href="ch09.html"><img src="right.png" width="16" height="16" border="0" alt="Next"></a></td>
+<td><a accesskey="p" href="utilities-ucdn.html"><img src="left.png" width="16" height="16" border="0" alt="Prev"></a></td>
+<td><a accesskey="n" href="ch11.html"><img src="right.png" width="16" height="16" border="0" alt="Next"></a></td>
 </tr></table>
 <div class="part">
 <div class="titlepage"><div>
 <div><h1 class="title">
 <a name="id-1.3"></a>Part II. Reference manual</h1></div>
 <div><p class="releaseinfo">
-        This document is for HarfBuzz 2.4.0
+        This document is for HarfBuzz 2.6.4
 .
         
       </p></div>
@@ -32,7 +32,7 @@
 <div class="toc">
 <p><b>Table of Contents</b></p>
 <dl class="toc">
-<dt><span class="chapter"><a href="ch09.html">Core API</a></span></dt>
+<dt><span class="chapter"><a href="ch11.html">Core API</a></span></dt>
 <dd><dl>
 <dt>
 <span class="refentrytitle"><a href="harfbuzz-hb-blob.html">hb-blob</a></span><span class="refpurpose"> — Binary data containers</span>
@@ -71,7 +71,7 @@
 <span class="refentrytitle"><a href="harfbuzz-hb-version.html">hb-version</a></span><span class="refpurpose"> — Information about the version of HarfBuzz in use</span>
 </dt>
 </dl></dd>
-<dt><span class="chapter"><a href="ch10.html">OpenType API</a></span></dt>
+<dt><span class="chapter"><a href="ch12.html">OpenType API</a></span></dt>
 <dd><dl>
 <dt>
 <span class="refentrytitle"><a href="harfbuzz-hb-ot-color.html">hb-ot-color</a></span><span class="refpurpose"> — OpenType Color Fonts</span>
 <span class="refentrytitle"><a href="harfbuzz-hb-ot-var.html">hb-ot-var</a></span><span class="refpurpose"> — OpenType Font Variations</span>
 </dt>
 </dl></dd>
-<dt><span class="chapter"><a href="ch11.html">Apple Advanced Typography API</a></span></dt>
+<dt><span class="chapter"><a href="ch13.html">Apple Advanced Typography API</a></span></dt>
 <dd><dl><dt>
 <span class="refentrytitle"><a href="harfbuzz-hb-aat-layout.html">hb-aat-layout</a></span><span class="refpurpose"> — Apple Advanced Typography Layout</span>
 </dt></dl></dd>
-<dt><span class="chapter"><a href="ch12.html">Integration API</a></span></dt>
+<dt><span class="chapter"><a href="ch14.html">Integration API</a></span></dt>
 <dd><dl>
 <dt>
 <span class="refentrytitle"><a href="harfbuzz-hb-coretext.html">hb-coretext</a></span><span class="refpurpose"> — CoreText integration</span>
index e35cf7a..aba2eac 100644 (file)
@@ -7,7 +7,7 @@
 <link rel="home" href="index.html" title="HarfBuzz Manual">
 <link rel="up" href="buffers-language-script-and-direction.html" title="Buffers, language, script and direction">
 <link rel="prev" href="adding-text-to-the-buffer.html" title="Adding text to the buffer">
-<link rel="next" href="what-about-the-other-scripts.html" title="What about the other scripts?">
+<link rel="next" href="customizing-unicode-functions.html" title="Customizing Unicode functions">
 <meta name="generator" content="GTK-Doc V1.29 (XML mode)">
 <link rel="stylesheet" href="style.css" type="text/css">
 </head>
 <td><a accesskey="h" href="index.html"><img src="home.png" width="16" height="16" border="0" alt="Home"></a></td>
 <td><a accesskey="u" href="buffers-language-script-and-direction.html"><img src="up.png" width="16" height="16" border="0" alt="Up"></a></td>
 <td><a accesskey="p" href="adding-text-to-the-buffer.html"><img src="left.png" width="16" height="16" border="0" alt="Prev"></a></td>
-<td><a accesskey="n" href="what-about-the-other-scripts.html"><img src="right.png" width="16" height="16" border="0" alt="Next"></a></td>
+<td><a accesskey="n" href="customizing-unicode-functions.html"><img src="right.png" width="16" height="16" border="0" alt="Next"></a></td>
 </tr></table>
 <div class="section">
 <div class="titlepage"><div><div><h2 class="title" style="clear: both">
 <a name="setting-buffer-properties"></a>Setting buffer properties</h2></div></div></div>
 <p>
+      Buffers containing input characters still need several
+      properties set before HarfBuzz can shape their text correctly.
+    </p>
+<p>
+      Initially, all buffers are set to the
+      <code class="literal">HB_BUFFER_CONTENT_TYPE_INVALID</code> content
+      type. After adding text, the buffer should be set to
+      <code class="literal">HB_BUFFER_CONTENT_TYPE_UNICODE</code> instead, which
+      indicates that it contains un-shaped input
+      characters. After shaping, the buffer will have the
+      <code class="literal">HB_BUFFER_CONTENT_TYPE_GLYPHS</code> content type.
+    </p>
+<p>
+      <code class="function">hb_buffer_add_utf8()</code> and the
+      other UTF functions set the content type of their buffer
+      automatically. But if you are reusing a buffer you may want to
+      check its state with
+      <code class="function">hb_buffer_get_content_type(buffer)</code>. If
+      necessary you can set the content type with
+    </p>
+<pre class="programlisting">
+      hb_buffer_set_content_type(buf, HB_BUFFER_CONTENT_TYPE_UNICODE);
+    </pre>
+<p>
+      to prepare for shaping.
+    </p>
+<p>
+      Buffers also need to carry information about the script,
+      language, and text direction of their contents. You can set
+      these properties individually:
+    </p>
+<pre class="programlisting">
+      hb_buffer_set_direction(buf, HB_DIRECTION_LTR);
+      hb_buffer_set_script(buf, HB_SCRIPT_LATIN);
+      hb_buffer_set_language(buf, hb_language_from_string("en", -1));
+    </pre>
+<p>
+      However, since these properties are often the repeated for
+      multiple text runs, you can also save them in a
+      <code class="literal">hb_segment_properties_t</code> for reuse:
+    </p>
+<pre class="programlisting">
+      hb_segment_properties_t *savedprops;
+      hb_buffer_get_segment_properties (buf, savedprops);
+      ...
+      hb_buffer_set_segment_properties (buf2, savedprops);
+    </pre>
+<p>
+      HarfBuzz also provides getter functions to retrieve a buffer's
+      direction, script, and language properties individually.
+    </p>
+<p>
+      HarfBuzz recognizes four text directions in
+      <span class="type">hb_direction_t</span>: left-to-right
+      (<code class="literal">HB_DIRECTION_LTR</code>), right-to-left (<code class="literal">HB_DIRECTION_RTL</code>),
+      top-to-bottom (<code class="literal">HB_DIRECTION_TTB</code>), and
+      bottom-to-top (<code class="literal">HB_DIRECTION_BTT</code>).  For the
+      script property, HarfBuzz uses identifiers based on the
+      <a class="ulink" href="https://unicode.org/iso15924/" target="_top">ISO 15924
+      standard</a>. For languages, HarfBuzz uses tags based on the
+      <a class="ulink" href="https://tools.ietf.org/html/bcp47" target="_top">IETF BCP 47</a> standard.
+    </p>
+<p>
+      Helper functions are provided to convert character strings into
+      the necessary script and language tag types.
+    </p>
+<p>
+      Two additional buffer properties to be aware of are the
+      "invisible glyph" and the replacement code point. The
+      replacement code point is inserted into buffer output in place of
+      any invalid code points encountered in the input. By default, it
+      is the Unicode <code class="literal">REPLACEMENT CHARACTER</code> code
+      point, <code class="literal">U+FFFD</code> "�". You can change this with
+    </p>
+<pre class="programlisting">
+      hb_buffer_set_replacement_codepoint(buf, replacement);
+    </pre>
+<p>
+      passing in the replacement Unicode code point as the
+      <em class="parameter"><code>replacement</code></em> parameter.
+    </p>
+<p>
+      The invisible glyph is used to replace all output glyphs that
+      are invisible. By default, the standard space character
+      <code class="literal">U+0020</code> is used; you can replace this (for
+      example, when using a font that provides script-specific
+      spaces) with 
+    </p>
+<pre class="programlisting">
+      hb_buffer_set_invisible_glyph(buf, replacement_glyph);
+    </pre>
+<p>
+      Do note that in the <em class="parameter"><code>replacement_glyph</code></em>
+      parameter, you must provide the glyph ID of the replacement you
+      wish to use, not the Unicode code point.
+    </p>
+<p>
+      HarfBuzz supports a few additional flags you might want to set
+      on your buffer under certain circumstances. The
+      <code class="literal">HB_BUFFER_FLAG_BOT</code> and
+      <code class="literal">HB_BUFFER_FLAG_EOT</code> flags tell HarfBuzz
+      that the buffer represents the beginning or end (respectively)
+      of a text element (such as a paragraph or other block). Knowing
+      this allows HarfBuzz to apply certain contextual font features
+      when shaping, such as initial or final variants in connected
+      scripts.
+    </p>
+<p>
+      <code class="literal">HB_BUFFER_FLAG_PRESERVE_DEFAULT_IGNORABLES</code>
+      tells HarfBuzz not to hide glyphs with the
+      <code class="literal">Default_Ignorable</code> property in Unicode. This 
+      property designates control characters and other non-printing
+      code points, such as joiners and variation selectors. Normally
+      HarfBuzz replaces them in the output buffer with zero-width
+      space glyphs (using the "invisible glyph" property discussed
+      above); setting this flag causes them to be printed, which can
+      be helpful for troubleshooting.
+    </p>
+<p>
+      Conversely, setting the
+      <code class="literal">HB_BUFFER_FLAG_REMOVE_DEFAULT_IGNORABLES</code> flag
+      tells HarfBuzz to remove <code class="literal">Default_Ignorable</code>
+      glyphs from the output buffer entirely. Finally, setting the
+      <code class="literal">HB_BUFFER_FLAG_DO_NOT_INSERT_DOTTED_CIRCLE</code>
+      flag tells HarfBuzz not to insert the dotted-circle glyph
+      (<code class="literal">U+25CC</code>, "◌"), which is normally
+      inserted into buffer output when broken character sequences are
+      encountered (such as combining marks that are not attached to a
+      base character).
     </p>
 </div>
 <div class="footer">
index 2831034..a3ac1aa 100644 (file)
@@ -6,8 +6,8 @@
 <meta name="generator" content="DocBook XSL Stylesheets Vsnapshot">
 <link rel="home" href="index.html" title="HarfBuzz Manual">
 <link rel="up" href="pt01.html" title="Part I. User's manual">
-<link rel="prev" href="level-2.html" title="Level 2">
-<link rel="next" href="plans-and-caching.html" title="Plans and caching">
+<link rel="prev" href="fonts-and-faces-variable.html" title="Working with OpenType Variable Fonts">
+<link rel="next" href="shaping-opentype-features.html" title="OpenType features">
 <meta name="generator" content="GTK-Doc V1.29 (XML mode)">
 <link rel="stylesheet" href="style.css" type="text/css">
 </head>
 <td width="100%" align="left" class="shortcuts"></td>
 <td><a accesskey="h" href="index.html"><img src="home.png" width="16" height="16" border="0" alt="Home"></a></td>
 <td><a accesskey="u" href="pt01.html"><img src="up.png" width="16" height="16" border="0" alt="Up"></a></td>
-<td><a accesskey="p" href="level-2.html"><img src="left.png" width="16" height="16" border="0" alt="Prev"></a></td>
-<td><a accesskey="n" href="plans-and-caching.html"><img src="right.png" width="16" height="16" border="0" alt="Next"></a></td>
+<td><a accesskey="p" href="fonts-and-faces-variable.html"><img src="left.png" width="16" height="16" border="0" alt="Prev"></a></td>
+<td><a accesskey="n" href="shaping-opentype-features.html"><img src="right.png" width="16" height="16" border="0" alt="Next"></a></td>
 </tr></table>
 <div class="chapter">
 <div class="titlepage"><div><div><h2 class="title">
 <a name="shaping-and-shape-plans"></a>Shaping and shape plans</h2></div></div></div>
 <div class="toc"><dl class="toc">
-<dt><span class="section"><a href="shaping-and-shape-plans.html#opentype-features">OpenType features</a></span></dt>
-<dt><span class="section"><a href="plans-and-caching.html">Plans and caching</a></span></dt>
+<dt><span class="section"><a href="shaping-and-shape-plans.html#shaping-buffer-output">Shaping and buffer output</a></span></dt>
+<dt><span class="section"><a href="shaping-opentype-features.html">OpenType features</a></span></dt>
+<dt><span class="section"><a href="shaping-shaper-selection.html">Shaper selection</a></span></dt>
+<dt><span class="section"><a href="shaping-plans-and-caching.html">Plans and caching</a></span></dt>
 </dl></div>
+<p>
+    Once you have your face and font objects configured as desired and
+    your input buffer is filled with the characters you need to shape,
+    all you need to do is call <code class="function">hb_shape()</code>.
+  </p>
+<p>
+    HarfBuzz will return the shaped version of the text in the same
+    buffer that you provided, but it will be in output mode. At that
+    point, you can iterate through the glyphs in the buffer, drawing
+    each one at the specified position or handing them off to the
+    appropriate graphics library.
+  </p>
+<p>
+    For the most part, HarfBuzz's shaping step is straightforward from
+    the outside. But that doesn't mean there will never be cases where
+    you want to look under the hood and see what is happening on the
+    inside. HarfBuzz provides facilities for doing that, too.
+  </p>
 <div class="section">
 <div class="titlepage"><div><div><h2 class="title" style="clear: both">
-<a name="opentype-features"></a>OpenType features</h2></div></div></div>
+<a name="shaping-buffer-output"></a>Shaping and buffer output</h2></div></div></div>
+<p>
+      The <code class="function">hb_shape()</code> function call takes four arguments: the font
+      object to use, the buffer of characters to shape, an array of
+      user-specified features to apply, and the length of that feature
+      array. The feature array can be NULL, so for the sake of
+      simplicity we will start with that case.
+    </p>
+<p>
+      Internally, HarfBuzz looks  at the tables of the font file to
+      determine where glyph classes, substitutions, and positioning
+      are defined, using that information to decide which
+      <span class="emphasis"><em>shaper</em></span> to use (<code class="literal">ot</code> for
+      OpenType fonts, <code class="literal">aat</code> for Apple Advanced
+      Typography fonts, and so on). It also looks at the direction,
+      script, and language properties of the segment to figure out
+      which script-specific shaping model is needed (at least, in
+      shapers that support multiple options).      
+    </p>
+<p>
+      If a font has a GDEF table, then that is used for
+      glyph classes; if not, HarfBuzz will fall back to Unicode
+      categorization by code point. If a font has an AAT "morx" table,
+      then it is used for substitutions; if not, but there is a GSUB
+      table, then the GSUB table is used. If the font has an AAT
+      "kerx" table, then it is used for positioning; if not, but
+      there is a GPOS table, then the GPOS table is used. If neither
+      table is found, but there is a "kern" table, then HarfBuzz will
+      use the "kern" table. If there is no "kerx", no GPOS, and no
+      "kern", HarfBuzz will fall back to positioning marks itself.
+    </p>
+<p>
+      With a well-behaved OpenType font, you expect GDEF, GSUB, and
+      GPOS tables to all be applied. HarfBuzz implements the
+      script-specific shaping models in internal functions, rather
+      than in the public API.
+    </p>
+<p>
+      The algorithms
+      used for complex scripts can be quite involved; HarfBuzz tries
+      to be compatible with the OpenType Layout specification
+      and, wherever there is any ambiguity, HarfBuzz attempts to replicate the
+      output of Microsoft's Uniscribe engine. See the <a class="ulink" href="https://docs.microsoft.com/en-us/typography/script-development/standard" target="_top">Microsoft
+      Typography pages</a> for more detail.
+    </p>
+<p>
+      In general, though, all that you need to know is that
+      <code class="function">hb_shape()</code> returns the results of shaping
+      in the same buffer that you provided. The buffer's content type
+      will now be set to
+      <code class="literal">HB_BUFFER_CONTENT_TYPE_GLYPHS</code>, indicating
+      that it contains shaped output, rather than input text. You can
+      now extract the glyph information and positioning arrays:
+    </p>
+<pre class="programlisting">
+      hb_glyph_info_t *glyph_info    = hb_buffer_get_glyph_infos(buf, &amp;glyph_count);
+      hb_glyph_position_t *glyph_pos = hb_buffer_get_glyph_positions(buf, &amp;glyph_count);
+    </pre>
+<p>
+      The glyph information array holds a <span class="type">hb_glyph_info_t</span>
+      for each output glyph, which has two fields:
+      <em class="parameter"><code>codepoint</code></em> and
+      <em class="parameter"><code>cluster</code></em>. Whereas, in the input buffer,
+      the <em class="parameter"><code>codepoint</code></em> field contained the Unicode
+      code point, it now contains the glyph ID of the corresponding
+      glyph in the font. The <em class="parameter"><code>cluster</code></em> field is
+      an integer that you can use to help identify when shaping has
+      reordered, split, or combined code points; we will say more
+      about that in the next chapter.
+    </p>
+<p>
+      The glyph positions array holds a corresponding
+      <span class="type">hb_glyph_position_t</span> for each output glyph,
+      containing four fields: <em class="parameter"><code>x_advance</code></em>,
+      <em class="parameter"><code>y_advance</code></em>,
+      <em class="parameter"><code>x_offset</code></em>, and
+      <em class="parameter"><code>y_offset</code></em>. The advances tell you how far
+      you need to move the drawing point after drawing this glyph,
+      depending on whether you are setting horizontal text (in which
+      case you will have x advances) or vertical text (for which you
+      will have y advances). The x and y offsets tell you where to
+      move to start drawing the glyph; usually you will have both and
+      x and a y offset, regardless of the text direction.
+    </p>
 <p>
+      Most of the time, you will rely on a font-rendering library or
+      other graphics library to do the actual drawing of glyphs, so
+      you will need to iterate through the glyphs in the buffer and
+      pass the corresponding values off.
     </p>
 </div>
 </div>
diff --git a/docs/html/shaping-opentype-features.html b/docs/html/shaping-opentype-features.html
new file mode 100644 (file)
index 0000000..2a22f12
--- /dev/null
@@ -0,0 +1,109 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>OpenType features: HarfBuzz Manual</title>
+<meta name="generator" content="DocBook XSL Stylesheets Vsnapshot">
+<link rel="home" href="index.html" title="HarfBuzz Manual">
+<link rel="up" href="shaping-and-shape-plans.html" title="Shaping and shape plans">
+<link rel="prev" href="shaping-and-shape-plans.html" title="Shaping and shape plans">
+<link rel="next" href="shaping-shaper-selection.html" title="Shaper selection">
+<meta name="generator" content="GTK-Doc V1.29 (XML mode)">
+<link rel="stylesheet" href="style.css" type="text/css">
+</head>
+<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
+<table class="navigation" id="top" width="100%" summary="Navigation header" cellpadding="2" cellspacing="5"><tr valign="middle">
+<td width="100%" align="left" class="shortcuts"></td>
+<td><a accesskey="h" href="index.html"><img src="home.png" width="16" height="16" border="0" alt="Home"></a></td>
+<td><a accesskey="u" href="shaping-and-shape-plans.html"><img src="up.png" width="16" height="16" border="0" alt="Up"></a></td>
+<td><a accesskey="p" href="shaping-and-shape-plans.html"><img src="left.png" width="16" height="16" border="0" alt="Prev"></a></td>
+<td><a accesskey="n" href="shaping-shaper-selection.html"><img src="right.png" width="16" height="16" border="0" alt="Next"></a></td>
+</tr></table>
+<div class="section">
+<div class="titlepage"><div><div><h2 class="title" style="clear: both">
+<a name="shaping-opentype-features"></a>OpenType features</h2></div></div></div>
+<p>
+      OpenType features enable fonts to include smart behavior,
+      implemented as "lookup" rules stored in the GSUB and GPOS
+      tables. The OpenType specification defines a long list of
+      standard features that fonts can use for these behaviors; each
+      feature has a four-character reserved name and a well-defined
+      semantic meaning.
+    </p>
+<p>
+      Some OpenType features are defined for the purpose of supporting
+      complex-script shaping, and are automatically activated, but
+      only when a buffer's script property is set to a script that the
+      feature supports.
+    </p>
+<p>
+      Other features are more generic and can apply to several (or
+      any) script, and shaping engines are expected to implement
+      them. By default, HarfBuzz activates several of these features
+      on every text run. They include <code class="literal">abvm</code>,
+      <code class="literal">blwm</code>, <code class="literal">ccmp</code>,
+      <code class="literal">locl</code>, <code class="literal">mark</code>,
+      <code class="literal">mkmk</code>, and <code class="literal">rlig</code>.
+    </p>
+<p>
+      In addition, if the text direction is horizontal, HarfBuzz
+      also applies the <code class="literal">calt</code>,
+      <code class="literal">clig</code>, <code class="literal">curs</code>,
+      <code class="literal">dist</code>, <code class="literal">kern</code>,
+      <code class="literal">liga</code>, <code class="literal">rclt</code>,
+      and <code class="literal">frac</code> features.
+    </p>
+<p>
+      If the text direction is vertical, HarfBuzz applies
+      the <code class="literal">vert</code> feature by default.
+    </p>
+<p>
+      Still other features are designed to be purely optional and left
+      up to the application or the end user to enable or disable as desired.
+    </p>
+<p>
+      You can adjust the set of features that HarfBuzz applies to a
+      buffer by supplying an array of <span class="type">hb_feature_t</span>
+      features as the third argument to
+      <code class="function">hb_shape()</code>. For a simple case, let's just
+      enable the <code class="literal">dlig</code> feature, which turns on any
+      "discretionary" ligatures in the font:
+    </p>
+<pre class="programlisting">
+      hb_feature_t userfeatures[1];
+      userfeatures[0].tag = HB_TAG('d','l','i','g');
+      userfeatures[0].value = 1;
+      userfeatures[0].start = HB_FEATURE_GLOBAL_START;
+      userfeatures[0].end = HB_FEATURE_GLOBAL_END;
+    </pre>
+<p>
+      <code class="literal">HB_FEATURE_GLOBAL_END</code> and
+      <code class="literal">HB_FEATURE_GLOBAL_END</code> are macros we can use
+      to indicate that the features will be applied to the entire
+      buffer. We could also have used a literal <code class="literal">0</code>
+      for the start and a <code class="literal">-1</code> to indicate the end of
+      the buffer (or have selected other start and end positions, if needed).
+    </p>
+<p>
+      When we pass the <code class="varname">userfeatures</code> array to
+      <code class="function">hb_shape()</code>, any discretionary ligature
+      substitutions from our font that match the text in our buffer
+      will get performed:
+    </p>
+<pre class="programlisting">
+      hb_shape(font, buf, userfeatures, num_features);
+    </pre>
+<p>
+      Just like we enabled the <code class="literal">dlig</code> feature by
+      setting its <em class="parameter"><code>value</code></em> to
+      <code class="literal">1</code>, you would disable a feature by setting its
+      <em class="parameter"><code>value</code></em> to <code class="literal">0</code>. Some
+      features can take other <em class="parameter"><code>value</code></em> settings;
+      be sure you read the full specification of each feature tag to
+      understand what it does and how to control it.
+    </p>
+</div>
+<div class="footer">
+<hr>Generated by GTK-Doc V1.29</div>
+</body>
+</html>
\ No newline at end of file
diff --git a/docs/html/shaping-plans-and-caching.html b/docs/html/shaping-plans-and-caching.html
new file mode 100644 (file)
index 0000000..7a17f0f
--- /dev/null
@@ -0,0 +1,85 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>Plans and caching: HarfBuzz Manual</title>
+<meta name="generator" content="DocBook XSL Stylesheets Vsnapshot">
+<link rel="home" href="index.html" title="HarfBuzz Manual">
+<link rel="up" href="shaping-and-shape-plans.html" title="Shaping and shape plans">
+<link rel="prev" href="shaping-shaper-selection.html" title="Shaper selection">
+<link rel="next" href="clusters.html" title="Clusters">
+<meta name="generator" content="GTK-Doc V1.29 (XML mode)">
+<link rel="stylesheet" href="style.css" type="text/css">
+</head>
+<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
+<table class="navigation" id="top" width="100%" summary="Navigation header" cellpadding="2" cellspacing="5"><tr valign="middle">
+<td width="100%" align="left" class="shortcuts"></td>
+<td><a accesskey="h" href="index.html"><img src="home.png" width="16" height="16" border="0" alt="Home"></a></td>
+<td><a accesskey="u" href="shaping-and-shape-plans.html"><img src="up.png" width="16" height="16" border="0" alt="Up"></a></td>
+<td><a accesskey="p" href="shaping-shaper-selection.html"><img src="left.png" width="16" height="16" border="0" alt="Prev"></a></td>
+<td><a accesskey="n" href="clusters.html"><img src="right.png" width="16" height="16" border="0" alt="Next"></a></td>
+</tr></table>
+<div class="section">
+<div class="titlepage"><div><div><h2 class="title" style="clear: both">
+<a name="shaping-plans-and-caching"></a>Plans and caching</h2></div></div></div>
+<p>
+      Internally, HarfBuzz uses a structure called a shape plan to
+      track its decisions about how to shape the contents of a
+      buffer. The <code class="function">hb_shape()</code> function builds up the shape plan by
+      examining segment properties and by inspecting the contents of
+      the font.
+    </p>
+<p>
+      This process can involve some decision-making and
+      trade-offs — for example, HarfBuzz inspects the GSUB and GPOS
+      lookups for the script and language tags set on the segment
+      properties, but it falls back on the lookups under the
+      <code class="literal">DFLT</code> tag (and sometimes other common tags)
+      if there are actually no lookups for the tag requested.
+    </p>
+<p>
+      HarfBuzz also includes some work-arounds for
+      handling well-known older font conventions that do not follow
+      OpenType or Unicode specifications, for buggy system fonts, and for
+      peculiarities of Microsoft Uniscribe. All of that means that a
+      shape plan, while not something that you should edit directly in
+      client code, still might be an object that you want to
+      inspect. Furthermore, if resources are tight, you might want to
+      cache the shape plan that HarfBuzz builds for your buffer and
+      font, so that you do not have to rebuild it for every shaping call.
+    </p>
+<p>
+      You can create a cacheable shape plan with
+      <code class="function">hb_shape_plan_create_cached(face, props,
+      user_features, num_user_features, shaper_list)</code>, where
+      <em class="parameter"><code>face</code></em> is a face object (not a font object,
+      notably), <em class="parameter"><code>props</code></em> is an
+      <span class="type">hb_segment_properties_t</span>,
+      <em class="parameter"><code>user_features</code></em> is an array of
+      <span class="type">hb_feature_t</span>s (with length
+      <em class="parameter"><code>num_user_features</code></em>), and
+      <em class="parameter"><code>shaper_list</code></em> is a list of shapers to try.
+    </p>
+<p>
+      Shape plans are objects in HarfBuzz, so there are
+      reference-counting functions and user-data attachment functions
+      you can
+      use. <code class="function">hb_shape_plan_reference(shape_plan)</code>
+      increases the reference count on a shape plan, while
+      <code class="function">hb_shape_plan_destroy(shape_plan)</code> decreases
+      the reference count, destroying the shape plan when the last
+      reference is dropped.
+    </p>
+<p>
+      You can attach user data to a shaper (with a key) using the
+      <code class="function">hb_shape_plan_set_user_data(shape_plan,key,data,destroy,replace)</code>
+      function, optionally supplying a <code class="function">destroy</code>
+      callback to use. You can then fetch the user data attached to a
+      shape plan with
+      <code class="function">hb_shape_plan_get_user_data(shape_plan, key)</code>.
+    </p>
+</div>
+<div class="footer">
+<hr>Generated by GTK-Doc V1.29</div>
+</body>
+</html>
\ No newline at end of file
diff --git a/docs/html/shaping-shaper-selection.html b/docs/html/shaping-shaper-selection.html
new file mode 100644 (file)
index 0000000..c6112ae
--- /dev/null
@@ -0,0 +1,65 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>Shaper selection: HarfBuzz Manual</title>
+<meta name="generator" content="DocBook XSL Stylesheets Vsnapshot">
+<link rel="home" href="index.html" title="HarfBuzz Manual">
+<link rel="up" href="shaping-and-shape-plans.html" title="Shaping and shape plans">
+<link rel="prev" href="shaping-opentype-features.html" title="OpenType features">
+<link rel="next" href="shaping-plans-and-caching.html" title="Plans and caching">
+<meta name="generator" content="GTK-Doc V1.29 (XML mode)">
+<link rel="stylesheet" href="style.css" type="text/css">
+</head>
+<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
+<table class="navigation" id="top" width="100%" summary="Navigation header" cellpadding="2" cellspacing="5"><tr valign="middle">
+<td width="100%" align="left" class="shortcuts"></td>
+<td><a accesskey="h" href="index.html"><img src="home.png" width="16" height="16" border="0" alt="Home"></a></td>
+<td><a accesskey="u" href="shaping-and-shape-plans.html"><img src="up.png" width="16" height="16" border="0" alt="Up"></a></td>
+<td><a accesskey="p" href="shaping-opentype-features.html"><img src="left.png" width="16" height="16" border="0" alt="Prev"></a></td>
+<td><a accesskey="n" href="shaping-plans-and-caching.html"><img src="right.png" width="16" height="16" border="0" alt="Next"></a></td>
+</tr></table>
+<div class="section">
+<div class="titlepage"><div><div><h2 class="title" style="clear: both">
+<a name="shaping-shaper-selection"></a>Shaper selection</h2></div></div></div>
+<p>
+      The basic version of <code class="function">hb_shape()</code> determines
+      its shaping strategy based on examining the capabilities of the
+      font file. OpenType font tables cause HarfBuzz to try the
+      <code class="literal">ot</code> shaper, while AAT font tables cause HarfBuzz to try the
+      <code class="literal">aat</code> shaper. 
+    </p>
+<p>
+      In the real world, however, a font might include some unusual
+      mix of tables, or one of the tables might simply be broken for
+      the script you need to shape. So, sometimes, you might not
+      want to rely on HarfBuzz's process for deciding what to do, and
+      just tell <code class="function">hb_shape()</code> what you want it to try.
+    </p>
+<p>
+      <code class="function">hb_shape_full()</code> is an alternate shaping
+      function that lets you supply a list of shapers for HarfBuzz to
+      try, in order, when shaping your buffer. For example, if you
+      have determined that HarfBuzz's attempts to work around broken
+      tables gives you better results than the AAT shaper itself does,
+      you might move the AAT shaper to the end of your list of
+      preferences and call <code class="function">hb_shape_full()</code>
+    </p>
+<pre class="programlisting">
+      char *shaperprefs[3] = {"ot", "default", "aat"};
+      ...
+      hb_shape_full(font, buf, userfeatures, num_features, shaperprefs);
+    </pre>
+<p>
+      to get results you are happier with.
+    </p>
+<p>
+      You may also want to call
+      <code class="function">hb_shape_list_shapers()</code> to get a list of
+      the shapers that were built at compile time in your copy of HarfBuzz.
+    </p>
+</div>
+<div class="footer">
+<hr>Generated by GTK-Doc V1.29</div>
+</body>
+</html>
\ No newline at end of file
diff --git a/docs/html/using-harfbuzzs-native-opentype-implementation.html b/docs/html/using-harfbuzzs-native-opentype-implementation.html
deleted file mode 100644 (file)
index 1ee3f3e..0000000
+++ /dev/null
@@ -1,31 +0,0 @@
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
-<html>
-<head>
-<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
-<title>Using HarfBuzz's native OpenType implementation: HarfBuzz Manual</title>
-<meta name="generator" content="DocBook XSL Stylesheets Vsnapshot">
-<link rel="home" href="index.html" title="HarfBuzz Manual">
-<link rel="up" href="fonts-and-faces.html" title="Fonts and faces">
-<link rel="prev" href="fonts-and-faces.html" title="Fonts and faces">
-<link rel="next" href="using-your-own-font-functions.html" title="Using your own font functions">
-<meta name="generator" content="GTK-Doc V1.29 (XML mode)">
-<link rel="stylesheet" href="style.css" type="text/css">
-</head>
-<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
-<table class="navigation" id="top" width="100%" summary="Navigation header" cellpadding="2" cellspacing="5"><tr valign="middle">
-<td width="100%" align="left" class="shortcuts"></td>
-<td><a accesskey="h" href="index.html"><img src="home.png" width="16" height="16" border="0" alt="Home"></a></td>
-<td><a accesskey="u" href="fonts-and-faces.html"><img src="up.png" width="16" height="16" border="0" alt="Up"></a></td>
-<td><a accesskey="p" href="fonts-and-faces.html"><img src="left.png" width="16" height="16" border="0" alt="Prev"></a></td>
-<td><a accesskey="n" href="using-your-own-font-functions.html"><img src="right.png" width="16" height="16" border="0" alt="Next"></a></td>
-</tr></table>
-<div class="section">
-<div class="titlepage"><div><div><h2 class="title" style="clear: both">
-<a name="using-harfbuzzs-native-opentype-implementation"></a>Using HarfBuzz's native OpenType implementation</h2></div></div></div>
-<p>
-    </p>
-</div>
-<div class="footer">
-<hr>Generated by GTK-Doc V1.29</div>
-</body>
-</html>
\ No newline at end of file
diff --git a/docs/html/using-your-own-font-functions.html b/docs/html/using-your-own-font-functions.html
deleted file mode 100644 (file)
index 53f33ac..0000000
+++ /dev/null
@@ -1,31 +0,0 @@
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
-<html>
-<head>
-<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
-<title>Using your own font functions: HarfBuzz Manual</title>
-<meta name="generator" content="DocBook XSL Stylesheets Vsnapshot">
-<link rel="home" href="index.html" title="HarfBuzz Manual">
-<link rel="up" href="fonts-and-faces.html" title="Fonts and faces">
-<link rel="prev" href="using-harfbuzzs-native-opentype-implementation.html" title="Using HarfBuzz's native OpenType implementation">
-<link rel="next" href="clusters.html" title="Clusters">
-<meta name="generator" content="GTK-Doc V1.29 (XML mode)">
-<link rel="stylesheet" href="style.css" type="text/css">
-</head>
-<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
-<table class="navigation" id="top" width="100%" summary="Navigation header" cellpadding="2" cellspacing="5"><tr valign="middle">
-<td width="100%" align="left" class="shortcuts"></td>
-<td><a accesskey="h" href="index.html"><img src="home.png" width="16" height="16" border="0" alt="Home"></a></td>
-<td><a accesskey="u" href="fonts-and-faces.html"><img src="up.png" width="16" height="16" border="0" alt="Up"></a></td>
-<td><a accesskey="p" href="using-harfbuzzs-native-opentype-implementation.html"><img src="left.png" width="16" height="16" border="0" alt="Prev"></a></td>
-<td><a accesskey="n" href="clusters.html"><img src="right.png" width="16" height="16" border="0" alt="Next"></a></td>
-</tr></table>
-<div class="section">
-<div class="titlepage"><div><div><h2 class="title" style="clear: both">
-<a name="using-your-own-font-functions"></a>Using your own font functions</h2></div></div></div>
-<p>
-    </p>
-</div>
-<div class="footer">
-<hr>Generated by GTK-Doc V1.29</div>
-</body>
-</html>
\ No newline at end of file
diff --git a/docs/html/utilities-common-types-apis.html b/docs/html/utilities-common-types-apis.html
new file mode 100644 (file)
index 0000000..fbde14a
--- /dev/null
@@ -0,0 +1,84 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>Common data types and APIs: HarfBuzz Manual</title>
+<meta name="generator" content="DocBook XSL Stylesheets Vsnapshot">
+<link rel="home" href="index.html" title="HarfBuzz Manual">
+<link rel="up" href="utilities.html" title="Utilities">
+<link rel="prev" href="utilities.html" title="Utilities">
+<link rel="next" href="utilities-ucdn.html" title="UCDN">
+<meta name="generator" content="GTK-Doc V1.29 (XML mode)">
+<link rel="stylesheet" href="style.css" type="text/css">
+</head>
+<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
+<table class="navigation" id="top" width="100%" summary="Navigation header" cellpadding="2" cellspacing="5"><tr valign="middle">
+<td width="100%" align="left" class="shortcuts"></td>
+<td><a accesskey="h" href="index.html"><img src="home.png" width="16" height="16" border="0" alt="Home"></a></td>
+<td><a accesskey="u" href="utilities.html"><img src="up.png" width="16" height="16" border="0" alt="Up"></a></td>
+<td><a accesskey="p" href="utilities.html"><img src="left.png" width="16" height="16" border="0" alt="Prev"></a></td>
+<td><a accesskey="n" href="utilities-ucdn.html"><img src="right.png" width="16" height="16" border="0" alt="Next"></a></td>
+</tr></table>
+<div class="section">
+<div class="titlepage"><div><div><h2 class="title" style="clear: both">
+<a name="utilities-common-types-apis"></a>Common data types and APIs</h2></div></div></div>
+<p>
+      HarfBuzz includes several APIs for working with general-purpose
+      data that you may find convenient to leverage in your own
+      software. They include set operations and integer-to-integer
+      mapping operations.
+    </p>
+<p>
+      HarfBuzz uses set operations for internal bookkeeping, such as
+      when it collects all of the glyph IDs covered by a particular
+      font feature. You can also use the set API to build sets, add
+      and remove elements, test whether or not sets contain particular
+      elements, or compute the unions, intersections, or differences
+      between sets.
+    </p>
+<p>
+      All set elements are integers (specifically,
+      <span class="type">hb_codepoint_t</span> 32-bit unsigned ints), and there are
+      functions for fetching the minimum and maximum element from a
+      set. The set API also includes some functions that might not 
+      be part of a generic set facility, such as the ability to add a
+      contiguous range of integer elements to a set in bulk, and the
+      ability to fetch the next-smallest or next-largest element.
+    </p>
+<p>
+      The HarfBuzz set API includes some conveniences as well. All
+      sets are lifecycle-managed, just like other HarfBuzz
+      objects. You increase the reference count on a set with
+      <code class="function">hb_set_reference()</code> and decrease it with
+      <code class="function">hb_set_destroy()</code>. You can also attach
+      user data to a set, just like you can to blobs, buffers, faces,
+      fonts, and other objects, and set destroy callbacks.
+    </p>
+<p>
+      HarfBuzz also provides an API for keeping track of
+      integer-to-integer mappings. As with the set API, each integer is
+      stored as an unsigned 32-bit <span class="type">hb_codepoint_t</span>
+      element. Maps, like other objects, are reference counted with
+      reference and destroy functions, and you can attach user data to
+      them. The mapping operations include adding and deleting
+      integer-to-integer key:value pairs to the map, testing for the
+      presence of a key, fetching the population of the map, and so on.
+    </p>
+<p>
+      There are several other internal HarfBuzz facilities that are
+      exposed publicly and which you may want to take advantage of
+      while processing text. HarfBuzz uses a common
+      <span class="type">hb_tag_t</span> for a variety of OpenType tag identifiers (for
+      scripts, languages, font features, table names, variation-axis
+      names, and more), and provides functions for converting strings
+      to tags and vice-versa. 
+    </p>
+<p>
+      Finally, HarfBuzz also includes data type for Booleans, bit
+      masks, and other simple types.
+    </p>
+</div>
+<div class="footer">
+<hr>Generated by GTK-Doc V1.29</div>
+</body>
+</html>
\ No newline at end of file
diff --git a/docs/html/utilities-ucdn.html b/docs/html/utilities-ucdn.html
new file mode 100644 (file)
index 0000000..0d932f9
--- /dev/null
@@ -0,0 +1,49 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>UCDN: HarfBuzz Manual</title>
+<meta name="generator" content="DocBook XSL Stylesheets Vsnapshot">
+<link rel="home" href="index.html" title="HarfBuzz Manual">
+<link rel="up" href="utilities.html" title="Utilities">
+<link rel="prev" href="utilities-common-types-apis.html" title="Common data types and APIs">
+<link rel="next" href="pt02.html" title="Part II. Reference manual">
+<meta name="generator" content="GTK-Doc V1.29 (XML mode)">
+<link rel="stylesheet" href="style.css" type="text/css">
+</head>
+<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
+<table class="navigation" id="top" width="100%" summary="Navigation header" cellpadding="2" cellspacing="5"><tr valign="middle">
+<td width="100%" align="left" class="shortcuts"></td>
+<td><a accesskey="h" href="index.html"><img src="home.png" width="16" height="16" border="0" alt="Home"></a></td>
+<td><a accesskey="u" href="utilities.html"><img src="up.png" width="16" height="16" border="0" alt="Up"></a></td>
+<td><a accesskey="p" href="utilities-common-types-apis.html"><img src="left.png" width="16" height="16" border="0" alt="Prev"></a></td>
+<td><a accesskey="n" href="pt02.html"><img src="right.png" width="16" height="16" border="0" alt="Next"></a></td>
+</tr></table>
+<div class="section">
+<div class="titlepage"><div><div><h2 class="title" style="clear: both">
+<a name="utilities-ucdn"></a>UCDN</h2></div></div></div>
+<p>
+      HarfBuzz includes a copy of the <a class="ulink" href="https://github.com/grigorig/ucdn" target="_top">UCDN</a> (Unicode
+      Database and Normalization) library, which provides functions
+      for accessing basic Unicode character properties, performing
+      canonical composition, and performing both canonical and
+      compatibility decomposition.
+    </p>
+<p>
+      Currently, UCDN supports direct queries for several more character
+      properties than HarfBuzz's built-in set of Unicode functions
+      does, such as the BiDirectional Class, East Asian Width, Paired
+      Bracket and Resolved Linebreak properties. If you need to access
+      more properties than HarfBuzz's internal implementation
+      provides, using the built-in UCDN functions may be a useful solution.
+    </p>
+<p>
+      The built-in UCDN functions are compiled by default when
+      building HarfBuzz from source, but this can be disabled with a
+      compile-time switch.
+    </p>
+</div>
+<div class="footer">
+<hr>Generated by GTK-Doc V1.29</div>
+</body>
+</html>
\ No newline at end of file
diff --git a/docs/html/utilities.html b/docs/html/utilities.html
new file mode 100644 (file)
index 0000000..05ff3ea
--- /dev/null
@@ -0,0 +1,188 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>Utilities: HarfBuzz Manual</title>
+<meta name="generator" content="DocBook XSL Stylesheets Vsnapshot">
+<link rel="home" href="index.html" title="HarfBuzz Manual">
+<link rel="up" href="pt01.html" title="Part I. User's manual">
+<link rel="prev" href="level-2.html" title="Level 2">
+<link rel="next" href="utilities-common-types-apis.html" title="Common data types and APIs">
+<meta name="generator" content="GTK-Doc V1.29 (XML mode)">
+<link rel="stylesheet" href="style.css" type="text/css">
+</head>
+<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
+<table class="navigation" id="top" width="100%" summary="Navigation header" cellpadding="2" cellspacing="5"><tr valign="middle">
+<td width="100%" align="left" class="shortcuts"></td>
+<td><a accesskey="h" href="index.html"><img src="home.png" width="16" height="16" border="0" alt="Home"></a></td>
+<td><a accesskey="u" href="pt01.html"><img src="up.png" width="16" height="16" border="0" alt="Up"></a></td>
+<td><a accesskey="p" href="level-2.html"><img src="left.png" width="16" height="16" border="0" alt="Prev"></a></td>
+<td><a accesskey="n" href="utilities-common-types-apis.html"><img src="right.png" width="16" height="16" border="0" alt="Next"></a></td>
+</tr></table>
+<div class="chapter">
+<div class="titlepage"><div><div><h2 class="title">
+<a name="utilities"></a>Utilities</h2></div></div></div>
+<div class="toc"><dl class="toc">
+<dt><span class="section"><a href="utilities.html#utilities-command-line-tools">Command-line tools</a></span></dt>
+<dd><dl>
+<dt><span class="section"><a href="utilities.html#utilities-command-line-hbshape">hb-shape</a></span></dt>
+<dt><span class="section"><a href="utilities.html#utilities-command-line-hbview">hb-view</a></span></dt>
+<dt><span class="section"><a href="utilities.html#utilities-command-line-hbsubset">hb-subset</a></span></dt>
+</dl></dd>
+<dt><span class="section"><a href="utilities-common-types-apis.html">Common data types and APIs</a></span></dt>
+<dt><span class="section"><a href="utilities-ucdn.html">UCDN</a></span></dt>
+</dl></div>
+<p>
+    HarfBuzz includes several auxiliary components in addition to the
+    main APIs. These include a set of command-line tools, a set of
+    lower-level APIs for common data types that may be of interest to
+    client programs, and an embedded library for working with
+    Unicode Character Database (UCD) data.
+  </p>
+<div class="section">
+<div class="titlepage"><div><div><h2 class="title" style="clear: both">
+<a name="utilities-command-line-tools"></a>Command-line tools</h2></div></div></div>
+<p>
+      HarfBuzz include three command-line tools:
+      <span style="color: red">&lt;program&gt;hb-shape&lt;/program&gt;</span>, <span style="color: red">&lt;program&gt;hb-view&lt;/program&gt;</span>, and
+      <span style="color: red">&lt;program&gt;hb-subset&lt;/program&gt;</span>. They can be used to examine
+      HarfBuzz's functionality, debug font binaries, or explore the
+      various shaping models and features from a terminal.
+    </p>
+<div class="section">
+<div class="titlepage"><div><div><h3 class="title">
+<a name="utilities-command-line-hbshape"></a>hb-shape</h3></div></div></div>
+<p>
+       <span class="emphasis"><em><span style="color: red">&lt;program&gt;hb-shape&lt;/program&gt;</span></em></span> allows you to run HarfBuzz's
+       <code class="function">hb_shape()</code> function on an input string and
+       to examine the outcome, in human-readable form, as terminal
+       output. <span style="color: red">&lt;program&gt;hb-shape&lt;/program&gt;</span> does
+       <span class="emphasis"><em>not</em></span> render the results of the shaping call
+       into rendered text (you can use <span style="color: red">&lt;program&gt;hb-view&lt;/program&gt;</span>, below, for
+       that). Instead, it prints out the final glyph indices and
+       positions, taking all shaping operations into account, as if the
+       input string were a HarfBuzz input buffer.
+      </p>
+<p>
+       You can specify the font to be used for shaping and, with
+       command-line options, you can add various aspects of the
+       internal state to the output that is sent to the terminal. The
+       general format is
+      </p>
+<pre class="programlisting">
+       <span class="command"><strong>hb-shape</strong></span> [<span class="optional">[OPTIONS]</span>]
+      <em class="parameter"><code>path/to/font/file.ttf</code></em>
+      <em class="parameter"><code>yourinputtext</code></em>
+      </pre>
+<p>
+       The default output format is plain text (although JSON output
+       can be selected instead by specifying the option
+       [<span class="optional">--output-format=json</span>]). The default output
+       syntax reports each glyph name (or glyph index if there is no
+       name) followed by its cluster value, its horizontal and vertical
+       position displacement, and its horizontal and vertical advances.
+      </p>
+<p>
+       Output options exist to skip any of these elements in the
+       output, and to include additional data, such as Unicode
+       code-point values, glyph extents, glyph flags, or interim
+       shaping results.
+      </p>
+<p>
+       Output can also be redirected to a file, or input read from a
+       file. Additional options enable you to enable or disable
+       specific font features, to set variation-font axis values, to
+       alter the language, script, direction, and clustering settings
+       used, to enable sanity checks, or to change which shaping engine is used.
+      </p>
+<p>
+       For a complete explanation of the options available, run
+      </p>
+<pre class="programlisting">
+       <span class="command"><strong>hb-shape</strong></span> <em class="parameter"><code>--help</code></em>
+      </pre>
+</div>
+<div class="section">
+<div class="titlepage"><div><div><h3 class="title">
+<a name="utilities-command-line-hbview"></a>hb-view</h3></div></div></div>
+<p>
+       <span class="emphasis"><em><span style="color: red">&lt;program&gt;hb-view&lt;/program&gt;</span></em></span> allows you to
+       see the shaped output of an input string in rendered
+       form. Like <span style="color: red">&lt;program&gt;hb-shape&lt;/program&gt;</span>,
+       <span style="color: red">&lt;program&gt;hb-view&lt;/program&gt;</span> takes a font file and a text string
+       as its arguments:
+      </p>
+<pre class="programlisting">
+       <span class="command"><strong>hb-view</strong></span> [<span class="optional">[OPTIONS]</span>]
+       <em class="parameter"><code>path/to/font/file.ttf</code></em>
+       <em class="parameter"><code>yourinputtext</code></em>
+      </pre>
+<p>
+       By default, <span style="color: red">&lt;program&gt;hb-view&lt;/program&gt;</span> renders the shaped
+       text in ASCII block-character images as terminal output. By
+       appending the
+       <span class="command"><strong>--output-file=[<span class="optional">filename</span>]</strong></span>
+       switch, you can write the output to a PNG, SVG, or PDF file
+       (among other formats).
+      </p>
+<p>
+       As with <span style="color: red">&lt;program&gt;hb-shape&lt;/program&gt;</span>, a lengthy set of options
+       is available, with which you can  enable or disable
+       specific font features, set variation-font axis values,
+       alter the language, script, direction, and clustering settings
+       used, enable sanity checks, or change which shaping engine is
+       used.
+      </p>
+<p>
+       You can also set the foreground and background colors used for
+       the output, independently control the width of all four
+       margins, alter the line spacing, and annotate the output image
+       with 
+      </p>
+<p>
+       In general, <span style="color: red">&lt;program&gt;hb-view&lt;/program&gt;</span> is a quick way to
+       verify that the output of HarfBuzz's shaping operation looks
+       correct for a given text-and-font combination, but you may
+       want to use <span style="color: red">&lt;program&gt;hb-shape&lt;/program&gt;</span> to figure out exactly
+       why something does not appear as expected.
+      </p>
+</div>
+<div class="section">
+<div class="titlepage"><div><div><h3 class="title">
+<a name="utilities-command-line-hbsubset"></a>hb-subset</h3></div></div></div>
+<p>
+       <span class="emphasis"><em><span style="color: red">&lt;program&gt;hb-subset&lt;/program&gt;</span></em></span> allows you
+       to generate a subset of a given font, with a limited set of
+       supported characters, features, and variation settings.
+      </p>
+<p>
+       By default, you provide an input font and an input text string
+       as the arguments to <span style="color: red">&lt;program&gt;hb-subset&lt;/program&gt;</span>, and it will
+       generate a font that covers the input text exactly like the
+       input font does, but includes no other characters or features.
+      </p>
+<pre class="programlisting">
+       <span class="command"><strong>hb-subset</strong></span> [<span class="optional">[OPTIONS]</span>]
+       <em class="parameter"><code>path/to/font/file.ttf</code></em>
+       <em class="parameter"><code>yourinputtext</code></em>
+      </pre>
+<p>
+       For example, to create a subset of Noto Serif that just includes the
+       numerals and the lowercase Latin alphabet, you could run
+      </p>
+<pre class="programlisting">
+       <span class="command"><strong>hb-subset</strong></span> [<span class="optional">[OPTIONS]</span>]
+       <em class="parameter"><code>NotoSerif-Regular.ttf</code></em>
+       <em class="parameter"><code>0123456789abcdefghijklmnopqrstuvwxyz</code></em>
+      </pre>
+<p>
+       There are options available to remove hinting from the
+       subsetted font and to specify a list of variation-axis settings.
+      </p>
+</div>
+</div>
+</div>
+<div class="footer">
+<hr>Generated by GTK-Doc V1.29</div>
+</body>
+</html>
\ No newline at end of file
diff --git a/docs/html/what-about-the-other-scripts.html b/docs/html/what-about-the-other-scripts.html
deleted file mode 100644 (file)
index edb7235..0000000
+++ /dev/null
@@ -1,31 +0,0 @@
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
-<html>
-<head>
-<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
-<title>What about the other scripts?: HarfBuzz Manual</title>
-<meta name="generator" content="DocBook XSL Stylesheets Vsnapshot">
-<link rel="home" href="index.html" title="HarfBuzz Manual">
-<link rel="up" href="buffers-language-script-and-direction.html" title="Buffers, language, script and direction">
-<link rel="prev" href="setting-buffer-properties.html" title="Setting buffer properties">
-<link rel="next" href="customizing-unicode-functions.html" title="Customizing Unicode functions">
-<meta name="generator" content="GTK-Doc V1.29 (XML mode)">
-<link rel="stylesheet" href="style.css" type="text/css">
-</head>
-<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
-<table class="navigation" id="top" width="100%" summary="Navigation header" cellpadding="2" cellspacing="5"><tr valign="middle">
-<td width="100%" align="left" class="shortcuts"></td>
-<td><a accesskey="h" href="index.html"><img src="home.png" width="16" height="16" border="0" alt="Home"></a></td>
-<td><a accesskey="u" href="buffers-language-script-and-direction.html"><img src="up.png" width="16" height="16" border="0" alt="Up"></a></td>
-<td><a accesskey="p" href="setting-buffer-properties.html"><img src="left.png" width="16" height="16" border="0" alt="Prev"></a></td>
-<td><a accesskey="n" href="customizing-unicode-functions.html"><img src="right.png" width="16" height="16" border="0" alt="Next"></a></td>
-</tr></table>
-<div class="section">
-<div class="titlepage"><div><div><h2 class="title" style="clear: both">
-<a name="what-about-the-other-scripts"></a>What about the other scripts?</h2></div></div></div>
-<p>
-    </p>
-</div>
-<div class="footer">
-<hr>Generated by GTK-Doc V1.29</div>
-</body>
-</html>
\ No newline at end of file
index e340ac5..fb61aed 100644 (file)
@@ -97,9 +97,9 @@
         </p>
 <p>
          For example, in Tamil, when the letter "TTA" (ட)
-         letter is followed by "U" (உ), the pair
+         letter is followed by the vowel sign "U" (ு), the pair
          must be replaced by the single glyph "டு". The
-         sequence of Unicode characters "ட" needs to be
+         sequence of Unicode characters "ட,ு" needs to be
          substituted with a single "டு" glyph from the
          font.
        </p>
index 74ffd3b..1fab4ad 100644 (file)
       order.
     </p>
 <p>
-      For left-to-right scripts (LTR) and top-to-bottom scripts (TTB),
+      For buffers in the left-to-right (LTR)
+      or top-to-bottom (TTB) text flow direction,
       HarfBuzz will preserve the monotonic property: client programs
-      are guaranteed that monotonically increasing initial clulster
+      are guaranteed that monotonically increasing initial cluster
       values will be returned as monotonically increasing final
       cluster values.
     </p>
 <p>
-      For right-to-left scripts (RTL) and bottom-to-top scripts (BTT),
+      For buffers in the right-to-left (RTL)
+      or bottom-to-top (BTT) text flow direction,
       the directionality of the buffer itself is reversed for final
       output as a matter of design. Therefore, HarfBuzz inverts the
       monotonic property: client programs are guaranteed that
-      monotonically increasing initial clulster values will be
+      monotonically increasing initial cluster values will be
       returned as monotonically <span class="emphasis"><em>decreasing</em></span> final
       cluster values.
     </p>
index 1c6b5da..2865426 100644 (file)
@@ -7,30 +7,38 @@
 <chapter id="buffers-language-script-and-direction">
   <title>Buffers, language, script and direction</title>
   <para>
-    The input to HarfBuzz is a series of Unicode characters, stored in a
+    The input to the HarfBuzz shaper is a series of Unicode characters, stored in a
     buffer. In this chapter, we'll look at how to set up a buffer with
-    the text that we want and then customize the properties of the
-    buffer.
+    the text that we want and how to customize the properties of the
+    buffer. We'll also look at a piece of lower-level machinery that
+    you will need to understand before proceeding: the functions that
+    HarfBuzz uses to retrieve Unicode information.
+  </para>
+  <para>
+    After shaping is complete, HarfBuzz puts its output back
+    into the buffer. But getting that output requires setting up a
+    face and a font first, so we will look at that in the next chapter
+    instead of here.
   </para>
   <section id="creating-and-destroying-buffers">
     <title>Creating and destroying buffers</title>
     <para>
       As we saw in our <emphasis>Getting Started</emphasis> example, a
       buffer is created and 
-      initialized with <literal>hb_buffer_create()</literal>. This
+      initialized with <function>hb_buffer_create()</function>. This
       produces a new, empty buffer object, instantiated with some
       default values and ready to accept your Unicode strings.
     </para>
     <para>
       HarfBuzz manages the memory of objects (such as buffers) that it
       creates, so you don't have to. When you have finished working on 
-      a buffer, you can call <literal>hb_buffer_destroy()</literal>:
+      a buffer, you can call <function>hb_buffer_destroy()</function>:
     </para>
     <programlisting language="C">
-  hb_buffer_t *buffer = hb_buffer_create();
-  ...
-  hb_buffer_destroy(buffer);
-</programlisting>
+      hb_buffer_t *buf = hb_buffer_create();
+      ...
+      hb_buffer_destroy(buf);
+    </programlisting>
     <para>
       This will destroy the object and free its associated memory -
       unless some other part of the program holds a reference to this
       else destroying it, you should increase its reference count:
     </para>
     <programlisting language="C">
-void somefunc(hb_buffer_t *buffer) {
-  buffer = hb_buffer_reference(buffer);
-  ...
-</programlisting>
+      void somefunc(hb_buffer_t *buf) {
+      buf = hb_buffer_reference(buf);
+      ...
+    </programlisting>
     <para>
       And then decrease it once you're done with it:
     </para>
     <programlisting language="C">
-  hb_buffer_destroy(buffer);
-}
-</programlisting>
+      hb_buffer_destroy(buf);
+      }
+    </programlisting>
+    <para>
+      While we are on the subject of reference-counting buffers, it is
+      worth noting that an individual buffer can only meaningfully be
+      used by one thread at a time.
+    </para>
     <para>
       To throw away all the data in your buffer and start from scratch,
-      call <literal>hb_buffer_reset(buffer)</literal>. If you want to
+      call <function>hb_buffer_reset(buf)</function>. If you want to
       throw away the string in the buffer but keep the options, you can
-      instead call <literal>hb_buffer_clear_contents(buffer)</literal>.
+      instead call <function>hb_buffer_clear_contents(buf)</function>.
     </para>
   </section>
+  
   <section id="adding-text-to-the-buffer">
     <title>Adding text to the buffer</title>
     <para>
       Now we have a brand new HarfBuzz buffer. Let's start filling it
       with text! From HarfBuzz's perspective, a buffer is just a stream
-      of Unicode codepoints, but your input string is probably in one of
-      the standard Unicode character encodings (UTF-8, UTF-16, UTF-32)
+      of Unicode code points, but your input string is probably in one of
+      the standard Unicode character encodings (UTF-8, UTF-16, or
+      UTF-32). HarfBuzz provides convenience functions that accept
+      each of these encodings:
+      <function>hb_buffer_add_utf8()</function>,
+      <function>hb_buffer_add_utf16()</function>, and
+      <function>hb_buffer_add_utf32()</function>. Other than the
+      character encoding they accept, they function identically.
+    </para>
+    <para>
+      You can add UTF-8 text to a buffer by passing in the text array,
+      the array's length, an offset into the array for the first
+      character to add, and the length of the segment to add:
     </para>
+    <programlisting language="C">
+    hb_buffer_add_utf8 (hb_buffer_t *buf,
+                    const char *text,
+                    int text_length,
+                    unsigned int item_offset,
+                    int item_length)
+    </programlisting>
+    <para>
+      So, in practice, you can say:
+    </para>
+    <programlisting language="C">
+      hb_buffer_add_utf8(buf, text, strlen(text), 0, strlen(text));
+    </programlisting>
+    <para>
+      This will append your new characters to
+      <parameter>buf</parameter>, not replace its existing
+      contents. Also, note that you can use <literal>-1</literal> in
+      place of the first instance of <function>strlen(text)</function>
+      if your text array is NULL-terminated. Similarly, you can also use
+      <literal>-1</literal> as the final argument want to add its full
+      contents.
+    </para>
+    <para>
+      Whatever start <parameter>item_offset</parameter> and
+      <parameter>item_length</parameter> you provide, HarfBuzz will also
+      attempt to grab the five characters <emphasis>before</emphasis>
+      the offset point and the five characters
+      <emphasis>after</emphasis> the designated end. These are the
+      before and after "context" segments, which are used internally
+      for HarfBuzz to make shaping decisions. They will not be part of
+      the final output, but they ensure that HarfBuzz's
+      script-specific shaping operations are correct. If there are
+      fewer than five characters available for the before or after
+      contexts, HarfBuzz will just grab what is there.
+    </para>
+    <para>
+      For longer text runs, such as full paragraphs, it might be
+      tempting to only add smaller sub-segments to a buffer and
+      shape them in piecemeal fashion. Generally, this is not a good
+      idea, however, because a lot of shaping decisions are
+      dependent on this context information. For example, in Arabic
+      and other connected scripts, HarfBuzz needs to know the code
+      points before and after each character in order to correctly
+      determine which glyph to return.
+    </para>
+    <para>
+      The safest approach is to add all of the text available, then
+      use <parameter>item_offset</parameter> and
+      <parameter>item_length</parameter> to indicate which characters you
+      want shaped, so that HarfBuzz has access to any context.
+    </para>
+    <para>
+      You can also add Unicode code points directly with
+      <function>hb_buffer_add_codepoints()</function>. The arguments
+      to this function are the same as those for the UTF
+      encodings. But it is particularly important to note that
+      HarfBuzz does not do validity checking on the text that is added
+      to a buffer. Invalid code points will be replaced, but it is up
+      to you to do any deep-sanity checking necessary.
+    </para>
+    
   </section>
+  
   <section id="setting-buffer-properties">
     <title>Setting buffer properties</title>
     <para>
+      Buffers containing input characters still need several
+      properties set before HarfBuzz can shape their text correctly.
+    </para>
+    <para>
+      Initially, all buffers are set to the
+      <literal>HB_BUFFER_CONTENT_TYPE_INVALID</literal> content
+      type. After adding text, the buffer should be set to
+      <literal>HB_BUFFER_CONTENT_TYPE_UNICODE</literal> instead, which
+      indicates that it contains un-shaped input
+      characters. After shaping, the buffer will have the
+      <literal>HB_BUFFER_CONTENT_TYPE_GLYPHS</literal> content type.
+    </para>
+    <para>
+      <function>hb_buffer_add_utf8()</function> and the
+      other UTF functions set the content type of their buffer
+      automatically. But if you are reusing a buffer you may want to
+      check its state with
+      <function>hb_buffer_get_content_type(buffer)</function>. If
+      necessary you can set the content type with
+    </para>
+    <programlisting language="C">
+      hb_buffer_set_content_type(buf, HB_BUFFER_CONTENT_TYPE_UNICODE);
+    </programlisting>
+    <para>
+      to prepare for shaping.
+    </para>
+    <para>
+      Buffers also need to carry information about the script,
+      language, and text direction of their contents. You can set
+      these properties individually:
+    </para>
+    <programlisting language="C">
+      hb_buffer_set_direction(buf, HB_DIRECTION_LTR);
+      hb_buffer_set_script(buf, HB_SCRIPT_LATIN);
+      hb_buffer_set_language(buf, hb_language_from_string("en", -1));
+    </programlisting>
+    <para>
+      However, since these properties are often the repeated for
+      multiple text runs, you can also save them in a
+      <literal>hb_segment_properties_t</literal> for reuse:
+    </para>
+    <programlisting language="C">
+      hb_segment_properties_t *savedprops;
+      hb_buffer_get_segment_properties (buf, savedprops);
+      ...
+      hb_buffer_set_segment_properties (buf2, savedprops);
+    </programlisting>
+    <para>
+      HarfBuzz also provides getter functions to retrieve a buffer's
+      direction, script, and language properties individually.
+    </para>
+    <para>
+      HarfBuzz recognizes four text directions in
+      <type>hb_direction_t</type>: left-to-right
+      (<literal>HB_DIRECTION_LTR</literal>), right-to-left (<literal>HB_DIRECTION_RTL</literal>),
+      top-to-bottom (<literal>HB_DIRECTION_TTB</literal>), and
+      bottom-to-top (<literal>HB_DIRECTION_BTT</literal>).  For the
+      script property, HarfBuzz uses identifiers based on the
+      <ulink
+      url="https://unicode.org/iso15924/">ISO 15924
+      standard</ulink>. For languages, HarfBuzz uses tags based on the
+      <ulink url="https://tools.ietf.org/html/bcp47">IETF BCP 47</ulink> standard.
+    </para>
+    <para>
+      Helper functions are provided to convert character strings into
+      the necessary script and language tag types.
+    </para>
+    <para>
+      Two additional buffer properties to be aware of are the
+      "invisible glyph" and the replacement code point. The
+      replacement code point is inserted into buffer output in place of
+      any invalid code points encountered in the input. By default, it
+      is the Unicode <literal>REPLACEMENT CHARACTER</literal> code
+      point, <literal>U+FFFD</literal> "&#xFFFD;". You can change this with
+    </para>
+    <programlisting language="C">
+      hb_buffer_set_replacement_codepoint(buf, replacement);
+    </programlisting>
+    <para>
+      passing in the replacement Unicode code point as the
+      <parameter>replacement</parameter> parameter.
     </para>
-  </section>
-  <section id="what-about-the-other-scripts">
-    <title>What about the other scripts?</title>
     <para>
+      The invisible glyph is used to replace all output glyphs that
+      are invisible. By default, the standard space character
+      <literal>U+0020</literal> is used; you can replace this (for
+      example, when using a font that provides script-specific
+      spaces) with 
+    </para>
+    <programlisting language="C">
+      hb_buffer_set_invisible_glyph(buf, replacement_glyph);
+    </programlisting>
+    <para>
+      Do note that in the <parameter>replacement_glyph</parameter>
+      parameter, you must provide the glyph ID of the replacement you
+      wish to use, not the Unicode code point.
+    </para>
+    <para>
+      HarfBuzz supports a few additional flags you might want to set
+      on your buffer under certain circumstances. The
+      <literal>HB_BUFFER_FLAG_BOT</literal> and
+      <literal>HB_BUFFER_FLAG_EOT</literal> flags tell HarfBuzz
+      that the buffer represents the beginning or end (respectively)
+      of a text element (such as a paragraph or other block). Knowing
+      this allows HarfBuzz to apply certain contextual font features
+      when shaping, such as initial or final variants in connected
+      scripts.
+    </para>
+    <para>
+      <literal>HB_BUFFER_FLAG_PRESERVE_DEFAULT_IGNORABLES</literal>
+      tells HarfBuzz not to hide glyphs with the
+      <literal>Default_Ignorable</literal> property in Unicode. This 
+      property designates control characters and other non-printing
+      code points, such as joiners and variation selectors. Normally
+      HarfBuzz replaces them in the output buffer with zero-width
+      space glyphs (using the "invisible glyph" property discussed
+      above); setting this flag causes them to be printed, which can
+      be helpful for troubleshooting.
+    </para>
+    <para>
+      Conversely, setting the
+      <literal>HB_BUFFER_FLAG_REMOVE_DEFAULT_IGNORABLES</literal> flag
+      tells HarfBuzz to remove <literal>Default_Ignorable</literal>
+      glyphs from the output buffer entirely. Finally, setting the
+      <literal>HB_BUFFER_FLAG_DO_NOT_INSERT_DOTTED_CIRCLE</literal>
+      flag tells HarfBuzz not to insert the dotted-circle glyph
+      (<literal>U+25CC</literal>, "&#x25CC;"), which is normally
+      inserted into buffer output when broken character sequences are
+      encountered (such as combining marks that are not attached to a
+      base character).
     </para>
   </section>
+  
   <section id="customizing-unicode-functions">
     <title>Customizing Unicode functions</title>
     <para>
+      HarfBuzz requires some simple functions for accessing
+      information from the Unicode Character Database (such as the
+      <literal>General_Category</literal> (gc) and
+      <literal>Script</literal> (sc) properties) that is useful
+      for shaping, as well as some useful operations like composing and
+      decomposing code points.
+    </para>
+    <para>
+      HarfBuzz includes its own internal, lightweight set of Unicode
+      functions. At build time, it is also possible to compile support
+      for some other options, such as the Unicode functions provided
+      by GLib or the International Components for Unicode (ICU)
+      library. Generally, this option is only of interest for client
+      programs that have specific integration requirements or that do
+      a significant amount of customization.
+    </para>
+    <para>
+      If your program has access to other Unicode functions, however,
+      such as through a system library or application framework, you
+      might prefer to use those instead of the built-in
+      options. HarfBuzz supports this by implementing its Unicode
+      functions as a set of virtual methods that you can replace —
+      without otherwise affecting HarfBuzz's functionality.
+    </para>
+    <para>
+      The Unicode functions are specified in a structure called
+      <literal>unicode_funcs</literal> which is attached to each
+      buffer. But even though <literal>unicode_funcs</literal> is
+      associated with a <type>hb_buffer_t</type>, the functions
+      themselves are called by other HarfBuzz APIs that access
+      buffers, so it would be unwise for you to hook different
+      functions into different buffers.
+    </para>
+    <para>
+      In addition, you can mark your <literal>unicode_funcs</literal>
+      as immutable by calling
+      <function>hb_unicode_funcs_make_immutable (ufuncs)</function>.
+      This is especially useful if your code is a
+      library or framework that will have its own client programs. By
+      marking your Unicode function choices as immutable, you prevent
+      your own client programs from changing the
+      <literal>unicode_funcs</literal> configuration and introducing
+      inconsistencies and errors downstream.
+    </para>
+    <para>
+      You can retrieve the Unicode-functions configuration for
+      your buffer by calling <function>hb_buffer_get_unicode_funcs()</function>:
+    </para>
+    <programlisting language="C">
+      hb_unicode_funcs_t *ufunctions;
+      ufunctions = hb_buffer_get_unicode_funcs(buf);
+    </programlisting>
+    <para>
+      The current version of <literal>unicode_funcs</literal> uses six functions:
+    </para>
+    <itemizedlist>
+      <listitem>
+       <para>
+         <function>hb_unicode_combining_class_func_t</function>:
+         returns the Canonical Combining Class of a code point.
+       </para>
+      </listitem>
+      <listitem>
+       <para>
+         <function>hb_unicode_general_category_func_t</function>:
+         returns the General Category (gc) of a code point.
+       </para>
+      </listitem>
+      <listitem>
+       <para>
+         <function>hb_unicode_mirroring_func_t</function>: returns
+         the Mirroring Glyph code point (for bi-directional
+         replacement) of a code point.
+       </para>
+      </listitem>
+      <listitem>
+       <para>
+         <function>hb_unicode_script_func_t</function>: returns the
+         Script (sc) property of a code point.
+       </para>
+      </listitem>
+      <listitem>
+       <para>
+         <function>hb_unicode_compose_func_t</function>: returns the
+         canonical composition of a sequence of two code points.
+       </para>
+      </listitem>
+      <listitem>
+       <para>
+         <function>hb_unicode_decompose_func_t</function>: returns
+         the canonical decomposition of a code point.
+       </para>
+      </listitem>
+    </itemizedlist>
+    <para>
+      Note, however, that future HarfBuzz releases may alter this set.
+    </para>
+    <para>
+      Each Unicode function has a corresponding setter, with which you
+      can assign a callback to your replacement function. For example,
+      to replace
+      <function>hb_unicode_general_category_func_t</function>, you can call
+    </para>
+    <programlisting language="C">
+      hb_unicode_funcs_set_general_category_func (*ufuncs, func, *user_data, destroy)      
+    </programlisting>
+    <para>
+      Virtualizing this set of Unicode functions is primarily intended
+      to improve portability. There is no need for every client
+      program to make the effort to replace the default options, so if
+      you are unsure, do not feel any pressure to customize
+      <literal>unicode_funcs</literal>. 
     </para>
   </section>
+  
 </chapter>
index b8d9191..9147ff0 100644 (file)
       order.
     </para>
     <para>
-      For left-to-right scripts (LTR) and top-to-bottom scripts (TTB),
+      For buffers in the left-to-right (LTR)
+      or top-to-bottom (TTB) text flow direction,
       HarfBuzz will preserve the monotonic property: client programs
-      are guaranteed that monotonically increasing initial clulster
+      are guaranteed that monotonically increasing initial cluster
       values will be returned as monotonically increasing final
       cluster values.
     </para>
     <para>
-      For right-to-left scripts (RTL) and bottom-to-top scripts (BTT),
+      For buffers in the right-to-left (RTL)
+      or bottom-to-top (BTT) text flow direction,
       the directionality of the buffer itself is reversed for final
       output as a matter of design. Therefore, HarfBuzz inverts the
       monotonic property: client programs are guaranteed that
-      monotonically increasing initial clulster values will be
+      monotonically increasing initial cluster values will be
       returned as monotonically <emphasis>decreasing</emphasis> final
       cluster values.
     </para>
index 5536004..1258bec 100644 (file)
   <!ENTITY version SYSTEM "version.xml">
 ]>
 <chapter id="fonts-and-faces">
-  <title>Fonts and faces</title>
-  <section id="using-freetype">
-    <title>Using FreeType</title>
+  <title>Fonts, faces, and output</title>
+    <para>
+      In the previous chapter, we saw how to set up a buffer and fill
+      it with text as Unicode code points. In order to shape this
+      buffer text with HarfBuzz, you will need also need a font
+      object.
+    </para>
+    <para>
+      HarfBuzz provides abstractions to help you cache and reuse the
+      heavier parts of working with binary fonts, so we will look at
+      how to do that. We will also look at how to work with the
+      FreeType font-rendering library and at how you can customize
+      HarfBuzz to work with other libraries.
+    </para>
+    <para>
+      Finally, we will look at how to work with OpenType variable
+      fonts, the latest update to the OpenType font format, and at
+      some other recent additions to OpenType.
+    </para>
+
+  <section id="fonts-and-faces-objects">
+    <title>Font and face objects</title>
+    <para>
+      The outcome of shaping a run of text depends on the contents of
+      a specific font file (such as the substitutions and positioning
+      moves in the 'GSUB' and 'GPOS' tables), so HarfBuzz makes
+      accessing those internals fast.
+    </para>
+    <para>
+      An <type>hb_face_t</type> represents a <emphasis>face</emphasis>
+      in HarfBuzz. This data type is a wrapper around an
+      <type>hb_blob_t</type> blob that holds the contents of a binary
+      font file. Since HarfBuzz supports TrueType Collections and
+      OpenType Collections (each of which can include multiple
+      typefaces), a HarfBuzz face also requires an index number
+      specifying which typeface in the file you want to use. Most of
+      the font files you will encounter in the wild include just a
+      single face, however, so most of the time you would pass in
+      <literal>0</literal> as the index when you create a face:
+    </para>
+    <programlisting language="C">
+      hb_blob_t* blob = hb_blob_create_from_file(file);
+      ...
+      hb_face_t* face = hb_face_create(blob, 0);
+    </programlisting>
+    <para>
+      On its own, a face object is not quite ready to use for
+      shaping. The typeface must be set to a specific point size in
+      order for some details (such as hinting) to work. In addition,
+      if the font file in question is an OpenType Variable Font, then
+      you may need to specify one or variation-axis settings (or a
+      named instance) in order to get the output you need.
+    </para>
+    <para>
+      In HarfBuzz, you do this by creating a <emphasis>font</emphasis>
+      object from your face.
+    </para>
+    <para>
+      Font objects also have the advantage of being considerably
+      lighter-weight than face objects (remember that a face contains
+      the contents of a binary font file mapped into memory). As a
+      result, you can cache and reuse a font object, but you could
+      also create a new one for each additional size you needed.
+      Creating new fonts incurs some additional overhead, of course,
+      but whether or not it is excessive is your call in the end. In
+      contrast, face objects are substantially larger, and you really
+      should cache them and reuse them whenever possible.
+    </para>
+    <para>
+      You can create a font object from a face object:
+    </para>
+    <programlisting language="C">
+      hb_font_t* hb_font = hb_font_create(hb_face);
+    </programlisting>
+    <para>
+      After creating a font, there are a few properties you should
+      set. Many fonts enable and disable hints based on the size it
+      is used at, so setting this is important for font
+      objects. <function>hb_font_set_ppem(font, x_ppem,
+      y_ppem)</function> sets the pixels-per-EM value of the font. You
+      can also set the point size of the font with
+      <function>hb_font_set_ptem(font, ptem)</function>. HarfBuzz uses the
+      industry standard 72 points per inch.
+    </para>
+    <para>
+      HarfBuzz lets you specify the degree subpixel precision you want
+      through a scaling factor. You can set horizontal and
+      vertical scaling factors on the
+      font by calling <function>hb_font_set_scale(font, x_scale,
+      y_scale)</function>. 
+    </para>
+    <para>
+      There may be times when you are handed a font object and need to
+      access the face object that it comes from. For that, you can call
+    </para>
+    <programlisting language="C">
+      hb_face = hb_font_get_face(hb_font);
+    </programlisting>
+    <para>
+      You can also create a font object from an existing font object
+      using the <function>hb_font_create_sub_font()</function>
+      function. This creates a child font object that is initiated
+      with the same attributes as its parent; it can be used to
+      quickly set up a new font for the purpose of overriding a specific
+      font-functions method.
+    </para>
     <para>
+      All face objects and font objects are lifecycle-managed by
+      HarfBuzz. After creating a face, you increase its reference
+      count with <function>hb_face_reference(face)</function> and
+      decrease it with
+      <function>hb_face_destroy(face)</function>. Likewise, you
+      increase the reference count on a font with
+      <function>hb_font_reference(font)</function> and decrease it
+      with <function>hb_font_destroy(font)</function>.
+    </para>
+    <para>
+      You can also attach user data to face objects and font objects.
     </para>
   </section>
-  <section id="using-harfbuzzs-native-opentype-implementation">
-    <title>Using HarfBuzz's native OpenType implementation</title>
+
+ <section id="fonts-and-faces-custom-functions">
+    <title>Customizing font functions</title>
+    <para>
+      During shaping, HarfBuzz frequently needs to query font objects
+      to get at the contents and parameters of the glyphs in a font
+      file. It includes a built-in set of functions that is tailored
+      to working with OpenType fonts. However, as was the case with
+      Unicode functions in the buffers chapter, HarfBuzz also wants to
+      make it easy for you to assign a substitute set of font
+      functions if you are developing a program to work with a library
+      or platform that provides its own font functions. 
+    </para>
+    <para>
+      Therefore, the HarfBuzz API defines a set of virtual
+      methods for accessing font-object properties, and you can
+      replace the defaults with your own selections without
+      interfering with the shaping process. Each font object in
+      HarfBuzz includes a structure called
+      <literal>font_funcs</literal> that serves as a vtable for the
+      font object. The virtual methods in
+      <literal>font_funcs</literal> are:
+    </para>
+    <itemizedlist>
+      <listitem>
+    <para>
+      <function>hb_font_get_font_h_extents_func_t</function>: returns
+      the extents of the font for horizontal text.
+    </para>
+      </listitem>
+      <listitem>
+    <para>
+      <function>hb_font_get_font_v_extents_func_t</function>: returns
+      the extents of the font for vertical text.
+    </para>
+      </listitem>
+      <listitem>
+    <para>
+      <function>hb_font_get_nominal_glyph_func_t</function>: returns
+      the font's nominal glyph for a given code point.
+    </para>
+      </listitem>
+      <listitem>
+    <para>
+      <function>hb_font_get_variation_glyph_func_t</function>: returns
+      the font's glyph for a given code point when it is followed by a
+      given Variation Selector.
+    </para>
+      </listitem>
+      <listitem>
     <para>
+      <function>hb_font_get_nominal_glyphs_func_t</function>: returns
+      the font's nominal glyphs for a series of code points.
+    </para>
+      </listitem>
+      <listitem>
+    <para>
+      <function>hb_font_get_glyph_advance_func_t</function>: returns
+      the advance for a glyph.
+    </para>
+      </listitem>
+      <listitem>
+    <para>
+      <function>hb_font_get_glyph_h_advance_func_t</function>: returns
+      the advance for a glyph for horizontal text.
+    </para>
+      </listitem>
+      <listitem>
+    <para>
+      <function>hb_font_get_glyph_v_advance_func_t</function>:returns
+      the advance for a glyph for vertical text.
+    </para>
+      </listitem>
+      <listitem>
+    <para>
+      <function>hb_font_get_glyph_advances_func_t</function>: returns
+      the advances for a series of glyphs.
+    </para>
+      </listitem>
+      <listitem>
+    <para>
+      <function>hb_font_get_glyph_h_advances_func_t</function>: returns
+      the advances for a series of glyphs for horizontal text .
+    </para>
+      </listitem>
+      <listitem>
+    <para>
+      <function>hb_font_get_glyph_v_advances_func_t</function>: returns
+      the advances for a series of glyphs for vertical text.
+    </para>
+      </listitem>
+      <listitem>
+    <para>
+      <function>hb_font_get_glyph_origin_func_t</function>: returns
+      the origin coordinates of a glyph.
+    </para>
+      </listitem>
+      <listitem>
+    <para>
+      <function>hb_font_get_glyph_h_origin_func_t</function>: returns
+      the origin coordinates of a glyph for horizontal text.
+    </para>
+      </listitem>
+      <listitem>
+    <para>
+      <function>hb_font_get_glyph_v_origin_func_t</function>: returns
+      the origin coordinates of a glyph for vertical text.
+    </para>
+      </listitem>
+      <listitem>
+    <para>
+      <function>hb_font_get_glyph_extents_func_t</function>: returns
+      the extents for a glyph.
+    </para>
+      </listitem>
+      <listitem>
+    <para>
+      <function>hb_font_get_glyph_contour_point_func_t</function>:
+      returns the coordinates of a specific contour point from a glyph.
+    </para>
+      </listitem>
+      <listitem>
+    <para>
+      <function>hb_font_get_glyph_name_func_t</function>: returns the
+      name of a glyph (from its glyph index).
+    </para>
+      </listitem>
+      <listitem>
+    <para>
+      <function>hb_font_get_glyph_from_name_func_t</function>: returns
+      the glyph index that corresponds to a given glyph name.
+    </para>
+      </listitem>
+    </itemizedlist>
+    <para>
+      You can fetch the font-functions configuration for a font object
+      by calling <function>hb_font_get_font_funcs()</function>:
+    </para>
+    <programlisting language="C">
+      hb_font_funcs_t *ffunctions;
+      ffunctions = hb_font_get_font_funcs (font);
+    </programlisting>
+    <para>
+      The individual methods can each be replaced with their own setter
+      function, such as
+      <function>hb_font_funcs_set_nominal_glyph_func(*ffunctions,
+      func, *user_data, destroy)</function>. 
+    </para>
+    <para>
+      Font-functions structures can be reused for multiple font
+      objects, and can be reference counted with
+      <function>hb_font_funcs_reference()</function> and
+      <function>hb_font_funcs_destroy()</function>. Just like other
+      objects in HarfBuzz, you can set user-data for each
+      font-functions structure and assign a destroy callback for
+      it.
+    </para>
+    <para>
+      You can also mark a font-functions structure as immutable,
+      with <function>hb_font_funcs_make_immutable()</function>. This
+      is especially useful if your code is a library or framework that
+      will have its own client programs. By marking your
+      font-functions structures as immutable, you prevent your client
+      programs from changing the configuration and introducing
+      inconsistencies and errors downstream.
     </para>
   </section>
-  <section id="using-your-own-font-functions">
-    <title>Using your own font functions</title>
+
+  <section id="fonts-and-faces-native-opentype">
+    <title>Font objects and HarfBuzz's native OpenType implementation</title>
+    <para>
+      By default, whenever HarfBuzz creates a font object, it will
+      configure the font to use a built-in set of font functions that
+      supports contemporary OpenType font internals. If you want to
+      work with OpenType or TrueType fonts, you should be able to use
+      these functions without difficulty.
+    </para>
+    <para>
+      Many of the methods in the font-functions structure deal with
+      the fundamental properties of glyphs that are required for
+      shaping text: extents (the maximums and minimums on each axis),
+      origins (the <literal>(0,0)</literal> coordinate point which
+      glyphs are drawn in reference to), and advances (the amount that
+      the cursor needs to be moved after drawing each glyph, including
+      any empty space for the glyph's side bearings).
+    </para>
+    <para>
+      As you can see in the list of functions, there are separate "horizontal"
+      and "vertical" variants depending on whether the text is set in
+      the horizontal or vertical direction. For some scripts, fonts
+      that are designed to support text set horizontally or vertically (for
+      example, in Japanese) may include metrics for both text
+      directions. When fonts don't include this information, HarfBuzz
+      does its best to transform what the font provides.
+    </para>
+    <para>
+      In addition to the direction-specific functions, HarfBuzz
+      provides some higher-level functions for fetching information
+      like extents and advances for a glyph. If you call
+    </para>
+    <programlisting language="C">
+      hb_font_get_glyph_advance_for_direction(font, direction, extents);
+    </programlisting>
+    <para>
+      then you can provide any <type>hb_direction_t</type> as the
+      <parameter>direction</parameter> parameter, and HarfBuzz will
+      use the correct function variant for the text direction. There
+      are similar higher-level versions of the functions for fetching
+      extents, origin coordinates, and contour-point
+      coordinates. There are also addition and subtraction functions
+      for moving points with respect to the origin.
+    </para>
+    <para>
+      There are also methods for fetching the glyph ID that
+      corresponds to a Unicode code point (possibly when followed by a
+      variation-selector code point), fetching the glyph name from the
+      font, and fetching the glyph ID that corresponds to a glyph name
+      you already have.
+    </para>
+    <para>
+      HarfBuzz also provides functions for converting between glyph
+      names and string
+      variables. <function>hb_font_glyph_to_string(font, glyph, s,
+      size)</function> retrieves the name for the glyph ID
+      <parameter>glyph</parameter> from the font object. It generates a
+      generic name of the form <literal>gidDDD</literal> (where DDD is
+      the glyph index) if there is no name for the glyph in the
+      font. The <function>hb_font_glyph_from_string(font, s, len,
+      glyph)</function> takes an input string <parameter>s</parameter>
+      and looks for a glyph with that name in the font, returning its
+      glyph ID in the <parameter>glyph</parameter>
+      output parameter. It automatically parses
+      <literal>gidDDD</literal> and <literal>uniUUUU</literal> strings.
+    </para>
+  </section>
+
+
+  <!-- Commenting out FreeType integration section-holder for now. May move
+       to the full-blown Integration Chapter. -->
+  
+  <!--   <section id="fonts-and-faces-freetype">
+    <title>Using FreeType</title>
+    <para>
+
+    </para>
+    <para>
+      
+    </para>
+  </section> -->
+
+  <section id="fonts-and-faces-variable">
+    <title>Working with OpenType Variable Fonts</title>
+    <para>
+      If you are working with OpenType Variable Fonts, there are a few
+      additional functions you should use to specify the
+      variation-axis settings of your font object. Without doing so,
+      your variable font's font object can still be used, but only at
+      the default setting for every axis (which, of course, is
+      sometimes what you want, but does not cover general usage).
+    </para>
+    <para>
+      HarfBuzz manages variation settings in the
+      <type>hb_variation_t</type> data type, which holds a <property>tag</property> for the
+      variation-axis identifier tag and a <property>value</property> for its
+      setting. You can retrieve the list of variation axes in a font
+      binary from the face object (not from a font object, notably) by
+      calling <function>hb_ot_var_get_axis_count(face)</function> to
+      find the number of axes, then using
+      <function>hb_ot_var_get_axis_infos()</function> to collect the 
+      axis structures:
+    </para>
+    <programlisting language="C">
+      axes = hb_ot_var_get_axis_count(face);
+      ...
+      hb_ot_var_get_axis_infos(face, 0, axes, axes_array);
+    </programlisting>
+    <para>
+      For each axis returned in the array, you can can access the
+      identifier in its <property>tag</property>. HarfBuzz also has
+      tag definitions predefined for the five standard axes specified
+      in OpenType (<literal>ital</literal> for italic,
+      <literal>opsz</literal> for optical size,
+      <literal>slnt</literal> for slant, <literal>wdth</literal> for
+      width, and <literal>wght</literal> for weight). Each axis also
+      has a <property>min_value</property>, a
+      <property>default_value</property>, and a <property>max_value</property>.
+    </para>
+    <para>
+      To set your font object's variation settings, you call the
+      <function>hb_font_set_variations()</function> function with an
+      array of <type>hb_variation_t</type> variation settings. Let's
+      say our font has weight and width axes. We need to specify each
+      of the axes by tag and assign a value on the axis:
+    </para>
+    <programlisting language="C">
+      unsigned int variation_count = 2;
+      hb_variation_t variation_data[variation_count];
+      variation_data[0].tag = HB_OT_TAG_VAR_AXIS_WIDTH;
+      variation_data[1].tag = HB_OT_TAG_VAR_AXIS_WEIGHT;
+      variation_data[0].value = 80;
+      variation_data[1].value = 750;
+      ...
+      hb_font_set_variations(font, variation_data, variation_count);
+    </programlisting>
+    <para>
+      That should give us a slightly condensed font ("normal" on the
+      <literal>wdth</literal> axis is 100) at a noticeably bolder
+      weight ("regular" is 400 on the <literal>wght</literal> axis).
+    </para>
+    <para>
+      In practice, though, you should always check that the value you
+      want to set on the axis is within the
+      [<property>min_value</property>,<property>max_value</property>]
+      range actually implemented in the font's variation axis. After
+      all, a font might only provide lighter-than-regular weights, and
+      setting a heavier value on the <literal>wght</literal> axis will
+      not change that. 
+    </para>
     <para>
+      Once your variation settings are specified on your font object,
+      however, shaping with a variable font is just like shaping a
+      static font.
     </para>
   </section>
-</chapter>
+
+ </chapter>
index a1e7ab0..2b61ce8 100644 (file)
          <listitem>
            <para>
             Use <ulink url="https://developer.gnome.org/glib/">GLib</ulink>. <emphasis>(Default = auto)</emphasis>
-           </para>         
+           </para>
            <para>
              This option enables or disables usage of the GLib
              library.  The default setting is to check for the
          <listitem>
            <para>
              Use <ulink url="https://www.freedesktop.org/wiki/Software/fontconfig/">Fontconfig</ulink>. <emphasis>(Default = auto)</emphasis>
-           </para>         
+           </para>
            <para>
              This option enables or disables usage of the Fontconfig
              library, which provides font-matching functions and
          <listitem>
            <para>
              Use the <ulink url="http://site.icu-project.org/home">ICU</ulink> library. <emphasis>(Default = auto)</emphasis>
-           </para>         
+           </para>
            <para>
              This option enables or disables usage of the
              <emphasis>International Components for
        </varlistentry>
        
        <varlistentry>
-         <term><command>--with-ucdn</command></term>
-         <listitem>
-           <para>
-             Use HarfBuzz's <ulink url="https://github.com/harfbuzz/harfbuzz/tree/master/src/hb-ucdn">built-in UCDN library</ulink>. <emphasis>(Default = auto)</emphasis>
-           </para>         
-           <para>
-             The HarfBuzz source tree includes a <emphasis>Unicode
-             Database and Normalization</emphasis> (UCDN) library
-             that provides access to basic character properties in
-             the Unicode Character Database (UCD) as well as low-level
-             normalization functions. HarfBuzz can be built without
-             this UCDN support if the usage of a different UCDN
-             library is desired.
-           </para>
-         </listitem>
-       </varlistentry>
-       
-       <varlistentry>
          <term><command>--with-graphite2</command></term>
          <listitem>
            <para>
              Use the <ulink url="http://graphite.sil.org/">Graphite2</ulink> library. <emphasis>(Default = no)</emphasis>
-           </para>         
+           </para>
            <para>
              This option enables or disables usage of the Graphite2
              library, which provides support for the Graphite shaping
          <listitem>
            <para>
              Use the <ulink url="https://www.freetype.org/">FreeType</ulink> library. <emphasis>(Default = auto)</emphasis>
-           </para>         
+           </para>
            <para>
              This option enables or disables usage of the FreeType
              font-rendering library. The default setting is to check for the
              Use the <ulink
              url="https://docs.microsoft.com/en-us/windows/desktop/intl/uniscribe">Uniscribe</ulink>
              library (experimental). <emphasis>(Default = no)</emphasis>
-           </para>         
+           </para>
            <para>
              This option enables or disables usage of the Uniscribe
              font-rendering library. Uniscribe is available on
          <listitem>
            <para>
              Use the <ulink url="https://docs.microsoft.com/en-us/windows/desktop/directwrite/direct-write-portal">DirectWrite</ulink> library (experimental). <emphasis>(Default = no)</emphasis>
-           </para>         
+           </para>
            <para>
              This option enables or disables usage of the DirectWrite
              font-rendering library. DirectWrite is available on
          <listitem>
            <para>
              Use the <ulink url="https://developer.apple.com/documentation/coretext">CoreText</ulink> library. <emphasis>(Default = no)</emphasis>
-           </para>         
+           </para>
            <para>
              This option enables or disables usage of the CoreText
              library. CoreText is available on macOS and iOS systems.
diff --git a/docs/usermanual-object-model.xml b/docs/usermanual-object-model.xml
new file mode 100644 (file)
index 0000000..f571c47
--- /dev/null
@@ -0,0 +1,258 @@
+<?xml version="1.0"?>
+<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.3//EN"
+               "http://www.oasis-open.org/docbook/xml/4.3/docbookx.dtd" [
+  <!ENTITY % local.common.attrib "xmlns:xi  CDATA  #FIXED 'http://www.w3.org/2003/XInclude'">
+  <!ENTITY version SYSTEM "version.xml">
+]>
+<chapter id="object-model">
+  <title>The HarfBuzz object model</title>
+  <section id="object-model-intro">
+    <title>An overview of data types in HarfBuzz</title>
+    <para>
+      HarfBuzz features two kinds of data types: non-opaque,
+      pass-by-value types and opaque, heap-allocated types.  This kind
+      of separation is common in C libraries that have to provide
+      API/ABI compatibility (almost) indefinitely. 
+    </para>
+    <para>
+      <emphasis>Value types:</emphasis> The non-opaque, pass-by-value
+      types include integer types, enums, and small structs.  Exposing
+      a struct in the public API makes it impossible to expand the
+      struct in the future. As such, exposing structs is reserved for
+      cases where it’s extremely inefficient to do otherwise.
+    </para>
+    <para>
+      In HarfBuzz, several structs, like <literal>hb_glyph_info_t</literal> and
+      <literal>hb_glyph_position_t</literal>, fall into that efficiency-sensitive
+      category and are non-opaque.
+    </para>
+    <para>
+      For all non-opaque structs where future extensibility may be
+      necessary, reserved members are included to hold space for
+      possible future members.  As such, it’s important to provide
+      <function>equal()</function>, and <function>hash()</function>
+      methods for such structs, allowing users of the API do
+      effectively deal with the type without having to 
+      adapt their code to future changes. 
+    </para>
+    <para>
+      Important value types provided by HarfBuzz include the structs
+      for working with Unicode code points, glyphs, and tags for font
+      tables and features, as well as the enums for many Unicode and
+      OpenType properties.
+    </para>
+  </section>
+  
+  <section id="object-model-object-types">
+    <title>Objects in HarfBuzz</title>
+    <para>
+      <emphasis>Object types:</emphasis> Opaque struct types are used
+      for what HarfBuzz loosely calls "objects."  This doesn’t have
+      much to do with the terminology from object-oriented programming
+      (OOP), although some of the concepts are similar.
+    </para>
+    <para>
+      In HarfBuzz, all object types provide certain
+      lifecycle-management APIs.  Objects are reference-counted, and
+      constructed with various <function>create()</function> methods, referenced via
+      <function>reference()</function> and dereferenced using
+      <function>destroy()</function>.
+    </para>
+    <para>
+      For example,
+      the <literal>hb_buffer_t</literal> object has
+      <function>hb_buffer_create()</function> as its constructor,
+      <function>hb_buffer_reference()</function> to reference, and
+      <function>hb_buffer_destroy()</function> to dereference. 
+    </para>
+    <para>
+      After construction, each object's properties are accessible only
+      through the setter and getter functions described in the API
+      Reference manual.
+    </para>
+    <para>
+      Key object types provided by HarfBuzz include:
+    </para>
+    <itemizedlist spacing="compact">
+      <listitem>
+       <para>
+         <emphasis>blobs</emphasis>, which act as low-level wrappers around binary
+         data. Blobs are typically used to hold the contents of a
+         binary font file.
+       </para>
+      </listitem>
+      <listitem>
+       <para>
+         <emphasis>faces</emphasis>, which represent typefaces from a
+         font file, but without specific parameters (such as size) set.
+       </para>
+      </listitem>
+      <listitem>
+       <para>
+         <emphasis>fonts</emphasis>, which represent instances of a
+         face with all of their parameters specified.
+       </para>
+      </listitem>
+      <listitem>
+       <para>
+         <emphasis>buffers</emphasis>, which hold Unicode code points
+         for characters (before shaping) and the shaped glyph output
+         (after shaping).
+       </para>
+      </listitem>
+      <listitem>
+       <para>
+         <emphasis>shape plans</emphasis>, which store the settings
+         that HarfBuzz will use when shaping a particular text
+         segment. Shape plans are not generally used by client
+         programs directly, but as we will see in a later chapter,
+         they are still valuable to understand.
+       </para>
+      </listitem>
+    </itemizedlist>
+       
+  </section>
+
+  
+  
+  <section id="object-model-lifecycle">
+    <title>Object lifecycle management</title>
+    <para>
+      Each object type in HarfBuzz provides a
+      <function>create()</function> method. Some object types provide
+      additional variants of <function>create()</function> to handle
+      special cases or to speed up common tasks; those variants are
+      documented in the API reference. For example,
+      <function>hb_blob_create_from_file()</function> constructs a new
+      blob directly from the contents of a file.
+    </para>
+    <para>
+      All objects are created with an initial reference count of
+      <literal>1</literal>. Client programs can increase the reference
+      count on an object by calling its
+      <function>reference()</function> method. Whenever a client
+      program is finished with an object, it should call its 
+      corresponding <function>destroy()</function> method. The destroy
+      method will decrease the reference count on the object and,
+      whenever the reference count reaches zero, it will also destroy
+      the object and free all of the associated memory.
+    </para>
+    <para>
+      All of HarfBuzz's object-lifecycle-management APIs are
+      thread-safe (unless you compiled HarfBuzz from source with the
+      <literal>HB_NO_MT</literal> configuration flag), even when the
+      object as a whole is not thread-safe. 
+      It is also permissible to <function>reference()</function> or to 
+      <function>destroy()</function> the <literal>NULL</literal>
+      value.
+    </para>
+    <para>
+      Some objects are thread-safe after they have been constructed
+      and set up. The general pattern is to
+      <function>create()</function> the object, make a few
+      <function>set_*()</function> calls to set up the
+      object, and then use it without further modification.
+    </para>
+    <para>
+      To ensure that such an object is not modified, client programs
+      can explicitly mark an object as immutable. HarfBuzz provides
+      <function>make_immutable()</function> methods to mark an object
+      as immutable and <function>is_immutable()</function> methods to
+      test whether or not an object is immutable. Attempts to use
+      setter functions on immutable objects will fail silently; see the API
+      Reference manual for specifics. 
+    </para>
+    <para>
+      Note also that there are no "make mutable" methods. If client
+      programs need to alter an object previously marked as immutable,
+      they will need to make a duplicate of the original.
+    </para>
+    <para>
+      Finally, object constructors (and, indeed, as much of the
+      shaping API as possible) will never return
+      <literal>NULL</literal>.  Instead, if there is an allocation
+      error, each constructor will return an “empty” object
+      singleton.
+    </para>
+    <para>
+      These empty-object singletons are inert and safe (although
+      typically useless) to pass around.  This design choice avoids
+      having to check for <literal>NULL</literal> pointers all
+      throughout the code.
+    </para>
+    <para>
+      In addition, this “empty” object singleton can also be accessed
+      using the <function>get_empty()</function> method of the object
+      type in question.
+    </para>
+  </section>
+
+  
+  <section id="object-model-user-data">
+    <title>User data</title>
+    <para>
+      To better integrate with client programs, HarfBuzz's objects
+      offer a "user data" mechanism that can be used to attach
+      arbitrary data to the object.  User-data attachment can be
+      useful for tying the lifecycles of various pieces of data
+      together, or for creating language bindings. 
+    </para>
+    <para>
+      Each object type has a <function>set_user_data()</function>
+      method and a <function>get_user_data()</function> method. The
+      <function>set_user_data()</function> methods take a client-provided
+      <literal>key</literal> and a pointer,
+      <literal>user_data</literal>, pointing to the data itself. Once
+      the key-data pair has been attached to the object, the
+      <function>get_user_data()</function> method can be called with
+      the key, returning the <function>user_data</function> pointer.
+    </para>
+    <para>
+      The <function>set_user_data()</function> methods also support an
+      optional <function>destroy</function> callback. Client programs
+      can set the <function>destroy</function> callback and receive
+      notification from HarfBuzz whenever the object is destructed.
+    </para>
+    <para>
+      Finally, each <function>set_user_data()</function> method allows
+      the client program to set a <literal>replace</literal> Boolean
+      indicating whether or not the function call should replace any
+      existing <literal>user_data</literal>
+      associated with the specified key.
+    </para>
+  </section>  
+
+  
+  
+  <section id="object-model-blobs">
+    <title>Blobs</title>
+    <para>
+      While most of HarfBuzz's object types are specific to the
+      shaping process, <emphasis>blobs</emphasis> are somewhat
+      different.
+    </para>
+    <para>
+      Blobs are an abstraction desgined to negotiate lifecycle and
+      permissions for raw pieces of data.  For example, when you load
+      the raw font data into memory and want to pass it to HarfBuzz,
+      you do so in a <literal>hb_blob_t</literal> wrapper.
+    </para>
+    <para>
+      This allows you to take advantage of HarffBuzz's
+      reference-counting and <function>destroy</function>
+      callbacks. If you allocated the memory for the data using 
+      <function>malloc()</function>, you would create the blob using
+    </para>
+    <programlisting language="C">
+      hb_blob_create (data, length, HB_MEMORY_MODE_WRITABLE, NULL, free)
+    </programlisting>
+    <para>
+      That way, HarfBuzz will call <function>free()</function> on the
+      allocated memory whenever the blob drops its last reference and
+      is deconstructed.  Consequently, the user code can stop worrying
+      about freeing memory and let the reference-counting machinery
+      take care of that. 
+    </para>
+  </section>
+  
+</chapter>
index 51ff55a..881af2a 100644 (file)
 ]>
 <chapter id="shaping-and-shape-plans">
   <title>Shaping and shape plans</title>
-  <section id="opentype-features">
+  <para>
+    Once you have your face and font objects configured as desired and
+    your input buffer is filled with the characters you need to shape,
+    all you need to do is call <function>hb_shape()</function>.
+  </para>
+  <para>
+    HarfBuzz will return the shaped version of the text in the same
+    buffer that you provided, but it will be in output mode. At that
+    point, you can iterate through the glyphs in the buffer, drawing
+    each one at the specified position or handing them off to the
+    appropriate graphics library.
+  </para>
+  <para>
+    For the most part, HarfBuzz's shaping step is straightforward from
+    the outside. But that doesn't mean there will never be cases where
+    you want to look under the hood and see what is happening on the
+    inside. HarfBuzz provides facilities for doing that, too.
+  </para>
+  
+  <section id="shaping-buffer-output">
+    <title>Shaping and buffer output</title>
+    <para>
+      The <function>hb_shape()</function> function call takes four arguments: the font
+      object to use, the buffer of characters to shape, an array of
+      user-specified features to apply, and the length of that feature
+      array. The feature array can be NULL, so for the sake of
+      simplicity we will start with that case.
+    </para>
+    <para>
+      Internally, HarfBuzz looks  at the tables of the font file to
+      determine where glyph classes, substitutions, and positioning
+      are defined, using that information to decide which
+      <emphasis>shaper</emphasis> to use (<literal>ot</literal> for
+      OpenType fonts, <literal>aat</literal> for Apple Advanced
+      Typography fonts, and so on). It also looks at the direction,
+      script, and language properties of the segment to figure out
+      which script-specific shaping model is needed (at least, in
+      shapers that support multiple options).      
+    </para>
+    <para>
+      If a font has a GDEF table, then that is used for
+      glyph classes; if not, HarfBuzz will fall back to Unicode
+      categorization by code point. If a font has an AAT "morx" table,
+      then it is used for substitutions; if not, but there is a GSUB
+      table, then the GSUB table is used. If the font has an AAT
+      "kerx" table, then it is used for positioning; if not, but
+      there is a GPOS table, then the GPOS table is used. If neither
+      table is found, but there is a "kern" table, then HarfBuzz will
+      use the "kern" table. If there is no "kerx", no GPOS, and no
+      "kern", HarfBuzz will fall back to positioning marks itself.
+    </para>
+    <para>
+      With a well-behaved OpenType font, you expect GDEF, GSUB, and
+      GPOS tables to all be applied. HarfBuzz implements the
+      script-specific shaping models in internal functions, rather
+      than in the public API.
+    </para>
+    <para>
+      The algorithms
+      used for complex scripts can be quite involved; HarfBuzz tries
+      to be compatible with the OpenType Layout specification
+      and, wherever there is any ambiguity, HarfBuzz attempts to replicate the
+      output of Microsoft's Uniscribe engine. See the <ulink
+      url="https://docs.microsoft.com/en-us/typography/script-development/standard">Microsoft
+      Typography pages</ulink> for more detail.
+    </para>
+    <para>
+      In general, though, all that you need to know is that
+      <function>hb_shape()</function> returns the results of shaping
+      in the same buffer that you provided. The buffer's content type
+      will now be set to
+      <literal>HB_BUFFER_CONTENT_TYPE_GLYPHS</literal>, indicating
+      that it contains shaped output, rather than input text. You can
+      now extract the glyph information and positioning arrays:
+    </para>
+    <programlisting language="C">
+      hb_glyph_info_t *glyph_info    = hb_buffer_get_glyph_infos(buf, &amp;glyph_count);
+      hb_glyph_position_t *glyph_pos = hb_buffer_get_glyph_positions(buf, &amp;glyph_count);
+    </programlisting>
+    <para>
+      The glyph information array holds a <type>hb_glyph_info_t</type>
+      for each output glyph, which has two fields:
+      <parameter>codepoint</parameter> and
+      <parameter>cluster</parameter>. Whereas, in the input buffer,
+      the <parameter>codepoint</parameter> field contained the Unicode
+      code point, it now contains the glyph ID of the corresponding
+      glyph in the font. The <parameter>cluster</parameter> field is
+      an integer that you can use to help identify when shaping has
+      reordered, split, or combined code points; we will say more
+      about that in the next chapter.
+    </para>
+    <para>
+      The glyph positions array holds a corresponding
+      <type>hb_glyph_position_t</type> for each output glyph,
+      containing four fields: <parameter>x_advance</parameter>,
+      <parameter>y_advance</parameter>,
+      <parameter>x_offset</parameter>, and
+      <parameter>y_offset</parameter>. The advances tell you how far
+      you need to move the drawing point after drawing this glyph,
+      depending on whether you are setting horizontal text (in which
+      case you will have x advances) or vertical text (for which you
+      will have y advances). The x and y offsets tell you where to
+      move to start drawing the glyph; usually you will have both and
+      x and a y offset, regardless of the text direction.
+    </para>
+    <para>
+      Most of the time, you will rely on a font-rendering library or
+      other graphics library to do the actual drawing of glyphs, so
+      you will need to iterate through the glyphs in the buffer and
+      pass the corresponding values off.
+    </para>
+  </section>
+  
+  <section id="shaping-opentype-features">
     <title>OpenType features</title>
     <para>
+      OpenType features enable fonts to include smart behavior,
+      implemented as "lookup" rules stored in the GSUB and GPOS
+      tables. The OpenType specification defines a long list of
+      standard features that fonts can use for these behaviors; each
+      feature has a four-character reserved name and a well-defined
+      semantic meaning.
+    </para>
+    <para>
+      Some OpenType features are defined for the purpose of supporting
+      complex-script shaping, and are automatically activated, but
+      only when a buffer's script property is set to a script that the
+      feature supports.
+    </para>
+    <para>
+      Other features are more generic and can apply to several (or
+      any) script, and shaping engines are expected to implement
+      them. By default, HarfBuzz activates several of these features
+      on every text run. They include <literal>abvm</literal>,
+      <literal>blwm</literal>, <literal>ccmp</literal>,
+      <literal>locl</literal>, <literal>mark</literal>,
+      <literal>mkmk</literal>, and <literal>rlig</literal>.
+    </para>
+    <para>
+      In addition, if the text direction is horizontal, HarfBuzz
+      also applies the <literal>calt</literal>,
+      <literal>clig</literal>, <literal>curs</literal>,
+      <literal>dist</literal>, <literal>kern</literal>,
+      <literal>liga</literal>, <literal>rclt</literal>,
+      and <literal>frac</literal> features.
+    </para>
+    <para>
+      If the text direction is vertical, HarfBuzz applies
+      the <literal>vert</literal> feature by default.
+    </para>
+    <para>
+      Still other features are designed to be purely optional and left
+      up to the application or the end user to enable or disable as desired.
+    </para>
+    <para>
+      You can adjust the set of features that HarfBuzz applies to a
+      buffer by supplying an array of <type>hb_feature_t</type>
+      features as the third argument to
+      <function>hb_shape()</function>. For a simple case, let's just
+      enable the <literal>dlig</literal> feature, which turns on any
+      "discretionary" ligatures in the font:
+    </para>
+    <programlisting language="C">
+      hb_feature_t userfeatures[1];
+      userfeatures[0].tag = HB_TAG('d','l','i','g');
+      userfeatures[0].value = 1;
+      userfeatures[0].start = HB_FEATURE_GLOBAL_START;
+      userfeatures[0].end = HB_FEATURE_GLOBAL_END;
+    </programlisting>
+    <para>
+      <literal>HB_FEATURE_GLOBAL_END</literal> and
+      <literal>HB_FEATURE_GLOBAL_END</literal> are macros we can use
+      to indicate that the features will be applied to the entire
+      buffer. We could also have used a literal <literal>0</literal>
+      for the start and a <literal>-1</literal> to indicate the end of
+      the buffer (or have selected other start and end positions, if needed).
+    </para>
+    <para>
+      When we pass the <varname>userfeatures</varname> array to
+      <function>hb_shape()</function>, any discretionary ligature
+      substitutions from our font that match the text in our buffer
+      will get performed:
+    </para>
+    <programlisting language="C">
+      hb_shape(font, buf, userfeatures, num_features);
+    </programlisting>
+    <para>
+      Just like we enabled the <literal>dlig</literal> feature by
+      setting its <parameter>value</parameter> to
+      <literal>1</literal>, you would disable a feature by setting its
+      <parameter>value</parameter> to <literal>0</literal>. Some
+      features can take other <parameter>value</parameter> settings;
+      be sure you read the full specification of each feature tag to
+      understand what it does and how to control it.
     </para>
   </section>
-  <section id="plans-and-caching">
+
+  <section id="shaping-shaper-selection">
+    <title>Shaper selection</title>
+    <para>
+      The basic version of <function>hb_shape()</function> determines
+      its shaping strategy based on examining the capabilities of the
+      font file. OpenType font tables cause HarfBuzz to try the
+      <literal>ot</literal> shaper, while AAT font tables cause HarfBuzz to try the
+      <literal>aat</literal> shaper. 
+    </para>
+    <para>
+      In the real world, however, a font might include some unusual
+      mix of tables, or one of the tables might simply be broken for
+      the script you need to shape. So, sometimes, you might not
+      want to rely on HarfBuzz's process for deciding what to do, and
+      just tell <function>hb_shape()</function> what you want it to try.
+    </para>
+    <para>
+      <function>hb_shape_full()</function> is an alternate shaping
+      function that lets you supply a list of shapers for HarfBuzz to
+      try, in order, when shaping your buffer. For example, if you
+      have determined that HarfBuzz's attempts to work around broken
+      tables gives you better results than the AAT shaper itself does,
+      you might move the AAT shaper to the end of your list of
+      preferences and call <function>hb_shape_full()</function>
+    </para>
+    <programlisting language="C">
+      char *shaperprefs[3] = {"ot", "default", "aat"};
+      ...
+      hb_shape_full(font, buf, userfeatures, num_features, shaperprefs);
+    </programlisting>
+    <para>
+      to get results you are happier with.
+    </para>
+    <para>
+      You may also want to call
+      <function>hb_shape_list_shapers()</function> to get a list of
+      the shapers that were built at compile time in your copy of HarfBuzz.
+    </para>
+  </section>
+  
+  <section id="shaping-plans-and-caching">
     <title>Plans and caching</title>
     <para>
+      Internally, HarfBuzz uses a structure called a shape plan to
+      track its decisions about how to shape the contents of a
+      buffer. The <function>hb_shape()</function> function builds up the shape plan by
+      examining segment properties and by inspecting the contents of
+      the font.
+    </para>
+    <para>
+      This process can involve some decision-making and
+      trade-offs — for example, HarfBuzz inspects the GSUB and GPOS
+      lookups for the script and language tags set on the segment
+      properties, but it falls back on the lookups under the
+      <literal>DFLT</literal> tag (and sometimes other common tags)
+      if there are actually no lookups for the tag requested.
+    </para>
+    <para>
+      HarfBuzz also includes some work-arounds for
+      handling well-known older font conventions that do not follow
+      OpenType or Unicode specifications, for buggy system fonts, and for
+      peculiarities of Microsoft Uniscribe. All of that means that a
+      shape plan, while not something that you should edit directly in
+      client code, still might be an object that you want to
+      inspect. Furthermore, if resources are tight, you might want to
+      cache the shape plan that HarfBuzz builds for your buffer and
+      font, so that you do not have to rebuild it for every shaping call.
+    </para>
+    <para>
+      You can create a cacheable shape plan with
+      <function>hb_shape_plan_create_cached(face, props,
+      user_features, num_user_features, shaper_list)</function>, where
+      <parameter>face</parameter> is a face object (not a font object,
+      notably), <parameter>props</parameter> is an
+      <type>hb_segment_properties_t</type>,
+      <parameter>user_features</parameter> is an array of
+      <type>hb_feature_t</type>s (with length
+      <parameter>num_user_features</parameter>), and
+      <parameter>shaper_list</parameter> is a list of shapers to try.
+    </para>
+    <para>
+      Shape plans are objects in HarfBuzz, so there are
+      reference-counting functions and user-data attachment functions
+      you can
+      use. <function>hb_shape_plan_reference(shape_plan)</function>
+      increases the reference count on a shape plan, while
+      <function>hb_shape_plan_destroy(shape_plan)</function> decreases
+      the reference count, destroying the shape plan when the last
+      reference is dropped.
+    </para>
+    <para>
+      You can attach user data to a shaper (with a key) using the
+      <function>hb_shape_plan_set_user_data(shape_plan,key,data,destroy,replace)</function>
+      function, optionally supplying a <function>destroy</function>
+      callback to use. You can then fetch the user data attached to a
+      shape plan with
+      <function>hb_shape_plan_get_user_data(shape_plan, key)</function>.
     </para>
   </section>
+  
 </chapter>
diff --git a/docs/usermanual-utilities.xml b/docs/usermanual-utilities.xml
new file mode 100644 (file)
index 0000000..1c5370c
--- /dev/null
@@ -0,0 +1,244 @@
+<?xml version="1.0"?>
+<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.3//EN"
+               "http://www.oasis-open.org/docbook/xml/4.3/docbookx.dtd" [
+  <!ENTITY % local.common.attrib "xmlns:xi  CDATA  #FIXED 'http://www.w3.org/2003/XInclude'">
+  <!ENTITY version SYSTEM "version.xml">
+]>
+<chapter id="utilities">
+  <title>Utilities</title>
+  <para>
+    HarfBuzz includes several auxiliary components in addition to the
+    main APIs. These include a set of command-line tools, a set of
+    lower-level APIs for common data types that may be of interest to
+    client programs, and an embedded library for working with
+    Unicode Character Database (UCD) data.
+  </para>
+  
+  <section id="utilities-command-line-tools">
+    <title>Command-line tools</title>
+    <para>
+      HarfBuzz include three command-line tools:
+      <program>hb-shape</program>, <program>hb-view</program>, and
+      <program>hb-subset</program>. They can be used to examine
+      HarfBuzz's functionality, debug font binaries, or explore the
+      various shaping models and features from a terminal.
+    </para>
+    
+    <section id="utilities-command-line-hbshape">
+      <title>hb-shape</title>
+      <para>
+       <emphasis><program>hb-shape</program></emphasis> allows you to run HarfBuzz's
+       <function>hb_shape()</function> function on an input string and
+       to examine the outcome, in human-readable form, as terminal
+       output. <program>hb-shape</program> does
+       <emphasis>not</emphasis> render the results of the shaping call
+       into rendered text (you can use <program>hb-view</program>, below, for
+       that). Instead, it prints out the final glyph indices and
+       positions, taking all shaping operations into account, as if the
+       input string were a HarfBuzz input buffer.
+      </para>
+      <para>
+       You can specify the font to be used for shaping and, with
+       command-line options, you can add various aspects of the
+       internal state to the output that is sent to the terminal. The
+       general format is
+      </para>
+      <programlisting>
+       <command>hb-shape</command> <optional>[OPTIONS]</optional>
+      <parameter>path/to/font/file.ttf</parameter>
+      <parameter>yourinputtext</parameter>
+      </programlisting>
+      <para>
+       The default output format is plain text (although JSON output
+       can be selected instead by specifying the option
+       <optional>--output-format=json</optional>). The default output
+       syntax reports each glyph name (or glyph index if there is no
+       name) followed by its cluster value, its horizontal and vertical
+       position displacement, and its horizontal and vertical advances.
+      </para>
+      <para>
+       Output options exist to skip any of these elements in the
+       output, and to include additional data, such as Unicode
+       code-point values, glyph extents, glyph flags, or interim
+       shaping results.
+      </para>
+      <para>
+       Output can also be redirected to a file, or input read from a
+       file. Additional options enable you to enable or disable
+       specific font features, to set variation-font axis values, to
+       alter the language, script, direction, and clustering settings
+       used, to enable sanity checks, or to change which shaping engine is used.
+      </para>
+      <para>
+       For a complete explanation of the options available, run
+      </para>
+      <programlisting>
+       <command>hb-shape</command> <parameter>--help</parameter>
+      </programlisting>  
+    </section>
+    
+    <section id="utilities-command-line-hbview">
+      <title>hb-view</title>
+      <para>
+       <emphasis><program>hb-view</program></emphasis> allows you to
+       see the shaped output of an input string in rendered
+       form. Like <program>hb-shape</program>,
+       <program>hb-view</program> takes a font file and a text string
+       as its arguments:
+      </para>
+      <programlisting>
+       <command>hb-view</command> <optional>[OPTIONS]</optional>
+       <parameter>path/to/font/file.ttf</parameter>
+       <parameter>yourinputtext</parameter>
+      </programlisting>
+      <para>
+       By default, <program>hb-view</program> renders the shaped
+       text in ASCII block-character images as terminal output. By
+       appending the
+       <command>--output-file=<optional>filename</optional></command>
+       switch, you can write the output to a PNG, SVG, or PDF file
+       (among other formats).
+      </para>
+      <para>
+       As with <program>hb-shape</program>, a lengthy set of options
+       is available, with which you can  enable or disable
+       specific font features, set variation-font axis values,
+       alter the language, script, direction, and clustering settings
+       used, enable sanity checks, or change which shaping engine is
+       used.
+      </para>
+      <para>
+       You can also set the foreground and background colors used for
+       the output, independently control the width of all four
+       margins, alter the line spacing, and annotate the output image
+       with 
+      </para>
+      <para>
+       In general, <program>hb-view</program> is a quick way to
+       verify that the output of HarfBuzz's shaping operation looks
+       correct for a given text-and-font combination, but you may
+       want to use <program>hb-shape</program> to figure out exactly
+       why something does not appear as expected.
+      </para>
+    </section>
+    
+    <section id="utilities-command-line-hbsubset">
+      <title>hb-subset</title>
+      <para>
+       <emphasis><program>hb-subset</program></emphasis> allows you
+       to generate a subset of a given font, with a limited set of
+       supported characters, features, and variation settings.
+      </para>
+      <para>
+       By default, you provide an input font and an input text string
+       as the arguments to <program>hb-subset</program>, and it will
+       generate a font that covers the input text exactly like the
+       input font does, but includes no other characters or features.
+      </para>
+      <programlisting>
+       <command>hb-subset</command> <optional>[OPTIONS]</optional>
+       <parameter>path/to/font/file.ttf</parameter>
+       <parameter>yourinputtext</parameter>
+      </programlisting>
+      <para>
+       For example, to create a subset of Noto Serif that just includes the
+       numerals and the lowercase Latin alphabet, you could run
+      </para>
+      <programlisting>
+       <command>hb-subset</command> <optional>[OPTIONS]</optional>
+       <parameter>NotoSerif-Regular.ttf</parameter>
+       <parameter>0123456789abcdefghijklmnopqrstuvwxyz</parameter>
+      </programlisting>
+      <para>
+       There are options available to remove hinting from the
+       subsetted font and to specify a list of variation-axis settings.
+      </para>
+    </section>
+    
+  </section>
+  
+  <section id="utilities-common-types-apis">
+    <title>Common data types and APIs</title>
+    <para>
+      HarfBuzz includes several APIs for working with general-purpose
+      data that you may find convenient to leverage in your own
+      software. They include set operations and integer-to-integer
+      mapping operations.
+    </para>
+    <para>
+      HarfBuzz uses set operations for internal bookkeeping, such as
+      when it collects all of the glyph IDs covered by a particular
+      font feature. You can also use the set API to build sets, add
+      and remove elements, test whether or not sets contain particular
+      elements, or compute the unions, intersections, or differences
+      between sets.
+    </para>
+    <para>
+      All set elements are integers (specifically,
+      <type>hb_codepoint_t</type> 32-bit unsigned ints), and there are
+      functions for fetching the minimum and maximum element from a
+      set. The set API also includes some functions that might not 
+      be part of a generic set facility, such as the ability to add a
+      contiguous range of integer elements to a set in bulk, and the
+      ability to fetch the next-smallest or next-largest element.
+    </para>
+    <para>
+      The HarfBuzz set API includes some conveniences as well. All
+      sets are lifecycle-managed, just like other HarfBuzz
+      objects. You increase the reference count on a set with
+      <function>hb_set_reference()</function> and decrease it with
+      <function>hb_set_destroy()</function>. You can also attach
+      user data to a set, just like you can to blobs, buffers, faces,
+      fonts, and other objects, and set destroy callbacks.
+    </para>
+    <para>
+      HarfBuzz also provides an API for keeping track of
+      integer-to-integer mappings. As with the set API, each integer is
+      stored as an unsigned 32-bit <type>hb_codepoint_t</type>
+      element. Maps, like other objects, are reference counted with
+      reference and destroy functions, and you can attach user data to
+      them. The mapping operations include adding and deleting
+      integer-to-integer key:value pairs to the map, testing for the
+      presence of a key, fetching the population of the map, and so on.
+    </para>
+    <para>
+      There are several other internal HarfBuzz facilities that are
+      exposed publicly and which you may want to take advantage of
+      while processing text. HarfBuzz uses a common
+      <type>hb_tag_t</type> for a variety of OpenType tag identifiers (for
+      scripts, languages, font features, table names, variation-axis
+      names, and more), and provides functions for converting strings
+      to tags and vice-versa. 
+    </para>
+    <para>
+      Finally, HarfBuzz also includes data type for Booleans, bit
+      masks, and other simple types.
+    </para>
+  </section>
+
+  <section id="utilities-ucdn">
+    <title>UCDN</title>
+    <para>
+      HarfBuzz includes a copy of the <ulink
+      url="https://github.com/grigorig/ucdn">UCDN</ulink> (Unicode
+      Database and Normalization) library, which provides functions
+      for accessing basic Unicode character properties, performing
+      canonical composition, and performing both canonical and
+      compatibility decomposition.
+    </para>
+    <para>
+      Currently, UCDN supports direct queries for several more character
+      properties than HarfBuzz's built-in set of Unicode functions
+      does, such as the BiDirectional Class, East Asian Width, Paired
+      Bracket and Resolved Linebreak properties. If you need to access
+      more properties than HarfBuzz's internal implementation
+      provides, using the built-in UCDN functions may be a useful solution.
+    </para>
+    <para>
+      The built-in UCDN functions are compiled by default when
+      building HarfBuzz from source, but this can be disabled with a
+      compile-time switch.
+    </para>
+  </section>
+
+</chapter>
index ed053f9..3513fb2 100644 (file)
         </para>
        <para>
          For example, in Tamil, when the letter &quot;TTA&quot; (ட)
-         letter is followed by &quot;U&quot; (உ), the pair
+         letter is followed by the vowel sign &quot;U&quot; (ு), the pair
          must be replaced by the single glyph &quot;டு&quot;. The
-         sequence of Unicode characters &quot;ட&quot; needs to be
+         sequence of Unicode characters &quot;ட,ு&quot; needs to be
          substituted with a single &quot;டு&quot; glyph from the
          font.
        </para>
index 197c4d5..2714f53 100644 (file)
@@ -1 +1 @@
-2.4.0
+2.6.4
index d3ab94d..7f3523d 100644 (file)
--- a/ltmain.sh
+++ b/ltmain.sh
@@ -1,12 +1,12 @@
 #! /bin/sh
 ## DO NOT EDIT - This file generated from ./build-aux/ltmain.in
-##               by inline-source v2018-07-24.06
+##               by inline-source v2014-01-03.01
 
-# libtool (GNU libtool) 2.4.6.42-b88ce
+# libtool (GNU libtool) 2.4.6
 # Provide generalized library-building support services.
 # Written by Gordon Matzigkeit <gord@gnu.ai.mit.edu>, 1996
 
-# Copyright (C) 1996-2018 Free Software Foundation, Inc.
+# Copyright (C) 1996-2015 Free Software Foundation, Inc.
 # This is free software; see the source for copying conditions.  There is NO
 # warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 
@@ -31,8 +31,8 @@
 
 PROGRAM=libtool
 PACKAGE=libtool
-VERSION=2.4.6.42-b88ce
-package_revision=2.4.6.42
+VERSION=2.4.6
+package_revision=2.4.6
 
 
 ## ------ ##
@@ -64,25 +64,34 @@ package_revision=2.4.6.42
 # libraries, which are installed to $pkgauxdir.
 
 # Set a version string for this script.
-scriptversion=2018-07-24.06; # UTC
+scriptversion=2015-01-20.17; # UTC
 
 # General shell script boiler plate, and helper functions.
 # Written by Gary V. Vaughan, 2004
 
-# This is free software.  There is NO warranty; not even for
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-#
-# Copyright (C) 2004-2018 Bootstrap Authors
-#
-# This file is dual licensed under the terms of the MIT license
-# <https://opensource.org/license/MIT>, and GPL version 3 or later
-# <http://www.gnu.org/licenses/gpl-2.0.html>.  You must apply one of
-# these licenses when using or redistributing this software or any of
-# the files within it.  See the URLs above, or the file `LICENSE`
-# included in the Bootstrap distribution for the full license texts.
+# Copyright (C) 2004-2015 Free Software Foundation, Inc.
+# This is free software; see the source for copying conditions.  There is NO
+# warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+
+# As a special exception to the GNU General Public License, if you distribute
+# this file as part of a program or library that is built using GNU Libtool,
+# you may include this file under the same distribution terms that you use
+# for the rest of that program.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNES FOR A PARTICULAR PURPOSE. See the GNU
+# General Public License for more details.
 
-# Please report bugs or propose patches to:
-# <https://github.com/gnulib-modules/bootstrap/issues>
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+# Please report bugs or propose patches to gary@gnu.org.
 
 
 ## ------ ##
@@ -131,6 +140,9 @@ do
        fi"
 done
 
+# CDPATH.
+(unset CDPATH) >/dev/null 2>&1 && unset CDPATH
+
 # Make sure IFS has a sensible default
 sp=' '
 nl='
@@ -147,26 +159,6 @@ if test "${PATH_SEPARATOR+set}" != set; then
 fi
 
 
-# func_unset VAR
-# --------------
-# Portably unset VAR.
-# In some shells, an 'unset VAR' statement leaves a non-zero return
-# status if VAR is already unset, which might be problematic if the
-# statement is used at the end of a function (thus poisoning its return
-# value) or when 'set -e' is active (causing even a spurious abort of
-# the script in this case).
-func_unset ()
-{
-    { eval $1=; (eval unset $1) >/dev/null 2>&1 && eval unset $1 || : ; }
-}
-
-
-# Make sure CDPATH doesn't cause `cd` commands to output the target dir.
-func_unset CDPATH
-
-# Make sure ${,E,F}GREP behave sanely.
-func_unset GREP_OPTIONS
-
 
 ## ------------------------- ##
 ## Locate command utilities. ##
@@ -267,7 +259,7 @@ test -z "$SED" && {
     rm -f conftest.in conftest.tmp conftest.nl conftest.out
   }
 
-  func_path_progs "sed gsed" func_check_prog_sed "$PATH:/usr/xpg4/bin"
+  func_path_progs "sed gsed" func_check_prog_sed $PATH:/usr/xpg4/bin
   rm -f conftest.sed
   SED=$func_path_progs_result
 }
@@ -303,7 +295,7 @@ test -z "$GREP" && {
     rm -f conftest.in conftest.tmp conftest.nl conftest.out
   }
 
-  func_path_progs "grep ggrep" func_check_prog_grep "$PATH:/usr/xpg4/bin"
+  func_path_progs "grep ggrep" func_check_prog_grep $PATH:/usr/xpg4/bin
   GREP=$func_path_progs_result
 }
 
@@ -588,16 +580,16 @@ if test yes = "$_G_HAVE_PLUSEQ_OP"; then
   {
     $debug_cmd
 
-    func_quote_arg pretty "$2"
-    eval "$1+=\\ \$func_quote_arg_result"
+    func_quote_for_eval "$2"
+    eval "$1+=\\ \$func_quote_for_eval_result"
   }'
 else
   func_append_quoted ()
   {
     $debug_cmd
 
-    func_quote_arg pretty "$2"
-    eval "$1=\$$1\\ \$func_quote_arg_result"
+    func_quote_for_eval "$2"
+    eval "$1=\$$1\\ \$func_quote_for_eval_result"
   }
 fi
 
@@ -1099,199 +1091,85 @@ func_relative_path ()
 }
 
 
-# func_quote_portable EVAL ARG
-# ----------------------------
-# Internal function to portably implement func_quote_arg.  Note that we still
-# keep attention to performance here so we as much as possible try to avoid
-# calling sed binary (so far O(N) complexity as long as func_append is O(1)).
-func_quote_portable ()
+# func_quote_for_eval ARG...
+# --------------------------
+# Aesthetically quote ARGs to be evaled later.
+# This function returns two values:
+#   i) func_quote_for_eval_result
+#      double-quoted, suitable for a subsequent eval
+#  ii) func_quote_for_eval_unquoted_result
+#      has all characters that are still active within double
+#      quotes backslashified.
+func_quote_for_eval ()
 {
     $debug_cmd
 
-    func_quote_portable_result=$2
-
-    # one-time-loop (easy break)
-    while true
-    do
-      if $1; then
-        func_quote_portable_result=`$ECHO "$2" | $SED \
-          -e "$sed_double_quote_subst" -e "$sed_double_backslash"`
-        break
-      fi
-
-      # Quote for eval.
-      case $func_quote_portable_result in
+    func_quote_for_eval_unquoted_result=
+    func_quote_for_eval_result=
+    while test 0 -lt $#; do
+      case $1 in
         *[\\\`\"\$]*)
-          case $func_quote_portable_result in
-            *[\[\*\?]*)
-              func_quote_portable_result=`$ECHO "$func_quote_portable_result" \
-                  | $SED "$sed_quote_subst"`
-              break
-              ;;
-          esac
+         _G_unquoted_arg=`printf '%s\n' "$1" |$SED "$sed_quote_subst"` ;;
+        *)
+          _G_unquoted_arg=$1 ;;
+      esac
+      if test -n "$func_quote_for_eval_unquoted_result"; then
+       func_append func_quote_for_eval_unquoted_result " $_G_unquoted_arg"
+      else
+        func_append func_quote_for_eval_unquoted_result "$_G_unquoted_arg"
+      fi
 
-          func_quote_portable_old_IFS=$IFS
-          for _G_char in '\' '`' '"' '$'
-          do
-            # STATE($1) PREV($2) SEPARATOR($3)
-            set start "" ""
-            func_quote_portable_result=dummy"$_G_char$func_quote_portable_result$_G_char"dummy
-            IFS=$_G_char
-            for _G_part in $func_quote_portable_result
-            do
-              case $1 in
-              quote)
-                func_append func_quote_portable_result "$3$2"
-                set quote "$_G_part" "\\$_G_char"
-                ;;
-              start)
-                set first "" ""
-                func_quote_portable_result=
-                ;;
-              first)
-                set quote "$_G_part" ""
-                ;;
-              esac
-            done
-          done
-          IFS=$func_quote_portable_old_IFS
+      case $_G_unquoted_arg in
+        # Double-quote args containing shell metacharacters to delay
+        # word splitting, command substitution and variable expansion
+        # for a subsequent eval.
+        # Many Bourne shells cannot handle close brackets correctly
+        # in scan sets, so we specify it separately.
+        *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \  ]*|*]*|"")
+          _G_quoted_arg=\"$_G_unquoted_arg\"
           ;;
-        *) ;;
+        *)
+          _G_quoted_arg=$_G_unquoted_arg
+         ;;
       esac
-      break
-    done
 
-    func_quote_portable_unquoted_result=$func_quote_portable_result
-    case $func_quote_portable_result in
-      # double-quote args containing shell metacharacters to delay
-      # word splitting, command substitution and variable expansion
-      # for a subsequent eval.
-      # many bourne shells cannot handle close brackets correctly
-      # in scan sets, so we specify it separately.
-      *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \    ]*|*]*|"")
-        func_quote_portable_result=\"$func_quote_portable_result\"
-        ;;
-    esac
+      if test -n "$func_quote_for_eval_result"; then
+       func_append func_quote_for_eval_result " $_G_quoted_arg"
+      else
+        func_append func_quote_for_eval_result "$_G_quoted_arg"
+      fi
+      shift
+    done
 }
 
 
-# func_quotefast_eval ARG
-# -----------------------
-# Quote one ARG (internal).  This is equivalent to 'func_quote_arg eval ARG',
-# but optimized for speed.  Result is stored in $func_quotefast_eval.
-if test xyes = `(x=; printf -v x %q yes; echo x"$x") 2>/dev/null`; then
-  printf -v _GL_test_printf_tilde %q '~'
-  if test '\~' = "$_GL_test_printf_tilde"; then
-    func_quotefast_eval ()
-    {
-      printf -v func_quotefast_eval_result %q "$1"
-    }
-  else
-    # Broken older Bash implementations.  Make those faster too if possible.
-    func_quotefast_eval ()
-    {
-      case $1 in
-        '~'*)
-          func_quote_portable false "$1"
-          func_quotefast_eval_result=$func_quote_portable_result
-          ;;
-        *)
-          printf -v func_quotefast_eval_result %q "$1"
-          ;;
-      esac
-    }
-  fi
-else
-  func_quotefast_eval ()
-  {
-    func_quote_portable false "$1"
-    func_quotefast_eval_result=$func_quote_portable_result
-  }
-fi
-
+# func_quote_for_expand ARG
+# -------------------------
+# Aesthetically quote ARG to be evaled later; same as above,
+# but do not quote variable references.
+func_quote_for_expand ()
+{
+    $debug_cmd
 
-# func_quote_arg MODEs ARG
-# ------------------------
-# Quote one ARG to be evaled later.  MODEs argument may contain zero or more
-# specifiers listed below separated by ',' character.  This function returns two
-# values:
-#   i) func_quote_arg_result
-#      double-quoted (when needed), suitable for a subsequent eval
-#  ii) func_quote_arg_unquoted_result
-#      has all characters that are still active within double
-#      quotes backslashified.  Available only if 'unquoted' is specified.
-#
-# Available modes:
-# ----------------
-# 'eval' (default)
-#       - escape shell special characters
-# 'expand'
-#       - the same as 'eval';  but do not quote variable references
-# 'pretty'
-#       - request aesthetic output, i.e. '"a b"' instead of 'a\ b'.  This might
-#         be used later in func_quote to get output like: 'echo "a b"' instead
-#         of 'echo a\ b'.  This is slower than default on some shells.
-# 'unquoted'
-#       - produce also $func_quote_arg_unquoted_result which does not contain
-#         wrapping double-quotes.
-#
-# Examples for 'func_quote_arg pretty,unquoted string':
-#
-#   string      | *_result              | *_unquoted_result
-#   ------------+-----------------------+-------------------
-#   "           | \"                    | \"
-#   a b         | "a b"                 | a b
-#   "a b"       | "\"a b\""             | \"a b\"
-#   *           | "*"                   | *
-#   z="${x-$y}" | "z=\"\${x-\$y}\""     | z=\"\${x-\$y}\"
-#
-# Examples for 'func_quote_arg pretty,unquoted,expand string':
-#
-#   string        |   *_result          |  *_unquoted_result
-#   --------------+---------------------+--------------------
-#   z="${x-$y}"   | "z=\"${x-$y}\""     | z=\"${x-$y}\"
-func_quote_arg ()
-{
-    _G_quote_expand=false
-    case ,$1, in
-      *,expand,*)
-        _G_quote_expand=:
-        ;;
+    case $1 in
+      *[\\\`\"]*)
+       _G_arg=`$ECHO "$1" | $SED \
+           -e "$sed_double_quote_subst" -e "$sed_double_backslash"` ;;
+      *)
+        _G_arg=$1 ;;
     esac
 
-    case ,$1, in
-      *,pretty,*|*,expand,*|*,unquoted,*)
-        func_quote_portable $_G_quote_expand "$2"
-        func_quote_arg_result=$func_quote_portable_result
-        func_quote_arg_unquoted_result=$func_quote_portable_unquoted_result
-        ;;
-      *)
-        # Faster quote-for-eval for some shells.
-        func_quotefast_eval "$2"
-        func_quote_arg_result=$func_quotefast_eval_result
+    case $_G_arg in
+      # Double-quote args containing shell metacharacters to delay
+      # word splitting and command substitution for a subsequent eval.
+      # Many Bourne shells cannot handle close brackets correctly
+      # in scan sets, so we specify it separately.
+      *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \    ]*|*]*|"")
+        _G_arg=\"$_G_arg\"
         ;;
     esac
-}
 
-
-# func_quote MODEs ARGs...
-# ------------------------
-# Quote all ARGs to be evaled later and join them into single command.  See
-# func_quote_arg's description for more info.
-func_quote ()
-{
-    $debug_cmd
-    _G_func_quote_mode=$1 ; shift
-    func_quote_result=
-    while test 0 -lt $#; do
-      func_quote_arg "$_G_func_quote_mode" "$1"
-      if test -n "$func_quote_result"; then
-        func_append func_quote_result " $func_quote_arg_result"
-      else
-        func_append func_quote_result "$func_quote_arg_result"
-      fi
-      shift
-    done
+    func_quote_for_expand_result=$_G_arg
 }
 
 
@@ -1337,8 +1215,8 @@ func_show_eval ()
     _G_cmd=$1
     _G_fail_exp=${2-':'}
 
-    func_quote_arg pretty,expand "$_G_cmd"
-    eval "func_notquiet $func_quote_arg_result"
+    func_quote_for_expand "$_G_cmd"
+    eval "func_notquiet $func_quote_for_expand_result"
 
     $opt_dry_run || {
       eval "$_G_cmd"
@@ -1363,8 +1241,8 @@ func_show_eval_locale ()
     _G_fail_exp=${2-':'}
 
     $opt_quiet || {
-      func_quote_arg expand,pretty "$_G_cmd"
-      eval "func_echo $func_quote_arg_result"
+      func_quote_for_expand "$_G_cmd"
+      eval "func_echo $func_quote_for_expand_result"
     }
 
     $opt_dry_run || {
@@ -1491,26 +1369,30 @@ func_lt_ver ()
 # End:
 #! /bin/sh
 
+# Set a version string for this script.
+scriptversion=2014-01-07.03; # UTC
+
 # A portable, pluggable option parser for Bourne shell.
 # Written by Gary V. Vaughan, 2010
 
-# This is free software.  There is NO warranty; not even for
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-#
-# Copyright (C) 2010-2018 Bootstrap Authors
-#
-# This file is dual licensed under the terms of the MIT license
-# <https://opensource.org/license/MIT>, and GPL version 3 or later
-# <http://www.gnu.org/licenses/gpl-2.0.html>.  You must apply one of
-# these licenses when using or redistributing this software or any of
-# the files within it.  See the URLs above, or the file `LICENSE`
-# included in the Bootstrap distribution for the full license texts.
+# Copyright (C) 2010-2015 Free Software Foundation, Inc.
+# This is free software; see the source for copying conditions.  There is NO
+# warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 
-# Please report bugs or propose patches to:
-# <https://github.com/gnulib-modules/bootstrap/issues>
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
 
-# Set a version string for this script.
-scriptversion=2018-07-24.06; # UTC
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+# Please report bugs or propose patches to gary@gnu.org.
 
 
 ## ------ ##
@@ -1533,7 +1415,7 @@ scriptversion=2018-07-24.06; # UTC
 #
 # In order for the '--version' option to work, you will need to have a
 # suitably formatted comment like the one at the top of this file
-# starting with '# Written by ' and ending with '# Copyright'.
+# starting with '# Written by ' and ending with '# warranty; '.
 #
 # For '-h' and '--help' to work, you will also need a one line
 # description of your script's purpose in a comment directly above the
@@ -1545,7 +1427,7 @@ scriptversion=2018-07-24.06; # UTC
 # to display verbose messages only when your user has specified
 # '--verbose'.
 #
-# After sourcing this file, you can plug in processing for additional
+# After sourcing this file, you can plug processing for additional
 # options by amending the variables from the 'Configuration' section
 # below, and following the instructions in the 'Option parsing'
 # section further down.
@@ -1594,8 +1476,8 @@ fatal_help="Try '\$progname --help' for more information."
 ## ------------------------- ##
 
 # This section contains functions for adding, removing, and running hooks
-# in the main code.  A hook is just a list of function names that can be
-# run in order later on.
+# to the main code.  A hook is just a named list of of function, that can
+# be run in order later on.
 
 # func_hookable FUNC_NAME
 # -----------------------
@@ -1628,8 +1510,7 @@ func_add_hook ()
 
 # func_remove_hook FUNC_NAME HOOK_FUNC
 # ------------------------------------
-# Remove HOOK_FUNC from the list of hook functions to be called by
-# FUNC_NAME.
+# Remove HOOK_FUNC from the list of functions called by FUNC_NAME.
 func_remove_hook ()
 {
     $debug_cmd
@@ -1638,28 +1519,10 @@ func_remove_hook ()
 }
 
 
-# func_propagate_result FUNC_NAME_A FUNC_NAME_B
-# ---------------------------------------------
-# If the *_result variable of FUNC_NAME_A _is set_, assign its value to
-# *_result variable of FUNC_NAME_B.
-func_propagate_result ()
-{
-    $debug_cmd
-
-    func_propagate_result_result=:
-    if eval "test \"\${${1}_result+set}\" = set"
-    then
-      eval "${2}_result=\$${1}_result"
-    else
-      func_propagate_result_result=false
-    fi
-}
-
-
 # func_run_hooks FUNC_NAME [ARG]...
 # ---------------------------------
 # Run all hook functions registered to FUNC_NAME.
-# It's assumed that the list of hook functions contains nothing more
+# It is assumed that the list of hook functions contains nothing more
 # than a whitespace-delimited list of legal shell function names, and
 # no effort is wasted trying to catch shell meta-characters or preserve
 # whitespace.
@@ -1669,19 +1532,22 @@ func_run_hooks ()
 
     case " $hookable_fns " in
       *" $1 "*) ;;
-      *) func_fatal_error "'$1' does not support hook functions." ;;
+      *) func_fatal_error "'$1' does not support hook funcions.n" ;;
     esac
 
     eval _G_hook_fns=\$$1_hooks; shift
 
     for _G_hook in $_G_hook_fns; do
-      func_unset "${_G_hook}_result"
-      eval $_G_hook '${1+"$@"}'
-      func_propagate_result $_G_hook func_run_hooks
-      if $func_propagate_result_result; then
-        eval set dummy "$func_run_hooks_result"; shift
-      fi
+      eval $_G_hook '"$@"'
+
+      # store returned options list back into positional
+      # parameters for next 'cmd' execution.
+      eval _G_hook_result=\$${_G_hook}_result
+      eval set dummy "$_G_hook_result"; shift
     done
+
+    func_quote_for_eval ${1+"$@"}
+    func_run_hooks_result=$func_quote_for_eval_result
 }
 
 
@@ -1691,18 +1557,10 @@ func_run_hooks ()
 ## --------------- ##
 
 # In order to add your own option parsing hooks, you must accept the
-# full positional parameter list from your hook function.  You may remove
-# or edit any options that you action, and then pass back the remaining
-# unprocessed options in '<hooked_function_name>_result', escaped
-# suitably for 'eval'.
-#
-# The '<hooked_function_name>_result' variable is automatically unset
-# before your hook gets called; for best performance, only set the
-# *_result variable when necessary (i.e. don't call the 'func_quote'
-# function unnecessarily because it can be an expensive operation on some
-# machines).
-#
-# Like this:
+# full positional parameter list in your hook function, remove any
+# options that you action, and then pass back the remaining unprocessed
+# options in '<hooked_function_name>_result', escaped suitably for
+# 'eval'.  Like this:
 #
 #    my_options_prep ()
 #    {
@@ -1712,8 +1570,9 @@ func_run_hooks ()
 #        usage_message=$usage_message'
 #      -s, --silent       don'\''t print informational messages
 #    '
-#        # No change in '$@' (ignored completely by this hook).  Leave
-#        # my_options_prep_result variable intact.
+#
+#        func_quote_for_eval ${1+"$@"}
+#        my_options_prep_result=$func_quote_for_eval_result
 #    }
 #    func_add_hook func_options_prep my_options_prep
 #
@@ -1722,36 +1581,25 @@ func_run_hooks ()
 #    {
 #        $debug_cmd
 #
-#        args_changed=false
-#
-#        # Note that, for efficiency, we parse as many options as we can
+#        # Note that for efficiency, we parse as many options as we can
 #        # recognise in a loop before passing the remainder back to the
 #        # caller on the first unrecognised argument we encounter.
 #        while test $# -gt 0; do
 #          opt=$1; shift
 #          case $opt in
-#            --silent|-s) opt_silent=:
-#                         args_changed=:
-#                         ;;
+#            --silent|-s) opt_silent=: ;;
 #            # Separate non-argument short options:
 #            -s*)         func_split_short_opt "$_G_opt"
 #                         set dummy "$func_split_short_opt_name" \
 #                             "-$func_split_short_opt_arg" ${1+"$@"}
 #                         shift
-#                         args_changed=:
 #                         ;;
-#            *)           # Make sure the first unrecognised option "$_G_opt"
-#                         # is added back to "$@" in case we need it later,
-#                         # if $args_changed was set to 'true'.
-#                         set dummy "$_G_opt" ${1+"$@"}; shift; break ;;
+#            *)            set dummy "$_G_opt" "$*"; shift; break ;;
 #          esac
 #        done
 #
-#        # Only call 'func_quote' here if we processed at least one argument.
-#        if $args_changed; then
-#          func_quote eval ${1+"$@"}
-#          my_silent_option_result=$func_quote_result
-#        fi
+#        func_quote_for_eval ${1+"$@"}
+#        my_silent_option_result=$func_quote_for_eval_result
 #    }
 #    func_add_hook func_parse_options my_silent_option
 #
@@ -1762,26 +1610,17 @@ func_run_hooks ()
 #
 #        $opt_silent && $opt_verbose && func_fatal_help "\
 #    '--silent' and '--verbose' options are mutually exclusive."
+#
+#        func_quote_for_eval ${1+"$@"}
+#        my_option_validation_result=$func_quote_for_eval_result
 #    }
 #    func_add_hook func_validate_options my_option_validation
 #
-# You'll also need to manually amend $usage_message to reflect the extra
+# You'll alse need to manually amend $usage_message to reflect the extra
 # options you parse.  It's preferable to append if you can, so that
 # multiple option parsing hooks can be added safely.
 
 
-# func_options_finish [ARG]...
-# ----------------------------
-# Finishing the option parse loop (call 'func_options' hooks ATM).
-func_options_finish ()
-{
-    $debug_cmd
-
-    func_run_hooks func_options ${1+"$@"}
-    func_propagate_result func_run_hooks func_options_finish
-}
-
-
 # func_options [ARG]...
 # ---------------------
 # All the functions called inside func_options are hookable. See the
@@ -1791,27 +1630,17 @@ func_options ()
 {
     $debug_cmd
 
-    _G_options_quoted=false
+    func_options_prep ${1+"$@"}
+    eval func_parse_options \
+        ${func_options_prep_result+"$func_options_prep_result"}
+    eval func_validate_options \
+        ${func_parse_options_result+"$func_parse_options_result"}
 
-    for my_func in options_prep parse_options validate_options options_finish
-    do
-      func_unset func_${my_func}_result
-      func_unset func_run_hooks_result
-      eval func_$my_func '${1+"$@"}'
-      func_propagate_result func_$my_func func_options
-      if $func_propagate_result_result; then
-        eval set dummy "$func_options_result"; shift
-        _G_options_quoted=:
-      fi
-    done
+    eval func_run_hooks func_options \
+        ${func_validate_options_result+"$func_validate_options_result"}
 
-    $_G_options_quoted || {
-      # As we (func_options) are top-level options-parser function and
-      # nobody quoted "$@" for us yet, we need to do it explicitly for
-      # caller.
-      func_quote eval ${1+"$@"}
-      func_options_result=$func_quote_result
-    }
+    # save modified positional parameters for caller
+    func_options_result=$func_run_hooks_result
 }
 
 
@@ -1820,8 +1649,9 @@ func_options ()
 # All initialisations required before starting the option parse loop.
 # Note that when calling hook functions, we pass through the list of
 # positional parameters.  If a hook function modifies that list, and
-# needs to propagate that back to rest of this script, then the complete
-# modified list must be put in 'func_run_hooks_result' before returning.
+# needs to propogate that back to rest of this script, then the complete
+# modified list must be put in 'func_run_hooks_result' before
+# returning.
 func_hookable func_options_prep
 func_options_prep ()
 {
@@ -1832,7 +1662,9 @@ func_options_prep ()
     opt_warning_types=
 
     func_run_hooks func_options_prep ${1+"$@"}
-    func_propagate_result func_run_hooks func_options_prep
+
+    # save modified positional parameters for caller
+    func_options_prep_result=$func_run_hooks_result
 }
 
 
@@ -1844,32 +1676,25 @@ func_parse_options ()
 {
     $debug_cmd
 
-    _G_parse_options_requote=false
+    func_parse_options_result=
+
     # this just eases exit handling
     while test $# -gt 0; do
       # Defer to hook functions for initial option parsing, so they
       # get priority in the event of reusing an option name.
       func_run_hooks func_parse_options ${1+"$@"}
-      func_propagate_result func_run_hooks func_parse_options
-      if $func_propagate_result_result; then
-        eval set dummy "$func_parse_options_result"; shift
-        # Even though we may have changed "$@", we passed the "$@" array
-        # down into the hook and it quoted it for us (because we are in
-        # this if-branch).  No need to quote it again.
-        _G_parse_options_requote=false
-      fi
+
+      # Adjust func_parse_options positional parameters to match
+      eval set dummy "$func_run_hooks_result"; shift
 
       # Break out of the loop if we already parsed every option.
       test $# -gt 0 || break
 
-      # We expect that one of the options parsed in this function matches
-      # and thus we remove _G_opt from "$@" and need to re-quote.
-      _G_match_parse_options=:
       _G_opt=$1
       shift
       case $_G_opt in
         --debug|-x)   debug_cmd='set -x'
-                      func_echo "enabling shell trace mode" >&2
+                      func_echo "enabling shell trace mode"
                       $debug_cmd
                       ;;
 
@@ -1879,10 +1704,7 @@ func_parse_options ()
                      ;;
 
         --warnings|--warning|-W)
-                      if test $# = 0 && func_missing_arg $_G_opt; then
-                        _G_parse_options_requote=:
-                        break
-                      fi
+                      test $# = 0 && func_missing_arg $_G_opt && break
                       case " $warning_categories $1" in
                         *" $1 "*)
                           # trailing space prevents matching last $1 above
@@ -1935,24 +1757,15 @@ func_parse_options ()
                       shift
                       ;;
 
-        --)           _G_parse_options_requote=: ; break ;;
+        --)           break ;;
         -*)           func_fatal_help "unrecognised option: '$_G_opt'" ;;
-        *)            set dummy "$_G_opt" ${1+"$@"}; shift
-                      _G_match_parse_options=false
-                      break
-                      ;;
+        *)            set dummy "$_G_opt" ${1+"$@"}; shift; break ;;
       esac
-
-      if $_G_match_parse_options; then
-        _G_parse_options_requote=:
-      fi
     done
 
-    if $_G_parse_options_requote; then
-      # save modified positional parameters for caller
-      func_quote eval ${1+"$@"}
-      func_parse_options_result=$func_quote_result
-    fi
+    # save modified positional parameters for caller
+    func_quote_for_eval ${1+"$@"}
+    func_parse_options_result=$func_quote_for_eval_result
 }
 
 
@@ -1969,10 +1782,12 @@ func_validate_options ()
     test -n "$opt_warning_types" || opt_warning_types=" $warning_categories"
 
     func_run_hooks func_validate_options ${1+"$@"}
-    func_propagate_result func_run_hooks func_validate_options
 
     # Bail if the options were screwed!
     $exit_cmd $EXIT_FAILURE
+
+    # save modified positional parameters for caller
+    func_validate_options_result=$func_run_hooks_result
 }
 
 
@@ -2028,8 +1843,8 @@ func_missing_arg ()
 
 # func_split_equals STRING
 # ------------------------
-# Set func_split_equals_lhs and func_split_equals_rhs shell variables
-# after splitting STRING at the '=' sign.
+# Set func_split_equals_lhs and func_split_equals_rhs shell variables after
+# splitting STRING at the '=' sign.
 test -z "$_G_HAVE_XSI_OPS" \
     && (eval 'x=a/b/c;
       test 5aa/bb/cc = "${#x}${x%%/*}${x%/*}${x#*/}${x##*/}"') 2>/dev/null \
@@ -2044,9 +1859,8 @@ then
 
       func_split_equals_lhs=${1%%=*}
       func_split_equals_rhs=${1#*=}
-      if test "x$func_split_equals_lhs" = "x$1"; then
-        func_split_equals_rhs=
-      fi
+      test "x$func_split_equals_lhs" = "x$1" \
+        && func_split_equals_rhs=
   }'
 else
   # ...otherwise fall back to using expr, which is often a shell builtin.
@@ -2124,44 +1938,31 @@ func_usage_message ()
 # func_version
 # ------------
 # Echo version message to standard output and exit.
-# The version message is extracted from the calling file's header
-# comments, with leading '# ' stripped:
-#   1. First display the progname and version
-#   2. Followed by the header comment line matching  /^# Written by /
-#   3. Then a blank line followed by the first following line matching
-#      /^# Copyright /
-#   4. Immediately followed by any lines between the previous matches,
-#      except lines preceding the intervening completely blank line.
-# For example, see the header comments of this file.
 func_version ()
 {
     $debug_cmd
 
     printf '%s\n' "$progname $scriptversion"
     $SED -n '
-        /^# Written by /!b
-        s|^# ||; p; n
-
-        :fwd2blnk
-        /./ {
-          n
-          b fwd2blnk
+        /(C)/!b go
+        :more
+        /\./!{
+          N
+          s|\n# | |
+          b more
         }
-        p; n
-
-        :holdwrnt
-        s|^# ||
-        s|^# *$||
-        /^Copyright /!{
-          /./H
-          n
-          b holdwrnt
+        :go
+        /^# Written by /,/# warranty; / {
+          s|^# ||
+          s|^# *$||
+          s|\((C)\)[ 0-9,-]*[ ,-]\([1-9][0-9]* \)|\1 \2|
+          p
         }
-
-        s|\((C)\)[ 0-9,-]*[ ,-]\([1-9][0-9]* \)|\1 \2|
-        G
-        s|\(\n\)\n*|\1|g
-        p; q' < "$progpath"
+        /^# Written by / {
+          s|^# ||
+          p
+        }
+        /^warranty; /q' < "$progpath"
 
     exit $?
 }
@@ -2171,12 +1972,12 @@ func_version ()
 # mode: shell-script
 # sh-indentation: 2
 # eval: (add-hook 'before-save-hook 'time-stamp)
-# time-stamp-pattern: "30/scriptversion=%:y-%02m-%02d.%02H; # UTC"
+# time-stamp-pattern: "10/scriptversion=%:y-%02m-%02d.%02H; # UTC"
 # time-stamp-time-zone: "UTC"
 # End:
 
 # Set a version string.
-scriptversion='(GNU libtool) 2.4.6.42-b88ce'
+scriptversion='(GNU libtool) 2.4.6'
 
 
 # func_echo ARG...
@@ -2267,12 +2068,12 @@ include the following information:
        compiler:       $LTCC
        compiler flags: $LTCFLAGS
        linker:         $LD (gnu? $with_gnu_ld)
-       version:        $progname (GNU libtool) 2.4.6.42-b88ce
+       version:        $progname (GNU libtool) 2.4.6
        automake:       `($AUTOMAKE --version) 2>/dev/null |$SED 1q`
        autoconf:       `($AUTOCONF --version) 2>/dev/null |$SED 1q`
 
 Report bugs to <bug-libtool@gnu.org>.
-GNU libtool home page: <http://www.gnu.org/s/libtool/>.
+GNU libtool home page: <http://www.gnu.org/software/libtool/>.
 General help using GNU software: <http://www.gnu.org/gethelp/>."
     exit 0
 }
@@ -2469,8 +2270,6 @@ libtool_options_prep ()
     nonopt=
     preserve_args=
 
-    _G_rc_lt_options_prep=:
-
     # Shorthand for --mode=foo, only valid as the first argument
     case $1 in
     clean|clea|cle|cl)
@@ -2494,16 +2293,11 @@ libtool_options_prep ()
     uninstall|uninstal|uninsta|uninst|unins|unin|uni|un|u)
       shift; set dummy --mode uninstall ${1+"$@"}; shift
       ;;
-    *)
-      _G_rc_lt_options_prep=false
-      ;;
     esac
 
-    if $_G_rc_lt_options_prep; then
-      # Pass back the list of options.
-      func_quote eval ${1+"$@"}
-      libtool_options_prep_result=$func_quote_result
-    fi
+    # Pass back the list of options.
+    func_quote_for_eval ${1+"$@"}
+    libtool_options_prep_result=$func_quote_for_eval_result
 }
 func_add_hook func_options_prep libtool_options_prep
 
@@ -2515,12 +2309,9 @@ libtool_parse_options ()
 {
     $debug_cmd
 
-    _G_rc_lt_parse_options=false
-
     # Perform our own loop to consume as many options as possible in
     # each iteration.
     while test $# -gt 0; do
-      _G_match_lt_parse_options=:
       _G_opt=$1
       shift
       case $_G_opt in
@@ -2595,20 +2386,15 @@ libtool_parse_options ()
                         func_append preserve_args " $_G_opt"
                         ;;
 
-        # An option not handled by this hook function:
-        *)              set dummy "$_G_opt" ${1+"$@"} ; shift
-                        _G_match_lt_parse_options=false
-                        break
-                        ;;
+       # An option not handled by this hook function:
+        *)             set dummy "$_G_opt" ${1+"$@"};  shift; break  ;;
       esac
-      $_G_match_lt_parse_options && _G_rc_lt_parse_options=:
     done
 
-    if $_G_rc_lt_parse_options; then
-      # save modified positional parameters for caller
-      func_quote eval ${1+"$@"}
-      libtool_parse_options_result=$func_quote_result
-    fi
+
+    # save modified positional parameters for caller
+    func_quote_for_eval ${1+"$@"}
+    libtool_parse_options_result=$func_quote_for_eval_result
 }
 func_add_hook func_parse_options libtool_parse_options
 
@@ -2665,8 +2451,8 @@ libtool_validate_options ()
     }
 
     # Pass back the unparsed argument list
-    func_quote eval ${1+"$@"}
-    libtool_validate_options_result=$func_quote_result
+    func_quote_for_eval ${1+"$@"}
+    libtool_validate_options_result=$func_quote_for_eval_result
 }
 func_add_hook func_validate_options libtool_validate_options
 
@@ -3632,8 +3418,8 @@ func_mode_compile ()
       esac
     done
 
-    func_quote_arg pretty "$libobj"
-    test "X$libobj" != "X$func_quote_arg_result" \
+    func_quote_for_eval "$libobj"
+    test "X$libobj" != "X$func_quote_for_eval_result" \
       && $ECHO "X$libobj" | $GREP '[]~#^*{};<>?"'"'"'   &()|`$[]' \
       && func_warning "libobj name '$libobj' may not contain shell special characters."
     func_dirname_and_basename "$obj" "/" ""
@@ -3706,8 +3492,8 @@ compiler."
 
     func_to_tool_file "$srcfile" func_convert_file_msys_to_w32
     srcfile=$func_to_tool_file_result
-    func_quote_arg pretty "$srcfile"
-    qsrcfile=$func_quote_arg_result
+    func_quote_for_eval "$srcfile"
+    qsrcfile=$func_quote_for_eval_result
 
     # Only build a PIC object if we are building libtool libraries.
     if test yes = "$build_libtool_libs"; then
@@ -4310,8 +4096,8 @@ func_mode_install ()
        case $nonopt in *shtool*) :;; *) false;; esac
     then
       # Aesthetically quote it.
-      func_quote_arg pretty "$nonopt"
-      install_prog="$func_quote_arg_result "
+      func_quote_for_eval "$nonopt"
+      install_prog="$func_quote_for_eval_result "
       arg=$1
       shift
     else
@@ -4321,8 +4107,8 @@ func_mode_install ()
 
     # The real first argument should be the name of the installation program.
     # Aesthetically quote it.
-    func_quote_arg pretty "$arg"
-    func_append install_prog "$func_quote_arg_result"
+    func_quote_for_eval "$arg"
+    func_append install_prog "$func_quote_for_eval_result"
     install_shared_prog=$install_prog
     case " $install_prog " in
       *[\\\ /]cp\ *) install_cp=: ;;
@@ -4379,12 +4165,12 @@ func_mode_install ()
       esac
 
       # Aesthetically quote the argument.
-      func_quote_arg pretty "$arg"
-      func_append install_prog " $func_quote_arg_result"
+      func_quote_for_eval "$arg"
+      func_append install_prog " $func_quote_for_eval_result"
       if test -n "$arg2"; then
-       func_quote_arg pretty "$arg2"
+       func_quote_for_eval "$arg2"
       fi
-      func_append install_shared_prog " $func_quote_arg_result"
+      func_append install_shared_prog " $func_quote_for_eval_result"
     done
 
     test -z "$install_prog" && \
@@ -4395,8 +4181,8 @@ func_mode_install ()
 
     if test -n "$install_override_mode" && $no_mode; then
       if $install_cp; then :; else
-       func_quote_arg pretty "$install_override_mode"
-       func_append install_shared_prog " -m $func_quote_arg_result"
+       func_quote_for_eval "$install_override_mode"
+       func_append install_shared_prog " -m $func_quote_for_eval_result"
       fi
     fi
 
@@ -4692,8 +4478,8 @@ func_mode_install ()
                relink_command=`$ECHO "$relink_command" | $SED 's%@OUTPUT@%'"$outputname"'%g'`
 
                $opt_quiet || {
-                 func_quote_arg expand,pretty "$relink_command"
-                 eval "func_echo $func_quote_arg_result"
+                 func_quote_for_expand "$relink_command"
+                 eval "func_echo $func_quote_for_expand_result"
                }
                if eval "$relink_command"; then :
                  else
@@ -5472,8 +5258,7 @@ else
   if test \"\$libtool_execute_magic\" != \"$magic\"; then
     file=\"\$0\""
 
-    func_quote_arg pretty "$ECHO"
-    qECHO=$func_quote_arg_result
+    qECHO=`$ECHO "$ECHO" | $SED "$sed_quote_subst"`
     $ECHO "\
 
 # A function that is used when there is no print builtin or printf.
@@ -5483,7 +5268,7 @@ func_fallback_echo ()
 \$1
 _LTECHO_EOF'
 }
-    ECHO=$qECHO
+    ECHO=\"$qECHO\"
   fi
 
 # Very basic option parsing. These options are (a) specific to
@@ -6826,9 +6611,9 @@ func_mode_link ()
     while test "$#" -gt 0; do
       arg=$1
       shift
-      func_quote_arg pretty,unquoted "$arg"
-      qarg=$func_quote_arg_unquoted_result
-      func_append libtool_args " $func_quote_arg_result"
+      func_quote_for_eval "$arg"
+      qarg=$func_quote_for_eval_unquoted_result
+      func_append libtool_args " $func_quote_for_eval_result"
 
       # If the previous option needs an argument, assign it.
       if test -n "$prev"; then
@@ -7426,9 +7211,9 @@ func_mode_link ()
        save_ifs=$IFS; IFS=,
        for flag in $args; do
          IFS=$save_ifs
-          func_quote_arg pretty "$flag"
-         func_append arg " $func_quote_arg_result"
-         func_append compiler_flags " $func_quote_arg_result"
+          func_quote_for_eval "$flag"
+         func_append arg " $func_quote_for_eval_result"
+         func_append compiler_flags " $func_quote_for_eval_result"
        done
        IFS=$save_ifs
        func_stripname ' ' '' "$arg"
@@ -7442,10 +7227,10 @@ func_mode_link ()
        save_ifs=$IFS; IFS=,
        for flag in $args; do
          IFS=$save_ifs
-          func_quote_arg pretty "$flag"
-         func_append arg " $wl$func_quote_arg_result"
-         func_append compiler_flags " $wl$func_quote_arg_result"
-         func_append linker_flags " $func_quote_arg_result"
+          func_quote_for_eval "$flag"
+         func_append arg " $wl$func_quote_for_eval_result"
+         func_append compiler_flags " $wl$func_quote_for_eval_result"
+         func_append linker_flags " $func_quote_for_eval_result"
        done
        IFS=$save_ifs
        func_stripname ' ' '' "$arg"
@@ -7469,8 +7254,8 @@ func_mode_link ()
 
       # -msg_* for osf cc
       -msg_*)
-       func_quote_arg pretty "$arg"
-       arg=$func_quote_arg_result
+       func_quote_for_eval "$arg"
+       arg=$func_quote_for_eval_result
        ;;
 
       # Flags to be passed through unchanged, with rationale:
@@ -7489,14 +7274,12 @@ func_mode_link ()
       # -O*, -g*, -flto*, -fwhopr*, -fuse-linker-plugin GCC link-time optimization
       # -specs=*             GCC specs files
       # -stdlib=*            select c++ std lib with clang
-      # -fsanitize=*         Clang/GCC memory and address sanitizer
-      # -fuse-ld=*           Linker select flags for GCC
       -64|-mips[0-9]|-r[0-9][0-9]*|-xarch=*|-xtarget=*|+DA*|+DD*|-q*|-m*| \
       -t[45]*|-txscale*|-p|-pg|--coverage|-fprofile-*|-F*|@*|-tp=*|--sysroot=*| \
       -O*|-g*|-flto*|-fwhopr*|-fuse-linker-plugin|-fstack-protector*|-stdlib=*| \
-      -specs=*|-fsanitize=*|-fuse-ld=*)
-        func_quote_arg pretty "$arg"
-       arg=$func_quote_arg_result
+      -specs=*)
+        func_quote_for_eval "$arg"
+       arg=$func_quote_for_eval_result
         func_append compile_command " $arg"
         func_append finalize_command " $arg"
         func_append compiler_flags " $arg"
@@ -7517,15 +7300,15 @@ func_mode_link ()
          continue
         else
          # Otherwise treat like 'Some other compiler flag' below
-         func_quote_arg pretty "$arg"
-         arg=$func_quote_arg_result
+         func_quote_for_eval "$arg"
+         arg=$func_quote_for_eval_result
         fi
        ;;
 
       # Some other compiler flag.
       -* | +*)
-        func_quote_arg pretty "$arg"
-       arg=$func_quote_arg_result
+        func_quote_for_eval "$arg"
+       arg=$func_quote_for_eval_result
        ;;
 
       *.$objext)
@@ -7645,8 +7428,8 @@ func_mode_link ()
       *)
        # Unknown arguments in both finalize_command and compile_command need
        # to be aesthetically quoted because they are evaled later.
-       func_quote_arg pretty "$arg"
-       arg=$func_quote_arg_result
+       func_quote_for_eval "$arg"
+       arg=$func_quote_for_eval_result
        ;;
       esac # arg
 
@@ -10152,8 +9935,8 @@ EOF
            for cmd in $concat_cmds; do
              IFS=$save_ifs
              $opt_quiet || {
-                 func_quote_arg expand,pretty "$cmd"
-                 eval "func_echo $func_quote_arg_result"
+                 func_quote_for_expand "$cmd"
+                 eval "func_echo $func_quote_for_expand_result"
              }
              $opt_dry_run || eval "$cmd" || {
                lt_exit=$?
@@ -10246,8 +10029,8 @@ EOF
          eval cmd=\"$cmd\"
          IFS=$save_ifs
          $opt_quiet || {
-           func_quote_arg expand,pretty "$cmd"
-           eval "func_echo $func_quote_arg_result"
+           func_quote_for_expand "$cmd"
+           eval "func_echo $func_quote_for_expand_result"
          }
          $opt_dry_run || eval "$cmd" || {
            lt_exit=$?
@@ -10721,13 +10504,12 @@ EOF
          elif eval var_value=\$$var; test -z "$var_value"; then
            relink_command="$var=; export $var; $relink_command"
          else
-           func_quote_arg pretty "$var_value"
-           relink_command="$var=$func_quote_arg_result; export $var; $relink_command"
+           func_quote_for_eval "$var_value"
+           relink_command="$var=$func_quote_for_eval_result; export $var; $relink_command"
          fi
        done
-       func_quote eval cd "`pwd`"
-       func_quote_arg pretty,unquoted "($func_quote_result; $relink_command)"
-       relink_command=$func_quote_arg_unquoted_result
+       relink_command="(cd `pwd`; $relink_command)"
+       relink_command=`$ECHO "$relink_command" | $SED "$sed_quote_subst"`
       fi
 
       # Only actually do things if not in dry run mode.
@@ -10967,15 +10749,13 @@ EOF
        elif eval var_value=\$$var; test -z "$var_value"; then
          relink_command="$var=; export $var; $relink_command"
        else
-         func_quote_arg pretty,unquoted "$var_value"
-         relink_command="$var=$func_quote_arg_unquoted_result; export $var; $relink_command"
+         func_quote_for_eval "$var_value"
+         relink_command="$var=$func_quote_for_eval_result; export $var; $relink_command"
        fi
       done
       # Quote the link command for shipping.
-      func_quote eval cd "`pwd`"
-      relink_command="($func_quote_result; $SHELL \"$progpath\" $preserve_args --mode=relink $libtool_args @inst_prefix_dir@)"
-      func_quote_arg pretty,unquoted "$relink_command"
-      relink_command=$func_quote_arg_unquoted_result
+      relink_command="(cd `pwd`; $SHELL \"$progpath\" $preserve_args --mode=relink $libtool_args @inst_prefix_dir@)"
+      relink_command=`$ECHO "$relink_command" | $SED "$sed_quote_subst"`
       if test yes = "$hardcode_automatic"; then
        relink_command=
       fi
diff --git a/m4/ax_cxx_compile_stdcxx.m4 b/m4/ax_cxx_compile_stdcxx.m4
new file mode 100644 (file)
index 0000000..5032bba
--- /dev/null
@@ -0,0 +1,982 @@
+# ===========================================================================
+#  https://www.gnu.org/software/autoconf-archive/ax_cxx_compile_stdcxx.html
+# ===========================================================================
+#
+# SYNOPSIS
+#
+#   AX_CXX_COMPILE_STDCXX(VERSION, [ext|noext], [mandatory|optional])
+#
+# DESCRIPTION
+#
+#   Check for baseline language coverage in the compiler for the specified
+#   version of the C++ standard.  If necessary, add switches to CXX and
+#   CXXCPP to enable support.  VERSION may be '11' (for the C++11 standard)
+#   or '14' (for the C++14 standard).
+#
+#   The second argument, if specified, indicates whether you insist on an
+#   extended mode (e.g. -std=gnu++11) or a strict conformance mode (e.g.
+#   -std=c++11).  If neither is specified, you get whatever works, with
+#   preference for an extended mode.
+#
+#   The third argument, if specified 'mandatory' or if left unspecified,
+#   indicates that baseline support for the specified C++ standard is
+#   required and that the macro should error out if no mode with that
+#   support is found.  If specified 'optional', then configuration proceeds
+#   regardless, after defining HAVE_CXX${VERSION} if and only if a
+#   supporting mode is found.
+#
+# LICENSE
+#
+#   Copyright (c) 2008 Benjamin Kosnik <bkoz@redhat.com>
+#   Copyright (c) 2012 Zack Weinberg <zackw@panix.com>
+#   Copyright (c) 2013 Roy Stogner <roystgnr@ices.utexas.edu>
+#   Copyright (c) 2014, 2015 Google Inc.; contributed by Alexey Sokolov <sokolov@google.com>
+#   Copyright (c) 2015 Paul Norman <penorman@mac.com>
+#   Copyright (c) 2015 Moritz Klammler <moritz@klammler.eu>
+#   Copyright (c) 2016 Krzesimir Nowak <qdlacz@gmail.com>
+#
+#   Copying and distribution of this file, with or without modification, are
+#   permitted in any medium without royalty provided the copyright notice
+#   and this notice are preserved.  This file is offered as-is, without any
+#   warranty.
+
+#serial 7
+
+dnl  This macro is based on the code from the AX_CXX_COMPILE_STDCXX_11 macro
+dnl  (serial version number 13).
+
+AX_REQUIRE_DEFINED([AC_MSG_WARN])
+AC_DEFUN([AX_CXX_COMPILE_STDCXX], [dnl
+  m4_if([$1], [11], [ax_cxx_compile_alternatives="11 0x"],
+        [$1], [14], [ax_cxx_compile_alternatives="14 1y"],
+        [$1], [17], [ax_cxx_compile_alternatives="17 1z"],
+        [m4_fatal([invalid first argument `$1' to AX_CXX_COMPILE_STDCXX])])dnl
+  m4_if([$2], [], [],
+        [$2], [ext], [],
+        [$2], [noext], [],
+        [m4_fatal([invalid second argument `$2' to AX_CXX_COMPILE_STDCXX])])dnl
+  m4_if([$3], [], [ax_cxx_compile_cxx$1_required=true],
+        [$3], [mandatory], [ax_cxx_compile_cxx$1_required=true],
+        [$3], [optional], [ax_cxx_compile_cxx$1_required=false],
+        [m4_fatal([invalid third argument `$3' to AX_CXX_COMPILE_STDCXX])])
+  AC_LANG_PUSH([C++])dnl
+  ac_success=no
+  AC_CACHE_CHECK(whether $CXX supports C++$1 features by default,
+  ax_cv_cxx_compile_cxx$1,
+  [AC_COMPILE_IFELSE([AC_LANG_SOURCE([_AX_CXX_COMPILE_STDCXX_testbody_$1])],
+    [ax_cv_cxx_compile_cxx$1=yes],
+    [ax_cv_cxx_compile_cxx$1=no])])
+  if test x$ax_cv_cxx_compile_cxx$1 = xyes; then
+    ac_success=yes
+  fi
+
+  m4_if([$2], [noext], [], [dnl
+  if test x$ac_success = xno; then
+    for alternative in ${ax_cxx_compile_alternatives}; do
+      switch="-std=gnu++${alternative}"
+      cachevar=AS_TR_SH([ax_cv_cxx_compile_cxx$1_$switch])
+      AC_CACHE_CHECK(whether $CXX supports C++$1 features with $switch,
+                     $cachevar,
+        [ac_save_CXX="$CXX"
+         CXX="$CXX $switch"
+         AC_COMPILE_IFELSE([AC_LANG_SOURCE([_AX_CXX_COMPILE_STDCXX_testbody_$1])],
+          [eval $cachevar=yes],
+          [eval $cachevar=no])
+         CXX="$ac_save_CXX"])
+      if eval test x\$$cachevar = xyes; then
+        CXX="$CXX $switch"
+        if test -n "$CXXCPP" ; then
+          CXXCPP="$CXXCPP $switch"
+        fi
+        ac_success=yes
+        break
+      fi
+    done
+  fi])
+
+  m4_if([$2], [ext], [], [dnl
+  if test x$ac_success = xno; then
+    dnl HP's aCC needs +std=c++11 according to:
+    dnl http://h21007.www2.hp.com/portal/download/files/unprot/aCxx/PDF_Release_Notes/769149-001.pdf
+    dnl Cray's crayCC needs "-h std=c++11"
+    for alternative in ${ax_cxx_compile_alternatives}; do
+      for switch in -std=c++${alternative} +std=c++${alternative} "-h std=c++${alternative}"; do
+        cachevar=AS_TR_SH([ax_cv_cxx_compile_cxx$1_$switch])
+        AC_CACHE_CHECK(whether $CXX supports C++$1 features with $switch,
+                       $cachevar,
+          [ac_save_CXX="$CXX"
+           CXX="$CXX $switch"
+           AC_COMPILE_IFELSE([AC_LANG_SOURCE([_AX_CXX_COMPILE_STDCXX_testbody_$1])],
+            [eval $cachevar=yes],
+            [eval $cachevar=no])
+           CXX="$ac_save_CXX"])
+        if eval test x\$$cachevar = xyes; then
+          CXX="$CXX $switch"
+          if test -n "$CXXCPP" ; then
+            CXXCPP="$CXXCPP $switch"
+          fi
+          ac_success=yes
+          break
+        fi
+      done
+      if test x$ac_success = xyes; then
+        break
+      fi
+    done
+  fi])
+  AC_LANG_POP([C++])
+  if test x$ax_cxx_compile_cxx$1_required = xtrue; then
+    if test x$ac_success = xno; then
+      AC_MSG_ERROR([*** A compiler with support for C++$1 language features is required.])
+    fi
+  fi
+  if test x$ac_success = xno; then
+    HAVE_CXX$1=0
+    AC_MSG_NOTICE([No compiler with C++$1 support was found])
+  else
+    HAVE_CXX$1=1
+    AC_DEFINE(HAVE_CXX$1,1,
+              [define if the compiler supports basic C++$1 syntax])
+  fi
+  AC_SUBST(HAVE_CXX$1)
+  m4_if([$1], [17], [AC_MSG_WARN([C++17 is not yet standardized, so the checks may change in incompatible ways anytime])])
+])
+
+
+dnl  Test body for checking C++11 support
+
+m4_define([_AX_CXX_COMPILE_STDCXX_testbody_11],
+  _AX_CXX_COMPILE_STDCXX_testbody_new_in_11
+)
+
+
+dnl  Test body for checking C++14 support
+
+m4_define([_AX_CXX_COMPILE_STDCXX_testbody_14],
+  _AX_CXX_COMPILE_STDCXX_testbody_new_in_11
+  _AX_CXX_COMPILE_STDCXX_testbody_new_in_14
+)
+
+m4_define([_AX_CXX_COMPILE_STDCXX_testbody_17],
+  _AX_CXX_COMPILE_STDCXX_testbody_new_in_11
+  _AX_CXX_COMPILE_STDCXX_testbody_new_in_14
+  _AX_CXX_COMPILE_STDCXX_testbody_new_in_17
+)
+
+dnl  Tests for new features in C++11
+
+m4_define([_AX_CXX_COMPILE_STDCXX_testbody_new_in_11], [[
+
+// If the compiler admits that it is not ready for C++11, why torture it?
+// Hopefully, this will speed up the test.
+
+#ifndef __cplusplus
+
+#error "This is not a C++ compiler"
+
+#elif __cplusplus < 201103L
+
+#error "This is not a C++11 compiler"
+
+#else
+
+namespace cxx11
+{
+
+  namespace test_static_assert
+  {
+
+    template <typename T>
+    struct check
+    {
+      static_assert(sizeof(int) <= sizeof(T), "not big enough");
+    };
+
+  }
+
+  namespace test_final_override
+  {
+
+    struct Base
+    {
+      virtual void f() {}
+    };
+
+    struct Derived : public Base
+    {
+      virtual void f() override {}
+    };
+
+  }
+
+  namespace test_double_right_angle_brackets
+  {
+
+    template < typename T >
+    struct check {};
+
+    typedef check<void> single_type;
+    typedef check<check<void>> double_type;
+    typedef check<check<check<void>>> triple_type;
+    typedef check<check<check<check<void>>>> quadruple_type;
+
+  }
+
+  namespace test_decltype
+  {
+
+    int
+    f()
+    {
+      int a = 1;
+      decltype(a) b = 2;
+      return a + b;
+    }
+
+  }
+
+  namespace test_type_deduction
+  {
+
+    template < typename T1, typename T2 >
+    struct is_same
+    {
+      static const bool value = false;
+    };
+
+    template < typename T >
+    struct is_same<T, T>
+    {
+      static const bool value = true;
+    };
+
+    template < typename T1, typename T2 >
+    auto
+    add(T1 a1, T2 a2) -> decltype(a1 + a2)
+    {
+      return a1 + a2;
+    }
+
+    int
+    test(const int c, volatile int v)
+    {
+      static_assert(is_same<int, decltype(0)>::value == true, "");
+      static_assert(is_same<int, decltype(c)>::value == false, "");
+      static_assert(is_same<int, decltype(v)>::value == false, "");
+      auto ac = c;
+      auto av = v;
+      auto sumi = ac + av + 'x';
+      auto sumf = ac + av + 1.0;
+      static_assert(is_same<int, decltype(ac)>::value == true, "");
+      static_assert(is_same<int, decltype(av)>::value == true, "");
+      static_assert(is_same<int, decltype(sumi)>::value == true, "");
+      static_assert(is_same<int, decltype(sumf)>::value == false, "");
+      static_assert(is_same<int, decltype(add(c, v))>::value == true, "");
+      return (sumf > 0.0) ? sumi : add(c, v);
+    }
+
+  }
+
+  namespace test_noexcept
+  {
+
+    int f() { return 0; }
+    int g() noexcept { return 0; }
+
+    static_assert(noexcept(f()) == false, "");
+    static_assert(noexcept(g()) == true, "");
+
+  }
+
+  namespace test_constexpr
+  {
+
+    template < typename CharT >
+    unsigned long constexpr
+    strlen_c_r(const CharT *const s, const unsigned long acc) noexcept
+    {
+      return *s ? strlen_c_r(s + 1, acc + 1) : acc;
+    }
+
+    template < typename CharT >
+    unsigned long constexpr
+    strlen_c(const CharT *const s) noexcept
+    {
+      return strlen_c_r(s, 0UL);
+    }
+
+    static_assert(strlen_c("") == 0UL, "");
+    static_assert(strlen_c("1") == 1UL, "");
+    static_assert(strlen_c("example") == 7UL, "");
+    static_assert(strlen_c("another\0example") == 7UL, "");
+
+  }
+
+  namespace test_rvalue_references
+  {
+
+    template < int N >
+    struct answer
+    {
+      static constexpr int value = N;
+    };
+
+    answer<1> f(int&)       { return answer<1>(); }
+    answer<2> f(const int&) { return answer<2>(); }
+    answer<3> f(int&&)      { return answer<3>(); }
+
+    void
+    test()
+    {
+      int i = 0;
+      const int c = 0;
+      static_assert(decltype(f(i))::value == 1, "");
+      static_assert(decltype(f(c))::value == 2, "");
+      static_assert(decltype(f(0))::value == 3, "");
+    }
+
+  }
+
+  namespace test_uniform_initialization
+  {
+
+    struct test
+    {
+      static const int zero {};
+      static const int one {1};
+    };
+
+    static_assert(test::zero == 0, "");
+    static_assert(test::one == 1, "");
+
+  }
+
+  namespace test_lambdas
+  {
+
+    void
+    test1()
+    {
+      auto lambda1 = [](){};
+      auto lambda2 = lambda1;
+      lambda1();
+      lambda2();
+    }
+
+    int
+    test2()
+    {
+      auto a = [](int i, int j){ return i + j; }(1, 2);
+      auto b = []() -> int { return '0'; }();
+      auto c = [=](){ return a + b; }();
+      auto d = [&](){ return c; }();
+      auto e = [a, &b](int x) mutable {
+        const auto identity = [](int y){ return y; };
+        for (auto i = 0; i < a; ++i)
+          a += b--;
+        return x + identity(a + b);
+      }(0);
+      return a + b + c + d + e;
+    }
+
+    int
+    test3()
+    {
+      const auto nullary = [](){ return 0; };
+      const auto unary = [](int x){ return x; };
+      using nullary_t = decltype(nullary);
+      using unary_t = decltype(unary);
+      const auto higher1st = [](nullary_t f){ return f(); };
+      const auto higher2nd = [unary](nullary_t f1){
+        return [unary, f1](unary_t f2){ return f2(unary(f1())); };
+      };
+      return higher1st(nullary) + higher2nd(nullary)(unary);
+    }
+
+  }
+
+  namespace test_variadic_templates
+  {
+
+    template <int...>
+    struct sum;
+
+    template <int N0, int... N1toN>
+    struct sum<N0, N1toN...>
+    {
+      static constexpr auto value = N0 + sum<N1toN...>::value;
+    };
+
+    template <>
+    struct sum<>
+    {
+      static constexpr auto value = 0;
+    };
+
+    static_assert(sum<>::value == 0, "");
+    static_assert(sum<1>::value == 1, "");
+    static_assert(sum<23>::value == 23, "");
+    static_assert(sum<1, 2>::value == 3, "");
+    static_assert(sum<5, 5, 11>::value == 21, "");
+    static_assert(sum<2, 3, 5, 7, 11, 13>::value == 41, "");
+
+  }
+
+  // http://stackoverflow.com/questions/13728184/template-aliases-and-sfinae
+  // Clang 3.1 fails with headers of libstd++ 4.8.3 when using std::function
+  // because of this.
+  namespace test_template_alias_sfinae
+  {
+
+    struct foo {};
+
+    template<typename T>
+    using member = typename T::member_type;
+
+    template<typename T>
+    void func(...) {}
+
+    template<typename T>
+    void func(member<T>*) {}
+
+    void test();
+
+    void test() { func<foo>(0); }
+
+  }
+
+}  // namespace cxx11
+
+#endif  // __cplusplus >= 201103L
+
+]])
+
+
+dnl  Tests for new features in C++14
+
+m4_define([_AX_CXX_COMPILE_STDCXX_testbody_new_in_14], [[
+
+// If the compiler admits that it is not ready for C++14, why torture it?
+// Hopefully, this will speed up the test.
+
+#ifndef __cplusplus
+
+#error "This is not a C++ compiler"
+
+#elif __cplusplus < 201402L
+
+#error "This is not a C++14 compiler"
+
+#else
+
+namespace cxx14
+{
+
+  namespace test_polymorphic_lambdas
+  {
+
+    int
+    test()
+    {
+      const auto lambda = [](auto&&... args){
+        const auto istiny = [](auto x){
+          return (sizeof(x) == 1UL) ? 1 : 0;
+        };
+        const int aretiny[] = { istiny(args)... };
+        return aretiny[0];
+      };
+      return lambda(1, 1L, 1.0f, '1');
+    }
+
+  }
+
+  namespace test_binary_literals
+  {
+
+    constexpr auto ivii = 0b0000000000101010;
+    static_assert(ivii == 42, "wrong value");
+
+  }
+
+  namespace test_generalized_constexpr
+  {
+
+    template < typename CharT >
+    constexpr unsigned long
+    strlen_c(const CharT *const s) noexcept
+    {
+      auto length = 0UL;
+      for (auto p = s; *p; ++p)
+        ++length;
+      return length;
+    }
+
+    static_assert(strlen_c("") == 0UL, "");
+    static_assert(strlen_c("x") == 1UL, "");
+    static_assert(strlen_c("test") == 4UL, "");
+    static_assert(strlen_c("another\0test") == 7UL, "");
+
+  }
+
+  namespace test_lambda_init_capture
+  {
+
+    int
+    test()
+    {
+      auto x = 0;
+      const auto lambda1 = [a = x](int b){ return a + b; };
+      const auto lambda2 = [a = lambda1(x)](){ return a; };
+      return lambda2();
+    }
+
+  }
+
+  namespace test_digit_separators
+  {
+
+    constexpr auto ten_million = 100'000'000;
+    static_assert(ten_million == 100000000, "");
+
+  }
+
+  namespace test_return_type_deduction
+  {
+
+    auto f(int& x) { return x; }
+    decltype(auto) g(int& x) { return x; }
+
+    template < typename T1, typename T2 >
+    struct is_same
+    {
+      static constexpr auto value = false;
+    };
+
+    template < typename T >
+    struct is_same<T, T>
+    {
+      static constexpr auto value = true;
+    };
+
+    int
+    test()
+    {
+      auto x = 0;
+      static_assert(is_same<int, decltype(f(x))>::value, "");
+      static_assert(is_same<int&, decltype(g(x))>::value, "");
+      return x;
+    }
+
+  }
+
+}  // namespace cxx14
+
+#endif  // __cplusplus >= 201402L
+
+]])
+
+
+dnl  Tests for new features in C++17
+
+m4_define([_AX_CXX_COMPILE_STDCXX_testbody_new_in_17], [[
+
+// If the compiler admits that it is not ready for C++17, why torture it?
+// Hopefully, this will speed up the test.
+
+#ifndef __cplusplus
+
+#error "This is not a C++ compiler"
+
+#elif __cplusplus <= 201402L
+
+#error "This is not a C++17 compiler"
+
+#else
+
+#if defined(__clang__)
+  #define REALLY_CLANG
+#else
+  #if defined(__GNUC__)
+    #define REALLY_GCC
+  #endif
+#endif
+
+#include <initializer_list>
+#include <utility>
+#include <type_traits>
+
+namespace cxx17
+{
+
+#if !defined(REALLY_CLANG)
+  namespace test_constexpr_lambdas
+  {
+
+    // TODO: test it with clang++ from git
+
+    constexpr int foo = [](){return 42;}();
+
+  }
+#endif // !defined(REALLY_CLANG)
+
+  namespace test::nested_namespace::definitions
+  {
+
+  }
+
+  namespace test_fold_expression
+  {
+
+    template<typename... Args>
+    int multiply(Args... args)
+    {
+      return (args * ... * 1);
+    }
+
+    template<typename... Args>
+    bool all(Args... args)
+    {
+      return (args && ...);
+    }
+
+  }
+
+  namespace test_extended_static_assert
+  {
+
+    static_assert (true);
+
+  }
+
+  namespace test_auto_brace_init_list
+  {
+
+    auto foo = {5};
+    auto bar {5};
+
+    static_assert(std::is_same<std::initializer_list<int>, decltype(foo)>::value);
+    static_assert(std::is_same<int, decltype(bar)>::value);
+  }
+
+  namespace test_typename_in_template_template_parameter
+  {
+
+    template<template<typename> typename X> struct D;
+
+  }
+
+  namespace test_fallthrough_nodiscard_maybe_unused_attributes
+  {
+
+    int f1()
+    {
+      return 42;
+    }
+
+    [[nodiscard]] int f2()
+    {
+      [[maybe_unused]] auto unused = f1();
+
+      switch (f1())
+      {
+      case 17:
+        f1();
+        [[fallthrough]];
+      case 42:
+        f1();
+      }
+      return f1();
+    }
+
+  }
+
+  namespace test_extended_aggregate_initialization
+  {
+
+    struct base1
+    {
+      int b1, b2 = 42;
+    };
+
+    struct base2
+    {
+      base2() {
+        b3 = 42;
+      }
+      int b3;
+    };
+
+    struct derived : base1, base2
+    {
+        int d;
+    };
+
+    derived d1 {{1, 2}, {}, 4};  // full initialization
+    derived d2 {{}, {}, 4};      // value-initialized bases
+
+  }
+
+  namespace test_general_range_based_for_loop
+  {
+
+    struct iter
+    {
+      int i;
+
+      int& operator* ()
+      {
+        return i;
+      }
+
+      const int& operator* () const
+      {
+        return i;
+      }
+
+      iter& operator++()
+      {
+        ++i;
+        return *this;
+      }
+    };
+
+    struct sentinel
+    {
+      int i;
+    };
+
+    bool operator== (const iter& i, const sentinel& s)
+    {
+      return i.i == s.i;
+    }
+
+    bool operator!= (const iter& i, const sentinel& s)
+    {
+      return !(i == s);
+    }
+
+    struct range
+    {
+      iter begin() const
+      {
+        return {0};
+      }
+
+      sentinel end() const
+      {
+        return {5};
+      }
+    };
+
+    void f()
+    {
+      range r {};
+
+      for (auto i : r)
+      {
+        [[maybe_unused]] auto v = i;
+      }
+    }
+
+  }
+
+  namespace test_lambda_capture_asterisk_this_by_value
+  {
+
+    struct t
+    {
+      int i;
+      int foo()
+      {
+        return [*this]()
+        {
+          return i;
+        }();
+      }
+    };
+
+  }
+
+  namespace test_enum_class_construction
+  {
+
+    enum class byte : unsigned char
+    {};
+
+    byte foo {42};
+
+  }
+
+  namespace test_constexpr_if
+  {
+
+    template <bool cond>
+    int f ()
+    {
+      if constexpr(cond)
+      {
+        return 13;
+      }
+      else
+      {
+        return 42;
+      }
+    }
+
+  }
+
+  namespace test_selection_statement_with_initializer
+  {
+
+    int f()
+    {
+      return 13;
+    }
+
+    int f2()
+    {
+      if (auto i = f(); i > 0)
+      {
+        return 3;
+      }
+
+      switch (auto i = f(); i + 4)
+      {
+      case 17:
+        return 2;
+
+      default:
+        return 1;
+      }
+    }
+
+  }
+
+#if !defined(REALLY_CLANG)
+  namespace test_template_argument_deduction_for_class_templates
+  {
+
+    // TODO: test it with clang++ from git
+
+    template <typename T1, typename T2>
+    struct pair
+    {
+      pair (T1 p1, T2 p2)
+        : m1 {p1},
+          m2 {p2}
+      {}
+
+      T1 m1;
+      T2 m2;
+    };
+
+    void f()
+    {
+      [[maybe_unused]] auto p = pair{13, 42u};
+    }
+
+  }
+#endif // !defined(REALLY_CLANG)
+
+  namespace test_non_type_auto_template_parameters
+  {
+
+    template <auto n>
+    struct B
+    {};
+
+    B<5> b1;
+    B<'a'> b2;
+
+  }
+
+#if !defined(REALLY_CLANG)
+  namespace test_structured_bindings
+  {
+
+    // TODO: test it with clang++ from git
+
+    int arr[2] = { 1, 2 };
+    std::pair<int, int> pr = { 1, 2 };
+
+    auto f1() -> int(&)[2]
+    {
+      return arr;
+    }
+
+    auto f2() -> std::pair<int, int>&
+    {
+      return pr;
+    }
+
+    struct S
+    {
+      int x1 : 2;
+      volatile double y1;
+    };
+
+    S f3()
+    {
+      return {};
+    }
+
+    auto [ x1, y1 ] = f1();
+    auto& [ xr1, yr1 ] = f1();
+    auto [ x2, y2 ] = f2();
+    auto& [ xr2, yr2 ] = f2();
+    const auto [ x3, y3 ] = f3();
+
+  }
+#endif // !defined(REALLY_CLANG)
+
+#if !defined(REALLY_CLANG)
+  namespace test_exception_spec_type_system
+  {
+
+    // TODO: test it with clang++ from git
+
+    struct Good {};
+    struct Bad {};
+
+    void g1() noexcept;
+    void g2();
+
+    template<typename T>
+    Bad
+    f(T*, T*);
+
+    template<typename T1, typename T2>
+    Good
+    f(T1*, T2*);
+
+    static_assert (std::is_same_v<Good, decltype(f(g1, g2))>);
+
+  }
+#endif // !defined(REALLY_CLANG)
+
+  namespace test_inline_variables
+  {
+
+    template<class T> void f(T)
+    {}
+
+    template<class T> inline T g(T)
+    {
+      return T{};
+    }
+
+    template<> inline void f<>(int)
+    {}
+
+    template<> int g<>(int)
+    {
+      return 5;
+    }
+
+  }
+
+}  // namespace cxx17
+
+#endif  // __cplusplus <= 201402L
+
+]])
index b55a6e5..a644432 100644 (file)
@@ -1,6 +1,6 @@
 # libtool.m4 - Configure libtool for the host system. -*-Autoconf-*-
 #
-#   Copyright (C) 1996-2001, 2003-2018 Free Software Foundation, Inc.
+#   Copyright (C) 1996-2001, 2003-2015 Free Software Foundation, Inc.
 #   Written by Gordon Matzigkeit, 1996
 #
 # This file is free software; the Free Software Foundation gives
@@ -219,8 +219,8 @@ esac
 ofile=libtool
 can_build_shared=yes
 
-# All known linkers require a '.a' archive for static linking (except MSVC and
-# ICC, which need '.lib').
+# All known linkers require a '.a' archive for static linking (except MSVC,
+# which needs '.lib').
 libext=a
 
 with_gnu_ld=$lt_cv_prog_gnu_ld
@@ -1042,8 +1042,8 @@ int forced_loaded() { return 2;}
 _LT_EOF
       echo "$LTCC $LTCFLAGS -c -o conftest.o conftest.c" >&AS_MESSAGE_LOG_FD
       $LTCC $LTCFLAGS -c -o conftest.o conftest.c 2>&AS_MESSAGE_LOG_FD
-      echo "$AR $AR_FLAGS libconftest.a conftest.o" >&AS_MESSAGE_LOG_FD
-      $AR $AR_FLAGS libconftest.a conftest.o 2>&AS_MESSAGE_LOG_FD
+      echo "$AR cru libconftest.a conftest.o" >&AS_MESSAGE_LOG_FD
+      $AR cru libconftest.a conftest.o 2>&AS_MESSAGE_LOG_FD
       echo "$RANLIB libconftest.a" >&AS_MESSAGE_LOG_FD
       $RANLIB libconftest.a 2>&AS_MESSAGE_LOG_FD
       cat > conftest.c << _LT_EOF
@@ -1493,22 +1493,9 @@ need_locks=$enable_libtool_lock
 m4_defun([_LT_PROG_AR],
 [AC_CHECK_TOOLS(AR, [ar], false)
 : ${AR=ar}
+: ${AR_FLAGS=cru}
 _LT_DECL([], [AR], [1], [The archiver])
-
-# Use ARFLAGS variable as AR's operation code to sync the variable naming with
-# Automake.  If both AR_FLAGS and ARFLAGS are specified, AR_FLAGS should have
-# higher priority because thats what people were doing historically (setting
-# ARFLAGS for automake and AR_FLAGS for libtool).  FIXME: Make the AR_FLAGS
-# variable obsoleted/removed.
-
-test ${AR_FLAGS+y} || AR_FLAGS=${ARFLAGS-cr}
-lt_ar_flags=$AR_FLAGS
-_LT_DECL([], [lt_ar_flags], [0], [Flags to create an archive (by configure)])
-
-# Make AR_FLAGS overridable by 'make ARFLAGS='.  Don't try to run-time override
-# by AR_FLAGS because that was never working and AR_FLAGS is about to die.
-_LT_DECL([], [AR_FLAGS], [\@S|@{ARFLAGS-"\@S|@lt_ar_flags"}],
-         [Flags to create an archive])
+_LT_DECL([], [AR_FLAGS], [1], [Flags to create an archive])
 
 AC_CACHE_CHECK([for archiver @FILE support], [lt_cv_ar_at_file],
   [lt_cv_ar_at_file=no
@@ -2220,35 +2207,26 @@ m4_defun([_LT_CMD_STRIPLIB],
 striplib=
 old_striplib=
 AC_MSG_CHECKING([whether stripping libraries is possible])
-if test -z "$STRIP"; then
-  AC_MSG_RESULT([no])
+if test -n "$STRIP" && $STRIP -V 2>&1 | $GREP "GNU strip" >/dev/null; then
+  test -z "$old_striplib" && old_striplib="$STRIP --strip-debug"
+  test -z "$striplib" && striplib="$STRIP --strip-unneeded"
+  AC_MSG_RESULT([yes])
 else
-  if $STRIP -V 2>&1 | $GREP "GNU strip" >/dev/null; then
-    old_striplib="$STRIP --strip-debug"
-    striplib="$STRIP --strip-unneeded"
-    AC_MSG_RESULT([yes])
-  else
-    case $host_os in
-    darwin*)
-      # FIXME - insert some real tests, host_os isn't really good enough
+# FIXME - insert some real tests, host_os isn't really good enough
+  case $host_os in
+  darwin*)
+    if test -n "$STRIP"; then
       striplib="$STRIP -x"
       old_striplib="$STRIP -S"
       AC_MSG_RESULT([yes])
-      ;;
-    freebsd*)
-      if $STRIP -V 2>&1 | $GREP "elftoolchain" >/dev/null; then
-        old_striplib="$STRIP --strip-debug"
-        striplib="$STRIP --strip-unneeded"
-        AC_MSG_RESULT([yes])
-      else
-        AC_MSG_RESULT([no])
-      fi
-      ;;
-    *)
+    else
       AC_MSG_RESULT([no])
-      ;;
-    esac
-  fi
+    fi
+    ;;
+  *)
+    AC_MSG_RESULT([no])
+    ;;
+  esac
 fi
 _LT_DECL([], [old_striplib], [1], [Commands to strip libraries])
 _LT_DECL([], [striplib], [1])
@@ -2587,8 +2565,8 @@ m4_if([$1], [],[
     dynamic_linker='Win32 ld.exe'
     ;;
 
-  *,cl* | *,icl*)
-    # Native MSVC or ICC
+  *,cl*)
+    # Native MSVC
     libname_spec='$name'
     soname_spec='$libname`echo $release | $SED -e 's/[[.]]/-/g'`$versuffix$shared_ext'
     library_names_spec='$libname.dll.lib'
@@ -2644,7 +2622,7 @@ m4_if([$1], [],[
     ;;
 
   *)
-    # Assume MSVC and ICC wrapper
+    # Assume MSVC wrapper
     library_names_spec='$libname`echo $release | $SED -e 's/[[.]]/-/g'`$versuffix$shared_ext $libname.lib'
     dynamic_linker='Win32 ld.exe'
     ;;
@@ -2889,6 +2867,9 @@ linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*)
   # before this can be enabled.
   hardcode_into_libs=yes
 
+  # Add ABI-specific directories to the system library path.
+  sys_lib_dlsearch_path_spec="/lib64 /usr/lib64 /lib /usr/lib"
+
   # Ideally, we could use ldconfig to report *all* directores which are
   # searched for libraries, however this is still not possible.  Aside from not
   # being certain /sbin/ldconfig is available, command
@@ -2897,7 +2878,7 @@ linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*)
   # appending ld.so.conf contents (and includes) to the search path.
   if test -f /etc/ld.so.conf; then
     lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s 2>/dev/null", \[$]2)); skip = 1; } { if (!skip) print \[$]0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;/^[  ]*hwcap[        ]/d;s/[:,      ]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;s/"//g;/^$/d' | tr '\n' ' '`
-    sys_lib_dlsearch_path_spec="/lib /usr/lib $lt_ld_extra"
+    sys_lib_dlsearch_path_spec="$sys_lib_dlsearch_path_spec $lt_ld_extra"
   fi
 
   # We used to test for /lib/ld.so.1 and disable shared libraries on
@@ -4032,7 +4013,7 @@ for ac_symprfx in "" "_"; do
   if test "$lt_cv_nm_interface" = "MS dumpbin"; then
     # Fake it for dumpbin and say T for any non-static function,
     # D for any global variable and I for any imported variable.
-    # Also find C++ and __fastcall symbols from MSVC++ or ICC,
+    # Also find C++ and __fastcall symbols from MSVC++,
     # which start with @ or ?.
     lt_cv_sys_global_symbol_pipe="$AWK ['"\
 "     {last_section=section; section=\$ 3};"\
@@ -4941,7 +4922,7 @@ m4_if([$1], [CXX], [
     if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then
       _LT_TAGVAR(export_symbols_cmds, $1)='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W")) && ([substr](\$ 3,1,1) != ".")) { if (\$ 2 == "W") { print \$ 3 " weak" } else { print \$ 3 } } }'\'' | sort -u > $export_symbols'
     else
-      _LT_TAGVAR(export_symbols_cmds, $1)='`func_echo_all $NM | $SED -e '\''s/B\([[^B]]*\)$/P\1/'\''` -PCpgl $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "L") || (\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) && ([substr](\$ 1,1,1) != ".")) { if ((\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) { print \$ 1 " weak" } else { print \$ 1 } } }'\'' | sort -u > $export_symbols'
+      _LT_TAGVAR(export_symbols_cmds, $1)='`func_echo_all $NM | $SED -e '\''s/B\([[^B]]*\)$/P\1/'\''` -PCpgl $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) && ([substr](\$ 1,1,1) != ".")) { if ((\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) { print \$ 1 " weak" } else { print \$ 1 } } }'\'' | sort -u > $export_symbols'
     fi
     ;;
   pw32*)
@@ -4949,7 +4930,7 @@ m4_if([$1], [CXX], [
     ;;
   cygwin* | mingw* | cegcc*)
     case $cc_basename in
-    cl* | icl*)
+    cl*)
       _LT_TAGVAR(exclude_expsyms, $1)='_NULL_IMPORT_DESCRIPTOR|_IMPORT_DESCRIPTOR_.*'
       ;;
     *)
@@ -5006,15 +4987,15 @@ dnl Note also adjust exclude_expsyms for C++ above.
 
   case $host_os in
   cygwin* | mingw* | pw32* | cegcc*)
-    # FIXME: the MSVC++ and ICC port hasn't been tested in a loooong time
+    # FIXME: the MSVC++ port hasn't been tested in a loooong time
     # When not using gcc, we currently assume that we are using
-    # Microsoft Visual C++ or Intel C++ Compiler.
+    # Microsoft Visual C++.
     if test yes != "$GCC"; then
       with_gnu_ld=no
     fi
     ;;
   interix*)
-    # we just hope/assume this is gcc and not c89 (= MSVC++ or ICC)
+    # we just hope/assume this is gcc and not c89 (= MSVC++)
     with_gnu_ld=yes
     ;;
   openbsd* | bitrig*)
@@ -5178,7 +5159,6 @@ _LT_EOF
        emximp -o $lib $output_objdir/$libname.def'
       _LT_TAGVAR(old_archive_From_new_cmds, $1)='emximp -o $output_objdir/${libname}_dll.a $output_objdir/$libname.def'
       _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes
-      _LT_TAGVAR(file_list_spec, $1)='@'
       ;;
 
     interix[[3-9]]*)
@@ -5396,7 +5376,7 @@ _LT_EOF
        if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then
          _LT_TAGVAR(export_symbols_cmds, $1)='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W")) && ([substr](\$ 3,1,1) != ".")) { if (\$ 2 == "W") { print \$ 3 " weak" } else { print \$ 3 } } }'\'' | sort -u > $export_symbols'
        else
-         _LT_TAGVAR(export_symbols_cmds, $1)='`func_echo_all $NM | $SED -e '\''s/B\([[^B]]*\)$/P\1/'\''` -PCpgl $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "L") || (\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) && ([substr](\$ 1,1,1) != ".")) { if ((\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) { print \$ 1 " weak" } else { print \$ 1 } } }'\'' | sort -u > $export_symbols'
+         _LT_TAGVAR(export_symbols_cmds, $1)='`func_echo_all $NM | $SED -e '\''s/B\([[^B]]*\)$/P\1/'\''` -PCpgl $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) && ([substr](\$ 1,1,1) != ".")) { if ((\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) { print \$ 1 " weak" } else { print \$ 1 } } }'\'' | sort -u > $export_symbols'
        fi
        aix_use_runtimelinking=no
 
@@ -5579,12 +5559,12 @@ _LT_EOF
 
     cygwin* | mingw* | pw32* | cegcc*)
       # When not using gcc, we currently assume that we are using
-      # Microsoft Visual C++ or Intel C++ Compiler.
+      # Microsoft Visual C++.
       # hardcode_libdir_flag_spec is actually meaningless, as there is
       # no search path for DLLs.
       case $cc_basename in
-      cl* | icl*)
-       # Native MSVC or ICC
+      cl*)
+       # Native MSVC
        _LT_TAGVAR(hardcode_libdir_flag_spec, $1)=' '
        _LT_TAGVAR(allow_undefined_flag, $1)=unsupported
        _LT_TAGVAR(always_export_symbols, $1)=yes
@@ -5625,7 +5605,7 @@ _LT_EOF
           fi'
        ;;
       *)
-       # Assume MSVC and ICC wrapper
+       # Assume MSVC wrapper
        _LT_TAGVAR(hardcode_libdir_flag_spec, $1)=' '
        _LT_TAGVAR(allow_undefined_flag, $1)=unsupported
        # Tell ltmain to make .lib files, not .a files.
@@ -5884,7 +5864,6 @@ _LT_EOF
        emximp -o $lib $output_objdir/$libname.def'
       _LT_TAGVAR(old_archive_From_new_cmds, $1)='emximp -o $output_objdir/${libname}_dll.a $output_objdir/$libname.def'
       _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes
-      _LT_TAGVAR(file_list_spec, $1)='@'
       ;;
 
     osf3*)
@@ -6655,8 +6634,8 @@ if test yes != "$_lt_caught_CXX_error"; then
 
       cygwin* | mingw* | pw32* | cegcc*)
        case $GXX,$cc_basename in
-       ,cl* | no,cl* | ,icl* | no,icl*)
-         # Native MSVC or ICC
+       ,cl* | no,cl*)
+         # Native MSVC
          # hardcode_libdir_flag_spec is actually meaningless, as there is
          # no search path for DLLs.
          _LT_TAGVAR(hardcode_libdir_flag_spec, $1)=' '
@@ -6754,7 +6733,6 @@ if test yes != "$_lt_caught_CXX_error"; then
          emximp -o $lib $output_objdir/$libname.def'
        _LT_TAGVAR(old_archive_From_new_cmds, $1)='emximp -o $output_objdir/${libname}_dll.a $output_objdir/$libname.def'
        _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes
-       _LT_TAGVAR(file_list_spec, $1)='@'
        ;;
 
       dgux*)
index 07421d9..94b0829 100644 (file)
@@ -1,6 +1,6 @@
 # Helper functions for option handling.                    -*- Autoconf -*-
 #
-#   Copyright (C) 2004-2005, 2007-2009, 2011-2018 Free Software
+#   Copyright (C) 2004-2005, 2007-2009, 2011-2015 Free Software
 #   Foundation, Inc.
 #   Written by Gary V. Vaughan, 2004
 #
index 3985c56..48bc934 100644 (file)
@@ -1,6 +1,6 @@
 # ltsugar.m4 -- libtool m4 base layer.                         -*-Autoconf-*-
 #
-# Copyright (C) 2004-2005, 2007-2008, 2011-2018 Free Software
+# Copyright (C) 2004-2005, 2007-2008, 2011-2015 Free Software
 # Foundation, Inc.
 # Written by Gary V. Vaughan, 2004
 #
index 86b2ad7..fa04b52 100644 (file)
@@ -1,6 +1,6 @@
 # ltversion.m4 -- version numbers                      -*- Autoconf -*-
 #
-#   Copyright (C) 2004, 2011-2018 Free Software Foundation, Inc.
+#   Copyright (C) 2004, 2011-2015 Free Software Foundation, Inc.
 #   Written by Scott James Remnant, 2004
 #
 # This file is free software; the Free Software Foundation gives
@@ -9,15 +9,15 @@
 
 # @configure_input@
 
-# serial 4221 ltversion.m4
+# serial 4179 ltversion.m4
 # This file is part of GNU Libtool
 
-m4_define([LT_PACKAGE_VERSION], [2.4.6.42-b88ce])
-m4_define([LT_PACKAGE_REVISION], [2.4.6.42])
+m4_define([LT_PACKAGE_VERSION], [2.4.6])
+m4_define([LT_PACKAGE_REVISION], [2.4.6])
 
 AC_DEFUN([LTVERSION_VERSION],
-[macro_version='2.4.6.42-b88ce'
-macro_revision='2.4.6.42'
+[macro_version='2.4.6'
+macro_revision='2.4.6'
 _LT_DECL(, macro_version, 0, [Which release of libtool.m4 was used?])
 _LT_DECL(, macro_revision, 0)
 ])
index 54ea1c4..c6b26f8 100644 (file)
@@ -1,6 +1,6 @@
 # lt~obsolete.m4 -- aclocal satisfying obsolete definitions.    -*-Autoconf-*-
 #
-#   Copyright (C) 2004-2005, 2007, 2009, 2011-2018 Free Software
+#   Copyright (C) 2004-2005, 2007, 2009, 2011-2015 Free Software
 #   Foundation, Inc.
 #   Written by Scott James Remnant, 2004.
 #
diff --git a/mingw-configure.sh b/mingw-configure.sh
new file mode 100755 (executable)
index 0000000..3281ce3
--- /dev/null
@@ -0,0 +1,28 @@
+#!/bin/sh
+
+case $1 in
+       i686 | x86_64) ;;
+       *) echo "Usage: $0 i686|x86_64" >&2; exit 1 ;;
+esac
+
+target=$1-w64-mingw32
+shift
+
+exec "$(dirname "$0")"/configure \
+       --build=`../config.guess` \
+       --host=$target \
+       --prefix=$HOME/.local/$target \
+       CC= \
+       CXX= \
+       CPP= \
+       LD= \
+       CFLAGS="-static-libgcc" \
+       CXXFLAGS="-static-libgcc -static-libstdc++" \
+       CPPFLAGS="-I$HOME/.local/$target/include" \
+       LDFLAGS=-L$HOME/.local/$target/lib \
+       PKG_CONFIG_LIBDIR=$HOME/.local/$target/lib/pkgconfig:/usr/$target/sys-root/mingw/lib/pkgconfig/ \
+       PKG_CONFIG_PATH=$HOME/.local/$target/share/pkgconfig:/usr/$target/sys-root/mingw/share/pkgconfig/ \
+       PATH=$HOME/.local/$target/bin:/usr/$target/sys-root/mingw/bin:/usr/$target/bin:$PATH \
+       --without-icu \
+       --with-uniscribe \
+       "$@"
diff --git a/mingw-ldd.py b/mingw-ldd.py
new file mode 100755 (executable)
index 0000000..1d659ef
--- /dev/null
@@ -0,0 +1,58 @@
+#!/usr/bin/env python
+
+# Copied from https://github.com/xantares/mingw-ldd/blob/master/mingw-ldd.py
+# Modified to point to right prefix location on Fedora.
+
+# WTFPL - Do What the Fuck You Want to Public License
+from __future__ import print_function
+import pefile
+import os
+import sys
+
+
+def get_dependency(filename):
+    deps = []
+    pe = pefile.PE(filename)
+    for imp in pe.DIRECTORY_ENTRY_IMPORT:
+        deps.append(imp.dll.decode())
+    return deps
+
+
+def dep_tree(root, prefix=None):
+    if not prefix:
+        arch = get_arch(root)
+        #print('Arch =', arch)
+        prefix = '/usr/'+arch+'-w64-mingw32/sys-root/mingw/bin'
+        #print('Using default prefix', prefix)
+    dep_dlls = dict()
+
+    def dep_tree_impl(root, prefix):
+        for dll in get_dependency(root):
+            if dll in dep_dlls:
+                continue
+            full_path = os.path.join(prefix, dll)
+            if os.path.exists(full_path):
+                dep_dlls[dll] = full_path
+                dep_tree_impl(full_path, prefix=prefix)
+            else:
+                dep_dlls[dll] = 'not found'
+
+    dep_tree_impl(root, prefix)
+    return (dep_dlls)
+
+
+def get_arch(filename):
+    type2arch= {pefile.OPTIONAL_HEADER_MAGIC_PE: 'i686',
+                pefile.OPTIONAL_HEADER_MAGIC_PE_PLUS: 'x86_64'}
+    pe = pefile.PE(filename)
+    try:
+        return type2arch[pe.PE_TYPE]
+    except KeyError:
+        sys.stderr.write('Error: unknown architecture')
+        sys.exit(1)
+
+if __name__ == '__main__':
+    filename = sys.argv[1]
+    for dll, full_path in dep_tree(filename).items():
+        print(' ' * 7, dll, '=>', full_path)
+
diff --git a/mingw32.sh b/mingw32.sh
new file mode 100755 (executable)
index 0000000..77edffa
--- /dev/null
@@ -0,0 +1,2 @@
+#!/bin/sh
+exec "$(dirname "$0")"/mingw-configure.sh i686 "$@"
diff --git a/mingw64.sh b/mingw64.sh
new file mode 100755 (executable)
index 0000000..28724a4
--- /dev/null
@@ -0,0 +1,2 @@
+#!/bin/sh
+exec "$(dirname "$0")"/mingw-configure.sh x86_64 "$@"
index 4a130e1..a76d968 100644 (file)
@@ -12,9 +12,15 @@ DISTCHECK_CONFIGURE_FLAGS = --enable-introspection
 TESTS =
 check_PROGRAMS =
 
+EXTRA_DIST += harfbuzz.cc
+
 # Convenience targets:
 lib: $(BUILT_SOURCES) libharfbuzz.la
 libs: $(BUILT_SOURCES) $(lib_LTLIBRARIES)
+tiny:
+       $(MAKE) $(AM_MAKEFLAGS) CPPFLAGS="-Os -DHB_TINY $(CPPFLAGS)" libs
+tinyz:
+       $(MAKE) $(AM_MAKEFLAGS) CPPFLAGS="-Oz -DHB_TINY $(CPPFLAGS)" libs
 
 lib_LTLIBRARIES = libharfbuzz.la
 
@@ -28,10 +34,6 @@ HBSOURCES =  $(HB_BASE_sources)
 HBSOURCES += $(HB_BASE_RAGEL_GENERATED_sources)
 HBHEADERS = $(HB_BASE_headers)
 
-if HAVE_FALLBACK
-HBSOURCES += $(HB_FALLBACK_sources)
-endif
-
 if HAVE_PTHREAD
 HBCFLAGS += $(PTHREAD_CFLAGS)
 HBNONPCLIBS += $(PTHREAD_LIBS)
@@ -80,6 +82,13 @@ HBSOURCES += $(HB_DIRECTWRITE_sources)
 HBHEADERS += $(HB_DIRECTWRITE_headers)
 endif
 
+if HAVE_GDI
+HBCFLAGS += $(GDI_CXXFLAGS)
+HBNONPCLIBS += $(GDI_LIBS)
+HBSOURCES += $(HB_GDI_sources)
+HBHEADERS += $(HB_GDI_headers)
+endif
+
 if HAVE_CORETEXT
 HBCFLAGS += $(CORETEXT_CFLAGS)
 HBNONPCLIBS += $(CORETEXT_LIBS)
@@ -87,17 +96,6 @@ HBSOURCES += $(HB_CORETEXT_sources)
 HBHEADERS += $(HB_CORETEXT_headers)
 endif
 
-if HAVE_UCDN
-SUBDIRS += hb-ucdn
-HBCFLAGS += -I$(srcdir)/hb-ucdn
-HBLIBS   += hb-ucdn/libhb-ucdn.la
-HBSOURCES += $(HB_UCDN_sources)
-hb-ucdn/libhb-ucdn.la: ucdn
-ucdn:
-       @$(MAKE) $(AM_MAKEFLAGS) -C hb-ucdn
-endif
-DIST_SUBDIRS += hb-ucdn
-
 
 BUILT_SOURCES += \
        hb-version.h
@@ -258,36 +256,44 @@ GENERATORS = \
        gen-indic-table.py \
        gen-os2-unicode-ranges.py \
        gen-tag-table.py \
+       gen-ucd-table.py \
        gen-use-table.py \
        gen-vowel-constraints.py \
        $(NULL)
 EXTRA_DIST += $(GENERATORS)
 
-unicode-tables: arabic-table indic-table tag-table use-table emoji-table
+unicode-tables: \
+       arabic-table \
+       emoji-table \
+       indic-table \
+       tag-table \
+       ucd-table \
+       use-table \
+       emoji-table \
+       $(NULL)
 
 arabic-table: gen-arabic-table.py ArabicShaping.txt UnicodeData.txt Blocks.txt
        $(AM_V_GEN) $(builddir)/$^ > $(srcdir)/hb-ot-shape-complex-arabic-table.hh \
        || ($(RM) $(srcdir)/hb-ot-shape-complex-arabic-table.hh; false)
-
+emoji-table: gen-emoji-table.py emoji-data.txt
+       $(AM_V_GEN) $(builddir)/$^ > $(srcdir)/hb-unicode-emoji-table.hh \
+       || ($(RM) $(srcdir)/hb-unicode-emoji-table.hh; false)
 indic-table: gen-indic-table.py IndicSyllabicCategory.txt IndicPositionalCategory.txt Blocks.txt
        $(AM_V_GEN) $(builddir)/$^ > $(srcdir)/hb-ot-shape-complex-indic-table.cc \
        || ($(RM) $(srcdir)/hb-ot-shape-complex-indic-table.cc; false)
-
 tag-table: gen-tag-table.py languagetags language-subtag-registry
        $(AM_V_GEN) $(builddir)/$^ > $(srcdir)/hb-ot-tag-table.hh \
        || ($(RM) $(srcdir)/hb-ot-tag-table.hh; false)
-
+ucd-table: gen-ucd-table.py ucd.nounihan.grouped.zip hb-common.h
+       $(AM_V_GEN) $(builddir)/$^ > $(srcdir)/hb-ucd-table.hh \
+       || ($(RM) $(srcdir)/hb-ucd-table.hh; false)
 use-table: gen-use-table.py IndicSyllabicCategory.txt IndicPositionalCategory.txt UnicodeData.txt Blocks.txt
        $(AM_V_GEN) $(builddir)/$^ > $(srcdir)/hb-ot-shape-complex-use-table.cc \
        || ($(RM) $(srcdir)/hb-ot-shape-complex-use-table.cc; false)
-
 vowel-constraints: gen-vowel-constraints.py HBIndicVowelConstraints.txt Scripts.txt
        $(AM_V_GEN) $(builddir)/$^ > $(srcdir)/hb-ot-shape-complex-vowel-constraints.cc \
        || ($(RM) $(srcdir)/hb-ot-shape-complex-vowel-constraints.cc; false)
 
-emoji-table: gen-emoji-table.py emoji-data.txt
-       $(AM_V_GEN) $(builddir)/$^ > $(srcdir)/hb-unicode-emoji-table.hh \
-       || ($(RM) $(srcdir)/hb-unicode-emoji-table.hh; false)
 
 built-sources: $(BUILT_SOURCES)
 
@@ -306,13 +312,30 @@ $(srcdir)/%.hh: $(srcdir)/%.rl
        $(AM_V_GEN)(cd $(srcdir) && $(RAGEL) -e -F1 -o "$*.hh" "$*.rl") \
        || ($(RM) "$@"; false)
 
+harfbuzz.cc: Makefile.sources
+       $(AM_V_GEN) \
+       for f in \
+               $(HB_BASE_sources) \
+               $(HB_GLIB_sources) \
+               $(HB_FT_sources) \
+               $(HB_GRAPHITE2_sources) \
+               $(HB_UNISCRIBE_sources) \
+               $(HB_GDI_sources) \
+               $(HB_DIRECTWRITE_sources) \
+               $(HB_CORETEXT_sources) \
+               ; do echo '#include "'$$f'"'; done | \
+       grep '[.]cc"' > $(srcdir)/harfbuzz.cc \
+       || ($(RM) $(srcdir)/harfbuzz.cc; false)
+BUILT_SOURCES += harfbuzz.cc
+
 noinst_PROGRAMS = \
        main \
        test \
        test-buffer-serialize \
-       test-name-table \
-       test-size-params \
-       test-would-substitute \
+       test-ot-meta \
+       test-ot-name \
+       test-gpos-size-params \
+       test-gsub-would-substitute \
        $(NULL)
 bin_PROGRAMS =
 
@@ -328,17 +351,21 @@ test_buffer_serialize_SOURCES = test-buffer-serialize.cc
 test_buffer_serialize_CPPFLAGS = $(HBCFLAGS)
 test_buffer_serialize_LDADD = libharfbuzz.la $(HBLIBS)
 
-test_name_table_SOURCES = test-name-table.cc
-test_name_table_CPPFLAGS = $(HBCFLAGS)
-test_name_table_LDADD = libharfbuzz.la $(HBLIBS)
+test_ot_meta_SOURCES = test-ot-meta.cc
+test_ot_meta_CPPFLAGS = $(HBCFLAGS)
+test_ot_meta_LDADD = libharfbuzz.la $(HBLIBS)
+
+test_ot_name_SOURCES = test-ot-name.cc
+test_ot_name_CPPFLAGS = $(HBCFLAGS)
+test_ot_name_LDADD = libharfbuzz.la $(HBLIBS)
 
-test_size_params_SOURCES = test-size-params.cc
-test_size_params_CPPFLAGS = $(HBCFLAGS)
-test_size_params_LDADD = libharfbuzz.la $(HBLIBS)
+test_gpos_size_params_SOURCES = test-gpos-size-params.cc
+test_gpos_size_params_CPPFLAGS = $(HBCFLAGS)
+test_gpos_size_params_LDADD = libharfbuzz.la $(HBLIBS)
 
-test_would_substitute_SOURCES = test-would-substitute.cc
-test_would_substitute_CPPFLAGS = $(HBCFLAGS) $(FREETYPE_CFLAGS)
-test_would_substitute_LDADD = libharfbuzz.la $(HBLIBS) $(FREETYPE_LIBS)
+test_gsub_would_substitute_SOURCES = test-gsub-would-substitute.cc
+test_gsub_would_substitute_CPPFLAGS = $(HBCFLAGS) $(FREETYPE_CFLAGS)
+test_gsub_would_substitute_LDADD = libharfbuzz.la $(HBLIBS) $(FREETYPE_LIBS)
 
 if HAVE_FREETYPE
 if HAVE_CAIRO_FT
@@ -384,16 +411,28 @@ dump_use_data_SOURCES = dump-use-data.cc hb-ot-shape-complex-use-table.cc
 dump_use_data_CPPFLAGS = $(HBCFLAGS)
 dump_use_data_LDADD = libharfbuzz.la $(HBLIBS)
 
-COMPILED_TESTS = test-iter test-ot-tag test-unicode-ranges
+COMPILED_TESTS = test-algs test-iter test-meta test-number test-ot-tag test-unicode-ranges test-bimap
 COMPILED_TESTS_CPPFLAGS = $(HBCFLAGS) -DMAIN -UNDEBUG
 COMPILED_TESTS_LDADD = libharfbuzz.la $(HBLIBS)
 check_PROGRAMS += $(COMPILED_TESTS)
 TESTS += $(COMPILED_TESTS)
 
+test_algs_SOURCES = test-algs.cc hb-static.cc
+test_algs_CPPFLAGS = $(COMPILED_TESTS_CPPFLAGS)
+test_algs_LDADD = $(COMPILED_TESTS_LDADD)
+
 test_iter_SOURCES = test-iter.cc hb-static.cc
 test_iter_CPPFLAGS = $(COMPILED_TESTS_CPPFLAGS)
 test_iter_LDADD = $(COMPILED_TESTS_LDADD)
 
+test_meta_SOURCES = test-meta.cc hb-static.cc
+test_meta_CPPFLAGS = $(COMPILED_TESTS_CPPFLAGS)
+test_meta_LDADD = $(COMPILED_TESTS_LDADD)
+
+test_number_SOURCES = test-number.cc hb-number.cc
+test_number_CPPFLAGS = $(COMPILED_TESTS_CPPFLAGS)
+test_number_LDADD = $(COMPILED_TESTS_LDADD)
+
 test_ot_tag_SOURCES = hb-ot-tag.cc
 test_ot_tag_CPPFLAGS = $(COMPILED_TESTS_CPPFLAGS)
 test_ot_tag_LDADD = $(COMPILED_TESTS_LDADD)
@@ -402,6 +441,10 @@ test_unicode_ranges_SOURCES = test-unicode-ranges.cc
 test_unicode_ranges_CPPFLAGS = $(COMPILED_TESTS_CPPFLAGS)
 test_unicode_ranges_LDADD = $(COMPILED_TESTS_LDADD)
 
+test_bimap_SOURCES = test-bimap.cc hb-static.cc
+test_bimap_CPPFLAGS = $(COMPILED_TESTS_CPPFLAGS)
+test_bimap_LDADD = $(COMPILED_TESTS_LDADD)
+
 TESTS_ENVIRONMENT = \
        srcdir="$(srcdir)" \
        MAKE="$(MAKE) $(AM_MAKEFLAGS)" \
@@ -430,6 +473,7 @@ HarfBuzz_0_0_gir_CFLAGS = \
        -DHB_AAT_H_IN \
        -DHB_GOBJECT_H \
        -DHB_GOBJECT_H_IN \
+       -DHAVE_GOBJECT \
        -DHB_EXTERN= \
        $(NULL)
 HarfBuzz_0_0_gir_LIBS = \
index 9614bb0..1e83d38 100644 (file)
@@ -99,82 +99,83 @@ TESTS = $(am__EXEEXT_5) $(am__EXEEXT_2)
 check_PROGRAMS = dump-indic-data$(EXEEXT) dump-khmer-data$(EXEEXT) \
        dump-myanmar-data$(EXEEXT) dump-use-data$(EXEEXT) \
        $(am__EXEEXT_1) $(am__EXEEXT_2)
-@HAVE_FALLBACK_TRUE@am__append_1 = $(HB_FALLBACK_sources)
-@HAVE_PTHREAD_TRUE@am__append_2 = $(PTHREAD_CFLAGS)
-@HAVE_PTHREAD_TRUE@am__append_3 = $(PTHREAD_LIBS)
-@HAVE_GLIB_TRUE@am__append_4 = $(GLIB_CFLAGS)
-@HAVE_GLIB_TRUE@am__append_5 = $(GLIB_LIBS)
-@HAVE_GLIB_TRUE@am__append_6 = $(GLIB_DEPS)
-@HAVE_GLIB_TRUE@am__append_7 = $(HB_GLIB_sources)
-@HAVE_GLIB_TRUE@am__append_8 = $(HB_GLIB_headers)
-@HAVE_FREETYPE_TRUE@am__append_9 = $(FREETYPE_CFLAGS)
-@HAVE_FREETYPE_TRUE@am__append_10 = $(FREETYPE_LIBS)
+@HAVE_PTHREAD_TRUE@am__append_1 = $(PTHREAD_CFLAGS)
+@HAVE_PTHREAD_TRUE@am__append_2 = $(PTHREAD_LIBS)
+@HAVE_GLIB_TRUE@am__append_3 = $(GLIB_CFLAGS)
+@HAVE_GLIB_TRUE@am__append_4 = $(GLIB_LIBS)
+@HAVE_GLIB_TRUE@am__append_5 = $(GLIB_DEPS)
+@HAVE_GLIB_TRUE@am__append_6 = $(HB_GLIB_sources)
+@HAVE_GLIB_TRUE@am__append_7 = $(HB_GLIB_headers)
+@HAVE_FREETYPE_TRUE@am__append_8 = $(FREETYPE_CFLAGS)
+@HAVE_FREETYPE_TRUE@am__append_9 = $(FREETYPE_LIBS)
 # XXX
 # The following creates a recursive dependency on FreeType if FreeType is
 # built with HarfBuzz support enabled.  Newer pkg-config handles that just
 # fine but pkg-config 0.26 as shipped in Ubuntu 14.04 crashes.  Remove
 # in a year or two, or otherwise work around it...
 #HBDEPS   += $(FREETYPE_DEPS)
-@HAVE_FREETYPE_TRUE@am__append_11 = $(HB_FT_sources)
-@HAVE_FREETYPE_TRUE@am__append_12 = $(HB_FT_headers)
-@HAVE_GRAPHITE2_TRUE@am__append_13 = $(GRAPHITE2_CFLAGS)
-@HAVE_GRAPHITE2_TRUE@am__append_14 = $(GRAPHITE2_LIBS)
-@HAVE_GRAPHITE2_TRUE@am__append_15 = $(GRAPHITE2_DEPS)
-@HAVE_GRAPHITE2_TRUE@am__append_16 = $(HB_GRAPHITE2_sources)
-@HAVE_GRAPHITE2_TRUE@am__append_17 = $(HB_GRAPHITE2_headers)
-@HAVE_UNISCRIBE_TRUE@am__append_18 = $(UNISCRIBE_CFLAGS)
-@HAVE_UNISCRIBE_TRUE@am__append_19 = $(UNISCRIBE_LIBS)
-@HAVE_UNISCRIBE_TRUE@am__append_20 = $(HB_UNISCRIBE_sources)
-@HAVE_UNISCRIBE_TRUE@am__append_21 = $(HB_UNISCRIBE_headers)
-@HAVE_DIRECTWRITE_TRUE@am__append_22 = $(DIRECTWRITE_CXXFLAGS)
-@HAVE_DIRECTWRITE_TRUE@am__append_23 = $(DIRECTWRITE_LIBS)
-@HAVE_DIRECTWRITE_TRUE@am__append_24 = $(HB_DIRECTWRITE_sources)
-@HAVE_DIRECTWRITE_TRUE@am__append_25 = $(HB_DIRECTWRITE_headers)
-@HAVE_CORETEXT_TRUE@am__append_26 = $(CORETEXT_CFLAGS)
-@HAVE_CORETEXT_TRUE@am__append_27 = $(CORETEXT_LIBS)
-@HAVE_CORETEXT_TRUE@am__append_28 = $(HB_CORETEXT_sources)
-@HAVE_CORETEXT_TRUE@am__append_29 = $(HB_CORETEXT_headers)
-@HAVE_UCDN_TRUE@am__append_30 = hb-ucdn
-@HAVE_UCDN_TRUE@am__append_31 = -I$(srcdir)/hb-ucdn
-@HAVE_UCDN_TRUE@am__append_32 = hb-ucdn/libhb-ucdn.la
-@HAVE_UCDN_TRUE@am__append_33 = $(HB_UCDN_sources)
-@HAVE_ICU_BUILTIN_TRUE@@HAVE_ICU_TRUE@am__append_34 = $(ICU_CFLAGS)
-@HAVE_ICU_BUILTIN_TRUE@@HAVE_ICU_TRUE@am__append_35 = $(ICU_LIBS)
-@HAVE_ICU_BUILTIN_TRUE@@HAVE_ICU_TRUE@am__append_36 = $(HB_ICU_sources)
-@HAVE_ICU_BUILTIN_TRUE@@HAVE_ICU_TRUE@am__append_37 = $(HB_ICU_headers)
-@HAVE_ICU_BUILTIN_FALSE@@HAVE_ICU_TRUE@am__append_38 = libharfbuzz-icu.la
-@HAVE_ICU_BUILTIN_FALSE@@HAVE_ICU_TRUE@am__append_39 = $(HB_ICU_headers)
-@HAVE_ICU_BUILTIN_FALSE@@HAVE_ICU_TRUE@am__append_40 = harfbuzz-icu.pc
-@HAVE_GOBJECT_TRUE@am__append_41 = libharfbuzz-gobject.la
-@HAVE_GOBJECT_TRUE@am__append_42 = $(HB_GOBJECT_DIST_headers)
-@HAVE_GOBJECT_TRUE@am__append_43 = $(HB_GOBJECT_NODIST_headers)
-@HAVE_GOBJECT_TRUE@am__append_44 = harfbuzz-gobject.pc
-@HAVE_GOBJECT_TRUE@am__append_45 = \
+@HAVE_FREETYPE_TRUE@am__append_10 = $(HB_FT_sources)
+@HAVE_FREETYPE_TRUE@am__append_11 = $(HB_FT_headers)
+@HAVE_GRAPHITE2_TRUE@am__append_12 = $(GRAPHITE2_CFLAGS)
+@HAVE_GRAPHITE2_TRUE@am__append_13 = $(GRAPHITE2_LIBS)
+@HAVE_GRAPHITE2_TRUE@am__append_14 = $(GRAPHITE2_DEPS)
+@HAVE_GRAPHITE2_TRUE@am__append_15 = $(HB_GRAPHITE2_sources)
+@HAVE_GRAPHITE2_TRUE@am__append_16 = $(HB_GRAPHITE2_headers)
+@HAVE_UNISCRIBE_TRUE@am__append_17 = $(UNISCRIBE_CFLAGS)
+@HAVE_UNISCRIBE_TRUE@am__append_18 = $(UNISCRIBE_LIBS)
+@HAVE_UNISCRIBE_TRUE@am__append_19 = $(HB_UNISCRIBE_sources)
+@HAVE_UNISCRIBE_TRUE@am__append_20 = $(HB_UNISCRIBE_headers)
+@HAVE_DIRECTWRITE_TRUE@am__append_21 = $(DIRECTWRITE_CXXFLAGS)
+@HAVE_DIRECTWRITE_TRUE@am__append_22 = $(DIRECTWRITE_LIBS)
+@HAVE_DIRECTWRITE_TRUE@am__append_23 = $(HB_DIRECTWRITE_sources)
+@HAVE_DIRECTWRITE_TRUE@am__append_24 = $(HB_DIRECTWRITE_headers)
+@HAVE_GDI_TRUE@am__append_25 = $(GDI_CXXFLAGS)
+@HAVE_GDI_TRUE@am__append_26 = $(GDI_LIBS)
+@HAVE_GDI_TRUE@am__append_27 = $(HB_GDI_sources)
+@HAVE_GDI_TRUE@am__append_28 = $(HB_GDI_headers)
+@HAVE_CORETEXT_TRUE@am__append_29 = $(CORETEXT_CFLAGS)
+@HAVE_CORETEXT_TRUE@am__append_30 = $(CORETEXT_LIBS)
+@HAVE_CORETEXT_TRUE@am__append_31 = $(HB_CORETEXT_sources)
+@HAVE_CORETEXT_TRUE@am__append_32 = $(HB_CORETEXT_headers)
+@HAVE_ICU_BUILTIN_TRUE@@HAVE_ICU_TRUE@am__append_33 = $(ICU_CFLAGS)
+@HAVE_ICU_BUILTIN_TRUE@@HAVE_ICU_TRUE@am__append_34 = $(ICU_LIBS)
+@HAVE_ICU_BUILTIN_TRUE@@HAVE_ICU_TRUE@am__append_35 = $(HB_ICU_sources)
+@HAVE_ICU_BUILTIN_TRUE@@HAVE_ICU_TRUE@am__append_36 = $(HB_ICU_headers)
+@HAVE_ICU_BUILTIN_FALSE@@HAVE_ICU_TRUE@am__append_37 = libharfbuzz-icu.la
+@HAVE_ICU_BUILTIN_FALSE@@HAVE_ICU_TRUE@am__append_38 = $(HB_ICU_headers)
+@HAVE_ICU_BUILTIN_FALSE@@HAVE_ICU_TRUE@am__append_39 = harfbuzz-icu.pc
+@HAVE_GOBJECT_TRUE@am__append_40 = libharfbuzz-gobject.la
+@HAVE_GOBJECT_TRUE@am__append_41 = $(HB_GOBJECT_DIST_headers)
+@HAVE_GOBJECT_TRUE@am__append_42 = $(HB_GOBJECT_NODIST_headers)
+@HAVE_GOBJECT_TRUE@am__append_43 = harfbuzz-gobject.pc
+@HAVE_GOBJECT_TRUE@am__append_44 = \
 @HAVE_GOBJECT_TRUE@    $(HB_GOBJECT_ENUM_sources) \
 @HAVE_GOBJECT_TRUE@    $(HB_GOBJECT_ENUM_headers) \
 @HAVE_GOBJECT_TRUE@    $(NULL)
 
-@HAVE_GOBJECT_TRUE@am__append_46 = \
+@HAVE_GOBJECT_TRUE@am__append_45 = \
 @HAVE_GOBJECT_TRUE@    $(HB_GOBJECT_ENUM_sources) \
 @HAVE_GOBJECT_TRUE@    $(HB_GOBJECT_ENUM_headers) \
 @HAVE_GOBJECT_TRUE@    $(NULL)
 
-@HAVE_GOBJECT_TRUE@am__append_47 = harfbuzz-gobject.def
+@HAVE_GOBJECT_TRUE@am__append_46 = harfbuzz-gobject.def
 noinst_PROGRAMS = main$(EXEEXT) test$(EXEEXT) \
-       test-buffer-serialize$(EXEEXT) test-name-table$(EXEEXT) \
-       test-size-params$(EXEEXT) test-would-substitute$(EXEEXT) \
-       $(am__EXEEXT_1) $(am__EXEEXT_3)
+       test-buffer-serialize$(EXEEXT) test-ot-meta$(EXEEXT) \
+       test-ot-name$(EXEEXT) test-gpos-size-params$(EXEEXT) \
+       test-gsub-would-substitute$(EXEEXT) $(am__EXEEXT_1) \
+       $(am__EXEEXT_3)
 bin_PROGRAMS =
-@HAVE_CAIRO_FT_TRUE@@HAVE_FREETYPE_TRUE@am__append_48 = test-ot-color
-@WITH_LIBSTDCXX_FALSE@am__append_49 = \
+@HAVE_CAIRO_FT_TRUE@@HAVE_FREETYPE_TRUE@am__append_47 = test-ot-color
+@WITH_LIBSTDCXX_FALSE@am__append_48 = \
 @WITH_LIBSTDCXX_FALSE@ check-libstdc++.sh \
 @WITH_LIBSTDCXX_FALSE@ $(NULL)
 
-@HAVE_INTROSPECTION_TRUE@am__append_50 = $(gir_DATA) $(typelib_DATA)
+@HAVE_INTROSPECTION_TRUE@am__append_49 = $(gir_DATA) $(typelib_DATA)
 subdir = src
 ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
 am__aclocal_m4_deps = $(top_srcdir)/m4/ax_check_link_flag.m4 \
        $(top_srcdir)/m4/ax_code_coverage.m4 \
+       $(top_srcdir)/m4/ax_cxx_compile_stdcxx.m4 \
        $(top_srcdir)/m4/ax_pthread.m4 $(top_srcdir)/m4/gtk-doc.m4 \
        $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \
        $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \
@@ -192,8 +193,9 @@ am__installdirs = "$(DESTDIR)$(bindir)" "$(DESTDIR)$(libdir)" \
        "$(DESTDIR)$(pkgconfigdir)" "$(DESTDIR)$(typelibdir)" \
        "$(DESTDIR)$(pkgincludedir)" "$(DESTDIR)$(pkgincludedir)"
 am__EXEEXT_1 =
-am__EXEEXT_2 = test-iter$(EXEEXT) test-ot-tag$(EXEEXT) \
-       test-unicode-ranges$(EXEEXT)
+am__EXEEXT_2 = test-algs$(EXEEXT) test-iter$(EXEEXT) \
+       test-meta$(EXEEXT) test-number$(EXEEXT) test-ot-tag$(EXEEXT) \
+       test-unicode-ranges$(EXEEXT) test-bimap$(EXEEXT)
 @HAVE_CAIRO_FT_TRUE@@HAVE_FREETYPE_TRUE@am__EXEEXT_3 = test-ot-color$(EXEEXT)
 PROGRAMS = $(bin_PROGRAMS) $(noinst_PROGRAMS)
 am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
@@ -258,13 +260,13 @@ libharfbuzz_icu_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX \
 @HAVE_ICU_BUILTIN_FALSE@@HAVE_ICU_TRUE@        -rpath $(libdir)
 libharfbuzz_subset_la_DEPENDENCIES = libharfbuzz.la
 am__objects_5 =
-am__objects_6 = libharfbuzz_subset_la-hb-ot-cff1-table.lo \
+am__objects_6 = libharfbuzz_subset_la-hb-number.lo \
+       libharfbuzz_subset_la-hb-ot-cff1-table.lo \
        libharfbuzz_subset_la-hb-ot-cff2-table.lo \
        libharfbuzz_subset_la-hb-static.lo \
        libharfbuzz_subset_la-hb-subset-cff-common.lo \
        libharfbuzz_subset_la-hb-subset-cff1.lo \
        libharfbuzz_subset_la-hb-subset-cff2.lo \
-       libharfbuzz_subset_la-hb-subset-glyf.lo \
        libharfbuzz_subset_la-hb-subset-input.lo \
        libharfbuzz_subset_la-hb-subset-plan.lo \
        libharfbuzz_subset_la-hb-subset.lo $(am__objects_5)
@@ -280,35 +282,40 @@ libharfbuzz_subset_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX \
 @HAVE_PTHREAD_TRUE@am__DEPENDENCIES_5 = $(am__DEPENDENCIES_1)
 @HAVE_UNISCRIBE_TRUE@am__DEPENDENCIES_6 = $(am__DEPENDENCIES_1)
 @HAVE_DIRECTWRITE_TRUE@am__DEPENDENCIES_7 = $(am__DEPENDENCIES_1)
-@HAVE_CORETEXT_TRUE@am__DEPENDENCIES_8 = $(am__DEPENDENCIES_1)
-am__DEPENDENCIES_9 = $(am__DEPENDENCIES_5) $(am__DEPENDENCIES_6) \
-       $(am__DEPENDENCIES_7) $(am__DEPENDENCIES_8)
-@HAVE_ICU_BUILTIN_TRUE@@HAVE_ICU_TRUE@am__DEPENDENCIES_10 =  \
+@HAVE_GDI_TRUE@am__DEPENDENCIES_8 = $(am__DEPENDENCIES_1)
+@HAVE_CORETEXT_TRUE@am__DEPENDENCIES_9 = $(am__DEPENDENCIES_1)
+am__DEPENDENCIES_10 = $(am__DEPENDENCIES_5) $(am__DEPENDENCIES_6) \
+       $(am__DEPENDENCIES_7) $(am__DEPENDENCIES_8) \
+       $(am__DEPENDENCIES_9)
+@HAVE_ICU_BUILTIN_TRUE@@HAVE_ICU_TRUE@am__DEPENDENCIES_11 =  \
 @HAVE_ICU_BUILTIN_TRUE@@HAVE_ICU_TRUE@ $(am__DEPENDENCIES_1)
-am__DEPENDENCIES_11 = $(am__DEPENDENCIES_2) $(am__DEPENDENCIES_3) \
-       $(am__DEPENDENCIES_4) $(am__append_32) $(am__DEPENDENCIES_9) \
-       $(am__DEPENDENCIES_10)
-libharfbuzz_la_DEPENDENCIES = $(am__DEPENDENCIES_11)
+am__DEPENDENCIES_12 = $(am__DEPENDENCIES_2) $(am__DEPENDENCIES_3) \
+       $(am__DEPENDENCIES_4) $(am__DEPENDENCIES_10) \
+       $(am__DEPENDENCIES_11)
+libharfbuzz_la_DEPENDENCIES = $(am__DEPENDENCIES_12)
 am__libharfbuzz_la_SOURCES_DIST = hb-aat-fdsc-table.hh \
        hb-aat-layout-ankr-table.hh hb-aat-layout-bsln-table.hh \
        hb-aat-layout-common.hh hb-aat-layout-feat-table.hh \
        hb-aat-layout-just-table.hh hb-aat-layout-kerx-table.hh \
        hb-aat-layout-lcar-table.hh hb-aat-layout-morx-table.hh \
-       hb-aat-layout-trak-table.hh hb-aat-layout.cc hb-aat-layout.hh \
-       hb-aat-ltag-table.hh hb-aat-map.cc hb-aat-map.hh hb-array.hh \
+       hb-aat-layout-opbd-table.hh hb-aat-layout-trak-table.hh \
+       hb-aat-layout.cc hb-aat-layout.hh hb-aat-ltag-table.hh \
+       hb-aat-map.cc hb-aat-map.hh hb-algs.hh hb-array.hh \
        hb-atomic.hh hb-blob.cc hb-blob.hh hb-buffer-serialize.cc \
        hb-buffer.cc hb-buffer.hh hb-cache.hh hb-cff-interp-common.hh \
        hb-cff-interp-cs-common.hh hb-cff-interp-dict-common.hh \
        hb-cff1-interp-cs.hh hb-cff2-interp-cs.hh hb-common.cc \
-       hb-debug.hh hb-dsalgs.hh hb-face.cc hb-face.hh hb-font.cc \
-       hb-font.hh hb-iter.hh hb-kern.hh hb-machinery.hh hb-map.cc \
-       hb-map.hh hb-mutex.hh hb-null.hh hb-object.hh hb-open-file.hh \
-       hb-open-type.hh hb-ot-cff-common.hh hb-ot-cff1-table.cc \
-       hb-ot-cff1-table.hh 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.cc hb-ot-face.hh hb-ot-font.cc \
+       hb-config.hh hb-debug.hh hb-dispatch.hh hb-face.cc hb-face.hh \
+       hb-fallback-shape.cc hb-font.cc hb-font.hh hb-iter.hh \
+       hb-kern.hh hb-machinery.hh hb-map.cc hb-map.hh hb-bimap.hh \
+       hb-meta.hh hb-mutex.hh hb-null.hh hb-number.cc hb-number.hh \
+       hb-object.hh hb-open-file.hh hb-open-type.hh \
+       hb-ot-cff-common.hh hb-ot-cff1-table.cc hb-ot-cff1-table.hh \
+       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.cc \
+       hb-ot-face.hh hb-ot-face-table-list.hh hb-ot-font.cc \
        hb-ot-gasp-table.hh hb-ot-glyf-table.hh hb-ot-hdmx-table.hh \
        hb-ot-head-table.hh hb-ot-hhea-table.hh hb-ot-hmtx-table.hh \
        hb-ot-kern-table.hh hb-ot-layout-base-table.hh \
@@ -317,10 +324,12 @@ am__libharfbuzz_la_SOURCES_DIST = hb-aat-fdsc-table.hh \
        hb-ot-layout-gsubgpos.hh hb-ot-layout-jstf-table.hh \
        hb-ot-layout.cc hb-ot-layout.hh hb-ot-map.cc hb-ot-map.hh \
        hb-ot-math-table.hh hb-ot-math.cc hb-ot-maxp-table.hh \
-       hb-ot-name-language.cc hb-ot-name-language.hh \
-       hb-ot-name-table.hh hb-ot-name.cc hb-ot-os2-table.hh \
-       hb-ot-os2-unicode-ranges.hh hb-ot-post-macroman.hh \
-       hb-ot-post-table.hh hb-ot-shape-complex-arabic-fallback.hh \
+       hb-ot-meta-table.hh hb-ot-meta.cc hb-ot-metrics.cc \
+       hb-ot-metrics.hh hb-ot-name-language-static.hh \
+       hb-ot-name-language.hh hb-ot-name-table.hh hb-ot-name.cc \
+       hb-ot-os2-table.hh hb-ot-os2-unicode-ranges.hh \
+       hb-ot-post-macroman.hh hb-ot-post-table.hh \
+       hb-ot-shape-complex-arabic-fallback.hh \
        hb-ot-shape-complex-arabic-table.hh \
        hb-ot-shape-complex-arabic-win1256.hh \
        hb-ot-shape-complex-arabic.cc hb-ot-shape-complex-arabic.hh \
@@ -339,38 +348,40 @@ am__libharfbuzz_la_SOURCES_DIST = hb-aat-fdsc-table.hh \
        hb-ot-shape-normalize.hh hb-ot-shape.cc hb-ot-shape.hh \
        hb-ot-stat-table.hh hb-ot-tag-table.hh hb-ot-tag.cc \
        hb-ot-var-avar-table.hh hb-ot-var-fvar-table.hh \
-       hb-ot-var-hvar-table.hh hb-ot-var-mvar-table.hh hb-ot-var.cc \
-       hb-ot-vorg-table.hh hb-set-digest.hh hb-set.cc hb-set.hh \
-       hb-shape-plan.cc hb-shape-plan.hh hb-shape.cc \
-       hb-shaper-impl.hh hb-shaper-list.hh hb-shaper.cc hb-shaper.hh \
-       hb-static.cc hb-string-array.hh hb-unicode-emoji-table.hh \
-       hb-unicode.cc hb-unicode.hh hb-utf.hh hb-vector.hh \
-       hb-warning.cc hb.hh hb-buffer-deserialize-json.hh \
-       hb-buffer-deserialize-text.hh \
-       hb-ot-shape-complex-indic-machine.hh \
+       hb-ot-var-gvar-table.hh hb-ot-var-hvar-table.hh \
+       hb-ot-var-mvar-table.hh hb-ot-var.cc hb-ot-vorg-table.hh \
+       hb-pool.hh hb-sanitize.hh hb-serialize.hh hb-set-digest.hh \
+       hb-set.cc hb-set.hh hb-shape-plan.cc hb-shape-plan.hh \
+       hb-shape.cc hb-shaper-impl.hh hb-shaper-list.hh hb-shaper.cc \
+       hb-shaper.hh hb-static.cc hb-string-array.hh hb-ucd-table.hh \
+       hb-ucd.cc hb-unicode-emoji-table.hh hb-unicode.cc \
+       hb-unicode.hh hb-utf.hh hb-vector.hh hb.hh \
+       hb-buffer-deserialize-json.hh hb-buffer-deserialize-text.hh \
+       hb-number-parser.hh hb-ot-shape-complex-indic-machine.hh \
        hb-ot-shape-complex-khmer-machine.hh \
        hb-ot-shape-complex-myanmar-machine.hh \
-       hb-ot-shape-complex-use-machine.hh hb-fallback-shape.cc \
-       hb-glib.cc hb-ft.cc hb-graphite2.cc hb-uniscribe.cc \
-       hb-directwrite.cc hb-coretext.cc hb-ucdn.cc hb-icu.cc \
-       hb-aat-layout.h hb-aat.h hb-blob.h hb-buffer.h hb-common.h \
-       hb-deprecated.h hb-face.h hb-font.h hb-map.h hb-ot-color.h \
-       hb-ot-deprecated.h hb-ot-font.h hb-ot-layout.h hb-ot-math.h \
+       hb-ot-shape-complex-use-machine.hh hb-glib.cc hb-ft.cc \
+       hb-graphite2.cc hb-uniscribe.cc hb-directwrite.cc hb-gdi.cc \
+       hb-coretext.cc hb-icu.cc hb-aat-layout.h hb-aat.h hb-blob.h \
+       hb-buffer.h hb-common.h hb-deprecated.h hb-face.h hb-font.h \
+       hb-map.h hb-ot-color.h hb-ot-deprecated.h hb-ot-font.h \
+       hb-ot-layout.h hb-ot-math.h hb-ot-meta.h hb-ot-metrics.h \
        hb-ot-name.h hb-ot-shape.h hb-ot-var.h hb-ot.h hb-set.h \
        hb-shape-plan.h hb-shape.h hb-unicode.h hb-version.h hb.h \
        hb-glib.h hb-ft.h hb-graphite2.h hb-uniscribe.h \
-       hb-directwrite.h hb-coretext.h hb-icu.h
+       hb-directwrite.h hb-gdi.h hb-coretext.h hb-icu.h
 am__objects_7 = libharfbuzz_la-hb-aat-layout.lo \
        libharfbuzz_la-hb-aat-map.lo libharfbuzz_la-hb-blob.lo \
        libharfbuzz_la-hb-buffer-serialize.lo \
        libharfbuzz_la-hb-buffer.lo libharfbuzz_la-hb-common.lo \
-       libharfbuzz_la-hb-face.lo libharfbuzz_la-hb-font.lo \
-       libharfbuzz_la-hb-map.lo libharfbuzz_la-hb-ot-cff1-table.lo \
+       libharfbuzz_la-hb-face.lo libharfbuzz_la-hb-fallback-shape.lo \
+       libharfbuzz_la-hb-font.lo libharfbuzz_la-hb-map.lo \
+       libharfbuzz_la-hb-number.lo libharfbuzz_la-hb-ot-cff1-table.lo \
        libharfbuzz_la-hb-ot-cff2-table.lo \
        libharfbuzz_la-hb-ot-color.lo libharfbuzz_la-hb-ot-face.lo \
        libharfbuzz_la-hb-ot-font.lo libharfbuzz_la-hb-ot-layout.lo \
        libharfbuzz_la-hb-ot-map.lo libharfbuzz_la-hb-ot-math.lo \
-       libharfbuzz_la-hb-ot-name-language.lo \
+       libharfbuzz_la-hb-ot-meta.lo libharfbuzz_la-hb-ot-metrics.lo \
        libharfbuzz_la-hb-ot-name.lo \
        libharfbuzz_la-hb-ot-shape-complex-arabic.lo \
        libharfbuzz_la-hb-ot-shape-complex-default.lo \
@@ -390,110 +401,128 @@ am__objects_7 = libharfbuzz_la-hb-aat-layout.lo \
        libharfbuzz_la-hb-ot-var.lo libharfbuzz_la-hb-set.lo \
        libharfbuzz_la-hb-shape-plan.lo libharfbuzz_la-hb-shape.lo \
        libharfbuzz_la-hb-shaper.lo libharfbuzz_la-hb-static.lo \
-       libharfbuzz_la-hb-unicode.lo libharfbuzz_la-hb-warning.lo \
+       libharfbuzz_la-hb-ucd.lo libharfbuzz_la-hb-unicode.lo \
        $(am__objects_5)
 am__objects_8 = $(am__objects_5)
-am__objects_9 = libharfbuzz_la-hb-fallback-shape.lo $(am__objects_5)
-@HAVE_FALLBACK_TRUE@am__objects_10 = $(am__objects_9)
-am__objects_11 = libharfbuzz_la-hb-glib.lo
-@HAVE_GLIB_TRUE@am__objects_12 = $(am__objects_11)
-am__objects_13 = libharfbuzz_la-hb-ft.lo
-@HAVE_FREETYPE_TRUE@am__objects_14 = $(am__objects_13)
-am__objects_15 = libharfbuzz_la-hb-graphite2.lo
-@HAVE_GRAPHITE2_TRUE@am__objects_16 = $(am__objects_15)
-am__objects_17 = libharfbuzz_la-hb-uniscribe.lo
-@HAVE_UNISCRIBE_TRUE@am__objects_18 = $(am__objects_17)
-am__objects_19 = libharfbuzz_la-hb-directwrite.lo
-@HAVE_DIRECTWRITE_TRUE@am__objects_20 = $(am__objects_19)
+am__objects_9 = libharfbuzz_la-hb-glib.lo
+@HAVE_GLIB_TRUE@am__objects_10 = $(am__objects_9)
+am__objects_11 = libharfbuzz_la-hb-ft.lo
+@HAVE_FREETYPE_TRUE@am__objects_12 = $(am__objects_11)
+am__objects_13 = libharfbuzz_la-hb-graphite2.lo
+@HAVE_GRAPHITE2_TRUE@am__objects_14 = $(am__objects_13)
+am__objects_15 = libharfbuzz_la-hb-uniscribe.lo
+@HAVE_UNISCRIBE_TRUE@am__objects_16 = $(am__objects_15)
+am__objects_17 = libharfbuzz_la-hb-directwrite.lo
+@HAVE_DIRECTWRITE_TRUE@am__objects_18 = $(am__objects_17)
+am__objects_19 = libharfbuzz_la-hb-gdi.lo
+@HAVE_GDI_TRUE@am__objects_20 = $(am__objects_19)
 am__objects_21 = libharfbuzz_la-hb-coretext.lo
 @HAVE_CORETEXT_TRUE@am__objects_22 = $(am__objects_21)
-am__objects_23 = libharfbuzz_la-hb-ucdn.lo
-@HAVE_UCDN_TRUE@am__objects_24 = $(am__objects_23)
-am__objects_25 = libharfbuzz_la-hb-icu.lo
-@HAVE_ICU_BUILTIN_TRUE@@HAVE_ICU_TRUE@am__objects_26 =  \
-@HAVE_ICU_BUILTIN_TRUE@@HAVE_ICU_TRUE@ $(am__objects_25)
-am__objects_27 = $(am__objects_7) $(am__objects_8) $(am__objects_10) \
+am__objects_23 = libharfbuzz_la-hb-icu.lo
+@HAVE_ICU_BUILTIN_TRUE@@HAVE_ICU_TRUE@am__objects_24 =  \
+@HAVE_ICU_BUILTIN_TRUE@@HAVE_ICU_TRUE@ $(am__objects_23)
+am__objects_25 = $(am__objects_7) $(am__objects_8) $(am__objects_10) \
        $(am__objects_12) $(am__objects_14) $(am__objects_16) \
        $(am__objects_18) $(am__objects_20) $(am__objects_22) \
-       $(am__objects_24) $(am__objects_26)
-@HAVE_GLIB_TRUE@am__objects_28 = $(am__objects_5)
-@HAVE_FREETYPE_TRUE@am__objects_29 = $(am__objects_5)
-@HAVE_GRAPHITE2_TRUE@am__objects_30 = $(am__objects_5)
-@HAVE_UNISCRIBE_TRUE@am__objects_31 = $(am__objects_5)
-@HAVE_DIRECTWRITE_TRUE@am__objects_32 = $(am__objects_5)
-@HAVE_CORETEXT_TRUE@am__objects_33 = $(am__objects_5)
-@HAVE_ICU_BUILTIN_TRUE@@HAVE_ICU_TRUE@am__objects_34 =  \
+       $(am__objects_24)
+@HAVE_GLIB_TRUE@am__objects_26 = $(am__objects_5)
+@HAVE_FREETYPE_TRUE@am__objects_27 = $(am__objects_5)
+@HAVE_GRAPHITE2_TRUE@am__objects_28 = $(am__objects_5)
+@HAVE_UNISCRIBE_TRUE@am__objects_29 = $(am__objects_5)
+@HAVE_DIRECTWRITE_TRUE@am__objects_30 = $(am__objects_5)
+@HAVE_GDI_TRUE@am__objects_31 = $(am__objects_5)
+@HAVE_CORETEXT_TRUE@am__objects_32 = $(am__objects_5)
+@HAVE_ICU_BUILTIN_TRUE@@HAVE_ICU_TRUE@am__objects_33 =  \
 @HAVE_ICU_BUILTIN_TRUE@@HAVE_ICU_TRUE@ $(am__objects_5)
-am__objects_35 = $(am__objects_8) $(am__objects_28) $(am__objects_29) \
-       $(am__objects_30) $(am__objects_31) $(am__objects_32) \
-       $(am__objects_33) $(am__objects_34)
-am_libharfbuzz_la_OBJECTS = $(am__objects_27) $(am__objects_35)
+am__objects_34 = $(am__objects_8) $(am__objects_26) $(am__objects_27) \
+       $(am__objects_28) $(am__objects_29) $(am__objects_30) \
+       $(am__objects_31) $(am__objects_32) $(am__objects_33)
+am_libharfbuzz_la_OBJECTS = $(am__objects_25) $(am__objects_34)
 libharfbuzz_la_OBJECTS = $(am_libharfbuzz_la_OBJECTS)
 am_dump_indic_data_OBJECTS =  \
        dump_indic_data-dump-indic-data.$(OBJEXT) \
        dump_indic_data-hb-ot-shape-complex-indic-table.$(OBJEXT)
 dump_indic_data_OBJECTS = $(am_dump_indic_data_OBJECTS)
-dump_indic_data_DEPENDENCIES = libharfbuzz.la $(am__DEPENDENCIES_11)
+dump_indic_data_DEPENDENCIES = libharfbuzz.la $(am__DEPENDENCIES_12)
 am_dump_khmer_data_OBJECTS =  \
        dump_khmer_data-dump-khmer-data.$(OBJEXT) \
        dump_khmer_data-hb-ot-shape-complex-indic-table.$(OBJEXT)
 dump_khmer_data_OBJECTS = $(am_dump_khmer_data_OBJECTS)
-dump_khmer_data_DEPENDENCIES = libharfbuzz.la $(am__DEPENDENCIES_11)
+dump_khmer_data_DEPENDENCIES = libharfbuzz.la $(am__DEPENDENCIES_12)
 am_dump_myanmar_data_OBJECTS =  \
        dump_myanmar_data-dump-myanmar-data.$(OBJEXT) \
        dump_myanmar_data-hb-ot-shape-complex-indic-table.$(OBJEXT)
 dump_myanmar_data_OBJECTS = $(am_dump_myanmar_data_OBJECTS)
-dump_myanmar_data_DEPENDENCIES = libharfbuzz.la $(am__DEPENDENCIES_11)
+dump_myanmar_data_DEPENDENCIES = libharfbuzz.la $(am__DEPENDENCIES_12)
 am_dump_use_data_OBJECTS = dump_use_data-dump-use-data.$(OBJEXT) \
        dump_use_data-hb-ot-shape-complex-use-table.$(OBJEXT)
 dump_use_data_OBJECTS = $(am_dump_use_data_OBJECTS)
-dump_use_data_DEPENDENCIES = libharfbuzz.la $(am__DEPENDENCIES_11)
+dump_use_data_DEPENDENCIES = libharfbuzz.la $(am__DEPENDENCIES_12)
 am_main_OBJECTS = main-main.$(OBJEXT)
 main_OBJECTS = $(am_main_OBJECTS)
-main_DEPENDENCIES = libharfbuzz.la $(am__DEPENDENCIES_11)
+main_DEPENDENCIES = libharfbuzz.la $(am__DEPENDENCIES_12)
 am_test_OBJECTS = test-test.$(OBJEXT)
 test_OBJECTS = $(am_test_OBJECTS)
-test_DEPENDENCIES = libharfbuzz.la $(am__DEPENDENCIES_11) \
+test_DEPENDENCIES = libharfbuzz.la $(am__DEPENDENCIES_12) \
        $(am__DEPENDENCIES_1)
+am_test_algs_OBJECTS = test_algs-test-algs.$(OBJEXT) \
+       test_algs-hb-static.$(OBJEXT)
+test_algs_OBJECTS = $(am_test_algs_OBJECTS)
+am__DEPENDENCIES_13 = libharfbuzz.la $(am__DEPENDENCIES_12)
+test_algs_DEPENDENCIES = $(am__DEPENDENCIES_13)
+am_test_bimap_OBJECTS = test_bimap-test-bimap.$(OBJEXT) \
+       test_bimap-hb-static.$(OBJEXT)
+test_bimap_OBJECTS = $(am_test_bimap_OBJECTS)
+test_bimap_DEPENDENCIES = $(am__DEPENDENCIES_13)
 am_test_buffer_serialize_OBJECTS =  \
        test_buffer_serialize-test-buffer-serialize.$(OBJEXT)
 test_buffer_serialize_OBJECTS = $(am_test_buffer_serialize_OBJECTS)
 test_buffer_serialize_DEPENDENCIES = libharfbuzz.la \
-       $(am__DEPENDENCIES_11)
+       $(am__DEPENDENCIES_12)
+am_test_gpos_size_params_OBJECTS =  \
+       test_gpos_size_params-test-gpos-size-params.$(OBJEXT)
+test_gpos_size_params_OBJECTS = $(am_test_gpos_size_params_OBJECTS)
+test_gpos_size_params_DEPENDENCIES = libharfbuzz.la \
+       $(am__DEPENDENCIES_12)
+am_test_gsub_would_substitute_OBJECTS = test_gsub_would_substitute-test-gsub-would-substitute.$(OBJEXT)
+test_gsub_would_substitute_OBJECTS =  \
+       $(am_test_gsub_would_substitute_OBJECTS)
+test_gsub_would_substitute_DEPENDENCIES = libharfbuzz.la \
+       $(am__DEPENDENCIES_12) $(am__DEPENDENCIES_1)
 am_test_iter_OBJECTS = test_iter-test-iter.$(OBJEXT) \
        test_iter-hb-static.$(OBJEXT)
 test_iter_OBJECTS = $(am_test_iter_OBJECTS)
-am__DEPENDENCIES_12 = libharfbuzz.la $(am__DEPENDENCIES_11)
-test_iter_DEPENDENCIES = $(am__DEPENDENCIES_12)
-am_test_name_table_OBJECTS =  \
-       test_name_table-test-name-table.$(OBJEXT)
-test_name_table_OBJECTS = $(am_test_name_table_OBJECTS)
-test_name_table_DEPENDENCIES = libharfbuzz.la $(am__DEPENDENCIES_11)
+test_iter_DEPENDENCIES = $(am__DEPENDENCIES_13)
+am_test_meta_OBJECTS = test_meta-test-meta.$(OBJEXT) \
+       test_meta-hb-static.$(OBJEXT)
+test_meta_OBJECTS = $(am_test_meta_OBJECTS)
+test_meta_DEPENDENCIES = $(am__DEPENDENCIES_13)
+am_test_number_OBJECTS = test_number-test-number.$(OBJEXT) \
+       test_number-hb-number.$(OBJEXT)
+test_number_OBJECTS = $(am_test_number_OBJECTS)
+test_number_DEPENDENCIES = $(am__DEPENDENCIES_13)
 am__test_ot_color_SOURCES_DIST = test-ot-color.cc
 @HAVE_CAIRO_FT_TRUE@@HAVE_FREETYPE_TRUE@am_test_ot_color_OBJECTS = test_ot_color-test-ot-color.$(OBJEXT)
 test_ot_color_OBJECTS = $(am_test_ot_color_OBJECTS)
 @HAVE_CAIRO_FT_TRUE@@HAVE_FREETYPE_TRUE@test_ot_color_DEPENDENCIES =  \
 @HAVE_CAIRO_FT_TRUE@@HAVE_FREETYPE_TRUE@       libharfbuzz.la \
-@HAVE_CAIRO_FT_TRUE@@HAVE_FREETYPE_TRUE@       $(am__DEPENDENCIES_11) \
+@HAVE_CAIRO_FT_TRUE@@HAVE_FREETYPE_TRUE@       $(am__DEPENDENCIES_12) \
 @HAVE_CAIRO_FT_TRUE@@HAVE_FREETYPE_TRUE@       $(am__DEPENDENCIES_1) \
 @HAVE_CAIRO_FT_TRUE@@HAVE_FREETYPE_TRUE@       $(am__DEPENDENCIES_1) \
 @HAVE_CAIRO_FT_TRUE@@HAVE_FREETYPE_TRUE@       $(am__DEPENDENCIES_1)
+am_test_ot_meta_OBJECTS = test_ot_meta-test-ot-meta.$(OBJEXT)
+test_ot_meta_OBJECTS = $(am_test_ot_meta_OBJECTS)
+test_ot_meta_DEPENDENCIES = libharfbuzz.la $(am__DEPENDENCIES_12)
+am_test_ot_name_OBJECTS = test_ot_name-test-ot-name.$(OBJEXT)
+test_ot_name_OBJECTS = $(am_test_ot_name_OBJECTS)
+test_ot_name_DEPENDENCIES = libharfbuzz.la $(am__DEPENDENCIES_12)
 am_test_ot_tag_OBJECTS = test_ot_tag-hb-ot-tag.$(OBJEXT)
 test_ot_tag_OBJECTS = $(am_test_ot_tag_OBJECTS)
-test_ot_tag_DEPENDENCIES = $(am__DEPENDENCIES_12)
-am_test_size_params_OBJECTS =  \
-       test_size_params-test-size-params.$(OBJEXT)
-test_size_params_OBJECTS = $(am_test_size_params_OBJECTS)
-test_size_params_DEPENDENCIES = libharfbuzz.la $(am__DEPENDENCIES_11)
+test_ot_tag_DEPENDENCIES = $(am__DEPENDENCIES_13)
 am_test_unicode_ranges_OBJECTS =  \
        test_unicode_ranges-test-unicode-ranges.$(OBJEXT)
 test_unicode_ranges_OBJECTS = $(am_test_unicode_ranges_OBJECTS)
-test_unicode_ranges_DEPENDENCIES = $(am__DEPENDENCIES_12)
-am_test_would_substitute_OBJECTS =  \
-       test_would_substitute-test-would-substitute.$(OBJEXT)
-test_would_substitute_OBJECTS = $(am_test_would_substitute_OBJECTS)
-test_would_substitute_DEPENDENCIES = libharfbuzz.la \
-       $(am__DEPENDENCIES_11) $(am__DEPENDENCIES_1)
+test_unicode_ranges_DEPENDENCIES = $(am__DEPENDENCIES_13)
 am__dist_check_SCRIPTS_DIST = check-c-linkage-decls.sh \
        check-externs.sh check-header-guards.sh check-includes.sh \
        check-static-inits.sh check-symbols.sh check-libstdc++.sh
@@ -535,10 +564,12 @@ am__depfiles_remade = ./$(DEPDIR)/dump_indic_data-dump-indic-data.Po \
        ./$(DEPDIR)/libharfbuzz_la-hb-fallback-shape.Plo \
        ./$(DEPDIR)/libharfbuzz_la-hb-font.Plo \
        ./$(DEPDIR)/libharfbuzz_la-hb-ft.Plo \
+       ./$(DEPDIR)/libharfbuzz_la-hb-gdi.Plo \
        ./$(DEPDIR)/libharfbuzz_la-hb-glib.Plo \
        ./$(DEPDIR)/libharfbuzz_la-hb-graphite2.Plo \
        ./$(DEPDIR)/libharfbuzz_la-hb-icu.Plo \
        ./$(DEPDIR)/libharfbuzz_la-hb-map.Plo \
+       ./$(DEPDIR)/libharfbuzz_la-hb-number.Plo \
        ./$(DEPDIR)/libharfbuzz_la-hb-ot-cff1-table.Plo \
        ./$(DEPDIR)/libharfbuzz_la-hb-ot-cff2-table.Plo \
        ./$(DEPDIR)/libharfbuzz_la-hb-ot-color.Plo \
@@ -547,7 +578,8 @@ am__depfiles_remade = ./$(DEPDIR)/dump_indic_data-dump-indic-data.Po \
        ./$(DEPDIR)/libharfbuzz_la-hb-ot-layout.Plo \
        ./$(DEPDIR)/libharfbuzz_la-hb-ot-map.Plo \
        ./$(DEPDIR)/libharfbuzz_la-hb-ot-math.Plo \
-       ./$(DEPDIR)/libharfbuzz_la-hb-ot-name-language.Plo \
+       ./$(DEPDIR)/libharfbuzz_la-hb-ot-meta.Plo \
+       ./$(DEPDIR)/libharfbuzz_la-hb-ot-metrics.Plo \
        ./$(DEPDIR)/libharfbuzz_la-hb-ot-name.Plo \
        ./$(DEPDIR)/libharfbuzz_la-hb-ot-shape-complex-arabic.Plo \
        ./$(DEPDIR)/libharfbuzz_la-hb-ot-shape-complex-default.Plo \
@@ -571,30 +603,38 @@ am__depfiles_remade = ./$(DEPDIR)/dump_indic_data-dump-indic-data.Po \
        ./$(DEPDIR)/libharfbuzz_la-hb-shape.Plo \
        ./$(DEPDIR)/libharfbuzz_la-hb-shaper.Plo \
        ./$(DEPDIR)/libharfbuzz_la-hb-static.Plo \
-       ./$(DEPDIR)/libharfbuzz_la-hb-ucdn.Plo \
+       ./$(DEPDIR)/libharfbuzz_la-hb-ucd.Plo \
        ./$(DEPDIR)/libharfbuzz_la-hb-unicode.Plo \
        ./$(DEPDIR)/libharfbuzz_la-hb-uniscribe.Plo \
-       ./$(DEPDIR)/libharfbuzz_la-hb-warning.Plo \
+       ./$(DEPDIR)/libharfbuzz_subset_la-hb-number.Plo \
        ./$(DEPDIR)/libharfbuzz_subset_la-hb-ot-cff1-table.Plo \
        ./$(DEPDIR)/libharfbuzz_subset_la-hb-ot-cff2-table.Plo \
        ./$(DEPDIR)/libharfbuzz_subset_la-hb-static.Plo \
        ./$(DEPDIR)/libharfbuzz_subset_la-hb-subset-cff-common.Plo \
        ./$(DEPDIR)/libharfbuzz_subset_la-hb-subset-cff1.Plo \
        ./$(DEPDIR)/libharfbuzz_subset_la-hb-subset-cff2.Plo \
-       ./$(DEPDIR)/libharfbuzz_subset_la-hb-subset-glyf.Plo \
        ./$(DEPDIR)/libharfbuzz_subset_la-hb-subset-input.Plo \
        ./$(DEPDIR)/libharfbuzz_subset_la-hb-subset-plan.Plo \
        ./$(DEPDIR)/libharfbuzz_subset_la-hb-subset.Plo \
        ./$(DEPDIR)/main-main.Po ./$(DEPDIR)/test-test.Po \
+       ./$(DEPDIR)/test_algs-hb-static.Po \
+       ./$(DEPDIR)/test_algs-test-algs.Po \
+       ./$(DEPDIR)/test_bimap-hb-static.Po \
+       ./$(DEPDIR)/test_bimap-test-bimap.Po \
        ./$(DEPDIR)/test_buffer_serialize-test-buffer-serialize.Po \
+       ./$(DEPDIR)/test_gpos_size_params-test-gpos-size-params.Po \
+       ./$(DEPDIR)/test_gsub_would_substitute-test-gsub-would-substitute.Po \
        ./$(DEPDIR)/test_iter-hb-static.Po \
        ./$(DEPDIR)/test_iter-test-iter.Po \
-       ./$(DEPDIR)/test_name_table-test-name-table.Po \
+       ./$(DEPDIR)/test_meta-hb-static.Po \
+       ./$(DEPDIR)/test_meta-test-meta.Po \
+       ./$(DEPDIR)/test_number-hb-number.Po \
+       ./$(DEPDIR)/test_number-test-number.Po \
        ./$(DEPDIR)/test_ot_color-test-ot-color.Po \
+       ./$(DEPDIR)/test_ot_meta-test-ot-meta.Po \
+       ./$(DEPDIR)/test_ot_name-test-ot-name.Po \
        ./$(DEPDIR)/test_ot_tag-hb-ot-tag.Po \
-       ./$(DEPDIR)/test_size_params-test-size-params.Po \
-       ./$(DEPDIR)/test_unicode_ranges-test-unicode-ranges.Po \
-       ./$(DEPDIR)/test_would_substitute-test-would-substitute.Po
+       ./$(DEPDIR)/test_unicode_ranges-test-unicode-ranges.Po
 am__mv = mv -f
 CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
        $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS)
@@ -638,22 +678,28 @@ SOURCES = $(libharfbuzz_gobject_la_SOURCES) \
        $(libharfbuzz_la_SOURCES) $(dump_indic_data_SOURCES) \
        $(dump_khmer_data_SOURCES) $(dump_myanmar_data_SOURCES) \
        $(dump_use_data_SOURCES) $(main_SOURCES) $(test_SOURCES) \
-       $(test_buffer_serialize_SOURCES) $(test_iter_SOURCES) \
-       $(test_name_table_SOURCES) $(test_ot_color_SOURCES) \
-       $(test_ot_tag_SOURCES) $(test_size_params_SOURCES) \
-       $(test_unicode_ranges_SOURCES) \
-       $(test_would_substitute_SOURCES)
+       $(test_algs_SOURCES) $(test_bimap_SOURCES) \
+       $(test_buffer_serialize_SOURCES) \
+       $(test_gpos_size_params_SOURCES) \
+       $(test_gsub_would_substitute_SOURCES) $(test_iter_SOURCES) \
+       $(test_meta_SOURCES) $(test_number_SOURCES) \
+       $(test_ot_color_SOURCES) $(test_ot_meta_SOURCES) \
+       $(test_ot_name_SOURCES) $(test_ot_tag_SOURCES) \
+       $(test_unicode_ranges_SOURCES)
 DIST_SOURCES = $(am__libharfbuzz_gobject_la_SOURCES_DIST) \
        $(am__libharfbuzz_icu_la_SOURCES_DIST) \
        $(libharfbuzz_subset_la_SOURCES) \
        $(am__libharfbuzz_la_SOURCES_DIST) $(dump_indic_data_SOURCES) \
        $(dump_khmer_data_SOURCES) $(dump_myanmar_data_SOURCES) \
        $(dump_use_data_SOURCES) $(main_SOURCES) $(test_SOURCES) \
-       $(test_buffer_serialize_SOURCES) $(test_iter_SOURCES) \
-       $(test_name_table_SOURCES) $(am__test_ot_color_SOURCES_DIST) \
-       $(test_ot_tag_SOURCES) $(test_size_params_SOURCES) \
-       $(test_unicode_ranges_SOURCES) \
-       $(test_would_substitute_SOURCES)
+       $(test_algs_SOURCES) $(test_bimap_SOURCES) \
+       $(test_buffer_serialize_SOURCES) \
+       $(test_gpos_size_params_SOURCES) \
+       $(test_gsub_would_substitute_SOURCES) $(test_iter_SOURCES) \
+       $(test_meta_SOURCES) $(test_number_SOURCES) \
+       $(am__test_ot_color_SOURCES_DIST) $(test_ot_meta_SOURCES) \
+       $(test_ot_name_SOURCES) $(test_ot_tag_SOURCES) \
+       $(test_unicode_ranges_SOURCES)
 RECURSIVE_TARGETS = all-recursive check-recursive cscopelist-recursive \
        ctags-recursive dvi-recursive html-recursive info-recursive \
        install-data-recursive install-dvi-recursive \
@@ -671,11 +717,12 @@ DATA = $(cmake_DATA) $(gir_DATA) $(pkgconfig_DATA) $(typelib_DATA)
 am__pkginclude_HEADERS_DIST = hb-aat-layout.h hb-aat.h hb-blob.h \
        hb-buffer.h hb-common.h hb-deprecated.h hb-face.h hb-font.h \
        hb-map.h hb-ot-color.h hb-ot-deprecated.h hb-ot-font.h \
-       hb-ot-layout.h hb-ot-math.h hb-ot-name.h hb-ot-shape.h \
-       hb-ot-var.h hb-ot.h hb-set.h hb-shape-plan.h hb-shape.h \
-       hb-unicode.h hb-version.h hb.h hb-glib.h hb-ft.h \
-       hb-graphite2.h hb-uniscribe.h hb-directwrite.h hb-coretext.h \
-       hb-icu.h hb-subset.h hb-gobject.h hb-gobject-structs.h
+       hb-ot-layout.h hb-ot-math.h hb-ot-meta.h hb-ot-metrics.h \
+       hb-ot-name.h hb-ot-shape.h hb-ot-var.h hb-ot.h hb-set.h \
+       hb-shape-plan.h hb-shape.h hb-unicode.h hb-version.h hb.h \
+       hb-glib.h hb-ft.h hb-graphite2.h hb-uniscribe.h \
+       hb-directwrite.h hb-gdi.h hb-coretext.h hb-icu.h hb-subset.h \
+       hb-gobject.h hb-gobject-structs.h
 HEADERS = $(nodist_pkginclude_HEADERS) $(pkginclude_HEADERS)
 RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive        \
   distclean-recursive maintainer-clean-recursive
@@ -963,6 +1010,8 @@ FREETYPE_CFLAGS = @FREETYPE_CFLAGS@
 FREETYPE_DEPS = @FREETYPE_DEPS@
 FREETYPE_LIBS = @FREETYPE_LIBS@
 GCOV = @GCOV@
+GDI_CFLAGS = @GDI_CFLAGS@
+GDI_LIBS = @GDI_LIBS@
 GENHTML = @GENHTML@
 GIT = @GIT@
 GLIB_CFLAGS = @GLIB_CFLAGS@
@@ -981,6 +1030,7 @@ GTKDOC_DEPS_CFLAGS = @GTKDOC_DEPS_CFLAGS@
 GTKDOC_DEPS_LIBS = @GTKDOC_DEPS_LIBS@
 GTKDOC_MKPDF = @GTKDOC_MKPDF@
 GTKDOC_REBASE = @GTKDOC_REBASE@
+HAVE_CXX11 = @HAVE_CXX11@
 HB_LIBTOOL_VERSION_INFO = @HB_LIBTOOL_VERSION_INFO@
 HB_VERSION = @HB_VERSION@
 HB_VERSION_MAJOR = @HB_VERSION_MAJOR@
@@ -1101,20 +1151,21 @@ top_build_prefix = @top_build_prefix@
 top_builddir = @top_builddir@
 top_srcdir = @top_srcdir@
 NULL = 
-SUBDIRS = $(am__append_30)
-DIST_SUBDIRS = hb-ucdn
-BUILT_SOURCES = hb-version.h $(am__append_45) $(RAGEL_GENERATED)
-EXTRA_DIST = hb-version.h.in harfbuzz.pc.in harfbuzz-config.cmake.in \
-       harfbuzz-subset.pc.in harfbuzz-icu.pc.in \
-       harfbuzz-gobject.pc.in hb-gobject-enums.cc.tmpl \
-       hb-gobject-enums.h.tmpl $(NULL) $(GENERATORS) \
-       $(HB_BASE_RAGEL_sources) $(NULL)
-CLEANFILES = $(pkgconfig_DATA) $(DEF_FILES) $(am__append_50)
-DISTCLEANFILES = $(am__append_46)
+SUBDIRS = 
+DIST_SUBDIRS = 
+BUILT_SOURCES = hb-version.h $(am__append_44) $(RAGEL_GENERATED) \
+       harfbuzz.cc
+EXTRA_DIST = harfbuzz.cc hb-version.h.in harfbuzz.pc.in \
+       harfbuzz-config.cmake.in harfbuzz-subset.pc.in \
+       harfbuzz-icu.pc.in harfbuzz-gobject.pc.in \
+       hb-gobject-enums.cc.tmpl hb-gobject-enums.h.tmpl $(NULL) \
+       $(GENERATORS) $(HB_BASE_RAGEL_sources) $(NULL)
+CLEANFILES = $(pkgconfig_DATA) $(DEF_FILES) $(am__append_49)
+DISTCLEANFILES = $(am__append_45)
 MAINTAINERCLEANFILES = 
 DISTCHECK_CONFIGURE_FLAGS = --enable-introspection
 lib_LTLIBRARIES = libharfbuzz.la libharfbuzz-subset.la \
-       $(am__append_38) $(am__append_41)
+       $(am__append_37) $(am__append_40)
 HB_BASE_sources = \
        hb-aat-fdsc-table.hh \
        hb-aat-layout-ankr-table.hh \
@@ -1125,12 +1176,14 @@ HB_BASE_sources = \
        hb-aat-layout-kerx-table.hh \
        hb-aat-layout-lcar-table.hh \
        hb-aat-layout-morx-table.hh \
+       hb-aat-layout-opbd-table.hh \
        hb-aat-layout-trak-table.hh \
        hb-aat-layout.cc \
        hb-aat-layout.hh \
        hb-aat-ltag-table.hh \
        hb-aat-map.cc \
        hb-aat-map.hh \
+       hb-algs.hh \
        hb-array.hh \
        hb-atomic.hh \
        hb-blob.cc \
@@ -1145,10 +1198,12 @@ HB_BASE_sources = \
        hb-cff1-interp-cs.hh \
        hb-cff2-interp-cs.hh \
        hb-common.cc \
+       hb-config.hh \
        hb-debug.hh \
-       hb-dsalgs.hh \
+       hb-dispatch.hh \
        hb-face.cc \
        hb-face.hh \
+       hb-fallback-shape.cc \
        hb-font.cc \
        hb-font.hh \
        hb-iter.hh \
@@ -1156,8 +1211,12 @@ HB_BASE_sources = \
        hb-machinery.hh \
        hb-map.cc \
        hb-map.hh \
+       hb-bimap.hh \
+       hb-meta.hh \
        hb-mutex.hh \
        hb-null.hh \
+       hb-number.cc \
+       hb-number.hh \
        hb-object.hh \
        hb-open-file.hh \
        hb-open-type.hh \
@@ -1175,6 +1234,7 @@ HB_BASE_sources = \
        hb-ot-color.cc \
        hb-ot-face.cc \
        hb-ot-face.hh \
+       hb-ot-face-table-list.hh \
        hb-ot-font.cc \
        hb-ot-gasp-table.hh \
        hb-ot-glyf-table.hh \
@@ -1197,7 +1257,11 @@ HB_BASE_sources = \
        hb-ot-math-table.hh \
        hb-ot-math.cc \
        hb-ot-maxp-table.hh \
-       hb-ot-name-language.cc \
+       hb-ot-meta-table.hh \
+       hb-ot-meta.cc \
+       hb-ot-metrics.cc \
+       hb-ot-metrics.hh \
+       hb-ot-name-language-static.hh \
        hb-ot-name-language.hh \
        hb-ot-name-table.hh \
        hb-ot-name.cc \
@@ -1238,10 +1302,14 @@ HB_BASE_sources = \
        hb-ot-tag.cc \
        hb-ot-var-avar-table.hh \
        hb-ot-var-fvar-table.hh \
+       hb-ot-var-gvar-table.hh \
        hb-ot-var-hvar-table.hh \
        hb-ot-var-mvar-table.hh \
        hb-ot-var.cc \
        hb-ot-vorg-table.hh \
+       hb-pool.hh \
+       hb-sanitize.hh \
+       hb-serialize.hh \
        hb-set-digest.hh \
        hb-set.cc \
        hb-set.hh \
@@ -1254,18 +1322,20 @@ HB_BASE_sources = \
        hb-shaper.hh \
        hb-static.cc \
        hb-string-array.hh \
+       hb-ucd-table.hh \
+       hb-ucd.cc \
        hb-unicode-emoji-table.hh \
        hb-unicode.cc \
        hb-unicode.hh \
        hb-utf.hh \
        hb-vector.hh \
-       hb-warning.cc \
        hb.hh \
        $(NULL)
 
 HB_BASE_RAGEL_GENERATED_sources = \
        hb-buffer-deserialize-json.hh \
        hb-buffer-deserialize-text.hh \
+       hb-number-parser.hh \
        hb-ot-shape-complex-indic-machine.hh \
        hb-ot-shape-complex-khmer-machine.hh \
        hb-ot-shape-complex-myanmar-machine.hh \
@@ -1275,6 +1345,7 @@ HB_BASE_RAGEL_GENERATED_sources = \
 HB_BASE_RAGEL_sources = \
        hb-buffer-deserialize-json.rl \
        hb-buffer-deserialize-text.rl \
+       hb-number-parser.rl \
        hb-ot-shape-complex-indic-machine.rl \
        hb-ot-shape-complex-khmer-machine.rl \
        hb-ot-shape-complex-myanmar-machine.rl \
@@ -1296,6 +1367,8 @@ HB_BASE_headers = \
        hb-ot-font.h \
        hb-ot-layout.h \
        hb-ot-math.h \
+       hb-ot-meta.h \
+       hb-ot-metrics.h \
        hb-ot-name.h \
        hb-ot-shape.h \
        hb-ot-var.h \
@@ -1308,10 +1381,6 @@ HB_BASE_headers = \
        hb.h \
        $(NULL)
 
-HB_FALLBACK_sources = \
-       hb-fallback-shape.cc    \
-       $(NULL)
-
 
 # Optional Sources and Headers with external deps
 HB_FT_sources = hb-ft.cc
@@ -1326,18 +1395,19 @@ HB_CORETEXT_sources = hb-coretext.cc
 HB_CORETEXT_headers = hb-coretext.h
 HB_DIRECTWRITE_sources = hb-directwrite.cc
 HB_DIRECTWRITE_headers = hb-directwrite.h
+HB_GDI_sources = hb-gdi.cc
+HB_GDI_headers = hb-gdi.h
 HB_UNISCRIBE_sources = hb-uniscribe.cc
 HB_UNISCRIBE_headers = hb-uniscribe.h
 
-# Additional supplemental sources
-HB_UCDN_sources = hb-ucdn.cc
-
 # Sources for libharfbuzz-gobject and libharfbuzz-icu
 HB_ICU_sources = hb-icu.cc
 HB_ICU_headers = hb-icu.h
 
 # Sources for libharfbuzz-subset
 HB_SUBSET_sources = \
+       hb-number.cc \
+       hb-number.hh \
        hb-ot-cff1-table.cc \
        hb-ot-cff2-table.cc \
        hb-static.cc \
@@ -1347,9 +1417,6 @@ HB_SUBSET_sources = \
        hb-subset-cff1.hh \
        hb-subset-cff2.cc \
        hb-subset-cff2.hh \
-       hb-subset-glyf.cc \
-       hb-subset-glyf.hh \
-       hb-subset-glyf.hh \
        hb-subset-input.cc \
        hb-subset-input.hh \
        hb-subset-plan.cc \
@@ -1372,23 +1439,23 @@ HB_GOBJECT_NODIST_sources = $(HB_GOBJECT_ENUM_sources)
 HB_GOBJECT_NODIST_headers = $(HB_GOBJECT_ENUM_headers)
 HB_GOBJECT_sources = $(HB_GOBJECT_DIST_sources) $(HB_GOBJECT_NODIST_sources)
 HB_GOBJECT_headers = $(HB_GOBJECT_DIST_headers) $(HB_GOBJECT_NODIST_headers)
-HBCFLAGS = $(am__append_2) $(am__append_4) $(am__append_9) \
-       $(am__append_13) $(am__append_18) $(am__append_22) \
-       $(am__append_26) $(am__append_31) $(am__append_34)
+HBCFLAGS = $(am__append_1) $(am__append_3) $(am__append_8) \
+       $(am__append_12) $(am__append_17) $(am__append_21) \
+       $(am__append_25) $(am__append_29) $(am__append_33)
 
 # Put the library together
-HBLIBS = $(am__append_5) $(am__append_10) $(am__append_14) \
-       $(am__append_32) $(HBNONPCLIBS) $(am__append_35)
-HBNONPCLIBS = $(am__append_3) $(am__append_19) $(am__append_23) \
-       $(am__append_27)
-HBDEPS = $(am__append_6) $(am__append_15)
+HBLIBS = $(am__append_4) $(am__append_9) $(am__append_13) \
+       $(HBNONPCLIBS) $(am__append_34)
+HBNONPCLIBS = $(am__append_2) $(am__append_18) $(am__append_22) \
+       $(am__append_26) $(am__append_30)
+HBDEPS = $(am__append_5) $(am__append_14)
 HBSOURCES = $(HB_BASE_sources) $(HB_BASE_RAGEL_GENERATED_sources) \
-       $(am__append_1) $(am__append_7) $(am__append_11) \
+       $(am__append_6) $(am__append_10) $(am__append_15) \
+       $(am__append_19) $(am__append_23) $(am__append_27) \
+       $(am__append_31) $(am__append_35)
+HBHEADERS = $(HB_BASE_headers) $(am__append_7) $(am__append_11) \
        $(am__append_16) $(am__append_20) $(am__append_24) \
-       $(am__append_28) $(am__append_33) $(am__append_36)
-HBHEADERS = $(HB_BASE_headers) $(am__append_8) $(am__append_12) \
-       $(am__append_17) $(am__append_21) $(am__append_25) \
-       $(am__append_29) $(am__append_37)
+       $(am__append_28) $(am__append_32) $(am__append_36)
 @OS_WIN32_TRUE@export_symbols = -export-symbols harfbuzz.def
 @OS_WIN32_TRUE@harfbuzz_def_dependency = harfbuzz.def
 @OS_WIN32_TRUE@export_symbols_subset = -export-symbols harfbuzz-subset.def
@@ -1410,11 +1477,11 @@ libharfbuzz_la_LDFLAGS = $(base_link_flags) $(export_symbols) $(CODE_COVERAGE_LD
 libharfbuzz_la_LIBADD = $(HBLIBS)
 EXTRA_libharfbuzz_la_DEPENDENCIES = $(harfbuzz_def_dependency)
 pkginclude_HEADERS = $(HBHEADERS) $(HB_SUBSET_headers) \
-       $(am__append_39) $(am__append_42)
-nodist_pkginclude_HEADERS = $(am__append_43)
+       $(am__append_38) $(am__append_41)
+nodist_pkginclude_HEADERS = $(am__append_42)
 pkgconfigdir = $(libdir)/pkgconfig
-pkgconfig_DATA = harfbuzz.pc harfbuzz-subset.pc $(am__append_40) \
-       $(am__append_44)
+pkgconfig_DATA = harfbuzz.pc harfbuzz-subset.pc $(am__append_39) \
+       $(am__append_43)
 cmakedir = $(libdir)/cmake/harfbuzz
 cmake_DATA = harfbuzz-config.cmake
 libharfbuzz_subset_la_SOURCES = $(HB_SUBSET_sources)
@@ -1435,7 +1502,7 @@ EXTRA_libharfbuzz_subset_la_DEPENDENCIES = $(harfbuzz_subset_def_dependency)
 @HAVE_GOBJECT_TRUE@libharfbuzz_gobject_la_LIBADD = $(GOBJECT_LIBS) libharfbuzz.la
 @HAVE_GOBJECT_TRUE@EXTRA_libharfbuzz_gobject_la_DEPENDENCIES = $(harfbuzz_gobject_def_dependency)
 DEF_FILES = harfbuzz.def harfbuzz-subset.def harfbuzz-icu.def \
-       harfbuzz-deprecated-symbols.txt $(am__append_47)
+       harfbuzz-deprecated-symbols.txt $(am__append_46)
 GENERATORS = \
        gen-arabic-table.py \
        gen-def.py \
@@ -1443,6 +1510,7 @@ GENERATORS = \
        gen-indic-table.py \
        gen-os2-unicode-ranges.py \
        gen-tag-table.py \
+       gen-ucd-table.py \
        gen-use-table.py \
        gen-vowel-constraints.py \
        $(NULL)
@@ -1460,21 +1528,24 @@ test_LDADD = libharfbuzz.la $(HBLIBS) $(FREETYPE_LIBS)
 test_buffer_serialize_SOURCES = test-buffer-serialize.cc
 test_buffer_serialize_CPPFLAGS = $(HBCFLAGS)
 test_buffer_serialize_LDADD = libharfbuzz.la $(HBLIBS)
-test_name_table_SOURCES = test-name-table.cc
-test_name_table_CPPFLAGS = $(HBCFLAGS)
-test_name_table_LDADD = libharfbuzz.la $(HBLIBS)
-test_size_params_SOURCES = test-size-params.cc
-test_size_params_CPPFLAGS = $(HBCFLAGS)
-test_size_params_LDADD = libharfbuzz.la $(HBLIBS)
-test_would_substitute_SOURCES = test-would-substitute.cc
-test_would_substitute_CPPFLAGS = $(HBCFLAGS) $(FREETYPE_CFLAGS)
-test_would_substitute_LDADD = libharfbuzz.la $(HBLIBS) $(FREETYPE_LIBS)
+test_ot_meta_SOURCES = test-ot-meta.cc
+test_ot_meta_CPPFLAGS = $(HBCFLAGS)
+test_ot_meta_LDADD = libharfbuzz.la $(HBLIBS)
+test_ot_name_SOURCES = test-ot-name.cc
+test_ot_name_CPPFLAGS = $(HBCFLAGS)
+test_ot_name_LDADD = libharfbuzz.la $(HBLIBS)
+test_gpos_size_params_SOURCES = test-gpos-size-params.cc
+test_gpos_size_params_CPPFLAGS = $(HBCFLAGS)
+test_gpos_size_params_LDADD = libharfbuzz.la $(HBLIBS)
+test_gsub_would_substitute_SOURCES = test-gsub-would-substitute.cc
+test_gsub_would_substitute_CPPFLAGS = $(HBCFLAGS) $(FREETYPE_CFLAGS)
+test_gsub_would_substitute_LDADD = libharfbuzz.la $(HBLIBS) $(FREETYPE_LIBS)
 @HAVE_CAIRO_FT_TRUE@@HAVE_FREETYPE_TRUE@test_ot_color_SOURCES = test-ot-color.cc
 @HAVE_CAIRO_FT_TRUE@@HAVE_FREETYPE_TRUE@test_ot_color_CPPFLAGS = $(HBCFLAGS) $(FREETYPE_CFLAGS) $(CAIRO_FT_CFLAGS)
 @HAVE_CAIRO_FT_TRUE@@HAVE_FREETYPE_TRUE@test_ot_color_LDADD = libharfbuzz.la $(HBLIBS) $(FREETYPE_LIBS) $(CAIRO_LIBS) $(CAIRO_FT_LIBS)
 dist_check_SCRIPTS = check-c-linkage-decls.sh check-externs.sh \
        check-header-guards.sh check-includes.sh check-static-inits.sh \
-       check-symbols.sh $(NULL) $(am__append_49)
+       check-symbols.sh $(NULL) $(am__append_48)
 dump_indic_data_SOURCES = dump-indic-data.cc hb-ot-shape-complex-indic-table.cc
 dump_indic_data_CPPFLAGS = $(HBCFLAGS)
 dump_indic_data_LDADD = libharfbuzz.la $(HBLIBS)
@@ -1487,18 +1558,30 @@ dump_myanmar_data_LDADD = libharfbuzz.la $(HBLIBS)
 dump_use_data_SOURCES = dump-use-data.cc hb-ot-shape-complex-use-table.cc
 dump_use_data_CPPFLAGS = $(HBCFLAGS)
 dump_use_data_LDADD = libharfbuzz.la $(HBLIBS)
-COMPILED_TESTS = test-iter test-ot-tag test-unicode-ranges
+COMPILED_TESTS = test-algs test-iter test-meta test-number test-ot-tag test-unicode-ranges test-bimap
 COMPILED_TESTS_CPPFLAGS = $(HBCFLAGS) -DMAIN -UNDEBUG
 COMPILED_TESTS_LDADD = libharfbuzz.la $(HBLIBS)
+test_algs_SOURCES = test-algs.cc hb-static.cc
+test_algs_CPPFLAGS = $(COMPILED_TESTS_CPPFLAGS)
+test_algs_LDADD = $(COMPILED_TESTS_LDADD)
 test_iter_SOURCES = test-iter.cc hb-static.cc
 test_iter_CPPFLAGS = $(COMPILED_TESTS_CPPFLAGS)
 test_iter_LDADD = $(COMPILED_TESTS_LDADD)
+test_meta_SOURCES = test-meta.cc hb-static.cc
+test_meta_CPPFLAGS = $(COMPILED_TESTS_CPPFLAGS)
+test_meta_LDADD = $(COMPILED_TESTS_LDADD)
+test_number_SOURCES = test-number.cc hb-number.cc
+test_number_CPPFLAGS = $(COMPILED_TESTS_CPPFLAGS)
+test_number_LDADD = $(COMPILED_TESTS_LDADD)
 test_ot_tag_SOURCES = hb-ot-tag.cc
 test_ot_tag_CPPFLAGS = $(COMPILED_TESTS_CPPFLAGS)
 test_ot_tag_LDADD = $(COMPILED_TESTS_LDADD)
 test_unicode_ranges_SOURCES = test-unicode-ranges.cc
 test_unicode_ranges_CPPFLAGS = $(COMPILED_TESTS_CPPFLAGS)
 test_unicode_ranges_LDADD = $(COMPILED_TESTS_LDADD)
+test_bimap_SOURCES = test-bimap.cc hb-static.cc
+test_bimap_CPPFLAGS = $(COMPILED_TESTS_CPPFLAGS)
+test_bimap_LDADD = $(COMPILED_TESTS_LDADD)
 TESTS_ENVIRONMENT = \
        srcdir="$(srcdir)" \
        MAKE="$(MAKE) $(AM_MAKEFLAGS)" \
@@ -1522,6 +1605,7 @@ TESTS_ENVIRONMENT = \
 @HAVE_INTROSPECTION_TRUE@      -DHB_AAT_H_IN \
 @HAVE_INTROSPECTION_TRUE@      -DHB_GOBJECT_H \
 @HAVE_INTROSPECTION_TRUE@      -DHB_GOBJECT_H_IN \
+@HAVE_INTROSPECTION_TRUE@      -DHAVE_GOBJECT \
 @HAVE_INTROSPECTION_TRUE@      -DHB_EXTERN= \
 @HAVE_INTROSPECTION_TRUE@      $(NULL)
 
@@ -1733,38 +1817,58 @@ test$(EXEEXT): $(test_OBJECTS) $(test_DEPENDENCIES) $(EXTRA_test_DEPENDENCIES)
        @rm -f test$(EXEEXT)
        $(AM_V_CXXLD)$(CXXLINK) $(test_OBJECTS) $(test_LDADD) $(LIBS)
 
+test-algs$(EXEEXT): $(test_algs_OBJECTS) $(test_algs_DEPENDENCIES) $(EXTRA_test_algs_DEPENDENCIES) 
+       @rm -f test-algs$(EXEEXT)
+       $(AM_V_CXXLD)$(CXXLINK) $(test_algs_OBJECTS) $(test_algs_LDADD) $(LIBS)
+
+test-bimap$(EXEEXT): $(test_bimap_OBJECTS) $(test_bimap_DEPENDENCIES) $(EXTRA_test_bimap_DEPENDENCIES) 
+       @rm -f test-bimap$(EXEEXT)
+       $(AM_V_CXXLD)$(CXXLINK) $(test_bimap_OBJECTS) $(test_bimap_LDADD) $(LIBS)
+
 test-buffer-serialize$(EXEEXT): $(test_buffer_serialize_OBJECTS) $(test_buffer_serialize_DEPENDENCIES) $(EXTRA_test_buffer_serialize_DEPENDENCIES) 
        @rm -f test-buffer-serialize$(EXEEXT)
        $(AM_V_CXXLD)$(CXXLINK) $(test_buffer_serialize_OBJECTS) $(test_buffer_serialize_LDADD) $(LIBS)
 
+test-gpos-size-params$(EXEEXT): $(test_gpos_size_params_OBJECTS) $(test_gpos_size_params_DEPENDENCIES) $(EXTRA_test_gpos_size_params_DEPENDENCIES) 
+       @rm -f test-gpos-size-params$(EXEEXT)
+       $(AM_V_CXXLD)$(CXXLINK) $(test_gpos_size_params_OBJECTS) $(test_gpos_size_params_LDADD) $(LIBS)
+
+test-gsub-would-substitute$(EXEEXT): $(test_gsub_would_substitute_OBJECTS) $(test_gsub_would_substitute_DEPENDENCIES) $(EXTRA_test_gsub_would_substitute_DEPENDENCIES) 
+       @rm -f test-gsub-would-substitute$(EXEEXT)
+       $(AM_V_CXXLD)$(CXXLINK) $(test_gsub_would_substitute_OBJECTS) $(test_gsub_would_substitute_LDADD) $(LIBS)
+
 test-iter$(EXEEXT): $(test_iter_OBJECTS) $(test_iter_DEPENDENCIES) $(EXTRA_test_iter_DEPENDENCIES) 
        @rm -f test-iter$(EXEEXT)
        $(AM_V_CXXLD)$(CXXLINK) $(test_iter_OBJECTS) $(test_iter_LDADD) $(LIBS)
 
-test-name-table$(EXEEXT): $(test_name_table_OBJECTS) $(test_name_table_DEPENDENCIES) $(EXTRA_test_name_table_DEPENDENCIES) 
-       @rm -f test-name-table$(EXEEXT)
-       $(AM_V_CXXLD)$(CXXLINK) $(test_name_table_OBJECTS) $(test_name_table_LDADD) $(LIBS)
+test-meta$(EXEEXT): $(test_meta_OBJECTS) $(test_meta_DEPENDENCIES) $(EXTRA_test_meta_DEPENDENCIES) 
+       @rm -f test-meta$(EXEEXT)
+       $(AM_V_CXXLD)$(CXXLINK) $(test_meta_OBJECTS) $(test_meta_LDADD) $(LIBS)
+
+test-number$(EXEEXT): $(test_number_OBJECTS) $(test_number_DEPENDENCIES) $(EXTRA_test_number_DEPENDENCIES) 
+       @rm -f test-number$(EXEEXT)
+       $(AM_V_CXXLD)$(CXXLINK) $(test_number_OBJECTS) $(test_number_LDADD) $(LIBS)
 
 test-ot-color$(EXEEXT): $(test_ot_color_OBJECTS) $(test_ot_color_DEPENDENCIES) $(EXTRA_test_ot_color_DEPENDENCIES) 
        @rm -f test-ot-color$(EXEEXT)
        $(AM_V_CXXLD)$(CXXLINK) $(test_ot_color_OBJECTS) $(test_ot_color_LDADD) $(LIBS)
 
+test-ot-meta$(EXEEXT): $(test_ot_meta_OBJECTS) $(test_ot_meta_DEPENDENCIES) $(EXTRA_test_ot_meta_DEPENDENCIES) 
+       @rm -f test-ot-meta$(EXEEXT)
+       $(AM_V_CXXLD)$(CXXLINK) $(test_ot_meta_OBJECTS) $(test_ot_meta_LDADD) $(LIBS)
+
+test-ot-name$(EXEEXT): $(test_ot_name_OBJECTS) $(test_ot_name_DEPENDENCIES) $(EXTRA_test_ot_name_DEPENDENCIES) 
+       @rm -f test-ot-name$(EXEEXT)
+       $(AM_V_CXXLD)$(CXXLINK) $(test_ot_name_OBJECTS) $(test_ot_name_LDADD) $(LIBS)
+
 test-ot-tag$(EXEEXT): $(test_ot_tag_OBJECTS) $(test_ot_tag_DEPENDENCIES) $(EXTRA_test_ot_tag_DEPENDENCIES) 
        @rm -f test-ot-tag$(EXEEXT)
        $(AM_V_CXXLD)$(CXXLINK) $(test_ot_tag_OBJECTS) $(test_ot_tag_LDADD) $(LIBS)
 
-test-size-params$(EXEEXT): $(test_size_params_OBJECTS) $(test_size_params_DEPENDENCIES) $(EXTRA_test_size_params_DEPENDENCIES) 
-       @rm -f test-size-params$(EXEEXT)
-       $(AM_V_CXXLD)$(CXXLINK) $(test_size_params_OBJECTS) $(test_size_params_LDADD) $(LIBS)
-
 test-unicode-ranges$(EXEEXT): $(test_unicode_ranges_OBJECTS) $(test_unicode_ranges_DEPENDENCIES) $(EXTRA_test_unicode_ranges_DEPENDENCIES) 
        @rm -f test-unicode-ranges$(EXEEXT)
        $(AM_V_CXXLD)$(CXXLINK) $(test_unicode_ranges_OBJECTS) $(test_unicode_ranges_LDADD) $(LIBS)
 
-test-would-substitute$(EXEEXT): $(test_would_substitute_OBJECTS) $(test_would_substitute_DEPENDENCIES) $(EXTRA_test_would_substitute_DEPENDENCIES) 
-       @rm -f test-would-substitute$(EXEEXT)
-       $(AM_V_CXXLD)$(CXXLINK) $(test_would_substitute_OBJECTS) $(test_would_substitute_LDADD) $(LIBS)
-
 mostlyclean-compile:
        -rm -f *.$(OBJEXT)
 
@@ -1794,10 +1898,12 @@ distclean-compile:
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libharfbuzz_la-hb-fallback-shape.Plo@am__quote@ # am--include-marker
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libharfbuzz_la-hb-font.Plo@am__quote@ # am--include-marker
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libharfbuzz_la-hb-ft.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libharfbuzz_la-hb-gdi.Plo@am__quote@ # am--include-marker
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libharfbuzz_la-hb-glib.Plo@am__quote@ # am--include-marker
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libharfbuzz_la-hb-graphite2.Plo@am__quote@ # am--include-marker
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libharfbuzz_la-hb-icu.Plo@am__quote@ # am--include-marker
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libharfbuzz_la-hb-map.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libharfbuzz_la-hb-number.Plo@am__quote@ # am--include-marker
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libharfbuzz_la-hb-ot-cff1-table.Plo@am__quote@ # am--include-marker
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libharfbuzz_la-hb-ot-cff2-table.Plo@am__quote@ # am--include-marker
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libharfbuzz_la-hb-ot-color.Plo@am__quote@ # am--include-marker
@@ -1806,7 +1912,8 @@ distclean-compile:
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libharfbuzz_la-hb-ot-layout.Plo@am__quote@ # am--include-marker
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libharfbuzz_la-hb-ot-map.Plo@am__quote@ # am--include-marker
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libharfbuzz_la-hb-ot-math.Plo@am__quote@ # am--include-marker
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libharfbuzz_la-hb-ot-name-language.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libharfbuzz_la-hb-ot-meta.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libharfbuzz_la-hb-ot-metrics.Plo@am__quote@ # am--include-marker
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libharfbuzz_la-hb-ot-name.Plo@am__quote@ # am--include-marker
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libharfbuzz_la-hb-ot-shape-complex-arabic.Plo@am__quote@ # am--include-marker
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libharfbuzz_la-hb-ot-shape-complex-default.Plo@am__quote@ # am--include-marker
@@ -1830,31 +1937,39 @@ distclean-compile:
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libharfbuzz_la-hb-shape.Plo@am__quote@ # am--include-marker
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libharfbuzz_la-hb-shaper.Plo@am__quote@ # am--include-marker
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libharfbuzz_la-hb-static.Plo@am__quote@ # am--include-marker
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libharfbuzz_la-hb-ucdn.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libharfbuzz_la-hb-ucd.Plo@am__quote@ # am--include-marker
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libharfbuzz_la-hb-unicode.Plo@am__quote@ # am--include-marker
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libharfbuzz_la-hb-uniscribe.Plo@am__quote@ # am--include-marker
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libharfbuzz_la-hb-warning.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libharfbuzz_subset_la-hb-number.Plo@am__quote@ # am--include-marker
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libharfbuzz_subset_la-hb-ot-cff1-table.Plo@am__quote@ # am--include-marker
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libharfbuzz_subset_la-hb-ot-cff2-table.Plo@am__quote@ # am--include-marker
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libharfbuzz_subset_la-hb-static.Plo@am__quote@ # am--include-marker
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libharfbuzz_subset_la-hb-subset-cff-common.Plo@am__quote@ # am--include-marker
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libharfbuzz_subset_la-hb-subset-cff1.Plo@am__quote@ # am--include-marker
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libharfbuzz_subset_la-hb-subset-cff2.Plo@am__quote@ # am--include-marker
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libharfbuzz_subset_la-hb-subset-glyf.Plo@am__quote@ # am--include-marker
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libharfbuzz_subset_la-hb-subset-input.Plo@am__quote@ # am--include-marker
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libharfbuzz_subset_la-hb-subset-plan.Plo@am__quote@ # am--include-marker
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libharfbuzz_subset_la-hb-subset.Plo@am__quote@ # am--include-marker
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/main-main.Po@am__quote@ # am--include-marker
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test-test.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_algs-hb-static.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_algs-test-algs.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_bimap-hb-static.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_bimap-test-bimap.Po@am__quote@ # am--include-marker
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_buffer_serialize-test-buffer-serialize.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_gpos_size_params-test-gpos-size-params.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_gsub_would_substitute-test-gsub-would-substitute.Po@am__quote@ # am--include-marker
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_iter-hb-static.Po@am__quote@ # am--include-marker
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_iter-test-iter.Po@am__quote@ # am--include-marker
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_name_table-test-name-table.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_meta-hb-static.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_meta-test-meta.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_number-hb-number.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_number-test-number.Po@am__quote@ # am--include-marker
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_ot_color-test-ot-color.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_ot_meta-test-ot-meta.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_ot_name-test-ot-name.Po@am__quote@ # am--include-marker
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_ot_tag-hb-ot-tag.Po@am__quote@ # am--include-marker
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_size_params-test-size-params.Po@am__quote@ # am--include-marker
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_unicode_ranges-test-unicode-ranges.Po@am__quote@ # am--include-marker
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_would_substitute-test-would-substitute.Po@am__quote@ # am--include-marker
 
 $(am__depfiles_remade):
        @$(MKDIR_P) $(@D)
@@ -1904,6 +2019,13 @@ libharfbuzz_icu_la-hb-icu.lo: hb-icu.cc
 @AMDEP_TRUE@@am__fastdepCXX_FALSE@     DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
 @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libharfbuzz_icu_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o libharfbuzz_icu_la-hb-icu.lo `test -f 'hb-icu.cc' || echo '$(srcdir)/'`hb-icu.cc
 
+libharfbuzz_subset_la-hb-number.lo: hb-number.cc
+@am__fastdepCXX_TRUE@  $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libharfbuzz_subset_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT libharfbuzz_subset_la-hb-number.lo -MD -MP -MF $(DEPDIR)/libharfbuzz_subset_la-hb-number.Tpo -c -o libharfbuzz_subset_la-hb-number.lo `test -f 'hb-number.cc' || echo '$(srcdir)/'`hb-number.cc
+@am__fastdepCXX_TRUE@  $(AM_V_at)$(am__mv) $(DEPDIR)/libharfbuzz_subset_la-hb-number.Tpo $(DEPDIR)/libharfbuzz_subset_la-hb-number.Plo
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@     $(AM_V_CXX)source='hb-number.cc' object='libharfbuzz_subset_la-hb-number.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@     DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libharfbuzz_subset_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o libharfbuzz_subset_la-hb-number.lo `test -f 'hb-number.cc' || echo '$(srcdir)/'`hb-number.cc
+
 libharfbuzz_subset_la-hb-ot-cff1-table.lo: hb-ot-cff1-table.cc
 @am__fastdepCXX_TRUE@  $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libharfbuzz_subset_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT libharfbuzz_subset_la-hb-ot-cff1-table.lo -MD -MP -MF $(DEPDIR)/libharfbuzz_subset_la-hb-ot-cff1-table.Tpo -c -o libharfbuzz_subset_la-hb-ot-cff1-table.lo `test -f 'hb-ot-cff1-table.cc' || echo '$(srcdir)/'`hb-ot-cff1-table.cc
 @am__fastdepCXX_TRUE@  $(AM_V_at)$(am__mv) $(DEPDIR)/libharfbuzz_subset_la-hb-ot-cff1-table.Tpo $(DEPDIR)/libharfbuzz_subset_la-hb-ot-cff1-table.Plo
@@ -1946,13 +2068,6 @@ libharfbuzz_subset_la-hb-subset-cff2.lo: hb-subset-cff2.cc
 @AMDEP_TRUE@@am__fastdepCXX_FALSE@     DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
 @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libharfbuzz_subset_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o libharfbuzz_subset_la-hb-subset-cff2.lo `test -f 'hb-subset-cff2.cc' || echo '$(srcdir)/'`hb-subset-cff2.cc
 
-libharfbuzz_subset_la-hb-subset-glyf.lo: hb-subset-glyf.cc
-@am__fastdepCXX_TRUE@  $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libharfbuzz_subset_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT libharfbuzz_subset_la-hb-subset-glyf.lo -MD -MP -MF $(DEPDIR)/libharfbuzz_subset_la-hb-subset-glyf.Tpo -c -o libharfbuzz_subset_la-hb-subset-glyf.lo `test -f 'hb-subset-glyf.cc' || echo '$(srcdir)/'`hb-subset-glyf.cc
-@am__fastdepCXX_TRUE@  $(AM_V_at)$(am__mv) $(DEPDIR)/libharfbuzz_subset_la-hb-subset-glyf.Tpo $(DEPDIR)/libharfbuzz_subset_la-hb-subset-glyf.Plo
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@     $(AM_V_CXX)source='hb-subset-glyf.cc' object='libharfbuzz_subset_la-hb-subset-glyf.lo' libtool=yes @AMDEPBACKSLASH@
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@     DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libharfbuzz_subset_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o libharfbuzz_subset_la-hb-subset-glyf.lo `test -f 'hb-subset-glyf.cc' || echo '$(srcdir)/'`hb-subset-glyf.cc
-
 libharfbuzz_subset_la-hb-subset-input.lo: hb-subset-input.cc
 @am__fastdepCXX_TRUE@  $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libharfbuzz_subset_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT libharfbuzz_subset_la-hb-subset-input.lo -MD -MP -MF $(DEPDIR)/libharfbuzz_subset_la-hb-subset-input.Tpo -c -o libharfbuzz_subset_la-hb-subset-input.lo `test -f 'hb-subset-input.cc' || echo '$(srcdir)/'`hb-subset-input.cc
 @am__fastdepCXX_TRUE@  $(AM_V_at)$(am__mv) $(DEPDIR)/libharfbuzz_subset_la-hb-subset-input.Tpo $(DEPDIR)/libharfbuzz_subset_la-hb-subset-input.Plo
@@ -2023,6 +2138,13 @@ libharfbuzz_la-hb-face.lo: hb-face.cc
 @AMDEP_TRUE@@am__fastdepCXX_FALSE@     DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
 @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libharfbuzz_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o libharfbuzz_la-hb-face.lo `test -f 'hb-face.cc' || echo '$(srcdir)/'`hb-face.cc
 
+libharfbuzz_la-hb-fallback-shape.lo: hb-fallback-shape.cc
+@am__fastdepCXX_TRUE@  $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libharfbuzz_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT libharfbuzz_la-hb-fallback-shape.lo -MD -MP -MF $(DEPDIR)/libharfbuzz_la-hb-fallback-shape.Tpo -c -o libharfbuzz_la-hb-fallback-shape.lo `test -f 'hb-fallback-shape.cc' || echo '$(srcdir)/'`hb-fallback-shape.cc
+@am__fastdepCXX_TRUE@  $(AM_V_at)$(am__mv) $(DEPDIR)/libharfbuzz_la-hb-fallback-shape.Tpo $(DEPDIR)/libharfbuzz_la-hb-fallback-shape.Plo
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@     $(AM_V_CXX)source='hb-fallback-shape.cc' object='libharfbuzz_la-hb-fallback-shape.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@     DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libharfbuzz_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o libharfbuzz_la-hb-fallback-shape.lo `test -f 'hb-fallback-shape.cc' || echo '$(srcdir)/'`hb-fallback-shape.cc
+
 libharfbuzz_la-hb-font.lo: hb-font.cc
 @am__fastdepCXX_TRUE@  $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libharfbuzz_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT libharfbuzz_la-hb-font.lo -MD -MP -MF $(DEPDIR)/libharfbuzz_la-hb-font.Tpo -c -o libharfbuzz_la-hb-font.lo `test -f 'hb-font.cc' || echo '$(srcdir)/'`hb-font.cc
 @am__fastdepCXX_TRUE@  $(AM_V_at)$(am__mv) $(DEPDIR)/libharfbuzz_la-hb-font.Tpo $(DEPDIR)/libharfbuzz_la-hb-font.Plo
@@ -2037,6 +2159,13 @@ libharfbuzz_la-hb-map.lo: hb-map.cc
 @AMDEP_TRUE@@am__fastdepCXX_FALSE@     DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
 @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libharfbuzz_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o libharfbuzz_la-hb-map.lo `test -f 'hb-map.cc' || echo '$(srcdir)/'`hb-map.cc
 
+libharfbuzz_la-hb-number.lo: hb-number.cc
+@am__fastdepCXX_TRUE@  $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libharfbuzz_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT libharfbuzz_la-hb-number.lo -MD -MP -MF $(DEPDIR)/libharfbuzz_la-hb-number.Tpo -c -o libharfbuzz_la-hb-number.lo `test -f 'hb-number.cc' || echo '$(srcdir)/'`hb-number.cc
+@am__fastdepCXX_TRUE@  $(AM_V_at)$(am__mv) $(DEPDIR)/libharfbuzz_la-hb-number.Tpo $(DEPDIR)/libharfbuzz_la-hb-number.Plo
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@     $(AM_V_CXX)source='hb-number.cc' object='libharfbuzz_la-hb-number.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@     DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libharfbuzz_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o libharfbuzz_la-hb-number.lo `test -f 'hb-number.cc' || echo '$(srcdir)/'`hb-number.cc
+
 libharfbuzz_la-hb-ot-cff1-table.lo: hb-ot-cff1-table.cc
 @am__fastdepCXX_TRUE@  $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libharfbuzz_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT libharfbuzz_la-hb-ot-cff1-table.lo -MD -MP -MF $(DEPDIR)/libharfbuzz_la-hb-ot-cff1-table.Tpo -c -o libharfbuzz_la-hb-ot-cff1-table.lo `test -f 'hb-ot-cff1-table.cc' || echo '$(srcdir)/'`hb-ot-cff1-table.cc
 @am__fastdepCXX_TRUE@  $(AM_V_at)$(am__mv) $(DEPDIR)/libharfbuzz_la-hb-ot-cff1-table.Tpo $(DEPDIR)/libharfbuzz_la-hb-ot-cff1-table.Plo
@@ -2093,12 +2222,19 @@ libharfbuzz_la-hb-ot-math.lo: hb-ot-math.cc
 @AMDEP_TRUE@@am__fastdepCXX_FALSE@     DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
 @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libharfbuzz_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o libharfbuzz_la-hb-ot-math.lo `test -f 'hb-ot-math.cc' || echo '$(srcdir)/'`hb-ot-math.cc
 
-libharfbuzz_la-hb-ot-name-language.lo: hb-ot-name-language.cc
-@am__fastdepCXX_TRUE@  $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libharfbuzz_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT libharfbuzz_la-hb-ot-name-language.lo -MD -MP -MF $(DEPDIR)/libharfbuzz_la-hb-ot-name-language.Tpo -c -o libharfbuzz_la-hb-ot-name-language.lo `test -f 'hb-ot-name-language.cc' || echo '$(srcdir)/'`hb-ot-name-language.cc
-@am__fastdepCXX_TRUE@  $(AM_V_at)$(am__mv) $(DEPDIR)/libharfbuzz_la-hb-ot-name-language.Tpo $(DEPDIR)/libharfbuzz_la-hb-ot-name-language.Plo
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@     $(AM_V_CXX)source='hb-ot-name-language.cc' object='libharfbuzz_la-hb-ot-name-language.lo' libtool=yes @AMDEPBACKSLASH@
+libharfbuzz_la-hb-ot-meta.lo: hb-ot-meta.cc
+@am__fastdepCXX_TRUE@  $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libharfbuzz_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT libharfbuzz_la-hb-ot-meta.lo -MD -MP -MF $(DEPDIR)/libharfbuzz_la-hb-ot-meta.Tpo -c -o libharfbuzz_la-hb-ot-meta.lo `test -f 'hb-ot-meta.cc' || echo '$(srcdir)/'`hb-ot-meta.cc
+@am__fastdepCXX_TRUE@  $(AM_V_at)$(am__mv) $(DEPDIR)/libharfbuzz_la-hb-ot-meta.Tpo $(DEPDIR)/libharfbuzz_la-hb-ot-meta.Plo
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@     $(AM_V_CXX)source='hb-ot-meta.cc' object='libharfbuzz_la-hb-ot-meta.lo' libtool=yes @AMDEPBACKSLASH@
 @AMDEP_TRUE@@am__fastdepCXX_FALSE@     DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libharfbuzz_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o libharfbuzz_la-hb-ot-name-language.lo `test -f 'hb-ot-name-language.cc' || echo '$(srcdir)/'`hb-ot-name-language.cc
+@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libharfbuzz_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o libharfbuzz_la-hb-ot-meta.lo `test -f 'hb-ot-meta.cc' || echo '$(srcdir)/'`hb-ot-meta.cc
+
+libharfbuzz_la-hb-ot-metrics.lo: hb-ot-metrics.cc
+@am__fastdepCXX_TRUE@  $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libharfbuzz_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT libharfbuzz_la-hb-ot-metrics.lo -MD -MP -MF $(DEPDIR)/libharfbuzz_la-hb-ot-metrics.Tpo -c -o libharfbuzz_la-hb-ot-metrics.lo `test -f 'hb-ot-metrics.cc' || echo '$(srcdir)/'`hb-ot-metrics.cc
+@am__fastdepCXX_TRUE@  $(AM_V_at)$(am__mv) $(DEPDIR)/libharfbuzz_la-hb-ot-metrics.Tpo $(DEPDIR)/libharfbuzz_la-hb-ot-metrics.Plo
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@     $(AM_V_CXX)source='hb-ot-metrics.cc' object='libharfbuzz_la-hb-ot-metrics.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@     DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libharfbuzz_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o libharfbuzz_la-hb-ot-metrics.lo `test -f 'hb-ot-metrics.cc' || echo '$(srcdir)/'`hb-ot-metrics.cc
 
 libharfbuzz_la-hb-ot-name.lo: hb-ot-name.cc
 @am__fastdepCXX_TRUE@  $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libharfbuzz_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT libharfbuzz_la-hb-ot-name.lo -MD -MP -MF $(DEPDIR)/libharfbuzz_la-hb-ot-name.Tpo -c -o libharfbuzz_la-hb-ot-name.lo `test -f 'hb-ot-name.cc' || echo '$(srcdir)/'`hb-ot-name.cc
@@ -2261,6 +2397,13 @@ libharfbuzz_la-hb-static.lo: hb-static.cc
 @AMDEP_TRUE@@am__fastdepCXX_FALSE@     DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
 @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libharfbuzz_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o libharfbuzz_la-hb-static.lo `test -f 'hb-static.cc' || echo '$(srcdir)/'`hb-static.cc
 
+libharfbuzz_la-hb-ucd.lo: hb-ucd.cc
+@am__fastdepCXX_TRUE@  $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libharfbuzz_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT libharfbuzz_la-hb-ucd.lo -MD -MP -MF $(DEPDIR)/libharfbuzz_la-hb-ucd.Tpo -c -o libharfbuzz_la-hb-ucd.lo `test -f 'hb-ucd.cc' || echo '$(srcdir)/'`hb-ucd.cc
+@am__fastdepCXX_TRUE@  $(AM_V_at)$(am__mv) $(DEPDIR)/libharfbuzz_la-hb-ucd.Tpo $(DEPDIR)/libharfbuzz_la-hb-ucd.Plo
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@     $(AM_V_CXX)source='hb-ucd.cc' object='libharfbuzz_la-hb-ucd.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@     DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libharfbuzz_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o libharfbuzz_la-hb-ucd.lo `test -f 'hb-ucd.cc' || echo '$(srcdir)/'`hb-ucd.cc
+
 libharfbuzz_la-hb-unicode.lo: hb-unicode.cc
 @am__fastdepCXX_TRUE@  $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libharfbuzz_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT libharfbuzz_la-hb-unicode.lo -MD -MP -MF $(DEPDIR)/libharfbuzz_la-hb-unicode.Tpo -c -o libharfbuzz_la-hb-unicode.lo `test -f 'hb-unicode.cc' || echo '$(srcdir)/'`hb-unicode.cc
 @am__fastdepCXX_TRUE@  $(AM_V_at)$(am__mv) $(DEPDIR)/libharfbuzz_la-hb-unicode.Tpo $(DEPDIR)/libharfbuzz_la-hb-unicode.Plo
@@ -2268,20 +2411,6 @@ libharfbuzz_la-hb-unicode.lo: hb-unicode.cc
 @AMDEP_TRUE@@am__fastdepCXX_FALSE@     DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
 @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libharfbuzz_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o libharfbuzz_la-hb-unicode.lo `test -f 'hb-unicode.cc' || echo '$(srcdir)/'`hb-unicode.cc
 
-libharfbuzz_la-hb-warning.lo: hb-warning.cc
-@am__fastdepCXX_TRUE@  $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libharfbuzz_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT libharfbuzz_la-hb-warning.lo -MD -MP -MF $(DEPDIR)/libharfbuzz_la-hb-warning.Tpo -c -o libharfbuzz_la-hb-warning.lo `test -f 'hb-warning.cc' || echo '$(srcdir)/'`hb-warning.cc
-@am__fastdepCXX_TRUE@  $(AM_V_at)$(am__mv) $(DEPDIR)/libharfbuzz_la-hb-warning.Tpo $(DEPDIR)/libharfbuzz_la-hb-warning.Plo
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@     $(AM_V_CXX)source='hb-warning.cc' object='libharfbuzz_la-hb-warning.lo' libtool=yes @AMDEPBACKSLASH@
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@     DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libharfbuzz_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o libharfbuzz_la-hb-warning.lo `test -f 'hb-warning.cc' || echo '$(srcdir)/'`hb-warning.cc
-
-libharfbuzz_la-hb-fallback-shape.lo: hb-fallback-shape.cc
-@am__fastdepCXX_TRUE@  $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libharfbuzz_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT libharfbuzz_la-hb-fallback-shape.lo -MD -MP -MF $(DEPDIR)/libharfbuzz_la-hb-fallback-shape.Tpo -c -o libharfbuzz_la-hb-fallback-shape.lo `test -f 'hb-fallback-shape.cc' || echo '$(srcdir)/'`hb-fallback-shape.cc
-@am__fastdepCXX_TRUE@  $(AM_V_at)$(am__mv) $(DEPDIR)/libharfbuzz_la-hb-fallback-shape.Tpo $(DEPDIR)/libharfbuzz_la-hb-fallback-shape.Plo
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@     $(AM_V_CXX)source='hb-fallback-shape.cc' object='libharfbuzz_la-hb-fallback-shape.lo' libtool=yes @AMDEPBACKSLASH@
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@     DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libharfbuzz_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o libharfbuzz_la-hb-fallback-shape.lo `test -f 'hb-fallback-shape.cc' || echo '$(srcdir)/'`hb-fallback-shape.cc
-
 libharfbuzz_la-hb-glib.lo: hb-glib.cc
 @am__fastdepCXX_TRUE@  $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libharfbuzz_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT libharfbuzz_la-hb-glib.lo -MD -MP -MF $(DEPDIR)/libharfbuzz_la-hb-glib.Tpo -c -o libharfbuzz_la-hb-glib.lo `test -f 'hb-glib.cc' || echo '$(srcdir)/'`hb-glib.cc
 @am__fastdepCXX_TRUE@  $(AM_V_at)$(am__mv) $(DEPDIR)/libharfbuzz_la-hb-glib.Tpo $(DEPDIR)/libharfbuzz_la-hb-glib.Plo
@@ -2317,6 +2446,13 @@ libharfbuzz_la-hb-directwrite.lo: hb-directwrite.cc
 @AMDEP_TRUE@@am__fastdepCXX_FALSE@     DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
 @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libharfbuzz_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o libharfbuzz_la-hb-directwrite.lo `test -f 'hb-directwrite.cc' || echo '$(srcdir)/'`hb-directwrite.cc
 
+libharfbuzz_la-hb-gdi.lo: hb-gdi.cc
+@am__fastdepCXX_TRUE@  $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libharfbuzz_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT libharfbuzz_la-hb-gdi.lo -MD -MP -MF $(DEPDIR)/libharfbuzz_la-hb-gdi.Tpo -c -o libharfbuzz_la-hb-gdi.lo `test -f 'hb-gdi.cc' || echo '$(srcdir)/'`hb-gdi.cc
+@am__fastdepCXX_TRUE@  $(AM_V_at)$(am__mv) $(DEPDIR)/libharfbuzz_la-hb-gdi.Tpo $(DEPDIR)/libharfbuzz_la-hb-gdi.Plo
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@     $(AM_V_CXX)source='hb-gdi.cc' object='libharfbuzz_la-hb-gdi.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@     DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libharfbuzz_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o libharfbuzz_la-hb-gdi.lo `test -f 'hb-gdi.cc' || echo '$(srcdir)/'`hb-gdi.cc
+
 libharfbuzz_la-hb-coretext.lo: hb-coretext.cc
 @am__fastdepCXX_TRUE@  $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libharfbuzz_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT libharfbuzz_la-hb-coretext.lo -MD -MP -MF $(DEPDIR)/libharfbuzz_la-hb-coretext.Tpo -c -o libharfbuzz_la-hb-coretext.lo `test -f 'hb-coretext.cc' || echo '$(srcdir)/'`hb-coretext.cc
 @am__fastdepCXX_TRUE@  $(AM_V_at)$(am__mv) $(DEPDIR)/libharfbuzz_la-hb-coretext.Tpo $(DEPDIR)/libharfbuzz_la-hb-coretext.Plo
@@ -2324,13 +2460,6 @@ libharfbuzz_la-hb-coretext.lo: hb-coretext.cc
 @AMDEP_TRUE@@am__fastdepCXX_FALSE@     DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
 @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libharfbuzz_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o libharfbuzz_la-hb-coretext.lo `test -f 'hb-coretext.cc' || echo '$(srcdir)/'`hb-coretext.cc
 
-libharfbuzz_la-hb-ucdn.lo: hb-ucdn.cc
-@am__fastdepCXX_TRUE@  $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libharfbuzz_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT libharfbuzz_la-hb-ucdn.lo -MD -MP -MF $(DEPDIR)/libharfbuzz_la-hb-ucdn.Tpo -c -o libharfbuzz_la-hb-ucdn.lo `test -f 'hb-ucdn.cc' || echo '$(srcdir)/'`hb-ucdn.cc
-@am__fastdepCXX_TRUE@  $(AM_V_at)$(am__mv) $(DEPDIR)/libharfbuzz_la-hb-ucdn.Tpo $(DEPDIR)/libharfbuzz_la-hb-ucdn.Plo
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@     $(AM_V_CXX)source='hb-ucdn.cc' object='libharfbuzz_la-hb-ucdn.lo' libtool=yes @AMDEPBACKSLASH@
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@     DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libharfbuzz_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o libharfbuzz_la-hb-ucdn.lo `test -f 'hb-ucdn.cc' || echo '$(srcdir)/'`hb-ucdn.cc
-
 libharfbuzz_la-hb-icu.lo: hb-icu.cc
 @am__fastdepCXX_TRUE@  $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libharfbuzz_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT libharfbuzz_la-hb-icu.lo -MD -MP -MF $(DEPDIR)/libharfbuzz_la-hb-icu.Tpo -c -o libharfbuzz_la-hb-icu.lo `test -f 'hb-icu.cc' || echo '$(srcdir)/'`hb-icu.cc
 @am__fastdepCXX_TRUE@  $(AM_V_at)$(am__mv) $(DEPDIR)/libharfbuzz_la-hb-icu.Tpo $(DEPDIR)/libharfbuzz_la-hb-icu.Plo
@@ -2478,6 +2607,62 @@ test-test.obj: test.cc
 @AMDEP_TRUE@@am__fastdepCXX_FALSE@     DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
 @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o test-test.obj `if test -f 'test.cc'; then $(CYGPATH_W) 'test.cc'; else $(CYGPATH_W) '$(srcdir)/test.cc'; fi`
 
+test_algs-test-algs.o: test-algs.cc
+@am__fastdepCXX_TRUE@  $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_algs_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT test_algs-test-algs.o -MD -MP -MF $(DEPDIR)/test_algs-test-algs.Tpo -c -o test_algs-test-algs.o `test -f 'test-algs.cc' || echo '$(srcdir)/'`test-algs.cc
+@am__fastdepCXX_TRUE@  $(AM_V_at)$(am__mv) $(DEPDIR)/test_algs-test-algs.Tpo $(DEPDIR)/test_algs-test-algs.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@     $(AM_V_CXX)source='test-algs.cc' object='test_algs-test-algs.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@     DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_algs_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o test_algs-test-algs.o `test -f 'test-algs.cc' || echo '$(srcdir)/'`test-algs.cc
+
+test_algs-test-algs.obj: test-algs.cc
+@am__fastdepCXX_TRUE@  $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_algs_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT test_algs-test-algs.obj -MD -MP -MF $(DEPDIR)/test_algs-test-algs.Tpo -c -o test_algs-test-algs.obj `if test -f 'test-algs.cc'; then $(CYGPATH_W) 'test-algs.cc'; else $(CYGPATH_W) '$(srcdir)/test-algs.cc'; fi`
+@am__fastdepCXX_TRUE@  $(AM_V_at)$(am__mv) $(DEPDIR)/test_algs-test-algs.Tpo $(DEPDIR)/test_algs-test-algs.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@     $(AM_V_CXX)source='test-algs.cc' object='test_algs-test-algs.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@     DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_algs_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o test_algs-test-algs.obj `if test -f 'test-algs.cc'; then $(CYGPATH_W) 'test-algs.cc'; else $(CYGPATH_W) '$(srcdir)/test-algs.cc'; fi`
+
+test_algs-hb-static.o: hb-static.cc
+@am__fastdepCXX_TRUE@  $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_algs_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT test_algs-hb-static.o -MD -MP -MF $(DEPDIR)/test_algs-hb-static.Tpo -c -o test_algs-hb-static.o `test -f 'hb-static.cc' || echo '$(srcdir)/'`hb-static.cc
+@am__fastdepCXX_TRUE@  $(AM_V_at)$(am__mv) $(DEPDIR)/test_algs-hb-static.Tpo $(DEPDIR)/test_algs-hb-static.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@     $(AM_V_CXX)source='hb-static.cc' object='test_algs-hb-static.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@     DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_algs_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o test_algs-hb-static.o `test -f 'hb-static.cc' || echo '$(srcdir)/'`hb-static.cc
+
+test_algs-hb-static.obj: hb-static.cc
+@am__fastdepCXX_TRUE@  $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_algs_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT test_algs-hb-static.obj -MD -MP -MF $(DEPDIR)/test_algs-hb-static.Tpo -c -o test_algs-hb-static.obj `if test -f 'hb-static.cc'; then $(CYGPATH_W) 'hb-static.cc'; else $(CYGPATH_W) '$(srcdir)/hb-static.cc'; fi`
+@am__fastdepCXX_TRUE@  $(AM_V_at)$(am__mv) $(DEPDIR)/test_algs-hb-static.Tpo $(DEPDIR)/test_algs-hb-static.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@     $(AM_V_CXX)source='hb-static.cc' object='test_algs-hb-static.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@     DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_algs_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o test_algs-hb-static.obj `if test -f 'hb-static.cc'; then $(CYGPATH_W) 'hb-static.cc'; else $(CYGPATH_W) '$(srcdir)/hb-static.cc'; fi`
+
+test_bimap-test-bimap.o: test-bimap.cc
+@am__fastdepCXX_TRUE@  $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_bimap_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT test_bimap-test-bimap.o -MD -MP -MF $(DEPDIR)/test_bimap-test-bimap.Tpo -c -o test_bimap-test-bimap.o `test -f 'test-bimap.cc' || echo '$(srcdir)/'`test-bimap.cc
+@am__fastdepCXX_TRUE@  $(AM_V_at)$(am__mv) $(DEPDIR)/test_bimap-test-bimap.Tpo $(DEPDIR)/test_bimap-test-bimap.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@     $(AM_V_CXX)source='test-bimap.cc' object='test_bimap-test-bimap.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@     DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_bimap_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o test_bimap-test-bimap.o `test -f 'test-bimap.cc' || echo '$(srcdir)/'`test-bimap.cc
+
+test_bimap-test-bimap.obj: test-bimap.cc
+@am__fastdepCXX_TRUE@  $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_bimap_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT test_bimap-test-bimap.obj -MD -MP -MF $(DEPDIR)/test_bimap-test-bimap.Tpo -c -o test_bimap-test-bimap.obj `if test -f 'test-bimap.cc'; then $(CYGPATH_W) 'test-bimap.cc'; else $(CYGPATH_W) '$(srcdir)/test-bimap.cc'; fi`
+@am__fastdepCXX_TRUE@  $(AM_V_at)$(am__mv) $(DEPDIR)/test_bimap-test-bimap.Tpo $(DEPDIR)/test_bimap-test-bimap.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@     $(AM_V_CXX)source='test-bimap.cc' object='test_bimap-test-bimap.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@     DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_bimap_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o test_bimap-test-bimap.obj `if test -f 'test-bimap.cc'; then $(CYGPATH_W) 'test-bimap.cc'; else $(CYGPATH_W) '$(srcdir)/test-bimap.cc'; fi`
+
+test_bimap-hb-static.o: hb-static.cc
+@am__fastdepCXX_TRUE@  $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_bimap_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT test_bimap-hb-static.o -MD -MP -MF $(DEPDIR)/test_bimap-hb-static.Tpo -c -o test_bimap-hb-static.o `test -f 'hb-static.cc' || echo '$(srcdir)/'`hb-static.cc
+@am__fastdepCXX_TRUE@  $(AM_V_at)$(am__mv) $(DEPDIR)/test_bimap-hb-static.Tpo $(DEPDIR)/test_bimap-hb-static.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@     $(AM_V_CXX)source='hb-static.cc' object='test_bimap-hb-static.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@     DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_bimap_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o test_bimap-hb-static.o `test -f 'hb-static.cc' || echo '$(srcdir)/'`hb-static.cc
+
+test_bimap-hb-static.obj: hb-static.cc
+@am__fastdepCXX_TRUE@  $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_bimap_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT test_bimap-hb-static.obj -MD -MP -MF $(DEPDIR)/test_bimap-hb-static.Tpo -c -o test_bimap-hb-static.obj `if test -f 'hb-static.cc'; then $(CYGPATH_W) 'hb-static.cc'; else $(CYGPATH_W) '$(srcdir)/hb-static.cc'; fi`
+@am__fastdepCXX_TRUE@  $(AM_V_at)$(am__mv) $(DEPDIR)/test_bimap-hb-static.Tpo $(DEPDIR)/test_bimap-hb-static.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@     $(AM_V_CXX)source='hb-static.cc' object='test_bimap-hb-static.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@     DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_bimap_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o test_bimap-hb-static.obj `if test -f 'hb-static.cc'; then $(CYGPATH_W) 'hb-static.cc'; else $(CYGPATH_W) '$(srcdir)/hb-static.cc'; fi`
+
 test_buffer_serialize-test-buffer-serialize.o: test-buffer-serialize.cc
 @am__fastdepCXX_TRUE@  $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_buffer_serialize_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT test_buffer_serialize-test-buffer-serialize.o -MD -MP -MF $(DEPDIR)/test_buffer_serialize-test-buffer-serialize.Tpo -c -o test_buffer_serialize-test-buffer-serialize.o `test -f 'test-buffer-serialize.cc' || echo '$(srcdir)/'`test-buffer-serialize.cc
 @am__fastdepCXX_TRUE@  $(AM_V_at)$(am__mv) $(DEPDIR)/test_buffer_serialize-test-buffer-serialize.Tpo $(DEPDIR)/test_buffer_serialize-test-buffer-serialize.Po
@@ -2492,6 +2677,34 @@ test_buffer_serialize-test-buffer-serialize.obj: test-buffer-serialize.cc
 @AMDEP_TRUE@@am__fastdepCXX_FALSE@     DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
 @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_buffer_serialize_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o test_buffer_serialize-test-buffer-serialize.obj `if test -f 'test-buffer-serialize.cc'; then $(CYGPATH_W) 'test-buffer-serialize.cc'; else $(CYGPATH_W) '$(srcdir)/test-buffer-serialize.cc'; fi`
 
+test_gpos_size_params-test-gpos-size-params.o: test-gpos-size-params.cc
+@am__fastdepCXX_TRUE@  $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_gpos_size_params_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT test_gpos_size_params-test-gpos-size-params.o -MD -MP -MF $(DEPDIR)/test_gpos_size_params-test-gpos-size-params.Tpo -c -o test_gpos_size_params-test-gpos-size-params.o `test -f 'test-gpos-size-params.cc' || echo '$(srcdir)/'`test-gpos-size-params.cc
+@am__fastdepCXX_TRUE@  $(AM_V_at)$(am__mv) $(DEPDIR)/test_gpos_size_params-test-gpos-size-params.Tpo $(DEPDIR)/test_gpos_size_params-test-gpos-size-params.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@     $(AM_V_CXX)source='test-gpos-size-params.cc' object='test_gpos_size_params-test-gpos-size-params.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@     DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_gpos_size_params_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o test_gpos_size_params-test-gpos-size-params.o `test -f 'test-gpos-size-params.cc' || echo '$(srcdir)/'`test-gpos-size-params.cc
+
+test_gpos_size_params-test-gpos-size-params.obj: test-gpos-size-params.cc
+@am__fastdepCXX_TRUE@  $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_gpos_size_params_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT test_gpos_size_params-test-gpos-size-params.obj -MD -MP -MF $(DEPDIR)/test_gpos_size_params-test-gpos-size-params.Tpo -c -o test_gpos_size_params-test-gpos-size-params.obj `if test -f 'test-gpos-size-params.cc'; then $(CYGPATH_W) 'test-gpos-size-params.cc'; else $(CYGPATH_W) '$(srcdir)/test-gpos-size-params.cc'; fi`
+@am__fastdepCXX_TRUE@  $(AM_V_at)$(am__mv) $(DEPDIR)/test_gpos_size_params-test-gpos-size-params.Tpo $(DEPDIR)/test_gpos_size_params-test-gpos-size-params.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@     $(AM_V_CXX)source='test-gpos-size-params.cc' object='test_gpos_size_params-test-gpos-size-params.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@     DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_gpos_size_params_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o test_gpos_size_params-test-gpos-size-params.obj `if test -f 'test-gpos-size-params.cc'; then $(CYGPATH_W) 'test-gpos-size-params.cc'; else $(CYGPATH_W) '$(srcdir)/test-gpos-size-params.cc'; fi`
+
+test_gsub_would_substitute-test-gsub-would-substitute.o: test-gsub-would-substitute.cc
+@am__fastdepCXX_TRUE@  $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_gsub_would_substitute_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT test_gsub_would_substitute-test-gsub-would-substitute.o -MD -MP -MF $(DEPDIR)/test_gsub_would_substitute-test-gsub-would-substitute.Tpo -c -o test_gsub_would_substitute-test-gsub-would-substitute.o `test -f 'test-gsub-would-substitute.cc' || echo '$(srcdir)/'`test-gsub-would-substitute.cc
+@am__fastdepCXX_TRUE@  $(AM_V_at)$(am__mv) $(DEPDIR)/test_gsub_would_substitute-test-gsub-would-substitute.Tpo $(DEPDIR)/test_gsub_would_substitute-test-gsub-would-substitute.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@     $(AM_V_CXX)source='test-gsub-would-substitute.cc' object='test_gsub_would_substitute-test-gsub-would-substitute.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@     DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_gsub_would_substitute_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o test_gsub_would_substitute-test-gsub-would-substitute.o `test -f 'test-gsub-would-substitute.cc' || echo '$(srcdir)/'`test-gsub-would-substitute.cc
+
+test_gsub_would_substitute-test-gsub-would-substitute.obj: test-gsub-would-substitute.cc
+@am__fastdepCXX_TRUE@  $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_gsub_would_substitute_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT test_gsub_would_substitute-test-gsub-would-substitute.obj -MD -MP -MF $(DEPDIR)/test_gsub_would_substitute-test-gsub-would-substitute.Tpo -c -o test_gsub_would_substitute-test-gsub-would-substitute.obj `if test -f 'test-gsub-would-substitute.cc'; then $(CYGPATH_W) 'test-gsub-would-substitute.cc'; else $(CYGPATH_W) '$(srcdir)/test-gsub-would-substitute.cc'; fi`
+@am__fastdepCXX_TRUE@  $(AM_V_at)$(am__mv) $(DEPDIR)/test_gsub_would_substitute-test-gsub-would-substitute.Tpo $(DEPDIR)/test_gsub_would_substitute-test-gsub-would-substitute.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@     $(AM_V_CXX)source='test-gsub-would-substitute.cc' object='test_gsub_would_substitute-test-gsub-would-substitute.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@     DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_gsub_would_substitute_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o test_gsub_would_substitute-test-gsub-would-substitute.obj `if test -f 'test-gsub-would-substitute.cc'; then $(CYGPATH_W) 'test-gsub-would-substitute.cc'; else $(CYGPATH_W) '$(srcdir)/test-gsub-would-substitute.cc'; fi`
+
 test_iter-test-iter.o: test-iter.cc
 @am__fastdepCXX_TRUE@  $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_iter_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT test_iter-test-iter.o -MD -MP -MF $(DEPDIR)/test_iter-test-iter.Tpo -c -o test_iter-test-iter.o `test -f 'test-iter.cc' || echo '$(srcdir)/'`test-iter.cc
 @am__fastdepCXX_TRUE@  $(AM_V_at)$(am__mv) $(DEPDIR)/test_iter-test-iter.Tpo $(DEPDIR)/test_iter-test-iter.Po
@@ -2520,19 +2733,61 @@ test_iter-hb-static.obj: hb-static.cc
 @AMDEP_TRUE@@am__fastdepCXX_FALSE@     DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
 @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_iter_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o test_iter-hb-static.obj `if test -f 'hb-static.cc'; then $(CYGPATH_W) 'hb-static.cc'; else $(CYGPATH_W) '$(srcdir)/hb-static.cc'; fi`
 
-test_name_table-test-name-table.o: test-name-table.cc
-@am__fastdepCXX_TRUE@  $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_name_table_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT test_name_table-test-name-table.o -MD -MP -MF $(DEPDIR)/test_name_table-test-name-table.Tpo -c -o test_name_table-test-name-table.o `test -f 'test-name-table.cc' || echo '$(srcdir)/'`test-name-table.cc
-@am__fastdepCXX_TRUE@  $(AM_V_at)$(am__mv) $(DEPDIR)/test_name_table-test-name-table.Tpo $(DEPDIR)/test_name_table-test-name-table.Po
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@     $(AM_V_CXX)source='test-name-table.cc' object='test_name_table-test-name-table.o' libtool=no @AMDEPBACKSLASH@
+test_meta-test-meta.o: test-meta.cc
+@am__fastdepCXX_TRUE@  $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_meta_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT test_meta-test-meta.o -MD -MP -MF $(DEPDIR)/test_meta-test-meta.Tpo -c -o test_meta-test-meta.o `test -f 'test-meta.cc' || echo '$(srcdir)/'`test-meta.cc
+@am__fastdepCXX_TRUE@  $(AM_V_at)$(am__mv) $(DEPDIR)/test_meta-test-meta.Tpo $(DEPDIR)/test_meta-test-meta.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@     $(AM_V_CXX)source='test-meta.cc' object='test_meta-test-meta.o' libtool=no @AMDEPBACKSLASH@
 @AMDEP_TRUE@@am__fastdepCXX_FALSE@     DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_name_table_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o test_name_table-test-name-table.o `test -f 'test-name-table.cc' || echo '$(srcdir)/'`test-name-table.cc
+@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_meta_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o test_meta-test-meta.o `test -f 'test-meta.cc' || echo '$(srcdir)/'`test-meta.cc
 
-test_name_table-test-name-table.obj: test-name-table.cc
-@am__fastdepCXX_TRUE@  $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_name_table_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT test_name_table-test-name-table.obj -MD -MP -MF $(DEPDIR)/test_name_table-test-name-table.Tpo -c -o test_name_table-test-name-table.obj `if test -f 'test-name-table.cc'; then $(CYGPATH_W) 'test-name-table.cc'; else $(CYGPATH_W) '$(srcdir)/test-name-table.cc'; fi`
-@am__fastdepCXX_TRUE@  $(AM_V_at)$(am__mv) $(DEPDIR)/test_name_table-test-name-table.Tpo $(DEPDIR)/test_name_table-test-name-table.Po
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@     $(AM_V_CXX)source='test-name-table.cc' object='test_name_table-test-name-table.obj' libtool=no @AMDEPBACKSLASH@
+test_meta-test-meta.obj: test-meta.cc
+@am__fastdepCXX_TRUE@  $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_meta_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT test_meta-test-meta.obj -MD -MP -MF $(DEPDIR)/test_meta-test-meta.Tpo -c -o test_meta-test-meta.obj `if test -f 'test-meta.cc'; then $(CYGPATH_W) 'test-meta.cc'; else $(CYGPATH_W) '$(srcdir)/test-meta.cc'; fi`
+@am__fastdepCXX_TRUE@  $(AM_V_at)$(am__mv) $(DEPDIR)/test_meta-test-meta.Tpo $(DEPDIR)/test_meta-test-meta.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@     $(AM_V_CXX)source='test-meta.cc' object='test_meta-test-meta.obj' libtool=no @AMDEPBACKSLASH@
 @AMDEP_TRUE@@am__fastdepCXX_FALSE@     DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_name_table_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o test_name_table-test-name-table.obj `if test -f 'test-name-table.cc'; then $(CYGPATH_W) 'test-name-table.cc'; else $(CYGPATH_W) '$(srcdir)/test-name-table.cc'; fi`
+@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_meta_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o test_meta-test-meta.obj `if test -f 'test-meta.cc'; then $(CYGPATH_W) 'test-meta.cc'; else $(CYGPATH_W) '$(srcdir)/test-meta.cc'; fi`
+
+test_meta-hb-static.o: hb-static.cc
+@am__fastdepCXX_TRUE@  $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_meta_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT test_meta-hb-static.o -MD -MP -MF $(DEPDIR)/test_meta-hb-static.Tpo -c -o test_meta-hb-static.o `test -f 'hb-static.cc' || echo '$(srcdir)/'`hb-static.cc
+@am__fastdepCXX_TRUE@  $(AM_V_at)$(am__mv) $(DEPDIR)/test_meta-hb-static.Tpo $(DEPDIR)/test_meta-hb-static.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@     $(AM_V_CXX)source='hb-static.cc' object='test_meta-hb-static.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@     DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_meta_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o test_meta-hb-static.o `test -f 'hb-static.cc' || echo '$(srcdir)/'`hb-static.cc
+
+test_meta-hb-static.obj: hb-static.cc
+@am__fastdepCXX_TRUE@  $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_meta_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT test_meta-hb-static.obj -MD -MP -MF $(DEPDIR)/test_meta-hb-static.Tpo -c -o test_meta-hb-static.obj `if test -f 'hb-static.cc'; then $(CYGPATH_W) 'hb-static.cc'; else $(CYGPATH_W) '$(srcdir)/hb-static.cc'; fi`
+@am__fastdepCXX_TRUE@  $(AM_V_at)$(am__mv) $(DEPDIR)/test_meta-hb-static.Tpo $(DEPDIR)/test_meta-hb-static.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@     $(AM_V_CXX)source='hb-static.cc' object='test_meta-hb-static.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@     DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_meta_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o test_meta-hb-static.obj `if test -f 'hb-static.cc'; then $(CYGPATH_W) 'hb-static.cc'; else $(CYGPATH_W) '$(srcdir)/hb-static.cc'; fi`
+
+test_number-test-number.o: test-number.cc
+@am__fastdepCXX_TRUE@  $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_number_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT test_number-test-number.o -MD -MP -MF $(DEPDIR)/test_number-test-number.Tpo -c -o test_number-test-number.o `test -f 'test-number.cc' || echo '$(srcdir)/'`test-number.cc
+@am__fastdepCXX_TRUE@  $(AM_V_at)$(am__mv) $(DEPDIR)/test_number-test-number.Tpo $(DEPDIR)/test_number-test-number.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@     $(AM_V_CXX)source='test-number.cc' object='test_number-test-number.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@     DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_number_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o test_number-test-number.o `test -f 'test-number.cc' || echo '$(srcdir)/'`test-number.cc
+
+test_number-test-number.obj: test-number.cc
+@am__fastdepCXX_TRUE@  $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_number_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT test_number-test-number.obj -MD -MP -MF $(DEPDIR)/test_number-test-number.Tpo -c -o test_number-test-number.obj `if test -f 'test-number.cc'; then $(CYGPATH_W) 'test-number.cc'; else $(CYGPATH_W) '$(srcdir)/test-number.cc'; fi`
+@am__fastdepCXX_TRUE@  $(AM_V_at)$(am__mv) $(DEPDIR)/test_number-test-number.Tpo $(DEPDIR)/test_number-test-number.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@     $(AM_V_CXX)source='test-number.cc' object='test_number-test-number.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@     DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_number_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o test_number-test-number.obj `if test -f 'test-number.cc'; then $(CYGPATH_W) 'test-number.cc'; else $(CYGPATH_W) '$(srcdir)/test-number.cc'; fi`
+
+test_number-hb-number.o: hb-number.cc
+@am__fastdepCXX_TRUE@  $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_number_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT test_number-hb-number.o -MD -MP -MF $(DEPDIR)/test_number-hb-number.Tpo -c -o test_number-hb-number.o `test -f 'hb-number.cc' || echo '$(srcdir)/'`hb-number.cc
+@am__fastdepCXX_TRUE@  $(AM_V_at)$(am__mv) $(DEPDIR)/test_number-hb-number.Tpo $(DEPDIR)/test_number-hb-number.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@     $(AM_V_CXX)source='hb-number.cc' object='test_number-hb-number.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@     DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_number_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o test_number-hb-number.o `test -f 'hb-number.cc' || echo '$(srcdir)/'`hb-number.cc
+
+test_number-hb-number.obj: hb-number.cc
+@am__fastdepCXX_TRUE@  $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_number_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT test_number-hb-number.obj -MD -MP -MF $(DEPDIR)/test_number-hb-number.Tpo -c -o test_number-hb-number.obj `if test -f 'hb-number.cc'; then $(CYGPATH_W) 'hb-number.cc'; else $(CYGPATH_W) '$(srcdir)/hb-number.cc'; fi`
+@am__fastdepCXX_TRUE@  $(AM_V_at)$(am__mv) $(DEPDIR)/test_number-hb-number.Tpo $(DEPDIR)/test_number-hb-number.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@     $(AM_V_CXX)source='hb-number.cc' object='test_number-hb-number.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@     DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_number_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o test_number-hb-number.obj `if test -f 'hb-number.cc'; then $(CYGPATH_W) 'hb-number.cc'; else $(CYGPATH_W) '$(srcdir)/hb-number.cc'; fi`
 
 test_ot_color-test-ot-color.o: test-ot-color.cc
 @am__fastdepCXX_TRUE@  $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_ot_color_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT test_ot_color-test-ot-color.o -MD -MP -MF $(DEPDIR)/test_ot_color-test-ot-color.Tpo -c -o test_ot_color-test-ot-color.o `test -f 'test-ot-color.cc' || echo '$(srcdir)/'`test-ot-color.cc
@@ -2548,6 +2803,34 @@ test_ot_color-test-ot-color.obj: test-ot-color.cc
 @AMDEP_TRUE@@am__fastdepCXX_FALSE@     DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
 @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_ot_color_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o test_ot_color-test-ot-color.obj `if test -f 'test-ot-color.cc'; then $(CYGPATH_W) 'test-ot-color.cc'; else $(CYGPATH_W) '$(srcdir)/test-ot-color.cc'; fi`
 
+test_ot_meta-test-ot-meta.o: test-ot-meta.cc
+@am__fastdepCXX_TRUE@  $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_ot_meta_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT test_ot_meta-test-ot-meta.o -MD -MP -MF $(DEPDIR)/test_ot_meta-test-ot-meta.Tpo -c -o test_ot_meta-test-ot-meta.o `test -f 'test-ot-meta.cc' || echo '$(srcdir)/'`test-ot-meta.cc
+@am__fastdepCXX_TRUE@  $(AM_V_at)$(am__mv) $(DEPDIR)/test_ot_meta-test-ot-meta.Tpo $(DEPDIR)/test_ot_meta-test-ot-meta.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@     $(AM_V_CXX)source='test-ot-meta.cc' object='test_ot_meta-test-ot-meta.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@     DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_ot_meta_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o test_ot_meta-test-ot-meta.o `test -f 'test-ot-meta.cc' || echo '$(srcdir)/'`test-ot-meta.cc
+
+test_ot_meta-test-ot-meta.obj: test-ot-meta.cc
+@am__fastdepCXX_TRUE@  $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_ot_meta_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT test_ot_meta-test-ot-meta.obj -MD -MP -MF $(DEPDIR)/test_ot_meta-test-ot-meta.Tpo -c -o test_ot_meta-test-ot-meta.obj `if test -f 'test-ot-meta.cc'; then $(CYGPATH_W) 'test-ot-meta.cc'; else $(CYGPATH_W) '$(srcdir)/test-ot-meta.cc'; fi`
+@am__fastdepCXX_TRUE@  $(AM_V_at)$(am__mv) $(DEPDIR)/test_ot_meta-test-ot-meta.Tpo $(DEPDIR)/test_ot_meta-test-ot-meta.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@     $(AM_V_CXX)source='test-ot-meta.cc' object='test_ot_meta-test-ot-meta.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@     DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_ot_meta_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o test_ot_meta-test-ot-meta.obj `if test -f 'test-ot-meta.cc'; then $(CYGPATH_W) 'test-ot-meta.cc'; else $(CYGPATH_W) '$(srcdir)/test-ot-meta.cc'; fi`
+
+test_ot_name-test-ot-name.o: test-ot-name.cc
+@am__fastdepCXX_TRUE@  $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_ot_name_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT test_ot_name-test-ot-name.o -MD -MP -MF $(DEPDIR)/test_ot_name-test-ot-name.Tpo -c -o test_ot_name-test-ot-name.o `test -f 'test-ot-name.cc' || echo '$(srcdir)/'`test-ot-name.cc
+@am__fastdepCXX_TRUE@  $(AM_V_at)$(am__mv) $(DEPDIR)/test_ot_name-test-ot-name.Tpo $(DEPDIR)/test_ot_name-test-ot-name.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@     $(AM_V_CXX)source='test-ot-name.cc' object='test_ot_name-test-ot-name.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@     DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_ot_name_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o test_ot_name-test-ot-name.o `test -f 'test-ot-name.cc' || echo '$(srcdir)/'`test-ot-name.cc
+
+test_ot_name-test-ot-name.obj: test-ot-name.cc
+@am__fastdepCXX_TRUE@  $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_ot_name_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT test_ot_name-test-ot-name.obj -MD -MP -MF $(DEPDIR)/test_ot_name-test-ot-name.Tpo -c -o test_ot_name-test-ot-name.obj `if test -f 'test-ot-name.cc'; then $(CYGPATH_W) 'test-ot-name.cc'; else $(CYGPATH_W) '$(srcdir)/test-ot-name.cc'; fi`
+@am__fastdepCXX_TRUE@  $(AM_V_at)$(am__mv) $(DEPDIR)/test_ot_name-test-ot-name.Tpo $(DEPDIR)/test_ot_name-test-ot-name.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@     $(AM_V_CXX)source='test-ot-name.cc' object='test_ot_name-test-ot-name.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@     DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_ot_name_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o test_ot_name-test-ot-name.obj `if test -f 'test-ot-name.cc'; then $(CYGPATH_W) 'test-ot-name.cc'; else $(CYGPATH_W) '$(srcdir)/test-ot-name.cc'; fi`
+
 test_ot_tag-hb-ot-tag.o: hb-ot-tag.cc
 @am__fastdepCXX_TRUE@  $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_ot_tag_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT test_ot_tag-hb-ot-tag.o -MD -MP -MF $(DEPDIR)/test_ot_tag-hb-ot-tag.Tpo -c -o test_ot_tag-hb-ot-tag.o `test -f 'hb-ot-tag.cc' || echo '$(srcdir)/'`hb-ot-tag.cc
 @am__fastdepCXX_TRUE@  $(AM_V_at)$(am__mv) $(DEPDIR)/test_ot_tag-hb-ot-tag.Tpo $(DEPDIR)/test_ot_tag-hb-ot-tag.Po
@@ -2562,20 +2845,6 @@ test_ot_tag-hb-ot-tag.obj: hb-ot-tag.cc
 @AMDEP_TRUE@@am__fastdepCXX_FALSE@     DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
 @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_ot_tag_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o test_ot_tag-hb-ot-tag.obj `if test -f 'hb-ot-tag.cc'; then $(CYGPATH_W) 'hb-ot-tag.cc'; else $(CYGPATH_W) '$(srcdir)/hb-ot-tag.cc'; fi`
 
-test_size_params-test-size-params.o: test-size-params.cc
-@am__fastdepCXX_TRUE@  $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_size_params_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT test_size_params-test-size-params.o -MD -MP -MF $(DEPDIR)/test_size_params-test-size-params.Tpo -c -o test_size_params-test-size-params.o `test -f 'test-size-params.cc' || echo '$(srcdir)/'`test-size-params.cc
-@am__fastdepCXX_TRUE@  $(AM_V_at)$(am__mv) $(DEPDIR)/test_size_params-test-size-params.Tpo $(DEPDIR)/test_size_params-test-size-params.Po
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@     $(AM_V_CXX)source='test-size-params.cc' object='test_size_params-test-size-params.o' libtool=no @AMDEPBACKSLASH@
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@     DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_size_params_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o test_size_params-test-size-params.o `test -f 'test-size-params.cc' || echo '$(srcdir)/'`test-size-params.cc
-
-test_size_params-test-size-params.obj: test-size-params.cc
-@am__fastdepCXX_TRUE@  $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_size_params_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT test_size_params-test-size-params.obj -MD -MP -MF $(DEPDIR)/test_size_params-test-size-params.Tpo -c -o test_size_params-test-size-params.obj `if test -f 'test-size-params.cc'; then $(CYGPATH_W) 'test-size-params.cc'; else $(CYGPATH_W) '$(srcdir)/test-size-params.cc'; fi`
-@am__fastdepCXX_TRUE@  $(AM_V_at)$(am__mv) $(DEPDIR)/test_size_params-test-size-params.Tpo $(DEPDIR)/test_size_params-test-size-params.Po
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@     $(AM_V_CXX)source='test-size-params.cc' object='test_size_params-test-size-params.obj' libtool=no @AMDEPBACKSLASH@
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@     DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_size_params_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o test_size_params-test-size-params.obj `if test -f 'test-size-params.cc'; then $(CYGPATH_W) 'test-size-params.cc'; else $(CYGPATH_W) '$(srcdir)/test-size-params.cc'; fi`
-
 test_unicode_ranges-test-unicode-ranges.o: test-unicode-ranges.cc
 @am__fastdepCXX_TRUE@  $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_unicode_ranges_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT test_unicode_ranges-test-unicode-ranges.o -MD -MP -MF $(DEPDIR)/test_unicode_ranges-test-unicode-ranges.Tpo -c -o test_unicode_ranges-test-unicode-ranges.o `test -f 'test-unicode-ranges.cc' || echo '$(srcdir)/'`test-unicode-ranges.cc
 @am__fastdepCXX_TRUE@  $(AM_V_at)$(am__mv) $(DEPDIR)/test_unicode_ranges-test-unicode-ranges.Tpo $(DEPDIR)/test_unicode_ranges-test-unicode-ranges.Po
@@ -2590,20 +2859,6 @@ test_unicode_ranges-test-unicode-ranges.obj: test-unicode-ranges.cc
 @AMDEP_TRUE@@am__fastdepCXX_FALSE@     DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
 @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_unicode_ranges_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o test_unicode_ranges-test-unicode-ranges.obj `if test -f 'test-unicode-ranges.cc'; then $(CYGPATH_W) 'test-unicode-ranges.cc'; else $(CYGPATH_W) '$(srcdir)/test-unicode-ranges.cc'; fi`
 
-test_would_substitute-test-would-substitute.o: test-would-substitute.cc
-@am__fastdepCXX_TRUE@  $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_would_substitute_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT test_would_substitute-test-would-substitute.o -MD -MP -MF $(DEPDIR)/test_would_substitute-test-would-substitute.Tpo -c -o test_would_substitute-test-would-substitute.o `test -f 'test-would-substitute.cc' || echo '$(srcdir)/'`test-would-substitute.cc
-@am__fastdepCXX_TRUE@  $(AM_V_at)$(am__mv) $(DEPDIR)/test_would_substitute-test-would-substitute.Tpo $(DEPDIR)/test_would_substitute-test-would-substitute.Po
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@     $(AM_V_CXX)source='test-would-substitute.cc' object='test_would_substitute-test-would-substitute.o' libtool=no @AMDEPBACKSLASH@
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@     DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_would_substitute_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o test_would_substitute-test-would-substitute.o `test -f 'test-would-substitute.cc' || echo '$(srcdir)/'`test-would-substitute.cc
-
-test_would_substitute-test-would-substitute.obj: test-would-substitute.cc
-@am__fastdepCXX_TRUE@  $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_would_substitute_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT test_would_substitute-test-would-substitute.obj -MD -MP -MF $(DEPDIR)/test_would_substitute-test-would-substitute.Tpo -c -o test_would_substitute-test-would-substitute.obj `if test -f 'test-would-substitute.cc'; then $(CYGPATH_W) 'test-would-substitute.cc'; else $(CYGPATH_W) '$(srcdir)/test-would-substitute.cc'; fi`
-@am__fastdepCXX_TRUE@  $(AM_V_at)$(am__mv) $(DEPDIR)/test_would_substitute-test-would-substitute.Tpo $(DEPDIR)/test_would_substitute-test-would-substitute.Po
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@     $(AM_V_CXX)source='test-would-substitute.cc' object='test_would_substitute-test-would-substitute.obj' libtool=no @AMDEPBACKSLASH@
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@     DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_would_substitute_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o test_would_substitute-test-would-substitute.obj `if test -f 'test-would-substitute.cc'; then $(CYGPATH_W) 'test-would-substitute.cc'; else $(CYGPATH_W) '$(srcdir)/test-would-substitute.cc'; fi`
-
 mostlyclean-libtool:
        -rm -f *.lo
 
@@ -3025,6 +3280,13 @@ check-libstdc++.sh.log: check-libstdc++.sh
        --log-file $$b.log --trs-file $$b.trs \
        $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \
        "$$tst" $(AM_TESTS_FD_REDIRECT)
+test-algs.log: test-algs$(EXEEXT)
+       @p='test-algs$(EXEEXT)'; \
+       b='test-algs'; \
+       $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \
+       --log-file $$b.log --trs-file $$b.trs \
+       $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \
+       "$$tst" $(AM_TESTS_FD_REDIRECT)
 test-iter.log: test-iter$(EXEEXT)
        @p='test-iter$(EXEEXT)'; \
        b='test-iter'; \
@@ -3032,6 +3294,20 @@ test-iter.log: test-iter$(EXEEXT)
        --log-file $$b.log --trs-file $$b.trs \
        $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \
        "$$tst" $(AM_TESTS_FD_REDIRECT)
+test-meta.log: test-meta$(EXEEXT)
+       @p='test-meta$(EXEEXT)'; \
+       b='test-meta'; \
+       $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \
+       --log-file $$b.log --trs-file $$b.trs \
+       $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \
+       "$$tst" $(AM_TESTS_FD_REDIRECT)
+test-number.log: test-number$(EXEEXT)
+       @p='test-number$(EXEEXT)'; \
+       b='test-number'; \
+       $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \
+       --log-file $$b.log --trs-file $$b.trs \
+       $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \
+       "$$tst" $(AM_TESTS_FD_REDIRECT)
 test-ot-tag.log: test-ot-tag$(EXEEXT)
        @p='test-ot-tag$(EXEEXT)'; \
        b='test-ot-tag'; \
@@ -3046,6 +3322,13 @@ test-unicode-ranges.log: test-unicode-ranges$(EXEEXT)
        --log-file $$b.log --trs-file $$b.trs \
        $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \
        "$$tst" $(AM_TESTS_FD_REDIRECT)
+test-bimap.log: test-bimap$(EXEEXT)
+       @p='test-bimap$(EXEEXT)'; \
+       b='test-bimap'; \
+       $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \
+       --log-file $$b.log --trs-file $$b.trs \
+       $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \
+       "$$tst" $(AM_TESTS_FD_REDIRECT)
 .test.log:
        @p='$<'; \
        $(am__set_b); \
@@ -3201,10 +3484,12 @@ distclean: distclean-recursive
        -rm -f ./$(DEPDIR)/libharfbuzz_la-hb-fallback-shape.Plo
        -rm -f ./$(DEPDIR)/libharfbuzz_la-hb-font.Plo
        -rm -f ./$(DEPDIR)/libharfbuzz_la-hb-ft.Plo
+       -rm -f ./$(DEPDIR)/libharfbuzz_la-hb-gdi.Plo
        -rm -f ./$(DEPDIR)/libharfbuzz_la-hb-glib.Plo
        -rm -f ./$(DEPDIR)/libharfbuzz_la-hb-graphite2.Plo
        -rm -f ./$(DEPDIR)/libharfbuzz_la-hb-icu.Plo
        -rm -f ./$(DEPDIR)/libharfbuzz_la-hb-map.Plo
+       -rm -f ./$(DEPDIR)/libharfbuzz_la-hb-number.Plo
        -rm -f ./$(DEPDIR)/libharfbuzz_la-hb-ot-cff1-table.Plo
        -rm -f ./$(DEPDIR)/libharfbuzz_la-hb-ot-cff2-table.Plo
        -rm -f ./$(DEPDIR)/libharfbuzz_la-hb-ot-color.Plo
@@ -3213,7 +3498,8 @@ distclean: distclean-recursive
        -rm -f ./$(DEPDIR)/libharfbuzz_la-hb-ot-layout.Plo
        -rm -f ./$(DEPDIR)/libharfbuzz_la-hb-ot-map.Plo
        -rm -f ./$(DEPDIR)/libharfbuzz_la-hb-ot-math.Plo
-       -rm -f ./$(DEPDIR)/libharfbuzz_la-hb-ot-name-language.Plo
+       -rm -f ./$(DEPDIR)/libharfbuzz_la-hb-ot-meta.Plo
+       -rm -f ./$(DEPDIR)/libharfbuzz_la-hb-ot-metrics.Plo
        -rm -f ./$(DEPDIR)/libharfbuzz_la-hb-ot-name.Plo
        -rm -f ./$(DEPDIR)/libharfbuzz_la-hb-ot-shape-complex-arabic.Plo
        -rm -f ./$(DEPDIR)/libharfbuzz_la-hb-ot-shape-complex-default.Plo
@@ -3237,31 +3523,39 @@ distclean: distclean-recursive
        -rm -f ./$(DEPDIR)/libharfbuzz_la-hb-shape.Plo
        -rm -f ./$(DEPDIR)/libharfbuzz_la-hb-shaper.Plo
        -rm -f ./$(DEPDIR)/libharfbuzz_la-hb-static.Plo
-       -rm -f ./$(DEPDIR)/libharfbuzz_la-hb-ucdn.Plo
+       -rm -f ./$(DEPDIR)/libharfbuzz_la-hb-ucd.Plo
        -rm -f ./$(DEPDIR)/libharfbuzz_la-hb-unicode.Plo
        -rm -f ./$(DEPDIR)/libharfbuzz_la-hb-uniscribe.Plo
-       -rm -f ./$(DEPDIR)/libharfbuzz_la-hb-warning.Plo
+       -rm -f ./$(DEPDIR)/libharfbuzz_subset_la-hb-number.Plo
        -rm -f ./$(DEPDIR)/libharfbuzz_subset_la-hb-ot-cff1-table.Plo
        -rm -f ./$(DEPDIR)/libharfbuzz_subset_la-hb-ot-cff2-table.Plo
        -rm -f ./$(DEPDIR)/libharfbuzz_subset_la-hb-static.Plo
        -rm -f ./$(DEPDIR)/libharfbuzz_subset_la-hb-subset-cff-common.Plo
        -rm -f ./$(DEPDIR)/libharfbuzz_subset_la-hb-subset-cff1.Plo
        -rm -f ./$(DEPDIR)/libharfbuzz_subset_la-hb-subset-cff2.Plo
-       -rm -f ./$(DEPDIR)/libharfbuzz_subset_la-hb-subset-glyf.Plo
        -rm -f ./$(DEPDIR)/libharfbuzz_subset_la-hb-subset-input.Plo
        -rm -f ./$(DEPDIR)/libharfbuzz_subset_la-hb-subset-plan.Plo
        -rm -f ./$(DEPDIR)/libharfbuzz_subset_la-hb-subset.Plo
        -rm -f ./$(DEPDIR)/main-main.Po
        -rm -f ./$(DEPDIR)/test-test.Po
+       -rm -f ./$(DEPDIR)/test_algs-hb-static.Po
+       -rm -f ./$(DEPDIR)/test_algs-test-algs.Po
+       -rm -f ./$(DEPDIR)/test_bimap-hb-static.Po
+       -rm -f ./$(DEPDIR)/test_bimap-test-bimap.Po
        -rm -f ./$(DEPDIR)/test_buffer_serialize-test-buffer-serialize.Po
+       -rm -f ./$(DEPDIR)/test_gpos_size_params-test-gpos-size-params.Po
+       -rm -f ./$(DEPDIR)/test_gsub_would_substitute-test-gsub-would-substitute.Po
        -rm -f ./$(DEPDIR)/test_iter-hb-static.Po
        -rm -f ./$(DEPDIR)/test_iter-test-iter.Po
-       -rm -f ./$(DEPDIR)/test_name_table-test-name-table.Po
+       -rm -f ./$(DEPDIR)/test_meta-hb-static.Po
+       -rm -f ./$(DEPDIR)/test_meta-test-meta.Po
+       -rm -f ./$(DEPDIR)/test_number-hb-number.Po
+       -rm -f ./$(DEPDIR)/test_number-test-number.Po
        -rm -f ./$(DEPDIR)/test_ot_color-test-ot-color.Po
+       -rm -f ./$(DEPDIR)/test_ot_meta-test-ot-meta.Po
+       -rm -f ./$(DEPDIR)/test_ot_name-test-ot-name.Po
        -rm -f ./$(DEPDIR)/test_ot_tag-hb-ot-tag.Po
-       -rm -f ./$(DEPDIR)/test_size_params-test-size-params.Po
        -rm -f ./$(DEPDIR)/test_unicode_ranges-test-unicode-ranges.Po
-       -rm -f ./$(DEPDIR)/test_would_substitute-test-would-substitute.Po
        -rm -f Makefile
 distclean-am: clean-am distclean-compile distclean-generic \
        distclean-tags
@@ -3332,10 +3626,12 @@ maintainer-clean: maintainer-clean-recursive
        -rm -f ./$(DEPDIR)/libharfbuzz_la-hb-fallback-shape.Plo
        -rm -f ./$(DEPDIR)/libharfbuzz_la-hb-font.Plo
        -rm -f ./$(DEPDIR)/libharfbuzz_la-hb-ft.Plo
+       -rm -f ./$(DEPDIR)/libharfbuzz_la-hb-gdi.Plo
        -rm -f ./$(DEPDIR)/libharfbuzz_la-hb-glib.Plo
        -rm -f ./$(DEPDIR)/libharfbuzz_la-hb-graphite2.Plo
        -rm -f ./$(DEPDIR)/libharfbuzz_la-hb-icu.Plo
        -rm -f ./$(DEPDIR)/libharfbuzz_la-hb-map.Plo
+       -rm -f ./$(DEPDIR)/libharfbuzz_la-hb-number.Plo
        -rm -f ./$(DEPDIR)/libharfbuzz_la-hb-ot-cff1-table.Plo
        -rm -f ./$(DEPDIR)/libharfbuzz_la-hb-ot-cff2-table.Plo
        -rm -f ./$(DEPDIR)/libharfbuzz_la-hb-ot-color.Plo
@@ -3344,7 +3640,8 @@ maintainer-clean: maintainer-clean-recursive
        -rm -f ./$(DEPDIR)/libharfbuzz_la-hb-ot-layout.Plo
        -rm -f ./$(DEPDIR)/libharfbuzz_la-hb-ot-map.Plo
        -rm -f ./$(DEPDIR)/libharfbuzz_la-hb-ot-math.Plo
-       -rm -f ./$(DEPDIR)/libharfbuzz_la-hb-ot-name-language.Plo
+       -rm -f ./$(DEPDIR)/libharfbuzz_la-hb-ot-meta.Plo
+       -rm -f ./$(DEPDIR)/libharfbuzz_la-hb-ot-metrics.Plo
        -rm -f ./$(DEPDIR)/libharfbuzz_la-hb-ot-name.Plo
        -rm -f ./$(DEPDIR)/libharfbuzz_la-hb-ot-shape-complex-arabic.Plo
        -rm -f ./$(DEPDIR)/libharfbuzz_la-hb-ot-shape-complex-default.Plo
@@ -3368,31 +3665,39 @@ maintainer-clean: maintainer-clean-recursive
        -rm -f ./$(DEPDIR)/libharfbuzz_la-hb-shape.Plo
        -rm -f ./$(DEPDIR)/libharfbuzz_la-hb-shaper.Plo
        -rm -f ./$(DEPDIR)/libharfbuzz_la-hb-static.Plo
-       -rm -f ./$(DEPDIR)/libharfbuzz_la-hb-ucdn.Plo
+       -rm -f ./$(DEPDIR)/libharfbuzz_la-hb-ucd.Plo
        -rm -f ./$(DEPDIR)/libharfbuzz_la-hb-unicode.Plo
        -rm -f ./$(DEPDIR)/libharfbuzz_la-hb-uniscribe.Plo
-       -rm -f ./$(DEPDIR)/libharfbuzz_la-hb-warning.Plo
+       -rm -f ./$(DEPDIR)/libharfbuzz_subset_la-hb-number.Plo
        -rm -f ./$(DEPDIR)/libharfbuzz_subset_la-hb-ot-cff1-table.Plo
        -rm -f ./$(DEPDIR)/libharfbuzz_subset_la-hb-ot-cff2-table.Plo
        -rm -f ./$(DEPDIR)/libharfbuzz_subset_la-hb-static.Plo
        -rm -f ./$(DEPDIR)/libharfbuzz_subset_la-hb-subset-cff-common.Plo
        -rm -f ./$(DEPDIR)/libharfbuzz_subset_la-hb-subset-cff1.Plo
        -rm -f ./$(DEPDIR)/libharfbuzz_subset_la-hb-subset-cff2.Plo
-       -rm -f ./$(DEPDIR)/libharfbuzz_subset_la-hb-subset-glyf.Plo
        -rm -f ./$(DEPDIR)/libharfbuzz_subset_la-hb-subset-input.Plo
        -rm -f ./$(DEPDIR)/libharfbuzz_subset_la-hb-subset-plan.Plo
        -rm -f ./$(DEPDIR)/libharfbuzz_subset_la-hb-subset.Plo
        -rm -f ./$(DEPDIR)/main-main.Po
        -rm -f ./$(DEPDIR)/test-test.Po
+       -rm -f ./$(DEPDIR)/test_algs-hb-static.Po
+       -rm -f ./$(DEPDIR)/test_algs-test-algs.Po
+       -rm -f ./$(DEPDIR)/test_bimap-hb-static.Po
+       -rm -f ./$(DEPDIR)/test_bimap-test-bimap.Po
        -rm -f ./$(DEPDIR)/test_buffer_serialize-test-buffer-serialize.Po
+       -rm -f ./$(DEPDIR)/test_gpos_size_params-test-gpos-size-params.Po
+       -rm -f ./$(DEPDIR)/test_gsub_would_substitute-test-gsub-would-substitute.Po
        -rm -f ./$(DEPDIR)/test_iter-hb-static.Po
        -rm -f ./$(DEPDIR)/test_iter-test-iter.Po
-       -rm -f ./$(DEPDIR)/test_name_table-test-name-table.Po
+       -rm -f ./$(DEPDIR)/test_meta-hb-static.Po
+       -rm -f ./$(DEPDIR)/test_meta-test-meta.Po
+       -rm -f ./$(DEPDIR)/test_number-hb-number.Po
+       -rm -f ./$(DEPDIR)/test_number-test-number.Po
        -rm -f ./$(DEPDIR)/test_ot_color-test-ot-color.Po
+       -rm -f ./$(DEPDIR)/test_ot_meta-test-ot-meta.Po
+       -rm -f ./$(DEPDIR)/test_ot_name-test-ot-name.Po
        -rm -f ./$(DEPDIR)/test_ot_tag-hb-ot-tag.Po
-       -rm -f ./$(DEPDIR)/test_size_params-test-size-params.Po
        -rm -f ./$(DEPDIR)/test_unicode_ranges-test-unicode-ranges.Po
-       -rm -f ./$(DEPDIR)/test_would_substitute-test-would-substitute.Po
        -rm -f Makefile
 maintainer-clean-am: distclean-am maintainer-clean-generic
 
@@ -3447,9 +3752,10 @@ uninstall-am: uninstall-binPROGRAMS uninstall-cmakeDATA \
 # Convenience targets:
 lib: $(BUILT_SOURCES) libharfbuzz.la
 libs: $(BUILT_SOURCES) $(lib_LTLIBRARIES)
-@HAVE_UCDN_TRUE@hb-ucdn/libhb-ucdn.la: ucdn
-@HAVE_UCDN_TRUE@ucdn:
-@HAVE_UCDN_TRUE@       @$(MAKE) $(AM_MAKEFLAGS) -C hb-ucdn
+tiny:
+       $(MAKE) $(AM_MAKEFLAGS) CPPFLAGS="-Os -DHB_TINY $(CPPFLAGS)" libs
+tinyz:
+       $(MAKE) $(AM_MAKEFLAGS) CPPFLAGS="-Oz -DHB_TINY $(CPPFLAGS)" libs
 
 $(srcdir)/hb-version.h: hb-version.h.in $(top_srcdir)/configure.ac
        $(AM_V_GEN) $(SED) \
@@ -3490,32 +3796,38 @@ harfbuzz-gobject.def: $(HB_GOBJECT_headers)
 harfbuzz-deprecated-symbols.txt: $(srcdir)/hb-deprecated.h
        $(AM_V_GEN) PLAIN_LIST=1 $(srcdir)/gen-def.py "$@" $^
 
-unicode-tables: arabic-table indic-table tag-table use-table emoji-table
+unicode-tables: \
+       arabic-table \
+       emoji-table \
+       indic-table \
+       tag-table \
+       ucd-table \
+       use-table \
+       emoji-table \
+       $(NULL)
 
 arabic-table: gen-arabic-table.py ArabicShaping.txt UnicodeData.txt Blocks.txt
        $(AM_V_GEN) $(builddir)/$^ > $(srcdir)/hb-ot-shape-complex-arabic-table.hh \
        || ($(RM) $(srcdir)/hb-ot-shape-complex-arabic-table.hh; false)
-
+emoji-table: gen-emoji-table.py emoji-data.txt
+       $(AM_V_GEN) $(builddir)/$^ > $(srcdir)/hb-unicode-emoji-table.hh \
+       || ($(RM) $(srcdir)/hb-unicode-emoji-table.hh; false)
 indic-table: gen-indic-table.py IndicSyllabicCategory.txt IndicPositionalCategory.txt Blocks.txt
        $(AM_V_GEN) $(builddir)/$^ > $(srcdir)/hb-ot-shape-complex-indic-table.cc \
        || ($(RM) $(srcdir)/hb-ot-shape-complex-indic-table.cc; false)
-
 tag-table: gen-tag-table.py languagetags language-subtag-registry
        $(AM_V_GEN) $(builddir)/$^ > $(srcdir)/hb-ot-tag-table.hh \
        || ($(RM) $(srcdir)/hb-ot-tag-table.hh; false)
-
+ucd-table: gen-ucd-table.py ucd.nounihan.grouped.zip hb-common.h
+       $(AM_V_GEN) $(builddir)/$^ > $(srcdir)/hb-ucd-table.hh \
+       || ($(RM) $(srcdir)/hb-ucd-table.hh; false)
 use-table: gen-use-table.py IndicSyllabicCategory.txt IndicPositionalCategory.txt UnicodeData.txt Blocks.txt
        $(AM_V_GEN) $(builddir)/$^ > $(srcdir)/hb-ot-shape-complex-use-table.cc \
        || ($(RM) $(srcdir)/hb-ot-shape-complex-use-table.cc; false)
-
 vowel-constraints: gen-vowel-constraints.py HBIndicVowelConstraints.txt Scripts.txt
        $(AM_V_GEN) $(builddir)/$^ > $(srcdir)/hb-ot-shape-complex-vowel-constraints.cc \
        || ($(RM) $(srcdir)/hb-ot-shape-complex-vowel-constraints.cc; false)
 
-emoji-table: gen-emoji-table.py emoji-data.txt
-       $(AM_V_GEN) $(builddir)/$^ > $(srcdir)/hb-unicode-emoji-table.hh \
-       || ($(RM) $(srcdir)/hb-unicode-emoji-table.hh; false)
-
 built-sources: $(BUILT_SOURCES)
 
 .PHONY: unicode-tables arabic-table indic-table tag-table use-table vowel-constraints emoji-table built-sources
@@ -3525,6 +3837,21 @@ $(srcdir)/%.hh: $(srcdir)/%.rl
        $(AM_V_GEN)(cd $(srcdir) && $(RAGEL) -e -F1 -o "$*.hh" "$*.rl") \
        || ($(RM) "$@"; false)
 
+harfbuzz.cc: Makefile.sources
+       $(AM_V_GEN) \
+       for f in \
+               $(HB_BASE_sources) \
+               $(HB_GLIB_sources) \
+               $(HB_FT_sources) \
+               $(HB_GRAPHITE2_sources) \
+               $(HB_UNISCRIBE_sources) \
+               $(HB_GDI_sources) \
+               $(HB_DIRECTWRITE_sources) \
+               $(HB_CORETEXT_sources) \
+               ; do echo '#include "'$$f'"'; done | \
+       grep '[.]cc"' > $(srcdir)/harfbuzz.cc \
+       || ($(RM) $(srcdir)/harfbuzz.cc; false)
+
 @HAVE_INTROSPECTION_TRUE@-include $(INTROSPECTION_MAKEFILE)
 
 @HAVE_INTROSPECTION_TRUE@HarfBuzz-0.0.gir: libharfbuzz.la libharfbuzz-gobject.la
index 0da4abe..cbbad90 100644 (file)
@@ -10,12 +10,14 @@ HB_BASE_sources = \
        hb-aat-layout-kerx-table.hh \
        hb-aat-layout-lcar-table.hh \
        hb-aat-layout-morx-table.hh \
+       hb-aat-layout-opbd-table.hh \
        hb-aat-layout-trak-table.hh \
        hb-aat-layout.cc \
        hb-aat-layout.hh \
        hb-aat-ltag-table.hh \
        hb-aat-map.cc \
        hb-aat-map.hh \
+       hb-algs.hh \
        hb-array.hh \
        hb-atomic.hh \
        hb-blob.cc \
@@ -30,10 +32,12 @@ HB_BASE_sources = \
        hb-cff1-interp-cs.hh \
        hb-cff2-interp-cs.hh \
        hb-common.cc \
+       hb-config.hh \
        hb-debug.hh \
-       hb-dsalgs.hh \
+       hb-dispatch.hh \
        hb-face.cc \
        hb-face.hh \
+       hb-fallback-shape.cc \
        hb-font.cc \
        hb-font.hh \
        hb-iter.hh \
@@ -41,8 +45,12 @@ HB_BASE_sources = \
        hb-machinery.hh \
        hb-map.cc \
        hb-map.hh \
+       hb-bimap.hh \
+       hb-meta.hh \
        hb-mutex.hh \
        hb-null.hh \
+       hb-number.cc \
+       hb-number.hh \
        hb-object.hh \
        hb-open-file.hh \
        hb-open-type.hh \
@@ -60,6 +68,7 @@ HB_BASE_sources = \
        hb-ot-color.cc \
        hb-ot-face.cc \
        hb-ot-face.hh \
+       hb-ot-face-table-list.hh \
        hb-ot-font.cc \
        hb-ot-gasp-table.hh \
        hb-ot-glyf-table.hh \
@@ -82,7 +91,11 @@ HB_BASE_sources = \
        hb-ot-math-table.hh \
        hb-ot-math.cc \
        hb-ot-maxp-table.hh \
-       hb-ot-name-language.cc \
+       hb-ot-meta-table.hh \
+       hb-ot-meta.cc \
+       hb-ot-metrics.cc \
+       hb-ot-metrics.hh \
+       hb-ot-name-language-static.hh \
        hb-ot-name-language.hh \
        hb-ot-name-table.hh \
        hb-ot-name.cc \
@@ -123,10 +136,14 @@ HB_BASE_sources = \
        hb-ot-tag.cc \
        hb-ot-var-avar-table.hh \
        hb-ot-var-fvar-table.hh \
+       hb-ot-var-gvar-table.hh \
        hb-ot-var-hvar-table.hh \
        hb-ot-var-mvar-table.hh \
        hb-ot-var.cc \
        hb-ot-vorg-table.hh \
+       hb-pool.hh \
+       hb-sanitize.hh \
+       hb-serialize.hh \
        hb-set-digest.hh \
        hb-set.cc \
        hb-set.hh \
@@ -139,18 +156,20 @@ HB_BASE_sources = \
        hb-shaper.hh \
        hb-static.cc \
        hb-string-array.hh \
+       hb-ucd-table.hh \
+       hb-ucd.cc \
        hb-unicode-emoji-table.hh \
        hb-unicode.cc \
        hb-unicode.hh \
        hb-utf.hh \
        hb-vector.hh \
-       hb-warning.cc \
        hb.hh \
        $(NULL)
 
 HB_BASE_RAGEL_GENERATED_sources = \
        hb-buffer-deserialize-json.hh \
        hb-buffer-deserialize-text.hh \
+       hb-number-parser.hh \
        hb-ot-shape-complex-indic-machine.hh \
        hb-ot-shape-complex-khmer-machine.hh \
        hb-ot-shape-complex-myanmar-machine.hh \
@@ -159,6 +178,7 @@ HB_BASE_RAGEL_GENERATED_sources = \
 HB_BASE_RAGEL_sources = \
        hb-buffer-deserialize-json.rl \
        hb-buffer-deserialize-text.rl \
+       hb-number-parser.rl \
        hb-ot-shape-complex-indic-machine.rl \
        hb-ot-shape-complex-khmer-machine.rl \
        hb-ot-shape-complex-myanmar-machine.rl \
@@ -180,6 +200,8 @@ HB_BASE_headers = \
        hb-ot-font.h \
        hb-ot-layout.h \
        hb-ot-math.h \
+       hb-ot-meta.h \
+       hb-ot-metrics.h \
        hb-ot-name.h \
        hb-ot-shape.h \
        hb-ot-var.h \
@@ -192,10 +214,6 @@ HB_BASE_headers = \
        hb.h \
        $(NULL)
 
-HB_FALLBACK_sources = \
-       hb-fallback-shape.cc    \
-       $(NULL)
-
 # Optional Sources and Headers with external deps
 
 HB_FT_sources = hb-ft.cc
@@ -215,18 +233,20 @@ HB_CORETEXT_headers = hb-coretext.h
 HB_DIRECTWRITE_sources = hb-directwrite.cc
 HB_DIRECTWRITE_headers = hb-directwrite.h
 
+HB_GDI_sources = hb-gdi.cc
+HB_GDI_headers = hb-gdi.h
+
 HB_UNISCRIBE_sources = hb-uniscribe.cc
 HB_UNISCRIBE_headers = hb-uniscribe.h
 
-# Additional supplemental sources
-HB_UCDN_sources  = hb-ucdn.cc
-
 # Sources for libharfbuzz-gobject and libharfbuzz-icu
 HB_ICU_sources = hb-icu.cc
 HB_ICU_headers = hb-icu.h
 
 # Sources for libharfbuzz-subset
 HB_SUBSET_sources = \
+       hb-number.cc \
+       hb-number.hh \
        hb-ot-cff1-table.cc \
        hb-ot-cff2-table.cc \
        hb-static.cc \
@@ -236,9 +256,6 @@ HB_SUBSET_sources = \
        hb-subset-cff1.hh \
        hb-subset-cff2.cc \
        hb-subset-cff2.hh \
-       hb-subset-glyf.cc \
-       hb-subset-glyf.hh \
-       hb-subset-glyf.hh \
        hb-subset-input.cc \
        hb-subset-input.hh \
        hb-subset-plan.cc \
index 423d186..f181b63 100755 (executable)
@@ -7,7 +7,7 @@ test -z "$srcdir" && srcdir=.
 test -z "$libs" && libs=.libs
 stat=0
 
-IGNORED_SYMBOLS='_fini\|_init\|_fdata\|_ftext\|_fbss\|__bss_start\|__bss_start__\|__bss_end__\|_edata\|_end\|_bss_end__\|__end__\|__gcov_flush\|llvm_.*'
+IGNORED_SYMBOLS='_fini\|_init\|_fdata\|_ftext\|_fbss\|__bss_start\|__bss_start__\|__bss_end__\|_edata\|_end\|_bss_end__\|__end__\|__gcov_.*\|llvm_.*'
 
 if which nm 2>/dev/null >/dev/null; then
        :
index 9afe747..49770d4 100755 (executable)
@@ -4,6 +4,7 @@ from __future__ import print_function, division, absolute_import
 import sys
 import os.path
 from collections import OrderedDict
+import packTab
 
 if len (sys.argv) != 2:
        print("usage: ./gen-emoji-table.py emoji-data.txt", file=sys.stderr)
@@ -52,14 +53,19 @@ print ()
 print ('#include "hb-unicode.hh"')
 print ()
 
-for typ,s in ranges.items():
+for typ, s in ranges.items():
        if typ != "Extended_Pictographic": continue
+
+       arr = dict()
+       for start,end in s:
+               for i in range(start,end):
+                       arr[i] = 1
+
+       sol = packTab.pack_table(arr, 0, compression=3)
+       code = packTab.Code('_hb_emoji')
+       sol.genCode(code, 'is_'+typ)
+       code.print_c(linkage='static inline')
        print()
-       print("static const struct hb_unicode_range_t _hb_unicode_emoji_%s_table[] =" % typ)
-       print("{")
-       for pair in sorted(s):
-               print("  {0x%04X, 0x%04X}," % pair)
-       print("};")
 
 print ()
 print ("#endif /* HB_UNICODE_EMOJI_TABLE_HH */")
index eedf420..912b1d7 100755 (executable)
@@ -98,6 +98,10 @@ for h in headers:
                print (" * %s" % (l.strip()))
 print (" */")
 print ()
+print ('#include "hb.hh"')
+print ()
+print ('#ifndef HB_NO_OT_SHAPE')
+print ()
 print ('#include "hb-ot-shape-complex-indic.hh"')
 print ()
 
@@ -129,8 +133,8 @@ what = ["INDIC_SYLLABIC_CATEGORY", "INDIC_MATRA_CATEGORY"]
 what_short = ["ISC", "IMC"]
 print ('#pragma GCC diagnostic push')
 print ('#pragma GCC diagnostic ignored "-Wunused-macros"')
+cat_defs = []
 for i in range (2):
-       print ()
        vv = sorted (values[i].keys ())
        for v in vv:
                v_no_and = v.replace ('_And_', '_')
@@ -142,10 +146,17 @@ for i in range (2):
                                raise Exception ("Duplicate short value alias", v, all_shorts[i][s])
                        all_shorts[i][s] = v
                        short[i][v] = s
-               print ("#define %s_%s   %s_%s   %s/* %3d chars; %s */" %
-                       (what_short[i], s, what[i], v.upper (),
-                       '       '* ((48-1 - len (what[i]) - 1 - len (v)) // 8),
-                       values[i][v], v))
+               cat_defs.append ((what_short[i] + '_' + s, what[i] + '_' + v.upper (), str (values[i][v]), v))
+
+maxlen_s = max ([len (c[0]) for c in cat_defs])
+maxlen_l = max ([len (c[1]) for c in cat_defs])
+maxlen_n = max ([len (c[2]) for c in cat_defs])
+for s in what_short:
+       print ()
+       for c in [c for c in cat_defs if s in c[0]]:
+               print ("#define %s %s /* %s chars; %s */" %
+                       (c[0].ljust (maxlen_s), c[1].ljust (maxlen_l), c[2].rjust (maxlen_n), c[3]))
+print ()
 print ('#pragma GCC diagnostic pop')
 print ()
 print ("#define _(S,M) INDIC_COMBINE_CATEGORIES (ISC_##S, IMC_##M)")
@@ -245,12 +256,14 @@ print ("}")
 print ()
 print ("#undef _")
 for i in range (2):
-       print
+       print ()
        vv = sorted (values[i].keys ())
        for v in vv:
                print ("#undef %s_%s" %
                        (what_short[i], short[i][v]))
 print ()
+print ('#endif')
+print ()
 print ("/* == End of generated table == */")
 
 # Maintain at least 30% occupancy in the table */
old mode 100644 (file)
new mode 100755 (executable)
index 8cf5985..515f4ca
@@ -1,8 +1,10 @@
+#!/usr/bin/python
+
 # -*- coding: utf-8 -*-
 
 # Generates the code for a sorted unicode range array as used in hb-ot-os2-unicode-ranges.hh
 # Input is a tab seperated list of unicode ranges from the otspec
-# (https://docs.microsoft.com/en-us/typography/opentype/spec/os2#ulunicoderange1).
+# (https://docs.microsoft.com/en-us/typography/opentype/spec/os2#ur).
 
 from __future__ import print_function, division, absolute_import
 
index 1300462..49f5b30 100755 (executable)
@@ -895,20 +895,18 @@ def language_name_intersection (a, b):
 def get_matching_language_name (intersection, candidates):
        return next (iter (c for c in candidates if not intersection.isdisjoint (get_variant_set (c))))
 
-maximum_tags = 0
+def same_tag (bcp_47_tag, ot_tags):
+       return len (bcp_47_tag) == 3 and len (ot_tags) == 1 and bcp_47_tag == ot_tags[0].lower ()
+
 for language, tags in sorted (ot.from_bcp_47.items ()):
        if language == '' or '-' in language:
                continue
-       print ('  {\"%s\",\t{' % language, end='')
-       maximum_tags = max (maximum_tags, len (tags))
-       tag_count = len (tags)
+       commented_out = same_tag (language, tags)
        for i, tag in enumerate (tags, start=1):
-               if i > 1:
-                       print ('\t\t ', end='')
-               print (hb_tag (tag), end='')
-               if i == tag_count:
-                       print ('}}', end='')
-               print (',\t/* ', end='')
+               print ('%s{\"%s\",\t%s},' % ('/*' if commented_out else '  ', language, hb_tag (tag)), end='')
+               if commented_out:
+                       print ('*/', end='')
+               print ('\t/* ', end='')
                bcp_47_name = bcp_47.names.get (language, '')
                bcp_47_name_candidates = bcp_47_name.split ('\n')
                intersection = language_name_intersection (bcp_47_name, ot.names[tag])
@@ -923,8 +921,6 @@ for language, tags in sorted (ot.from_bcp_47.items ()):
 
 print ('};')
 print ()
-print ('static_assert (HB_OT_MAX_TAGS_PER_LANGUAGE == %iu, "");' % maximum_tags)
-print ()
 
 print ('/**')
 print (' * hb_ot_tags_from_complex_language:')
@@ -1051,7 +1047,8 @@ print (' * @tag: A language tag.')
 print (' *')
 print (' * Converts @tag to a BCP 47 language tag if it is ambiguous (it corresponds to')
 print (' * many language tags) and the best tag is not the alphabetically first, or if')
-print (' * the best tag consists of multiple subtags.')
+print (' * the best tag consists of multiple subtags, or if the best tag does not appear')
+print (' * in #ot_languages.')
 print (' *')
 print (' * Return value: The #hb_language_t corresponding to the BCP 47 language tag,')
 print (' * or #HB_LANGUAGE_INVALID if @tag is not ambiguous.')
@@ -1102,7 +1099,8 @@ def verify_disambiguation_dict ():
                                                '%s is not a valid disambiguation for %s' % (disambiguation[ot_tag], ot_tag))
                        elif ot_tag not in disambiguation:
                                disambiguation[ot_tag] = macrolanguages[0]
-                       if disambiguation[ot_tag] == sorted (primary_tags)[0] and '-' not in disambiguation[ot_tag]:
+                       different_primary_tags = sorted (t for t in primary_tags if not same_tag (t, ot.from_bcp_47.get (t)))
+                       if different_primary_tags and disambiguation[ot_tag] == different_primary_tags[0] and '-' not in disambiguation[ot_tag]:
                                del disambiguation[ot_tag]
        for ot_tag in disambiguation.keys ():
                expect (ot_tag in ot.to_bcp_47, 'unknown OT tag: %s' % ot_tag)
diff --git a/src/gen-ucd-table.py b/src/gen-ucd-table.py
new file mode 100755 (executable)
index 0000000..552c3c6
--- /dev/null
@@ -0,0 +1,164 @@
+#!/usr/bin/env python
+
+from __future__ import print_function, division, absolute_import
+
+import io, os.path, sys, re
+import logging
+logging.basicConfig(format='%(levelname)s: %(message)s', level=logging.INFO)
+
+if len (sys.argv) not in (2, 3):
+       print("usage: ./gen-ucd-table ucd.nounihan.grouped.xml [/path/to/hb-common.h]", file=sys.stderr)
+       sys.exit(1)
+
+# https://github.com/harfbuzz/packtab
+import packTab
+import packTab.ucdxml
+
+logging.info('Loading UCDXML...')
+ucdxml = packTab.ucdxml.load_ucdxml(sys.argv[1])
+ucd = packTab.ucdxml.ucdxml_get_repertoire(ucdxml)
+
+hb_common_h = 'hb-common.h' if len (sys.argv) < 3 else sys.argv[2]
+
+logging.info('Preparing data tables...')
+
+gc = [u['gc'] for u in ucd]
+ccc = [int(u['ccc']) for u in ucd]
+bmg = [int(v, 16) - int(u) if v else 0 for u,v in enumerate(u['bmg'] for u in ucd)]
+#gc_ccc_non0 = set((cat,klass) for cat,klass in zip(gc,ccc) if klass)
+#gc_bmg_non0 = set((cat,mirr) for cat,mirr in zip(gc, bmg) if mirr)
+
+sc = [u['sc'] for u in ucd]
+
+dm = {i:tuple(int(v, 16) for v in u['dm'].split()) for i,u in enumerate(ucd)
+      if u['dm'] != '#' and u['dt'] == 'can' and not (0xAC00 <= i < 0xAC00+11172)}
+ce = {i for i,u in enumerate(ucd) if u['Comp_Ex'] == 'Y'}
+
+assert not any(v for v in dm.values() if len(v) not in (1,2))
+dm1 = sorted(set(v for v in dm.values() if len(v) == 1))
+assert all((v[0] >> 16) in (0,2) for v in dm1)
+dm1_p0_array = ['0x%04Xu' % (v[0] & 0xFFFF) for v in dm1 if (v[0] >> 16) == 0]
+dm1_p2_array = ['0x%04Xu' % (v[0] & 0xFFFF) for v in dm1 if (v[0] >> 16) == 2]
+dm1_order = {v:i+1 for i,v in enumerate(dm1)}
+
+dm2 = sorted((v+(i if i not in ce and not ccc[i] else 0,), v)
+             for i,v in dm.items() if len(v) == 2)
+
+filt = lambda v: ((v[0] & 0xFFFFF800) == 0x0000 and
+                  (v[1] & 0xFFFFFF80) == 0x0300 and
+                  (v[2] & 0xFFF0C000) == 0x0000)
+dm2_u32_array = [v for v in dm2 if filt(v[0])]
+dm2_u64_array = [v for v in dm2 if not filt(v[0])]
+assert dm2_u32_array + dm2_u64_array == dm2
+dm2_u32_array = ["HB_CODEPOINT_ENCODE3_11_7_14 (0x%04Xu, 0x%04Xu, 0x%04Xu)" % v[0] for v in dm2_u32_array]
+dm2_u64_array = ["HB_CODEPOINT_ENCODE3 (0x%04Xu, 0x%04Xu, 0x%04Xu)" % v[0] for v in dm2_u64_array]
+
+l = 1 + len(dm1_p0_array) + len(dm1_p2_array)
+dm2_order = {v[1]:i+l for i,v in enumerate(dm2)}
+
+dm_order = {None: 0}
+dm_order.update(dm1_order)
+dm_order.update(dm2_order)
+
+gc_order = dict()
+for i,v in enumerate(('Cc', 'Cf', 'Cn', 'Co', 'Cs', 'Ll', 'Lm', 'Lo', 'Lt', 'Lu',
+                      'Mc', 'Me', 'Mn', 'Nd', 'Nl', 'No', 'Pc', 'Pd', 'Pe', 'Pf',
+                      'Pi', 'Po', 'Ps', 'Sc', 'Sk', 'Sm', 'So', 'Zl', 'Zp', 'Zs',)):
+    gc_order[i] = v
+    gc_order[v] = i
+
+sc_order = dict()
+sc_array = []
+sc_re = re.compile(r"\b(HB_SCRIPT_[_A-Z]*).*HB_TAG [(]'(.)','(.)','(.)','(.)'[)]")
+for line in open(hb_common_h):
+    m = sc_re.search (line)
+    if not m: continue
+    name = m.group(1)
+    tag = ''.join(m.group(i) for i in range(2, 6))
+    i = len(sc_array)
+    sc_order[tag] = i
+    sc_order[i] = tag
+    sc_array.append(name)
+
+DEFAULT = 1
+COMPACT = 3
+SLOPPY  = 5
+
+
+logging.info('Generating output...')
+print("/* == Start of generated table == */")
+print("/*")
+print(" * The following table is generated by running:")
+print(" *")
+print(" *   ./gen-ucd-table.py ucd.nounihan.grouped.xml")
+print(" *")
+print(" * on file with this description:", ucdxml.description)
+print(" */")
+print()
+print("#ifndef HB_UCD_TABLE_HH")
+print("#define HB_UCD_TABLE_HH")
+print()
+print('#include "hb.hh"')
+print()
+
+code = packTab.Code('_hb_ucd')
+sc_array, _ = code.addArray('hb_script_t', 'sc_map', sc_array)
+dm1_p0_array, _ = code.addArray('uint16_t', 'dm1_p0_map', dm1_p0_array)
+dm1_p2_array, _ = code.addArray('uint16_t', 'dm1_p2_map', dm1_p2_array)
+dm2_u32_array, _ = code.addArray('uint32_t', 'dm2_u32_map', dm2_u32_array)
+dm2_u64_array, _ = code.addArray('uint64_t', 'dm2_u64_map', dm2_u64_array)
+code.print_c(linkage='static inline')
+
+datasets = [
+    ('gc', gc, 'Cn', gc_order),
+    ('ccc', ccc, 0, None),
+    ('bmg', bmg, 0, None),
+    ('sc', sc, 'Zzzz', sc_order),
+    ('dm', dm, None, dm_order),
+]
+
+for compression in (DEFAULT, COMPACT, SLOPPY):
+    logging.info('  Compression=%d:' % compression)
+    print()
+    if compression == DEFAULT:
+        print('#ifndef HB_OPTIMIZE_SIZE')
+    elif compression == COMPACT:
+        print('#elif !defined(HB_NO_UCD_UNASSIGNED)')
+    else:
+        print('#else')
+    print()
+
+    if compression == SLOPPY:
+        for i in range(len(gc)):
+            if (i % 128) and gc[i] == 'Cn':
+                gc[i] = gc[i - 1]
+        for i in range(len(gc) - 2, -1, -1):
+            if ((i + 1) % 128) and gc[i] == 'Cn':
+                gc[i] = gc[i + 1]
+        for i in range(len(sc)):
+            if (i % 128) and sc[i] == 'Zzzz':
+                sc[i] = sc[i - 1]
+        for i in range(len(sc) - 2, -1, -1):
+            if ((i + 1) % 128) and sc[i] == 'Zzzz':
+                sc[i] = sc[i + 1]
+
+
+    code = packTab.Code('_hb_ucd')
+
+    for name,data,default,mapping in datasets:
+        sol = packTab.pack_table(data, default, mapping=mapping, compression=compression)
+        logging.info('      Dataset=%-8s FullCost=%d' % (name, sol.fullCost))
+        sol.genCode(code, name)
+
+    code.print_c(linkage='static inline')
+
+    print()
+
+print('#endif')
+print()
+
+print()
+print("#endif /* HB_UCD_TABLE_HH */")
+print()
+print("/* == End of generated table == */")
+logging.info('Done.')
index 029e66e..4523fb8 100755 (executable)
@@ -47,8 +47,22 @@ defaults = ('Other', 'Not_Applicable', 'Cn', 'No_Block')
 
 # TODO Characters that are not in Unicode Indic files, but used in USE
 data[0][0x034F] = defaults[0]
+data[0][0x1B61] = defaults[0]
+data[0][0x1B63] = defaults[0]
+data[0][0x1B64] = defaults[0]
+data[0][0x1B65] = defaults[0]
+data[0][0x1B66] = defaults[0]
+data[0][0x1B67] = defaults[0]
+data[0][0x1B69] = defaults[0]
+data[0][0x1B6A] = defaults[0]
 data[0][0x2060] = defaults[0]
-# TODO https://github.com/roozbehp/unicode-data/issues/9
+# TODO https://github.com/harfbuzz/harfbuzz/pull/1685
+data[0][0x1B5B] = 'Consonant_Placeholder'
+data[0][0x1B5C] = 'Consonant_Placeholder'
+data[0][0x1B5F] = 'Consonant_Placeholder'
+data[0][0x1B62] = 'Consonant_Placeholder'
+data[0][0x1B68] = 'Consonant_Placeholder'
+# TODO https://github.com/harfbuzz/harfbuzz/issues/1035
 data[0][0x11C44] = 'Consonant_Placeholder'
 data[0][0x11C45] = 'Consonant_Placeholder'
 # TODO https://github.com/harfbuzz/harfbuzz/pull/1399
@@ -171,7 +185,7 @@ def is_BASE(U, UISC, UGC):
 def is_BASE_IND(U, UISC, UGC):
        #SPEC-DRAFT return (UISC in [Consonant_Dead, Modifying_Letter] or UGC == Po)
        return (UISC in [Consonant_Dead, Modifying_Letter] or
-               (UGC == Po and not U in [0x104B, 0x104E, 0x2022, 0x111C8, 0x11A3F, 0x11A45, 0x11C44, 0x11C45]) or
+               (UGC == Po and not U in [0x104B, 0x104E, 0x1B5B, 0x1B5C, 0x1B5F, 0x2022, 0x111C8, 0x11A3F, 0x11A45, 0x11C44, 0x11C45]) or
                False # SPEC-DRAFT-OUTDATED! U == 0x002D
                )
 def is_BASE_NUM(U, UISC, UGC):
@@ -183,15 +197,15 @@ def is_BASE_OTHER(U, UISC, UGC):
 def is_CGJ(U, UISC, UGC):
        return U == 0x034F
 def is_CONS_FINAL(U, UISC, UGC):
-       # Consonant_Initial_Postfixed is new in Unicode 11; not in the spec.
        return ((UISC == Consonant_Final and UGC != Lo) or
-               UISC == Consonant_Initial_Postfixed or
                UISC == Consonant_Succeeding_Repha)
 def is_CONS_FINAL_MOD(U, UISC, UGC):
        #SPEC-DRAFT return  UISC in [Consonant_Final_Modifier, Syllable_Modifier]
        return  UISC == Syllable_Modifier
 def is_CONS_MED(U, UISC, UGC):
-       return UISC == Consonant_Medial and UGC != Lo
+       # Consonant_Initial_Postfixed is new in Unicode 11; not in the spec.
+       return (UISC == Consonant_Medial and UGC != Lo or
+               UISC == Consonant_Initial_Postfixed)
 def is_CONS_MOD(U, UISC, UGC):
        return UISC in [Nukta, Gemination_Mark, Consonant_Killer]
 def is_CONS_SUB(U, UISC, UGC):
@@ -200,7 +214,9 @@ def is_CONS_SUB(U, UISC, UGC):
 def is_CONS_WITH_STACKER(U, UISC, UGC):
        return UISC == Consonant_With_Stacker
 def is_HALANT(U, UISC, UGC):
-       return UISC in [Virama, Invisible_Stacker] and not is_HALANT_OR_VOWEL_MODIFIER(U, UISC, UGC)
+       return (UISC in [Virama, Invisible_Stacker]
+               and not is_HALANT_OR_VOWEL_MODIFIER(U, UISC, UGC)
+               and not is_SAKOT(U, UISC, UGC))
 def is_HALANT_OR_VOWEL_MODIFIER(U, UISC, UGC):
        # https://github.com/harfbuzz/harfbuzz/issues/1102
        # https://github.com/harfbuzz/harfbuzz/issues/1379
@@ -216,6 +232,7 @@ def is_Word_Joiner(U, UISC, UGC):
 def is_OTHER(U, UISC, UGC):
        #SPEC-OUTDATED return UGC == Zs # or any other SCRIPT_COMMON characters
        return (UISC == Other
+               and not is_SYM(U, UISC, UGC)
                and not is_SYM_MOD(U, UISC, UGC)
                and not is_CGJ(U, UISC, UGC)
                and not is_Word_Joiner(U, UISC, UGC)
@@ -225,20 +242,22 @@ def is_Reserved(U, UISC, UGC):
        return UGC == 'Cn'
 def is_REPHA(U, UISC, UGC):
        return UISC in [Consonant_Preceding_Repha, Consonant_Prefixed]
+def is_SAKOT(U, UISC, UGC):
+       return U == 0x1A60
 def is_SYM(U, UISC, UGC):
        if U == 0x25CC: return False #SPEC-DRAFT
        #SPEC-DRAFT return UGC in [So, Sc] or UISC == Symbol_Letter
-       return UGC in [So, Sc]
+       return UGC in [So, Sc] and U not in [0x1B62, 0x1B68]
 def is_SYM_MOD(U, UISC, UGC):
        return U in [0x1B6B, 0x1B6C, 0x1B6D, 0x1B6E, 0x1B6F, 0x1B70, 0x1B71, 0x1B72, 0x1B73]
 def is_VARIATION_SELECTOR(U, UISC, UGC):
        return 0xFE00 <= U <= 0xFE0F
 def is_VOWEL(U, UISC, UGC):
-       # https://github.com/roozbehp/unicode-data/issues/6
+       # https://github.com/harfbuzz/harfbuzz/issues/376
        return (UISC == Pure_Killer or
                (UGC != Lo and UISC in [Vowel, Vowel_Dependent] and U not in [0xAA29]))
 def is_VOWEL_MOD(U, UISC, UGC):
-       # https://github.com/roozbehp/unicode-data/issues/6
+       # https://github.com/harfbuzz/harfbuzz/issues/376
        return (UISC in [Tone_Mark, Cantillation_Mark, Register_Shifter, Visarga] or
                (UGC != Lo and (UISC == Bindu or U in [0xAA29])))
 
@@ -264,6 +283,7 @@ use_mapping = {
        'Rsv':  is_Reserved,
        'R':    is_REPHA,
        'S':    is_SYM,
+       'Sk':   is_SAKOT,
        'SM':   is_SYM_MOD,
        'VS':   is_VARIATION_SELECTOR,
        'V':    is_VOWEL,
@@ -305,7 +325,11 @@ use_positions = {
        'H': None,
        'HVM': None,
        'B': None,
-       'FM': None,
+       'FM': {
+               'Abv': [Top],
+               'Blw': [Bottom],
+               'Pst': [Not_Applicable],
+       },
        'SUB': None,
 }
 
@@ -344,15 +368,9 @@ def map_to_use(data):
                # the nasalization marks, maybe only for U+1CE9..U+1CF1.
                if U == 0x1CED: UISC = Tone_Mark
 
-               # TODO: https://github.com/harfbuzz/harfbuzz/issues/525
-               if U == 0x1A7F: UISC = Consonant_Final
-
                # TODO: https://github.com/harfbuzz/harfbuzz/issues/1105
                if U == 0x11134: UISC = Gemination_Mark
 
-               # TODO: https://github.com/harfbuzz/harfbuzz/pull/1399
-               if U == 0x111C9: UISC = Consonant_Final
-
                values = [k for k,v in items if v(U,UISC,UGC)]
                assert len(values) == 1, "%s %s %s %s" % (hex(U), UISC, UGC, values)
                USE = values[0]
@@ -365,6 +383,9 @@ def map_to_use(data):
                # TODO: In USE's override list but not in Unicode 12.0
                if U == 0x103C: UIPC = Left
 
+               # TODO: https://github.com/harfbuzz/harfbuzz/pull/2012
+               if U == 0x1C29: UIPC = Left
+
                # TODO: These are not in USE's override list that we have, nor are they in Unicode 12.0
                if 0xA926 <= U <= 0xA92A: UIPC = Top
                # TODO: https://github.com/harfbuzz/harfbuzz/pull/1037
@@ -401,6 +422,10 @@ for h in headers:
                print (" * %s" % (l.strip()))
 print (" */")
 print ()
+print ('#include "hb.hh"')
+print ()
+print ('#ifndef HB_NO_OT_SHAPE')
+print ()
 print ('#include "hb-ot-shape-complex-use.hh"')
 print ()
 
@@ -515,6 +540,8 @@ for k,v in sorted(use_positions.items()):
                tag = k + suf
                print ("#undef %s" % tag)
 print ()
+print ()
+print ('#endif')
 print ("/* == End of generated table == */")
 
 # Maintain at least 50% occupancy in the table */
index afb21d9..8ca90c8 100755 (executable)
@@ -157,6 +157,11 @@ print (' *')
 for line in scripts_header:
        print (' * %s' % line.strip ())
 print (' */')
+
+print ()
+print ('#include "hb.hh"')
+print ()
+print ('#ifndef HB_NO_OT_SHAPE')
 print ()
 print ('#include "hb-ot-shape-complex-vowel-constraints.hh"')
 print ()
@@ -180,6 +185,9 @@ print ('_hb_preprocess_text_vowel_constraints (const hb_ot_shape_plan_t *plan HB
 print ('\t\t\t\t       hb_buffer_t              *buffer,')
 print ('\t\t\t\t       hb_font_t                *font HB_UNUSED)')
 print ('{')
+print ('#if defined(HB_NO_OT_SHAPE_COMPLEX_VOWEL_CONSTRAINTS)')
+print ('  return;')
+print ('#endif')
 print ('  if (buffer->flags & HB_BUFFER_FLAG_DO_NOT_INSERT_DOTTED_CIRCLE)')
 print ('    return;')
 print ()
@@ -220,4 +228,6 @@ print ('  }')
 print ('}')
 
 print ()
+print ()
+print ('#endif')
 print ('/* == End of generated functions == */')
diff --git a/src/harfbuzz.cc b/src/harfbuzz.cc
new file mode 100644 (file)
index 0000000..251a065
--- /dev/null
@@ -0,0 +1,53 @@
+#include "hb-aat-layout.cc"
+#include "hb-aat-map.cc"
+#include "hb-blob.cc"
+#include "hb-buffer-serialize.cc"
+#include "hb-buffer.cc"
+#include "hb-common.cc"
+#include "hb-face.cc"
+#include "hb-fallback-shape.cc"
+#include "hb-font.cc"
+#include "hb-map.cc"
+#include "hb-number.cc"
+#include "hb-ot-cff1-table.cc"
+#include "hb-ot-cff2-table.cc"
+#include "hb-ot-color.cc"
+#include "hb-ot-face.cc"
+#include "hb-ot-font.cc"
+#include "hb-ot-layout.cc"
+#include "hb-ot-map.cc"
+#include "hb-ot-math.cc"
+#include "hb-ot-meta.cc"
+#include "hb-ot-metrics.cc"
+#include "hb-ot-name.cc"
+#include "hb-ot-shape-complex-arabic.cc"
+#include "hb-ot-shape-complex-default.cc"
+#include "hb-ot-shape-complex-hangul.cc"
+#include "hb-ot-shape-complex-hebrew.cc"
+#include "hb-ot-shape-complex-indic-table.cc"
+#include "hb-ot-shape-complex-indic.cc"
+#include "hb-ot-shape-complex-khmer.cc"
+#include "hb-ot-shape-complex-myanmar.cc"
+#include "hb-ot-shape-complex-thai.cc"
+#include "hb-ot-shape-complex-use-table.cc"
+#include "hb-ot-shape-complex-use.cc"
+#include "hb-ot-shape-complex-vowel-constraints.cc"
+#include "hb-ot-shape-fallback.cc"
+#include "hb-ot-shape-normalize.cc"
+#include "hb-ot-shape.cc"
+#include "hb-ot-tag.cc"
+#include "hb-ot-var.cc"
+#include "hb-set.cc"
+#include "hb-shape-plan.cc"
+#include "hb-shape.cc"
+#include "hb-shaper.cc"
+#include "hb-static.cc"
+#include "hb-ucd.cc"
+#include "hb-unicode.cc"
+#include "hb-glib.cc"
+#include "hb-ft.cc"
+#include "hb-graphite2.cc"
+#include "hb-uniscribe.cc"
+#include "hb-gdi.cc"
+#include "hb-directwrite.cc"
+#include "hb-coretext.cc"
index 1188e35..604d5bc 100644 (file)
@@ -65,7 +65,7 @@ struct FontDescriptor
   protected:
   Tag          tag;            /* The 4-byte table tag name. */
   union {
-  Fixed                value;          /* The value for the descriptor tag. */
+  HBFixed              value;          /* The value for the descriptor tag. */
   HBUINT32     nalfType;       /* If the tag is `nalf`, see non_alphabetic_value_t */
   } u;
   public:
@@ -108,7 +108,7 @@ struct fdsc
   }
 
   protected:
-  Fixed                version;        /* Version number of the font descriptors
+  HBFixed              version;        /* Version number of the font descriptors
                                 * table (0x00010000 for the current version). */
   LArrayOf<FontDescriptor>
                descriptors;    /* List of tagged-coordinate pairs style descriptors
index 4087b8c..ef98884 100644 (file)
@@ -83,7 +83,7 @@ struct ankr
   protected:
   HBUINT16     version;        /* Version number (set to zero) */
   HBUINT16     flags;          /* Flags (currently unused; set to zero) */
-  LOffsetTo<Lookup<NNOffsetTo<GlyphAnchors> > >
+  LOffsetTo<Lookup<NNOffsetTo<GlyphAnchors>>>
                lookupTable;    /* Offset to the table's lookup table */
   LNNOffsetTo<HBUINT8>
                anchorData;     /* Offset to the glyph data table */
index 9139d28..15ef2da 100644 (file)
@@ -82,7 +82,7 @@ struct BaselineTableFormat2Part
   }
 
   protected:
-  GlyphID      stdGlyph;       /* The specific glyph index number in this
+  HBGlyphID    stdGlyph;       /* The specific glyph index number in this
                                 * font that is used to set the baseline values.
                                 * This is the standard glyph.
                                 * This glyph must contain a set of control points
@@ -105,7 +105,7 @@ struct BaselineTableFormat3Part
   }
 
   protected:
-  GlyphID      stdGlyph;       /* ditto */
+  HBGlyphID    stdGlyph;       /* ditto */
   HBUINT16     ctlPoints[32];  /* ditto */
   Lookup<HBUINT16>
                lookupTable;    /* Lookup table that maps glyphs to their
index 2508276..473f2cd 100644 (file)
@@ -93,8 +93,8 @@ struct LookupSegmentSingle
     return_trace (c->check_struct (this) && value.sanitize (c, base));
   }
 
-  GlyphID      last;           /* Last GlyphID in this segment */
-  GlyphID      first;          /* First GlyphID in this segment */
+  HBGlyphID    last;           /* Last GlyphID in this segment */
+  HBGlyphID    first;          /* First GlyphID in this segment */
   T            value;          /* The lookup value (only one) */
   public:
   DEFINE_SIZE_STATIC (4 + T::static_size);
@@ -125,7 +125,7 @@ struct LookupFormat2
 
   protected:
   HBUINT16     format;         /* Format identifier--format = 2 */
-  VarSizedBinSearchArrayOf<LookupSegmentSingle<T> >
+  VarSizedBinSearchArrayOf<LookupSegmentSingle<T>>
                segments;       /* The actual segments. These must already be sorted,
                                 * according to the first word in each one (the last
                                 * glyph in each segment). */
@@ -153,18 +153,18 @@ struct LookupSegmentArray
                  first <= last &&
                  valuesZ.sanitize (c, base, last - first + 1));
   }
-  template <typename T2>
-  bool sanitize (hb_sanitize_context_t *c, const void *base, T2 user_data) const
+  template <typename ...Ts>
+  bool sanitize (hb_sanitize_context_t *c, const void *base, Ts&&... ds) const
   {
     TRACE_SANITIZE (this);
     return_trace (c->check_struct (this) &&
                  first <= last &&
-                 valuesZ.sanitize (c, base, last - first + 1, user_data));
+                 valuesZ.sanitize (c, base, last - first + 1, hb_forward<Ts> (ds)...));
   }
 
-  GlyphID      last;           /* Last GlyphID in this segment */
-  GlyphID      first;          /* First GlyphID in this segment */
-  NNOffsetTo<UnsizedArrayOf<T> >
+  HBGlyphID    last;           /* Last GlyphID in this segment */
+  HBGlyphID    first;          /* First GlyphID in this segment */
+  NNOffsetTo<UnsizedArrayOf<T>>
                valuesZ;        /* A 16-bit offset from the start of
                                 * the table to the data. */
   public:
@@ -196,7 +196,7 @@ struct LookupFormat4
 
   protected:
   HBUINT16     format;         /* Format identifier--format = 4 */
-  VarSizedBinSearchArrayOf<LookupSegmentArray<T> >
+  VarSizedBinSearchArrayOf<LookupSegmentArray<T>>
                segments;       /* The actual segments. These must already be sorted,
                                 * according to the first word in each one (the last
                                 * glyph in each segment). */
@@ -222,7 +222,7 @@ struct LookupSingle
     return_trace (c->check_struct (this) && value.sanitize (c, base));
   }
 
-  GlyphID      glyph;          /* Last GlyphID */
+  HBGlyphID    glyph;          /* Last GlyphID */
   T            value;          /* The lookup value (only one) */
   public:
   DEFINE_SIZE_STATIC (2 + T::static_size);
@@ -253,7 +253,7 @@ struct LookupFormat6
 
   protected:
   HBUINT16     format;         /* Format identifier--format = 6 */
-  VarSizedBinSearchArrayOf<LookupSingle<T> >
+  VarSizedBinSearchArrayOf<LookupSingle<T>>
                entries;        /* The actual entries, sorted by glyph index. */
   public:
   DEFINE_SIZE_ARRAY (8, entries);
@@ -284,7 +284,7 @@ struct LookupFormat8
 
   protected:
   HBUINT16     format;         /* Format identifier--format = 8 */
-  GlyphID      firstGlyph;     /* First glyph index included in the trimmed array. */
+  HBGlyphID    firstGlyph;     /* First glyph index included in the trimmed array. */
   HBUINT16     glyphCount;     /* Total number of glyphs (equivalent to the last
                                 * glyph minus the value of firstGlyph plus 1). */
   UnsizedArrayOf<T>
@@ -326,7 +326,7 @@ struct LookupFormat10
   protected:
   HBUINT16     format;         /* Format identifier--format = 8 */
   HBUINT16     valueSize;      /* Byte size of each value. */
-  GlyphID      firstGlyph;     /* First glyph index included in the trimmed array. */
+  HBGlyphID    firstGlyph;     /* First glyph index included in the trimmed array. */
   HBUINT16     glyphCount;     /* Total number of glyphs (equivalent to the last
                                 * glyph minus the value of firstGlyph plus 1). */
   UnsizedArrayOf<HBUINT8>
@@ -419,7 +419,7 @@ struct Lookup
 /* Ugly hand-coded null objects for template Lookup<> :(. */
 extern HB_INTERNAL const unsigned char _hb_Null_AAT_Lookup[2];
 template <typename T>
-struct Null<AAT::Lookup<T> > {
+struct Null<AAT::Lookup<T>> {
   static AAT::Lookup<T> const & get_null ()
   { return *reinterpret_cast<const AAT::Lookup<T> *> (_hb_Null_AAT_Lookup); }
 };
@@ -510,7 +510,7 @@ struct StateTable
   const Entry<Extra> &get_entry (int state, unsigned int klass) const
   {
     if (unlikely (klass >= nClasses))
-      klass = StateTable<Types, Entry<Extra> >::CLASS_OUT_OF_BOUNDS;
+      klass = StateTable<Types, Entry<Extra>>::CLASS_OUT_OF_BOUNDS;
 
     const HBUSHORT *states = (this+stateArrayTable).arrayZ;
     const Entry<Extra> *entries = (this+entryTable).arrayZ;
@@ -576,7 +576,7 @@ struct StateTable
          if (unlikely (stop > states))
            return_trace (false);
          for (const HBUSHORT *p = states; stop < p; p--)
-           num_entries = MAX<unsigned int> (num_entries, *(p - 1) + 1);
+           num_entries = hb_max (num_entries, *(p - 1) + 1);
          state_neg = min_state;
        }
       }
@@ -597,7 +597,7 @@ struct StateTable
          if (unlikely (stop < states))
            return_trace (false);
          for (const HBUSHORT *p = &states[state_pos * num_classes]; p < stop; p++)
-           num_entries = MAX<unsigned int> (num_entries, *p + 1);
+           num_entries = hb_max (num_entries, *p + 1);
          state_pos = max_state + 1;
        }
       }
@@ -611,8 +611,8 @@ struct StateTable
        for (const Entry<Extra> *p = &entries[entry]; p < stop; p++)
        {
          int newState = new_state (p->newState);
-         min_state = MIN (min_state, newState);
-         max_state = MAX (max_state, newState);
+         min_state = hb_min (min_state, newState);
+         max_state = hb_max (max_state, newState);
        }
        entry = num_entries;
       }
@@ -631,7 +631,7 @@ struct StateTable
                classTable;     /* Offset to the class table. */
   NNOffsetTo<UnsizedArrayOf<HBUSHORT>, HBUINT>
                stateArrayTable;/* Offset to the state array. */
-  NNOffsetTo<UnsizedArrayOf<Entry<Extra> >, HBUINT>
+  NNOffsetTo<UnsizedArrayOf<Entry<Extra>>, HBUINT>
                entryTable;     /* Offset to the entry array. */
 
   public:
@@ -658,7 +658,7 @@ struct ClassTable
     return_trace (c->check_struct (this) && classArray.sanitize (c));
   }
   protected:
-  GlyphID              firstGlyph;     /* First glyph index included in the trimmed array. */
+  HBGlyphID            firstGlyph;     /* First glyph index included in the trimmed array. */
   ArrayOf<HBUCHAR>     classArray;     /* The class codes (indexed by glyph index minus
                                         * firstGlyph). */
   public:
@@ -678,7 +678,7 @@ struct ObsoleteTypes
                                     const void *base,
                                     const T *array)
   {
-    return (offset - ((const char *) array - (const char *) base)) / sizeof (T);
+    return (offset - ((const char *) array - (const char *) base)) / T::static_size;
   }
   template <typename T>
   static unsigned int byteOffsetToIndex (unsigned int offset,
index ab23ee0..788d408 100644 (file)
@@ -47,17 +47,16 @@ struct SettingName
   hb_aat_layout_feature_selector_t get_selector () const
   { return (hb_aat_layout_feature_selector_t) (unsigned) setting; }
 
-  void get_info (hb_aat_layout_feature_selector_info_t *s,
-                       hb_aat_layout_feature_selector_t default_selector) const
+  hb_aat_layout_feature_selector_info_t get_info (hb_aat_layout_feature_selector_t default_selector) const
   {
-    s->name_id = nameIndex;
-
-    s->enable = (hb_aat_layout_feature_selector_t) (unsigned int) setting;
-    s->disable = default_selector == HB_AAT_LAYOUT_FEATURE_SELECTOR_INVALID ?
-                (hb_aat_layout_feature_selector_t) (s->enable + 1) :
-                default_selector;
-
-    s->reserved = 0;
+    return {
+      nameIndex,
+      (hb_aat_layout_feature_selector_t) (unsigned int) setting,
+      default_selector == HB_AAT_LAYOUT_FEATURE_SELECTOR_INVALID
+       ? (hb_aat_layout_feature_selector_t) (setting + 1)
+       : default_selector,
+      0
+    };
   }
 
   bool sanitize (hb_sanitize_context_t *c) const
@@ -117,9 +116,10 @@ struct FeatureName
 
     if (selectors_count)
     {
-      hb_array_t<const SettingName> arr = settings_table.sub_array (start_offset, selectors_count);
-      for (unsigned int i = 0; i < arr.length; i++)
-        settings_table[start_offset + i].get_info (&selectors[i], default_selector);
+      + settings_table.sub_array (start_offset, selectors_count)
+      | hb_map ([=] (const SettingName& setting) { return setting.get_info (default_selector); })
+      | hb_sink (hb_array (selectors, *selectors_count))
+      ;
     }
     return settings_table.length;
   }
@@ -162,21 +162,18 @@ struct feat
                                  unsigned int                 *count,
                                  hb_aat_layout_feature_type_t *features) const
   {
-    unsigned int feature_count = featureNameCount;
-    if (count && *count)
+    if (count)
     {
-      unsigned int len = MIN (feature_count - start_offset, *count);
-      for (unsigned int i = 0; i < len; i++)
-       features[i] = namesZ[i + start_offset].get_feature_type ();
-      *count = len;
+      + namesZ.as_array (featureNameCount).sub_array (start_offset, count)
+      | hb_map (&FeatureName::get_feature_type)
+      | hb_sink (hb_array (features, *count))
+      ;
     }
     return featureNameCount;
   }
 
   const FeatureName& get_feature (hb_aat_layout_feature_type_t feature_type) const
-  {
-    return namesZ.bsearch (featureNameCount, feature_type);
-  }
+  { return namesZ.bsearch (featureNameCount, feature_type); }
 
   hb_ot_name_id_t get_feature_name_id (hb_aat_layout_feature_type_t feature) const
   { return get_feature (feature).get_feature_name_id (); }
@@ -209,7 +206,7 @@ struct feat
   SortedUnsizedArrayOf<FeatureName>
                namesZ;         /* The feature name array. */
   public:
-  DEFINE_SIZE_STATIC (24);
+  DEFINE_SIZE_ARRAY (12, namesZ);
 };
 
 } /* namespace AAT */
index d53f8f1..e1787d1 100644 (file)
@@ -70,9 +70,9 @@ struct DecompositionAction
 
   ActionSubrecordHeader
                header;
-  Fixed                lowerLimit;     /* If the distance factor is less than this value,
+  HBFixed              lowerLimit;     /* If the distance factor is less than this value,
                                 * then the ligature is decomposed. */
-  Fixed                upperLimit;     /* If the distance factor is greater than this value,
+  HBFixed              upperLimit;     /* If the distance factor is greater than this value,
                                 * then the ligature is decomposed. */
   HBUINT16     order;          /* Numerical order in which this ligature will
                                 * be decomposed; you may want infrequent ligatures
@@ -100,7 +100,7 @@ struct UnconditionalAddGlyphAction
   protected:
   ActionSubrecordHeader
                header;
-  GlyphID      addGlyph;       /* Glyph that should be added if the distance factor
+  HBGlyphID    addGlyph;       /* Glyph that should be added if the distance factor
                                 * is growing. */
 
   public:
@@ -118,14 +118,14 @@ struct ConditionalAddGlyphAction
   protected:
   ActionSubrecordHeader
                header;
-  Fixed        substThreshold; /* Distance growth factor (in ems) at which
+  HBFixed      substThreshold; /* Distance growth factor (in ems) at which
                                 * this glyph is replaced and the growth factor
                                 * recalculated. */
-  GlyphID      addGlyph;       /* Glyph to be added as kashida. If this value is
+  HBGlyphID    addGlyph;       /* Glyph to be added as kashida. If this value is
                                 * 0xFFFF, no extra glyph will be added. Note that
                                 * generally when a glyph is added, justification
                                 * will need to be redone. */
-  GlyphID      substGlyph;     /* Glyph to be substituted for this glyph if the
+  HBGlyphID    substGlyph;     /* Glyph to be substituted for this glyph if the
                                 * growth factor equals or exceeds the value of
                                 * substThreshold. */
   public:
@@ -146,13 +146,13 @@ struct DuctileGlyphAction
   HBUINT32     variationAxis;  /* The 4-byte tag identifying the ductile axis.
                                 * This would normally be 0x64756374 ('duct'),
                                 * but you may use any axis the font contains. */
-  Fixed        minimumLimit;   /* The lowest value for the ductility axis tha
+  HBFixed      minimumLimit;   /* The lowest value for the ductility axis tha
                                 * still yields an acceptable appearance. Normally
                                 * this will be 1.0. */
-  Fixed        noStretchValue; /* This is the default value that corresponds to
+  HBFixed      noStretchValue; /* This is the default value that corresponds to
                                 * no change in appearance. Normally, this will
                                 * be 1.0. */
-  Fixed        maximumLimit;   /* The highest value for the ductility axis that
+  HBFixed      maximumLimit;   /* The highest value for the ductility axis that
                                 * still yields an acceptable appearance. */
   public:
   DEFINE_SIZE_STATIC (22);
@@ -170,7 +170,7 @@ struct RepeatedAddGlyphAction
   ActionSubrecordHeader
                header;
   HBUINT16     flags;          /* Currently unused; set to 0. */
-  GlyphID      glyph;          /* Glyph that should be added if the distance factor
+  HBGlyphID    glyph;          /* Glyph that should be added if the distance factor
                                 * is growing. */
   public:
   DEFINE_SIZE_STATIC (10);
@@ -271,14 +271,14 @@ struct JustWidthDeltaEntry
   };
 
   protected:
-  Fixed                beforeGrowLimit;/* The ratio by which the advance width of the
+  HBFixed              beforeGrowLimit;/* The ratio by which the advance width of the
                                 * glyph is permitted to grow on the left or top side. */
-  Fixed                beforeShrinkLimit;
+  HBFixed              beforeShrinkLimit;
                                /* The ratio by which the advance width of the
                                 * glyph is permitted to shrink on the left or top side. */
-  Fixed                afterGrowLimit; /* The ratio by which the advance width of the glyph
+  HBFixed              afterGrowLimit; /* The ratio by which the advance width of the glyph
                                 * is permitted to shrink on the left or top side. */
-  Fixed                afterShrinkLimit;
+  HBFixed              afterShrinkLimit;
                                /* The ratio by which the advance width of the glyph
                                 * is at most permitted to shrink on the right or
                                 * bottom side. */
@@ -309,7 +309,7 @@ struct WidthDeltaPair
   public:
   DEFINE_SIZE_STATIC (24);
 };
-  
+
 typedef OT::LArrayOf<WidthDeltaPair> WidthDeltaCluster;
 
 struct JustificationCategory
@@ -371,7 +371,7 @@ struct JustificationHeader
                                 * of postcompensation subtable (set to zero if none).
                                 *
                                 * The postcompensation subtable, if present in the font. */
-  Lookup<OffsetTo<WidthDeltaCluster> >
+  Lookup<OffsetTo<WidthDeltaCluster>>
                lookupTable;    /* Lookup table associating glyphs with width delta
                                 * clusters. See the description of Width Delta Clusters
                                 * table for details on how to interpret the lookup values. */
index a64c807..be1b339 100644 (file)
@@ -82,8 +82,8 @@ struct KernPair
   }
 
   protected:
-  GlyphID      left;
-  GlyphID      right;
+  HBGlyphID    left;
+  HBGlyphID    right;
   FWORD                value;
   public:
   DEFINE_SIZE_STATIC (6);
@@ -251,7 +251,7 @@ struct KerxSubTableFormat1
 
       if (Format1EntryT::performAction (entry) && depth)
       {
-       unsigned int tuple_count = MAX (1u, table->header.tuple_count ());
+       unsigned int tuple_count = hb_max (1u, table->header.tuple_count ());
 
        unsigned int kern_idx = Format1EntryT::kernActionIndex (entry);
        kern_idx = Types::byteOffsetToIndex (kern_idx, &table->machine, kernAction.arrayZ);
@@ -392,7 +392,7 @@ struct KerxSubTableFormat2
 
     const UnsizedArrayOf<FWORD> &arrayZ = this+array;
     unsigned int kern_idx = l + r;
-    kern_idx = Types::offsetToIndex (kern_idx, this, &arrayZ);
+    kern_idx = Types::offsetToIndex (kern_idx, this, arrayZ.arrayZ);
     const FWORD *v = &arrayZ[kern_idx];
     if (unlikely (!v->sanitize (&c->sanitizer))) return 0;
 
@@ -712,18 +712,18 @@ struct KerxSubTableFormat6
   {
     struct Long
     {
-      LNNOffsetTo<Lookup<HBUINT32> >           rowIndexTable;
-      LNNOffsetTo<Lookup<HBUINT32> >           columnIndexTable;
-      LNNOffsetTo<UnsizedArrayOf<FWORD32> >    array;
+      LNNOffsetTo<Lookup<HBUINT32>           rowIndexTable;
+      LNNOffsetTo<Lookup<HBUINT32>           columnIndexTable;
+      LNNOffsetTo<UnsizedArrayOf<FWORD32>    array;
     } l;
     struct Short
     {
-      LNNOffsetTo<Lookup<HBUINT16> >           rowIndexTable;
-      LNNOffsetTo<Lookup<HBUINT16> >           columnIndexTable;
-      LNNOffsetTo<UnsizedArrayOf<FWORD> >      array;
+      LNNOffsetTo<Lookup<HBUINT16>           rowIndexTable;
+      LNNOffsetTo<Lookup<HBUINT16>           columnIndexTable;
+      LNNOffsetTo<UnsizedArrayOf<FWORD>      array;
     } s;
   } u;
-  LNNOffsetTo<UnsizedArrayOf<FWORD> >  vector;
+  LNNOffsetTo<UnsizedArrayOf<FWORD>  vector;
   public:
   DEFINE_SIZE_STATIC (KernSubTableHeader::static_size + 24);
 };
@@ -733,8 +733,8 @@ struct KerxSubTableHeader
 {
   typedef ExtendedTypes Types;
 
-  unsigned int tuple_count () const { return tupleCount; }
-  bool is_horizontal () const       { return !(coverage & Vertical); }
+  unsigned   tuple_count () const { return tupleCount; }
+  bool     is_horizontal () const { return !(coverage & Vertical); }
 
   enum Coverage
   {
@@ -771,17 +771,17 @@ struct KerxSubTable
   unsigned int get_size () const { return u.header.length; }
   unsigned int get_type () const { return u.header.coverage & u.header.SubtableType; }
 
-  template <typename context_t>
-  typename context_t::return_t dispatch (context_t *c) const
+  template <typename context_t, typename ...Ts>
+  typename context_t::return_t dispatch (context_t *c, Ts&&... ds) const
   {
     unsigned int subtable_type = get_type ();
     TRACE_DISPATCH (this, subtable_type);
     switch (subtable_type) {
-    case 0:    return_trace (c->dispatch (u.format0));
-    case 1:    return_trace (c->dispatch (u.format1));
-    case 2:    return_trace (c->dispatch (u.format2));
-    case 4:    return_trace (c->dispatch (u.format4));
-    case 6:    return_trace (c->dispatch (u.format6));
+    case 0:    return_trace (c->dispatch (u.format0, hb_forward<Ts> (ds)...));
+    case 1:    return_trace (c->dispatch (u.format1, hb_forward<Ts> (ds)...));
+    case 2:    return_trace (c->dispatch (u.format2, hb_forward<Ts> (ds)...));
+    case 4:    return_trace (c->dispatch (u.format4, hb_forward<Ts> (ds)...));
+    case 6:    return_trace (c->dispatch (u.format6, hb_forward<Ts> (ds)...));
     default:   return_trace (c->default_return_value ());
     }
   }
@@ -830,7 +830,7 @@ struct KerxTable
     for (unsigned int i = 0; i < count; i++)
     {
       if (st->get_type () == 1)
-        return true;
+       return true;
       st = &StructAfter<SubTable> (*st);
     }
     return false;
@@ -845,7 +845,7 @@ struct KerxTable
     for (unsigned int i = 0; i < count; i++)
     {
       if (st->u.header.coverage & st->u.header.CrossStream)
-        return true;
+       return true;
       st = &StructAfter<SubTable> (*st);
     }
     return false;
@@ -862,7 +862,7 @@ struct KerxTable
     {
       if ((st->u.header.coverage & (st->u.header.Variation | st->u.header.CrossStream)) ||
          !st->u.header.is_horizontal ())
-        continue;
+       continue;
       v += st->get_kerning (left, right);
       st = &StructAfter<SubTable> (*st);
     }
@@ -883,7 +883,7 @@ struct KerxTable
       bool reverse;
 
       if (!T::Types::extended && (st->u.header.coverage & st->u.header.Variation))
-        goto skip;
+       goto skip;
 
       if (HB_DIRECTION_IS_HORIZONTAL (c->buffer->props.direction) != st->u.header.is_horizontal ())
        goto skip;
@@ -897,8 +897,8 @@ struct KerxTable
       if (!seenCrossStream &&
          (st->u.header.coverage & st->u.header.CrossStream))
       {
-        /* Attach all glyphs into a chain. */
-        seenCrossStream = true;
+       /* Attach all glyphs into a chain. */
+       seenCrossStream = true;
        hb_glyph_position_t *pos = c->buffer->pos;
        unsigned int count = c->buffer->len;
        for (unsigned int i = 0; i < count; i++)
index 4be799f..7063b38 100644 (file)
@@ -38,52 +38,121 @@ namespace AAT {
 
 typedef ArrayOf<HBINT16> LigCaretClassEntry;
 
-struct lcar
+struct lcarFormat0
 {
-  static constexpr hb_tag_t tableTag = HB_AAT_TAG_lcar;
+  unsigned int get_lig_carets (hb_font_t      *font,
+                              hb_direction_t  direction,
+                              hb_codepoint_t  glyph,
+                              unsigned int    start_offset,
+                              unsigned int   *caret_count /* IN/OUT */,
+                              hb_position_t  *caret_array /* OUT */,
+                              const void     *base) const
+  {
+    const OffsetTo<LigCaretClassEntry>* entry_offset = lookupTable.get_value (glyph,
+                                                                             font->face->get_num_glyphs ());
+    const LigCaretClassEntry& array = entry_offset ? base+*entry_offset : Null (LigCaretClassEntry);
+    if (caret_count)
+    {
+      hb_array_t<const HBINT16> arr = array.sub_array (start_offset, caret_count);
+      for (unsigned int i = 0; i < arr.length; ++i)
+       caret_array[i] = font->em_scale_dir (arr[i], direction);
+    }
+    return array.len;
+  }
+
+  bool sanitize (hb_sanitize_context_t *c, const void *base) const
+  {
+    TRACE_SANITIZE (this);
+    return_trace (likely (c->check_struct (this) && lookupTable.sanitize (c, base)));
+  }
+
+  protected:
+  Lookup<OffsetTo<LigCaretClassEntry>>
+               lookupTable;    /* data Lookup table associating glyphs */
+  public:
+  DEFINE_SIZE_MIN (2);
+};
 
+struct lcarFormat1
+{
   unsigned int get_lig_carets (hb_font_t      *font,
                               hb_direction_t  direction,
                               hb_codepoint_t  glyph,
                               unsigned int    start_offset,
                               unsigned int   *caret_count /* IN/OUT */,
-                              hb_position_t  *caret_array /* OUT */) const
+                              hb_position_t  *caret_array /* OUT */,
+                              const void     *base) const
   {
-    const OffsetTo<LigCaretClassEntry>* entry_offset = lookup.get_value (glyph,
-                                                                        font->face->get_num_glyphs ());
-    const LigCaretClassEntry& array = entry_offset ? this+*entry_offset : Null (LigCaretClassEntry);
+    const OffsetTo<LigCaretClassEntry>* entry_offset = lookupTable.get_value (glyph,
+                                                                             font->face->get_num_glyphs ());
+    const LigCaretClassEntry& array = entry_offset ? base+*entry_offset : Null (LigCaretClassEntry);
     if (caret_count)
     {
       hb_array_t<const HBINT16> arr = array.sub_array (start_offset, caret_count);
-      unsigned int count = arr.length;
-      for (unsigned int i = 0; i < count; ++i)
-       switch (format)
-       {
-       case 0: caret_array[i] = font->em_scale_dir (arr[i], direction); break;
-       case 1:
-         hb_position_t x, y;
-         font->get_glyph_contour_point_for_origin (glyph, arr[i], direction, &x, &y);
-         caret_array[i] = HB_DIRECTION_IS_HORIZONTAL (direction) ? x : y;
-         break;
-       }
+      for (unsigned int i = 0; i < arr.length; ++i)
+      {
+       hb_position_t x = 0, y = 0;
+       font->get_glyph_contour_point_for_origin (glyph, arr[i], direction, &x, &y);
+       caret_array[i] = HB_DIRECTION_IS_HORIZONTAL (direction) ? x : y;
+      }
     }
     return array.len;
   }
 
+  bool sanitize (hb_sanitize_context_t *c, const void *base) const
+  {
+    TRACE_SANITIZE (this);
+    return_trace (likely (c->check_struct (this) && lookupTable.sanitize (c, base)));
+  }
+
+  protected:
+  Lookup<OffsetTo<LigCaretClassEntry>>
+               lookupTable;    /* data Lookup table associating glyphs */
+  public:
+  DEFINE_SIZE_MIN (2);
+};
+
+struct lcar
+{
+  static constexpr hb_tag_t tableTag = HB_AAT_TAG_lcar;
+
+  unsigned int get_lig_carets (hb_font_t      *font,
+                              hb_direction_t  direction,
+                              hb_codepoint_t  glyph,
+                              unsigned int    start_offset,
+                              unsigned int   *caret_count /* IN/OUT */,
+                              hb_position_t  *caret_array /* OUT */) const
+  {
+    switch (format)
+    {
+    case 0: return u.format0.get_lig_carets (font, direction, glyph, start_offset,
+                                            caret_count, caret_array, this);
+    case 1: return u.format1.get_lig_carets (font, direction, glyph, start_offset,
+                                            caret_count, caret_array, this);
+    default:if (caret_count) *caret_count = 0; return 0;
+    }
+  }
+
   bool sanitize (hb_sanitize_context_t *c) const
   {
     TRACE_SANITIZE (this);
-    return_trace (likely (c->check_struct (this) &&
-                         version.major == 1 &&
-                         lookup.sanitize (c, this)));
+    if (unlikely (!c->check_struct (this) || version.major != 1))
+      return_trace (false);
+
+    switch (format) {
+    case 0: return_trace (u.format0.sanitize (c, this));
+    case 1: return_trace (u.format1.sanitize (c, this));
+    default:return_trace (true);
+    }
   }
 
   protected:
   FixedVersion<>version;       /* Version number of the ligature caret table */
   HBUINT16     format;         /* Format of the ligature caret table. */
-  Lookup<OffsetTo<LigCaretClassEntry> >
-               lookup;         /* data Lookup table associating glyphs */
-
+  union {
+  lcarFormat0  format0;
+  lcarFormat0  format1;
+  } u;
   public:
   DEFINE_SIZE_MIN (8);
 };
index 4a1d959..d8df579 100644 (file)
@@ -88,7 +88,7 @@ struct RearrangementSubtable
        start = buffer->idx;
 
       if (flags & MarkLast)
-       end = MIN (buffer->idx + 1, buffer->len);
+       end = hb_min (buffer->idx + 1, buffer->len);
 
       if ((flags & Verb) && start < end)
       {
@@ -117,14 +117,14 @@ struct RearrangementSubtable
        };
 
        unsigned int m = map[flags & Verb];
-       unsigned int l = MIN<unsigned int> (2, m >> 4);
-       unsigned int r = MIN<unsigned int> (2, m & 0x0F);
+       unsigned int l = hb_min (2u, m >> 4);
+       unsigned int r = hb_min (2u, m & 0x0F);
        bool reverse_l = 3 == (m >> 4);
        bool reverse_r = 3 == (m & 0x0F);
 
        if (end - start >= l + r)
        {
-         buffer->merge_clusters (start, MIN (buffer->idx + 1, buffer->len));
+         buffer->merge_clusters (start, hb_min (buffer->idx + 1, buffer->len));
          buffer->merge_clusters (start, end);
 
          hb_glyph_info_t *info = buffer->info;
@@ -226,7 +226,7 @@ struct ContextualSubtable
       hb_buffer_t *buffer = driver->buffer;
 
       if (buffer->idx == buffer->len && !mark_set)
-        return false;
+       return false;
 
       return entry.data.markIndex != 0xFFFF || entry.data.currentIndex != 0xFFFF;
     }
@@ -238,48 +238,48 @@ struct ContextualSubtable
       /* Looks like CoreText applies neither mark nor current substitution for
        * end-of-text if mark was not explicitly set. */
       if (buffer->idx == buffer->len && !mark_set)
-        return;
+       return;
 
-      const GlyphID *replacement;
+      const HBGlyphID *replacement;
 
       replacement = nullptr;
       if (Types::extended)
       {
        if (entry.data.markIndex != 0xFFFF)
        {
-         const Lookup<GlyphID> &lookup = subs[entry.data.markIndex];
+         const Lookup<HBGlyphID> &lookup = subs[entry.data.markIndex];
          replacement = lookup.get_value (buffer->info[mark].codepoint, driver->num_glyphs);
        }
       }
       else
       {
        unsigned int offset = entry.data.markIndex + buffer->info[mark].codepoint;
-       const UnsizedArrayOf<GlyphID> &subs_old = (const UnsizedArrayOf<GlyphID> &) subs;
+       const UnsizedArrayOf<HBGlyphID> &subs_old = (const UnsizedArrayOf<HBGlyphID> &) subs;
        replacement = &subs_old[Types::wordOffsetToIndex (offset, table, subs_old.arrayZ)];
        if (!replacement->sanitize (&c->sanitizer) || !*replacement)
          replacement = nullptr;
       }
       if (replacement)
       {
-       buffer->unsafe_to_break (mark, MIN (buffer->idx + 1, buffer->len));
+       buffer->unsafe_to_break (mark, hb_min (buffer->idx + 1, buffer->len));
        buffer->info[mark].codepoint = *replacement;
        ret = true;
       }
 
       replacement = nullptr;
-      unsigned int idx = MIN (buffer->idx, buffer->len - 1);
+      unsigned int idx = hb_min (buffer->idx, buffer->len - 1);
       if (Types::extended)
       {
        if (entry.data.currentIndex != 0xFFFF)
        {
-         const Lookup<GlyphID> &lookup = subs[entry.data.currentIndex];
+         const Lookup<HBGlyphID> &lookup = subs[entry.data.currentIndex];
          replacement = lookup.get_value (buffer->info[idx].codepoint, driver->num_glyphs);
        }
       }
       else
       {
        unsigned int offset = entry.data.currentIndex + buffer->info[idx].codepoint;
-       const UnsizedArrayOf<GlyphID> &subs_old = (const UnsizedArrayOf<GlyphID> &) subs;
+       const UnsizedArrayOf<HBGlyphID> &subs_old = (const UnsizedArrayOf<HBGlyphID> &) subs;
        replacement = &subs_old[Types::wordOffsetToIndex (offset, table, subs_old.arrayZ)];
        if (!replacement->sanitize (&c->sanitizer) || !*replacement)
          replacement = nullptr;
@@ -304,7 +304,7 @@ struct ContextualSubtable
     bool mark_set;
     unsigned int mark;
     const ContextualSubtable *table;
-    const UnsizedOffsetListOf<Lookup<GlyphID>, HBUINT, false> &subs;
+    const UnsizedOffsetListOf<Lookup<HBGlyphID>, HBUINT, false> &subs;
   };
 
   bool apply (hb_aat_apply_context_t *c) const
@@ -337,9 +337,9 @@ struct ContextualSubtable
       const EntryData &data = entries[i].data;
 
       if (data.markIndex != 0xFFFF)
-       num_lookups = MAX<unsigned int> (num_lookups, 1 + data.markIndex);
+       num_lookups = hb_max (num_lookups, 1 + data.markIndex);
       if (data.currentIndex != 0xFFFF)
-       num_lookups = MAX<unsigned int> (num_lookups, 1 + data.currentIndex);
+       num_lookups = hb_max (num_lookups, 1 + data.currentIndex);
     }
 
     return_trace (substitutionTables.sanitize (c, this, num_lookups));
@@ -348,7 +348,7 @@ struct ContextualSubtable
   protected:
   StateTable<Types, EntryData>
                machine;
-  NNOffsetTo<UnsizedOffsetListOf<Lookup<GlyphID>, HBUINT, false>, HBUINT>
+  NNOffsetTo<UnsizedOffsetListOf<Lookup<HBGlyphID>, HBUINT, false>, HBUINT>
                substitutionTables;
   public:
   DEFINE_SIZE_STATIC (20);
@@ -488,7 +488,7 @@ struct LigatureSubtable
 
        unsigned int ligature_idx = 0;
        unsigned int action;
-        do
+       do
        {
          if (unlikely (!cursor))
          {
@@ -520,7 +520,7 @@ struct LigatureSubtable
          if (action & (LigActionStore | LigActionLast))
          {
            ligature_idx = Types::offsetToIndex (ligature_idx, table, ligature.arrayZ);
-           const GlyphID &ligatureData = ligature[ligature_idx];
+           const HBGlyphID &ligatureData = ligature[ligature_idx];
            if (unlikely (!ligatureData.sanitize (&c->sanitizer))) break;
            hb_codepoint_t lig = ligatureData;
 
@@ -554,7 +554,7 @@ struct LigatureSubtable
     const LigatureSubtable *table;
     const UnsizedArrayOf<HBUINT32> &ligAction;
     const UnsizedArrayOf<HBUINT16> &component;
-    const UnsizedArrayOf<GlyphID> &ligature;
+    const UnsizedArrayOf<HBGlyphID> &ligature;
     unsigned int match_length;
     unsigned int match_positions[HB_MAX_CONTEXT_LENGTH];
   };
@@ -586,7 +586,7 @@ struct LigatureSubtable
                ligAction;      /* Offset to the ligature action table. */
   NNOffsetTo<UnsizedArrayOf<HBUINT16>, HBUINT>
                component;      /* Offset to the component table. */
-  NNOffsetTo<UnsizedArrayOf<GlyphID>, HBUINT>
+  NNOffsetTo<UnsizedArrayOf<HBGlyphID>, HBUINT>
                ligature;       /* Offset to the actual ligature lists. */
   public:
   DEFINE_SIZE_STATIC (28);
@@ -606,7 +606,7 @@ struct NoncontextualSubtable
     unsigned int count = c->buffer->len;
     for (unsigned int i = 0; i < count; i++)
     {
-      const GlyphID *replacement = substitute.get_value (info[i].codepoint, num_glyphs);
+      const HBGlyphID *replacement = substitute.get_value (info[i].codepoint, num_glyphs);
       if (replacement)
       {
        info[i].codepoint = *replacement;
@@ -624,7 +624,7 @@ struct NoncontextualSubtable
   }
 
   protected:
-  Lookup<GlyphID>      substitute;
+  Lookup<HBGlyphID>    substitute;
   public:
   DEFINE_SIZE_MIN (2);
 };
@@ -726,7 +726,7 @@ struct InsertionSubtable
       {
        unsigned int count = (flags & MarkedInsertCount);
        unsigned int start = entry.data.markedInsertIndex;
-       const GlyphID *glyphs = &insertionAction[start];
+       const HBGlyphID *glyphs = &insertionAction[start];
        if (unlikely (!c->sanitizer.check_array (glyphs, count))) count = 0;
 
        bool before = flags & MarkedInsertBefore;
@@ -744,7 +744,7 @@ struct InsertionSubtable
 
        buffer->move_to (end + count);
 
-       buffer->unsafe_to_break_from_outbuffer (mark, MIN (buffer->idx + 1, buffer->len));
+       buffer->unsafe_to_break_from_outbuffer (mark, hb_min (buffer->idx + 1, buffer->len));
       }
 
       if (flags & SetMark)
@@ -754,7 +754,7 @@ struct InsertionSubtable
       {
        unsigned int count = (flags & CurrentInsertCount) >> 5;
        unsigned int start = entry.data.currentInsertIndex;
-       const GlyphID *glyphs = &insertionAction[start];
+       const HBGlyphID *glyphs = &insertionAction[start];
        if (unlikely (!c->sanitizer.check_array (glyphs, count))) count = 0;
 
        bool before = flags & CurrentInsertBefore;
@@ -793,7 +793,7 @@ struct InsertionSubtable
     private:
     hb_aat_apply_context_t *c;
     unsigned int mark;
-    const UnsizedArrayOf<GlyphID> &insertionAction;
+    const UnsizedArrayOf<HBGlyphID> &insertionAction;
   };
 
   bool apply (hb_aat_apply_context_t *c) const
@@ -819,7 +819,7 @@ struct InsertionSubtable
   protected:
   StateTable<Types, EntryData>
                machine;
-  NNOffsetTo<UnsizedArrayOf<GlyphID>, HBUINT>
+  NNOffsetTo<UnsizedArrayOf<HBGlyphID>, HBUINT>
                insertionAction;        /* Byte offset from stateHeader to the start of
                                         * the insertion glyph table. */
   public:
@@ -883,17 +883,17 @@ struct ChainSubtable
     Insertion          = 5
   };
 
-  template <typename context_t>
-  typename context_t::return_t dispatch (context_t *c) const
+  template <typename context_t, typename ...Ts>
+  typename context_t::return_t dispatch (context_t *c, Ts&&... ds) const
   {
     unsigned int subtable_type = get_type ();
     TRACE_DISPATCH (this, subtable_type);
     switch (subtable_type) {
-    case Rearrangement:                return_trace (c->dispatch (u.rearrangement));
-    case Contextual:           return_trace (c->dispatch (u.contextual));
-    case Ligature:             return_trace (c->dispatch (u.ligature));
-    case Noncontextual:                return_trace (c->dispatch (u.noncontextual));
-    case Insertion:            return_trace (c->dispatch (u.insertion));
+    case Rearrangement:                return_trace (c->dispatch (u.rearrangement, hb_forward<Ts> (ds)...));
+    case Contextual:           return_trace (c->dispatch (u.contextual, hb_forward<Ts> (ds)...));
+    case Ligature:             return_trace (c->dispatch (u.ligature, hb_forward<Ts> (ds)...));
+    case Noncontextual:                return_trace (c->dispatch (u.noncontextual, hb_forward<Ts> (ds)...));
+    case Insertion:            return_trace (c->dispatch (u.insertion, hb_forward<Ts> (ds)...));
     default:                   return_trace (c->default_return_value ());
     }
   }
@@ -969,19 +969,19 @@ struct Chain
   void apply (hb_aat_apply_context_t *c,
                     hb_mask_t flags) const
   {
-    const ChainSubtable<Types> *subtable = &StructAfter<ChainSubtable<Types> > (featureZ.as_array (featureCount));
+    const ChainSubtable<Types> *subtable = &StructAfter<ChainSubtable<Types>> (featureZ.as_array (featureCount));
     unsigned int count = subtableCount;
     for (unsigned int i = 0; i < count; i++)
     {
       bool reverse;
 
       if (!(subtable->subFeatureFlags & flags))
-        goto skip;
+       goto skip;
 
       if (!(subtable->get_coverage() & ChainSubtable<Types>::AllDirections) &&
          HB_DIRECTION_IS_VERTICAL (c->buffer->props.direction) !=
          bool (subtable->get_coverage() & ChainSubtable<Types>::Vertical))
-        goto skip;
+       goto skip;
 
       /* Buffer contents is always in logical direction.  Determine if
        * we need to reverse before applying this subtable.  We reverse
@@ -1016,22 +1016,22 @@ struct Chain
                HB_DIRECTION_IS_BACKWARD (c->buffer->props.direction);
 
       if (!c->buffer->message (c->font, "start chain subtable %d", c->lookup_index))
-        goto skip;
+       goto skip;
 
       if (reverse)
-        c->buffer->reverse ();
+       c->buffer->reverse ();
 
       subtable->apply (c);
 
       if (reverse)
-        c->buffer->reverse ();
+       c->buffer->reverse ();
 
       (void) c->buffer->message (c->font, "end chain subtable %d", c->lookup_index);
 
       if (unlikely (!c->buffer->successful)) return;
 
     skip:
-      subtable = &StructAfter<ChainSubtable<Types> > (*subtable);
+      subtable = &StructAfter<ChainSubtable<Types>> (*subtable);
       c->set_lookup_index (c->lookup_index + 1);
     }
   }
@@ -1049,13 +1049,13 @@ struct Chain
     if (!c->check_array (featureZ.arrayZ, featureCount))
       return_trace (false);
 
-    const ChainSubtable<Types> *subtable = &StructAfter<ChainSubtable<Types> > (featureZ.as_array (featureCount));
+    const ChainSubtable<Types> *subtable = &StructAfter<ChainSubtable<Types>> (featureZ.as_array (featureCount));
     unsigned int count = subtableCount;
     for (unsigned int i = 0; i < count; i++)
     {
       if (!subtable->sanitize (c))
        return_trace (false);
-      subtable = &StructAfter<ChainSubtable<Types> > (*subtable);
+      subtable = &StructAfter<ChainSubtable<Types>> (*subtable);
     }
 
     return_trace (true);
@@ -1080,10 +1080,10 @@ struct Chain
  * The 'mort'/'morx' Table
  */
 
-template <typename Types>
+template <typename Types, hb_tag_t TAG>
 struct mortmorx
 {
-  static constexpr hb_tag_t tableTag = HB_AAT_TAG_morx;
+  static constexpr hb_tag_t tableTag = TAG;
 
   bool has_data () const { return version != 0; }
 
@@ -1095,7 +1095,7 @@ struct mortmorx
     for (unsigned int i = 0; i < count; i++)
     {
       map->chain_flags.push (chain->compile_flags (mapper));
-      chain = &StructAfter<Chain<Types> > (*chain);
+      chain = &StructAfter<Chain<Types>> (*chain);
     }
   }
 
@@ -1109,7 +1109,7 @@ struct mortmorx
     {
       chain->apply (c, c->plan->aat_map.chain_flags[i]);
       if (unlikely (!c->buffer->successful)) return;
-      chain = &StructAfter<Chain<Types> > (*chain);
+      chain = &StructAfter<Chain<Types>> (*chain);
     }
   }
 
@@ -1125,7 +1125,7 @@ struct mortmorx
     {
       if (!chain->sanitize (c, version))
        return_trace (false);
-      chain = &StructAfter<Chain<Types> > (*chain);
+      chain = &StructAfter<Chain<Types>> (*chain);
     }
 
     return_trace (true);
@@ -1143,14 +1143,8 @@ struct mortmorx
   DEFINE_SIZE_MIN (8);
 };
 
-struct morx : mortmorx<ExtendedTypes>
-{
-  static constexpr hb_tag_t tableTag = HB_AAT_TAG_morx;
-};
-struct mort : mortmorx<ObsoleteTypes>
-{
-  static constexpr hb_tag_t tableTag = HB_AAT_TAG_mort;
-};
+struct morx : mortmorx<ExtendedTypes, HB_AAT_TAG_morx> {};
+struct mort : mortmorx<ObsoleteTypes, HB_AAT_TAG_mort> {};
 
 
 } /* namespace AAT */
diff --git a/src/hb-aat-layout-opbd-table.hh b/src/hb-aat-layout-opbd-table.hh
new file mode 100644 (file)
index 0000000..4e02340
--- /dev/null
@@ -0,0 +1,173 @@
+/*
+ * Copyright © 2019  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_AAT_LAYOUT_OPBD_TABLE_HH
+#define HB_AAT_LAYOUT_OPBD_TABLE_HH
+
+#include "hb-aat-layout-common.hh"
+#include "hb-open-type.hh"
+
+/*
+ * opbd -- Optical Bounds
+ * https://developer.apple.com/fonts/TrueType-Reference-Manual/RM06/Chap6opbd.html
+ */
+#define HB_AAT_TAG_opbd HB_TAG('o','p','b','d')
+
+
+namespace AAT {
+
+struct OpticalBounds
+{
+  bool sanitize (hb_sanitize_context_t *c) const
+  {
+    TRACE_SANITIZE (this);
+    return_trace (likely (c->check_struct (this)));
+  }
+
+  FWORD                leftSide;
+  FWORD                topSide;
+  FWORD                rightSide;
+  FWORD                bottomSide;
+  public:
+  DEFINE_SIZE_STATIC (8);
+};
+
+struct opbdFormat0
+{
+  bool get_bounds (hb_font_t *font, hb_codepoint_t glyph_id,
+                  hb_glyph_extents_t *extents, const void *base) const
+  {
+    const OffsetTo<OpticalBounds> *bounds_offset = lookupTable.get_value (glyph_id, font->face->get_num_glyphs ());
+    if (!bounds_offset) return false;
+    const OpticalBounds &bounds = base+*bounds_offset;
+
+    if (extents)
+      *extents = {
+       font->em_scale_x (bounds.leftSide),
+       font->em_scale_y (bounds.topSide),
+       font->em_scale_x (bounds.rightSide),
+       font->em_scale_y (bounds.bottomSide)
+      };
+    return true;
+  }
+
+  bool sanitize (hb_sanitize_context_t *c, const void *base) const
+  {
+    TRACE_SANITIZE (this);
+    return_trace (likely (c->check_struct (this) && lookupTable.sanitize (c, base)));
+  }
+
+  protected:
+  Lookup<OffsetTo<OpticalBounds>>
+               lookupTable;    /* Lookup table associating glyphs with the four
+                                * int16 values for the left-side, top-side,
+                                * right-side, and bottom-side optical bounds. */
+  public:
+  DEFINE_SIZE_MIN (2);
+};
+
+struct opbdFormat1
+{
+  bool get_bounds (hb_font_t *font, hb_codepoint_t glyph_id,
+                  hb_glyph_extents_t *extents, const void *base) const
+  {
+    const OffsetTo<OpticalBounds> *bounds_offset = lookupTable.get_value (glyph_id, font->face->get_num_glyphs ());
+    if (!bounds_offset) return false;
+    const OpticalBounds &bounds = base+*bounds_offset;
+
+    hb_position_t left = 0, top = 0, right = 0, bottom = 0, ignore;
+    if (font->get_glyph_contour_point (glyph_id, bounds.leftSide, &left, &ignore) ||
+       font->get_glyph_contour_point (glyph_id, bounds.topSide, &ignore, &top) ||
+       font->get_glyph_contour_point (glyph_id, bounds.rightSide, &right, &ignore) ||
+       font->get_glyph_contour_point (glyph_id, bounds.bottomSide, &ignore, &bottom))
+    {
+      if (extents)
+       *extents = {left, top, right, bottom};
+      return true;
+    }
+    return false;
+  }
+
+  bool sanitize (hb_sanitize_context_t *c, const void *base) const
+  {
+    TRACE_SANITIZE (this);
+    return_trace (likely (c->check_struct (this) && lookupTable.sanitize (c, base)));
+  }
+
+  protected:
+  Lookup<OffsetTo<OpticalBounds>>
+               lookupTable;    /* Lookup table associating glyphs with the four
+                                * int16 values for the left-side, top-side,
+                                * right-side, and bottom-side optical bounds. */
+  public:
+  DEFINE_SIZE_MIN (2);
+};
+
+struct opbd
+{
+  static constexpr hb_tag_t tableTag = HB_AAT_TAG_opbd;
+
+  bool get_bounds (hb_font_t *font, hb_codepoint_t glyph_id,
+                  hb_glyph_extents_t *extents) const
+  {
+    switch (format)
+    {
+    case 0: return u.format0.get_bounds (font, glyph_id, extents, this);
+    case 1: return u.format1.get_bounds (font, glyph_id, extents, this);
+    default:return false;
+    }
+  }
+
+  bool sanitize (hb_sanitize_context_t *c) const
+  {
+    TRACE_SANITIZE (this);
+    if (unlikely (!c->check_struct (this) || version.major != 1))
+      return_trace (false);
+
+    switch (format)
+    {
+    case 0: return_trace (u.format0.sanitize (c, this));
+    case 1: return_trace (u.format1.sanitize (c, this));
+    default:return_trace (true);
+    }
+  }
+
+  protected:
+  FixedVersion<>version;       /* Version number of the optical bounds
+                                * table (0x00010000 for the current version). */
+  HBUINT16     format;         /* Format of the optical bounds table.
+                                * Format 0 indicates distance and Format 1 indicates
+                                * control point. */
+  union {
+  opbdFormat0 format0;
+  opbdFormat1 format1;
+  } u;
+  public:
+  DEFINE_SIZE_MIN (8);
+};
+
+} /* namespace AAT */
+
+
+#endif /* HB_AAT_LAYOUT_OPBD_TABLE_HH */
index 0c8e455..99dddd8 100644 (file)
@@ -62,11 +62,11 @@ struct TrackTableEntry
   }
 
   protected:
-  Fixed                track;          /* Track value for this record. */
+  HBFixed              track;          /* Track value for this record. */
   NameID       trackNameID;    /* The 'name' table index for this track.
                                 * (a short word or phrase like "loose"
                                 * or "very tight") */
-  NNOffsetTo<UnsizedArrayOf<FWORD> >
+  NNOffsetTo<UnsizedArrayOf<FWORD>>
                valuesZ;        /* Offset from start of tracking table to
                                 * per-size tracking values for this track. */
 
@@ -82,7 +82,7 @@ struct TrackData
                        const void *base) const
   {
     unsigned int sizes = nSizes;
-    hb_array_t<const Fixed> size_table ((base+sizeTable).arrayZ, sizes);
+    hb_array_t<const HBFixed> size_table ((base+sizeTable).arrayZ, sizes);
 
     float s0 = size_table[idx].to_float ();
     float s1 = size_table[idx + 1].to_float ();
@@ -93,13 +93,6 @@ struct TrackData
 
   int get_tracking (const void *base, float ptem) const
   {
-    /* CoreText points are CSS pixels (96 per inch),
-     * NOT typographic points (72 per inch).
-     *
-     * https://developer.apple.com/library/content/documentation/GraphicsAnimation/Conceptual/HighResolutionOSX/Explained/Explained.html
-     */
-    float csspx = ptem * 96.f / 72.f;
-
     /*
      * Choose track.
      */
@@ -127,14 +120,14 @@ struct TrackData
     if (!sizes) return 0.;
     if (sizes == 1) return trackTableEntry->get_value (base, 0, sizes);
 
-    hb_array_t<const Fixed> size_table ((base+sizeTable).arrayZ, sizes);
+    hb_array_t<const HBFixed> size_table ((base+sizeTable).arrayZ, sizes);
     unsigned int size_index;
     for (size_index = 0; size_index < sizes - 1; size_index++)
-      if (size_table[size_index].to_float () >= csspx)
-        break;
+      if (size_table[size_index].to_float () >= ptem)
+       break;
 
-    return round (interpolate_at (size_index ? size_index - 1 : 0, csspx,
-                                 *trackTableEntry, base));
+    return roundf (interpolate_at (size_index ? size_index - 1 : 0, ptem,
+                                  *trackTableEntry, base));
   }
 
   bool sanitize (hb_sanitize_context_t *c, const void *base) const
@@ -148,7 +141,7 @@ struct TrackData
   protected:
   HBUINT16     nTracks;        /* Number of separate tracks included in this table. */
   HBUINT16     nSizes;         /* Number of point sizes included in this table. */
-  LOffsetTo<UnsizedArrayOf<Fixed>, false>
+  LOffsetTo<UnsizedArrayOf<HBFixed>, false>
                sizeTable;      /* Offset from start of the tracking table to
                                 * Array[nSizes] of size values.. */
   UnsizedArrayOf<TrackTableEntry>
@@ -183,7 +176,7 @@ struct trak
       hb_position_t advance_to_add = c->font->em_scalef_x (tracking);
       foreach_grapheme (buffer, start, end)
       {
-        if (!(buffer->info[start].mask & trak_mask)) continue;
+       if (!(buffer->info[start].mask & trak_mask)) continue;
        buffer->pos[start].x_advance += advance_to_add;
        buffer->pos[start].x_offset += offset_to_add;
       }
@@ -196,7 +189,7 @@ struct trak
       hb_position_t advance_to_add = c->font->em_scalef_y (tracking);
       foreach_grapheme (buffer, start, end)
       {
-        if (!(buffer->info[start].mask & trak_mask)) continue;
+       if (!(buffer->info[start].mask & trak_mask)) continue;
        buffer->pos[start].y_advance += advance_to_add;
        buffer->pos[start].y_offset += offset_to_add;
       }
index 5168a9c..4e506de 100644 (file)
@@ -25,9 +25,8 @@
  * Google Author(s): Behdad Esfahbod
  */
 
-#include "hb-open-type.hh"
+#include "hb.hh"
 
-#include "hb-ot-face.hh"
 #include "hb-aat-layout.hh"
 #include "hb-aat-fdsc-table.hh" // Just so we compile it; unused otherwise.
 #include "hb-aat-layout-ankr-table.hh"
 #include "hb-aat-ltag-table.hh"
 
 
+/*
+ * hb_aat_apply_context_t
+ */
+
+/* Note: This context is used for kerning, even without AAT, hence the condition. */
+#if !defined(HB_NO_AAT) || !defined(HB_NO_OT_KERN)
+
+AAT::hb_aat_apply_context_t::hb_aat_apply_context_t (const hb_ot_shape_plan_t *plan_,
+                                                    hb_font_t *font_,
+                                                    hb_buffer_t *buffer_,
+                                                    hb_blob_t *blob) :
+                                                      plan (plan_),
+                                                      font (font_),
+                                                      face (font->face),
+                                                      buffer (buffer_),
+                                                      sanitizer (),
+                                                      ankr_table (&Null(AAT::ankr)),
+                                                      lookup_index (0),
+                                                      debug_depth (0)
+{
+  sanitizer.init (blob);
+  sanitizer.set_num_glyphs (face->get_num_glyphs ());
+  sanitizer.start_processing ();
+  sanitizer.set_max_ops (HB_SANITIZE_MAX_OPS_MAX);
+}
+
+AAT::hb_aat_apply_context_t::~hb_aat_apply_context_t ()
+{ sanitizer.end_processing (); }
+
+void
+AAT::hb_aat_apply_context_t::set_ankr_table (const AAT::ankr *ankr_table_)
+{ ankr_table = ankr_table_; }
+
+#endif
+
+
 /**
  * SECTION:hb-aat-layout
  * @title: hb-aat-layout
@@ -50,6 +85,8 @@
  **/
 
 
+#if !defined(HB_NO_AAT) || defined(HAVE_CORETEXT)
+
 /* Table data courtesy of Apple.  Converted from mnemonics to integers
  * when moving to this file. */
 static const hb_aat_feature_mapping_t feature_mappings[] =
@@ -135,44 +172,16 @@ static const hb_aat_feature_mapping_t feature_mappings[] =
 const hb_aat_feature_mapping_t *
 hb_aat_layout_find_feature_mapping (hb_tag_t tag)
 {
-  return (const hb_aat_feature_mapping_t *) bsearch (&tag,
-                                                    feature_mappings,
-                                                    ARRAY_LENGTH (feature_mappings),
-                                                    sizeof (feature_mappings[0]),
-                                                    hb_aat_feature_mapping_t::cmp);
-}
-
-
-/*
- * hb_aat_apply_context_t
- */
-
-AAT::hb_aat_apply_context_t::hb_aat_apply_context_t (const hb_ot_shape_plan_t *plan_,
-                                                    hb_font_t *font_,
-                                                    hb_buffer_t *buffer_,
-                                                    hb_blob_t *blob) :
-                                                      plan (plan_),
-                                                      font (font_),
-                                                      face (font->face),
-                                                      buffer (buffer_),
-                                                      sanitizer (),
-                                                      ankr_table (&Null(AAT::ankr)),
-                                                      lookup_index (0),
-                                                      debug_depth (0)
-{
-  sanitizer.init (blob);
-  sanitizer.set_num_glyphs (face->get_num_glyphs ());
-  sanitizer.start_processing ();
-  sanitizer.set_max_ops (HB_SANITIZE_MAX_OPS_MAX);
+  return (const hb_aat_feature_mapping_t *) hb_bsearch (&tag,
+                                                       feature_mappings,
+                                                       ARRAY_LENGTH (feature_mappings),
+                                                       sizeof (feature_mappings[0]),
+                                                       hb_aat_feature_mapping_t::cmp);
 }
+#endif
 
-AAT::hb_aat_apply_context_t::~hb_aat_apply_context_t ()
-{ sanitizer.end_processing (); }
-
-void
-AAT::hb_aat_apply_context_t::set_ankr_table (const AAT::ankr *ankr_table_)
-{ ankr_table = ankr_table_; }
 
+#ifndef HB_NO_AAT
 
 /*
  * mort/morx/kerx/trak
@@ -311,14 +320,6 @@ hb_aat_layout_track (const hb_ot_shape_plan_t *plan,
   trak.apply (&c);
 }
 
-
-hb_language_t
-_hb_aat_language_get (hb_face_t *face,
-                     unsigned int i)
-{
-  return face->table.ltag->get_language (i);
-}
-
 /**
  * hb_aat_layout_get_feature_types:
  * @face: a face object
@@ -382,3 +383,6 @@ hb_aat_layout_feature_type_get_selector_infos (hb_face_t
 {
   return face->table.feat->get_selector_infos (feature_type, start_offset, selector_count, selectors, default_index);
 }
+
+
+#endif
index 760aaae..b617e8b 100644 (file)
@@ -85,7 +85,7 @@ typedef enum
   HB_AAT_LAYOUT_FEATURE_TYPE_LANGUAGE_TAG_TYPE                 = 39,
   HB_AAT_LAYOUT_FEATURE_TYPE_CJK_ROMAN_SPACING_TYPE            = 103,
 
-  _HB_AAT_LAYOUT_FEATURE_TYPE_MAX_VALUE= 0x7FFFFFFFu, /*< skip >*/
+  _HB_AAT_LAYOUT_FEATURE_TYPE_MAX_VALUE = HB_TAG_MAX_SIGNED /*< skip >*/
 } hb_aat_layout_feature_type_t;
 
 /**
@@ -424,7 +424,7 @@ typedef enum
   HB_AAT_LAYOUT_FEATURE_SELECTOR_DEFAULT_CJK_ROMAN             = 2,
   HB_AAT_LAYOUT_FEATURE_SELECTOR_FULL_WIDTH_CJK_ROMAN          = 3,
 
-  _HB_AAT_LAYOUT_FEATURE_SELECTOR_MAX_VALUE= 0x7FFFFFFFu, /*< skip >*/
+  _HB_AAT_LAYOUT_FEATURE_SELECTOR_MAX_VALUE = HB_TAG_MAX_SIGNED /*< skip >*/
 } hb_aat_layout_feature_selector_t;
 
 HB_EXTERN unsigned int
index 8346d9f..8310bfc 100644 (file)
@@ -30,7 +30,7 @@
 #include "hb.hh"
 
 #include "hb-ot-shape.hh"
-
+#include "hb-aat-ltag-table.hh"
 
 struct hb_aat_feature_mapping_t
 {
@@ -39,7 +39,7 @@ struct hb_aat_feature_mapping_t
   hb_aat_layout_feature_selector_t selectorToEnable;
   hb_aat_layout_feature_selector_t selectorToDisable;
 
-  static int cmp (const void *key_, const void *entry_)
+  HB_INTERNAL static int cmp (const void *key_, const void *entry_)
   {
     hb_tag_t key = * (unsigned int *) key_;
     const hb_aat_feature_mapping_t * entry = (const hb_aat_feature_mapping_t *) entry_;
@@ -77,9 +77,5 @@ hb_aat_layout_track (const hb_ot_shape_plan_t *plan,
                     hb_font_t *font,
                     hb_buffer_t *buffer);
 
-HB_INTERNAL hb_language_t
-_hb_aat_language_get (hb_face_t *face,
-                     unsigned int i);
-
 
 #endif /* HB_AAT_LAYOUT_HH */
index 6f34a00..711f9aa 100644 (file)
@@ -50,7 +50,7 @@ struct FTStringRange
   }
 
   protected:
-  NNOffsetTo<UnsizedArrayOf<HBUINT8> >
+  NNOffsetTo<UnsizedArrayOf<HBUINT8>>
                tag;            /* Offset from the start of the table to
                                 * the beginning of the string */
   HBUINT16     length;         /* String length (in bytes) */
index 98c5d7f..bc87935 100644 (file)
  * Google Author(s): Behdad Esfahbod
  */
 
+#include "hb.hh"
+
+#ifndef HB_NO_AAT_SHAPE
+
 #include "hb-aat-map.hh"
 
 #include "hb-aat-layout.hh"
@@ -66,3 +70,6 @@ hb_aat_map_builder_t::compile (hb_aat_map_t  &m)
 
   hb_aat_layout_compile_map (this, &m);
 }
+
+
+#endif
index 3d5ad0e..984a59c 100644 (file)
@@ -66,7 +66,7 @@ struct hb_aat_map_builder_t
     hb_aat_layout_feature_selector_t  setting;
     unsigned  seq; /* For stable sorting only. */
 
-    static int cmp (const void *pa, const void *pb)
+    HB_INTERNAL static int cmp (const void *pa, const void *pb)
     {
       const feature_info_t *a = (const feature_info_t *) pa;
       const feature_info_t *b = (const feature_info_t *) pb;
@@ -84,7 +84,7 @@ struct hb_aat_map_builder_t
   hb_face_t *face;
 
   public:
-  hb_vector_t<feature_info_t> features;
+  hb_sorted_vector_t<feature_info_t> features;
 };
 
 
diff --git a/src/hb-algs.hh b/src/hb-algs.hh
new file mode 100644 (file)
index 0000000..042e1c2
--- /dev/null
@@ -0,0 +1,1059 @@
+/*
+ * Copyright © 2017  Google, Inc.
+ * Copyright © 2019  Facebook, 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
+ * Facebook Author(s): Behdad Esfahbod
+ */
+
+#ifndef HB_ALGS_HH
+#define HB_ALGS_HH
+
+#include "hb.hh"
+#include "hb-meta.hh"
+#include "hb-null.hh"
+#include "hb-number.hh"
+
+
+/* Encodes three unsigned integers in one 64-bit number.  If the inputs have more than 21 bits,
+ * values will be truncated / overlap, and might not decode exactly. */
+#define HB_CODEPOINT_ENCODE3(x,y,z) (((uint64_t) (x) << 42) | ((uint64_t) (y) << 21) | (uint64_t) (z))
+#define HB_CODEPOINT_DECODE3_1(v) ((hb_codepoint_t) ((v) >> 42))
+#define HB_CODEPOINT_DECODE3_2(v) ((hb_codepoint_t) ((v) >> 21) & 0x1FFFFFu)
+#define HB_CODEPOINT_DECODE3_3(v) ((hb_codepoint_t) (v) & 0x1FFFFFu)
+
+/* Custom encoding used by hb-ucd. */
+#define HB_CODEPOINT_ENCODE3_11_7_14(x,y,z) (((uint32_t) ((x) & 0x07FFu) << 21) | (((uint32_t) (y) & 0x007Fu) << 14) | (uint32_t) ((z) & 0x3FFFu))
+#define HB_CODEPOINT_DECODE3_11_7_14_1(v) ((hb_codepoint_t) ((v) >> 21))
+#define HB_CODEPOINT_DECODE3_11_7_14_2(v) ((hb_codepoint_t) (((v) >> 14) & 0x007Fu) | 0x0300)
+#define HB_CODEPOINT_DECODE3_11_7_14_3(v) ((hb_codepoint_t) (v) & 0x3FFFu)
+
+struct
+{
+  /* Note.  This is dangerous in that if it's passed an rvalue, it returns rvalue-reference. */
+  template <typename T> constexpr auto
+  operator () (T&& v) const HB_AUTO_RETURN ( hb_forward<T> (v) )
+}
+HB_FUNCOBJ (hb_identity);
+struct
+{
+  /* Like identity(), but only retains lvalue-references.  Rvalues are returned as rvalues. */
+  template <typename T> constexpr T&
+  operator () (T& v) const { return v; }
+
+  template <typename T> constexpr hb_remove_reference<T>
+  operator () (T&& v) const { return v; }
+}
+HB_FUNCOBJ (hb_lidentity);
+struct
+{
+  /* Like identity(), but always returns rvalue. */
+  template <typename T> constexpr hb_remove_reference<T>
+  operator () (T&& v) const { return v; }
+}
+HB_FUNCOBJ (hb_ridentity);
+
+struct
+{
+  template <typename T> constexpr bool
+  operator () (T&& v) const { return bool (hb_forward<T> (v)); }
+}
+HB_FUNCOBJ (hb_bool);
+
+struct
+{
+  private:
+
+  template <typename T> constexpr auto
+  impl (const T& v, hb_priority<1>) const HB_RETURN (uint32_t, hb_deref (v).hash ())
+
+  template <typename T,
+           hb_enable_if (hb_is_integral (T))> constexpr auto
+  impl (const T& v, hb_priority<0>) const HB_AUTO_RETURN
+  (
+    /* Knuth's multiplicative method: */
+    (uint32_t) v * 2654435761u
+  )
+
+  public:
+
+  template <typename T> constexpr auto
+  operator () (const T& v) const HB_RETURN (uint32_t, impl (v, hb_prioritize))
+}
+HB_FUNCOBJ (hb_hash);
+
+
+struct
+{
+  private:
+
+  /* Pointer-to-member-function. */
+  template <typename Appl, typename T, typename ...Ts> auto
+  impl (Appl&& a, hb_priority<2>, T &&v, Ts&&... ds) const HB_AUTO_RETURN
+  ((hb_deref (hb_forward<T> (v)).*hb_forward<Appl> (a)) (hb_forward<Ts> (ds)...))
+
+  /* Pointer-to-member. */
+  template <typename Appl, typename T> auto
+  impl (Appl&& a, hb_priority<1>, T &&v) const HB_AUTO_RETURN
+  ((hb_deref (hb_forward<T> (v))).*hb_forward<Appl> (a))
+
+  /* Operator(). */
+  template <typename Appl, typename ...Ts> auto
+  impl (Appl&& a, hb_priority<0>, Ts&&... ds) const HB_AUTO_RETURN
+  (hb_deref (hb_forward<Appl> (a)) (hb_forward<Ts> (ds)...))
+
+  public:
+
+  template <typename Appl, typename ...Ts> auto
+  operator () (Appl&& a, Ts&&... ds) const HB_AUTO_RETURN
+  (
+    impl (hb_forward<Appl> (a),
+         hb_prioritize,
+         hb_forward<Ts> (ds)...)
+  )
+}
+HB_FUNCOBJ (hb_invoke);
+
+template <unsigned Pos, typename Appl, typename V>
+struct hb_partial_t
+{
+  hb_partial_t (Appl a, V v) : a (a), v (v) {}
+
+  static_assert (Pos > 0, "");
+
+  template <typename ...Ts,
+           unsigned P = Pos,
+           hb_enable_if (P == 1)> auto
+  operator () (Ts&& ...ds) -> decltype (hb_invoke (hb_declval (Appl),
+                                                  hb_declval (V),
+                                                  hb_declval (Ts)...))
+  {
+    return hb_invoke (hb_forward<Appl> (a),
+                     hb_forward<V> (v),
+                     hb_forward<Ts> (ds)...);
+  }
+  template <typename T0, typename ...Ts,
+           unsigned P = Pos,
+           hb_enable_if (P == 2)> auto
+  operator () (T0&& d0, Ts&& ...ds) -> decltype (hb_invoke (hb_declval (Appl),
+                                                           hb_declval (T0),
+                                                           hb_declval (V),
+                                                           hb_declval (Ts)...))
+  {
+    return hb_invoke (hb_forward<Appl> (a),
+                     hb_forward<T0> (d0),
+                     hb_forward<V> (v),
+                     hb_forward<Ts> (ds)...);
+  }
+
+  private:
+  hb_reference_wrapper<Appl> a;
+  V v;
+};
+template <unsigned Pos=1, typename Appl, typename V>
+auto hb_partial (Appl&& a, V&& v) HB_AUTO_RETURN
+(( hb_partial_t<Pos, Appl, V> (a, v) ))
+
+/* The following, HB_PARTIALIZE, macro uses a particular corner-case
+ * of C++11 that is not particularly well-supported by all compilers.
+ * What's happening is that it's using "this" in a trailing return-type
+ * via decltype().  Broken compilers deduce the type of "this" pointer
+ * in that context differently from what it resolves to in the body
+ * of the function.
+ *
+ * One probable cause of this is that at the time of trailing return
+ * type declaration, "this" points to an incomplete type, whereas in
+ * the function body the type is complete.  That doesn't justify the
+ * error in any way, but is probably what's happening.
+ *
+ * In the case of MSVC, we get around this by using C++14 "decltype(auto)"
+ * which deduces the type from the actual return statement.  For gcc 4.8
+ * we use "+this" instead of "this" which produces an rvalue that seems
+ * to be deduced as the same type with this particular compiler, and seem
+ * to be fine as default code path as well.
+ */
+#ifdef _MSC_VER
+/* https://github.com/harfbuzz/harfbuzz/issues/1730 */ \
+#define HB_PARTIALIZE(Pos) \
+  template <typename _T> \
+  decltype(auto) operator () (_T&& _v) const \
+  { return hb_partial<Pos> (this, hb_forward<_T> (_v)); } \
+  static_assert (true, "")
+#else
+/* https://github.com/harfbuzz/harfbuzz/issues/1724 */
+#define HB_PARTIALIZE(Pos) \
+  template <typename _T> \
+  auto operator () (_T&& _v) const HB_AUTO_RETURN \
+  (hb_partial<Pos> (+this, hb_forward<_T> (_v))) \
+  static_assert (true, "")
+#endif
+
+
+struct
+{
+  private:
+
+  template <typename Pred, typename Val> auto
+  impl (Pred&& p, Val &&v, hb_priority<1>) const HB_AUTO_RETURN
+  (hb_deref (hb_forward<Pred> (p)).has (hb_forward<Val> (v)))
+
+  template <typename Pred, typename Val> auto
+  impl (Pred&& p, Val &&v, hb_priority<0>) const HB_AUTO_RETURN
+  (
+    hb_invoke (hb_forward<Pred> (p),
+              hb_forward<Val> (v))
+  )
+
+  public:
+
+  template <typename Pred, typename Val> auto
+  operator () (Pred&& p, Val &&v) const HB_RETURN (bool,
+    impl (hb_forward<Pred> (p),
+         hb_forward<Val> (v),
+         hb_prioritize)
+  )
+}
+HB_FUNCOBJ (hb_has);
+
+struct
+{
+  private:
+
+  template <typename Pred, typename Val> auto
+  impl (Pred&& p, Val &&v, hb_priority<1>) const HB_AUTO_RETURN
+  (
+    hb_has (hb_forward<Pred> (p),
+           hb_forward<Val> (v))
+  )
+
+  template <typename Pred, typename Val> auto
+  impl (Pred&& p, Val &&v, hb_priority<0>) const HB_AUTO_RETURN
+  (
+    hb_forward<Pred> (p) == hb_forward<Val> (v)
+  )
+
+  public:
+
+  template <typename Pred, typename Val> auto
+  operator () (Pred&& p, Val &&v) const HB_RETURN (bool,
+    impl (hb_forward<Pred> (p),
+         hb_forward<Val> (v),
+         hb_prioritize)
+  )
+}
+HB_FUNCOBJ (hb_match);
+
+struct
+{
+  private:
+
+  template <typename Proj, typename Val> auto
+  impl (Proj&& f, Val &&v, hb_priority<2>) const HB_AUTO_RETURN
+  (hb_deref (hb_forward<Proj> (f)).get (hb_forward<Val> (v)))
+
+  template <typename Proj, typename Val> auto
+  impl (Proj&& f, Val &&v, hb_priority<1>) const HB_AUTO_RETURN
+  (
+    hb_invoke (hb_forward<Proj> (f),
+              hb_forward<Val> (v))
+  )
+
+  template <typename Proj, typename Val> auto
+  impl (Proj&& f, Val &&v, hb_priority<0>) const HB_AUTO_RETURN
+  (
+    hb_forward<Proj> (f)[hb_forward<Val> (v)]
+  )
+
+  public:
+
+  template <typename Proj, typename Val> auto
+  operator () (Proj&& f, Val &&v) const HB_AUTO_RETURN
+  (
+    impl (hb_forward<Proj> (f),
+         hb_forward<Val> (v),
+         hb_prioritize)
+  )
+}
+HB_FUNCOBJ (hb_get);
+
+
+template <typename T1, typename T2>
+struct hb_pair_t
+{
+  typedef T1 first_t;
+  typedef T2 second_t;
+  typedef hb_pair_t<T1, T2> pair_t;
+
+  hb_pair_t (T1 a, T2 b) : first (a), second (b) {}
+
+  template <typename Q1, typename Q2,
+           hb_enable_if (hb_is_convertible (T1, Q1) &&
+                         hb_is_convertible (T2, T2))>
+  operator hb_pair_t<Q1, Q2> () { return hb_pair_t<Q1, Q2> (first, second); }
+
+  hb_pair_t<T1, T2> reverse () const
+  { return hb_pair_t<T1, T2> (second, first); }
+
+  bool operator == (const pair_t& o) const { return first == o.first && second == o.second; }
+  bool operator != (const pair_t& o) const { return !(*this == o); }
+  bool operator < (const pair_t& o) const { return first < o.first || (first == o.first && second < o.second); }
+  bool operator >= (const pair_t& o) const { return !(*this < o); }
+  bool operator > (const pair_t& o) const { return first > o.first || (first == o.first && second > o.second); }
+  bool operator <= (const pair_t& o) const { return !(*this > o); }
+
+  T1 first;
+  T2 second;
+};
+#define hb_pair_t(T1,T2) hb_pair_t<T1, T2>
+template <typename T1, typename T2> static inline hb_pair_t<T1, T2>
+hb_pair (T1&& a, T2&& b) { return hb_pair_t<T1, T2> (a, b); }
+
+struct
+{
+  template <typename Pair> constexpr typename Pair::first_t
+  operator () (const Pair& pair) const { return pair.first; }
+}
+HB_FUNCOBJ (hb_first);
+
+struct
+{
+  template <typename Pair> constexpr typename Pair::second_t
+  operator () (const Pair& pair) const { return pair.second; }
+}
+HB_FUNCOBJ (hb_second);
+
+/* Note.  In min/max impl, we can use hb_type_identity<T> for second argument.
+ * However, that would silently convert between different-signedness integers.
+ * Instead we accept two different types, such that compiler can err if
+ * comparing integers of different signedness. */
+struct
+{
+  template <typename T, typename T2> constexpr auto
+  operator () (T&& a, T2&& b) const HB_AUTO_RETURN
+  (hb_forward<T> (a) <= hb_forward<T2> (b) ? hb_forward<T> (a) : hb_forward<T2> (b))
+}
+HB_FUNCOBJ (hb_min);
+struct
+{
+  template <typename T, typename T2> constexpr auto
+  operator () (T&& a, T2&& b) const HB_AUTO_RETURN
+  (hb_forward<T> (a) >= hb_forward<T2> (b) ? hb_forward<T> (a) : hb_forward<T2> (b))
+}
+HB_FUNCOBJ (hb_max);
+
+
+/*
+ * Bithacks.
+ */
+
+/* Return the number of 1 bits in v. */
+template <typename T>
+static inline HB_CONST_FUNC unsigned int
+hb_popcount (T v)
+{
+#if (defined(__GNUC__) && (__GNUC__ >= 4)) || defined(__clang__)
+  if (sizeof (T) <= sizeof (unsigned int))
+    return __builtin_popcount (v);
+
+  if (sizeof (T) <= sizeof (unsigned long))
+    return __builtin_popcountl (v);
+
+  if (sizeof (T) <= sizeof (unsigned long long))
+    return __builtin_popcountll (v);
+#endif
+
+  if (sizeof (T) <= 4)
+  {
+    /* "HACKMEM 169" */
+    uint32_t y;
+    y = (v >> 1) &033333333333;
+    y = v - y - ((y >>1) & 033333333333);
+    return (((y + (y >> 3)) & 030707070707) % 077);
+  }
+
+  if (sizeof (T) == 8)
+  {
+    unsigned int shift = 32;
+    return hb_popcount<uint32_t> ((uint32_t) v) + hb_popcount ((uint32_t) (v >> shift));
+  }
+
+  if (sizeof (T) == 16)
+  {
+    unsigned int shift = 64;
+    return hb_popcount<uint64_t> ((uint64_t) v) + hb_popcount ((uint64_t) (v >> shift));
+  }
+
+  assert (0);
+  return 0; /* Shut up stupid compiler. */
+}
+
+/* Returns the number of bits needed to store number */
+template <typename T>
+static inline HB_CONST_FUNC unsigned int
+hb_bit_storage (T v)
+{
+  if (unlikely (!v)) return 0;
+
+#if (defined(__GNUC__) && (__GNUC__ >= 4)) || defined(__clang__)
+  if (sizeof (T) <= sizeof (unsigned int))
+    return sizeof (unsigned int) * 8 - __builtin_clz (v);
+
+  if (sizeof (T) <= sizeof (unsigned long))
+    return sizeof (unsigned long) * 8 - __builtin_clzl (v);
+
+  if (sizeof (T) <= sizeof (unsigned long long))
+    return sizeof (unsigned long long) * 8 - __builtin_clzll (v);
+#endif
+
+#if (defined(_MSC_VER) && _MSC_VER >= 1500) || (defined(__MINGW32__) && (__GNUC__ < 4))
+  if (sizeof (T) <= sizeof (unsigned int))
+  {
+    unsigned long where;
+    _BitScanReverse (&where, v);
+    return 1 + where;
+  }
+# if defined(_WIN64)
+  if (sizeof (T) <= 8)
+  {
+    unsigned long where;
+    _BitScanReverse64 (&where, v);
+    return 1 + where;
+  }
+# endif
+#endif
+
+  if (sizeof (T) <= 4)
+  {
+    /* "bithacks" */
+    const unsigned int b[] = {0x2, 0xC, 0xF0, 0xFF00, 0xFFFF0000};
+    const unsigned int S[] = {1, 2, 4, 8, 16};
+    unsigned int r = 0;
+    for (int i = 4; i >= 0; i--)
+      if (v & b[i])
+      {
+       v >>= S[i];
+       r |= S[i];
+      }
+    return r + 1;
+  }
+  if (sizeof (T) <= 8)
+  {
+    /* "bithacks" */
+    const uint64_t b[] = {0x2ULL, 0xCULL, 0xF0ULL, 0xFF00ULL, 0xFFFF0000ULL, 0xFFFFFFFF00000000ULL};
+    const unsigned int S[] = {1, 2, 4, 8, 16, 32};
+    unsigned int r = 0;
+    for (int i = 5; i >= 0; i--)
+      if (v & b[i])
+      {
+       v >>= S[i];
+       r |= S[i];
+      }
+    return r + 1;
+  }
+  if (sizeof (T) == 16)
+  {
+    unsigned int shift = 64;
+    return (v >> shift) ? hb_bit_storage<uint64_t> ((uint64_t) (v >> shift)) + shift :
+                         hb_bit_storage<uint64_t> ((uint64_t) v);
+  }
+
+  assert (0);
+  return 0; /* Shut up stupid compiler. */
+}
+
+/* Returns the number of zero bits in the least significant side of v */
+template <typename T>
+static inline HB_CONST_FUNC unsigned int
+hb_ctz (T v)
+{
+  if (unlikely (!v)) return 0;
+
+#if (defined(__GNUC__) && (__GNUC__ >= 4)) || defined(__clang__)
+  if (sizeof (T) <= sizeof (unsigned int))
+    return __builtin_ctz (v);
+
+  if (sizeof (T) <= sizeof (unsigned long))
+    return __builtin_ctzl (v);
+
+  if (sizeof (T) <= sizeof (unsigned long long))
+    return __builtin_ctzll (v);
+#endif
+
+#if (defined(_MSC_VER) && _MSC_VER >= 1500) || (defined(__MINGW32__) && (__GNUC__ < 4))
+  if (sizeof (T) <= sizeof (unsigned int))
+  {
+    unsigned long where;
+    _BitScanForward (&where, v);
+    return where;
+  }
+# if defined(_WIN64)
+  if (sizeof (T) <= 8)
+  {
+    unsigned long where;
+    _BitScanForward64 (&where, v);
+    return where;
+  }
+# endif
+#endif
+
+  if (sizeof (T) <= 4)
+  {
+    /* "bithacks" */
+    unsigned int c = 32;
+    v &= - (int32_t) v;
+    if (v) c--;
+    if (v & 0x0000FFFF) c -= 16;
+    if (v & 0x00FF00FF) c -= 8;
+    if (v & 0x0F0F0F0F) c -= 4;
+    if (v & 0x33333333) c -= 2;
+    if (v & 0x55555555) c -= 1;
+    return c;
+  }
+  if (sizeof (T) <= 8)
+  {
+    /* "bithacks" */
+    unsigned int c = 64;
+    v &= - (int64_t) (v);
+    if (v) c--;
+    if (v & 0x00000000FFFFFFFFULL) c -= 32;
+    if (v & 0x0000FFFF0000FFFFULL) c -= 16;
+    if (v & 0x00FF00FF00FF00FFULL) c -= 8;
+    if (v & 0x0F0F0F0F0F0F0F0FULL) c -= 4;
+    if (v & 0x3333333333333333ULL) c -= 2;
+    if (v & 0x5555555555555555ULL) c -= 1;
+    return c;
+  }
+  if (sizeof (T) == 16)
+  {
+    unsigned int shift = 64;
+    return (uint64_t) v ? hb_bit_storage<uint64_t> ((uint64_t) v) :
+                         hb_bit_storage<uint64_t> ((uint64_t) (v >> shift)) + shift;
+  }
+
+  assert (0);
+  return 0; /* Shut up stupid compiler. */
+}
+
+
+/*
+ * Tiny stuff.
+ */
+
+/* ASCII tag/character handling */
+static inline bool ISALPHA (unsigned char c)
+{ return (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z'); }
+static inline bool ISALNUM (unsigned char c)
+{ return (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || (c >= '0' && c <= '9'); }
+static inline bool ISSPACE (unsigned char c)
+{ return c == ' ' || c =='\f'|| c =='\n'|| c =='\r'|| c =='\t'|| c =='\v'; }
+static inline unsigned char TOUPPER (unsigned char c)
+{ return (c >= 'a' && c <= 'z') ? c - 'a' + 'A' : c; }
+static inline unsigned char TOLOWER (unsigned char c)
+{ return (c >= 'A' && c <= 'Z') ? c - 'A' + 'a' : c; }
+
+static inline unsigned int DIV_CEIL (const unsigned int a, unsigned int b)
+{ return (a + (b - 1)) / b; }
+
+
+#undef  ARRAY_LENGTH
+template <typename Type, unsigned int n>
+static inline unsigned int ARRAY_LENGTH (const Type (&)[n]) { return n; }
+/* A const version, but does not detect erratically being called on pointers. */
+#define ARRAY_LENGTH_CONST(__array) ((signed int) (sizeof (__array) / sizeof (__array[0])))
+
+
+static inline int
+hb_memcmp (const void *a, const void *b, unsigned int len)
+{
+  /* It's illegal to pass NULL to memcmp(), even if len is zero.
+   * So, wrap it.
+   * https://sourceware.org/bugzilla/show_bug.cgi?id=23878 */
+  if (unlikely (!len)) return 0;
+  return memcmp (a, b, len);
+}
+
+static inline void *
+hb_memset (void *s, int c, unsigned int n)
+{
+  /* It's illegal to pass NULL to memset(), even if n is zero. */
+  if (unlikely (!n)) return 0;
+  return memset (s, c, n);
+}
+
+static inline bool
+hb_unsigned_mul_overflows (unsigned int count, unsigned int size)
+{
+  return (size > 0) && (count >= ((unsigned int) -1) / size);
+}
+
+static inline unsigned int
+hb_ceil_to_4 (unsigned int v)
+{
+  return ((v - 1) | 3) + 1;
+}
+
+template <typename T> static inline bool
+hb_in_range (T u, T lo, T hi)
+{
+  static_assert (!hb_is_signed<T>::value, "");
+
+  /* The casts below are important as if T is smaller than int,
+   * the subtract results will become a signed int! */
+  return (T)(u - lo) <= (T)(hi - lo);
+}
+template <typename T> static inline bool
+hb_in_ranges (T u, T lo1, T hi1, T lo2, T hi2)
+{
+  return hb_in_range (u, lo1, hi1) || hb_in_range (u, lo2, hi2);
+}
+template <typename T> static inline bool
+hb_in_ranges (T u, T lo1, T hi1, T lo2, T hi2, T lo3, T hi3)
+{
+  return hb_in_range (u, lo1, hi1) || hb_in_range (u, lo2, hi2) || hb_in_range (u, lo3, hi3);
+}
+
+
+/*
+ * Sort and search.
+ */
+template <typename ...Ts>
+static inline void *
+hb_bsearch (const void *key, const void *base,
+           size_t nmemb, size_t size,
+           int (*compar)(const void *_key, const void *_item, Ts... _ds),
+           Ts... ds)
+{
+  int min = 0, max = (int) nmemb - 1;
+  while (min <= max)
+  {
+    int mid = ((unsigned int) min + (unsigned int) max) / 2;
+    const void *p = (const void *) (((const char *) base) + (mid * size));
+    int c = compar (key, p, ds...);
+    if (c < 0)
+      max = mid - 1;
+    else if (c > 0)
+      min = mid + 1;
+    else
+      return (void *) p;
+  }
+  return nullptr;
+}
+
+
+/* From https://github.com/noporpoise/sort_r
+   Feb 5, 2019 (c8c65c1e)
+   Modified to support optional argument using templates */
+
+/* Isaac Turner 29 April 2014 Public Domain */
+
+/*
+hb_qsort function to be exported.
+Parameters:
+  base is the array to be sorted
+  nel is the number of elements in the array
+  width is the size in bytes of each element of the array
+  compar is the comparison function
+  arg (optional) is a pointer to be passed to the comparison function
+
+void hb_qsort(void *base, size_t nel, size_t width,
+              int (*compar)(const void *_a, const void *_b, [void *_arg]),
+              [void *arg]);
+*/
+
+#define SORT_R_SWAP(a,b,tmp) ((tmp) = (a), (a) = (b), (b) = (tmp))
+
+/* swap a and b */
+/* a and b must not be equal! */
+static inline void sort_r_swap(char *__restrict a, char *__restrict b,
+                               size_t w)
+{
+  char tmp, *end = a+w;
+  for(; a < end; a++, b++) { SORT_R_SWAP(*a, *b, tmp); }
+}
+
+/* swap a, b iff a>b */
+/* a and b must not be equal! */
+/* __restrict is same as restrict but better support on old machines */
+template <typename ...Ts>
+static inline int sort_r_cmpswap(char *__restrict a,
+                                 char *__restrict b, size_t w,
+                                 int (*compar)(const void *_a,
+                                               const void *_b,
+                                               Ts... _ds),
+                                 Ts... ds)
+{
+  if(compar(a, b, ds...) > 0) {
+    sort_r_swap(a, b, w);
+    return 1;
+  }
+  return 0;
+}
+
+/*
+Swap consecutive blocks of bytes of size na and nb starting at memory addr ptr,
+with the smallest swap so that the blocks are in the opposite order. Blocks may
+be internally re-ordered e.g.
+  12345ab  ->   ab34512
+  123abc   ->   abc123
+  12abcde  ->   deabc12
+*/
+static inline void sort_r_swap_blocks(char *ptr, size_t na, size_t nb)
+{
+  if(na > 0 && nb > 0) {
+    if(na > nb) { sort_r_swap(ptr, ptr+na, nb); }
+    else { sort_r_swap(ptr, ptr+nb, na); }
+  }
+}
+
+/* Implement recursive quicksort ourselves */
+/* Note: quicksort is not stable, equivalent values may be swapped */
+template <typename ...Ts>
+static inline void sort_r_simple(void *base, size_t nel, size_t w,
+                                 int (*compar)(const void *_a,
+                                               const void *_b,
+                                               Ts... _ds),
+                                 Ts... ds)
+{
+  char *b = (char *)base, *end = b + nel*w;
+
+  /* for(size_t i=0; i<nel; i++) {printf("%4i", *(int*)(b + i*sizeof(int)));}
+  printf("\n"); */
+
+  if(nel < 10) {
+    /* Insertion sort for arbitrarily small inputs */
+    char *pi, *pj;
+    for(pi = b+w; pi < end; pi += w) {
+      for(pj = pi; pj > b && sort_r_cmpswap(pj-w,pj,w,compar,ds...); pj -= w) {}
+    }
+  }
+  else
+  {
+    /* nel > 9; Quicksort */
+
+    int cmp;
+    char *pl, *ple, *pr, *pre, *pivot;
+    char *last = b+w*(nel-1), *tmp;
+
+    /*
+    Use median of second, middle and second-last items as pivot.
+    First and last may have been swapped with pivot and therefore be extreme
+    */
+    char *l[3];
+    l[0] = b + w;
+    l[1] = b+w*(nel/2);
+    l[2] = last - w;
+
+    /* printf("pivots: %i, %i, %i\n", *(int*)l[0], *(int*)l[1], *(int*)l[2]); */
+
+    if(compar(l[0],l[1],ds...) > 0) { SORT_R_SWAP(l[0], l[1], tmp); }
+    if(compar(l[1],l[2],ds...) > 0) {
+      SORT_R_SWAP(l[1], l[2], tmp);
+      if(compar(l[0],l[1],ds...) > 0) { SORT_R_SWAP(l[0], l[1], tmp); }
+    }
+
+    /* swap mid value (l[1]), and last element to put pivot as last element */
+    if(l[1] != last) { sort_r_swap(l[1], last, w); }
+
+    /*
+    pl is the next item on the left to be compared to the pivot
+    pr is the last item on the right that was compared to the pivot
+    ple is the left position to put the next item that equals the pivot
+    ple is the last right position where we put an item that equals the pivot
+                                           v- end (beyond the array)
+      EEEEEELLLLLLLLuuuuuuuuGGGGGGGEEEEEEEE.
+      ^- b  ^- ple  ^- pl   ^- pr  ^- pre ^- last (where the pivot is)
+    Pivot comparison key:
+      E = equal, L = less than, u = unknown, G = greater than, E = equal
+    */
+    pivot = last;
+    ple = pl = b;
+    pre = pr = last;
+
+    /*
+    Strategy:
+    Loop into the list from the left and right at the same time to find:
+    - an item on the left that is greater than the pivot
+    - an item on the right that is less than the pivot
+    Once found, they are swapped and the loop continues.
+    Meanwhile items that are equal to the pivot are moved to the edges of the
+    array.
+    */
+    while(pl < pr) {
+      /* Move left hand items which are equal to the pivot to the far left.
+         break when we find an item that is greater than the pivot */
+      for(; pl < pr; pl += w) {
+        cmp = compar(pl, pivot, ds...);
+        if(cmp > 0) { break; }
+        else if(cmp == 0) {
+          if(ple < pl) { sort_r_swap(ple, pl, w); }
+          ple += w;
+        }
+      }
+      /* break if last batch of left hand items were equal to pivot */
+      if(pl >= pr) { break; }
+      /* Move right hand items which are equal to the pivot to the far right.
+         break when we find an item that is less than the pivot */
+      for(; pl < pr; ) {
+        pr -= w; /* Move right pointer onto an unprocessed item */
+        cmp = compar(pr, pivot, ds...);
+        if(cmp == 0) {
+          pre -= w;
+          if(pr < pre) { sort_r_swap(pr, pre, w); }
+        }
+        else if(cmp < 0) {
+          if(pl < pr) { sort_r_swap(pl, pr, w); }
+          pl += w;
+          break;
+        }
+      }
+    }
+
+    pl = pr; /* pr may have gone below pl */
+
+    /*
+    Now we need to go from: EEELLLGGGGEEEE
+                        to: LLLEEEEEEEGGGG
+    Pivot comparison key:
+      E = equal, L = less than, u = unknown, G = greater than, E = equal
+    */
+    sort_r_swap_blocks(b, ple-b, pl-ple);
+    sort_r_swap_blocks(pr, pre-pr, end-pre);
+
+    /*for(size_t i=0; i<nel; i++) {printf("%4i", *(int*)(b + i*sizeof(int)));}
+    printf("\n");*/
+
+    sort_r_simple(b, (pl-ple)/w, w, compar, ds...);
+    sort_r_simple(end-(pre-pr), (pre-pr)/w, w, compar, ds...);
+  }
+}
+
+static inline void
+hb_qsort (void *base, size_t nel, size_t width,
+         int (*compar)(const void *_a, const void *_b))
+{
+#if defined(__OPTIMIZE_SIZE__) && !defined(HB_USE_INTERNAL_QSORT)
+  qsort (base, nel, width, compar);
+#else
+  sort_r_simple (base, nel, width, compar);
+#endif
+}
+
+static inline void
+hb_qsort (void *base, size_t nel, size_t width,
+         int (*compar)(const void *_a, const void *_b, void *_arg),
+         void *arg)
+{
+#ifdef HAVE_GNU_QSORT_R
+  qsort_r (base, nel, width, compar, arg);
+#else
+  sort_r_simple (base, nel, width, compar, arg);
+#endif
+}
+
+
+template <typename T, typename T2, typename T3> static inline void
+hb_stable_sort (T *array, unsigned int len, int(*compar)(const T2 *, const T2 *), T3 *array2)
+{
+  for (unsigned int i = 1; i < len; i++)
+  {
+    unsigned int j = i;
+    while (j && compar (&array[j - 1], &array[i]) > 0)
+      j--;
+    if (i == j)
+      continue;
+    /* Move item i to occupy place for item j, shift what's in between. */
+    {
+      T t = array[i];
+      memmove (&array[j + 1], &array[j], (i - j) * sizeof (T));
+      array[j] = t;
+    }
+    if (array2)
+    {
+      T3 t = array2[i];
+      memmove (&array2[j + 1], &array2[j], (i - j) * sizeof (T3));
+      array2[j] = t;
+    }
+  }
+}
+
+template <typename T> static inline void
+hb_stable_sort (T *array, unsigned int len, int(*compar)(const T *, const T *))
+{
+  hb_stable_sort (array, len, compar, (int *) nullptr);
+}
+
+static inline hb_bool_t
+hb_codepoint_parse (const char *s, unsigned int len, int base, hb_codepoint_t *out)
+{
+  unsigned int v;
+  const char *p = s;
+  const char *end = p + len;
+  if (unlikely (!hb_parse_uint (&p, end, &v, true/* whole buffer */, base)))
+    return false;
+
+  *out = v;
+  return true;
+}
+
+
+/* Operators. */
+
+struct hb_bitwise_and
+{ HB_PARTIALIZE(2);
+  static constexpr bool passthru_left = false;
+  static constexpr bool passthru_right = false;
+  template <typename T> constexpr auto
+  operator () (const T &a, const T &b) const HB_AUTO_RETURN (a & b)
+}
+HB_FUNCOBJ (hb_bitwise_and);
+struct hb_bitwise_or
+{ HB_PARTIALIZE(2);
+  static constexpr bool passthru_left = true;
+  static constexpr bool passthru_right = true;
+  template <typename T> constexpr auto
+  operator () (const T &a, const T &b) const HB_AUTO_RETURN (a | b)
+}
+HB_FUNCOBJ (hb_bitwise_or);
+struct hb_bitwise_xor
+{ HB_PARTIALIZE(2);
+  static constexpr bool passthru_left = true;
+  static constexpr bool passthru_right = true;
+  template <typename T> constexpr auto
+  operator () (const T &a, const T &b) const HB_AUTO_RETURN (a ^ b)
+}
+HB_FUNCOBJ (hb_bitwise_xor);
+struct hb_bitwise_sub
+{ HB_PARTIALIZE(2);
+  static constexpr bool passthru_left = true;
+  static constexpr bool passthru_right = false;
+  template <typename T> constexpr auto
+  operator () (const T &a, const T &b) const HB_AUTO_RETURN (a & ~b)
+}
+HB_FUNCOBJ (hb_bitwise_sub);
+struct
+{
+  template <typename T> constexpr auto
+  operator () (const T &a) const HB_AUTO_RETURN (~a)
+}
+HB_FUNCOBJ (hb_bitwise_neg);
+
+struct
+{ HB_PARTIALIZE(2);
+  template <typename T, typename T2> constexpr auto
+  operator () (const T &a, const T2 &b) const HB_AUTO_RETURN (a + b)
+}
+HB_FUNCOBJ (hb_add);
+struct
+{ HB_PARTIALIZE(2);
+  template <typename T, typename T2> constexpr auto
+  operator () (const T &a, const T2 &b) const HB_AUTO_RETURN (a - b)
+}
+HB_FUNCOBJ (hb_sub);
+struct
+{ HB_PARTIALIZE(2);
+  template <typename T, typename T2> constexpr auto
+  operator () (const T &a, const T2 &b) const HB_AUTO_RETURN (a * b)
+}
+HB_FUNCOBJ (hb_mul);
+struct
+{ HB_PARTIALIZE(2);
+  template <typename T, typename T2> constexpr auto
+  operator () (const T &a, const T2 &b) const HB_AUTO_RETURN (a / b)
+}
+HB_FUNCOBJ (hb_div);
+struct
+{ HB_PARTIALIZE(2);
+  template <typename T, typename T2> constexpr auto
+  operator () (const T &a, const T2 &b) const HB_AUTO_RETURN (a % b)
+}
+HB_FUNCOBJ (hb_mod);
+struct
+{
+  template <typename T> constexpr auto
+  operator () (const T &a) const HB_AUTO_RETURN (+a)
+}
+HB_FUNCOBJ (hb_pos);
+struct
+{
+  template <typename T> constexpr auto
+  operator () (const T &a) const HB_AUTO_RETURN (-a)
+}
+HB_FUNCOBJ (hb_neg);
+struct
+{
+  template <typename T> constexpr auto
+  operator () (T &a) const HB_AUTO_RETURN (++a)
+}
+HB_FUNCOBJ (hb_inc);
+struct
+{
+  template <typename T> constexpr auto
+  operator () (T &a) const HB_AUTO_RETURN (--a)
+}
+HB_FUNCOBJ (hb_dec);
+
+
+/* Compiler-assisted vectorization. */
+
+/* Type behaving similar to vectorized vars defined using __attribute__((vector_size(...))),
+ * basically a fixed-size bitset. */
+template <typename elt_t, unsigned int byte_size>
+struct hb_vector_size_t
+{
+  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) { memset (this, v, sizeof (*this)); }
+
+  template <typename Op>
+  hb_vector_size_t process (const Op& op) const
+  {
+    hb_vector_size_t r;
+    for (unsigned int i = 0; i < ARRAY_LENGTH (v); i++)
+      r.v[i] = op (v[i]);
+    return r;
+  }
+  template <typename Op>
+  hb_vector_size_t process (const Op& op, const hb_vector_size_t &o) const
+  {
+    hb_vector_size_t r;
+    for (unsigned int i = 0; i < ARRAY_LENGTH (v); i++)
+      r.v[i] = op (v[i], o.v[i]);
+    return r;
+  }
+  hb_vector_size_t operator | (const hb_vector_size_t &o) const
+  { return process (hb_bitwise_or, o); }
+  hb_vector_size_t operator & (const hb_vector_size_t &o) const
+  { return process (hb_bitwise_and, o); }
+  hb_vector_size_t operator ^ (const hb_vector_size_t &o) const
+  { return process (hb_bitwise_xor, o); }
+  hb_vector_size_t operator ~ () const
+  { return process (hb_bitwise_neg); }
+
+  private:
+  static_assert (0 == byte_size % sizeof (elt_t), "");
+  elt_t v[byte_size / sizeof (elt_t)];
+};
+
+
+#endif /* HB_ALGS_HH */
index 52b775e..d9adf2c 100644 (file)
@@ -28,7 +28,7 @@
 #define HB_ARRAY_HH
 
 #include "hb.hh"
-#include "hb-dsalgs.hh"
+#include "hb-algs.hh"
 #include "hb-iter.hh"
 #include "hb-null.hh"
 
@@ -37,22 +37,31 @@ template <typename Type>
 struct hb_sorted_array_t;
 
 template <typename Type>
-struct hb_array_t :
-       hb_iter_t<hb_array_t<Type>, Type>,
-       hb_iter_mixin_t<hb_array_t<Type>, Type>
+struct hb_array_t : hb_iter_with_fallback_t<hb_array_t<Type>, Type&>
 {
   /*
    * Constructors.
    */
-  hb_array_t () : arrayZ (nullptr), length (0) {}
-  hb_array_t (Type *array_, unsigned int length_) : arrayZ (array_), length (length_) {}
-  template <unsigned int length_> hb_array_t (Type (&array_)[length_]) : arrayZ (array_), length (length_) {}
+  hb_array_t () : arrayZ (nullptr), length (0), backwards_length (0) {}
+  hb_array_t (Type *array_, unsigned int length_) : arrayZ (array_), length (length_), backwards_length (0) {}
+  template <unsigned int length_>
+  hb_array_t (Type (&array_)[length_]) : arrayZ (array_), length (length_), backwards_length (0) {}
 
+  template <typename U,
+           hb_enable_if (hb_is_cr_convertible(U, Type))>
+  hb_array_t (const hb_array_t<U> &o) :
+    hb_iter_with_fallback_t<hb_array_t, Type&> (),
+    arrayZ (o.arrayZ), length (o.length), backwards_length (o.backwards_length) {}
+  template <typename U,
+           hb_enable_if (hb_is_cr_convertible(U, Type))>
+  hb_array_t& operator = (const hb_array_t<U> &o)
+  { arrayZ = o.arrayZ; length = o.length; backwards_length = o.backwards_length; return *this; }
 
   /*
    * Iterator implementation.
    */
-  typedef Type __item_type__;
+  typedef Type& __item_t__;
+  static constexpr bool is_random_access_iterator = true;
   Type& __item_at__ (unsigned i) const
   {
     if (unlikely (i >= length)) return CrapOrNull (Type);
@@ -63,16 +72,25 @@ struct hb_array_t :
     if (unlikely (n > length))
       n = length;
     length -= n;
+    backwards_length += n;
     arrayZ += n;
   }
   void __rewind__ (unsigned n)
   {
-    if (unlikely (n > length))
-      n = length;
-    length -= n;
+    if (unlikely (n > backwards_length))
+      n = backwards_length;
+    length += n;
+    backwards_length -= n;
+    arrayZ -= n;
   }
   unsigned __len__ () const { return length; }
-  bool __random_access__ () const { return true; }
+  /* Ouch. The operator== compares the contents of the array.  For range-based for loops,
+   * it's best if we can just compare arrayZ, though comparing contents is still fast,
+   * but also would require that Type has operator==.  As such, we optimize this operator
+   * for range-based for loop and just compare arrayZ.  No need to compare length, as we
+   * assume we're only compared to .end(). */
+  bool operator != (const hb_array_t& o) const
+  { return arrayZ != o.arrayZ; }
 
   /* Extra operators.
    */
@@ -80,21 +98,31 @@ struct hb_array_t :
   operator hb_array_t<const Type> () { return hb_array_t<const Type> (arrayZ, length); }
   template <typename T> operator T * () const { return arrayZ; }
 
+  HB_INTERNAL bool operator == (const hb_array_t &o) const;
+
+  uint32_t hash () const {
+    uint32_t current = 0;
+    for (unsigned int i = 0; i < this->length; i++) {
+      current = current * 31 + hb_hash (this->arrayZ[i]);
+    }
+    return current;
+  }
+
   /*
    * Compare, Sort, and Search.
    */
 
   /* Note: our compare is NOT lexicographic; it also does NOT call Type::cmp. */
-  int cmp (const hb_array_t<Type> &a) const
+  int cmp (const hb_array_t &a) const
   {
     if (length != a.length)
       return (int) a.length - (int) length;
     return hb_memcmp (a.arrayZ, arrayZ, get_size ());
   }
-  static int cmp (const void *pa, const void *pb)
+  HB_INTERNAL static int cmp (const void *pa, const void *pb)
   {
-    hb_array_t<Type> *a = (hb_array_t<Type> *) pa;
-    hb_array_t<Type> *b = (hb_array_t<Type> *) pb;
+    hb_array_t *a = (hb_array_t *) pa;
+    hb_array_t *b = (hb_array_t *) pb;
     return b->cmp (*a);
   }
 
@@ -120,30 +148,30 @@ struct hb_array_t :
   hb_sorted_array_t<Type> qsort (int (*cmp_)(const void*, const void*))
   {
     if (likely (length))
-      ::qsort (arrayZ, length, this->item_size, cmp_);
+      hb_qsort (arrayZ, length, this->get_item_size (), cmp_);
     return hb_sorted_array_t<Type> (*this);
   }
   hb_sorted_array_t<Type> qsort ()
   {
     if (likely (length))
-      ::qsort (arrayZ, length, this->item_size, Type::cmp);
+      hb_qsort (arrayZ, length, this->get_item_size (), Type::cmp);
     return hb_sorted_array_t<Type> (*this);
   }
   void qsort (unsigned int start, unsigned int end)
   {
-    end = MIN (end, length);
+    end = hb_min (end, length);
     assert (start <= end);
     if (likely (start < end))
-      ::qsort (arrayZ + start, end - start, this->item_size, Type::cmp);
+      hb_qsort (arrayZ + start, end - start, this->get_item_size (), Type::cmp);
   }
 
   /*
    * Other methods.
    */
 
-  unsigned int get_size () const { return length * this->item_size; }
+  unsigned int get_size () const { return length * this->get_item_size (); }
 
-  hb_array_t<Type> sub_array (unsigned int start_offset = 0, unsigned int *seg_count = nullptr /* IN/OUT */) const
+  hb_array_t sub_array (unsigned int start_offset = 0, unsigned int *seg_count = nullptr /* IN/OUT */) const
   {
     if (!start_offset && !seg_count)
       return *this;
@@ -154,16 +182,44 @@ struct hb_array_t :
     else
       count -= start_offset;
     if (seg_count)
-      count = *seg_count = MIN (count, *seg_count);
-    return hb_array_t<Type> (arrayZ + start_offset, count);
+      count = *seg_count = hb_min (count, *seg_count);
+    return hb_array_t (arrayZ + start_offset, count);
   }
-  hb_array_t<Type> sub_array (unsigned int start_offset, unsigned int seg_count) const
+  hb_array_t sub_array (unsigned int start_offset, unsigned int seg_count) const
   { return sub_array (start_offset, &seg_count); }
 
+  hb_array_t truncate (unsigned length) const { return sub_array (0, length); }
+
+  template <typename T,
+           unsigned P = sizeof (Type),
+           hb_enable_if (P == 1)>
+  const T *as () const
+  { return length < hb_null_size (T) ? &Null (T) : reinterpret_cast<const T *> (arrayZ); }
+
+  template <typename T,
+           unsigned P = sizeof (Type),
+           hb_enable_if (P == 1)>
+  bool in_range (const T *p, unsigned int size = T::static_size) const
+  {
+    return ((const char *) p) >= arrayZ
+       && ((const char *) p + size) <= arrayZ + length;
+  }
+
   /* Only call if you allocated the underlying array using malloc() or similar. */
   void free ()
   { ::free ((void *) arrayZ); arrayZ = nullptr; length = 0; }
 
+  template <typename hb_serialize_context_t>
+  hb_array_t copy (hb_serialize_context_t *c) const
+  {
+    TRACE_SERIALIZE (this);
+    auto* out = c->start_embed (arrayZ);
+    if (unlikely (!c->extend_size (out, get_size ()))) return_trace (hb_array_t ());
+    for (unsigned i = 0; i < length; i++)
+      out[i] = arrayZ[i]; /* TODO: add version that calls c->copy() */
+    return_trace (hb_array_t (out, length));
+  }
+
   template <typename hb_sanitize_context_t>
   bool sanitize (hb_sanitize_context_t *c) const
   { return c->check_array (arrayZ, length); }
@@ -175,6 +231,7 @@ struct hb_array_t :
   public:
   Type *arrayZ;
   unsigned int length;
+  unsigned int backwards_length;
 };
 template <typename T> inline hb_array_t<T>
 hb_array (T *array, unsigned int length)
@@ -183,7 +240,6 @@ template <typename T, unsigned int length_> inline hb_array_t<T>
 hb_array (T (&array_)[length_])
 { return hb_array_t<T> (array_); }
 
-
 enum hb_bfind_not_found_t
 {
   HB_BFIND_NOT_FOUND_DONT_STORE,
@@ -193,20 +249,40 @@ enum hb_bfind_not_found_t
 
 template <typename Type>
 struct hb_sorted_array_t :
-       hb_sorted_iter_t<hb_sorted_array_t<Type>, Type>,
-       hb_array_t<Type>,
-       hb_iter_mixin_t<hb_sorted_array_t<Type>, Type>
+       hb_iter_t<hb_sorted_array_t<Type>, Type&>,
+       hb_array_t<Type>
 {
+  typedef hb_iter_t<hb_sorted_array_t, Type&> iter_base_t;
+  HB_ITER_USING (iter_base_t);
+  static constexpr bool is_random_access_iterator = true;
+  static constexpr bool is_sorted_iterator = true;
+
   hb_sorted_array_t () : hb_array_t<Type> () {}
-  hb_sorted_array_t (const hb_array_t<Type> &o) : hb_array_t<Type> (o) {}
   hb_sorted_array_t (Type *array_, unsigned int length_) : hb_array_t<Type> (array_, length_) {}
-  template <unsigned int length_> hb_sorted_array_t (Type (&array_)[length_]) : hb_array_t<Type> (array_) {}
+  template <unsigned int length_>
+  hb_sorted_array_t (Type (&array_)[length_]) : hb_array_t<Type> (array_) {}
+
+  template <typename U,
+           hb_enable_if (hb_is_cr_convertible(U, Type))>
+  hb_sorted_array_t (const hb_array_t<U> &o) :
+    hb_iter_t<hb_sorted_array_t, Type&> (),
+    hb_array_t<Type> (o) {}
+  template <typename U,
+           hb_enable_if (hb_is_cr_convertible(U, Type))>
+  hb_sorted_array_t& operator = (const hb_array_t<U> &o)
+  { hb_array_t<Type> (*this) = o; return *this; }
 
-  hb_sorted_array_t<Type> sub_array (unsigned int start_offset, unsigned int *seg_count /* IN/OUT */) const
-  { return hb_sorted_array_t<Type> (((const hb_array_t<Type> *) (this))->sub_array (start_offset, seg_count)); }
-  hb_sorted_array_t<Type> sub_array (unsigned int start_offset, unsigned int seg_count) const
+  /* Iterator implementation. */
+  bool operator != (const hb_sorted_array_t& o) const
+  { return this->arrayZ != o.arrayZ || this->length != o.length; }
+
+  hb_sorted_array_t sub_array (unsigned int start_offset, unsigned int *seg_count /* IN/OUT */) const
+  { return hb_sorted_array_t (((const hb_array_t<Type> *) (this))->sub_array (start_offset, seg_count)); }
+  hb_sorted_array_t sub_array (unsigned int start_offset, unsigned int seg_count) const
   { return sub_array (start_offset, &seg_count); }
 
+  hb_sorted_array_t truncate (unsigned length) const { return sub_array (0, length); }
+
   template <typename T>
   Type *bsearch (const T &x, Type *not_found = nullptr)
   {
@@ -221,8 +297,8 @@ struct hb_sorted_array_t :
   }
   template <typename T>
   bool bfind (const T &x, unsigned int *i = nullptr,
-                    hb_bfind_not_found_t not_found = HB_BFIND_NOT_FOUND_DONT_STORE,
-                    unsigned int to_store = (unsigned int) -1) const
+             hb_bfind_not_found_t not_found = HB_BFIND_NOT_FOUND_DONT_STORE,
+             unsigned int to_store = (unsigned int) -1) const
   {
     int min = 0, max = (int) this->length - 1;
     const Type *array = this->arrayZ;
@@ -231,9 +307,9 @@ struct hb_sorted_array_t :
       int mid = ((unsigned int) min + (unsigned int) max) / 2;
       int c = array[mid].cmp (x);
       if (c < 0)
-        max = mid - 1;
+       max = mid - 1;
       else if (c > 0)
-        min = mid + 1;
+       min = mid + 1;
       else
       {
        if (i)
@@ -269,9 +345,38 @@ template <typename T, unsigned int length_> inline hb_sorted_array_t<T>
 hb_sorted_array (T (&array_)[length_])
 { return hb_sorted_array_t<T> (array_); }
 
+template <typename T>
+bool hb_array_t<T>::operator == (const hb_array_t<T> &o) const
+{
+  if (o.length != this->length) return false;
+  for (unsigned int i = 0; i < this->length; i++) {
+    if (this->arrayZ[i] != o.arrayZ[i]) return false;
+  }
+  return true;
+}
+
+/* TODO Specialize opeator== for hb_bytes_t and hb_ubytes_t. */
+
+template <>
+inline uint32_t hb_array_t<const char>::hash () const {
+  uint32_t current = 0;
+  for (unsigned int i = 0; i < this->length; i++)
+    current = current * 31 + (uint32_t) (this->arrayZ[i] * 2654435761u);
+  return current;
+}
+
+template <>
+inline uint32_t hb_array_t<const unsigned char>::hash () const {
+  uint32_t current = 0;
+  for (unsigned int i = 0; i < this->length; i++)
+    current = current * 31 + (uint32_t) (this->arrayZ[i] * 2654435761u);
+  return current;
+}
+
 
 typedef hb_array_t<const char> hb_bytes_t;
 typedef hb_array_t<const unsigned char> hb_ubytes_t;
 
 
+
 #endif /* HB_ARRAY_HH */
index f9afd4f..b3fb296 100644 (file)
@@ -33,6 +33,7 @@
 #define HB_ATOMIC_HH
 
 #include "hb.hh"
+#include "hb-meta.hh"
 
 
 /*
@@ -106,7 +107,7 @@ _hb_atomic_ptr_impl_cmplexch (const void **P, const void *O_, const void *N)
 
 static inline void _hb_memory_barrier ()
 {
-#if !defined(MemoryBarrier)
+#if !defined(MemoryBarrier) && !defined(__MINGW32_VERSION)
   /* MinGW has a convoluted history of supporting MemoryBarrier. */
   LONG dummy = 0;
   InterlockedExchange (&dummy, 1);
@@ -211,25 +212,19 @@ static inline bool _hb_compare_and_swaplp (long *P, long O, long N)
 static_assert ((sizeof (long) == sizeof (void *)), "");
 
 
-#elif !defined(HB_NO_MT)
-
-#define HB_ATOMIC_INT_NIL 1 /* Warn that fallback implementation is in use. */
-
-#define _hb_memory_barrier()
+#elif defined(HB_NO_MT)
 
 #define hb_atomic_int_impl_add(AI, V)          ((*(AI) += (V)) - (V))
 
-#define hb_atomic_ptr_impl_cmpexch(P,O,N)      (* (void **) (P) == (void *) (O) ? (* (void **) (P) = (void *) (N), true) : false)
-
-
-#else /* HB_NO_MT */
+#define _hb_memory_barrier()                   do {} while (0)
 
-#define hb_atomic_int_impl_add(AI, V)          ((*(AI) += (V)) - (V))
+#define hb_atomic_ptr_impl_cmpexch(P,O,N)      (* (void **) (P) == (void *) (O) ? (* (void **) (P) = (void *) (N), true) : false)
 
-#define _hb_memory_barrier()
 
-#define hb_atomic_ptr_impl_cmpexch(P,O,N)      (* (void **) (P) == (void *) (O) ? (* (void **) (P) = (void *) (N), true) : false)
+#else
 
+#error "Could not find any system to define atomic_int macros."
+#error "Check hb-atomic.hh for possible resolutions."
 
 #endif
 
@@ -282,7 +277,7 @@ struct hb_atomic_int_t
 template <typename P>
 struct hb_atomic_ptr_t
 {
-  typedef typename hb_remove_pointer (P) T;
+  typedef hb_remove_pointer<P> T;
 
   void init (T* v_ = nullptr) { set_relaxed (v_); }
   void set_relaxed (T* v_) { hb_atomic_ptr_impl_set_relaxed (&v, v_); }
diff --git a/src/hb-bimap.hh b/src/hb-bimap.hh
new file mode 100644 (file)
index 0000000..cae0a4d
--- /dev/null
@@ -0,0 +1,166 @@
+/*
+ * Copyright © 2019 Adobe 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.
+ *
+ * Adobe Author(s): Michiharu Ariza
+ */
+
+#ifndef HB_BIMAP_HH
+#define HB_BIMAP_HH
+
+#include "hb.hh"
+#include "hb-map.hh"
+
+/* Bi-directional map */
+struct hb_bimap_t
+{
+  hb_bimap_t () { init (); }
+  ~hb_bimap_t () { fini (); }
+
+  void init ()
+  {
+    forw_map.init ();
+    back_map.init ();
+  }
+
+  void fini ()
+  {
+    forw_map.fini ();
+    back_map.fini ();
+  }
+
+  void reset ()
+  {
+    forw_map.reset ();
+    back_map.reset ();
+  }
+
+  bool in_error () const { return forw_map.in_error () || back_map.in_error (); }
+
+  void set (hb_codepoint_t lhs, hb_codepoint_t rhs)
+  {
+    if (unlikely (lhs == HB_MAP_VALUE_INVALID)) return;
+    if (unlikely (rhs == HB_MAP_VALUE_INVALID)) { del (lhs); return; }
+    forw_map.set (lhs, rhs);
+    back_map.set (rhs, lhs);
+  }
+
+  hb_codepoint_t get (hb_codepoint_t lhs) const { return forw_map.get (lhs); }
+  hb_codepoint_t backward (hb_codepoint_t rhs) const { return back_map.get (rhs); }
+
+  hb_codepoint_t operator [] (hb_codepoint_t lhs) const { return get (lhs); }
+  bool has (hb_codepoint_t lhs, hb_codepoint_t *vp = nullptr) const { return forw_map.has (lhs, vp); }
+
+  void del (hb_codepoint_t lhs)
+  {
+    back_map.del (get (lhs));
+    forw_map.del (lhs);
+  }
+
+  void clear ()
+  {
+    forw_map.clear ();
+    back_map.clear ();
+  }
+
+  bool is_empty () const { return get_population () == 0; }
+
+  unsigned int get_population () const { return forw_map.get_population (); }
+
+  protected:
+  hb_map_t  forw_map;
+  hb_map_t  back_map;
+};
+
+/* Inremental bimap: only lhs is given, rhs is incrementally assigned */
+struct hb_inc_bimap_t : hb_bimap_t
+{
+  hb_inc_bimap_t () { init (); }
+
+  void init ()
+  {
+    hb_bimap_t::init ();
+    next_value = 0;
+  }
+
+  /* Add a mapping from lhs to rhs with a unique value if lhs is unknown.
+   * Return the rhs value as the result.
+   */
+  hb_codepoint_t add (hb_codepoint_t lhs)
+  {
+    hb_codepoint_t  rhs = forw_map[lhs];
+    if (rhs == HB_MAP_VALUE_INVALID)
+    {
+      rhs = next_value++;
+      set (lhs, rhs);
+    }
+    return rhs;
+  }
+
+  hb_codepoint_t skip ()
+  { return next_value++; }
+
+  hb_codepoint_t get_next_value () const
+  { return next_value; }
+
+  void add_set (const hb_set_t *set)
+  {
+    hb_codepoint_t i = HB_SET_VALUE_INVALID;
+    while (hb_set_next (set, &i)) add (i);
+  }
+
+  /* Create an identity map. */
+  bool identity (unsigned int size)
+  {
+    clear ();
+    for (hb_codepoint_t i = 0; i < size; i++) set (i, i);
+    return !in_error ();
+  }
+
+  protected:
+  static int cmp_id (const void* a, const void* b)
+  { return (int)*(const hb_codepoint_t *)a - (int)*(const hb_codepoint_t *)b; }
+
+  public:
+  /* Optional: after finished adding all mappings in a random order,
+   * reassign rhs to lhs so that they are in the same order. */
+  void sort ()
+  {
+    hb_codepoint_t  count = get_population ();
+    hb_vector_t <hb_codepoint_t> work;
+    work.resize (count);
+
+    for (hb_codepoint_t rhs = 0; rhs < count; rhs++)
+      work[rhs] = back_map[rhs];
+  
+    work.qsort (cmp_id);
+  
+    clear ();
+    for (hb_codepoint_t rhs = 0; rhs < count; rhs++)
+      set (work[rhs], rhs);
+  }
+
+  protected:
+  unsigned int next_value;
+};
+
+#endif /* HB_BIMAP_HH */
index bcf381e..2e72683 100644 (file)
@@ -30,7 +30,7 @@
  * http://www.gnu.org/software/libc/manual/html_node/Feature-Test-Macros.html
  * https://www.oracle.com/technetwork/articles/servers-storage-dev/standardheaderfiles-453865.html
  */
-#ifndef _POSIX_C_SOURCE
+#if !defined(_POSIX_C_SOURCE) && !defined(_MSC_VER) && !defined(__NetBSD__)
 #pragma GCC diagnostic push
 #pragma GCC diagnostic ignored "-Wunused-macros"
 #define _POSIX_C_SOURCE 200809L
@@ -48,7 +48,6 @@
 #endif /* HAVE_SYS_MMAN_H */
 
 #include <stdio.h>
-#include <errno.h>
 #include <stdlib.h>
 
 
@@ -155,7 +154,7 @@ hb_blob_create_sub_blob (hb_blob_t    *parent,
   hb_blob_make_immutable (parent);
 
   blob = hb_blob_create (parent->data + offset,
-                        MIN (length, parent->length - offset),
+                        hb_min (length, parent->length - offset),
                         HB_MEMORY_MODE_READONLY,
                         hb_blob_reference (parent),
                         _hb_blob_destroy);
@@ -487,6 +486,7 @@ hb_blob_t::try_make_writable ()
  * Mmap
  */
 
+#ifndef HB_NO_OPEN
 #ifdef HAVE_MMAP
 # include <sys/types.h>
 # include <sys/stat.h>
@@ -591,7 +591,7 @@ fail_without_close:
     ceparams.lpSecurityAttributes = nullptr;
     ceparams.hTemplateFile = nullptr;
     fd = CreateFile2 (wchar_file_name, GENERIC_READ, FILE_SHARE_READ,
-                      OPEN_EXISTING, &ceparams);
+                     OPEN_EXISTING, &ceparams);
   }
 #else
   fd = CreateFileW (wchar_file_name, GENERIC_READ, FILE_SHARE_READ, nullptr,
@@ -668,7 +668,7 @@ fail_without_close:
   }
 
   return hb_blob_create (data, len, HB_MEMORY_MODE_WRITABLE, data,
-                         (hb_destroy_func_t) free);
+                        (hb_destroy_func_t) free);
 
 fread_fail:
   fclose (fp);
@@ -676,3 +676,4 @@ fread_fail_without_close:
   free (data);
   return hb_blob_get_empty ();
 }
+#endif /* !HB_NO_OPEN */
index d1d9134..f80e9af 100644 (file)
@@ -71,6 +71,9 @@ hb_blob_create (const char        *data,
                void              *user_data,
                hb_destroy_func_t  destroy);
 
+HB_EXTERN hb_blob_t *
+hb_blob_create_from_file (const char *file_name);
+
 /* Always creates with MEMORY_MODE_READONLY.
  * Even if the parent blob is writable, we don't
  * want the user of the sub-blob to be able to
@@ -123,9 +126,6 @@ hb_blob_get_data (hb_blob_t *blob, unsigned int *length);
 HB_EXTERN char *
 hb_blob_get_data_writable (hb_blob_t *blob, unsigned int *length);
 
-HB_EXTERN hb_blob_t *
-hb_blob_create_from_file (const char *file_name);
-
 HB_END_DECLS
 
 #endif /* HB_BLOB_H */
index 4ea13f8..d85bd82 100644 (file)
@@ -54,13 +54,9 @@ struct hb_blob_t
   HB_INTERNAL bool try_make_writable_inplace ();
   HB_INTERNAL bool try_make_writable_inplace_unix ();
 
+  hb_bytes_t as_bytes () const { return hb_bytes_t (data, length); }
   template <typename Type>
-  const Type* as () const
-  {
-    return length < hb_null_size (Type) ? &Null(Type) : reinterpret_cast<const Type *> (data);
-  }
-  hb_bytes_t as_bytes () const
-  { return hb_bytes_t (data, length); }
+  const Type* as () const { return as_bytes ().as<Type> (); }
 
   public:
   hb_object_header_t header;
@@ -81,7 +77,7 @@ struct hb_blob_t
 template <typename P>
 struct hb_blob_ptr_t
 {
-  typedef typename hb_remove_pointer (P) T;
+  typedef hb_remove_pointer<P> T;
 
   hb_blob_ptr_t (hb_blob_t *b_ = nullptr) : b (b_) {}
   hb_blob_t * operator = (hb_blob_t *b_) { return b = b_; }
index 6e265e8..e64eb0e 100644 (file)
  * Google Author(s): Behdad Esfahbod
  */
 
+#include "hb.hh"
+
+#ifndef HB_NO_BUFFER_SERIALIZE
+
 #include "hb-buffer.hh"
 
 
@@ -85,7 +89,7 @@ hb_buffer_serialize_format_from_string (const char *str, int len)
 const char *
 hb_buffer_serialize_format_to_string (hb_buffer_serialize_format_t format)
 {
-  switch (format)
+  switch ((unsigned) format)
   {
     case HB_BUFFER_SERIALIZE_FORMAT_TEXT:      return serialize_formats[0];
     case HB_BUFFER_SERIALIZE_FORMAT_JSON:      return serialize_formats[1];
@@ -131,41 +135,41 @@ _hb_buffer_serialize_glyphs_json (hb_buffer_t *buffer,
       hb_font_glyph_to_string (font, info[i].codepoint, g, sizeof (g));
       *p++ = '"';
       for (char *q = g; *q; q++) {
-        if (*q == '"')
+       if (*q == '"')
          *p++ = '\\';
        *p++ = *q;
       }
       *p++ = '"';
     }
     else
-      p += MAX (0, snprintf (p, ARRAY_LENGTH (b) - (p - b), "%u", info[i].codepoint));
+      p += hb_max (0, snprintf (p, ARRAY_LENGTH (b) - (p - b), "%u", info[i].codepoint));
 
     if (!(flags & HB_BUFFER_SERIALIZE_FLAG_NO_CLUSTERS)) {
-      p += MAX (0, snprintf (p, ARRAY_LENGTH (b) - (p - b), ",\"cl\":%u", info[i].cluster));
+      p += hb_max (0, snprintf (p, ARRAY_LENGTH (b) - (p - b), ",\"cl\":%u", info[i].cluster));
     }
 
     if (!(flags & HB_BUFFER_SERIALIZE_FLAG_NO_POSITIONS))
     {
-      p += MAX (0, snprintf (p, ARRAY_LENGTH (b) - (p - b), ",\"dx\":%d,\"dy\":%d",
+      p += hb_max (0, snprintf (p, ARRAY_LENGTH (b) - (p - b), ",\"dx\":%d,\"dy\":%d",
                             x+pos[i].x_offset, y+pos[i].y_offset));
       if (!(flags & HB_BUFFER_SERIALIZE_FLAG_NO_ADVANCES))
-       p += MAX (0, snprintf (p, ARRAY_LENGTH (b) - (p - b), ",\"ax\":%d,\"ay\":%d",
+       p += hb_max (0, snprintf (p, ARRAY_LENGTH (b) - (p - b), ",\"ax\":%d,\"ay\":%d",
                               pos[i].x_advance, pos[i].y_advance));
     }
 
     if (flags & HB_BUFFER_SERIALIZE_FLAG_GLYPH_FLAGS)
     {
       if (info[i].mask & HB_GLYPH_FLAG_DEFINED)
-       p += MAX (0, snprintf (p, ARRAY_LENGTH (b) - (p - b), ",\"fl\":%u", info[i].mask & HB_GLYPH_FLAG_DEFINED));
+       p += hb_max (0, snprintf (p, ARRAY_LENGTH (b) - (p - b), ",\"fl\":%u", info[i].mask & HB_GLYPH_FLAG_DEFINED));
     }
 
     if (flags & HB_BUFFER_SERIALIZE_FLAG_GLYPH_EXTENTS)
     {
       hb_glyph_extents_t extents;
       hb_font_get_glyph_extents(font, info[i].codepoint, &extents);
-      p += MAX (0, snprintf (p, ARRAY_LENGTH (b) - (p - b), ",\"xb\":%d,\"yb\":%d",
+      p += hb_max (0, snprintf (p, ARRAY_LENGTH (b) - (p - b), ",\"xb\":%d,\"yb\":%d",
                extents.x_bearing, extents.y_bearing));
-      p += MAX (0, snprintf (p, ARRAY_LENGTH (b) - (p - b), ",\"w\":%d,\"h\":%d",
+      p += hb_max (0, snprintf (p, ARRAY_LENGTH (b) - (p - b), ",\"w\":%d,\"h\":%d",
                extents.width, extents.height));
     }
 
@@ -224,37 +228,37 @@ _hb_buffer_serialize_glyphs_text (hb_buffer_t *buffer,
       p += strlen (p);
     }
     else
-      p += MAX (0, snprintf (p, ARRAY_LENGTH (b) - (p - b), "%u", info[i].codepoint));
+      p += hb_max (0, snprintf (p, ARRAY_LENGTH (b) - (p - b), "%u", info[i].codepoint));
 
     if (!(flags & HB_BUFFER_SERIALIZE_FLAG_NO_CLUSTERS)) {
-      p += MAX (0, snprintf (p, ARRAY_LENGTH (b) - (p - b), "=%u", info[i].cluster));
+      p += hb_max (0, snprintf (p, ARRAY_LENGTH (b) - (p - b), "=%u", info[i].cluster));
     }
 
     if (!(flags & HB_BUFFER_SERIALIZE_FLAG_NO_POSITIONS))
     {
       if (x+pos[i].x_offset || y+pos[i].y_offset)
-       p += MAX (0, snprintf (p, ARRAY_LENGTH (b) - (p - b), "@%d,%d", x+pos[i].x_offset, y+pos[i].y_offset));
+       p += hb_max (0, snprintf (p, ARRAY_LENGTH (b) - (p - b), "@%d,%d", x+pos[i].x_offset, y+pos[i].y_offset));
 
       if (!(flags & HB_BUFFER_SERIALIZE_FLAG_NO_ADVANCES))
       {
        *p++ = '+';
-       p += MAX (0, snprintf (p, ARRAY_LENGTH (b) - (p - b), "%d", pos[i].x_advance));
+       p += hb_max (0, snprintf (p, ARRAY_LENGTH (b) - (p - b), "%d", pos[i].x_advance));
        if (pos[i].y_advance)
-         p += MAX (0, snprintf (p, ARRAY_LENGTH (b) - (p - b), ",%d", pos[i].y_advance));
+         p += hb_max (0, snprintf (p, ARRAY_LENGTH (b) - (p - b), ",%d", pos[i].y_advance));
       }
     }
 
     if (flags & HB_BUFFER_SERIALIZE_FLAG_GLYPH_FLAGS)
     {
       if (info[i].mask & HB_GLYPH_FLAG_DEFINED)
-       p += MAX (0, snprintf (p, ARRAY_LENGTH (b) - (p - b), "#%X", info[i].mask &HB_GLYPH_FLAG_DEFINED));
+       p += hb_max (0, snprintf (p, ARRAY_LENGTH (b) - (p - b), "#%X", info[i].mask &HB_GLYPH_FLAG_DEFINED));
     }
 
     if (flags & HB_BUFFER_SERIALIZE_FLAG_GLYPH_EXTENTS)
     {
       hb_glyph_extents_t extents;
       hb_font_get_glyph_extents(font, info[i].codepoint, &extents);
-      p += MAX (0, snprintf (p, ARRAY_LENGTH (b) - (p - b), "<%d,%d,%d,%d>", extents.x_bearing, extents.y_bearing, extents.width, extents.height));
+      p += hb_max (0, snprintf (p, ARRAY_LENGTH (b) - (p - b), "<%d,%d,%d,%d>", extents.x_bearing, extents.y_bearing, extents.width, extents.height));
     }
 
     unsigned int l = p - b;
@@ -375,43 +379,24 @@ hb_buffer_serialize_glyphs (hb_buffer_t *buffer,
   }
 }
 
-
-static hb_bool_t
-parse_uint (const char *pp, const char *end, uint32_t *pv)
+static bool
+parse_int (const char *pp, const char *end, int32_t *pv)
 {
-  char buf[32];
-  unsigned int len = MIN (ARRAY_LENGTH (buf) - 1, (unsigned int) (end - pp));
-  strncpy (buf, pp, len);
-  buf[len] = '\0';
-
-  char *p = buf;
-  char *pend = p;
-  uint32_t v;
-
-  errno = 0;
-  v = strtol (p, &pend, 10);
-  if (errno || p == pend || pend - p != end - pp)
+  int v;
+  const char *p = pp;
+  if (unlikely (!hb_parse_int (&p, end, &v, true/* whole buffer */)))
     return false;
 
   *pv = v;
   return true;
 }
 
-static hb_bool_t
-parse_int (const char *pp, const char *end, int32_t *pv)
+static bool
+parse_uint (const char *pp, const char *end, uint32_t *pv)
 {
-  char buf[32];
-  unsigned int len = MIN (ARRAY_LENGTH (buf) - 1, (unsigned int) (end - pp));
-  strncpy (buf, pp, len);
-  buf[len] = '\0';
-
-  char *p = buf;
-  char *pend = p;
-  int32_t v;
-
-  errno = 0;
-  v = strtol (p, &pend, 10);
-  if (errno || p == pend || pend - p != end - pp)
+  unsigned int v;
+  const char *p = pp;
+  if (unlikely (!hb_parse_uint (&p, end, &v, true/* whole buffer */)))
     return false;
 
   *pv = v;
@@ -484,3 +469,6 @@ hb_buffer_deserialize_glyphs (hb_buffer_t *buffer,
 
   }
 }
+
+
+#endif
index 2dc02e9..6131c86 100644 (file)
@@ -324,7 +324,7 @@ hb_buffer_t::clear_positions ()
   out_len = 0;
   out_info = info;
 
-  memset (pos, 0, sizeof (pos[0]) * len);
+  hb_memset (pos, 0, sizeof (pos[0]) * len);
 }
 
 void
@@ -524,7 +524,7 @@ hb_buffer_t::merge_clusters_impl (unsigned int start,
   unsigned int cluster = info[start].cluster;
 
   for (unsigned int i = start + 1; i < end; i++)
-    cluster = MIN<unsigned int> (cluster, info[i].cluster);
+    cluster = hb_min (cluster, info[i].cluster);
 
   /* Extend end */
   while (end < len && info[end - 1].cluster == info[end].cluster)
@@ -555,7 +555,7 @@ hb_buffer_t::merge_out_clusters (unsigned int start,
   unsigned int cluster = out_info[start].cluster;
 
   for (unsigned int i = start + 1; i < end; i++)
-    cluster = MIN<unsigned int> (cluster, out_info[i].cluster);
+    cluster = hb_min (cluster, out_info[i].cluster);
 
   /* Extend start */
   while (start && out_info[start - 1].cluster == out_info[start].cluster)
@@ -648,8 +648,8 @@ hb_buffer_t::guess_segment_properties ()
       if (likely (script != HB_SCRIPT_COMMON &&
                  script != HB_SCRIPT_INHERITED &&
                  script != HB_SCRIPT_UNKNOWN)) {
-        props.script = script;
-        break;
+       props.script = script;
+       break;
       }
     }
   }
@@ -776,8 +776,10 @@ hb_buffer_destroy (hb_buffer_t *buffer)
 
   free (buffer->info);
   free (buffer->pos);
+#ifndef HB_NO_BUFFER_MESSAGE
   if (buffer->message_destroy)
     buffer->message_destroy (buffer->message_data);
+#endif
 
   free (buffer);
 }
@@ -1388,7 +1390,7 @@ hb_buffer_get_length (hb_buffer_t *buffer)
  **/
 hb_glyph_info_t *
 hb_buffer_get_glyph_infos (hb_buffer_t  *buffer,
-                           unsigned int *length)
+                          unsigned int *length)
 {
   if (length)
     *length = buffer->len;
@@ -1412,7 +1414,7 @@ hb_buffer_get_glyph_infos (hb_buffer_t  *buffer,
  **/
 hb_glyph_position_t *
 hb_buffer_get_glyph_positions (hb_buffer_t  *buffer,
-                               unsigned int *length)
+                              unsigned int *length)
 {
   if (!buffer->have_positions)
     buffer->clear_positions ();
@@ -1936,9 +1938,9 @@ hb_buffer_diff (hb_buffer_t *buffer,
     for (i = 0; i < count; i++)
     {
       if (contains && info[i].codepoint == dottedcircle_glyph)
-        result |= HB_BUFFER_DIFF_FLAG_DOTTED_CIRCLE_PRESENT;
+       result |= HB_BUFFER_DIFF_FLAG_DOTTED_CIRCLE_PRESENT;
       if (contains && info[i].codepoint == 0)
-        result |= HB_BUFFER_DIFF_FLAG_NOTDEF_PRESENT;
+       result |= HB_BUFFER_DIFF_FLAG_NOTDEF_PRESENT;
     }
     result |= HB_BUFFER_DIFF_FLAG_LENGTH_MISMATCH;
     return hb_buffer_diff_flags_t (result);
@@ -1973,12 +1975,12 @@ hb_buffer_diff (hb_buffer_t *buffer,
     for (unsigned int i = 0; i < count; i++)
     {
       if ((unsigned int) abs (buf_pos->x_advance - ref_pos->x_advance) > position_fuzz ||
-          (unsigned int) abs (buf_pos->y_advance - ref_pos->y_advance) > position_fuzz ||
-          (unsigned int) abs (buf_pos->x_offset - ref_pos->x_offset) > position_fuzz ||
-          (unsigned int) abs (buf_pos->y_offset - ref_pos->y_offset) > position_fuzz)
+         (unsigned int) abs (buf_pos->y_advance - ref_pos->y_advance) > position_fuzz ||
+         (unsigned int) abs (buf_pos->x_offset - ref_pos->x_offset) > position_fuzz ||
+         (unsigned int) abs (buf_pos->y_offset - ref_pos->y_offset) > position_fuzz)
       {
-        result |= HB_BUFFER_DIFF_FLAG_POSITION_MISMATCH;
-        break;
+       result |= HB_BUFFER_DIFF_FLAG_POSITION_MISMATCH;
+       break;
       }
       buf_pos++;
       ref_pos++;
@@ -1993,6 +1995,7 @@ hb_buffer_diff (hb_buffer_t *buffer,
  * Debugging.
  */
 
+#ifndef HB_NO_BUFFER_MESSAGE
 /**
  * hb_buffer_set_message_func:
  * @buffer: an #hb_buffer_t.
@@ -2022,11 +2025,11 @@ hb_buffer_set_message_func (hb_buffer_t *buffer,
     buffer->message_destroy = nullptr;
   }
 }
-
 bool
 hb_buffer_t::message_impl (hb_font_t *font, const char *fmt, va_list ap)
 {
   char buf[100];
-  vsnprintf (buf, sizeof (buf),  fmt, ap);
+  vsnprintf (buf, sizeof (buf), fmt, ap);
   return (bool) this->message_func (this, font, buf, this->message_data);
 }
+#endif
index ac1d452..d5cb746 100644 (file)
@@ -441,11 +441,11 @@ hb_buffer_get_length (hb_buffer_t *buffer);
 
 HB_EXTERN hb_glyph_info_t *
 hb_buffer_get_glyph_infos (hb_buffer_t  *buffer,
-                           unsigned int *length);
+                          unsigned int *length);
 
 HB_EXTERN hb_glyph_position_t *
 hb_buffer_get_glyph_positions (hb_buffer_t  *buffer,
-                               unsigned int *length);
+                              unsigned int *length);
 
 
 HB_EXTERN void
index 330f88b..b5596d9 100644 (file)
@@ -124,9 +124,11 @@ struct hb_buffer_t
   unsigned int context_len[2];
 
   /* Debugging API */
+#ifndef HB_NO_BUFFER_MESSAGE
   hb_buffer_message_func_t message_func;
   void *message_data;
   hb_destroy_func_t message_destroy;
+#endif
 
   /* Internal debugging. */
   /* The bits here reflect current allocations of the bytes in glyph_info_t's var1 and var2. */
@@ -347,9 +349,19 @@ struct hb_buffer_t
 
   HB_INTERNAL void sort (unsigned int start, unsigned int end, int(*compar)(const hb_glyph_info_t *, const hb_glyph_info_t *));
 
-  bool messaging () { return unlikely (message_func); }
+  bool messaging ()
+  {
+#ifdef HB_NO_BUFFER_MESSAGE
+    return false;
+#else
+    return unlikely (message_func);
+#endif
+  }
   bool message (hb_font_t *font, const char *fmt, ...) HB_PRINTF_FUNC(3, 4)
   {
+#ifdef HB_NO_BUFFER_MESSAGE
+   return true;
+#else
     if (!messaging ())
       return true;
     va_list ap;
@@ -357,6 +369,7 @@ struct hb_buffer_t
     bool ret = message_impl (font, fmt, ap);
     va_end (ap);
     return ret;
+#endif
   }
   HB_INTERNAL bool message_impl (hb_font_t *font, const char *fmt, va_list ap) HB_PRINTF_FUNC(3, 0);
 
@@ -379,7 +392,7 @@ struct hb_buffer_t
                                     unsigned int cluster) const
   {
     for (unsigned int i = start; i < end; i++)
-      cluster = MIN<unsigned int> (cluster, infos[i].cluster);
+      cluster = hb_min (cluster, infos[i].cluster);
     return cluster;
   }
   void
@@ -395,8 +408,7 @@ struct hb_buffer_t
       }
   }
 
-  void unsafe_to_break_all ()
-  { unsafe_to_break_impl (0, len); }
+  void unsafe_to_break_all () { unsafe_to_break_impl (0, len); }
   void safe_to_break_all ()
   {
     for (unsigned int i = 0; i < len; i++)
index 72e9e06..780f618 100644 (file)
@@ -220,32 +220,22 @@ struct number_t
   void init () { set_real (0.0); }
   void fini () {}
 
-  void set_int (int v)       { value = (double) v; }
-  int to_int () const        { return (int) value; }
+  void set_int (int v)       { value = v; }
+  int to_int () const        { return value; }
 
   void set_fixed (int32_t v) { value = v / 65536.0; }
-  int32_t to_fixed () const  { return (int32_t) (value * 65536.0); }
+  int32_t to_fixed () const  { return value * 65536.0; }
 
-  void set_real (double v)      { value = v; }
+  void set_real (double v)   { value = v; }
   double to_real () const    { return value; }
 
-  int ceil () const          { return (int) ::ceil (value); }
-  int floor () const         { return (int) ::floor (value); }
-
   bool in_int_range () const
   { return ((double) (int16_t) to_int () == value); }
 
-  bool operator > (const number_t &n) const
-  { return value > n.to_real (); }
-
-  bool operator < (const number_t &n) const
-  { return n > *this; }
-
-  bool operator >= (const number_t &n) const
-  { return !(*this < n); }
-
-  bool operator <= (const number_t &n) const
-  { return !(*this > n); }
+  bool operator >  (const number_t &n) const { return value > n.to_real (); }
+  bool operator <  (const number_t &n) const { return n > *this; }
+  bool operator >= (const number_t &n) const { return !(*this < n); }
+  bool operator <= (const number_t &n) const { return !(*this > n); }
 
   const number_t &operator += (const number_t &n)
   {
@@ -255,7 +245,7 @@ struct number_t
   }
 
   protected:
-  double  value;
+  double value;
 };
 
 /* byte string */
@@ -272,11 +262,11 @@ struct UnsizedByteStr : UnsizedArrayOf <HBUINT8>
 
     HBUINT8 *p = c->allocate_size<HBUINT8> (1);
     if (unlikely (p == nullptr)) return_trace (false);
-    p->set (intOp);
+    *p = intOp;
 
     INTTYPE *ip = c->allocate_size<INTTYPE> (INTTYPE::static_size);
     if (unlikely (ip == nullptr)) return_trace (false);
-    ip->set ((unsigned int)value);
+    *ip = (unsigned int) value;
 
     return_trace (true);
   }
@@ -308,7 +298,7 @@ struct byte_str_t : hb_ubytes_t
     : hb_ubytes_t (s, l) {}
   byte_str_t (const hb_ubytes_t &ub)   /* conversion from hb_ubytes_t */
     : hb_ubytes_t (ub) {}
-  
+
   /* sub-string */
   byte_str_t sub_str (unsigned int offset, unsigned int len_) const
   { return byte_str_t (hb_ubytes_t::sub_array (offset, len_)); }
@@ -320,8 +310,7 @@ struct byte_str_t : hb_ubytes_t
 /* A byte string associated with the current offset and an error condition */
 struct byte_str_ref_t
 {
-  byte_str_ref_t ()
-  { init (); }
+  byte_str_ref_t () { init (); }
 
   void init ()
   {
@@ -343,13 +332,12 @@ struct byte_str_ref_t
   }
 
   const unsigned char& operator [] (int i) {
-    if (unlikely ((unsigned int)(offset + i) >= str.length))
+    if (unlikely ((unsigned int) (offset + i) >= str.length))
     {
       set_error ();
-      return Null(unsigned char);
+      return Null (unsigned char);
     }
-    else
-      return str[offset + i];
+    return str[offset + i];
   }
 
   /* Conversion to byte_str_t */
@@ -359,9 +347,7 @@ struct byte_str_ref_t
   { return str.sub_str (offset_, len_); }
 
   bool avail (unsigned int count=1) const
-  {
-    return (!in_error () && str.check_limit (offset, count));
-  }
+  { return (!in_error () && str.check_limit (offset, count)); }
   void inc (unsigned int count=1)
   {
     if (likely (!in_error () && (offset <= str.length) && (offset + count <= str.length)))
@@ -389,7 +375,7 @@ typedef hb_vector_t<byte_str_t> byte_str_array_t;
 
 /* stack */
 template <typename ELEM, int LIMIT>
-struct stack_t
+struct cff_stack_t
 {
   void init ()
   {
@@ -400,11 +386,7 @@ struct stack_t
     for (unsigned int i = 0; i < elements.length; i++)
       elements[i].init ();
   }
-
-  void fini ()
-  {
-    elements.fini_deep ();
-  }
+  void fini () { elements.fini_deep (); }
 
   ELEM& operator [] (unsigned int i)
   {
@@ -419,7 +401,6 @@ struct stack_t
     else
       set_error ();
   }
-
   ELEM &push ()
   {
     if (likely (count < elements.length))
@@ -441,7 +422,6 @@ struct stack_t
       return Crap(ELEM);
     }
   }
-
   void pop (unsigned int n)
   {
     if (likely (count >= n))
@@ -452,13 +432,12 @@ struct stack_t
 
   const ELEM& peek ()
   {
-    if (likely (count > 0))
-      return elements[count-1];
-    else
+    if (unlikely (count < 0))
     {
       set_error ();
       return Null(ELEM);
     }
+    return elements[count - 1];
   }
 
   void unpop ()
@@ -475,7 +454,7 @@ struct stack_t
   void set_error ()      { error = true; }
 
   unsigned int get_count () const { return count; }
-  bool is_empty () const { return count == 0; }
+  bool is_empty () const          { return !count; }
 
   static constexpr unsigned kSizeLimit = LIMIT;
 
@@ -487,7 +466,7 @@ struct stack_t
 
 /* argument stack */
 template <typename ARG=number_t>
-struct arg_stack_t : stack_t<ARG, 513>
+struct arg_stack_t : cff_stack_t<ARG, 513>
 {
   void push_int (int v)
   {
@@ -519,7 +498,7 @@ struct arg_stack_t : stack_t<ARG, 513>
       i = 0;
       S::set_error ();
     }
-    return (unsigned)i;
+    return (unsigned) i;
   }
 
   void push_longint_from_substr (byte_str_ref_t& str_ref)
@@ -538,12 +517,10 @@ struct arg_stack_t : stack_t<ARG, 513>
   }
 
   hb_array_t<const ARG> get_subarray (unsigned int start) const
-  {
-    return S::elements.sub_array (start);
-  }
+  { return S::elements.sub_array (start); }
 
   private:
-  typedef stack_t<ARG, 513> S;
+  typedef cff_stack_t<ARG, 513> S;
 };
 
 /* an operator prefixed by its operands in a byte string */
@@ -605,7 +582,7 @@ struct parsed_values_t
   }
 
   unsigned get_count () const { return values.length; }
-  const VAL &get_value (unsigned int i) const { return values[i]; }
+  const VAL &get_value (unsigned int i)   const { return values[i]; }
   const VAL &operator [] (unsigned int i) const { return get_value (i); }
 
   unsigned int       opStart;
@@ -644,30 +621,19 @@ struct interp_env_t
     return op;
   }
 
-  const ARG& eval_arg (unsigned int i)
-  {
-    return argStack[i];
-  }
-
-  ARG& pop_arg ()
-  {
-    return argStack.pop ();
-  }
+  const ARG& eval_arg (unsigned int i) { return argStack[i]; }
 
-  void pop_n_args (unsigned int n)
-  {
-    argStack.pop (n);
-  }
+  ARG& pop_arg () { return argStack.pop (); }
+  void pop_n_args (unsigned int n) { argStack.pop (n); }
 
-  void clear_args ()
-  {
-    pop_n_args (argStack.get_count ());
-  }
+  void clear_args () { pop_n_args (argStack.get_count ()); }
 
-  byte_str_ref_t    str_ref;
-  arg_stack_t<ARG> argStack;
+  byte_str_ref_t
+               str_ref;
+  arg_stack_t<ARG>
+               argStack;
   protected:
-  bool   error;
+  bool         error;
 };
 
 typedef interp_env_t<> num_interp_env_t;
@@ -691,7 +657,7 @@ struct opset_t
 
       case OpCode_TwoByteNegInt0: case OpCode_TwoByteNegInt1:
       case OpCode_TwoByteNegInt2: case OpCode_TwoByteNegInt3:
-       env.argStack.push_int ((int16_t)(-(op - OpCode_TwoByteNegInt0) * 256 - env.str_ref[0] - 108));
+       env.argStack.push_int ((-(int16_t)(op - OpCode_TwoByteNegInt0) * 256 - env.str_ref[0] - 108));
        env.str_ref.inc ();
        break;
 
@@ -711,8 +677,8 @@ struct opset_t
 };
 
 template <typename ENV>
-struct interpreter_t {
-
+struct interpreter_t
+{
   ~interpreter_t() { fini (); }
 
   void fini () { env.fini (); }
index 283bdf1..d9ad4d0 100644 (file)
@@ -57,14 +57,14 @@ struct call_context_t
 
 /* call stack */
 const unsigned int kMaxCallLimit = 10;
-struct call_stack_t : stack_t<call_context_t, kMaxCallLimit> {};
+struct call_stack_t : cff_stack_t<call_context_t, kMaxCallLimit> {};
 
 template <typename SUBRS>
 struct biased_subrs_t
 {
-  void init (const SUBRS &subrs_)
+  void init (const SUBRS *subrs_)
   {
-    subrs = &subrs_;
+    subrs = subrs_;
     unsigned int  nSubrs = get_count ();
     if (nSubrs < 1240)
       bias = 107;
@@ -76,8 +76,8 @@ struct biased_subrs_t
 
   void fini () {}
 
-  unsigned int get_count () const { return (subrs == nullptr)? 0: subrs->count; }
-  unsigned int get_bias () const { return bias; }
+  unsigned int get_count () const { return (subrs == nullptr) ? 0 : subrs->count; }
+  unsigned int get_bias () const  { return bias; }
 
   byte_str_t operator [] (unsigned int index) const
   {
@@ -118,7 +118,7 @@ struct point_t
 template <typename ARG, typename SUBRS>
 struct cs_interp_env_t : interp_env_t<ARG>
 {
-  void init (const byte_str_t &str, const SUBRS &globalSubrs_, const SUBRS &localSubrs_)
+  void init (const byte_str_t &str, const SUBRS *globalSubrs_, const SUBRS *localSubrs_)
   {
     interp_env_t<ARG>::init (str);
 
@@ -147,8 +147,9 @@ struct cs_interp_env_t : interp_env_t<ARG>
     return callStack.in_error () || SUPER::in_error ();
   }
 
-  bool popSubrNum (const biased_subrs_t<SUBRS>& biasedSubrs, unsigned int &subr_num)
+  bool pop_subr_num (const biased_subrs_t<SUBRS>& biasedSubrs, unsigned int &subr_num)
   {
+    subr_num = 0;
     int n = SUPER::argStack.pop_int ();
     n += biasedSubrs.get_bias ();
     if (unlikely ((n < 0) || ((unsigned int)n >= biasedSubrs.get_count ())))
@@ -158,11 +159,11 @@ struct cs_interp_env_t : interp_env_t<ARG>
     return true;
   }
 
-  void callSubr (const biased_subrs_t<SUBRS>& biasedSubrs, cs_type_t type)
+  void call_subr (const biased_subrs_t<SUBRS>& biasedSubrs, cs_type_t type)
   {
-    unsigned int subr_num;
+    unsigned int subr_num = 0;
 
-    if (unlikely (!popSubrNum (biasedSubrs, subr_num)
+    if (unlikely (!pop_subr_num (biasedSubrs, subr_num)
                 || callStack.get_count () >= kMaxCallLimit))
     {
       SUPER::set_error ();
@@ -175,7 +176,7 @@ struct cs_interp_env_t : interp_env_t<ARG>
     SUPER::str_ref = context.str_ref;
   }
 
-  void returnFromSubr ()
+  void return_from_subr ()
   {
     if (unlikely (SUPER::str_ref.in_error ()))
       SUPER::set_error ();
@@ -246,7 +247,7 @@ struct path_procs_null_t
   static void flex1 (ENV &env, PARAM& param) {}
 };
 
-template <typename ARG, typename OPSET, typename ENV, typename PARAM, typename PATH=path_procs_null_t<ENV, PARAM> >
+template <typename ARG, typename OPSET, typename ENV, typename PARAM, typename PATH=path_procs_null_t<ENV, PARAM>>
 struct cs_opset_t : opset_t<ARG>
 {
   static void process_op (op_code_t op, ENV &env, PARAM& param)
@@ -254,7 +255,7 @@ struct cs_opset_t : opset_t<ARG>
     switch (op) {
 
       case OpCode_return:
-       env.returnFromSubr ();
+       env.return_from_subr ();
        break;
       case OpCode_endchar:
        OPSET::check_width (op, env, param);
@@ -267,11 +268,11 @@ struct cs_opset_t : opset_t<ARG>
        break;
 
       case OpCode_callsubr:
-       env.callSubr (env.localSubrs, CSType_LocalSubr);
+       env.call_subr (env.localSubrs, CSType_LocalSubr);
        break;
 
       case OpCode_callgsubr:
-       env.callSubr (env.globalSubrs, CSType_GlobalSubr);
+       env.call_subr (env.globalSubrs, CSType_GlobalSubr);
        break;
 
       case OpCode_hstem:
index 2c54909..1f03d82 100644 (file)
@@ -94,130 +94,52 @@ struct dict_opset_t : opset_t<number_t>
     }
   }
 
+  /* Turns CFF's BCD format into strtod understandable string */
   static double parse_bcd (byte_str_ref_t& str_ref)
   {
-    bool    neg = false;
-    double  int_part = 0;
-    uint64_t frac_part = 0;
-    uint32_t  frac_count = 0;
-    bool    exp_neg = false;
-    uint32_t  exp_part = 0;
-    bool    exp_overflow = false;
-    enum Part { INT_PART=0, FRAC_PART, EXP_PART } part = INT_PART;
+    if (unlikely (str_ref.in_error ())) return .0;
+
     enum Nibble { DECIMAL=10, EXP_POS, EXP_NEG, RESERVED, NEG, END };
-    const uint64_t MAX_FRACT = 0xFFFFFFFFFFFFFull; /* 1^52-1 */
-    const uint32_t MAX_EXP = 0x7FFu; /* 1^11-1 */
 
-    double  value = 0.0;
+    char buf[32];
     unsigned char byte = 0;
-    for (uint32_t i = 0;; i++)
+    for (unsigned i = 0, count = 0; count < ARRAY_LENGTH (buf); ++i, ++count)
     {
-      char d;
-      if ((i & 1) == 0)
+      unsigned nibble;
+      if (!(i & 1))
       {
-       if (!str_ref.avail ())
-       {
-         str_ref.set_error ();
-         return 0.0;
-       }
+       if (unlikely (!str_ref.avail ())) break;
+
        byte = str_ref[0];
        str_ref.inc ();
-       d = byte >> 4;
+       nibble = byte >> 4;
       }
       else
-       d = byte & 0x0F;
+       nibble = byte & 0x0F;
 
-      switch (d)
+      if (unlikely (nibble == RESERVED)) break;
+      else if (nibble == END)
       {
-       case RESERVED:
-         str_ref.set_error ();
-         return value;
-
-       case END:
-         value = (double)(neg? -int_part: int_part);
-         if (frac_count > 0)
-         {
-           double frac = (frac_part / pow (10.0, (double)frac_count));
-           if (neg) frac = -frac;
-           value += frac;
-         }
-         if (unlikely (exp_overflow))
-         {
-           if (value == 0.0)
-             return value;
-           if (exp_neg)
-             return neg? -DBL_MIN: DBL_MIN;
-           else
-             return neg? -DBL_MAX: DBL_MAX;
-         }
-         if (exp_part != 0)
-         {
-           if (exp_neg)
-             value /= pow (10.0, (double)exp_part);
-           else
-             value *= pow (10.0, (double)exp_part);
-         }
-         return value;
-
-       case NEG:
-         if (i != 0)
-         {
-           str_ref.set_error ();
-           return 0.0;
-         }
-         neg = true;
-         break;
-
-       case DECIMAL:
-         if (part != INT_PART)
-         {
-           str_ref.set_error ();
-           return value;
-         }
-         part = FRAC_PART;
+       const char *p = buf;
+       double pv;
+       if (unlikely (!hb_parse_double (&p, p + count, &pv, true/* whole buffer */)))
          break;
-
-       case EXP_NEG:
-         exp_neg = true;
-         HB_FALLTHROUGH;
-
-       case EXP_POS:
-         if (part == EXP_PART)
-         {
-           str_ref.set_error ();
-           return value;
-         }
-         part = EXP_PART;
-         break;
-
-       default:
-         switch (part) {
-           default:
-           case INT_PART:
-             int_part = (int_part * 10) + d;
-             break;
-
-           case FRAC_PART:
-             if (likely (frac_part <= MAX_FRACT / 10))
-             {
-               frac_part = (frac_part * 10) + (unsigned)d;
-               frac_count++;
-             }
-             break;
-
-           case EXP_PART:
-             if (likely (exp_part * 10 + d <= MAX_EXP))
-             {
-               exp_part = (exp_part * 10) + d;
-             }
-             else
-               exp_overflow = true;
-             break;
-         }
+       return pv;
+      }
+      else
+      {
+       buf[count] = "0123456789.EE?-?"[nibble];
+       if (nibble == EXP_NEG)
+       {
+         ++count;
+         if (unlikely (count == ARRAY_LENGTH (buf))) break;
+         buf[count] = '-';
+       }
       }
     }
 
-    return value;
+    str_ref.set_error ();
+    return .0;
   }
 
   static bool is_hint_op (op_code_t op)
index c7209ed..1c8762c 100644 (file)
@@ -40,7 +40,7 @@ struct cff1_cs_interp_env_t : cs_interp_env_t<number_t, CFF1Subrs>
   template <typename ACC>
   void init (const byte_str_t &str, ACC &acc, unsigned int fd)
   {
-    SUPER::init (str, *acc.globalSubrs, *acc.privateDicts[fd].localSubrs);
+    SUPER::init (str, acc.globalSubrs, acc.privateDicts[fd].localSubrs);
     processed_width = false;
     has_width = false;
     arg_start = 0;
@@ -81,7 +81,7 @@ struct cff1_cs_interp_env_t : cs_interp_env_t<number_t, CFF1Subrs>
   typedef cs_interp_env_t<number_t, CFF1Subrs> SUPER;
 };
 
-template <typename OPSET, typename PARAM, typename PATH=path_procs_null_t<cff1_cs_interp_env_t, PARAM> >
+template <typename OPSET, typename PARAM, typename PATH=path_procs_null_t<cff1_cs_interp_env_t, PARAM>>
 struct cff1_cs_opset_t : cs_opset_t<number_t, OPSET, cff1_cs_interp_env_t, PARAM, PATH>
 {
   /* PostScript-originated legacy opcodes (OpCode_add etc) are unsupported */
index 49e5ee7..a72100e 100644 (file)
@@ -82,7 +82,7 @@ struct cff2_cs_interp_env_t : cs_interp_env_t<blend_arg_t, CFF2Subrs>
   void init (const byte_str_t &str, ACC &acc, unsigned int fd,
                    const int *coords_=nullptr, unsigned int num_coords_=0)
   {
-    SUPER::init (str, *acc.globalSubrs, *acc.privateDicts[fd].localSubrs);
+    SUPER::init (str, acc.globalSubrs, acc.privateDicts[fd].localSubrs);
 
     coords = coords_;
     num_coords = num_coords_;
@@ -193,7 +193,7 @@ struct cff2_cs_interp_env_t : cs_interp_env_t<blend_arg_t, CFF2Subrs>
 
   typedef cs_interp_env_t<blend_arg_t, CFF2Subrs> SUPER;
 };
-template <typename OPSET, typename PARAM, typename PATH=path_procs_null_t<cff2_cs_interp_env_t, PARAM> >
+template <typename OPSET, typename PARAM, typename PATH=path_procs_null_t<cff2_cs_interp_env_t, PARAM>>
 struct cff2_cs_opset_t : cs_opset_t<blend_arg_t, OPSET, cff2_cs_interp_env_t, PARAM, PATH>
 {
   static void process_op (op_code_t op, cff2_cs_interp_env_t &env, PARAM& param)
index ab93bf4..0ae0c05 100644 (file)
  */
 
 #include "hb.hh"
-
 #include "hb-machinery.hh"
 
 #include <locale.h>
-#ifdef HAVE_XLOCALE_H
-#include <xlocale.h>
-#endif
 
+#ifdef HB_NO_SETLOCALE
+#define setlocale(Category, Locale) "C"
+#endif
 
 /**
  * SECTION:hb-common
@@ -64,10 +63,10 @@ _hb_options_init ()
     {
       const char *p = strchr (c, ':');
       if (!p)
-        p = c + strlen (c);
+       p = c + strlen (c);
 
 #define OPTION(name, symbol) \
-       if (0 == strncmp (c, name, p - c) && strlen (name) == p - c) u.opts.symbol = true;
+       if (0 == strncmp (c, name, p - c) && strlen (name) == static_cast<size_t>(p - c)) do { u.opts.symbol = true; } while (0)
 
       OPTION ("uniscribe-bug-compatible", uniscribe_bug_compatible);
       OPTION ("aat", aat);
@@ -356,7 +355,7 @@ hb_language_from_string (const char *str, int len)
   {
     /* NUL-terminate it. */
     char strbuf[64];
-    len = MIN (len, (int) sizeof (strbuf) - 1);
+    len = hb_min (len, (int) sizeof (strbuf) - 1);
     memcpy (strbuf, str, len);
     strbuf[len] = '\0';
     item = lang_find_or_insert (strbuf);
@@ -382,7 +381,8 @@ hb_language_from_string (const char *str, int len)
 const char *
 hb_language_to_string (hb_language_t language)
 {
-  /* This is actually nullptr-safe! */
+  if (unlikely (!language)) return nullptr;
+
   return language->s;
 }
 
@@ -488,7 +488,7 @@ hb_script_from_string (const char *str, int len)
 
 /**
  * hb_script_to_iso15924_tag:
- * @script: an #hb_script_ to convert.
+ * @script: an #hb_script_t to convert.
  *
  * See hb_script_from_iso15924_tag().
  *
@@ -719,131 +719,24 @@ parse_char (const char **pp, const char *end, char c)
 static bool
 parse_uint (const char **pp, const char *end, unsigned int *pv)
 {
-  char buf[32];
-  unsigned int len = MIN (ARRAY_LENGTH (buf) - 1, (unsigned int) (end - *pp));
-  strncpy (buf, *pp, len);
-  buf[len] = '\0';
-
-  char *p = buf;
-  char *pend = p;
-  unsigned int v;
-
-  /* Intentionally use strtol instead of strtoul, such that
-   * -1 turns into "big number"... */
-  errno = 0;
-  v = strtol (p, &pend, 10);
-  if (errno || p == pend)
-    return false;
+  /* Intentionally use hb_parse_int inside instead of hb_parse_uint,
+   * such that -1 turns into "big number"... */
+  int v;
+  if (unlikely (!hb_parse_int (pp, end, &v))) return false;
 
   *pv = v;
-  *pp += pend - p;
   return true;
 }
 
 static bool
 parse_uint32 (const char **pp, const char *end, uint32_t *pv)
 {
-  char buf[32];
-  unsigned int len = MIN (ARRAY_LENGTH (buf) - 1, (unsigned int) (end - *pp));
-  strncpy (buf, *pp, len);
-  buf[len] = '\0';
-
-  char *p = buf;
-  char *pend = p;
-  unsigned int v;
-
-  /* Intentionally use strtol instead of strtoul, such that
-   * -1 turns into "big number"... */
-  errno = 0;
-  v = strtol (p, &pend, 10);
-  if (errno || p == pend)
-    return false;
-
-  *pv = v;
-  *pp += pend - p;
-  return true;
-}
-
-#if defined (HAVE_NEWLOCALE) && defined (HAVE_STRTOD_L)
-#define USE_XLOCALE 1
-#define HB_LOCALE_T locale_t
-#define HB_CREATE_LOCALE(locName) newlocale (LC_ALL_MASK, locName, nullptr)
-#define HB_FREE_LOCALE(loc) freelocale (loc)
-#elif defined(_MSC_VER)
-#define USE_XLOCALE 1
-#define HB_LOCALE_T _locale_t
-#define HB_CREATE_LOCALE(locName) _create_locale (LC_ALL, locName)
-#define HB_FREE_LOCALE(loc) _free_locale (loc)
-#define strtod_l(a, b, c) _strtod_l ((a), (b), (c))
-#endif
-
-#ifdef USE_XLOCALE
-
-#if HB_USE_ATEXIT
-static void free_static_C_locale ();
-#endif
-
-static struct hb_C_locale_lazy_loader_t : hb_lazy_loader_t<hb_remove_pointer (HB_LOCALE_T),
-                                                         hb_C_locale_lazy_loader_t>
-{
-  static HB_LOCALE_T create ()
-  {
-    HB_LOCALE_T C_locale = HB_CREATE_LOCALE ("C");
-
-#if HB_USE_ATEXIT
-    atexit (free_static_C_locale);
-#endif
-
-    return C_locale;
-  }
-  static void destroy (HB_LOCALE_T p)
-  {
-    HB_FREE_LOCALE (p);
-  }
-  static HB_LOCALE_T get_null ()
-  {
-    return nullptr;
-  }
-} static_C_locale;
-
-#if HB_USE_ATEXIT
-static
-void free_static_C_locale ()
-{
-  static_C_locale.free_instance ();
-}
-#endif
-
-static HB_LOCALE_T
-get_C_locale ()
-{
-  return static_C_locale.get_unconst ();
-}
-#endif /* USE_XLOCALE */
-
-static bool
-parse_float (const char **pp, const char *end, float *pv)
-{
-  char buf[32];
-  unsigned int len = MIN (ARRAY_LENGTH (buf) - 1, (unsigned int) (end - *pp));
-  strncpy (buf, *pp, len);
-  buf[len] = '\0';
-
-  char *p = buf;
-  char *pend = p;
-  float v;
-
-  errno = 0;
-#ifdef USE_XLOCALE
-  v = strtod_l (p, &pend, get_C_locale ());
-#else
-  v = strtod (p, &pend);
-#endif
-  if (errno || p == pend)
-    return false;
+  /* Intentionally use hb_parse_int inside instead of hb_parse_uint,
+   * such that -1 turns into "big number"... */
+  int v;
+  if (unlikely (!hb_parse_int (pp, end, &v))) return false;
 
   *pv = v;
-  *pp += pend - p;
   return true;
 }
 
@@ -953,7 +846,7 @@ parse_feature_value_postfix (const char **pp, const char *end, hb_feature_t *fea
 {
   bool had_equal = parse_char (pp, end, '=');
   bool had_value = parse_uint32 (pp, end, &feature->value) ||
-                   parse_bool (pp, end, &feature->value);
+                  parse_bool (pp, end, &feature->value);
   /* CSS doesn't use equal-sign between tag and value.
    * If there was an equal-sign, then there *must* be a value.
    * A value without an equal-sign is ok, but not required. */
@@ -1071,21 +964,21 @@ hb_feature_to_string (hb_feature_t *feature,
   {
     s[len++] = '[';
     if (feature->start)
-      len += MAX (0, snprintf (s + len, ARRAY_LENGTH (s) - len, "%u", feature->start));
+      len += hb_max (0, snprintf (s + len, ARRAY_LENGTH (s) - len, "%u", feature->start));
     if (feature->end != feature->start + 1) {
       s[len++] = ':';
       if (feature->end != (unsigned int) -1)
-       len += MAX (0, snprintf (s + len, ARRAY_LENGTH (s) - len, "%u", feature->end));
+       len += hb_max (0, snprintf (s + len, ARRAY_LENGTH (s) - len, "%u", feature->end));
     }
     s[len++] = ']';
   }
   if (feature->value > 1)
   {
     s[len++] = '=';
-    len += MAX (0, snprintf (s + len, ARRAY_LENGTH (s) - len, "%u", feature->value));
+    len += hb_max (0, snprintf (s + len, ARRAY_LENGTH (s) - len, "%u", feature->value));
   }
   assert (len < ARRAY_LENGTH (s));
-  len = MIN (len, size - 1);
+  len = hb_min (len, size - 1);
   memcpy (buf, s, len);
   buf[len] = '\0';
 }
@@ -1096,7 +989,11 @@ static bool
 parse_variation_value (const char **pp, const char *end, hb_variation_t *variation)
 {
   parse_char (pp, end, '='); /* Optional. */
-  return parse_float (pp, end, &variation->value);
+  double v;
+  if (unlikely (!hb_parse_double (pp, end, &v))) return false;
+
+  variation->value = v;
+  return true;
 }
 
 static bool
@@ -1152,14 +1049,71 @@ hb_variation_to_string (hb_variation_t *variation,
   while (len && s[len - 1] == ' ')
     len--;
   s[len++] = '=';
-  len += MAX (0, snprintf (s + len, ARRAY_LENGTH (s) - len, "%g", (double) variation->value));
+  len += hb_max (0, snprintf (s + len, ARRAY_LENGTH (s) - len, "%g", (double) variation->value));
 
   assert (len < ARRAY_LENGTH (s));
-  len = MIN (len, size - 1);
+  len = hb_min (len, size - 1);
   memcpy (buf, s, len);
   buf[len] = '\0';
 }
 
+/**
+ * hb_color_get_alpha:
+ * color: a #hb_color_t we are interested in its channels.
+ *
+ * Return value: Alpha channel value of the given color
+ *
+ * Since: 2.1.0
+ */
+uint8_t
+(hb_color_get_alpha) (hb_color_t color)
+{
+  return hb_color_get_alpha (color);
+}
+
+/**
+ * hb_color_get_red:
+ * color: a #hb_color_t we are interested in its channels.
+ *
+ * Return value: Red channel value of the given color
+ *
+ * Since: 2.1.0
+ */
+uint8_t
+(hb_color_get_red) (hb_color_t color)
+{
+  return hb_color_get_red (color);
+}
+
+/**
+ * hb_color_get_green:
+ * color: a #hb_color_t we are interested in its channels.
+ *
+ * Return value: Green channel value of the given color
+ *
+ * Since: 2.1.0
+ */
+uint8_t
+(hb_color_get_green) (hb_color_t color)
+{
+  return hb_color_get_green (color);
+}
+
+/**
+ * hb_color_get_blue:
+ * color: a #hb_color_t we are interested in its channels.
+ *
+ * Return value: Blue channel value of the given color
+ *
+ * Since: 2.1.0
+ */
+uint8_t
+(hb_color_get_blue) (hb_color_t color)
+{
+  return hb_color_get_blue (color);
+}
+
+
 /* If there is no visibility control, then hb-static.cc will NOT
  * define anything.  Instead, we get it to define one set in here
  * only, so only libharfbuzz.so defines them, not other libs. */
index fbabd71..037e508 100644 (file)
@@ -63,6 +63,8 @@ typedef __int32 int32_t;
 typedef unsigned __int32 uint32_t;
 typedef __int64 int64_t;
 typedef unsigned __int64 uint64_t;
+#elif defined (__KERNEL__)
+#  include <linux/types.h>
 #else
 #  include <stdint.h>
 #endif
@@ -358,7 +360,7 @@ typedef enum
   /*11.0*/HB_SCRIPT_SOGDIAN                    = HB_TAG ('S','o','g','d'),
 
   /*
-   * Since REPLACEME
+   * Since 2.4.0
    */
   /*12.0*/HB_SCRIPT_ELYMAIC                    = HB_TAG ('E','l','y','m'),
   /*12.0*/HB_SCRIPT_NANDINAGARI                        = HB_TAG ('N','a','n','d'),
@@ -423,6 +425,21 @@ typedef void (*hb_destroy_func_t) (void *user_data);
  */
 #define HB_FEATURE_GLOBAL_END  ((unsigned int) -1)
 
+/**
+ * hb_feature_t:
+ * @tag: a feature tag
+ * @value: 0 disables the feature, non-zero (usually 1) enables the feature.
+ * For features implemented as lookup type 3 (like 'salt') the @value is a one
+ * based index into the alternates.
+ * @start: the cluster to start applying this feature setting (inclusive).
+ * @end: the cluster to end applying this feature setting (exclusive).
+ *
+ * The #hb_feature_t is the structure that holds information about requested
+ * feature application. The feature will be applied with the given value to all
+ * glyphs which are in clusters between @start (inclusive) and @end (exclusive).
+ * Setting start to @HB_FEATURE_GLOBAL_START and end to @HB_FEATURE_GLOBAL_END
+ * specifies that the feature always applies to the entire buffer.
+ */
 typedef struct hb_feature_t {
   hb_tag_t      tag;
   uint32_t      value;
@@ -467,39 +484,21 @@ typedef uint32_t hb_color_t;
 
 #define HB_COLOR(b,g,r,a) ((hb_color_t) HB_TAG ((b),(g),(r),(a)))
 
-/**
- * hb_color_get_alpha:
- *
- *
- *
- * Since: 2.1.0
- */
+HB_EXTERN uint8_t
+hb_color_get_alpha (hb_color_t color);
 #define hb_color_get_alpha(color)      ((color) & 0xFF)
-/**
- * hb_color_get_red:
- *
- *
- *
- * Since: 2.1.0
- */
+
+HB_EXTERN uint8_t
+hb_color_get_red (hb_color_t color);
 #define hb_color_get_red(color)                (((color) >> 8) & 0xFF)
-/**
- * hb_color_get_green:
- *
- *
- *
- * Since: 2.1.0
- */
+
+HB_EXTERN uint8_t
+hb_color_get_green (hb_color_t color);
 #define hb_color_get_green(color)      (((color) >> 16) & 0xFF)
-/**
- * hb_color_get_blue:
- *
- *
- *
- * Since: 2.1.0
- */
-#define hb_color_get_blue(color)       (((color) >> 24) & 0xFF)
 
+HB_EXTERN uint8_t
+hb_color_get_blue (hb_color_t color);
+#define hb_color_get_blue(color)       (((color) >> 24) & 0xFF)
 
 HB_END_DECLS
 
diff --git a/src/hb-config.hh b/src/hb-config.hh
new file mode 100644 (file)
index 0000000..14c5395
--- /dev/null
@@ -0,0 +1,162 @@
+/*
+ * Copyright © 2019  Facebook, 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.
+ *
+ * Facebook Author(s): Behdad Esfahbod
+ */
+
+#ifndef HB_CONFIG_HH
+#define HB_CONFIG_HH
+
+#if 0 /* Make test happy. */
+#include "hb.hh"
+#endif
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+
+#ifdef HB_TINY
+#define HB_LEAN
+#define HB_MINI
+#define HB_NO_MT
+#define HB_NO_UCD_UNASSIGNED
+#ifndef NDEBUG
+#define NDEBUG
+#endif
+#ifndef __OPTIMIZE_SIZE__
+#define __OPTIMIZE_SIZE__
+#endif
+#endif
+
+#ifdef HB_LEAN
+#define HB_DISABLE_DEPRECATED
+#define HB_NDEBUG
+#define HB_NO_ATEXIT
+#define HB_NO_BUFFER_MESSAGE
+#define HB_NO_BUFFER_SERIALIZE
+#define HB_NO_BITMAP
+#define HB_NO_CFF
+#define HB_NO_COLOR
+#define HB_NO_ERRNO
+#define HB_NO_FACE_COLLECT_UNICODES
+#define HB_NO_GETENV
+#define HB_NO_HINTING
+#define HB_NO_LANGUAGE_PRIVATE_SUBTAG
+#define HB_NO_LAYOUT_FEATURE_PARAMS
+#define HB_NO_LAYOUT_COLLECT_GLYPHS
+#define HB_NO_LAYOUT_UNUSED
+#define HB_NO_MATH
+#define HB_NO_META
+#define HB_NO_METRICS
+#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_STAT
+#define HB_NO_SUBSET_LAYOUT
+#define HB_NO_VAR
+#endif
+
+#ifdef HB_MINI
+#define HB_NO_AAT
+#define HB_NO_LEGACY
+#endif
+
+
+/* Closure of options. */
+
+#ifdef HB_DISABLE_DEPRECATED
+#define HB_IF_NOT_DEPRECATED(x)
+#else
+#define HB_IF_NOT_DEPRECATED(x) x
+#endif
+
+#ifdef HB_NO_AAT
+#define HB_NO_OT_NAME_LANGUAGE_AAT
+#define HB_NO_AAT_SHAPE
+#endif
+
+#ifdef HB_NO_BITMAP
+#define HB_NO_OT_FONT_BITMAP
+#endif
+
+#ifdef HB_NO_CFF
+#define HB_NO_OT_FONT_CFF
+#define HB_NO_SUBSET_CFF
+#endif
+
+#ifdef HB_NO_GETENV
+#define HB_NO_UNISCRIBE_BUG_COMPATIBLE
+#endif
+
+#ifdef HB_NO_LEGACY
+#define HB_NO_CMAP_LEGACY_SUBTABLES
+#define HB_NO_FALLBACK_SHAPE
+#define HB_NO_OT_KERN
+#define HB_NO_OT_LAYOUT_BLACKLIST
+#define HB_NO_OT_SHAPE_FALLBACK
+#endif
+
+#ifdef HB_NO_NAME
+#define HB_NO_OT_NAME_LANGUAGE
+#endif
+
+#ifdef HB_NO_OT
+#define HB_NO_OT_FONT
+#define HB_NO_OT_LAYOUT
+#define HB_NO_OT_TAG
+#define HB_NO_OT_SHAPE
+#endif
+
+#ifdef HB_NO_OT_SHAPE
+#define HB_NO_AAT_SHAPE
+#endif
+
+#ifdef HB_NO_OT_SHAPE_FALLBACK
+#define HB_NO_OT_SHAPE_COMPLEX_ARABIC_FALLBACK
+#define HB_NO_OT_SHAPE_COMPLEX_HEBREW_FALLBACK
+#define HB_NO_OT_SHAPE_COMPLEX_THAI_FALLBACK
+#define HB_NO_OT_SHAPE_COMPLEX_VOWEL_CONSTRAINTS
+#endif
+
+#ifdef NDEBUG
+#ifndef HB_NDEBUG
+#define HB_NDEBUG
+#endif
+#endif
+
+#ifdef __OPTIMIZE_SIZE__
+#ifndef HB_OPTIMIZE_SIZE
+#define HB_OPTIMIZE_SIZE
+#endif
+#endif
+
+#ifdef HAVE_CONFIG_OVERRIDE_H
+#include "config-override.h"
+#endif
+
+
+#endif /* HB_CONFIG_HH */
index 5989306..8885cfe 100644 (file)
@@ -27,6 +27,9 @@
  */
 
 #include "hb.hh"
+
+#ifdef HAVE_CORETEXT
+
 #include "hb-shaper-impl.hh"
 
 #include "hb-coretext.h"
 /* https://developer.apple.com/documentation/coretext/1508745-ctfontcreatewithgraphicsfont */
 #define HB_CORETEXT_DEFAULT_FONT_SIZE 12.f
 
-static CGFloat
-coretext_font_size_from_ptem (float ptem)
-{
-  /* CoreText points are CSS pixels (96 per inch),
-   * NOT typographic points (72 per inch).
-   *
-   * https://developer.apple.com/library/content/documentation/GraphicsAnimation/Conceptual/HighResolutionOSX/Explained/Explained.html
-   */
-  ptem *= 96.f / 72.f;
-  return ptem <= 0.f ? HB_CORETEXT_DEFAULT_FONT_SIZE : ptem;
-}
-static float
-coretext_font_size_to_ptem (CGFloat size)
-{
-  size *= 72.f / 96.f;
-  return size <= 0.f ? 0 : size;
-}
-
 static void
 release_table_data (void *user_data)
 {
@@ -72,7 +57,7 @@ release_table_data (void *user_data)
 }
 
 static hb_blob_t *
-reference_table  (hb_face_t *face HB_UNUSED, hb_tag_t tag, void *user_data)
+_hb_cg_reference_table (hb_face_t *face HB_UNUSED, hb_tag_t tag, void *user_data)
 {
   CGFontRef cg_font = reinterpret_cast<CGFontRef> (user_data);
   CFDataRef cf_data = CGFontCopyTableForTag (cg_font, tag);
@@ -126,7 +111,7 @@ static void
 release_data (void *info, const void *data, size_t size)
 {
   assert (hb_blob_get_length ((hb_blob_t *) info) == size &&
-          hb_blob_get_data ((hb_blob_t *) info, nullptr) == data);
+         hb_blob_get_data ((hb_blob_t *) info, nullptr) == data);
 
   hb_blob_destroy ((hb_blob_t *) info);
 }
@@ -248,21 +233,21 @@ create_ct_font (CGFontRef cg_font, CGFloat font_size)
       atsFont = CTFontGetPlatformFont (new_ct_font, NULL);
       status = ATSFontGetFileReference (atsFont, &fsref);
       if (status == noErr)
-        new_url = CFURLCreateFromFSRef (NULL, &fsref);
+       new_url = CFURLCreateFromFSRef (NULL, &fsref);
 #else
       new_url = (CFURLRef) CTFontCopyAttribute (new_ct_font, kCTFontURLAttribute);
 #endif
       // Keep reconfigured font if URL cannot be retrieved (seems to be the case
       // on Mac OS 10.12 Sierra), speculative fix for crbug.com/625606
       if (!original_url || !new_url || CFEqual (original_url, new_url)) {
-        CFRelease (ct_font);
-        ct_font = new_ct_font;
+       CFRelease (ct_font);
+       ct_font = new_ct_font;
       } else {
-        CFRelease (new_ct_font);
-        DEBUG_MSG (CORETEXT, ct_font, "Discarding reconfigured CTFont, location changed.");
+       CFRelease (new_ct_font);
+       DEBUG_MSG (CORETEXT, ct_font, "Discarding reconfigured CTFont, location changed.");
       }
       if (new_url)
-        CFRelease (new_url);
+       CFRelease (new_url);
     }
     else
       DEBUG_MSG (CORETEXT, ct_font, "Font copy with empty cascade list failed");
@@ -296,7 +281,7 @@ _hb_coretext_shaper_face_data_destroy (hb_coretext_face_data_t *data)
 hb_face_t *
 hb_coretext_face_create (CGFontRef cg_font)
 {
-  return hb_face_create_for_tables (reference_table, CGFontRetain (cg_font), _hb_cg_font_release);
+  return hb_face_create_for_tables (_hb_cg_reference_table, CGFontRetain (cg_font), _hb_cg_font_release);
 }
 
 /*
@@ -317,7 +302,8 @@ _hb_coretext_shaper_font_data_create (hb_font_t *font)
   if (unlikely (!face_data)) return nullptr;
   CGFontRef cg_font = (CGFontRef) (const void *) face->data.coretext;
 
-  CTFontRef ct_font = create_ct_font (cg_font, coretext_font_size_from_ptem (font->ptem));
+  CGFloat font_size = (CGFloat) (font->ptem <= 0.f ? HB_CORETEXT_DEFAULT_FONT_SIZE : font->ptem);
+  CTFontRef ct_font = create_ct_font (cg_font, font_size);
 
   if (unlikely (!ct_font))
   {
@@ -341,7 +327,7 @@ retry:
   const hb_coretext_font_data_t *data = font->data.coretext;
   if (unlikely (!data)) return nullptr;
 
-  if (fabs (CTFontGetSize((CTFontRef) data) - coretext_font_size_from_ptem (font->ptem)) > .5)
+  if (fabs (CTFontGetSize ((CTFontRef) data) - (CGFloat) font->ptem) > .5)
   {
     /* XXX-MT-bug
      * Note that evaluating condition above can be dangerous if another thread
@@ -381,7 +367,7 @@ hb_coretext_font_create (CTFontRef ct_font)
   if (unlikely (hb_object_is_immutable (font)))
     return font;
 
-  hb_font_set_ptem (font, coretext_font_size_to_ptem (CTFontGetSize(ct_font)));
+  hb_font_set_ptem (font, CTFontGetSize (ct_font));
 
   /* Let there be dragons here... */
   font->data.coretext.cmpexch (nullptr, (hb_coretext_font_data_t *) CFRetain (ct_font));
@@ -410,7 +396,7 @@ struct active_feature_t {
   feature_record_t rec;
   unsigned int order;
 
-  static int cmp (const void *pa, const void *pb) {
+  HB_INTERNAL static int cmp (const void *pa, const void *pb) {
     const active_feature_t *a = (const active_feature_t *) pa;
     const active_feature_t *b = (const active_feature_t *) pb;
     return a->rec.feature < b->rec.feature ? -1 : a->rec.feature > b->rec.feature ? 1 :
@@ -428,7 +414,7 @@ struct feature_event_t {
   bool start;
   active_feature_t feature;
 
-  static int cmp (const void *pa, const void *pb) {
+  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 :
@@ -447,9 +433,9 @@ struct range_record_t {
 hb_bool_t
 _hb_coretext_shape (hb_shape_plan_t    *shape_plan,
                    hb_font_t          *font,
-                    hb_buffer_t        *buffer,
-                    const hb_feature_t *features,
-                    unsigned int        num_features)
+                   hb_buffer_t        *buffer,
+                   const hb_feature_t *features,
+                   unsigned int        num_features)
 {
   hb_face_t *face = font->face;
   CGFontRef cg_font = (CGFontRef) (const void *) face->data.coretext;
@@ -491,7 +477,7 @@ _hb_coretext_shape (hb_shape_plan_t    *shape_plan,
     {
       const hb_aat_feature_mapping_t * mapping = hb_aat_layout_find_feature_mapping (features[i].tag);
       if (!mapping)
-        continue;
+       continue;
 
       active_feature_t feature;
       feature.rec.feature = mapping->aatFeatureType;
@@ -533,7 +519,7 @@ _hb_coretext_shape (hb_shape_plan_t    *shape_plan,
 
       if (event->index != last_index)
       {
-        /* Save a snapshot of active features and the range. */
+       /* Save a snapshot of active features and the range. */
        range_record_t *range = range_records.push ();
 
        if (active_features.length)
@@ -594,11 +580,11 @@ _hb_coretext_shape (hb_shape_plan_t    *shape_plan,
 
       if (event->start)
       {
-        active_features.push (event->feature);
+       active_features.push (event->feature);
       } else {
-        active_feature_t *feature = active_features.find (&event->feature);
+       active_feature_t *feature = active_features.find (&event->feature);
        if (feature)
-         active_features.remove (feature - active_features.arrayZ ());
+         active_features.remove (feature - active_features.arrayZ);
       }
     }
   }
@@ -608,7 +594,7 @@ _hb_coretext_shape (hb_shape_plan_t    *shape_plan,
 
 #define ALLOCATE_ARRAY(Type, name, len, on_no_room) \
   Type *name = (Type *) scratch; \
-  { \
+  do { \
     unsigned int _consumed = DIV_CEIL ((len) * sizeof (Type), sizeof (*scratch)); \
     if (unlikely (_consumed > scratch_size)) \
     { \
@@ -617,7 +603,7 @@ _hb_coretext_shape (hb_shape_plan_t    *shape_plan,
     } \
     scratch += _consumed; \
     scratch_size -= _consumed; \
-  }
+  } while (0)
 
   ALLOCATE_ARRAY (UniChar, pchars, buffer->len * 2, /*nothing*/);
   unsigned int chars_len = 0;
@@ -649,7 +635,7 @@ _hb_coretext_shape (hb_shape_plan_t    *shape_plan,
     DEBUG_MSG (CORETEXT, nullptr, __VA_ARGS__); \
     ret = false; \
     goto fail; \
-  } HB_STMT_END;
+  } HB_STMT_END
 
   bool ret = true;
   CFStringRef string_ref = nullptr;
@@ -714,15 +700,15 @@ resize_and_retry:
 #if !(defined(TARGET_OS_IPHONE) && TARGET_OS_IPHONE) && MAC_OS_X_VERSION_MIN_REQUIRED < 1090
 #  define kCTLanguageAttributeName CFSTR ("NSLanguage")
 #endif
-        CFStringRef lang = CFStringCreateWithCStringNoCopy (kCFAllocatorDefault,
+       CFStringRef lang = CFStringCreateWithCStringNoCopy (kCFAllocatorDefault,
                                                            hb_language_to_string (buffer->props.language),
                                                            kCFStringEncodingUTF8,
                                                            kCFAllocatorNull);
        if (unlikely (!lang))
-        {
+       {
          CFRelease (attr_string);
          FAIL ("CFStringCreateWithCStringNoCopy failed");
-        }
+       }
        CFAttributedStringSetAttribute (attr_string, CFRangeMake (0, chars_len),
                                        kCTLanguageAttributeName, lang);
        CFRelease (lang);
@@ -771,7 +757,7 @@ resize_and_retry:
              feature.start < chars_len && feature.start < feature.end)
          {
            CFRange feature_range = CFRangeMake (feature.start,
-                                                MIN (feature.end, chars_len) - feature.start);
+                                                hb_min (feature.end, chars_len) - feature.start);
            if (feature.value)
              CFAttributedStringRemoveAttribute (attr_string, feature_range, kCTKernAttributeName);
            else
@@ -795,8 +781,8 @@ resize_and_retry:
       CFRelease (level_number);
       if (unlikely (!options))
       {
-        CFRelease (attr_string);
-        FAIL ("CFDictionaryCreate failed");
+       CFRelease (attr_string);
+       FAIL ("CFDictionaryCreate failed");
       }
 
       CTTypesetterRef typesetter = CTTypesetterCreateWithAttributedStringAndOptions (attr_string, options);
@@ -907,7 +893,7 @@ resize_and_retry:
        if (!matched)
        {
          CFRange range = CTRunGetStringRange (run);
-          DEBUG_MSG (CORETEXT, run, "Run used fallback font: %ld..%ld",
+         DEBUG_MSG (CORETEXT, run, "Run used fallback font: %ld..%ld",
                     range.location, range.location + range.length);
          if (!buffer->ensure_inplace (buffer->len + range.length))
            goto resize_and_retry;
@@ -935,7 +921,7 @@ resize_and_retry:
                  continue;
              }
              if (buffer->unicode->is_default_ignorable (ch))
-               continue;
+               continue;
 
              info->codepoint = notdef;
              info->cluster = log_clusters[j];
@@ -977,10 +963,10 @@ resize_and_retry:
 
 #define SCRATCH_RESTORE() \
   scratch_size = scratch_size_saved; \
-  scratch = scratch_saved;
+  scratch = scratch_saved
 
       { /* Setup glyphs */
-        SCRATCH_SAVE();
+       SCRATCH_SAVE();
        const CGGlyph* glyphs = USE_PTR ? CTRunGetGlyphsPtr (run) : nullptr;
        if (!glyphs) {
          ALLOCATE_ARRAY (CGGlyph, glyph_buf, num_glyphs, goto resize_and_retry);
@@ -1003,12 +989,12 @@ resize_and_retry:
        SCRATCH_RESTORE();
       }
       {
-        /* Setup positions.
+       /* Setup positions.
         * Note that CoreText does not return advances for glyphs.  As such,
         * for all but last glyph, we use the delta position to next glyph as
         * advance (in the advance direction only), and for last glyph we set
         * whatever is needed to make the whole run's advance add up. */
-        SCRATCH_SAVE();
+       SCRATCH_SAVE();
        const CGPoint* positions = USE_PTR ? CTRunGetPositionsPtr (run) : nullptr;
        if (!positions) {
          ALLOCATE_ARRAY (CGPoint, position_buf, num_glyphs, goto resize_and_retry);
@@ -1069,7 +1055,7 @@ resize_and_retry:
     if (false)
     {
       /* Make sure all runs had the expected direction. */
-      bool backward = HB_DIRECTION_IS_BACKWARD (buffer->props.direction);
+      HB_UNUSED bool backward = HB_DIRECTION_IS_BACKWARD (buffer->props.direction);
       assert (bool (status_and & kCTRunStatusRightToLeft) == backward);
       assert (bool (status_or  & kCTRunStatusRightToLeft) == backward);
     }
@@ -1116,7 +1102,7 @@ resize_and_retry:
        unsigned int cluster = info[count - 1].cluster;
        for (unsigned int i = count - 1; i > 0; i--)
        {
-         cluster = MIN (cluster, info[i - 1].cluster);
+         cluster = hb_min (cluster, info[i - 1].cluster);
          info[i - 1].cluster = cluster;
        }
       }
@@ -1125,7 +1111,7 @@ resize_and_retry:
        unsigned int cluster = info[0].cluster;
        for (unsigned int i = 1; i < count; i++)
        {
-         cluster = MIN (cluster, info[i].cluster);
+         cluster = hb_min (cluster, info[i].cluster);
          info[i].cluster = cluster;
        }
       }
@@ -1150,57 +1136,4 @@ fail:
 }
 
 
-/*
- * AAT shaper
- */
-
-/*
- * shaper face data
- */
-
-struct hb_coretext_aat_face_data_t {};
-
-hb_coretext_aat_face_data_t *
-_hb_coretext_aat_shaper_face_data_create (hb_face_t *face)
-{
-  return hb_aat_layout_has_substitution (face) || hb_aat_layout_has_positioning (face) ?
-        (hb_coretext_aat_face_data_t *) HB_SHAPER_DATA_SUCCEEDED : nullptr;
-}
-
-void
-_hb_coretext_aat_shaper_face_data_destroy (hb_coretext_aat_face_data_t *data HB_UNUSED)
-{
-}
-
-
-/*
- * shaper font data
- */
-
-struct hb_coretext_aat_font_data_t {};
-
-hb_coretext_aat_font_data_t *
-_hb_coretext_aat_shaper_font_data_create (hb_font_t *font)
-{
-  return font->data.coretext ? (hb_coretext_aat_font_data_t *) HB_SHAPER_DATA_SUCCEEDED : nullptr;
-}
-
-void
-_hb_coretext_aat_shaper_font_data_destroy (hb_coretext_aat_font_data_t *data HB_UNUSED)
-{
-}
-
-
-/*
- * shaper
- */
-
-hb_bool_t
-_hb_coretext_aat_shape (hb_shape_plan_t    *shape_plan,
-                       hb_font_t          *font,
-                       hb_buffer_t        *buffer,
-                       const hb_feature_t *features,
-                       unsigned int        num_features)
-{
-  return _hb_coretext_shape (shape_plan, font, buffer, features, num_features);
-}
+#endif
index d7d0165..a7e52c8 100644 (file)
@@ -29,7 +29,7 @@
 
 #include "hb.hh"
 #include "hb-atomic.hh"
-#include "hb-dsalgs.hh"
+#include "hb-algs.hh"
 
 
 #ifndef HB_DEBUG
@@ -63,6 +63,9 @@ extern HB_INTERNAL hb_atomic_int_t _hb_options;
 static inline hb_options_t
 hb_options ()
 {
+#ifdef HB_NO_GETENV
+  return hb_options_t ();
+#endif
   /* Make a local copy, so we can access bitfield threadsafely. */
   hb_options_union_t u;
   u.i = _hb_options.get_relaxed ();
@@ -158,7 +161,7 @@ _hb_debug_msg_va (const char *what,
       VBAR VBAR VBAR VBAR VBAR VBAR VBAR VBAR VBAR VBAR;
     fprintf (stderr, "%2u %s" VRBAR "%s",
             level,
-            bars + sizeof (bars) - 1 - MIN ((unsigned int) sizeof (bars) - 1, (unsigned int) (sizeof (VBAR) - 1) * level),
+            bars + sizeof (bars) - 1 - hb_min ((unsigned int) sizeof (bars) - 1, (unsigned int) (sizeof (VBAR) - 1) * level),
             level_dir ? (level_dir > 0 ? DLBAR : ULBAR) : LBAR);
   } else
     fprintf (stderr, "   " VRBAR LBAR);
@@ -246,8 +249,8 @@ struct hb_printer_t<bool> {
 };
 
 template <>
-struct hb_printer_t<hb_void_t> {
-  const char *print (hb_void_t) { return ""; }
+struct hb_printer_t<hb_empty_t> {
+  const char *print (hb_empty_t) { return ""; }
 };
 
 
@@ -263,7 +266,7 @@ static inline void _hb_warn_no_return (bool returned)
   }
 }
 template <>
-/*static*/ inline void _hb_warn_no_return<hb_void_t> (bool returned HB_UNUSED)
+/*static*/ inline void _hb_warn_no_return<hb_empty_t> (bool returned HB_UNUSED)
 {}
 
 template <int max_level, typename ret_t>
@@ -293,22 +296,23 @@ struct hb_auto_trace_t
     if (plevel) --*plevel;
   }
 
-  ret_t ret (ret_t v,
-            const char *func = "",
-            unsigned int line = 0)
+  template <typename T>
+  T ret (T&& v,
+        const char *func = "",
+        unsigned int line = 0)
   {
     if (unlikely (returned)) {
       fprintf (stderr, "OUCH, double calls to return_trace().  This is a bug, please report.\n");
-      return v;
+      return hb_forward<T> (v);
     }
 
     _hb_debug_msg<max_level> (what, obj, func, true, plevel ? *plevel : 1, -1,
                              "return %s (line %d)",
-                             hb_printer_t<ret_t>().print (v), line);
+                             hb_printer_t<decltype (v)>().print (v), line);
     if (plevel) --*plevel;
     plevel = nullptr;
     returned = true;
-    return v;
+    return hb_forward<T> (v);
   }
 
   private:
@@ -327,18 +331,20 @@ struct hb_auto_trace_t<0, ret_t>
                                   const char *message,
                                   ...) HB_PRINTF_FUNC(6, 7) {}
 
-  ret_t ret (ret_t v,
-            const char *func HB_UNUSED = nullptr,
-            unsigned int line HB_UNUSED = 0) { return v; }
+  template <typename T>
+  T ret (T&& v,
+        const char *func HB_UNUSED = nullptr,
+        unsigned int line HB_UNUSED = 0) { return hb_forward<T> (v); }
 };
 
 /* For disabled tracing; optimize out everything.
  * https://github.com/harfbuzz/harfbuzz/pull/605 */
 template <typename ret_t>
 struct hb_no_trace_t {
-  ret_t ret (ret_t v,
-            const char *func HB_UNUSED = "",
-            unsigned int line HB_UNUSED = 0) { return v; }
+  template <typename T>
+  T ret (T&& v,
+        const char *func HB_UNUSED = nullptr,
+        unsigned int line HB_UNUSED = 0) { return hb_forward<T> (v); }
 };
 
 #define return_trace(RET) return trace.ret (RET, HB_FUNC, __LINE__)
@@ -408,7 +414,7 @@ struct hb_no_trace_t {
 #define TRACE_SANITIZE(this) \
        hb_auto_trace_t<HB_DEBUG_SANITIZE, bool> trace \
        (&c->debug_depth, c->get_name (), this, HB_FUNC, \
-        " ");
+        " ")
 #else
 #define TRACE_SANITIZE(this) hb_no_trace_t<bool> trace
 #endif
@@ -420,7 +426,7 @@ struct hb_no_trace_t {
 #define TRACE_SERIALIZE(this) \
        hb_auto_trace_t<HB_DEBUG_SERIALIZE, bool> trace \
        (&c->debug_depth, "SERIALIZE", c, HB_FUNC, \
-        " ");
+        " ")
 #else
 #define TRACE_SERIALIZE(this) hb_no_trace_t<bool> trace
 #endif
@@ -432,37 +438,24 @@ struct hb_no_trace_t {
 #define TRACE_SUBSET(this) \
   hb_auto_trace_t<HB_DEBUG_SUBSET, bool> trace \
   (&c->debug_depth, c->get_name (), this, HB_FUNC, \
-   " ");
+   " ")
 #else
 #define TRACE_SUBSET(this) hb_no_trace_t<bool> trace
 #endif
 
-#ifndef HB_DEBUG_WOULD_APPLY
-#define HB_DEBUG_WOULD_APPLY (HB_DEBUG+0)
-#endif
-#if HB_DEBUG_WOULD_APPLY
-#define TRACE_WOULD_APPLY(this) \
-       hb_auto_trace_t<HB_DEBUG_WOULD_APPLY, bool> trace \
-       (&c->debug_depth, c->get_name (), this, HB_FUNC, \
-        "%d glyphs", c->len);
-#else
-#define TRACE_WOULD_APPLY(this) hb_no_trace_t<bool> trace
-#endif
-
 #ifndef HB_DEBUG_DISPATCH
 #define HB_DEBUG_DISPATCH ( \
        HB_DEBUG_APPLY + \
        HB_DEBUG_SANITIZE + \
        HB_DEBUG_SERIALIZE + \
-  HB_DEBUG_SUBSET + \
-       HB_DEBUG_WOULD_APPLY + \
+       HB_DEBUG_SUBSET + \
        0)
 #endif
 #if HB_DEBUG_DISPATCH
 #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 %d", (int) format)
 #else
 #define TRACE_DISPATCH(this, format) hb_no_trace_t<typename context_t::return_t> trace
 #endif
index 4a5e702..43f89a4 100644 (file)
@@ -63,7 +63,7 @@ typedef hb_bool_t (*hb_font_get_glyph_func_t) (hb_font_t *font, void *font_data,
                                               hb_codepoint_t *glyph,
                                               void *user_data);
 
-HB_EXTERN HB_DEPRECATED_FOR(hb_font_funcs_set_nominal_glyph_func or hb_font_funcs_set_variation_glyph_func) void
+HB_EXTERN HB_DEPRECATED_FOR(hb_font_funcs_set_nominal_glyph_func and hb_font_funcs_set_variation_glyph_func) 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);
@@ -165,30 +165,9 @@ hb_unicode_decompose_compatibility (hb_unicode_funcs_t *ufuncs,
                                    hb_codepoint_t     *decomposed);
 
 
-typedef hb_position_t (*hb_font_get_glyph_kerning_func_t) (hb_font_t *font, void *font_data,
-                                                          hb_codepoint_t first_glyph, hb_codepoint_t second_glyph,
-                                                          void *user_data);
-typedef hb_font_get_glyph_kerning_func_t hb_font_get_glyph_h_kerning_func_t;
 typedef hb_font_get_glyph_kerning_func_t hb_font_get_glyph_v_kerning_func_t;
 
 /**
- * hb_font_funcs_set_glyph_h_kerning_func:
- * @ffuncs: font functions.
- * @func: (closure user_data) (destroy destroy) (scope notified):
- * @user_data:
- * @destroy:
- *
- * 
- *
- * Since: 0.9.2
- * Deprecated: 2.0.0
- **/
-HB_EXTERN void
-hb_font_funcs_set_glyph_h_kerning_func (hb_font_funcs_t *ffuncs,
-                                       hb_font_get_glyph_h_kerning_func_t func,
-                                       void *user_data, hb_destroy_func_t destroy);
-
-/**
  * hb_font_funcs_set_glyph_v_kerning_func:
  * @ffuncs: font functions.
  * @func: (closure user_data) (destroy destroy) (scope notified):
@@ -206,19 +185,9 @@ hb_font_funcs_set_glyph_v_kerning_func (hb_font_funcs_t *ffuncs,
                                        void *user_data, hb_destroy_func_t destroy);
 
 HB_EXTERN hb_position_t
-hb_font_get_glyph_h_kerning (hb_font_t *font,
-                            hb_codepoint_t left_glyph, hb_codepoint_t right_glyph);
-HB_EXTERN hb_position_t
 hb_font_get_glyph_v_kerning (hb_font_t *font,
                             hb_codepoint_t top_glyph, hb_codepoint_t bottom_glyph);
 
-HB_EXTERN void
-hb_font_get_glyph_kerning_for_direction (hb_font_t *font,
-                                        hb_codepoint_t first_glyph, hb_codepoint_t second_glyph,
-                                        hb_direction_t direction,
-                                        hb_position_t *x, hb_position_t *y);
-
-
 #endif
 
 HB_END_DECLS
index 137cd56..efb2029 100644 (file)
  */
 
 #include "hb.hh"
+
+#ifdef HAVE_DIRECTWRITE
+
 #include "hb-shaper-impl.hh"
 
-#include <DWrite_1.h>
+#include <dwrite_1.h>
 
 #include "hb-directwrite.h"
 
 
+/* Declare object creator for dynamic support of DWRITE */
+typedef HRESULT (* WINAPI t_DWriteCreateFactory)(
+  DWRITE_FACTORY_TYPE factoryType,
+  REFIID              iid,
+  IUnknown            **factory
+);
+
 /*
  * hb-directwrite uses new/delete syntatically but as we let users
  * to override malloc/free, we will redefine new/delete so users
@@ -135,6 +145,7 @@ public:
 
 struct hb_directwrite_face_data_t
 {
+  HMODULE dwrite_dll;
   IDWriteFactory *dwriteFactory;
   IDWriteFontFile *fontFile;
   DWriteFontFileStream *fontFileStream;
@@ -150,12 +161,43 @@ _hb_directwrite_shaper_face_data_create (hb_face_t *face)
   if (unlikely (!data))
     return nullptr;
 
+#define FAIL(...) \
+  HB_STMT_START { \
+    DEBUG_MSG (DIRECTWRITE, nullptr, __VA_ARGS__); \
+    return nullptr; \
+  } HB_STMT_END
+
+  data->dwrite_dll = LoadLibrary (TEXT ("DWRITE"));
+  if (unlikely (!data->dwrite_dll))
+    FAIL ("Cannot find DWrite.DLL");
+
+  t_DWriteCreateFactory p_DWriteCreateFactory;
+
+#if defined(__GNUC__)
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wcast-function-type"
+#endif
+
+  p_DWriteCreateFactory = (t_DWriteCreateFactory)
+                         GetProcAddress (data->dwrite_dll, "DWriteCreateFactory");
+
+#if defined(__GNUC__)
+#pragma GCC diagnostic pop
+#endif
+
+  if (unlikely (!p_DWriteCreateFactory))
+    FAIL ("Cannot find DWriteCreateFactory().");
+
+  HRESULT hr;
+
   // TODO: factory and fontFileLoader should be cached separately
   IDWriteFactory* dwriteFactory;
-  DWriteCreateFactory (DWRITE_FACTORY_TYPE_SHARED, __uuidof (IDWriteFactory),
-                      (IUnknown**) &dwriteFactory);
+  hr = p_DWriteCreateFactory (DWRITE_FACTORY_TYPE_SHARED, __uuidof (IDWriteFactory),
+                             (IUnknown**) &dwriteFactory);
+
+  if (unlikely (hr != S_OK))
+    FAIL ("Failed to run DWriteCreateFactory().");
 
-  HRESULT hr;
   hb_blob_t *blob = hb_face_reference_blob (face);
   DWriteFontFileStream *fontFileStream;
   fontFileStream = new DWriteFontFileStream ((uint8_t *) hb_blob_get_data (blob, nullptr),
@@ -169,12 +211,6 @@ _hb_directwrite_shaper_face_data_create (hb_face_t *face)
   hr = dwriteFactory->CreateCustomFontFileReference (&fontFileKey, sizeof (fontFileKey),
                                                     fontFileLoader, &fontFile);
 
-#define FAIL(...) \
-  HB_STMT_START { \
-    DEBUG_MSG (DIRECTWRITE, nullptr, __VA_ARGS__); \
-    return nullptr; \
-  } HB_STMT_END;
-
   if (FAILED (hr))
     FAIL ("Failed to load font file from data!");
 
@@ -221,6 +257,8 @@ _hb_directwrite_shaper_face_data_destroy (hb_directwrite_face_data_t *data)
     delete data->fontFileStream;
   if (data->faceBlob)
     hb_blob_destroy (data->faceBlob);
+  if (data->dwrite_dll)
+    FreeLibrary (data->dwrite_dll);
   if (data)
     delete data;
 }
@@ -501,11 +539,6 @@ protected:
   Run  mRunHead;
 };
 
-static inline uint16_t hb_uint16_swap (const uint16_t v)
-{ return (v >> 8) | (v << 8); }
-static inline uint32_t hb_uint32_swap (const uint32_t v)
-{ return (hb_uint16_swap (v) << 16) | hb_uint16_swap (v >> 16); }
-
 /*
  * shaper
  */
@@ -530,12 +563,12 @@ _hb_directwrite_shape_full (hb_shape_plan_t    *shape_plan,
   hb_buffer_t::scratch_buffer_t *scratch = buffer->get_scratch_buffer (&scratch_size);
 #define ALLOCATE_ARRAY(Type, name, len) \
   Type *name = (Type *) scratch; \
-  { \
+  do { \
     unsigned int _consumed = DIV_CEIL ((len) * sizeof (Type), sizeof (*scratch)); \
     assert (_consumed <= scratch_size); \
     scratch += _consumed; \
     scratch_size -= _consumed; \
-  }
+  } while (0)
 
 #define utf16_index() var1.u32
 
@@ -592,7 +625,7 @@ _hb_directwrite_shape_full (hb_shape_plan_t    *shape_plan,
   HB_STMT_START { \
     DEBUG_MSG (DIRECTWRITE, nullptr, __VA_ARGS__); \
     return false; \
-  } HB_STMT_END;
+  } HB_STMT_END
 
   if (FAILED (hr))
     FAIL ("Analyzer failed to generate results.");
@@ -778,7 +811,7 @@ retry_getglyphs:
   {
     uint32_t *p =
       &vis_clusters[log_clusters[buffer->info[i].utf16_index ()]];
-    *p = MIN (*p, buffer->info[i].cluster);
+    *p = hb_min (*p, buffer->info[i].cluster);
   }
   for (unsigned int i = 1; i < glyphCount; i++)
     if (vis_clusters[i] == (uint32_t) -1)
@@ -846,16 +879,12 @@ _hb_directwrite_shape (hb_shape_plan_t    *shape_plan,
                                     features, num_features, 0);
 }
 
-/*
- * Public [experimental] API
- */
-
-hb_bool_t
-hb_directwrite_shape_experimental_width (hb_font_t          *font,
-                                        hb_buffer_t        *buffer,
-                                        const hb_feature_t *features,
-                                        unsigned int        num_features,
-                                        float               width)
+HB_UNUSED static bool
+_hb_directwrite_shape_experimental_width (hb_font_t          *font,
+                                         hb_buffer_t        *buffer,
+                                         const hb_feature_t *features,
+                                         unsigned int        num_features,
+                                         float               width)
 {
   static const char *shapers = "directwrite";
   hb_shape_plan_t *shape_plan;
@@ -883,7 +912,7 @@ _hb_directwrite_table_data_release (void *data)
 }
 
 static hb_blob_t *
-reference_table (hb_face_t *face HB_UNUSED, hb_tag_t tag, void *user_data)
+_hb_directwrite_reference_table (hb_face_t *face HB_UNUSED, hb_tag_t tag, void *user_data)
 {
   IDWriteFontFace *dw_face = ((IDWriteFontFace *) user_data);
   const void *data;
@@ -917,14 +946,34 @@ _hb_directwrite_font_release (void *data)
 
 /**
  * hb_directwrite_face_create:
- * @font_face:
- * Since: REPLACEME
+ * @font_face: a DirectWrite IDWriteFontFace object.
+ *
+ * Return value: #hb_face_t object corresponding to the given input
+ *
+ * Since: 2.4.0
  **/
 hb_face_t *
 hb_directwrite_face_create (IDWriteFontFace *font_face)
 {
   if (font_face)
     font_face->AddRef ();
-  return hb_face_create_for_tables (reference_table, font_face,
+  return hb_face_create_for_tables (_hb_directwrite_reference_table, font_face,
                                    _hb_directwrite_font_release);
 }
+
+/**
+* hb_directwrite_face_get_font_face:
+* @face: a #hb_face_t object
+*
+* Return value: DirectWrite IDWriteFontFace object corresponding to the given input
+*
+* Since: 2.5.0
+**/
+IDWriteFontFace *
+hb_directwrite_face_get_font_face (hb_face_t *face)
+{
+  return face->data.directwrite->fontFace;
+}
+
+
+#endif
index 09776fd..f837627 100644 (file)
 
 HB_BEGIN_DECLS
 
-HB_EXTERN hb_bool_t
-hb_directwrite_shape_experimental_width (hb_font_t *font, hb_buffer_t *buffer,
-                                        const hb_feature_t *features,
-                                        unsigned int num_features, float width);
-
 HB_EXTERN hb_face_t *
 hb_directwrite_face_create (IDWriteFontFace *font_face);
 
+HB_EXTERN IDWriteFontFace *
+hb_directwrite_face_get_font_face (hb_face_t *face);
+
 HB_END_DECLS
 
 #endif /* HB_DIRECTWRITE_H */
diff --git a/src/hb-dispatch.hh b/src/hb-dispatch.hh
new file mode 100644 (file)
index 0000000..1ce3fac
--- /dev/null
@@ -0,0 +1,58 @@
+/*
+ * Copyright © 2007,2008,2009,2010  Red Hat, Inc.
+ * Copyright © 2012,2018  Google, Inc.
+ *
+ *  This is part of HarfBuzz, a text shaping library.
+ *
+ * Permission is hereby granted, without written agreement and without
+ * license or royalty fees, to use, copy, modify, and distribute this
+ * software and its documentation for any purpose, provided that the
+ * above copyright notice and the following two paragraphs appear in
+ * all copies of this software.
+ *
+ * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
+ * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
+ * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
+ * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+ * DAMAGE.
+ *
+ * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
+ * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS
+ * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
+ * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
+ *
+ * Red Hat Author(s): Behdad Esfahbod
+ * Google Author(s): Behdad Esfahbod
+ */
+
+#ifndef HB_DISPATCH_HH
+#define HB_DISPATCH_HH
+
+#include "hb.hh"
+
+/*
+ * Dispatch
+ */
+
+template <typename Context, typename Return, unsigned int MaxDebugDepth>
+struct hb_dispatch_context_t
+{
+  private:
+  /* https://en.wikipedia.org/wiki/Curiously_recurring_template_pattern */
+  const Context* thiz () const { return static_cast<const Context *> (this); }
+       Context* thiz ()       { return static_cast<      Context *> (this); }
+  public:
+  static constexpr unsigned max_debug_depth = MaxDebugDepth;
+  typedef Return return_t;
+  template <typename T, typename F>
+  bool may_dispatch (const T *obj HB_UNUSED, const F *format HB_UNUSED) { return true; }
+  template <typename T, typename ...Ts>
+  return_t dispatch (const T &obj, Ts&&... ds)
+  { return obj.dispatch (thiz (), hb_forward<Ts> (ds)...); }
+  static return_t no_dispatch_return_value () { return Context::default_return_value (); }
+  static bool stop_sublookup_iteration (const return_t r HB_UNUSED) { return false; }
+};
+
+
+#endif /* HB_DISPATCH_HH */
diff --git a/src/hb-dsalgs.hh b/src/hb-dsalgs.hh
deleted file mode 100644 (file)
index 0da244f..0000000
+++ /dev/null
@@ -1,627 +0,0 @@
-/*
- * Copyright © 2017  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_DSALGS_HH
-#define HB_DSALGS_HH
-
-#include "hb.hh"
-#include "hb-null.hh"
-
-
-/* Void! For when we need a expression-type of void. */
-typedef const struct _hb_void_t *hb_void_t;
-#define HB_VOID ((const _hb_void_t *) nullptr)
-
-
-/*
- * Bithacks.
- */
-
-/* Return the number of 1 bits in v. */
-template <typename T>
-static inline HB_CONST_FUNC unsigned int
-hb_popcount (T v)
-{
-#if (defined(__GNUC__) && (__GNUC__ >= 4)) || defined(__clang__)
-  if (sizeof (T) <= sizeof (unsigned int))
-    return __builtin_popcount (v);
-
-  if (sizeof (T) <= sizeof (unsigned long))
-    return __builtin_popcountl (v);
-
-  if (sizeof (T) <= sizeof (unsigned long long))
-    return __builtin_popcountll (v);
-#endif
-
-  if (sizeof (T) <= 4)
-  {
-    /* "HACKMEM 169" */
-    uint32_t y;
-    y = (v >> 1) &033333333333;
-    y = v - y - ((y >>1) & 033333333333);
-    return (((y + (y >> 3)) & 030707070707) % 077);
-  }
-
-  if (sizeof (T) == 8)
-  {
-    unsigned int shift = 32;
-    return hb_popcount<uint32_t> ((uint32_t) v) + hb_popcount ((uint32_t) (v >> shift));
-  }
-
-  if (sizeof (T) == 16)
-  {
-    unsigned int shift = 64;
-    return hb_popcount<uint64_t> ((uint64_t) v) + hb_popcount ((uint64_t) (v >> shift));
-  }
-
-  assert (0);
-  return 0; /* Shut up stupid compiler. */
-}
-
-/* Returns the number of bits needed to store number */
-template <typename T>
-static inline HB_CONST_FUNC unsigned int
-hb_bit_storage (T v)
-{
-  if (unlikely (!v)) return 0;
-
-#if (defined(__GNUC__) && (__GNUC__ >= 4)) || defined(__clang__)
-  if (sizeof (T) <= sizeof (unsigned int))
-    return sizeof (unsigned int) * 8 - __builtin_clz (v);
-
-  if (sizeof (T) <= sizeof (unsigned long))
-    return sizeof (unsigned long) * 8 - __builtin_clzl (v);
-
-  if (sizeof (T) <= sizeof (unsigned long long))
-    return sizeof (unsigned long long) * 8 - __builtin_clzll (v);
-#endif
-
-#if (defined(_MSC_VER) && _MSC_VER >= 1500) || defined(__MINGW32__)
-  if (sizeof (T) <= sizeof (unsigned int))
-  {
-    unsigned long where;
-    _BitScanReverse (&where, v);
-    return 1 + where;
-  }
-# if defined(_WIN64)
-  if (sizeof (T) <= 8)
-  {
-    unsigned long where;
-    _BitScanReverse64 (&where, v);
-    return 1 + where;
-  }
-# endif
-#endif
-
-  if (sizeof (T) <= 4)
-  {
-    /* "bithacks" */
-    const unsigned int b[] = {0x2, 0xC, 0xF0, 0xFF00, 0xFFFF0000};
-    const unsigned int S[] = {1, 2, 4, 8, 16};
-    unsigned int r = 0;
-    for (int i = 4; i >= 0; i--)
-      if (v & b[i])
-      {
-       v >>= S[i];
-       r |= S[i];
-      }
-    return r + 1;
-  }
-  if (sizeof (T) <= 8)
-  {
-    /* "bithacks" */
-    const uint64_t b[] = {0x2ULL, 0xCULL, 0xF0ULL, 0xFF00ULL, 0xFFFF0000ULL, 0xFFFFFFFF00000000ULL};
-    const unsigned int S[] = {1, 2, 4, 8, 16, 32};
-    unsigned int r = 0;
-    for (int i = 5; i >= 0; i--)
-      if (v & b[i])
-      {
-       v >>= S[i];
-       r |= S[i];
-      }
-    return r + 1;
-  }
-  if (sizeof (T) == 16)
-  {
-    unsigned int shift = 64;
-    return (v >> shift) ? hb_bit_storage<uint64_t> ((uint64_t) (v >> shift)) + shift :
-                         hb_bit_storage<uint64_t> ((uint64_t) v);
-  }
-
-  assert (0);
-  return 0; /* Shut up stupid compiler. */
-}
-
-/* Returns the number of zero bits in the least significant side of v */
-template <typename T>
-static inline HB_CONST_FUNC unsigned int
-hb_ctz (T v)
-{
-  if (unlikely (!v)) return 0;
-
-#if (defined(__GNUC__) && (__GNUC__ >= 4)) || defined(__clang__)
-  if (sizeof (T) <= sizeof (unsigned int))
-    return __builtin_ctz (v);
-
-  if (sizeof (T) <= sizeof (unsigned long))
-    return __builtin_ctzl (v);
-
-  if (sizeof (T) <= sizeof (unsigned long long))
-    return __builtin_ctzll (v);
-#endif
-
-#if (defined(_MSC_VER) && _MSC_VER >= 1500) || defined(__MINGW32__)
-  if (sizeof (T) <= sizeof (unsigned int))
-  {
-    unsigned long where;
-    _BitScanForward (&where, v);
-    return where;
-  }
-# if defined(_WIN64)
-  if (sizeof (T) <= 8)
-  {
-    unsigned long where;
-    _BitScanForward64 (&where, v);
-    return where;
-  }
-# endif
-#endif
-
-  if (sizeof (T) <= 4)
-  {
-    /* "bithacks" */
-    unsigned int c = 32;
-    v &= - (int32_t) v;
-    if (v) c--;
-    if (v & 0x0000FFFF) c -= 16;
-    if (v & 0x00FF00FF) c -= 8;
-    if (v & 0x0F0F0F0F) c -= 4;
-    if (v & 0x33333333) c -= 2;
-    if (v & 0x55555555) c -= 1;
-    return c;
-  }
-  if (sizeof (T) <= 8)
-  {
-    /* "bithacks" */
-    unsigned int c = 64;
-    v &= - (int64_t) (v);
-    if (v) c--;
-    if (v & 0x00000000FFFFFFFFULL) c -= 32;
-    if (v & 0x0000FFFF0000FFFFULL) c -= 16;
-    if (v & 0x00FF00FF00FF00FFULL) c -= 8;
-    if (v & 0x0F0F0F0F0F0F0F0FULL) c -= 4;
-    if (v & 0x3333333333333333ULL) c -= 2;
-    if (v & 0x5555555555555555ULL) c -= 1;
-    return c;
-  }
-  if (sizeof (T) == 16)
-  {
-    unsigned int shift = 64;
-    return (uint64_t) v ? hb_bit_storage<uint64_t> ((uint64_t) v) :
-                         hb_bit_storage<uint64_t> ((uint64_t) (v >> shift)) + shift;
-  }
-
-  assert (0);
-  return 0; /* Shut up stupid compiler. */
-}
-
-
-/*
- * Tiny stuff.
- */
-
-template <typename T>
-static inline T* hb_addressof (T& arg)
-{
-#pragma GCC diagnostic push
-#pragma GCC diagnostic ignored "-Wcast-align"
-  /* https://en.cppreference.com/w/cpp/memory/addressof */
-  return reinterpret_cast<T*>(
-          &const_cast<char&>(
-             reinterpret_cast<const volatile char&>(arg)));
-#pragma GCC diagnostic pop
-}
-
-/* ASCII tag/character handling */
-static inline bool ISALPHA (unsigned char c)
-{ return (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z'); }
-static inline bool ISALNUM (unsigned char c)
-{ return (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || (c >= '0' && c <= '9'); }
-static inline bool ISSPACE (unsigned char c)
-{ return c == ' ' || c =='\f'|| c =='\n'|| c =='\r'|| c =='\t'|| c =='\v'; }
-static inline unsigned char TOUPPER (unsigned char c)
-{ return (c >= 'a' && c <= 'z') ? c - 'a' + 'A' : c; }
-static inline unsigned char TOLOWER (unsigned char c)
-{ return (c >= 'A' && c <= 'Z') ? c - 'A' + 'a' : c; }
-
-#undef MIN
-template <typename Type>
-static inline Type MIN (const Type &a, const Type &b) { return a < b ? a : b; }
-
-#undef MAX
-template <typename Type>
-static inline Type MAX (const Type &a, const Type &b) { return a > b ? a : b; }
-
-static inline unsigned int DIV_CEIL (const unsigned int a, unsigned int b)
-{ return (a + (b - 1)) / b; }
-
-
-#undef  ARRAY_LENGTH
-template <typename Type, unsigned int n>
-static inline unsigned int ARRAY_LENGTH (const Type (&)[n]) { return n; }
-/* A const version, but does not detect erratically being called on pointers. */
-#define ARRAY_LENGTH_CONST(__array) ((signed int) (sizeof (__array) / sizeof (__array[0])))
-
-
-static inline int
-hb_memcmp (const void *a, const void *b, unsigned int len)
-{
-  /* It's illegal to pass NULL to memcmp(), even if len is zero.
-   * So, wrap it.
-   * https://sourceware.org/bugzilla/show_bug.cgi?id=23878 */
-  if (!len) return 0;
-  return memcmp (a, b, len);
-}
-
-static inline bool
-hb_unsigned_mul_overflows (unsigned int count, unsigned int size)
-{
-  return (size > 0) && (count >= ((unsigned int) -1) / size);
-}
-
-static inline unsigned int
-hb_ceil_to_4 (unsigned int v)
-{
-  return ((v - 1) | 3) + 1;
-}
-
-template <typename T> struct hb_is_signed;
-/* https://github.com/harfbuzz/harfbuzz/issues/1535 */
-template <> struct hb_is_signed<int8_t> { enum { value = true }; };
-template <> struct hb_is_signed<int16_t> { enum { value = true }; };
-template <> struct hb_is_signed<int32_t> { enum { value = true }; };
-template <> struct hb_is_signed<int64_t> { enum { value = true }; };
-template <> struct hb_is_signed<uint8_t> { enum { value = false }; };
-template <> struct hb_is_signed<uint16_t> { enum { value = false }; };
-template <> struct hb_is_signed<uint32_t> { enum { value = false }; };
-template <> struct hb_is_signed<uint64_t> { enum { value = false }; };
-
-template <typename T> static inline bool
-hb_in_range (T u, T lo, T hi)
-{
-  static_assert (!hb_is_signed<T>::value, "");
-
-  /* The casts below are important as if T is smaller than int,
-   * the subtract results will become a signed int! */
-  return (T)(u - lo) <= (T)(hi - lo);
-}
-template <typename T> static inline bool
-hb_in_ranges (T u, T lo1, T hi1, T lo2, T hi2)
-{
-  return hb_in_range (u, lo1, hi1) || hb_in_range (u, lo2, hi2);
-}
-template <typename T> static inline bool
-hb_in_ranges (T u, T lo1, T hi1, T lo2, T hi2, T lo3, T hi3)
-{
-  return hb_in_range (u, lo1, hi1) || hb_in_range (u, lo2, hi2) || hb_in_range (u, lo3, hi3);
-}
-
-
-/*
- * Sort and search.
- */
-
-static inline void *
-hb_bsearch (const void *key, const void *base,
-           size_t nmemb, size_t size,
-           int (*compar)(const void *_key, const void *_item))
-{
-  int min = 0, max = (int) nmemb - 1;
-  while (min <= max)
-  {
-    int mid = (min + max) / 2;
-    const void *p = (const void *) (((const char *) base) + (mid * size));
-    int c = compar (key, p);
-    if (c < 0)
-      max = mid - 1;
-    else if (c > 0)
-      min = mid + 1;
-    else
-      return (void *) p;
-  }
-  return nullptr;
-}
-
-static inline void *
-hb_bsearch_r (const void *key, const void *base,
-             size_t nmemb, size_t size,
-             int (*compar)(const void *_key, const void *_item, void *_arg),
-             void *arg)
-{
-  int min = 0, max = (int) nmemb - 1;
-  while (min <= max)
-  {
-    int mid = ((unsigned int) min + (unsigned int) max) / 2;
-    const void *p = (const void *) (((const char *) base) + (mid * size));
-    int c = compar (key, p, arg);
-    if (c < 0)
-      max = mid - 1;
-    else if (c > 0)
-      min = mid + 1;
-    else
-      return (void *) p;
-  }
-  return nullptr;
-}
-
-
-/* From https://github.com/noporpoise/sort_r
- * With following modifications:
- *
- * 10 November 2018:
- * https://github.com/noporpoise/sort_r/issues/7
- */
-
-/* Isaac Turner 29 April 2014 Public Domain */
-
-/*
-
-hb_sort_r function to be exported.
-
-Parameters:
-  base is the array to be sorted
-  nel is the number of elements in the array
-  width is the size in bytes of each element of the array
-  compar is the comparison function
-  arg is a pointer to be passed to the comparison function
-
-void hb_sort_r(void *base, size_t nel, size_t width,
-               int (*compar)(const void *_a, const void *_b, void *_arg),
-               void *arg);
-*/
-
-
-/* swap a, b iff a>b */
-/* __restrict is same as restrict but better support on old machines */
-static int sort_r_cmpswap(char *__restrict a, char *__restrict b, size_t w,
-                         int (*compar)(const void *_a, const void *_b,
-                                       void *_arg),
-                         void *arg)
-{
-  char tmp, *end = a+w;
-  if(compar(a, b, arg) > 0) {
-    for(; a < end; a++, b++) { tmp = *a; *a = *b; *b = tmp; }
-    return 1;
-  }
-  return 0;
-}
-
-/* Note: quicksort is not stable, equivalent values may be swapped */
-static inline void sort_r_simple(void *base, size_t nel, size_t w,
-                                int (*compar)(const void *_a, const void *_b,
-                                              void *_arg),
-                                void *arg)
-{
-  char *b = (char *)base, *end = b + nel*w;
-  if(nel < 7) {
-    /* Insertion sort for arbitrarily small inputs */
-    char *pi, *pj;
-    for(pi = b+w; pi < end; pi += w) {
-      for(pj = pi; pj > b && sort_r_cmpswap(pj-w,pj,w,compar,arg); pj -= w) {}
-    }
-  }
-  else
-  {
-    /* nel > 6; Quicksort */
-
-    /* Use median of first, middle and last items as pivot */
-    char *x, *y, *xend, ch;
-    char *pl, *pm, *pr;
-    char *last = b+w*(nel-1), *tmp;
-    char *l[3];
-    l[0] = b;
-    l[1] = b+w*(nel/2);
-    l[2] = last;
-
-    if(compar(l[0],l[1],arg) > 0) { tmp=l[0]; l[0]=l[1]; l[1]=tmp; }
-    if(compar(l[1],l[2],arg) > 0) {
-      tmp=l[1]; l[1]=l[2]; l[2]=tmp; /* swap(l[1],l[2]) */
-      if(compar(l[0],l[1],arg) > 0) { tmp=l[0]; l[0]=l[1]; l[1]=tmp; }
-    }
-
-    /* swap l[id], l[2] to put pivot as last element */
-    for(x = l[1], y = last, xend = x+w; x<xend; x++, y++) {
-      ch = *x; *x = *y; *y = ch;
-    }
-
-    pl = b;
-    pr = last;
-
-    while(pl < pr) {
-      pm = pl+((pr-pl+1)>>1);
-      for(; pl < pm; pl += w) {
-        if(sort_r_cmpswap(pl, pr, w, compar, arg)) {
-          pr -= w; /* pivot now at pl */
-          break;
-        }
-      }
-      pm = pl+((pr-pl)>>1);
-      for(; pm < pr; pr -= w) {
-        if(sort_r_cmpswap(pl, pr, w, compar, arg)) {
-          pl += w; /* pivot now at pr */
-          break;
-        }
-      }
-    }
-
-    sort_r_simple(b, (pl-b)/w, w, compar, arg);
-    sort_r_simple(pl+w, (end-(pl+w))/w, w, compar, arg);
-  }
-}
-
-static inline void hb_sort_r(void *base, size_t nel, size_t width,
-                            int (*compar)(const void *_a, const void *_b, void *_arg),
-                            void *arg)
-{
-    sort_r_simple(base, nel, width, compar, arg);
-}
-
-
-template <typename T, typename T2> static inline void
-hb_stable_sort (T *array, unsigned int len, int(*compar)(const T *, const T *), T2 *array2)
-{
-  for (unsigned int i = 1; i < len; i++)
-  {
-    unsigned int j = i;
-    while (j && compar (&array[j - 1], &array[i]) > 0)
-      j--;
-    if (i == j)
-      continue;
-    /* Move item i to occupy place for item j, shift what's in between. */
-    {
-      T t = array[i];
-      memmove (&array[j + 1], &array[j], (i - j) * sizeof (T));
-      array[j] = t;
-    }
-    if (array2)
-    {
-      T2 t = array2[i];
-      memmove (&array2[j + 1], &array2[j], (i - j) * sizeof (T2));
-      array2[j] = t;
-    }
-  }
-}
-
-template <typename T> static inline void
-hb_stable_sort (T *array, unsigned int len, int(*compar)(const T *, const T *))
-{
-  hb_stable_sort (array, len, compar, (int *) nullptr);
-}
-
-static inline hb_bool_t
-hb_codepoint_parse (const char *s, unsigned int len, int base, hb_codepoint_t *out)
-{
-  /* Pain because we don't know whether s is nul-terminated. */
-  char buf[64];
-  len = MIN (ARRAY_LENGTH (buf) - 1, len);
-  strncpy (buf, s, len);
-  buf[len] = '\0';
-
-  char *end;
-  errno = 0;
-  unsigned long v = strtoul (buf, &end, base);
-  if (errno) return false;
-  if (*end) return false;
-  *out = v;
-  return true;
-}
-
-
-struct HbOpOr
-{
-  static constexpr bool passthru_left = true;
-  static constexpr bool passthru_right = true;
-  template <typename T> static void process (T &o, const T &a, const T &b) { o = a | b; }
-};
-struct HbOpAnd
-{
-  static constexpr bool passthru_left = false;
-  static constexpr bool passthru_right = false;
-  template <typename T> static void process (T &o, const T &a, const T &b) { o = a & b; }
-};
-struct HbOpMinus
-{
-  static constexpr bool passthru_left = true;
-  static constexpr bool passthru_right = false;
-  template <typename T> static void process (T &o, const T &a, const T &b) { o = a & ~b; }
-};
-struct HbOpXor
-{
-  static constexpr bool passthru_left = true;
-  static constexpr bool passthru_right = true;
-  template <typename T> static void process (T &o, const T &a, const T &b) { o = a ^ b; }
-};
-
-
-/* Compiler-assisted vectorization. */
-
-/* Type behaving similar to vectorized vars defined using __attribute__((vector_size(...))),
- * using vectorized operations if HB_VECTOR_SIZE is set to **bit** numbers (eg 128).
- * Define that to 0 to disable. */
-template <typename elt_t, unsigned int byte_size>
-struct hb_vector_size_t
-{
-  elt_t& operator [] (unsigned int i) { return u.v[i]; }
-  const elt_t& operator [] (unsigned int i) const { return u.v[i]; }
-
-  void clear (unsigned char v = 0) { memset (this, v, sizeof (*this)); }
-
-  template <class Op>
-  hb_vector_size_t process (const hb_vector_size_t &o) const
-  {
-    hb_vector_size_t r;
-#if HB_VECTOR_SIZE
-    if (HB_VECTOR_SIZE && 0 == (byte_size * 8) % HB_VECTOR_SIZE)
-      for (unsigned int i = 0; i < ARRAY_LENGTH (u.vec); i++)
-       Op::process (r.u.vec[i], u.vec[i], o.u.vec[i]);
-    else
-#endif
-      for (unsigned int i = 0; i < ARRAY_LENGTH (u.v); i++)
-       Op::process (r.u.v[i], u.v[i], o.u.v[i]);
-    return r;
-  }
-  hb_vector_size_t operator | (const hb_vector_size_t &o) const
-  { return process<HbOpOr> (o); }
-  hb_vector_size_t operator & (const hb_vector_size_t &o) const
-  { return process<HbOpAnd> (o); }
-  hb_vector_size_t operator ^ (const hb_vector_size_t &o) const
-  { return process<HbOpXor> (o); }
-  hb_vector_size_t operator ~ () const
-  {
-    hb_vector_size_t r;
-#if HB_VECTOR_SIZE && 0
-    if (HB_VECTOR_SIZE && 0 == (byte_size * 8) % HB_VECTOR_SIZE)
-      for (unsigned int i = 0; i < ARRAY_LENGTH (u.vec); i++)
-       r.u.vec[i] = ~u.vec[i];
-    else
-#endif
-    for (unsigned int i = 0; i < ARRAY_LENGTH (u.v); i++)
-      r.u.v[i] = ~u.v[i];
-    return r;
-  }
-
-  private:
-  static_assert (byte_size / sizeof (elt_t) * sizeof (elt_t) == byte_size, "");
-  union {
-    elt_t v[byte_size / sizeof (elt_t)];
-#if HB_VECTOR_SIZE
-    hb_vector_size_impl_t vec[byte_size / sizeof (hb_vector_size_impl_t)];
-#endif
-  } u;
-};
-
-
-#endif /* HB_DSALGS_HH */
index 375ef92..0c9949f 100644 (file)
@@ -367,6 +367,9 @@ hb_blob_t *
 hb_face_reference_table (const hb_face_t *face,
                         hb_tag_t tag)
 {
+  if (unlikely (tag == HB_TAG_NONE))
+    return hb_blob_get_empty ();
+
   return face->reference_table (tag);
 }
 
@@ -531,6 +534,7 @@ hb_face_get_table_tags (const hb_face_t *face,
  */
 
 
+#ifndef HB_NO_FACE_COLLECT_UNICODES
 /**
  * hb_face_collect_unicodes:
  * @face: font face.
@@ -544,7 +548,6 @@ hb_face_collect_unicodes (hb_face_t *face,
 {
   face->table.cmap->collect_unicodes (out);
 }
-
 /**
  * hb_face_collect_variation_selectors:
  * @face: font face.
@@ -560,7 +563,6 @@ hb_face_collect_variation_selectors (hb_face_t *face,
 {
   face->table.cmap->collect_variation_selectors (out);
 }
-
 /**
  * hb_face_collect_variation_unicodes:
  * @face: font face.
@@ -577,7 +579,7 @@ hb_face_collect_variation_unicodes (hb_face_t *face,
 {
   face->table.cmap->collect_variation_unicodes (variation_selector, out);
 }
-
+#endif
 
 
 /*
index 09f0290..c5b7c2c 100644 (file)
@@ -26,6 +26,7 @@
 
 #include "hb-shaper-impl.hh"
 
+#ifndef HB_NO_FALLBACK_SHAPE
 
 /*
  * shaper face data
@@ -120,3 +121,5 @@ _hb_fallback_shape (hb_shape_plan_t    *shape_plan HB_UNUSED,
 
   return true;
 }
+
+#endif
index 817a1a7..e89ad69 100644 (file)
@@ -355,6 +355,7 @@ hb_font_get_glyph_h_kerning_default (hb_font_t *font,
   return font->parent_scale_x_distance (font->parent->get_glyph_h_kerning (left_glyph, right_glyph));
 }
 
+#ifndef HB_DISABLE_DEPRECATED
 static hb_position_t
 hb_font_get_glyph_v_kerning_nil (hb_font_t *font HB_UNUSED,
                                 void *font_data HB_UNUSED,
@@ -373,6 +374,7 @@ hb_font_get_glyph_v_kerning_default (hb_font_t *font,
 {
   return font->parent_scale_y_distance (font->parent->get_glyph_v_kerning (top_glyph, bottom_glyph));
 }
+#endif
 
 static hb_bool_t
 hb_font_get_glyph_extents_nil (hb_font_t *font HB_UNUSED,
@@ -516,9 +518,9 @@ static const hb_font_funcs_t _hb_font_funcs_default = {
 /**
  * hb_font_funcs_create: (Xconstructor)
  *
- * 
  *
- * Return value: (transfer full): 
+ *
+ * Return value: (transfer full):
  *
  * Since: 0.9.2
  **/
@@ -538,9 +540,9 @@ hb_font_funcs_create ()
 /**
  * hb_font_funcs_get_empty:
  *
- * 
  *
- * Return value: (transfer full): 
+ *
+ * Return value: (transfer full):
  *
  * Since: 0.9.2
  **/
@@ -554,9 +556,9 @@ hb_font_funcs_get_empty ()
  * hb_font_funcs_reference: (skip)
  * @ffuncs: font functions.
  *
- * 
  *
- * Return value: 
+ *
+ * Return value:
  *
  * Since: 0.9.2
  **/
@@ -570,7 +572,7 @@ hb_font_funcs_reference (hb_font_funcs_t *ffuncs)
  * hb_font_funcs_destroy: (skip)
  * @ffuncs: font functions.
  *
- * 
+ *
  *
  * Since: 0.9.2
  **/
@@ -590,14 +592,14 @@ hb_font_funcs_destroy (hb_font_funcs_t *ffuncs)
 /**
  * hb_font_funcs_set_user_data: (skip)
  * @ffuncs: font functions.
- * @key: 
- * @data: 
- * @destroy: 
- * @replace: 
+ * @key:
+ * @data:
+ * @destroy:
+ * @replace:
+ *
  *
- * 
  *
- * Return value: 
+ * Return value:
  *
  * Since: 0.9.2
  **/
@@ -614,11 +616,11 @@ hb_font_funcs_set_user_data (hb_font_funcs_t    *ffuncs,
 /**
  * hb_font_funcs_get_user_data: (skip)
  * @ffuncs: font functions.
- * @key: 
+ * @key:
  *
- * 
  *
- * Return value: (transfer none): 
+ *
+ * Return value: (transfer none):
  *
  * Since: 0.9.2
  **/
@@ -634,7 +636,7 @@ hb_font_funcs_get_user_data (hb_font_funcs_t    *ffuncs,
  * hb_font_funcs_make_immutable:
  * @ffuncs: font functions.
  *
- * 
+ *
  *
  * Since: 0.9.2
  **/
@@ -651,9 +653,9 @@ hb_font_funcs_make_immutable (hb_font_funcs_t *ffuncs)
  * hb_font_funcs_is_immutable:
  * @ffuncs: font functions.
  *
- * 
  *
- * Return value: 
+ *
+ * Return value:
  *
  * Since: 0.9.2
  **/
@@ -665,22 +667,22 @@ hb_font_funcs_is_immutable (hb_font_funcs_t *ffuncs)
 
 
 #define HB_FONT_FUNC_IMPLEMENT(name) \
-                                                                         \
+                                                                        \
 void                                                                     \
 hb_font_funcs_set_##name##_func (hb_font_funcs_t             *ffuncs,    \
-                                 hb_font_get_##name##_func_t  func,      \
-                                 void                        *user_data, \
-                                 hb_destroy_func_t            destroy)   \
+                                hb_font_get_##name##_func_t  func,      \
+                                void                        *user_data, \
+                                hb_destroy_func_t            destroy)   \
 {                                                                        \
   if (hb_object_is_immutable (ffuncs)) {                                 \
     if (destroy)                                                         \
       destroy (user_data);                                               \
     return;                                                              \
   }                                                                      \
-                                                                         \
+                                                                        \
   if (ffuncs->destroy.name)                                              \
     ffuncs->destroy.name (ffuncs->user_data.name);                       \
-                                                                         \
+                                                                        \
   if (func) {                                                            \
     ffuncs->get.f.name = func;                                           \
     ffuncs->user_data.name = user_data;                                  \
@@ -749,13 +751,13 @@ hb_font_get_v_extents (hb_font_t *font,
 /**
  * hb_font_get_glyph:
  * @font: a font.
- * @unicode: 
- * @variation_selector: 
- * @glyph: (out): 
+ * @unicode:
+ * @variation_selector:
+ * @glyph: (out):
  *
- * 
  *
- * Return value: 
+ *
+ * Return value:
  *
  * Since: 0.9.2
  **/
@@ -772,12 +774,12 @@ hb_font_get_glyph (hb_font_t *font,
 /**
  * hb_font_get_nominal_glyph:
  * @font: a font.
- * @unicode: 
- * @glyph: (out): 
+ * @unicode:
+ * @glyph: (out):
+ *
  *
- * 
  *
- * Return value: 
+ * Return value:
  *
  * Since: 1.2.3
  **/
@@ -790,15 +792,38 @@ hb_font_get_nominal_glyph (hb_font_t *font,
 }
 
 /**
+ * hb_font_get_nominal_glyphs:
+ * @font: a font.
+ *
+ *
+ *
+ * Return value:
+ *
+ * Since: 2.6.3
+ **/
+unsigned int
+hb_font_get_nominal_glyphs (hb_font_t *font,
+                           unsigned int count,
+                           const hb_codepoint_t *first_unicode,
+                           unsigned int unicode_stride,
+                           hb_codepoint_t *first_glyph,
+                           unsigned int glyph_stride)
+{
+  return font->get_nominal_glyphs (count,
+                                  first_unicode, unicode_stride,
+                                  first_glyph, glyph_stride);
+}
+
+/**
  * hb_font_get_variation_glyph:
  * @font: a font.
- * @unicode: 
- * @variation_selector: 
- * @glyph: (out): 
+ * @unicode:
+ * @variation_selector:
+ * @glyph: (out):
+ *
  *
- * 
  *
- * Return value: 
+ * Return value:
  *
  * Since: 1.2.3
  **/
@@ -813,11 +838,11 @@ hb_font_get_variation_glyph (hb_font_t *font,
 /**
  * hb_font_get_glyph_h_advance:
  * @font: a font.
- * @glyph: 
+ * @glyph:
  *
- * 
  *
- * Return value: 
+ *
+ * Return value:
  *
  * Since: 0.9.2
  **/
@@ -831,11 +856,11 @@ hb_font_get_glyph_h_advance (hb_font_t *font,
 /**
  * hb_font_get_glyph_v_advance:
  * @font: a font.
- * @glyph: 
+ * @glyph:
  *
- * 
  *
- * Return value: 
+ *
+ * Return value:
  *
  * Since: 0.9.2
  **/
@@ -850,7 +875,7 @@ hb_font_get_glyph_v_advance (hb_font_t *font,
  * hb_font_get_glyph_h_advances:
  * @font: a font.
  *
- * 
+ *
  *
  * Since: 1.8.6
  **/
@@ -868,7 +893,7 @@ hb_font_get_glyph_h_advances (hb_font_t* font,
  * hb_font_get_glyph_v_advances:
  * @font: a font.
  *
- * 
+ *
  *
  * Since: 1.8.6
  **/
@@ -886,13 +911,13 @@ hb_font_get_glyph_v_advances (hb_font_t* font,
 /**
  * hb_font_get_glyph_h_origin:
  * @font: a font.
- * @glyph: 
- * @x: (out): 
- * @y: (out): 
+ * @glyph:
+ * @x: (out):
+ * @y: (out):
+ *
  *
- * 
  *
- * Return value: 
+ * Return value:
  *
  * Since: 0.9.2
  **/
@@ -907,13 +932,13 @@ hb_font_get_glyph_h_origin (hb_font_t *font,
 /**
  * hb_font_get_glyph_v_origin:
  * @font: a font.
- * @glyph: 
- * @x: (out): 
- * @y: (out): 
+ * @glyph:
+ * @x: (out):
+ * @y: (out):
+ *
  *
- * 
  *
- * Return value: 
+ * Return value:
  *
  * Since: 0.9.2
  **/
@@ -928,15 +953,14 @@ hb_font_get_glyph_v_origin (hb_font_t *font,
 /**
  * hb_font_get_glyph_h_kerning:
  * @font: a font.
- * @left_glyph: 
- * @right_glyph: 
+ * @left_glyph:
+ * @right_glyph:
  *
- * 
  *
- * Return value: 
+ *
+ * Return value:
  *
  * Since: 0.9.2
- * Deprecated: 2.0.0
  **/
 hb_position_t
 hb_font_get_glyph_h_kerning (hb_font_t *font,
@@ -945,15 +969,16 @@ hb_font_get_glyph_h_kerning (hb_font_t *font,
   return font->get_glyph_h_kerning (left_glyph, right_glyph);
 }
 
+#ifndef HB_DISABLE_DEPRECATED
 /**
  * hb_font_get_glyph_v_kerning:
  * @font: a font.
- * @top_glyph: 
- * @bottom_glyph: 
+ * @top_glyph:
+ * @bottom_glyph:
+ *
  *
- * 
  *
- * Return value: 
+ * Return value:
  *
  * Since: 0.9.2
  * Deprecated: 2.0.0
@@ -964,16 +989,17 @@ hb_font_get_glyph_v_kerning (hb_font_t *font,
 {
   return font->get_glyph_v_kerning (top_glyph, bottom_glyph);
 }
+#endif
 
 /**
  * hb_font_get_glyph_extents:
  * @font: a font.
- * @glyph: 
- * @extents: (out): 
+ * @glyph:
+ * @extents: (out):
  *
- * 
  *
- * Return value: 
+ *
+ * Return value:
  *
  * Since: 0.9.2
  **/
@@ -988,14 +1014,14 @@ hb_font_get_glyph_extents (hb_font_t *font,
 /**
  * hb_font_get_glyph_contour_point:
  * @font: a font.
- * @glyph: 
- * @point_index: 
- * @x: (out): 
- * @y: (out): 
+ * @glyph:
+ * @point_index:
+ * @x: (out):
+ * @y: (out):
  *
- * 
  *
- * Return value: 
+ *
+ * Return value:
  *
  * Since: 0.9.2
  **/
@@ -1010,13 +1036,13 @@ hb_font_get_glyph_contour_point (hb_font_t *font,
 /**
  * hb_font_get_glyph_name:
  * @font: a font.
- * @glyph: 
- * @name: (array length=size): 
- * @size: 
+ * @glyph:
+ * @name: (array length=size):
+ * @size:
+ *
  *
- * 
  *
- * Return value: 
+ * Return value:
  *
  * Since: 0.9.2
  **/
@@ -1031,13 +1057,13 @@ hb_font_get_glyph_name (hb_font_t *font,
 /**
  * hb_font_get_glyph_from_name:
  * @font: a font.
- * @name: (array length=len): 
- * @len: 
- * @glyph: (out): 
+ * @name: (array length=len):
+ * @len:
+ * @glyph: (out):
+ *
  *
- * 
  *
- * Return value: 
+ * Return value:
  *
  * Since: 0.9.2
  **/
@@ -1072,12 +1098,12 @@ hb_font_get_extents_for_direction (hb_font_t *font,
 /**
  * hb_font_get_glyph_advance_for_direction:
  * @font: a font.
- * @glyph: 
- * @direction: 
- * @x: (out): 
- * @y: (out): 
+ * @glyph:
+ * @direction:
+ * @x: (out):
+ * @y: (out):
+ *
  *
- * 
  *
  * Since: 0.9.2
  **/
@@ -1092,9 +1118,9 @@ hb_font_get_glyph_advance_for_direction (hb_font_t *font,
 /**
  * hb_font_get_glyph_advances_for_direction:
  * @font: a font.
- * @direction: 
+ * @direction:
+ *
  *
- * 
  *
  * Since: 1.8.6
  **/
@@ -1113,12 +1139,12 @@ hb_font_get_glyph_advances_for_direction (hb_font_t* font,
 /**
  * hb_font_get_glyph_origin_for_direction:
  * @font: a font.
- * @glyph: 
- * @direction: 
- * @x: (out): 
- * @y: (out): 
+ * @glyph:
+ * @direction:
+ * @x: (out):
+ * @y: (out):
+ *
  *
- * 
  *
  * Since: 0.9.2
  **/
@@ -1134,12 +1160,12 @@ hb_font_get_glyph_origin_for_direction (hb_font_t *font,
 /**
  * hb_font_add_glyph_origin_for_direction:
  * @font: a font.
- * @glyph: 
- * @direction: 
- * @x: (out): 
- * @y: (out): 
+ * @glyph:
+ * @direction:
+ * @x: (out):
+ * @y: (out):
+ *
  *
- * 
  *
  * Since: 0.9.2
  **/
@@ -1155,12 +1181,12 @@ hb_font_add_glyph_origin_for_direction (hb_font_t *font,
 /**
  * hb_font_subtract_glyph_origin_for_direction:
  * @font: a font.
- * @glyph: 
- * @direction: 
- * @x: (out): 
- * @y: (out): 
+ * @glyph:
+ * @direction:
+ * @x: (out):
+ * @y: (out):
+ *
  *
- * 
  *
  * Since: 0.9.2
  **/
@@ -1176,16 +1202,15 @@ hb_font_subtract_glyph_origin_for_direction (hb_font_t *font,
 /**
  * hb_font_get_glyph_kerning_for_direction:
  * @font: a font.
- * @first_glyph: 
- * @second_glyph: 
- * @direction: 
- * @x: (out): 
- * @y: (out): 
+ * @first_glyph:
+ * @second_glyph:
+ * @direction:
+ * @x: (out):
+ * @y: (out):
+ *
  *
- * 
  *
  * Since: 0.9.2
- * Deprecated: 2.0.0
  **/
 void
 hb_font_get_glyph_kerning_for_direction (hb_font_t *font,
@@ -1199,13 +1224,13 @@ hb_font_get_glyph_kerning_for_direction (hb_font_t *font,
 /**
  * hb_font_get_glyph_extents_for_origin:
  * @font: a font.
- * @glyph: 
- * @direction: 
- * @extents: (out): 
+ * @glyph:
+ * @direction:
+ * @extents: (out):
  *
- * 
  *
- * Return value: 
+ *
+ * Return value:
  *
  * Since: 0.9.2
  **/
@@ -1221,15 +1246,15 @@ hb_font_get_glyph_extents_for_origin (hb_font_t *font,
 /**
  * hb_font_get_glyph_contour_point_for_origin:
  * @font: a font.
- * @glyph: 
- * @point_index: 
- * @direction: 
- * @x: (out): 
- * @y: (out): 
+ * @glyph:
+ * @point_index:
+ * @direction:
+ * @x: (out):
+ * @y: (out):
  *
- * 
  *
- * Return value: 
+ *
+ * Return value:
  *
  * Since: 0.9.2
  **/
@@ -1246,11 +1271,11 @@ hb_font_get_glyph_contour_point_for_origin (hb_font_t *font,
 /**
  * hb_font_glyph_to_string:
  * @font: a font.
- * @glyph: 
- * @s: (array length=size): 
- * @size: 
+ * @glyph:
+ * @s: (array length=size):
+ * @size:
+ *
  *
- * 
  *
  * Since: 0.9.2
  **/
@@ -1266,13 +1291,13 @@ hb_font_glyph_to_string (hb_font_t *font,
 /**
  * hb_font_glyph_from_string:
  * @font: a font.
- * @s: (array length=len) (element-type uint8_t): 
- * @len: 
- * @glyph: (out): 
+ * @s: (array length=len) (element-type uint8_t):
+ * @len:
+ * @glyph: (out):
  *
- * 
  *
- * Return value: 
+ *
+ * Return value:
  *
  * Since: 0.9.2
  **/
@@ -1298,6 +1323,8 @@ DEFINE_NULL_INSTANCE (hb_font_t) =
 
   1000, /* x_scale */
   1000, /* y_scale */
+  1<<16, /* x_mult */
+  1<<16, /* y_mult */
 
   0, /* x_ppem */
   0, /* y_ppem */
@@ -1328,6 +1355,7 @@ _hb_font_create (hb_face_t *face)
   font->klass = hb_font_funcs_get_empty ();
   font->data.init0 (font);
   font->x_scale = font->y_scale = hb_face_get_upem (face);
+  font->x_mult = font->y_mult = 1 << 16;
 
   return font;
 }
@@ -1336,9 +1364,9 @@ _hb_font_create (hb_face_t *face)
  * hb_font_create: (Xconstructor)
  * @face: a face.
  *
- * 
  *
- * Return value: (transfer full): 
+ *
+ * Return value: (transfer full):
  *
  * Since: 0.9.2
  **/
@@ -1347,8 +1375,10 @@ hb_font_create (hb_face_t *face)
 {
   hb_font_t *font = _hb_font_create (face);
 
+#ifndef HB_NO_OT_FONT
   /* Install our in-house, very lightweight, funcs. */
   hb_ot_font_set_funcs (font);
+#endif
 
   return font;
 }
@@ -1357,9 +1387,9 @@ hb_font_create (hb_face_t *face)
  * hb_font_create_sub_font:
  * @parent: parent font.
  *
- * 
  *
- * Return value: (transfer full): 
+ *
+ * Return value: (transfer full):
  *
  * Since: 0.9.2
  **/
@@ -1378,14 +1408,13 @@ hb_font_create_sub_font (hb_font_t *parent)
 
   font->x_scale = parent->x_scale;
   font->y_scale = parent->y_scale;
+  font->mults_changed ();
   font->x_ppem = parent->x_ppem;
   font->y_ppem = parent->y_ppem;
   font->ptem = parent->ptem;
 
   font->num_coords = parent->num_coords;
-  if (!font->num_coords)
-    font->coords = nullptr;
-  else
+  if (font->num_coords)
   {
     unsigned int size = parent->num_coords * sizeof (parent->coords[0]);
     font->coords = (int *) malloc (size);
@@ -1401,7 +1430,7 @@ hb_font_create_sub_font (hb_font_t *parent)
 /**
  * hb_font_get_empty:
  *
- * 
+ *
  *
  * Return value: (transfer full)
  *
@@ -1417,9 +1446,9 @@ hb_font_get_empty ()
  * hb_font_reference: (skip)
  * @font: a font.
  *
- * 
  *
- * Return value: (transfer full): 
+ *
+ * Return value: (transfer full):
  *
  * Since: 0.9.2
  **/
@@ -1433,7 +1462,7 @@ hb_font_reference (hb_font_t *font)
  * hb_font_destroy: (skip)
  * @font: a font.
  *
- * 
+ *
  *
  * Since: 0.9.2
  **/
@@ -1459,14 +1488,14 @@ hb_font_destroy (hb_font_t *font)
 /**
  * hb_font_set_user_data: (skip)
  * @font: a font.
- * @key: 
- * @data: 
- * @destroy: 
- * @replace: 
+ * @key:
+ * @data:
+ * @destroy:
+ * @replace:
  *
- * 
  *
- * Return value: 
+ *
+ * Return value:
  *
  * Since: 0.9.2
  **/
@@ -1483,11 +1512,11 @@ hb_font_set_user_data (hb_font_t          *font,
 /**
  * hb_font_get_user_data: (skip)
  * @font: a font.
- * @key: 
+ * @key:
+ *
  *
- * 
  *
- * Return value: (transfer none): 
+ * Return value: (transfer none):
  *
  * Since: 0.9.2
  **/
@@ -1502,7 +1531,7 @@ hb_font_get_user_data (hb_font_t          *font,
  * hb_font_make_immutable:
  * @font: a font.
  *
- * 
+ *
  *
  * Since: 0.9.2
  **/
@@ -1522,9 +1551,9 @@ hb_font_make_immutable (hb_font_t *font)
  * hb_font_is_immutable:
  * @font: a font.
  *
- * 
  *
- * Return value: 
+ *
+ * Return value:
  *
  * Since: 0.9.2
  **/
@@ -1564,9 +1593,9 @@ hb_font_set_parent (hb_font_t *font,
  * hb_font_get_parent:
  * @font: a font.
  *
- * 
  *
- * Return value: (transfer none): 
+ *
+ * Return value: (transfer none):
  *
  * Since: 0.9.2
  **/
@@ -1597,7 +1626,9 @@ hb_font_set_face (hb_font_t *font,
 
   hb_face_t *old = font->face;
 
+  hb_face_make_immutable (face);
   font->face = hb_face_reference (face);
+  font->mults_changed ();
 
   hb_face_destroy (old);
 }
@@ -1606,9 +1637,9 @@ hb_font_set_face (hb_font_t *font,
  * hb_font_get_face:
  * @font: a font.
  *
- * 
  *
- * Return value: (transfer none): 
+ *
+ * Return value: (transfer none):
  *
  * Since: 0.9.2
  **/
@@ -1623,10 +1654,10 @@ hb_font_get_face (hb_font_t *font)
  * hb_font_set_funcs:
  * @font: a font.
  * @klass: (closure font_data) (destroy destroy) (scope notified):
- * @font_data: 
- * @destroy: 
+ * @font_data:
+ * @destroy:
+ *
  *
- * 
  *
  * Since: 0.9.2
  **/
@@ -1660,16 +1691,16 @@ hb_font_set_funcs (hb_font_t         *font,
  * hb_font_set_funcs_data:
  * @font: a font.
  * @font_data: (destroy destroy) (scope notified):
- * @destroy: 
+ * @destroy:
+ *
  *
- * 
  *
  * Since: 0.9.2
  **/
 void
 hb_font_set_funcs_data (hb_font_t         *font,
-                       void              *font_data,
-                       hb_destroy_func_t  destroy)
+                       void              *font_data,
+                       hb_destroy_func_t  destroy)
 {
   /* Destroy user_data? */
   if (hb_object_is_immutable (font))
@@ -1690,10 +1721,10 @@ hb_font_set_funcs_data (hb_font_t         *font,
 /**
  * hb_font_set_scale:
  * @font: a font.
- * @x_scale: 
- * @y_scale: 
+ * @x_scale:
+ * @y_scale:
+ *
  *
- * 
  *
  * Since: 0.9.2
  **/
@@ -1707,15 +1738,16 @@ hb_font_set_scale (hb_font_t *font,
 
   font->x_scale = x_scale;
   font->y_scale = y_scale;
+  font->mults_changed ();
 }
 
 /**
  * hb_font_get_scale:
  * @font: a font.
- * @x_scale: (out): 
- * @y_scale: (out): 
+ * @x_scale: (out):
+ * @y_scale: (out):
+ *
  *
- * 
  *
  * Since: 0.9.2
  **/
@@ -1731,10 +1763,10 @@ hb_font_get_scale (hb_font_t *font,
 /**
  * hb_font_set_ppem:
  * @font: a font.
- * @x_ppem: 
- * @y_ppem: 
+ * @x_ppem:
+ * @y_ppem:
+ *
  *
- * 
  *
  * Since: 0.9.2
  **/
@@ -1753,10 +1785,10 @@ hb_font_set_ppem (hb_font_t *font,
 /**
  * hb_font_get_ppem:
  * @font: a font.
- * @x_ppem: (out): 
- * @y_ppem: (out): 
+ * @x_ppem: (out):
+ * @y_ppem: (out):
+ *
  *
- * 
  *
  * Since: 0.9.2
  **/
@@ -1805,6 +1837,7 @@ hb_font_get_ptem (hb_font_t *font)
   return font->ptem;
 }
 
+#ifndef HB_NO_VAR
 /*
  * Variations
  */
@@ -1873,6 +1906,33 @@ hb_font_set_var_coords_design (hb_font_t *font,
 }
 
 /**
+ * hb_font_set_var_named_instance:
+ * @font: a font.
+ * @instance_index: 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)
+{
+  if (hb_object_is_immutable (font))
+    return;
+
+  unsigned int coords_length = hb_ot_var_named_instance_get_design_coords (font->face, instance_index, nullptr, nullptr);
+
+  float *coords = coords_length ? (float *) 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);
+  free (coords);
+}
+
+/**
  * hb_font_set_var_coords_normalized:
  *
  * Since: 1.4.2
@@ -1912,8 +1972,9 @@ hb_font_get_var_coords_normalized (hb_font_t *font,
 
   return font->coords;
 }
+#endif
 
-
+#ifndef HB_DISABLE_DEPRECATED
 /*
  * Deprecated get_glyph_func():
  */
@@ -2036,3 +2097,4 @@ hb_font_funcs_set_glyph_func (hb_font_funcs_t *ffuncs,
                                          trampoline,
                                          trampoline_destroy);
 }
+#endif
index e2086d8..01ff201 100644 (file)
@@ -157,6 +157,11 @@ typedef hb_bool_t (*hb_font_get_glyph_origin_func_t) (hb_font_t *font, void *fon
 typedef hb_font_get_glyph_origin_func_t hb_font_get_glyph_h_origin_func_t;
 typedef hb_font_get_glyph_origin_func_t hb_font_get_glyph_v_origin_func_t;
 
+typedef hb_position_t (*hb_font_get_glyph_kerning_func_t) (hb_font_t *font, void *font_data,
+                                                          hb_codepoint_t first_glyph, hb_codepoint_t second_glyph,
+                                                          void *user_data);
+typedef hb_font_get_glyph_kerning_func_t hb_font_get_glyph_h_kerning_func_t;
+
 
 typedef hb_bool_t (*hb_font_get_glyph_extents_func_t) (hb_font_t *font, void *font_data,
                                                       hb_codepoint_t glyph,
@@ -219,7 +224,7 @@ hb_font_funcs_set_font_v_extents_func (hb_font_funcs_t *ffuncs,
  * @user_data:
  * @destroy:
  *
- * 
+ *
  *
  * Since: 1.2.3
  **/
@@ -251,7 +256,7 @@ hb_font_funcs_set_nominal_glyphs_func (hb_font_funcs_t *ffuncs,
  * @user_data:
  * @destroy:
  *
- * 
+ *
  *
  * Since: 1.2.3
  **/
@@ -267,7 +272,7 @@ hb_font_funcs_set_variation_glyph_func (hb_font_funcs_t *ffuncs,
  * @user_data:
  * @destroy:
  *
- * 
+ *
  *
  * Since: 0.9.2
  **/
@@ -283,7 +288,7 @@ hb_font_funcs_set_glyph_h_advance_func (hb_font_funcs_t *ffuncs,
  * @user_data:
  * @destroy:
  *
- * 
+ *
  *
  * Since: 0.9.2
  **/
@@ -299,7 +304,7 @@ hb_font_funcs_set_glyph_v_advance_func (hb_font_funcs_t *ffuncs,
  * @user_data:
  * @destroy:
  *
- * 
+ *
  *
  * Since: 1.8.6
  **/
@@ -315,7 +320,7 @@ hb_font_funcs_set_glyph_h_advances_func (hb_font_funcs_t *ffuncs,
  * @user_data:
  * @destroy:
  *
- * 
+ *
  *
  * Since: 1.8.6
  **/
@@ -331,7 +336,7 @@ hb_font_funcs_set_glyph_v_advances_func (hb_font_funcs_t *ffuncs,
  * @user_data:
  * @destroy:
  *
- * 
+ *
  *
  * Since: 0.9.2
  **/
@@ -347,7 +352,7 @@ hb_font_funcs_set_glyph_h_origin_func (hb_font_funcs_t *ffuncs,
  * @user_data:
  * @destroy:
  *
- * 
+ *
  *
  * Since: 0.9.2
  **/
@@ -357,13 +362,29 @@ hb_font_funcs_set_glyph_v_origin_func (hb_font_funcs_t *ffuncs,
                                       void *user_data, hb_destroy_func_t destroy);
 
 /**
+ * hb_font_funcs_set_glyph_h_kerning_func:
+ * @ffuncs: font functions.
+ * @func: (closure user_data) (destroy destroy) (scope notified):
+ * @user_data:
+ * @destroy:
+ *
+ *
+ *
+ * Since: 0.9.2
+ **/
+HB_EXTERN void
+hb_font_funcs_set_glyph_h_kerning_func (hb_font_funcs_t *ffuncs,
+                                       hb_font_get_glyph_h_kerning_func_t func,
+                                       void *user_data, hb_destroy_func_t destroy);
+
+/**
  * hb_font_funcs_set_glyph_extents_func:
  * @ffuncs: font functions.
  * @func: (closure user_data) (destroy destroy) (scope notified):
  * @user_data:
  * @destroy:
  *
- * 
+ *
  *
  * Since: 0.9.2
  **/
@@ -379,7 +400,7 @@ hb_font_funcs_set_glyph_extents_func (hb_font_funcs_t *ffuncs,
  * @user_data:
  * @destroy:
  *
- * 
+ *
  *
  * Since: 0.9.2
  **/
@@ -395,7 +416,7 @@ hb_font_funcs_set_glyph_contour_point_func (hb_font_funcs_t *ffuncs,
  * @user_data:
  * @destroy:
  *
- * 
+ *
  *
  * Since: 0.9.2
  **/
@@ -411,7 +432,7 @@ hb_font_funcs_set_glyph_name_func (hb_font_funcs_t *ffuncs,
  * @user_data:
  * @destroy:
  *
- * 
+ *
  *
  * Since: 0.9.2
  **/
@@ -438,6 +459,14 @@ hb_font_get_variation_glyph (hb_font_t *font,
                             hb_codepoint_t unicode, hb_codepoint_t variation_selector,
                             hb_codepoint_t *glyph);
 
+HB_EXTERN unsigned int
+hb_font_get_nominal_glyphs (hb_font_t *font,
+                           unsigned int count,
+                           const hb_codepoint_t *first_unicode,
+                           unsigned int unicode_stride,
+                           hb_codepoint_t *first_glyph,
+                           unsigned int glyph_stride);
+
 HB_EXTERN hb_position_t
 hb_font_get_glyph_h_advance (hb_font_t *font,
                             hb_codepoint_t glyph);
@@ -469,6 +498,10 @@ hb_font_get_glyph_v_origin (hb_font_t *font,
                            hb_codepoint_t glyph,
                            hb_position_t *x, hb_position_t *y);
 
+HB_EXTERN hb_position_t
+hb_font_get_glyph_h_kerning (hb_font_t *font,
+                            hb_codepoint_t left_glyph, hb_codepoint_t right_glyph);
+
 HB_EXTERN hb_bool_t
 hb_font_get_glyph_extents (hb_font_t *font,
                           hb_codepoint_t glyph,
@@ -531,6 +564,12 @@ hb_font_subtract_glyph_origin_for_direction (hb_font_t *font,
                                             hb_direction_t direction,
                                             hb_position_t *x, hb_position_t *y);
 
+HB_EXTERN void
+hb_font_get_glyph_kerning_for_direction (hb_font_t *font,
+                                        hb_codepoint_t first_glyph, hb_codepoint_t second_glyph,
+                                        hb_direction_t direction,
+                                        hb_position_t *x, hb_position_t *y);
+
 HB_EXTERN hb_bool_t
 hb_font_get_glyph_extents_for_origin (hb_font_t *font,
                                      hb_codepoint_t glyph,
@@ -618,8 +657,8 @@ hb_font_set_funcs (hb_font_t         *font,
 /* Be *very* careful with this function! */
 HB_EXTERN void
 hb_font_set_funcs_data (hb_font_t         *font,
-                       void              *font_data,
-                       hb_destroy_func_t  destroy);
+                       void              *font_data,
+                       hb_destroy_func_t  destroy);
 
 
 HB_EXTERN void
@@ -674,6 +713,10 @@ HB_EXTERN const int *
 hb_font_get_var_coords_normalized (hb_font_t *font,
                                   unsigned int *length);
 
+HB_EXTERN void
+hb_font_set_var_named_instance (hb_font_t *font,
+                               unsigned instance_index);
+
 HB_END_DECLS
 
 #endif /* HB_FONT_H */
index aaa0fd9..b1e8e64 100644 (file)
@@ -52,7 +52,7 @@
   HB_FONT_FUNC_IMPLEMENT (glyph_h_origin) \
   HB_FONT_FUNC_IMPLEMENT (glyph_v_origin) \
   HB_FONT_FUNC_IMPLEMENT (glyph_h_kerning) \
-  HB_FONT_FUNC_IMPLEMENT (glyph_v_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) \
@@ -107,8 +107,10 @@ struct hb_font_t
   hb_font_t *parent;
   hb_face_t *face;
 
-  int x_scale;
-  int y_scale;
+  int32_t x_scale;
+  int32_t y_scale;
+  int64_t x_mult;
+  int64_t y_mult;
 
   unsigned int x_ppem;
   unsigned int y_ppem;
@@ -127,16 +129,16 @@ struct hb_font_t
 
 
   /* Convert from font-space to user-space */
-  int dir_scale (hb_direction_t direction)
-  { return HB_DIRECTION_IS_VERTICAL(direction) ? y_scale : x_scale; }
-  hb_position_t em_scale_x (int16_t v) { return em_scale (v, x_scale); }
-  hb_position_t em_scale_y (int16_t v) { return em_scale (v, y_scale); }
-  hb_position_t em_scalef_x (float v) { return em_scalef (v, this->x_scale); }
-  hb_position_t em_scalef_y (float v) { return em_scalef (v, this->y_scale); }
+  int64_t dir_mult (hb_direction_t direction)
+  { return HB_DIRECTION_IS_VERTICAL(direction) ? y_mult : x_mult; }
+  hb_position_t em_scale_x (int16_t v) { return em_mult (v, x_mult); }
+  hb_position_t em_scale_y (int16_t v) { return em_mult (v, y_mult); }
+  hb_position_t em_scalef_x (float v) { return em_scalef (v, x_scale); }
+  hb_position_t em_scalef_y (float v) { return em_scalef (v, y_scale); }
   float em_fscale_x (int16_t v) { return em_fscale (v, x_scale); }
   float em_fscale_y (int16_t v) { return em_fscale (v, y_scale); }
   hb_position_t em_scale_dir (int16_t v, hb_direction_t direction)
-  { return em_scale (v, dir_scale (direction)); }
+  { return em_mult (v, dir_mult (direction)); }
 
   /* Convert from parent-font user-space to our user-space */
   hb_position_t parent_scale_x_distance (hb_position_t v)
@@ -214,7 +216,7 @@ struct hb_font_t
   }
 
   hb_bool_t get_nominal_glyph (hb_codepoint_t unicode,
-                                     hb_codepoint_t *glyph)
+                              hb_codepoint_t *glyph)
   {
     *glyph = 0;
     return klass->get.f.nominal_glyph (this, user_data,
@@ -284,7 +286,7 @@ struct hb_font_t
   }
 
   hb_bool_t get_glyph_h_origin (hb_codepoint_t glyph,
-                                      hb_position_t *x, hb_position_t *y)
+                               hb_position_t *x, hb_position_t *y)
   {
     *x = *y = 0;
     return klass->get.f.glyph_h_origin (this, user_data,
@@ -304,21 +306,29 @@ struct hb_font_t
   hb_position_t get_glyph_h_kerning (hb_codepoint_t left_glyph,
                                     hb_codepoint_t right_glyph)
   {
+#ifdef HB_DISABLE_DEPRECATED
+    return 0;
+#else
     return klass->get.f.glyph_h_kerning (this, user_data,
                                         left_glyph, right_glyph,
                                         klass->user_data.glyph_h_kerning);
+#endif
   }
 
   hb_position_t get_glyph_v_kerning (hb_codepoint_t top_glyph,
                                     hb_codepoint_t bottom_glyph)
   {
+#ifdef HB_DISABLE_DEPRECATED
+    return 0;
+#else
     return klass->get.f.glyph_v_kerning (this, user_data,
                                         top_glyph, bottom_glyph,
                                         klass->user_data.glyph_v_kerning);
+#endif
   }
 
   hb_bool_t get_glyph_extents (hb_codepoint_t glyph,
-                                     hb_glyph_extents_t *extents)
+                              hb_glyph_extents_t *extents)
   {
     memset (extents, 0, sizeof (*extents));
     return klass->get.f.glyph_extents (this, user_data,
@@ -489,7 +499,7 @@ struct hb_font_t
   }
 
   void subtract_glyph_h_origin (hb_codepoint_t glyph,
-                               hb_position_t *x, hb_position_t *y)
+                               hb_position_t *x, hb_position_t *y)
   {
     hb_position_t origin_x, origin_y;
 
@@ -599,15 +609,19 @@ struct hb_font_t
     return false;
   }
 
-  hb_position_t em_scale (int16_t v, int scale)
+  void mults_changed ()
+  {
+    signed upem = face->get_upem ();
+    x_mult = ((int64_t) x_scale << 16) / upem;
+    y_mult = ((int64_t) y_scale << 16) / upem;
+  }
+
+  hb_position_t em_mult (int16_t v, int64_t mult)
   {
-    int upem = face->get_upem ();
-    int64_t scaled = v * (int64_t) scale;
-    scaled += scaled >= 0 ? upem/2 : -upem/2; /* Round. */
-    return (hb_position_t) (scaled / upem);
+    return (hb_position_t) ((v * mult) >> 16);
   }
   hb_position_t em_scalef (float v, int scale)
-  { return (hb_position_t) round (v * scale / face->get_upem ()); }
+  { return (hb_position_t) roundf (v * scale / face->get_upem ()); }
   float em_fscale (int16_t v, int scale)
   { return (float) v * scale / face->get_upem (); }
 };
index 1900f30..e526bf4 100644 (file)
@@ -29,6 +29,8 @@
 
 #include "hb.hh"
 
+#ifdef HAVE_FREETYPE
+
 #include "hb-ft.h"
 
 #include "hb-font.hh"
@@ -96,7 +98,7 @@ _hb_ft_font_create (FT_Face ft_face, bool symbol, bool unref)
 
   ft_font->load_flags = FT_LOAD_DEFAULT | FT_LOAD_NO_HINTING;
 
-  ft_font->cached_x_scale.set (0);
+  ft_font->cached_x_scale.set_relaxed (0);
   ft_font->advance_cache.init ();
 
   return ft_font;
@@ -346,6 +348,25 @@ hb_ft_get_glyph_v_origin (hb_font_t *font,
   return true;
 }
 
+#ifndef HB_NO_OT_SHAPE_FALLBACK
+static hb_position_t
+hb_ft_get_glyph_h_kerning (hb_font_t *font,
+                          void *font_data,
+                          hb_codepoint_t left_glyph,
+                          hb_codepoint_t right_glyph,
+                          void *user_data HB_UNUSED)
+{
+  const hb_ft_font_t *ft_font = (const hb_ft_font_t *) font_data;
+  FT_Vector kerningv;
+
+  FT_Kerning_Mode mode = font->x_ppem ? FT_KERNING_DEFAULT : FT_KERNING_UNFITTED;
+  if (FT_Get_Kerning (ft_font->ft_face, left_glyph, right_glyph, mode, &kerningv))
+    return 0;
+
+  return kerningv.x;
+}
+#endif
+
 static hb_bool_t
 hb_ft_get_glyph_extents (hb_font_t *font,
                         void *font_data,
@@ -439,7 +460,7 @@ hb_ft_get_glyph_from_name (hb_font_t *font HB_UNUSED,
   else {
     /* Make a nul-terminated version. */
     char buf[128];
-    len = MIN (len, (int) sizeof (buf) - 1);
+    len = hb_min (len, (int) sizeof (buf) - 1);
     strncpy (buf, name, len);
     buf[len] = '\0';
     *glyph = FT_Get_Name_Index (ft_face, buf);
@@ -450,7 +471,7 @@ hb_ft_get_glyph_from_name (hb_font_t *font HB_UNUSED,
     /* Check whether the given name was actually the name of glyph 0. */
     char buf[128];
     if (!FT_Get_Glyph_Name(ft_face, 0, buf, sizeof (buf)) &&
-        len < 0 ? !strcmp (buf, name) : !strncmp (buf, name, len))
+       len < 0 ? !strcmp (buf, name) : !strncmp (buf, name, len))
       return true;
   }
 
@@ -497,6 +518,10 @@ static struct hb_ft_font_funcs_lazy_loader_t : hb_font_funcs_lazy_loader_t<hb_ft
     hb_font_funcs_set_glyph_v_advance_func (funcs, hb_ft_get_glyph_v_advance, nullptr, nullptr);
     //hb_font_funcs_set_glyph_h_origin_func (funcs, hb_ft_get_glyph_h_origin, nullptr, nullptr);
     hb_font_funcs_set_glyph_v_origin_func (funcs, hb_ft_get_glyph_v_origin, nullptr, nullptr);
+#ifndef HB_NO_OT_SHAPE_FALLBACK
+    hb_font_funcs_set_glyph_h_kerning_func (funcs, hb_ft_get_glyph_h_kerning, nullptr, nullptr);
+#endif
+    //hb_font_funcs_set_glyph_v_kerning_func (funcs, hb_ft_get_glyph_v_kerning, nullptr, nullptr);
     hb_font_funcs_set_glyph_extents_func (funcs, hb_ft_get_glyph_extents, nullptr, nullptr);
     hb_font_funcs_set_glyph_contour_point_func (funcs, hb_ft_get_glyph_contour_point, nullptr, nullptr);
     hb_font_funcs_set_glyph_name_func (funcs, hb_ft_get_glyph_name, nullptr, nullptr);
@@ -539,7 +564,7 @@ _hb_ft_font_set_funcs (hb_font_t *font, FT_Face ft_face, bool unref)
 
 
 static hb_blob_t *
-reference_table  (hb_face_t *face HB_UNUSED, hb_tag_t tag, void *user_data)
+_hb_ft_reference_table (hb_face_t *face HB_UNUSED, hb_tag_t tag, void *user_data)
 {
   FT_Face ft_face = (FT_Face) user_data;
   FT_Byte *buffer;
@@ -594,7 +619,7 @@ hb_ft_face_create (FT_Face           ft_face,
     face = hb_face_create (blob, ft_face->face_index);
     hb_blob_destroy (blob);
   } else {
-    face = hb_face_create_for_tables (reference_table, ft_face, destroy);
+    face = hb_face_create_for_tables (_hb_ft_reference_table, ft_face, destroy);
   }
 
   hb_face_set_index (face, ft_face->face_index);
@@ -748,7 +773,7 @@ hb_ft_font_create_referenced (FT_Face ft_face)
 static void free_static_ft_library ();
 #endif
 
-static struct hb_ft_library_lazy_loader_t : hb_lazy_loader_t<hb_remove_pointer (FT_Library),
+static struct hb_ft_library_lazy_loader_t : hb_lazy_loader_t<hb_remove_pointer<FT_Library>,
                                                             hb_ft_library_lazy_loader_t>
 {
   static FT_Library create ()
@@ -815,8 +840,8 @@ hb_ft_font_set_funcs (hb_font_t *font)
     return;
   }
 
-  if (FT_Select_Charmap (ft_face, FT_ENCODING_UNICODE))
-    FT_Select_Charmap (ft_face, FT_ENCODING_MS_SYMBOL);
+  if (FT_Select_Charmap (ft_face, FT_ENCODING_MS_SYMBOL))
+    FT_Select_Charmap (ft_face, FT_ENCODING_UNICODE);
 
   FT_Set_Char_Size (ft_face,
                    abs (font->x_scale), abs (font->y_scale),
@@ -841,7 +866,7 @@ hb_ft_font_set_funcs (hb_font_t *font)
     if (ft_coords)
     {
       for (unsigned int i = 0; i < num_coords; i++)
-       ft_coords[i] = coords[i] << 2;
+       ft_coords[i] = coords[i] * 4;
       FT_Set_Var_Blend_Coordinates (ft_face, num_coords, ft_coords);
       free (ft_coords);
     }
@@ -854,3 +879,6 @@ hb_ft_font_set_funcs (hb_font_t *font)
   _hb_ft_font_set_funcs (font, ft_face, true);
   hb_ft_font_set_load_flags (font, FT_LOAD_DEFAULT | FT_LOAD_NO_HINTING);
 }
+
+
+#endif
diff --git a/src/hb-gdi.cc b/src/hb-gdi.cc
new file mode 100644 (file)
index 0000000..f6306ef
--- /dev/null
@@ -0,0 +1,73 @@
+/*
+ * Copyright © 2019  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.
+ */
+
+#include "hb.hh"
+
+#ifdef HAVE_GDI
+
+#include "hb-gdi.h"
+
+static hb_blob_t *
+_hb_gdi_reference_table (hb_face_t *face HB_UNUSED, hb_tag_t tag, void *user_data)
+{
+  char *buffer = nullptr;
+  DWORD length = 0;
+
+  HDC hdc = GetDC (nullptr);
+  if (unlikely (!SelectObject (hdc, (HFONT) user_data))) goto fail;
+
+  length = GetFontData (hdc, hb_uint32_swap (tag), 0, buffer, length);
+  if (unlikely (length == GDI_ERROR)) goto fail_with_releasedc;
+
+  buffer = (char *) malloc (length);
+  if (unlikely (!buffer)) goto fail_with_releasedc;
+  length = GetFontData (hdc, hb_uint32_swap (tag), 0, buffer, length);
+  if (unlikely (length == GDI_ERROR)) goto fail_with_releasedc_and_free;
+  ReleaseDC (nullptr, hdc);
+
+  return hb_blob_create ((const char *) buffer, length, HB_MEMORY_MODE_WRITABLE, buffer, free);
+
+fail_with_releasedc_and_free:
+  free (buffer);
+fail_with_releasedc:
+  ReleaseDC (nullptr, hdc);
+fail:
+  return hb_blob_get_empty ();
+}
+
+/**
+ * hb_gdi_face_create:
+ * @hfont: a HFONT object.
+ *
+ * Return value: #hb_face_t object corresponding to the given input
+ *
+ * Since: 2.6.0
+ **/
+hb_face_t *
+hb_gdi_face_create (HFONT hfont)
+{
+  return hb_face_create_for_tables (_hb_gdi_reference_table, (void *) hfont, nullptr);
+}
+
+#endif
diff --git a/src/hb-gdi.h b/src/hb-gdi.h
new file mode 100644 (file)
index 0000000..68cc439
--- /dev/null
@@ -0,0 +1,39 @@
+/*
+ * Copyright © 2019  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_GDI_H
+#define HB_GDI_H
+
+#include "hb.h"
+
+#include <windows.h>
+
+HB_BEGIN_DECLS
+
+HB_EXTERN hb_face_t *
+hb_gdi_face_create (HFONT hfont);
+
+HB_END_DECLS
+
+#endif /* HB_GDI_H */
index 5763754..db02b67 100644 (file)
@@ -28,6 +28,8 @@
 
 #include "hb.hh"
 
+#ifdef HAVE_GLIB
+
 #include "hb-glib.h"
 
 #include "hb-machinery.hh"
@@ -404,3 +406,6 @@ hb_glib_blob_create (GBytes *gbytes)
                         _hb_g_bytes_unref);
 }
 #endif
+
+
+#endif
index e3a9a6b..17f1ade 100644 (file)
@@ -27,6 +27,8 @@
 
 #include "hb.hh"
 
+#ifdef HAVE_GOBJECT
+
 /* g++ didn't like older gtype.h gcc-only code path. */
 #include <glib.h>
 #if !GLIB_CHECK_VERSION(2,29,16)
 /* enumerations from "@filename@" */
 /*** END file-production ***/
 
+/*** BEGIN file-tail ***/
+
+#endif
+/*** END file-tail ***/
+
 /*** BEGIN value-header ***/
 GType
 @enum_name@_get_type ()
index 3cff880..7f4922e 100644 (file)
@@ -26,6 +26,8 @@
 
 #include "hb.hh"
 
+#ifdef HAVE_GOBJECT
+
 
 /**
  * SECTION:hb-gobject
@@ -94,3 +96,6 @@ HB_DEFINE_VALUE_TYPE (user_data_key)
 
 HB_DEFINE_VALUE_TYPE (ot_math_glyph_variant)
 HB_DEFINE_VALUE_TYPE (ot_math_glyph_part)
+
+
+#endif
index fdb5453..f0f2f8c 100644 (file)
  * Google Author(s): Behdad Esfahbod
  */
 
+#include "hb.hh"
+
+#ifdef HAVE_GRAPHITE2
+
 #include "hb-shaper-impl.hh"
 
 #include "hb-graphite2.h"
@@ -102,32 +106,6 @@ retry:
   return d;
 }
 
-static void hb_graphite2_release_table(const void *data, const void *table_buffer)
-{
-  hb_graphite2_face_data_t *face_data = (hb_graphite2_face_data_t *) data;
-  hb_graphite2_tablelist_t *tlist = face_data->tlist;
-
-  hb_graphite2_tablelist_t *prev = nullptr;
-  hb_graphite2_tablelist_t *curr = tlist;
-  while (curr)
-  {
-    if (hb_blob_get_data(curr->blob, nullptr) == table_buffer)
-    {
-      if (prev == nullptr)
-        face_data->tlist.cmpexch(tlist, curr->next);
-      else
-        prev->next = curr->next;
-      hb_blob_destroy(curr->blob);
-      free(curr);
-      break;
-    }
-    prev = curr;
-    curr = curr->next;
-  }
-}
-
-static gr_face_ops hb_graphite2_face_ops = { sizeof(gr_face_ops), hb_graphite2_get_table, hb_graphite2_release_table };
-
 hb_graphite2_face_data_t *
 _hb_graphite2_shaper_face_data_create (hb_face_t *face)
 {
@@ -146,7 +124,7 @@ _hb_graphite2_shaper_face_data_create (hb_face_t *face)
     return nullptr;
 
   data->face = face;
-  data->grface = gr_make_face_with_ops (data, &hb_graphite2_face_ops, gr_face_preloadAll);
+  data->grface = gr_make_face (data, &hb_graphite2_get_table, gr_face_preloadAll);
 
   if (unlikely (!data->grface)) {
     free (data);
@@ -202,6 +180,7 @@ _hb_graphite2_shaper_font_data_destroy (hb_graphite2_font_data_t *data HB_UNUSED
 {
 }
 
+#ifndef HB_DISABLE_DEPRECATED
 /**
  * hb_graphite2_font_get_gr_font:
  *
@@ -213,6 +192,7 @@ hb_graphite2_font_get_gr_font (hb_font_t *font HB_UNUSED)
 {
   return nullptr;
 }
+#endif
 
 
 /*
@@ -308,12 +288,12 @@ _hb_graphite2_shape (hb_shape_plan_t    *shape_plan HB_UNUSED,
 
 #define ALLOCATE_ARRAY(Type, name, len) \
   Type *name = (Type *) scratch; \
-  { \
+  do { \
     unsigned int _consumed = DIV_CEIL ((len) * sizeof (Type), sizeof (*scratch)); \
     assert (_consumed <= scratch_size); \
     scratch += _consumed; \
     scratch_size -= _consumed; \
-  }
+  } while (0)
 
   ALLOCATE_ARRAY (hb_graphite2_cluster_t, clusters, buffer->len);
   ALLOCATE_ARRAY (hb_codepoint_t, gids, glyph_count);
@@ -360,14 +340,14 @@ _hb_graphite2_shape (hb_shape_plan_t    *shape_plan HB_UNUSED,
       c->num_glyphs = 0;
       if (HB_DIRECTION_IS_BACKWARD(buffer->props.direction))
       {
-        c->advance = curradv - gr_slot_origin_X(is) * xscale;
-        curradv -= c->advance;
+       c->advance = curradv - gr_slot_origin_X(is) * xscale;
+       curradv -= c->advance;
       }
       else
       {
-        c->advance = 0;
-        clusters[ci].advance += gr_slot_origin_X(is) * xscale - curradv;
-        curradv += clusters[ci].advance;
+       c->advance = 0;
+       clusters[ci].advance += gr_slot_origin_X(is) * xscale - curradv;
+       curradv += clusters[ci].advance;
       }
       ci++;
     }
@@ -445,3 +425,6 @@ _hb_graphite2_shape (hb_shape_plan_t    *shape_plan HB_UNUSED,
 
   return true;
 }
+
+
+#endif
index c26c91d..985ff02 100644 (file)
@@ -29,6 +29,8 @@
 
 #include "hb.hh"
 
+#ifdef HAVE_ICU
+
 #include "hb-icu.h"
 
 #include "hb-machinery.hh"
 #include <unicode/utf16.h>
 #include <unicode/uversion.h>
 
+/* ICU extra semicolon, fixed since 65, https://github.com/unicode-org/icu/commit/480bec3 */
+#if U_ICU_VERSION_MAJOR_NUM < 65 && (defined(__GNUC__) || defined(__clang__))
+#define HB_ICU_EXTRA_SEMI_IGNORED
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wextra-semi-stmt"
+#endif
 
 /**
  * SECTION:hb-icu
@@ -49,7 +57,6 @@
  * Functions for using HarfBuzz with the ICU library to provide Unicode data.
  **/
 
-
 hb_script_t
 hb_icu_script_to_script (UScriptCode script)
 {
@@ -225,7 +232,7 @@ hb_icu_unicode_decompose (hb_unicode_funcs_t *ufuncs HB_UNUSED,
       *b = 0;
       return *a != ab;
     } else if (len == 2) {
-      len =0;
+      len = 0;
       U16_NEXT_UNSAFE (decomposed, len, *a);
       U16_NEXT_UNSAFE (decomposed, len, *b);
     }
@@ -236,7 +243,7 @@ hb_icu_unicode_decompose (hb_unicode_funcs_t *ufuncs HB_UNUSED,
   /* We don't ifdef-out the fallback code such that compiler always
    * sees it and makes sure it's compilable. */
 
-  UChar utf16[2], normalized[2 * HB_UNICODE_MAX_DECOMPOSITION_LEN + 1];
+  UChar utf16[2], normalized[2 * 19/*HB_UNICODE_MAX_DECOMPOSITION_LEN*/ + 1];
   unsigned int len;
   hb_bool_t ret, err;
   UErrorCode icu_err;
@@ -262,7 +269,7 @@ hb_icu_unicode_decompose (hb_unicode_funcs_t *ufuncs HB_UNUSED,
     *b = 0;
     ret = *a != ab;
   } else if (len == 2) {
-    len =0;
+    len = 0;
     U16_NEXT_UNSAFE (normalized, len, *a);
     U16_NEXT_UNSAFE (normalized, len, *b);
 
@@ -348,3 +355,9 @@ hb_icu_get_unicode_funcs ()
 {
   return static_icu_funcs.get_unconst ();
 }
+
+#ifdef HB_ICU_EXTRA_SEMI_IGNORED
+#pragma GCC diagnostic pop
+#endif
+
+#endif
index c4ab26d..981c5c2 100644 (file)
@@ -1,5 +1,6 @@
 /*
  * Copyright © 2018  Google, Inc.
+ * Copyright © 2019  Facebook, Inc.
  *
  *  This is part of HarfBuzz, a text shaping library.
  *
  * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
  *
  * Google Author(s): Behdad Esfahbod
+ * Facebook Author(s): Behdad Esfahbod
  */
 
 #ifndef HB_ITER_HH
 #define HB_ITER_HH
 
 #include "hb.hh"
-#include "hb-null.hh"
+#include "hb-algs.hh"
+#include "hb-meta.hh"
 
 
 /* Unified iterator object.
  * copied by value.  If the collection / object being iterated on
  * is writable, then the iterator returns lvalues, otherwise it
  * returns rvalues.
+ *
+ * TODO Document more.
+ *
+ * If iterator implementation implements operator!=, then can be
+ * used in range-based for loop.  That comes free if the iterator
+ * is random-access.  Otherwise, the range-based for loop incurs
+ * one traversal to find end(), which can be avoided if written
+ * as a while-style for loop, or if iterator implements a faster
+ * __end__() method.
+ * TODO When opting in for C++17, address this by changing return
+ * type of .end()?
+ */
+
+/*
+ * Base classes for iterators.
  */
 
 /* Base class for all iterators. */
-template <typename Iter, typename Item = typename Iter::__item_type__>
+template <typename iter_t, typename Item = typename iter_t::__item_t__>
 struct hb_iter_t
 {
-  typedef Iter iter_t;
-  typedef iter_t const_iter_t;
   typedef Item item_t;
-  static constexpr unsigned item_size = hb_static_size (Item);
+  constexpr unsigned get_item_size () const { return hb_static_size (Item); }
+  static constexpr bool is_iterator = true;
+  static constexpr bool is_random_access_iterator = false;
+  static constexpr bool is_sorted_iterator = false;
 
   private:
   /* https://en.wikipedia.org/wiki/Curiously_recurring_template_pattern */
   const iter_t* thiz () const { return static_cast<const iter_t *> (this); }
-        iter_t* thiz ()       { return static_cast<      iter_t *> (this); }
+       iter_t* thiz ()       { return static_cast<      iter_t *> (this); }
   public:
 
-  /* Operators. */
-  operator iter_t () { return iter(); }
-  explicit_operator bool () const { return more (); }
-  item_t& operator * () const { return item (); }
-  item_t& operator [] (signed i) const { return item_at ((unsigned) i); }
-  iter_t& operator += (unsigned count) { forward (count); return *thiz(); }
-  iter_t& operator ++ () { next (); return *thiz(); }
-  iter_t& operator -= (unsigned count) { rewind (count); return *thiz(); }
-  iter_t& operator -- () { prev (); return *thiz(); }
-  iter_t operator + (unsigned count) { iter_t c (*thiz()); c += count; return c; }
-  iter_t operator ++ (int) { iter_t c (*thiz()); ++*thiz(); return c; }
-  iter_t operator - (unsigned count) { iter_t c (*thiz()); c -= count; return c; }
-  iter_t operator -- (int) { iter_t c (*thiz()); --*thiz(); return c; }
+  /* TODO:
+   * Port operators below to use hb_enable_if to sniff which method implements
+   * an operator and use it, and remove hb_iter_fallback_mixin_t completely. */
 
-  /* Methods. */
+  /* Operators. */
   iter_t iter () const { return *thiz(); }
-  const_iter_t const_iter () const { return iter (); }
-  item_t& item () const { return thiz()->__item__ (); }
-  item_t& item_at (unsigned i) const { return thiz()->__item_at__ (i); }
-  bool more () const { return thiz()->__more__ (); }
+  iter_t operator + () const { return *thiz(); }
+  iter_t begin () const { return *thiz(); }
+  iter_t end () const { return thiz()->__end__ (); }
+  explicit operator bool () const { return thiz()->__more__ (); }
   unsigned len () const { return thiz()->__len__ (); }
-  void next () { thiz()->__next__ (); }
-  void forward (unsigned n) { thiz()->__forward__ (n); }
-  void prev () { thiz()->__prev__ (); }
-  void rewind (unsigned n) { thiz()->__rewind__ (n); }
-  bool random_access () const { return thiz()->__random_access__ (); }
+  /* The following can only be enabled if item_t is reference type.  Otherwise
+   * it will be returning pointer to temporary rvalue.
+   * TODO Use a wrapper return type to fix for non-reference type. */
+  template <typename T = item_t,
+           hb_enable_if (hb_is_reference (T))>
+  hb_remove_reference<item_t>* operator -> () const { return hb_addressof (**thiz()); }
+  item_t operator * () const { return thiz()->__item__ (); }
+  item_t operator * () { return thiz()->__item__ (); }
+  item_t operator [] (unsigned i) const { return thiz()->__item_at__ (i); }
+  item_t operator [] (unsigned i) { return thiz()->__item_at__ (i); }
+  iter_t& operator += (unsigned count) &  { thiz()->__forward__ (count); return *thiz(); }
+  iter_t  operator += (unsigned count) && { thiz()->__forward__ (count); return *thiz(); }
+  iter_t& operator ++ () &  { thiz()->__next__ (); return *thiz(); }
+  iter_t  operator ++ () && { thiz()->__next__ (); return *thiz(); }
+  iter_t& operator -= (unsigned count) &  { thiz()->__rewind__ (count); return *thiz(); }
+  iter_t  operator -= (unsigned count) && { thiz()->__rewind__ (count); return *thiz(); }
+  iter_t& operator -- () &  { thiz()->__prev__ (); return *thiz(); }
+  iter_t  operator -- () && { thiz()->__prev__ (); return *thiz(); }
+  iter_t operator + (unsigned count) const { auto c = thiz()->iter (); c += count; return c; }
+  friend iter_t operator + (unsigned count, const iter_t &it) { return it + count; }
+  iter_t operator ++ (int) { iter_t c (*thiz()); ++*thiz(); return c; }
+  iter_t operator - (unsigned count) const { auto c = thiz()->iter (); c -= count; return c; }
+  iter_t operator -- (int) { iter_t c (*thiz()); --*thiz(); return c; }
+  template <typename T>
+  iter_t& operator >> (T &v) &  { v = **thiz(); ++*thiz(); return *thiz(); }
+  template <typename T>
+  iter_t  operator >> (T &v) && { v = **thiz(); ++*thiz(); return *thiz(); }
+  template <typename T>
+  iter_t& operator << (const T v) &  { **thiz() = v; ++*thiz(); return *thiz(); }
+  template <typename T>
+  iter_t  operator << (const T v) && { **thiz() = v; ++*thiz(); return *thiz(); }
 
   protected:
-  hb_iter_t () {}
-  hb_iter_t (const hb_iter_t &o HB_UNUSED) {}
-  void operator = (const hb_iter_t &o HB_UNUSED) {}
+  hb_iter_t () = default;
+  hb_iter_t (const hb_iter_t &o HB_UNUSED) = default;
+  hb_iter_t (hb_iter_t &&o HB_UNUSED) = default;
+  hb_iter_t& operator = (const hb_iter_t &o HB_UNUSED) = default;
+  hb_iter_t& operator = (hb_iter_t &&o HB_UNUSED) = default;
 };
 
-/* Base class for sorted iterators.  Does not enforce anything.
- * Just for class taxonomy and requirements. */
-template <typename Iter, typename Item = typename Iter::__item_type__>
-struct hb_sorted_iter_t : hb_iter_t<Iter, Item>
+#define HB_ITER_USING(Name) \
+  using item_t = typename Name::item_t; \
+  using Name::begin; \
+  using Name::end; \
+  using Name::get_item_size; \
+  using Name::is_iterator; \
+  using Name::iter; \
+  using Name::operator bool; \
+  using Name::len; \
+  using Name::operator ->; \
+  using Name::operator *; \
+  using Name::operator []; \
+  using Name::operator +=; \
+  using Name::operator ++; \
+  using Name::operator -=; \
+  using Name::operator --; \
+  using Name::operator +; \
+  using Name::operator -; \
+  using Name::operator >>; \
+  using Name::operator <<; \
+  static_assert (true, "")
+
+/* Returns iterator / item type of a type. */
+template <typename Iterable>
+using hb_iter_type = decltype (hb_deref (hb_declval (Iterable)).iter ());
+template <typename Iterable>
+using hb_item_type = decltype (*hb_deref (hb_declval (Iterable)).iter ());
+
+
+template <typename> struct hb_array_t;
+template <typename> struct hb_sorted_array_t;
+
+struct
 {
-  protected:
-  hb_sorted_iter_t () {}
-  hb_sorted_iter_t (const hb_sorted_iter_t &o) : hb_iter_t<Iter, Item> (o) {}
-  void operator = (const hb_sorted_iter_t &o HB_UNUSED) {}
-};
+  template <typename T> hb_iter_type<T>
+  operator () (T&& c) const
+  { return hb_deref (hb_forward<T> (c)).iter (); }
+
+  /* Specialization for C arrays. */
+
+  template <typename Type> inline hb_array_t<Type>
+  operator () (Type *array, unsigned int length) const
+  { return hb_array_t<Type> (array, length); }
+
+  template <typename Type, unsigned int length> hb_array_t<Type>
+  operator () (Type (&array)[length]) const
+  { return hb_array_t<Type> (array, length); }
+
+}
+HB_FUNCOBJ (hb_iter);
+struct
+{
+  template <typename T> unsigned
+  operator () (T&& c) const
+  { return c.len (); }
+
+}
+HB_FUNCOBJ (hb_len);
 
 /* Mixin to fill in what the subclass doesn't provide. */
-template <typename iter_t, typename item_t = typename iter_t::__item_type__>
-struct hb_iter_mixin_t
+template <typename iter_t, typename item_t = typename iter_t::__item_t__>
+struct hb_iter_fallback_mixin_t
 {
   private:
   /* https://en.wikipedia.org/wiki/Curiously_recurring_template_pattern */
   const iter_t* thiz () const { return static_cast<const iter_t *> (this); }
-        iter_t* thiz ()       { return static_cast<      iter_t *> (this); }
+       iter_t* thiz ()       { return static_cast<      iter_t *> (this); }
   public:
 
   /* Access: Implement __item__(), or __item_at__() if random-access. */
-  item_t& __item__ () const { return thiz()->item_at (0); }
-  item_t& __item_at__ (unsigned i) const { return *(thiz() + i); }
+  item_t __item__ () const { return (*thiz())[0]; }
+  item_t __item_at__ (unsigned i) const { return *(*thiz() + i); }
 
   /* Termination: Implement __more__(), or __len__() if random-access. */
-  bool __more__ () const { return thiz()->__len__ (); }
+  bool __more__ () const { return bool (thiz()->len ()); }
   unsigned __len__ () const
-  { iter_t c (*thiz()); unsigned l = 0; while (c) { c++; l++; }; return l; }
+  { iter_t c (*thiz()); unsigned l = 0; while (c) { c++; l++; } return l; }
 
   /* Advancing: Implement __next__(), or __forward__() if random-access. */
-  void __next__ () { thiz()->forward (1); }
-  void __forward__ (unsigned n) { while (n--) thiz()->next (); }
+  void __next__ () { *thiz() += 1; }
+  void __forward__ (unsigned n) { while (*thiz() && n--) ++*thiz(); }
 
   /* Rewinding: Implement __prev__() or __rewind__() if bidirectional. */
-  void __prev__ () { thiz()->rewind (1); }
-  void __rewind__ (unsigned n) { while (n--) thiz()->prev (); }
+  void __prev__ () { *thiz() -= 1; }
+  void __rewind__ (unsigned n) { while (*thiz() && n--) --*thiz(); }
+
+  /* Range-based for: Implement __end__() if can be done faster,
+   * and operator!=. */
+  iter_t __end__ () const
+  {
+    if (thiz()->is_random_access_iterator)
+      return *thiz() + thiz()->len ();
+    /* Above expression loops twice. Following loops once. */
+    auto it = *thiz();
+    while (it) ++it;
+    return it;
+  }
+
+  protected:
+  hb_iter_fallback_mixin_t () = default;
+  hb_iter_fallback_mixin_t (const hb_iter_fallback_mixin_t &o HB_UNUSED) = default;
+  hb_iter_fallback_mixin_t (hb_iter_fallback_mixin_t &&o HB_UNUSED) = default;
+  hb_iter_fallback_mixin_t& operator = (const hb_iter_fallback_mixin_t &o HB_UNUSED) = default;
+  hb_iter_fallback_mixin_t& operator = (hb_iter_fallback_mixin_t &&o HB_UNUSED) = default;
+};
+
+template <typename iter_t, typename item_t = typename iter_t::__item_t__>
+struct hb_iter_with_fallback_t :
+  hb_iter_t<iter_t, item_t>,
+  hb_iter_fallback_mixin_t<iter_t, item_t>
+{
+  protected:
+  hb_iter_with_fallback_t () = default;
+  hb_iter_with_fallback_t (const hb_iter_with_fallback_t &o HB_UNUSED) = default;
+  hb_iter_with_fallback_t (hb_iter_with_fallback_t &&o HB_UNUSED) = default;
+  hb_iter_with_fallback_t& operator = (const hb_iter_with_fallback_t &o HB_UNUSED) = default;
+  hb_iter_with_fallback_t& operator = (hb_iter_with_fallback_t &&o HB_UNUSED) = default;
+};
+
+/*
+ * Meta-programming predicates.
+ */
+
+/* hb_is_iterator() / hb_is_iterator_of() */
+
+template<typename Iter, typename Item>
+struct hb_is_iterator_of
+{
+  template <typename Item2 = Item>
+  static hb_true_type impl (hb_priority<2>, hb_iter_t<Iter, hb_type_identity<Item2>> *);
+  static hb_false_type impl (hb_priority<0>, const void *);
+
+  public:
+  static constexpr bool value = decltype (impl (hb_prioritize, hb_declval (Iter*)))::value;
+};
+#define hb_is_iterator_of(Iter, Item) hb_is_iterator_of<Iter, Item>::value
+#define hb_is_iterator(Iter) hb_is_iterator_of (Iter, typename Iter::item_t)
+
+/* hb_is_iterable() */
+
+template <typename T>
+struct hb_is_iterable
+{
+  private:
+
+  template <typename U>
+  static auto impl (hb_priority<1>) -> decltype (hb_declval (U).iter (), hb_true_type ());
+
+  template <typename>
+  static hb_false_type impl (hb_priority<0>);
+
+  public:
+  static constexpr bool value = decltype (impl<T> (hb_prioritize))::value;
+};
+#define hb_is_iterable(Iterable) hb_is_iterable<Iterable>::value
+
+/* hb_is_source_of() / hb_is_sink_of() */
+
+template<typename Iter, typename Item>
+struct hb_is_source_of
+{
+  private:
+  template <typename Iter2 = Iter,
+           hb_enable_if (hb_is_convertible (typename Iter2::item_t, hb_add_lvalue_reference<hb_add_const<Item>>))>
+  static hb_true_type impl (hb_priority<2>);
+  template <typename Iter2 = Iter>
+  static auto impl (hb_priority<1>) -> decltype (hb_declval (Iter2) >> hb_declval (Item &), hb_true_type ());
+  static hb_false_type impl (hb_priority<0>);
+
+  public:
+  static constexpr bool value = decltype (impl (hb_prioritize))::value;
+};
+#define hb_is_source_of(Iter, Item) hb_is_source_of<Iter, Item>::value
+
+template<typename Iter, typename Item>
+struct hb_is_sink_of
+{
+  private:
+  template <typename Iter2 = Iter,
+           hb_enable_if (hb_is_convertible (typename Iter2::item_t, hb_add_lvalue_reference<Item>))>
+  static hb_true_type impl (hb_priority<2>);
+  template <typename Iter2 = Iter>
+  static auto impl (hb_priority<1>) -> decltype (hb_declval (Iter2) << hb_declval (Item), hb_true_type ());
+  static hb_false_type impl (hb_priority<0>);
+
+  public:
+  static constexpr bool value = decltype (impl (hb_prioritize))::value;
+};
+#define hb_is_sink_of(Iter, Item) hb_is_sink_of<Iter, Item>::value
+
+/* This is commonly used, so define: */
+#define hb_is_sorted_source_of(Iter, Item) \
+       (hb_is_source_of(Iter, Item) && Iter::is_sorted_iterator)
+
+
+/* Range-based 'for' for iterables. */
+
+template <typename Iterable,
+         hb_requires (hb_is_iterable (Iterable))>
+static inline auto begin (Iterable&& iterable) HB_AUTO_RETURN (hb_iter (iterable).begin ())
+
+template <typename Iterable,
+         hb_requires (hb_is_iterable (Iterable))>
+static inline auto end (Iterable&& iterable) HB_AUTO_RETURN (hb_iter (iterable).end ())
+
+/* begin()/end() are NOT looked up non-ADL.  So each namespace must declare them.
+ * Do it for namespace OT. */
+namespace OT {
+
+template <typename Iterable,
+         hb_requires (hb_is_iterable (Iterable))>
+static inline auto begin (Iterable&& iterable) HB_AUTO_RETURN (hb_iter (iterable).begin ())
+
+template <typename Iterable,
+         hb_requires (hb_is_iterable (Iterable))>
+static inline auto end (Iterable&& iterable) HB_AUTO_RETURN (hb_iter (iterable).end ())
+
+}
+
+
+/*
+ * Adaptors, combiners, etc.
+ */
+
+template <typename Lhs, typename Rhs,
+         hb_requires (hb_is_iterator (Lhs))>
+static inline auto
+operator | (Lhs&& lhs, Rhs&& rhs) HB_AUTO_RETURN (hb_forward<Rhs> (rhs) (hb_forward<Lhs> (lhs)))
+
+/* hb_map(), hb_filter(), hb_reduce() */
+
+enum  class hb_function_sortedness_t {
+  NOT_SORTED,
+  RETAINS_SORTING,
+  SORTED,
+};
+
+template <typename Iter, typename Proj, hb_function_sortedness_t Sorted,
+        hb_requires (hb_is_iterator (Iter))>
+struct hb_map_iter_t :
+  hb_iter_t<hb_map_iter_t<Iter, Proj, Sorted>,
+           decltype (hb_get (hb_declval (Proj), *hb_declval (Iter)))>
+{
+  hb_map_iter_t (const Iter& it, Proj f_) : it (it), f (f_) {}
+
+  typedef decltype (hb_get (hb_declval (Proj), *hb_declval (Iter))) __item_t__;
+  static constexpr bool is_random_access_iterator = Iter::is_random_access_iterator;
+  static constexpr bool is_sorted_iterator =
+    Sorted == hb_function_sortedness_t::SORTED ? true :
+    Sorted == hb_function_sortedness_t::RETAINS_SORTING ? Iter::is_sorted_iterator :
+    false;
+  __item_t__ __item__ () const { return hb_get (f.get (), *it); }
+  __item_t__ __item_at__ (unsigned i) const { return hb_get (f.get (), it[i]); }
+  bool __more__ () const { return bool (it); }
+  unsigned __len__ () const { return it.len (); }
+  void __next__ () { ++it; }
+  void __forward__ (unsigned n) { it += n; }
+  void __prev__ () { --it; }
+  void __rewind__ (unsigned n) { it -= n; }
+  hb_map_iter_t __end__ () const { return hb_map_iter_t (it.end (), f); }
+  bool operator != (const hb_map_iter_t& o) const
+  { return it != o.it; }
+
+  private:
+  Iter it;
+  hb_reference_wrapper<Proj> f;
+};
+
+template <typename Proj, hb_function_sortedness_t Sorted>
+struct hb_map_iter_factory_t
+{
+  hb_map_iter_factory_t (Proj f) : f (f) {}
+
+  template <typename Iter,
+           hb_requires (hb_is_iterator (Iter))>
+  hb_map_iter_t<Iter, Proj, Sorted>
+  operator () (Iter it)
+  { return hb_map_iter_t<Iter, Proj, Sorted> (it, f); }
+
+  private:
+  Proj f;
+};
+struct
+{
+  template <typename Proj>
+  hb_map_iter_factory_t<Proj, hb_function_sortedness_t::NOT_SORTED>
+  operator () (Proj&& f) const
+  { return hb_map_iter_factory_t<Proj, hb_function_sortedness_t::NOT_SORTED> (f); }
+}
+HB_FUNCOBJ (hb_map);
+struct
+{
+  template <typename Proj>
+  hb_map_iter_factory_t<Proj, hb_function_sortedness_t::RETAINS_SORTING>
+  operator () (Proj&& f) const
+  { return hb_map_iter_factory_t<Proj, hb_function_sortedness_t::RETAINS_SORTING> (f); }
+}
+HB_FUNCOBJ (hb_map_retains_sorting);
+struct
+{
+  template <typename Proj>
+  hb_map_iter_factory_t<Proj, hb_function_sortedness_t::SORTED>
+  operator () (Proj&& f) const
+  { return hb_map_iter_factory_t<Proj, hb_function_sortedness_t::SORTED> (f); }
+}
+HB_FUNCOBJ (hb_map_sorted);
+
+template <typename Iter, typename Pred, typename Proj,
+        hb_requires (hb_is_iterator (Iter))>
+struct hb_filter_iter_t :
+  hb_iter_with_fallback_t<hb_filter_iter_t<Iter, Pred, Proj>,
+                         typename Iter::item_t>
+{
+  hb_filter_iter_t (const Iter& it_, Pred p_, Proj f_) : it (it_), p (p_), f (f_)
+  { while (it && !hb_has (p.get (), hb_get (f.get (), *it))) ++it; }
+
+  typedef typename Iter::item_t __item_t__;
+  static constexpr bool is_sorted_iterator = Iter::is_sorted_iterator;
+  __item_t__ __item__ () const { return *it; }
+  bool __more__ () const { return bool (it); }
+  void __next__ () { do ++it; while (it && !hb_has (p.get (), hb_get (f.get (), *it))); }
+  void __prev__ () { do --it; while (it && !hb_has (p.get (), hb_get (f.get (), *it))); }
+  hb_filter_iter_t __end__ () const { return hb_filter_iter_t (it.end (), p, f); }
+  bool operator != (const hb_filter_iter_t& o) const
+  { return it != o.it; }
+
+  private:
+  Iter it;
+  hb_reference_wrapper<Pred> p;
+  hb_reference_wrapper<Proj> f;
+};
+template <typename Pred, typename Proj>
+struct hb_filter_iter_factory_t
+{
+  hb_filter_iter_factory_t (Pred p, Proj f) : p (p), f (f) {}
+
+  template <typename Iter,
+           hb_requires (hb_is_iterator (Iter))>
+  hb_filter_iter_t<Iter, Pred, Proj>
+  operator () (Iter it)
+  { return hb_filter_iter_t<Iter, Pred, Proj> (it, p, f); }
+
+  private:
+  Pred p;
+  Proj f;
+};
+struct
+{
+  template <typename Pred = decltype ((hb_identity)),
+           typename Proj = decltype ((hb_identity))>
+  hb_filter_iter_factory_t<Pred, Proj>
+  operator () (Pred&& p = hb_identity, Proj&& f = hb_identity) const
+  { return hb_filter_iter_factory_t<Pred, Proj> (p, f); }
+}
+HB_FUNCOBJ (hb_filter);
+
+template <typename Redu, typename InitT>
+struct hb_reduce_t
+{
+  hb_reduce_t (Redu r, InitT init_value) : r (r), init_value (init_value) {}
+
+  template <typename Iter,
+           hb_requires (hb_is_iterator (Iter)),
+           typename AccuT = hb_decay<decltype (hb_declval (Redu) (hb_declval (InitT), hb_declval (typename Iter::item_t)))>>
+  AccuT
+  operator () (Iter it)
+  {
+    AccuT value = init_value;
+    for (; it; ++it)
+      value = r (value, *it);
+    return value;
+  }
+
+  private:
+  Redu r;
+  InitT init_value;
+};
+struct
+{
+  template <typename Redu, typename InitT>
+  hb_reduce_t<Redu, InitT>
+  operator () (Redu&& r, InitT init_value) const
+  { return hb_reduce_t<Redu, InitT> (r, init_value); }
+}
+HB_FUNCOBJ (hb_reduce);
+
+
+/* hb_zip() */
 
-  /* Random access: Return true if item_at(), len(), forward() are fast. */
-  bool __random_access__ () const { return false; }
+template <typename A, typename B>
+struct hb_zip_iter_t :
+  hb_iter_t<hb_zip_iter_t<A, B>,
+           hb_pair_t<typename A::item_t, typename B::item_t>>
+{
+  hb_zip_iter_t () {}
+  hb_zip_iter_t (const A& a, const B& b) : a (a), b (b) {}
+
+  typedef hb_pair_t<typename A::item_t, typename B::item_t> __item_t__;
+  static constexpr bool is_random_access_iterator =
+    A::is_random_access_iterator &&
+    B::is_random_access_iterator;
+  /* Note.  The following categorization is only valid if A is strictly sorted,
+   * ie. does NOT have duplicates.  Previously I tried to categorize sortedness
+   * more granularly, see commits:
+   *
+   *   513762849a683914fc266a17ddf38f133cccf072
+   *   4d3cf2adb669c345cc43832d11689271995e160a
+   *
+   * However, that was not enough, since hb_sorted_array_t, hb_sorted_vector_t,
+   * SortedArrayOf, etc all needed to be updated to add more variants.  At that
+   * point I saw it not worth the effort, and instead we now deem all sorted
+   * collections as essentially strictly-sorted for the purposes of zip.
+   *
+   * The above assumption is not as bad as it sounds.  Our "sorted" comes with
+   * no guarantees.  It's just a contract, put in place to help you remember,
+   * and think about, whether an iterator you receive is expected to be
+   * sorted or not.  As such, it's not perfect by definition, and should not
+   * be treated so.  The inaccuracy here just errs in the direction of being
+   * more permissive, so your code compiles instead of erring on the side of
+   * marking your zipped iterator unsorted in which case your code won't
+   * compile.
+   *
+   * This semantical limitation does NOT affect logic in any other place I
+   * know of as of this writing.
+   */
+  static constexpr bool is_sorted_iterator = A::is_sorted_iterator;
+
+  __item_t__ __item__ () const { return __item_t__ (*a, *b); }
+  __item_t__ __item_at__ (unsigned i) const { return __item_t__ (a[i], b[i]); }
+  bool __more__ () const { return bool (a) && bool (b); }
+  unsigned __len__ () const { return hb_min (a.len (), b.len ()); }
+  void __next__ () { ++a; ++b; }
+  void __forward__ (unsigned n) { a += n; b += n; }
+  void __prev__ () { --a; --b; }
+  void __rewind__ (unsigned n) { a -= n; b -= n; }
+  hb_zip_iter_t __end__ () const { return hb_zip_iter_t (a.end (), b.end ()); }
+  /* Note, we should stop if ANY of the iters reaches end.  As such two compare
+   * unequal if both items are unequal, NOT if either is unequal. */
+  bool operator != (const hb_zip_iter_t& o) const
+  { return a != o.a && b != o.b; }
+
+  private:
+  A a;
+  B b;
+};
+struct
+{ HB_PARTIALIZE(2);
+  template <typename A, typename B,
+           hb_requires (hb_is_iterable (A) && hb_is_iterable (B))>
+  hb_zip_iter_t<hb_iter_type<A>, hb_iter_type<B>>
+  operator () (A&& a, B&& b) const
+  { return hb_zip_iter_t<hb_iter_type<A>, hb_iter_type<B>> (hb_iter (a), hb_iter (b)); }
+}
+HB_FUNCOBJ (hb_zip);
+
+/* hb_apply() */
+
+template <typename Appl>
+struct hb_apply_t
+{
+  hb_apply_t (Appl a) : a (a) {}
+
+  template <typename Iter,
+           hb_requires (hb_is_iterator (Iter))>
+  void operator () (Iter it)
+  {
+    for (; it; ++it)
+      (void) hb_invoke (a, *it);
+  }
+
+  private:
+  Appl a;
 };
+struct
+{
+  template <typename Appl> hb_apply_t<Appl>
+  operator () (Appl&& a) const
+  { return hb_apply_t<Appl> (a); }
 
+  template <typename Appl> hb_apply_t<Appl&>
+  operator () (Appl *a) const
+  { return hb_apply_t<Appl&> (*a); }
+}
+HB_FUNCOBJ (hb_apply);
+
+/* hb_range()/hb_iota()/hb_repeat() */
+
+template <typename T, typename S>
+struct hb_range_iter_t :
+  hb_iter_t<hb_range_iter_t<T, S>, T>
+{
+  hb_range_iter_t (T start, T end_, S step) : v (start), end_ (end_for (start, end_, step)), step (step) {}
+
+  typedef T __item_t__;
+  static constexpr bool is_random_access_iterator = true;
+  static constexpr bool is_sorted_iterator = true;
+  __item_t__ __item__ () const { return hb_ridentity (v); }
+  __item_t__ __item_at__ (unsigned j) const { return v + j * step; }
+  bool __more__ () const { return v != end_; }
+  unsigned __len__ () const { return !step ? UINT_MAX : (end_ - v) / step; }
+  void __next__ () { v += step; }
+  void __forward__ (unsigned n) { v += n * step; }
+  void __prev__ () { v -= step; }
+  void __rewind__ (unsigned n) { v -= n * step; }
+  hb_range_iter_t __end__ () const { return hb_range_iter_t (end_, end_, step); }
+  bool operator != (const hb_range_iter_t& o) const
+  { return v != o.v; }
+
+  private:
+  static inline T end_for (T start, T end_, S step)
+  {
+    if (!step)
+      return end_;
+    auto res = (end_ - start) % step;
+    if (!res)
+      return end_;
+    end_ += step - res;
+    return end_;
+  }
+
+  private:
+  T v;
+  T end_;
+  S step;
+};
+struct
+{
+  template <typename T = unsigned> hb_range_iter_t<T, unsigned>
+  operator () (T end = (unsigned) -1) const
+  { return hb_range_iter_t<T, unsigned> (0, end, 1u); }
+
+  template <typename T, typename S = unsigned> hb_range_iter_t<T, S>
+  operator () (T start, T end, S step = 1u) const
+  { return hb_range_iter_t<T, S> (start, end, step); }
+}
+HB_FUNCOBJ (hb_range);
+
+template <typename T, typename S>
+struct hb_iota_iter_t :
+  hb_iter_with_fallback_t<hb_iota_iter_t<T, S>, T>
+{
+  hb_iota_iter_t (T start, S step) : v (start), step (step) {}
+
+  private:
+
+  template <typename S2 = S>
+  auto
+  inc (hb_type_identity<S2> s, hb_priority<1>)
+    -> hb_void_t<decltype (hb_invoke (hb_forward<S2> (s), hb_declval<T&> ()))>
+  { v = hb_invoke (hb_forward<S2> (s), v); }
+
+  void
+  inc (S s, hb_priority<0>)
+  { v += s; }
+
+  public:
+
+  typedef T __item_t__;
+  static constexpr bool is_random_access_iterator = true;
+  static constexpr bool is_sorted_iterator = true;
+  __item_t__ __item__ () const { return hb_ridentity (v); }
+  bool __more__ () const { return true; }
+  unsigned __len__ () const { return UINT_MAX; }
+  void __next__ () { inc (step, hb_prioritize); }
+  void __prev__ () { v -= step; }
+  hb_iota_iter_t __end__ () const { return *this; }
+  bool operator != (const hb_iota_iter_t& o) const { return true; }
+
+  private:
+  T v;
+  S step;
+};
+struct
+{
+  template <typename T = unsigned, typename S = unsigned> hb_iota_iter_t<T, S>
+  operator () (T start = 0u, S step = 1u) const
+  { return hb_iota_iter_t<T, S> (start, step); }
+}
+HB_FUNCOBJ (hb_iota);
 
-/* Functions operating on iterators or iteratables. */
+template <typename T>
+struct hb_repeat_iter_t :
+  hb_iter_t<hb_repeat_iter_t<T>, T>
+{
+  hb_repeat_iter_t (T value) : v (value) {}
+
+  typedef T __item_t__;
+  static constexpr bool is_random_access_iterator = true;
+  static constexpr bool is_sorted_iterator = true;
+  __item_t__ __item__ () const { return v; }
+  __item_t__ __item_at__ (unsigned j) const { return v; }
+  bool __more__ () const { return true; }
+  unsigned __len__ () const { return UINT_MAX; }
+  void __next__ () {}
+  void __forward__ (unsigned) {}
+  void __prev__ () {}
+  void __rewind__ (unsigned) {}
+  hb_repeat_iter_t __end__ () const { return *this; }
+  bool operator != (const hb_repeat_iter_t& o) const { return true; }
+
+  private:
+  T v;
+};
+struct
+{
+  template <typename T> hb_repeat_iter_t<T>
+  operator () (T value) const
+  { return hb_repeat_iter_t<T> (value); }
+}
+HB_FUNCOBJ (hb_repeat);
+
+/* hb_enumerate()/hb_take() */
+
+struct
+{
+  template <typename Iterable,
+           typename Index = unsigned,
+           hb_requires (hb_is_iterable (Iterable))>
+  auto operator () (Iterable&& it, Index start = 0u) const HB_AUTO_RETURN
+  ( hb_zip (hb_iota (start), it) )
+}
+HB_FUNCOBJ (hb_enumerate);
+
+struct
+{ HB_PARTIALIZE(2);
+  template <typename Iterable,
+           hb_requires (hb_is_iterable (Iterable))>
+  auto operator () (Iterable&& it, unsigned count) const HB_AUTO_RETURN
+  ( hb_zip (hb_range (count), it) | hb_map (hb_second) )
+
+  /* Specialization arrays. */
+
+  template <typename Type> inline hb_array_t<Type>
+  operator () (hb_array_t<Type> array, unsigned count) const
+  { return array.sub_array (0, count); }
+
+  template <typename Type> inline hb_sorted_array_t<Type>
+  operator () (hb_sorted_array_t<Type> array, unsigned count) const
+  { return array.sub_array (0, count); }
+}
+HB_FUNCOBJ (hb_take);
+
+struct
+{ HB_PARTIALIZE(2);
+  template <typename Iter,
+           hb_requires (hb_is_iterator (Iter))>
+  auto operator () (Iter it, unsigned count) const HB_AUTO_RETURN
+  (
+    + hb_iota (it, hb_add (count))
+    | hb_map (hb_take (count))
+    | hb_take ((hb_len (it) + count - 1) / count)
+  )
+}
+HB_FUNCOBJ (hb_chop);
+
+/* hb_sink() */
+
+template <typename Sink>
+struct hb_sink_t
+{
+  hb_sink_t (Sink s) : s (s) {}
+
+  template <typename Iter,
+           hb_requires (hb_is_iterator (Iter))>
+  void operator () (Iter it)
+  {
+    for (; it; ++it)
+      s << *it;
+  }
+
+  private:
+  Sink s;
+};
+struct
+{
+  template <typename Sink> hb_sink_t<Sink>
+  operator () (Sink&& s) const
+  { return hb_sink_t<Sink> (s); }
+
+  template <typename Sink> hb_sink_t<Sink&>
+  operator () (Sink *s) const
+  { return hb_sink_t<Sink&> (*s); }
+}
+HB_FUNCOBJ (hb_sink);
+
+/* hb-drain: hb_sink to void / blackhole / /dev/null. */
+
+struct
+{
+  template <typename Iter,
+           hb_requires (hb_is_iterator (Iter))>
+  void operator () (Iter it) const
+  {
+    for (; it; ++it)
+      (void) *it;
+  }
+}
+HB_FUNCOBJ (hb_drain);
+
+/* hb_unzip(): unzip and sink to two sinks. */
+
+template <typename Sink1, typename Sink2>
+struct hb_unzip_t
+{
+  hb_unzip_t (Sink1 s1, Sink2 s2) : s1 (s1), s2 (s2) {}
+
+  template <typename Iter,
+           hb_requires (hb_is_iterator (Iter))>
+  void operator () (Iter it)
+  {
+    for (; it; ++it)
+    {
+      const auto &v = *it;
+      s1 << v.first;
+      s2 << v.second;
+    }
+  }
+
+  private:
+  Sink1 s1;
+  Sink2 s2;
+};
+struct
+{
+  template <typename Sink1, typename Sink2> hb_unzip_t<Sink1, Sink2>
+  operator () (Sink1&& s1, Sink2&& s2) const
+  { return hb_unzip_t<Sink1, Sink2> (s1, s2); }
+
+  template <typename Sink1, typename Sink2> hb_unzip_t<Sink1&, Sink2&>
+  operator () (Sink1 *s1, Sink2 *s2) const
+  { return hb_unzip_t<Sink1&, Sink2&> (*s1, *s2); }
+}
+HB_FUNCOBJ (hb_unzip);
+
+
+/* hb-all, hb-any, hb-none. */
+
+struct
+{
+  template <typename Iterable,
+           typename Pred = decltype ((hb_identity)),
+           typename Proj = decltype ((hb_identity)),
+           hb_requires (hb_is_iterable (Iterable))>
+  bool operator () (Iterable&& c,
+                   Pred&& p = hb_identity,
+                   Proj&& f = hb_identity) const
+  {
+    for (auto it = hb_iter (c); it; ++it)
+      if (!hb_match (hb_forward<Pred> (p), hb_get (hb_forward<Proj> (f), *it)))
+       return false;
+    return true;
+  }
+}
+HB_FUNCOBJ (hb_all);
+struct
+{
+  template <typename Iterable,
+           typename Pred = decltype ((hb_identity)),
+           typename Proj = decltype ((hb_identity)),
+           hb_requires (hb_is_iterable (Iterable))>
+  bool operator () (Iterable&& c,
+                   Pred&& p = hb_identity,
+                   Proj&& f = hb_identity) const
+  {
+    for (auto it = hb_iter (c); it; ++it)
+      if (hb_match (hb_forward<Pred> (p), hb_get (hb_forward<Proj> (f), *it)))
+       return true;
+    return false;
+  }
+}
+HB_FUNCOBJ (hb_any);
+struct
+{
+  template <typename Iterable,
+           typename Pred = decltype ((hb_identity)),
+           typename Proj = decltype ((hb_identity)),
+           hb_requires (hb_is_iterable (Iterable))>
+  bool operator () (Iterable&& c,
+                   Pred&& p = hb_identity,
+                   Proj&& f = hb_identity) const
+  {
+    for (auto it = hb_iter (c); it; ++it)
+      if (hb_match (hb_forward<Pred> (p), hb_get (hb_forward<Proj> (f), *it)))
+       return false;
+    return true;
+  }
+}
+HB_FUNCOBJ (hb_none);
+
+/*
+ * Algorithms operating on iterators.
+ */
 
-template <typename C, typename V> inline void
-hb_fill (const C& c, const V &v)
+template <typename C, typename V,
+         hb_requires (hb_is_iterable (C))>
+inline void
+hb_fill (C& c, const V &v)
 {
-  for (typename C::iter_t i (c); i; i++)
-    hb_assign (*i, v);
+  for (auto i = hb_iter (c); i; i++)
+    *i = v;
 }
 
-template <typename S, typename D> inline bool
-hb_copy (hb_iter_t<D> &id, hb_iter_t<S> &is)
+template <typename S, typename D>
+inline void
+hb_copy (S&& is, D&& id)
 {
-  for (; id && is; ++id, ++is)
-    *id = *is;
-  return !is;
+  hb_iter (is) | hb_sink (id);
 }
 
 
index fd5bb9e..99d533c 100644 (file)
@@ -82,11 +82,11 @@ struct hb_kern_machine_t
 
 
       if (likely (!kern))
-        goto skip;
+       goto skip;
 
       if (horizontal)
       {
-        if (scale)
+       if (scale)
          kern = font->em_scale_x (kern);
        if (crossStream)
        {
@@ -104,7 +104,7 @@ struct hb_kern_machine_t
       }
       else
       {
-        if (scale)
+       if (scale)
          kern = font->em_scale_y (kern);
        if (crossStream)
        {
index ffa423d..15535d7 100644 (file)
@@ -32,8 +32,9 @@
 #include "hb.hh"
 #include "hb-blob.hh"
 
-#include "hb-array.hh"
-#include "hb-vector.hh"
+#include "hb-dispatch.hh"
+#include "hb-sanitize.hh"
+#include "hb-serialize.hh"
 
 
 /*
@@ -134,7 +135,7 @@ static inline Type& StructAfter(TObject &X)
 
 #define DEFINE_SIZE_ARRAY(size, array) \
   DEFINE_COMPILES_ASSERTION ((void) (array)[0].static_size) \
-  DEFINE_INSTANCE_ASSERTION (sizeof (*this) == (size) + VAR * sizeof ((array)[0])) \
+  DEFINE_INSTANCE_ASSERTION (sizeof (*this) == (size) + HB_VAR_ARRAY * sizeof ((array)[0])) \
   static constexpr unsigned null_size = (size); \
   static constexpr unsigned min_size = (size)
 
@@ -143,617 +144,6 @@ static inline Type& StructAfter(TObject &X)
   DEFINE_SIZE_ARRAY(size, array)
 
 
-/*
- * Dispatch
- */
-
-template <typename Context, typename Return, unsigned int MaxDebugDepth>
-struct hb_dispatch_context_t
-{
-  static constexpr unsigned max_debug_depth = MaxDebugDepth;
-  typedef Return return_t;
-  template <typename T, typename F>
-  bool may_dispatch (const T *obj HB_UNUSED, const F *format HB_UNUSED) { return true; }
-  static return_t no_dispatch_return_value () { return Context::default_return_value (); }
-  static bool stop_sublookup_iteration (const return_t r HB_UNUSED) { return false; }
-};
-
-
-/*
- * Sanitize
- *
- *
- * === Introduction ===
- *
- * The sanitize machinery is at the core of our zero-cost font loading.  We
- * mmap() font file into memory and create a blob out of it.  Font subtables
- * are returned as a readonly sub-blob of the main font blob.  These table
- * blobs are then sanitized before use, to ensure invalid memory access does
- * not happen.  The toplevel sanitize API use is like, eg. to load the 'head'
- * table:
- *
- *   hb_blob_t *head_blob = hb_sanitize_context_t ().reference_table<OT::head> (face);
- *
- * The blob then can be converted to a head table struct with:
- *
- *   const head *head_table = head_blob->as<head> ();
- *
- * What the reference_table does is, to call hb_face_reference_table() to load
- * the table blob, sanitize it and return either the sanitized blob, or empty
- * blob if sanitization failed.  The blob->as() function returns the null
- * object of its template type argument if the blob is empty.  Otherwise, it
- * just casts the blob contents to the desired type.
- *
- * Sanitizing a blob of data with a type T works as follows (with minor
- * simplification):
- *
- *   - Cast blob content to T*, call sanitize() method of it,
- *   - If sanitize succeeded, return blob.
- *   - Otherwise, if blob is not writable, try making it writable,
- *     or copy if cannot be made writable in-place,
- *   - Call sanitize() again.  Return blob if sanitize succeeded.
- *   - Return empty blob otherwise.
- *
- *
- * === The sanitize() contract ===
- *
- * The sanitize() method of each object type shall return true if it's safe to
- * call other methods of the object, and false otherwise.
- *
- * Note that what sanitize() checks for might align with what the specification
- * describes as valid table data, but does not have to be.  In particular, we
- * do NOT want to be pedantic and concern ourselves with validity checks that
- * are irrelevant to our use of the table.  On the contrary, we want to be
- * lenient with error handling and accept invalid data to the extent that it
- * does not impose extra burden on us.
- *
- * Based on the sanitize contract, one can see that what we check for depends
- * on how we use the data in other table methods.  Ie. if other table methods
- * assume that offsets do NOT point out of the table data block, then that's
- * something sanitize() must check for (GSUB/GPOS/GDEF/etc work this way).  On
- * the other hand, if other methods do such checks themselves, then sanitize()
- * does not have to bother with them (glyf/local work this way).  The choice
- * depends on the table structure and sanitize() performance.  For example, to
- * check glyf/loca offsets in sanitize() would cost O(num-glyphs).  We try hard
- * to avoid such costs during font loading.  By postponing such checks to the
- * actual glyph loading, we reduce the sanitize cost to O(1) and total runtime
- * cost to O(used-glyphs).  As such, this is preferred.
- *
- * The same argument can be made re GSUB/GPOS/GDEF, but there, the table
- * structure is so complicated that by checking all offsets at sanitize() time,
- * we make the code much simpler in other methods, as offsets and referenced
- * objects do not need to be validated at each use site.
- */
-
-/* This limits sanitizing time on really broken fonts. */
-#ifndef HB_SANITIZE_MAX_EDITS
-#define HB_SANITIZE_MAX_EDITS 32
-#endif
-#ifndef HB_SANITIZE_MAX_OPS_FACTOR
-#define HB_SANITIZE_MAX_OPS_FACTOR 8
-#endif
-#ifndef HB_SANITIZE_MAX_OPS_MIN
-#define HB_SANITIZE_MAX_OPS_MIN 16384
-#endif
-#ifndef HB_SANITIZE_MAX_OPS_MAX
-#define HB_SANITIZE_MAX_OPS_MAX 0x3FFFFFFF
-#endif
-
-struct hb_sanitize_context_t :
-       hb_dispatch_context_t<hb_sanitize_context_t, bool, HB_DEBUG_SANITIZE>
-{
-  hb_sanitize_context_t () :
-       debug_depth (0),
-       start (nullptr), end (nullptr),
-       max_ops (0),
-       writable (false), edit_count (0),
-       blob (nullptr),
-       num_glyphs (65536),
-       num_glyphs_set (false) {}
-
-  const char *get_name () { return "SANITIZE"; }
-  template <typename T, typename F>
-  bool may_dispatch (const T *obj HB_UNUSED, const F *format)
-  { return format->sanitize (this); }
-  template <typename T>
-  return_t dispatch (const T &obj) { return obj.sanitize (this); }
-  static return_t default_return_value () { return true; }
-  static return_t no_dispatch_return_value () { return false; }
-  bool stop_sublookup_iteration (const return_t r) const { return !r; }
-
-  void init (hb_blob_t *b)
-  {
-    this->blob = hb_blob_reference (b);
-    this->writable = false;
-  }
-
-  void set_num_glyphs (unsigned int num_glyphs_)
-  {
-    num_glyphs = num_glyphs_;
-    num_glyphs_set = true;
-  }
-  unsigned int get_num_glyphs () { return num_glyphs; }
-
-  void set_max_ops (int max_ops_) { max_ops = max_ops_; }
-
-  template <typename T>
-  void set_object (const T *obj)
-  {
-    reset_object ();
-
-    if (!obj) return;
-
-    const char *obj_start = (const char *) obj;
-    if (unlikely (obj_start < this->start || this->end <= obj_start))
-      this->start = this->end = nullptr;
-    else
-    {
-      this->start = obj_start;
-      this->end   = obj_start + MIN<uintptr_t> (this->end - obj_start, obj->get_size ());
-    }
-  }
-
-  void reset_object ()
-  {
-    this->start = this->blob->data;
-    this->end = this->start + this->blob->length;
-    assert (this->start <= this->end); /* Must not overflow. */
-  }
-
-  void start_processing ()
-  {
-    reset_object ();
-    this->max_ops = MAX ((unsigned int) (this->end - this->start) * HB_SANITIZE_MAX_OPS_FACTOR,
-                        (unsigned) HB_SANITIZE_MAX_OPS_MIN);
-    this->edit_count = 0;
-    this->debug_depth = 0;
-
-    DEBUG_MSG_LEVEL (SANITIZE, start, 0, +1,
-                    "start [%p..%p] (%lu bytes)",
-                    this->start, this->end,
-                    (unsigned long) (this->end - this->start));
-  }
-
-  void end_processing ()
-  {
-    DEBUG_MSG_LEVEL (SANITIZE, this->start, 0, -1,
-                    "end [%p..%p] %u edit requests",
-                    this->start, this->end, this->edit_count);
-
-    hb_blob_destroy (this->blob);
-    this->blob = nullptr;
-    this->start = this->end = nullptr;
-  }
-
-  bool check_range (const void *base,
-                   unsigned int len) const
-  {
-    const char *p = (const char *) base;
-    bool ok = !len ||
-             (this->start <= p &&
-              p <= this->end &&
-              (unsigned int) (this->end - p) >= len &&
-              this->max_ops-- > 0);
-
-    DEBUG_MSG_LEVEL (SANITIZE, p, this->debug_depth+1, 0,
-                    "check_range [%p..%p]"
-                    " (%d bytes) in [%p..%p] -> %s",
-                    p, p + len, len,
-                    this->start, this->end,
-                    ok ? "OK" : "OUT-OF-RANGE");
-
-    return likely (ok);
-  }
-
-  template <typename T>
-  bool check_range (const T *base,
-                   unsigned int a,
-                   unsigned int b) const
-  {
-    return !hb_unsigned_mul_overflows (a, b) &&
-          this->check_range (base, a * b);
-  }
-
-  template <typename T>
-  bool check_range (const T *base,
-                   unsigned int a,
-                   unsigned int b,
-                   unsigned int c) const
-  {
-    return !hb_unsigned_mul_overflows (a, b) &&
-          this->check_range (base, a * b, c);
-  }
-
-  template <typename T>
-  bool check_array (const T *base, unsigned int len) const
-  {
-    return this->check_range (base, len, hb_static_size (T));
-  }
-
-  template <typename T>
-  bool check_array (const T *base,
-                   unsigned int a,
-                   unsigned int b) const
-  {
-    return this->check_range (base, a, b, hb_static_size (T));
-  }
-
-  template <typename Type>
-  bool check_struct (const Type *obj) const
-  { return likely (this->check_range (obj, obj->min_size)); }
-
-  bool may_edit (const void *base, unsigned int len)
-  {
-    if (this->edit_count >= HB_SANITIZE_MAX_EDITS)
-      return false;
-
-    const char *p = (const char *) base;
-    this->edit_count++;
-
-    DEBUG_MSG_LEVEL (SANITIZE, p, this->debug_depth+1, 0,
-       "may_edit(%u) [%p..%p] (%d bytes) in [%p..%p] -> %s",
-       this->edit_count,
-       p, p + len, len,
-       this->start, this->end,
-       this->writable ? "GRANTED" : "DENIED");
-
-    return this->writable;
-  }
-
-  template <typename Type, typename ValueType>
-  bool try_set (const Type *obj, const ValueType &v)
-  {
-    if (this->may_edit (obj, hb_static_size (Type)))
-    {
-      hb_assign (* const_cast<Type *> (obj), v);
-      return true;
-    }
-    return false;
-  }
-
-  template <typename Type>
-  hb_blob_t *sanitize_blob (hb_blob_t *blob)
-  {
-    bool sane;
-
-    init (blob);
-
-  retry:
-    DEBUG_MSG_FUNC (SANITIZE, start, "start");
-
-    start_processing ();
-
-    if (unlikely (!start))
-    {
-      end_processing ();
-      return blob;
-    }
-
-    Type *t = CastP<Type> (const_cast<char *> (start));
-
-    sane = t->sanitize (this);
-    if (sane)
-    {
-      if (edit_count)
-      {
-       DEBUG_MSG_FUNC (SANITIZE, start, "passed first round with %d edits; going for second round", edit_count);
-
-        /* sanitize again to ensure no toe-stepping */
-        edit_count = 0;
-       sane = t->sanitize (this);
-       if (edit_count) {
-         DEBUG_MSG_FUNC (SANITIZE, start, "requested %d edits in second round; FAILLING", edit_count);
-         sane = false;
-       }
-      }
-    }
-    else
-    {
-      if (edit_count && !writable) {
-        start = hb_blob_get_data_writable (blob, nullptr);
-       end = start + blob->length;
-
-       if (start)
-       {
-         writable = true;
-         /* ok, we made it writable by relocating.  try again */
-         DEBUG_MSG_FUNC (SANITIZE, start, "retry");
-         goto retry;
-       }
-      }
-    }
-
-    end_processing ();
-
-    DEBUG_MSG_FUNC (SANITIZE, start, sane ? "PASSED" : "FAILED");
-    if (sane)
-    {
-      hb_blob_make_immutable (blob);
-      return blob;
-    }
-    else
-    {
-      hb_blob_destroy (blob);
-      return hb_blob_get_empty ();
-    }
-  }
-
-  template <typename Type>
-  hb_blob_t *reference_table (const hb_face_t *face, hb_tag_t tableTag = Type::tableTag)
-  {
-    if (!num_glyphs_set)
-      set_num_glyphs (hb_face_get_glyph_count (face));
-    return sanitize_blob<Type> (hb_face_reference_table (face, tableTag));
-  }
-
-  mutable unsigned int debug_depth;
-  const char *start, *end;
-  mutable int max_ops;
-  private:
-  bool writable;
-  unsigned int edit_count;
-  hb_blob_t *blob;
-  unsigned int num_glyphs;
-  bool  num_glyphs_set;
-};
-
-struct hb_sanitize_with_object_t
-{
-  template <typename T>
-  hb_sanitize_with_object_t (hb_sanitize_context_t *c,
-                                   const T& obj) : c (c)
-  { c->set_object (obj); }
-  ~hb_sanitize_with_object_t ()
-  { c->reset_object (); }
-
-  private:
-  hb_sanitize_context_t *c;
-};
-
-
-/*
- * Serialize
- */
-
-struct hb_serialize_context_t
-{
-  hb_serialize_context_t (void *start_, unsigned int size)
-  {
-    this->start = (char *) start_;
-    this->end = this->start + size;
-    reset ();
-  }
-
-  bool in_error () const { return !this->successful; }
-
-  void reset ()
-  {
-    this->successful = true;
-    this->head = this->start;
-    this->debug_depth = 0;
-  }
-
-  bool propagate_error (bool e)
-  { return this->successful = this->successful && e; }
-  template <typename T> bool propagate_error (const T &obj)
-  { return this->successful = this->successful && !obj.in_error (); }
-  template <typename T> bool propagate_error (const T *obj)
-  { return this->successful = this->successful && !obj->in_error (); }
-  template <typename T1, typename T2> bool propagate_error (T1 &o1, T2 &o2)
-  { return propagate_error (o1) && propagate_error (o2); }
-  template <typename T1, typename T2> bool propagate_error (T1 *o1, T2 *o2)
-  { return propagate_error (o1) && propagate_error (o2); }
-  template <typename T1, typename T2, typename T3>
-  bool propagate_error (T1 &o1, T2 &o2, T3 &o3)
-  { return propagate_error (o1) && propagate_error (o2, o3); }
-  template <typename T1, typename T2, typename T3>
-  bool propagate_error (T1 *o1, T2 *o2, T3 *o3)
-  { return propagate_error (o1) && propagate_error (o2, o3); }
-
-  /* To be called around main operation. */
-  template <typename Type>
-  Type *start_serialize ()
-  {
-    DEBUG_MSG_LEVEL (SERIALIZE, this->start, 0, +1,
-                    "start [%p..%p] (%lu bytes)",
-                    this->start, this->end,
-                    (unsigned long) (this->end - this->start));
-
-    return start_embed<Type> ();
-  }
-  void end_serialize ()
-  {
-    DEBUG_MSG_LEVEL (SERIALIZE, this->start, 0, -1,
-                    "end [%p..%p] serialized %d bytes; %s",
-                    this->start, this->end,
-                    (int) (this->head - this->start),
-                    this->successful ? "successful" : "UNSUCCESSFUL");
-  }
-
-  unsigned int length () const { return this->head - this->start; }
-
-  void align (unsigned int alignment)
-  {
-    unsigned int l = length () % alignment;
-    if (l)
-      allocate_size<void> (alignment - l);
-  }
-
-  template <typename Type>
-  Type *start_embed (const Type *_ HB_UNUSED = nullptr) const
-  {
-    Type *ret = reinterpret_cast<Type *> (this->head);
-    return ret;
-  }
-
-  template <typename Type>
-  Type *allocate_size (unsigned int size)
-  {
-    if (unlikely (!this->successful || this->end - this->head < ptrdiff_t (size))) {
-      this->successful = false;
-      return nullptr;
-    }
-    memset (this->head, 0, size);
-    char *ret = this->head;
-    this->head += size;
-    return reinterpret_cast<Type *> (ret);
-  }
-
-  template <typename Type>
-  Type *allocate_min ()
-  {
-    return this->allocate_size<Type> (Type::min_size);
-  }
-
-  template <typename Type>
-  Type *embed (const Type &obj)
-  {
-    unsigned int size = obj.get_size ();
-    Type *ret = this->allocate_size<Type> (size);
-    if (unlikely (!ret)) return nullptr;
-    memcpy (ret, &obj, size);
-    return ret;
-  }
-  template <typename Type>
-  hb_serialize_context_t &operator << (const Type &obj) { embed (obj); return *this; }
-
-  template <typename Type>
-  Type *extend_size (Type &obj, unsigned int size)
-  {
-    assert (this->start <= (char *) &obj);
-    assert ((char *) &obj <= this->head);
-    assert ((char *) &obj + size >= this->head);
-    if (unlikely (!this->allocate_size<Type> (((char *) &obj) + size - this->head))) return nullptr;
-    return reinterpret_cast<Type *> (&obj);
-  }
-
-  template <typename Type>
-  Type *extend_min (Type &obj) { return extend_size (obj, obj.min_size); }
-
-  template <typename Type>
-  Type *extend (Type &obj) { return extend_size (obj, obj.get_size ()); }
-
-  /* Output routines. */
-  template <typename Type>
-  Type *copy () const
-  {
-    assert (this->successful);
-    unsigned int len = this->head - this->start;
-    void *p = malloc (len);
-    if (p)
-      memcpy (p, this->start, len);
-    return reinterpret_cast<Type *> (p);
-  }
-  hb_bytes_t copy_bytes () const
-  {
-    assert (this->successful);
-    unsigned int len = this->head - this->start;
-    void *p = malloc (len);
-    if (p)
-      memcpy (p, this->start, len);
-    else
-      return hb_bytes_t ();
-    return hb_bytes_t ((char *) p, len);
-  }
-  hb_blob_t *copy_blob () const
-  {
-    assert (this->successful);
-    return hb_blob_create (this->start,
-                          this->head - this->start,
-                          HB_MEMORY_MODE_DUPLICATE,
-                          nullptr, nullptr);
-  }
-
-  public:
-  unsigned int debug_depth;
-  char *start, *end, *head;
-  bool successful;
-};
-
-
-
-/*
- * Big-endian integers.
- */
-
-template <typename Type, int Bytes> struct BEInt;
-
-template <typename Type>
-struct BEInt<Type, 1>
-{
-  public:
-  void set (Type V)      { v = V; }
-  operator Type () const { return v; }
-  private: uint8_t v;
-};
-template <typename Type>
-struct BEInt<Type, 2>
-{
-  public:
-  void set (Type V)
-  {
-    v[0] = (V >>  8) & 0xFF;
-    v[1] = (V      ) & 0xFF;
-  }
-  operator Type () const
-  {
-#if ((defined(__GNUC__) && __GNUC__ >= 5) || defined(__clang__)) && \
-    defined(__BYTE_ORDER) && \
-    (__BYTE_ORDER == __LITTLE_ENDIAN || __BYTE_ORDER == __BIG_ENDIAN)
-    /* Spoon-feed the compiler a big-endian integer with alignment 1.
-     * https://github.com/harfbuzz/harfbuzz/pull/1398 */
-    struct __attribute__((packed)) packed_uint16_t { uint16_t v; };
-#if __BYTE_ORDER == __LITTLE_ENDIAN
-    return __builtin_bswap16 (((packed_uint16_t *) this)->v);
-#else /* __BYTE_ORDER == __BIG_ENDIAN */
-    return ((packed_uint16_t *) this)->v;
-#endif
-#endif
-    return (v[0] <<  8)
-         + (v[1]      );
-  }
-  private: uint8_t v[2];
-};
-template <typename Type>
-struct BEInt<Type, 3>
-{
-  public:
-  void set (Type V)
-  {
-    v[0] = (V >> 16) & 0xFF;
-    v[1] = (V >>  8) & 0xFF;
-    v[2] = (V      ) & 0xFF;
-  }
-  operator Type () const
-  {
-    return (v[0] << 16)
-         + (v[1] <<  8)
-         + (v[2]      );
-  }
-  private: uint8_t v[3];
-};
-template <typename Type>
-struct BEInt<Type, 4>
-{
-  public:
-  typedef Type type;
-  void set (Type V)
-  {
-    v[0] = (V >> 24) & 0xFF;
-    v[1] = (V >> 16) & 0xFF;
-    v[2] = (V >>  8) & 0xFF;
-    v[3] = (V      ) & 0xFF;
-  }
-  operator Type () const
-  {
-    return (v[0] << 24)
-         + (v[1] << 16)
-         + (v[2] <<  8)
-         + (v[3]      );
-  }
-  private: uint8_t v[4];
-};
-
 
 /*
  * Lazy loaders.
@@ -816,7 +206,7 @@ struct hb_lazy_loader_t : hb_data_wrapper_t<Data, WheresData>
 
   const Returned * operator -> () const { return get (); }
   const Returned & operator * () const  { return *get (); }
-  explicit_operator bool () const
+  explicit operator bool () const
   { return get_stored () != Funcs::get_null (); }
   template <typename C> operator const C * () const { return get (); }
 
@@ -835,7 +225,7 @@ struct hb_lazy_loader_t : hb_data_wrapper_t<Data, WheresData>
 
       if (unlikely (!cmpexch (nullptr, p)))
       {
-        do_destroy (p);
+       do_destroy (p);
        goto retry;
       }
     }
index f7156e5..8c8db4d 100644 (file)
 #include "hb.hh"
 
 
-template <typename T>
-inline uint32_t Hash (const T &v)
-{
-  /* Knuth's multiplicative method: */
-  return (uint32_t) v * 2654435761u;
-}
-
-
 /*
- * hb_map_t
+ * hb_hashmap_t
  */
 
-struct hb_map_t
+template <typename K, typename V,
+         K kINVALID = hb_is_pointer (K) ? 0 : hb_is_signed (K) ? hb_int_min (K) : (K) -1,
+         V vINVALID = hb_is_pointer (V) ? 0 : hb_is_signed (V) ? hb_int_min (V) : (V) -1>
+struct hb_hashmap_t
 {
-  HB_NO_COPY_ASSIGN (hb_map_t);
-  hb_map_t ()  { init (); }
-  ~hb_map_t () { fini (); }
+  HB_DELETE_COPY_ASSIGN (hb_hashmap_t);
+  hb_hashmap_t ()  { init (); }
+  ~hb_hashmap_t () { fini (); }
+
+  static_assert (hb_is_integral (K) || hb_is_pointer (K), "");
+  static_assert (hb_is_integral (V) || hb_is_pointer (V), "");
 
   struct item_t
   {
-    hb_codepoint_t key;
-    hb_codepoint_t value;
-
-    bool is_unused () const    { return key == INVALID; }
-    bool is_tombstone () const { return key != INVALID && value == INVALID; }
+    K key;
+    V value;
+    uint32_t hash;
+
+    void clear () { key = kINVALID; value = vINVALID; hash = 0; }
+
+    bool operator == (K o) { return hb_deref (key) == hb_deref (o); }
+    bool operator == (const item_t &o) { return *this == o.key; }
+    bool is_unused () const    { return key == kINVALID; }
+    bool is_tombstone () const { return key != kINVALID && value == vINVALID; }
+    bool is_real () const { return key != kINVALID && value != vINVALID; }
+    hb_pair_t<K, V> get_pair() const { return hb_pair_t<K, V> (key, value); }
   };
 
   hb_object_header_t header;
@@ -82,14 +87,22 @@ struct hb_map_t
   {
     free (items);
     items = nullptr;
+    population = occupancy = 0;
   }
   void fini ()
   {
-    population = occupancy = 0;
     hb_object_fini (this);
     fini_shallow ();
   }
 
+  void reset ()
+  {
+    if (unlikely (hb_object_is_immutable (this)))
+      return;
+    successful = true;
+    clear ();
+  }
+
   bool in_error () const { return !successful; }
 
   bool resize ()
@@ -104,7 +117,9 @@ struct hb_map_t
       successful = false;
       return false;
     }
-    memset (new_items, 0xFF, (size_t) new_size * sizeof (item_t));
+    + hb_iter (new_items, new_size)
+    | hb_apply (&item_t::clear)
+    ;
 
     unsigned int old_size = mask + 1;
     item_t *old_items = items;
@@ -118,22 +133,97 @@ struct hb_map_t
     /* Insert back old items. */
     if (old_items)
       for (unsigned int i = 0; i < old_size; i++)
-       if (old_items[i].key != INVALID && old_items[i].value != INVALID)
-         set (old_items[i].key, old_items[i].value);
+       if (old_items[i].is_real ())
+         set_with_hash (old_items[i].key,
+                         old_items[i].hash,
+                         old_items[i].value);
 
     free (old_items);
 
     return true;
   }
 
-  void set (hb_codepoint_t key, hb_codepoint_t value)
+  void set (K key, V value)
+  {
+    set_with_hash (key, hb_hash (key), value);
+  }
+
+  V get (K key) const
+  {
+    if (unlikely (!items)) return vINVALID;
+    unsigned int i = bucket_for (key);
+    return items[i].is_real () && items[i] == key ? items[i].value : vINVALID;
+  }
+
+  void del (K key) { set (key, vINVALID); }
+
+  /* Has interface. */
+  static constexpr V SENTINEL = vINVALID;
+  typedef V value_t;
+  value_t operator [] (K k) const { return get (k); }
+  bool has (K k, V *vp = nullptr) const
+  {
+    V v = (*this)[k];
+    if (vp) *vp = v;
+    return v != SENTINEL;
+  }
+  /* Projection. */
+  V operator () (K k) const { return get (k); }
+
+  void clear ()
+  {
+    if (unlikely (hb_object_is_immutable (this)))
+      return;
+    if (items)
+      + hb_iter (items, mask + 1)
+      | hb_apply (&item_t::clear)
+      ;
+
+    population = occupancy = 0;
+  }
+
+  bool is_empty () const { return population == 0; }
+
+  unsigned int get_population () const { return population; }
+
+  /*
+   * Iterator
+   */
+  auto iter () const HB_AUTO_RETURN
+  (
+    + hb_array (items, mask ? mask + 1 : 0)
+    | hb_filter (&item_t::is_real)
+    | hb_map (&item_t::get_pair)
+  )
+  auto keys () const HB_AUTO_RETURN
+  (
+    + hb_array (items, mask ? mask + 1 : 0)
+    | hb_filter (&item_t::is_real)
+    | hb_map (&item_t::key)
+    | hb_map (hb_ridentity)
+  )
+  auto values () const HB_AUTO_RETURN
+  (
+    + hb_array (items, mask ? mask + 1 : 0)
+    | hb_filter (&item_t::is_real)
+    | hb_map (&item_t::value)
+    | hb_map (hb_ridentity)
+  )
+
+  /* Sink interface. */
+  hb_hashmap_t<K, V, kINVALID, vINVALID>& operator << (const hb_pair_t<K, V>& v)
+  { set (v.first, v.second); return *this; }
+
+  protected:
+
+  void set_with_hash (K key, uint32_t hash, V value)
   {
     if (unlikely (!successful)) return;
-    if (unlikely (key == INVALID)) return;
+    if (unlikely (key == kINVALID)) return;
     if ((occupancy + occupancy / 2) >= mask && !resize ()) return;
-    unsigned int i = bucket_for (key);
+    unsigned int i = bucket_for_hash (key, hash);
 
-    if (value == INVALID && items[i].key != key)
+    if (value == vINVALID && items[i].key != key)
       return; /* Trying to delete non-existent key. */
 
     if (!items[i].is_unused ())
@@ -145,55 +235,32 @@ struct hb_map_t
 
     items[i].key = key;
     items[i].value = value;
+    items[i].hash = hash;
 
     occupancy++;
     if (!items[i].is_tombstone ())
       population++;
-
-  }
-  hb_codepoint_t get (hb_codepoint_t key) const
-  {
-    if (unlikely (!items)) return INVALID;
-    unsigned int i = bucket_for (key);
-    return items[i].key == key ? items[i].value : INVALID;
   }
 
-  void del (hb_codepoint_t key) { set (key, INVALID); }
-
-  bool has (hb_codepoint_t key) const
-  { return get (key) != INVALID; }
-
-  hb_codepoint_t operator [] (unsigned int key) const
-  { return get (key); }
-
-  static constexpr hb_codepoint_t INVALID = HB_MAP_VALUE_INVALID;
-
-  void clear ()
+  unsigned int bucket_for (K key) const
   {
-    if (items) memset (items, 0xFF, ((size_t) mask + 1) * sizeof (item_t));
-    population = occupancy = 0;
+    return bucket_for_hash (key, hb_hash (key));
   }
 
-  bool is_empty () const { return population == 0; }
-
-  unsigned int get_population () const { return population; }
-
-  protected:
-
-  unsigned int bucket_for (hb_codepoint_t key) const
+  unsigned int bucket_for_hash (K key, uint32_t hash) const
   {
-    unsigned int i = Hash (key) % prime;
+    unsigned int i = hash % prime;
     unsigned int step = 0;
-    unsigned int tombstone = INVALID;
+    unsigned int tombstone = (unsigned) -1;
     while (!items[i].is_unused ())
     {
-      if (items[i].key == key)
-        return i;
-      if (tombstone == INVALID && items[i].is_tombstone ())
-        tombstone = i;
+      if (items[i].hash == hash && items[i] == key)
+       return i;
+      if (tombstone == (unsigned) -1 && items[i].is_tombstone ())
+       tombstone = i;
       i = (i + ++step) & mask;
     }
-    return tombstone == INVALID ? i : tombstone;
+    return tombstone == (unsigned) -1 ? i : tombstone;
   }
 
   static unsigned int prime_for (unsigned int shift)
@@ -248,5 +315,14 @@ struct hb_map_t
   }
 };
 
+/*
+ * hb_map_t
+ */
+
+struct hb_map_t : hb_hashmap_t<hb_codepoint_t,
+                              hb_codepoint_t,
+                              HB_MAP_VALUE_INVALID,
+                              HB_MAP_VALUE_INVALID> {};
+
 
 #endif /* HB_MAP_HH */
diff --git a/src/hb-meta.hh b/src/hb-meta.hh
new file mode 100644 (file)
index 0000000..2dfaeb7
--- /dev/null
@@ -0,0 +1,400 @@
+/*
+ * Copyright © 2018  Google, Inc.
+ *
+ *  This is part of HarfBuzz, a text shaping library.
+ *
+ * Permission is hereby granted, without written agreement and without
+ * license or royalty fees, to use, copy, modify, and distribute this
+ * software and its documentation for any purpose, provided that the
+ * above copyright notice and the following two paragraphs appear in
+ * all copies of this software.
+ *
+ * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
+ * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
+ * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
+ * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+ * DAMAGE.
+ *
+ * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
+ * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS
+ * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
+ * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
+ *
+ * Google Author(s): Behdad Esfahbod
+ */
+
+#ifndef HB_META_HH
+#define HB_META_HH
+
+#include "hb.hh"
+
+
+/*
+ * C++ template meta-programming & fundamentals used with them.
+ */
+
+/* Void!  For when we need a expression-type of void. */
+struct hb_empty_t {};
+
+/* https://en.cppreference.com/w/cpp/types/void_t */
+template<typename... Ts> struct _hb_void_t { typedef void type; };
+template<typename... Ts> using hb_void_t = typename _hb_void_t<Ts...>::type;
+
+template<typename Head, typename... Ts> struct _hb_head_t { typedef Head type; };
+template<typename... Ts> using hb_head_t = typename _hb_head_t<Ts...>::type;
+
+template <typename T, T v> struct hb_integral_constant { static constexpr T value = v; };
+template <bool b> using hb_bool_constant = hb_integral_constant<bool, b>;
+using hb_true_type = hb_bool_constant<true>;
+using hb_false_type = hb_bool_constant<false>;
+
+
+/* Basic type SFINAE. */
+
+template <bool B, typename T = void> struct hb_enable_if {};
+template <typename T>                struct hb_enable_if<true, T> { typedef T type; };
+#define hb_enable_if(Cond) typename hb_enable_if<(Cond)>::type* = nullptr
+/* Concepts/Requires alias: */
+#define hb_requires(Cond) hb_enable_if((Cond))
+
+template <typename T, typename T2> struct hb_is_same : hb_false_type {};
+template <typename T>              struct hb_is_same<T, T> : hb_true_type {};
+#define hb_is_same(T, T2) hb_is_same<T, T2>::value
+
+/* Function overloading SFINAE and priority. */
+
+#define HB_RETURN(Ret, E) -> hb_head_t<Ret, decltype ((E))> { return (E); }
+#define HB_AUTO_RETURN(E) -> decltype ((E)) { return (E); }
+#define HB_VOID_RETURN(E) -> hb_void_t<decltype ((E))> { (E); }
+
+template <unsigned Pri> struct hb_priority : hb_priority<Pri - 1> {};
+template <>             struct hb_priority<0> {};
+#define hb_prioritize hb_priority<16> ()
+
+#define HB_FUNCOBJ(x) static_const x HB_UNUSED
+
+
+template <typename T> struct hb_type_identity_t { typedef T type; };
+template <typename T> using hb_type_identity = typename hb_type_identity_t<T>::type;
+
+struct
+{
+  template <typename T> constexpr T*
+  operator () (T& arg) const
+  {
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wcast-align"
+    /* https://en.cppreference.com/w/cpp/memory/addressof */
+    return reinterpret_cast<T*> (
+            &const_cast<char&> (
+               reinterpret_cast<const volatile char&> (arg)));
+#pragma GCC diagnostic pop
+  }
+}
+HB_FUNCOBJ (hb_addressof);
+
+template <typename T> static inline T hb_declval ();
+#define hb_declval(T) (hb_declval<T> ())
+
+template <typename T> struct hb_match_const            : hb_type_identity_t<T>, hb_bool_constant<false>{};
+template <typename T> struct hb_match_const<const T>   : hb_type_identity_t<T>, hb_bool_constant<true> {};
+template <typename T> using hb_remove_const = typename hb_match_const<T>::type;
+template <typename T> using hb_add_const = const T;
+#define hb_is_const(T) hb_match_const<T>::value
+template <typename T> struct hb_match_reference                : hb_type_identity_t<T>, hb_bool_constant<false>{};
+template <typename T> struct hb_match_reference<T &>   : hb_type_identity_t<T>, hb_bool_constant<true> {};
+template <typename T> struct hb_match_reference<T &&>  : hb_type_identity_t<T>, hb_bool_constant<true> {};
+template <typename T> using hb_remove_reference = typename hb_match_reference<T>::type;
+template <typename T> auto _hb_try_add_lvalue_reference (hb_priority<1>) -> hb_type_identity<T&>;
+template <typename T> auto _hb_try_add_lvalue_reference (hb_priority<0>) -> hb_type_identity<T>;
+template <typename T> using hb_add_lvalue_reference = decltype (_hb_try_add_lvalue_reference<T> (hb_prioritize));
+template <typename T> auto _hb_try_add_rvalue_reference (hb_priority<1>) -> hb_type_identity<T&&>;
+template <typename T> auto _hb_try_add_rvalue_reference (hb_priority<0>) -> hb_type_identity<T>;
+template <typename T> using hb_add_rvalue_reference = decltype (_hb_try_add_rvalue_reference<T> (hb_prioritize));
+#define hb_is_reference(T) hb_match_reference<T>::value
+template <typename T> struct hb_match_pointer          : hb_type_identity_t<T>, hb_bool_constant<false>{};
+template <typename T> struct hb_match_pointer<T *>     : hb_type_identity_t<T>, hb_bool_constant<true> {};
+template <typename T> using hb_remove_pointer = typename hb_match_pointer<T>::type;
+template <typename T> auto _hb_try_add_pointer (hb_priority<1>) -> hb_type_identity<hb_remove_reference<T>*>;
+template <typename T> auto _hb_try_add_pointer (hb_priority<1>) -> hb_type_identity<T>;
+template <typename T> using hb_add_pointer = decltype (_hb_try_add_pointer<T> (hb_prioritize));
+#define hb_is_pointer(T) hb_match_pointer<T>::value
+
+
+/* TODO Add feature-parity to std::decay. */
+template <typename T> using hb_decay = hb_remove_const<hb_remove_reference<T>>;
+
+
+template<bool B, class T, class F>
+struct _hb_conditional { typedef T type; };
+template<class T, class F>
+struct _hb_conditional<false, T, F> { typedef F type; };
+template<bool B, class T, class F>
+using hb_conditional = typename _hb_conditional<B, T, F>::type;
+
+
+template <typename From, typename To>
+struct hb_is_convertible
+{
+  private:
+  static constexpr bool   from_void = hb_is_same (void, hb_decay<From>);
+  static constexpr bool     to_void = hb_is_same (void, hb_decay<To>  );
+  static constexpr bool either_void = from_void || to_void;
+  static constexpr bool   both_void = from_void && to_void;
+
+  static hb_true_type impl2 (hb_conditional<to_void, int, To>);
+
+  template <typename T>
+  static auto impl (hb_priority<1>) -> decltype (impl2 (hb_declval (T)));
+  template <typename T>
+  static hb_false_type impl (hb_priority<0>);
+  public:
+  static constexpr bool value = both_void ||
+                      (!either_void &&
+                       decltype (impl<hb_conditional<from_void, int, From>> (hb_prioritize))::value);
+};
+#define hb_is_convertible(From,To) hb_is_convertible<From, To>::value
+
+template <typename Base, typename Derived>
+using hb_is_base_of = hb_is_convertible<hb_decay<Derived> *, hb_decay<Base> *>;
+#define hb_is_base_of(Base,Derived) hb_is_base_of<Base, Derived>::value
+
+template <typename From, typename To>
+using hb_is_cr_convertible = hb_bool_constant<
+  hb_is_same (hb_decay<From>, hb_decay<To>) &&
+  (!hb_is_const (From) || hb_is_const (To)) &&
+  (!hb_is_reference (To) || hb_is_const (To) || hb_is_reference (To))
+>;
+#define hb_is_cr_convertible(From,To) hb_is_cr_convertible<From, To>::value
+
+/* std::move and std::forward */
+
+template <typename T>
+static constexpr hb_remove_reference<T>&& hb_move (T&& t) { return (hb_remove_reference<T>&&) (t); }
+
+template <typename T>
+static constexpr T&& hb_forward (hb_remove_reference<T>& t) { return (T&&) t; }
+template <typename T>
+static constexpr T&& hb_forward (hb_remove_reference<T>&& t) { return (T&&) t; }
+
+struct
+{
+  template <typename T> constexpr auto
+  operator () (T&& v) const HB_AUTO_RETURN (hb_forward<T> (v))
+
+  template <typename T> constexpr auto
+  operator () (T *v) const HB_AUTO_RETURN (*v)
+}
+HB_FUNCOBJ (hb_deref);
+
+struct
+{
+  template <typename T> constexpr auto
+  operator () (T&& v) const HB_AUTO_RETURN (hb_forward<T> (v))
+
+  template <typename T> constexpr auto
+  operator () (T& v) const HB_AUTO_RETURN (hb_addressof (v))
+}
+HB_FUNCOBJ (hb_ref);
+
+template <typename T>
+struct hb_reference_wrapper
+{
+  hb_reference_wrapper (T v) : v (v) {}
+  bool operator == (const hb_reference_wrapper& o) const { return v == o.v; }
+  bool operator != (const hb_reference_wrapper& o) const { return v != o.v; }
+  operator T () const { return v; }
+  T get () const { return v; }
+  T v;
+};
+template <typename T>
+struct hb_reference_wrapper<T&>
+{
+  hb_reference_wrapper (T& v) : v (hb_addressof (v)) {}
+  bool operator == (const hb_reference_wrapper& o) const { return v == o.v; }
+  bool operator != (const hb_reference_wrapper& o) const { return v != o.v; }
+  operator T& () const { return *v; }
+  T& get () const { return *v; }
+  T* v;
+};
+
+
+template <typename T>
+using hb_is_integral = hb_bool_constant<
+  hb_is_same (hb_decay<T>, char) ||
+  hb_is_same (hb_decay<T>, signed char) ||
+  hb_is_same (hb_decay<T>, unsigned char) ||
+  hb_is_same (hb_decay<T>, signed int) ||
+  hb_is_same (hb_decay<T>, unsigned int) ||
+  hb_is_same (hb_decay<T>, signed short) ||
+  hb_is_same (hb_decay<T>, unsigned short) ||
+  hb_is_same (hb_decay<T>, signed long) ||
+  hb_is_same (hb_decay<T>, unsigned long) ||
+  hb_is_same (hb_decay<T>, signed long long) ||
+  hb_is_same (hb_decay<T>, unsigned long long) ||
+  false
+>;
+#define hb_is_integral(T) hb_is_integral<T>::value
+template <typename T>
+using hb_is_floating_point = hb_bool_constant<
+  hb_is_same (hb_decay<T>, float) ||
+  hb_is_same (hb_decay<T>, double) ||
+  hb_is_same (hb_decay<T>, long double) ||
+  false
+>;
+#define hb_is_floating_point(T) hb_is_floating_point<T>::value
+template <typename T>
+using hb_is_arithmetic = hb_bool_constant<
+  hb_is_integral (T) ||
+  hb_is_floating_point (T) ||
+  false
+>;
+#define hb_is_arithmetic(T) hb_is_arithmetic<T>::value
+
+
+template <typename T>
+using hb_is_signed = hb_conditional<hb_is_arithmetic (T),
+                                   hb_bool_constant<(T) -1 < (T) 0>,
+                                   hb_false_type>;
+#define hb_is_signed(T) hb_is_signed<T>::value
+template <typename T>
+using hb_is_unsigned = hb_conditional<hb_is_arithmetic (T),
+                                     hb_bool_constant<(T) 0 < (T) -1>,
+                                     hb_false_type>;
+#define hb_is_unsigned(T) hb_is_unsigned<T>::value
+
+template <typename T> struct hb_int_min;
+template <> struct hb_int_min<char>                    : hb_integral_constant<char,                    CHAR_MIN>       {};
+template <> struct hb_int_min<signed char>             : hb_integral_constant<signed char,             SCHAR_MIN>      {};
+template <> struct hb_int_min<unsigned char>           : hb_integral_constant<unsigned char,           0>              {};
+template <> struct hb_int_min<signed short>            : hb_integral_constant<signed short,            SHRT_MIN>       {};
+template <> struct hb_int_min<unsigned short>          : hb_integral_constant<unsigned short,          0>              {};
+template <> struct hb_int_min<signed int>              : hb_integral_constant<signed int,              INT_MIN>        {};
+template <> struct hb_int_min<unsigned int>            : hb_integral_constant<unsigned int,            0>              {};
+template <> struct hb_int_min<signed long>             : hb_integral_constant<signed long,             LONG_MIN>       {};
+template <> struct hb_int_min<unsigned long>           : hb_integral_constant<unsigned long,           0>              {};
+template <> struct hb_int_min<signed long long>                : hb_integral_constant<signed long long,        LLONG_MIN>      {};
+template <> struct hb_int_min<unsigned long long>      : hb_integral_constant<unsigned long long,      0>              {};
+#define hb_int_min(T) hb_int_min<T>::value
+template <typename T> struct hb_int_max;
+template <> struct hb_int_max<char>                    : hb_integral_constant<char,                    CHAR_MAX>       {};
+template <> struct hb_int_max<signed char>             : hb_integral_constant<signed char,             SCHAR_MAX>      {};
+template <> struct hb_int_max<unsigned char>           : hb_integral_constant<unsigned char,           UCHAR_MAX>      {};
+template <> struct hb_int_max<signed short>            : hb_integral_constant<signed short,            SHRT_MAX>       {};
+template <> struct hb_int_max<unsigned short>          : hb_integral_constant<unsigned short,          USHRT_MAX>      {};
+template <> struct hb_int_max<signed int>              : hb_integral_constant<signed int,              INT_MAX>        {};
+template <> struct hb_int_max<unsigned int>            : hb_integral_constant<unsigned int,            UINT_MAX>       {};
+template <> struct hb_int_max<signed long>             : hb_integral_constant<signed long,             LONG_MAX>       {};
+template <> struct hb_int_max<unsigned long>           : hb_integral_constant<unsigned long,           ULONG_MAX>      {};
+template <> struct hb_int_max<signed long long>                : hb_integral_constant<signed long long,        LLONG_MAX>      {};
+template <> struct hb_int_max<unsigned long long>      : hb_integral_constant<unsigned long long,      ULLONG_MAX>     {};
+#define hb_int_max(T) hb_int_max<T>::value
+
+
+
+template <typename T, typename>
+struct _hb_is_destructible : hb_false_type {};
+template <typename T>
+struct _hb_is_destructible<T, hb_void_t<decltype (hb_declval (T).~T ())>> : hb_true_type {};
+template <typename T>
+using hb_is_destructible = _hb_is_destructible<T, void>;
+#define hb_is_destructible(T) hb_is_destructible<T>::value
+
+template <typename T, typename, typename ...Ts>
+struct _hb_is_constructible : hb_false_type {};
+template <typename T, typename ...Ts>
+struct _hb_is_constructible<T, hb_void_t<decltype (T (hb_declval (Ts)...))>, Ts...> : hb_true_type {};
+template <typename T, typename ...Ts>
+using hb_is_constructible = _hb_is_constructible<T, void, Ts...>;
+#define hb_is_constructible(...) hb_is_constructible<__VA_ARGS__>::value
+
+template <typename T>
+using hb_is_default_constructible = hb_is_constructible<T>;
+#define hb_is_default_constructible(T) hb_is_default_constructible<T>::value
+
+template <typename T>
+using hb_is_copy_constructible = hb_is_constructible<T, hb_add_lvalue_reference<hb_add_const<T>>>;
+#define hb_is_copy_constructible(T) hb_is_copy_constructible<T>::value
+
+template <typename T>
+using hb_is_move_constructible = hb_is_constructible<T, hb_add_rvalue_reference<hb_add_const<T>>>;
+#define hb_is_move_constructible(T) hb_is_move_constructible<T>::value
+
+template <typename T, typename U, typename>
+struct _hb_is_assignable : hb_false_type {};
+template <typename T, typename U>
+struct _hb_is_assignable<T, U, hb_void_t<decltype (hb_declval (T) = hb_declval (U))>> : hb_true_type {};
+template <typename T, typename U>
+using hb_is_assignable = _hb_is_assignable<T, U, void>;
+#define hb_is_assignable(T,U) hb_is_assignable<T, U>::value
+
+template <typename T>
+using hb_is_copy_assignable = hb_is_assignable<hb_add_lvalue_reference<T>,
+                                              hb_add_lvalue_reference<hb_add_const<T>>>;
+#define hb_is_copy_assignable(T) hb_is_copy_assignable<T>::value
+
+template <typename T>
+using hb_is_move_assignable = hb_is_assignable<hb_add_lvalue_reference<T>,
+                                              hb_add_rvalue_reference<T>>;
+#define hb_is_move_assignable(T) hb_is_move_assignable<T>::value
+
+/* Trivial versions. */
+
+template <typename T> union hb_trivial { T value; };
+
+/* Don't know how to do the following. */
+template <typename T>
+using hb_is_trivially_destructible= hb_is_destructible<hb_trivial<T>>;
+#define hb_is_trivially_destructible(T) hb_is_trivially_destructible<T>::value
+
+/* Don't know how to do the following. */
+//template <typename T, typename ...Ts>
+//using hb_is_trivially_constructible= hb_is_constructible<hb_trivial<T>, hb_trivial<Ts>...>;
+//#define hb_is_trivially_constructible(...) hb_is_trivially_constructible<__VA_ARGS__>::value
+
+template <typename T>
+using hb_is_trivially_default_constructible= hb_is_default_constructible<hb_trivial<T>>;
+#define hb_is_trivially_default_constructible(T) hb_is_trivially_default_constructible<T>::value
+
+template <typename T>
+using hb_is_trivially_copy_constructible= hb_is_copy_constructible<hb_trivial<T>>;
+#define hb_is_trivially_copy_constructible(T) hb_is_trivially_copy_constructible<T>::value
+
+template <typename T>
+using hb_is_trivially_move_constructible= hb_is_move_constructible<hb_trivial<T>>;
+#define hb_is_trivially_move_constructible(T) hb_is_trivially_move_constructible<T>::value
+
+/* Don't know how to do the following. */
+//template <typename T, typename U>
+//using hb_is_trivially_assignable= hb_is_assignable<hb_trivial<T>, hb_trivial<U>>;
+//#define hb_is_trivially_assignable(T,U) hb_is_trivially_assignable<T, U>::value
+
+template <typename T>
+using hb_is_trivially_copy_assignable= hb_is_copy_assignable<hb_trivial<T>>;
+#define hb_is_trivially_copy_assignable(T) hb_is_trivially_copy_assignable<T>::value
+
+template <typename T>
+using hb_is_trivially_move_assignable= hb_is_move_assignable<hb_trivial<T>>;
+#define hb_is_trivially_move_assignable(T) hb_is_trivially_move_assignable<T>::value
+
+template <typename T>
+using hb_is_trivially_copyable= hb_bool_constant<
+  hb_is_trivially_destructible (T) &&
+  (!hb_is_move_assignable (T) || hb_is_trivially_move_assignable (T)) &&
+  (!hb_is_move_constructible (T) || hb_is_trivially_move_constructible (T)) &&
+  (!hb_is_copy_assignable (T) || hb_is_trivially_copy_assignable (T)) &&
+  (!hb_is_copy_constructible (T) || hb_is_trivially_copy_constructible (T)) &&
+  true
+>;
+#define hb_is_trivially_copyable(T) hb_is_trivially_copyable<T>::value
+
+template <typename T>
+using hb_is_trivial= hb_bool_constant<
+  hb_is_trivially_copyable (T) &&
+  hb_is_trivially_default_constructible (T)
+>;
+#define hb_is_trivial(T) hb_is_trivial<T>::value
+
+
+#endif /* HB_META_HH */
index 35f1fde..e7f8b1c 100644 (file)
 /* Defined externally, i.e. in config.h; must have typedef'ed hb_mutex_impl_t as well. */
 
 
+#elif !defined(HB_NO_MT) && (defined(HAVE_PTHREAD) || defined(__APPLE__))
+
+#include <pthread.h>
+typedef pthread_mutex_t hb_mutex_impl_t;
+#define HB_MUTEX_IMPL_INIT     PTHREAD_MUTEX_INITIALIZER
+#define hb_mutex_impl_init(M)  pthread_mutex_init (M, nullptr)
+#define hb_mutex_impl_lock(M)  pthread_mutex_lock (M)
+#define hb_mutex_impl_unlock(M)        pthread_mutex_unlock (M)
+#define hb_mutex_impl_finish(M)        pthread_mutex_destroy (M)
+
+
 #elif !defined(HB_NO_MT) && defined(_WIN32)
 
 #include <windows.h>
@@ -63,17 +74,6 @@ typedef CRITICAL_SECTION hb_mutex_impl_t;
 #define hb_mutex_impl_finish(M)        DeleteCriticalSection (M)
 
 
-#elif !defined(HB_NO_MT) && (defined(HAVE_PTHREAD) || defined(__APPLE__))
-
-#include <pthread.h>
-typedef pthread_mutex_t hb_mutex_impl_t;
-#define HB_MUTEX_IMPL_INIT     PTHREAD_MUTEX_INITIALIZER
-#define hb_mutex_impl_init(M)  pthread_mutex_init (M, nullptr)
-#define hb_mutex_impl_lock(M)  pthread_mutex_lock (M)
-#define hb_mutex_impl_unlock(M)        pthread_mutex_unlock (M)
-#define hb_mutex_impl_finish(M)        pthread_mutex_destroy (M)
-
-
 #elif !defined(HB_NO_MT) && defined(HAVE_INTEL_ATOMIC_PRIMITIVES)
 
 #if defined(HAVE_SCHED_H) && defined(HAVE_SCHED_YIELD)
@@ -92,25 +92,7 @@ typedef volatile int hb_mutex_impl_t;
 #define hb_mutex_impl_finish(M)        HB_STMT_START {} HB_STMT_END
 
 
-#elif !defined(HB_NO_MT)
-
-#if defined(HAVE_SCHED_H) && defined(HAVE_SCHED_YIELD)
-# include <sched.h>
-# define HB_SCHED_YIELD() sched_yield ()
-#else
-# define HB_SCHED_YIELD() HB_STMT_START {} HB_STMT_END
-#endif
-
-#define HB_MUTEX_INT_NIL 1 /* Warn that fallback implementation is in use. */
-typedef volatile int hb_mutex_impl_t;
-#define HB_MUTEX_IMPL_INIT     0
-#define hb_mutex_impl_init(M)  *(M) = 0
-#define hb_mutex_impl_lock(M)  HB_STMT_START { while (*(M)) HB_SCHED_YIELD (); (*(M))++; } HB_STMT_END
-#define hb_mutex_impl_unlock(M)        (*(M))--;
-#define hb_mutex_impl_finish(M)        HB_STMT_START {} HB_STMT_END
-
-
-#else /* HB_NO_MT */
+#elif defined(HB_NO_MT)
 
 typedef int hb_mutex_impl_t;
 #define HB_MUTEX_IMPL_INIT     0
@@ -120,6 +102,11 @@ typedef int hb_mutex_impl_t;
 #define hb_mutex_impl_finish(M)        HB_STMT_START {} HB_STMT_END
 
 
+#else
+
+#error "Could not find any system to define mutex macros."
+#error "Check hb-mutex.hh for possible resolutions."
+
 #endif
 
 
@@ -127,8 +114,6 @@ typedef int hb_mutex_impl_t;
 
 struct hb_mutex_t
 {
-  /* TODO Add tracing. */
-
   hb_mutex_impl_t m;
 
   void init   () { hb_mutex_impl_init   (&m); }
index baddd99..d457820 100644 (file)
@@ -28,6 +28,7 @@
 #define HB_NULL_HH
 
 #include "hb.hh"
+#include "hb-meta.hh"
 
 
 /*
@@ -36,7 +37,7 @@
 
 /* Global nul-content Null pool.  Enlarge as necessary. */
 
-#define HB_NULL_POOL_SIZE 9880
+#define HB_NULL_POOL_SIZE 384
 
 /* Use SFINAE to sniff whether T has min_size; in which case return T::null_size,
  * otherwise return sizeof(T). */
  * https://stackoverflow.com/questions/7776448/sfinae-tried-with-bool-gives-compiler-error-template-argument-tvalue-invol
  */
 
-template<bool> struct _hb_bool_type {};
-
-template <typename T, typename B>
-struct _hb_null_size
-{ enum { value = sizeof (T) }; };
+template <typename T, typename>
+struct _hb_null_size : hb_integral_constant<unsigned, sizeof (T)> {};
 template <typename T>
-struct _hb_null_size<T, _hb_bool_type<(bool) (1 + (unsigned int) T::min_size)> >
-{ enum { value = T::null_size }; };
+struct _hb_null_size<T, hb_void_t<decltype (T::min_size)>> : hb_integral_constant<unsigned, T::null_size> {};
 
 template <typename T>
-struct hb_null_size
-{ enum { value = _hb_null_size<T, _hb_bool_type<true> >::value }; };
+using hb_null_size = _hb_null_size<T, void>;
 #define hb_null_size(T) hb_null_size<T>::value
 
 /* These doesn't belong here, but since is copy/paste from above, put it here. */
@@ -64,44 +60,21 @@ struct hb_null_size
 /* hb_static_size (T)
  * Returns T::static_size if T::min_size is defined, or sizeof (T) otherwise. */
 
-template <typename T, typename B>
-struct _hb_static_size
-{ enum { value = sizeof (T) }; };
+template <typename T, typename>
+struct _hb_static_size : hb_integral_constant<unsigned, sizeof (T)> {};
 template <typename T>
-struct _hb_static_size<T, _hb_bool_type<(bool) (1 + (unsigned int) T::min_size)> >
-{ enum { value = T::static_size }; };
-
+struct _hb_static_size<T, hb_void_t<decltype (T::min_size)>> : hb_integral_constant<unsigned, T::static_size> {};
 template <typename T>
-struct hb_static_size
-{ enum { value = _hb_static_size<T, _hb_bool_type<true> >::value }; };
+using hb_static_size = _hb_static_size<T, void>;
 #define hb_static_size(T) hb_static_size<T>::value
 
 
-/* hb_assign (obj, value)
- * Calls obj.set (value) if obj.min_size is defined and value has different type
- * from obj, or obj = v otherwise. */
-
-template <typename T, typename V, typename B>
-struct _hb_assign
-{ static inline void value (T &o, const V v) { o = v; } };
-template <typename T, typename V>
-struct _hb_assign<T, V, _hb_bool_type<(bool) (1 + (unsigned int) T::min_size)> >
-{ static inline void value (T &o, const V v) { o.set (v); } };
-template <typename T>
-struct _hb_assign<T, T, _hb_bool_type<(bool) (1 + (unsigned int) T::min_size)> >
-{ static inline void value (T &o, const T v) { o = v; } };
-
-template <typename T, typename V>
-static inline void hb_assign (T &o, const V v)
-{ _hb_assign<T, V, _hb_bool_type<true> >::value (o, v); }
-
-
 /*
  * Null()
  */
 
 extern HB_INTERNAL
-hb_vector_size_impl_t const _hb_NullPool[(HB_NULL_POOL_SIZE + sizeof (hb_vector_size_impl_t) - 1) / sizeof (hb_vector_size_impl_t)];
+uint64_t const _hb_NullPool[(HB_NULL_POOL_SIZE + sizeof (uint64_t) - 1) / sizeof (uint64_t)];
 
 /* Generic nul-content Null objects. */
 template <typename Type>
@@ -115,7 +88,7 @@ struct Null {
 template <typename QType>
 struct NullHelper
 {
-  typedef typename hb_remove_const (typename hb_remove_reference (QType)) Type;
+  typedef hb_remove_const<hb_remove_reference<QType>> Type;
   static const Type & get_null () { return Null<Type>::get_null (); }
 };
 #define Null(Type) NullHelper<Type>::get_null ()
@@ -155,7 +128,7 @@ struct NullHelper
  * causing bad memory access. So, races there are not actually introducing incorrectness
  * in the code. Has ~12kb binary size overhead to have it, also clang build fails with it. */
 extern HB_INTERNAL
-/*thread_local*/ hb_vector_size_impl_t _hb_CrapPool[(HB_NULL_POOL_SIZE + sizeof (hb_vector_size_impl_t) - 1) / sizeof (hb_vector_size_impl_t)];
+/*thread_local*/ uint64_t _hb_CrapPool[(HB_NULL_POOL_SIZE + sizeof (uint64_t) - 1) / sizeof (uint64_t)];
 
 /* CRAP pool: Common Region for Access Protection. */
 template <typename Type>
@@ -168,7 +141,7 @@ static inline Type& Crap () {
 template <typename QType>
 struct CrapHelper
 {
-  typedef typename hb_remove_const (typename hb_remove_reference (QType)) Type;
+  typedef hb_remove_const<hb_remove_reference<QType>> Type;
   static Type & get_crap () { return Crap<Type> (); }
 };
 #define Crap(Type) CrapHelper<Type>::get_crap ()
@@ -191,7 +164,7 @@ struct CrapOrNullHelper<const Type> {
 template <typename P>
 struct hb_nonnull_ptr_t
 {
-  typedef typename hb_remove_pointer (P) T;
+  typedef hb_remove_pointer<P> T;
 
   hb_nonnull_ptr_t (T *v_ = nullptr) : v (v_) {}
   T * operator = (T *v_)   { return v = v_; }
diff --git a/src/hb-number-parser.hh b/src/hb-number-parser.hh
new file mode 100644 (file)
index 0000000..c78c850
--- /dev/null
@@ -0,0 +1,240 @@
+
+#line 1 "hb-number-parser.rl"
+/*
+ * Copyright © 2019  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_NUMBER_PARSER_HH
+#define HB_NUMBER_PARSER_HH
+
+#include "hb.hh"
+
+#include <float.h>
+
+
+#line 37 "hb-number-parser.hh"
+static const unsigned char _double_parser_trans_keys[] = {
+       0u, 0u, 43u, 57u, 46u, 57u, 48u, 57u, 43u, 57u, 48u, 57u, 48u, 101u, 48u, 57u, 
+       46u, 101u, 0
+};
+
+static const char _double_parser_key_spans[] = {
+       0, 15, 12, 10, 15, 10, 54, 10, 
+       56
+};
+
+static const unsigned char _double_parser_index_offsets[] = {
+       0, 0, 16, 29, 40, 56, 67, 122, 
+       133
+};
+
+static const char _double_parser_indicies[] = {
+       0, 1, 2, 3, 1, 4, 4, 
+       4, 4, 4, 4, 4, 4, 4, 4, 
+       1, 3, 1, 4, 4, 4, 4, 4, 
+       4, 4, 4, 4, 4, 1, 5, 5, 
+       5, 5, 5, 5, 5, 5, 5, 5, 
+       1, 6, 1, 7, 1, 1, 8, 8, 
+       8, 8, 8, 8, 8, 8, 8, 8, 
+       1, 8, 8, 8, 8, 8, 8, 8, 
+       8, 8, 8, 1, 5, 5, 5, 5, 
+       5, 5, 5, 5, 5, 5, 1, 1, 
+       1, 1, 1, 1, 1, 1, 1, 1, 
+       1, 9, 1, 1, 1, 1, 1, 1, 
+       1, 1, 1, 1, 1, 1, 1, 1, 
+       1, 1, 1, 1, 1, 1, 1, 1, 
+       1, 1, 1, 1, 1, 1, 1, 1, 
+       1, 9, 1, 8, 8, 8, 8, 8, 
+       8, 8, 8, 8, 8, 1, 3, 1, 
+       4, 4, 4, 4, 4, 4, 4, 4, 
+       4, 4, 1, 1, 1, 1, 1, 1, 
+       1, 1, 1, 1, 1, 9, 1, 1, 
+       1, 1, 1, 1, 1, 1, 1, 1, 
+       1, 1, 1, 1, 1, 1, 1, 1, 
+       1, 1, 1, 1, 1, 1, 1, 1, 
+       1, 1, 1, 1, 1, 9, 1, 0
+};
+
+static const char _double_parser_trans_targs[] = {
+       2, 0, 2, 3, 8, 6, 5, 5, 
+       7, 4
+};
+
+static const char _double_parser_trans_actions[] = {
+       0, 0, 1, 0, 2, 3, 0, 4, 
+       5, 0
+};
+
+static const int double_parser_start = 1;
+static const int double_parser_first_final = 6;
+static const int double_parser_error = 0;
+
+static const int double_parser_en_main = 1;
+
+
+#line 70 "hb-number-parser.rl"
+
+
+/* Works only for n < 512 */
+static inline double
+_pow10 (unsigned int exponent)
+{
+  static const double _powers_of_10[] =
+  {
+    1.0e+256,
+    1.0e+128,
+    1.0e+64,
+    1.0e+32,
+    1.0e+16,
+    1.0e+8,
+    10000.,
+    100.,
+    10.
+  };
+  unsigned int mask = 1 << (ARRAY_LENGTH (_powers_of_10) - 1);
+  double result = 1;
+  for (const double *power = _powers_of_10; mask; ++power, mask >>= 1)
+    if (exponent & mask) result *= *power;
+  return result;
+}
+
+static inline double
+strtod_rl (const char *buf, char **end_ptr)
+{
+  const char *p, *pe;
+  double value = 0;
+  double frac = 0;
+  double frac_count = 0;
+  unsigned int exp = 0;
+  bool neg = false, exp_neg = false, exp_overflow = false;
+  const unsigned long long MAX_FRACT = 0xFFFFFFFFFFFFFull; /* 1^52-1 */
+  const unsigned int MAX_EXP = 0x7FFu; /* 1^11-1 */
+  p = buf;
+  pe = p + strlen (p);
+
+  while (p < pe && ISSPACE (*p))
+    p++;
+
+  int cs;
+  
+#line 142 "hb-number-parser.hh"
+       {
+       cs = double_parser_start;
+       }
+
+#line 147 "hb-number-parser.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 = _double_parser_trans_keys + (cs<<1);
+       _inds = _double_parser_indicies + _double_parser_index_offsets[cs];
+
+       _slen = _double_parser_key_spans[cs];
+       _trans = _inds[ _slen > 0 && _keys[0] <=(*p) &&
+               (*p) <= _keys[1] ?
+               (*p) - _keys[0] : _slen ];
+
+       cs = _double_parser_trans_targs[_trans];
+
+       if ( _double_parser_trans_actions[_trans] == 0 )
+               goto _again;
+
+       switch ( _double_parser_trans_actions[_trans] ) {
+       case 1:
+#line 39 "hb-number-parser.rl"
+       { neg = true; }
+       break;
+       case 4:
+#line 40 "hb-number-parser.rl"
+       { exp_neg = true; }
+       break;
+       case 2:
+#line 42 "hb-number-parser.rl"
+       {
+       value = value * 10. + ((*p) - '0');
+}
+       break;
+       case 3:
+#line 45 "hb-number-parser.rl"
+       {
+       if (likely (frac <= MAX_FRACT / 10))
+       {
+         frac = frac * 10. + ((*p) - '0');
+         ++frac_count;
+       }
+}
+       break;
+       case 5:
+#line 52 "hb-number-parser.rl"
+       {
+       if (likely (exp * 10 + ((*p) - '0') <= MAX_EXP))
+         exp = exp * 10 + ((*p) - '0');
+       else
+         exp_overflow = true;
+}
+       break;
+#line 205 "hb-number-parser.hh"
+       }
+
+_again:
+       if ( cs == 0 )
+               goto _out;
+       if ( ++p != pe )
+               goto _resume;
+       _test_eof: {}
+       _out: {}
+       }
+
+#line 116 "hb-number-parser.rl"
+
+
+  *end_ptr = (char *) p;
+
+  if (frac_count) value += frac / _pow10 (frac_count);
+  if (neg) value *= -1.;
+
+  if (unlikely (exp_overflow))
+  {
+    if (value == 0) return value;
+    if (exp_neg)    return neg ? -DBL_MIN : DBL_MIN;
+    else            return neg ? -DBL_MAX : DBL_MAX;
+  }
+
+  if (exp)
+  {
+    if (exp_neg) value /= _pow10 (exp);
+    else         value *= _pow10 (exp);
+  }
+
+  return value;
+}
+
+#endif /* HB_NUMBER_PARSER_HH */
diff --git a/src/hb-number-parser.rl b/src/hb-number-parser.rl
new file mode 100644 (file)
index 0000000..8445fa2
--- /dev/null
@@ -0,0 +1,139 @@
+/*
+ * Copyright © 2019  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_NUMBER_PARSER_HH
+#define HB_NUMBER_PARSER_HH
+
+#include "hb.hh"
+
+#include <float.h>
+
+%%{
+
+machine double_parser;
+alphtype unsigned char;
+write data;
+
+action see_neg { neg = true; }
+action see_exp_neg { exp_neg = true; }
+
+action add_int  {
+       value = value * 10. + (fc - '0');
+}
+action add_frac {
+       if (likely (frac <= MAX_FRACT / 10))
+       {
+         frac = frac * 10. + (fc - '0');
+         ++frac_count;
+       }
+}
+action add_exp  {
+       if (likely (exp * 10 + (fc - '0') <= MAX_EXP))
+         exp = exp * 10 + (fc - '0');
+       else
+         exp_overflow = true;
+}
+
+num = [0-9]+;
+
+main := (
+       (
+               (('+'|'-'@see_neg)? num @add_int) ('.' num @add_frac)?
+               |
+               (('+'|'-'@see_neg)? '.' num @add_frac)
+       )
+       (('e'|'E') (('+'|'-'@see_exp_neg)? num @add_exp))?
+);
+
+}%%
+
+/* Works only for n < 512 */
+static inline double
+_pow10 (unsigned int exponent)
+{
+  static const double _powers_of_10[] =
+  {
+    1.0e+256,
+    1.0e+128,
+    1.0e+64,
+    1.0e+32,
+    1.0e+16,
+    1.0e+8,
+    10000.,
+    100.,
+    10.
+  };
+  unsigned int mask = 1 << (ARRAY_LENGTH (_powers_of_10) - 1);
+  double result = 1;
+  for (const double *power = _powers_of_10; mask; ++power, mask >>= 1)
+    if (exponent & mask) result *= *power;
+  return result;
+}
+
+static inline double
+strtod_rl (const char *buf, char **end_ptr)
+{
+  const char *p, *pe;
+  double value = 0;
+  double frac = 0;
+  double frac_count = 0;
+  unsigned int exp = 0;
+  bool neg = false, exp_neg = false, exp_overflow = false;
+  const unsigned long long MAX_FRACT = 0xFFFFFFFFFFFFFull; /* 1^52-1 */
+  const unsigned int MAX_EXP = 0x7FFu; /* 1^11-1 */
+  p = buf;
+  pe = p + strlen (p);
+
+  while (p < pe && ISSPACE (*p))
+    p++;
+
+  int cs;
+  %%{
+    write init;
+    write exec;
+  }%%
+
+  *end_ptr = (char *) p;
+
+  if (frac_count) value += frac / _pow10 (frac_count);
+  if (neg) value *= -1.;
+
+  if (unlikely (exp_overflow))
+  {
+    if (value == 0) return value;
+    if (exp_neg)    return neg ? -DBL_MIN : DBL_MIN;
+    else            return neg ? -DBL_MAX : DBL_MAX;
+  }
+
+  if (exp)
+  {
+    if (exp_neg) value /= _pow10 (exp);
+    else         value *= _pow10 (exp);
+  }
+
+  return value;
+}
+
+#endif /* HB_NUMBER_PARSER_HH */
diff --git a/src/hb-number.cc b/src/hb-number.cc
new file mode 100644 (file)
index 0000000..4f84d4a
--- /dev/null
@@ -0,0 +1,147 @@
+/*
+ * Copyright © 2019  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.
+ *
+ */
+
+#include "hb.hh"
+#include "hb-machinery.hh"
+#include "hb-number-parser.hh"
+
+#include <locale.h>
+#ifdef HAVE_XLOCALE_H
+#include <xlocale.h>
+#endif
+
+template<typename T, typename Func>
+static bool
+_parse_number (const char **pp, const char *end, T *pv,
+              bool whole_buffer, Func f)
+{
+  char buf[32];
+  unsigned int len = hb_min (ARRAY_LENGTH (buf) - 1,
+                            (unsigned int) (end - *pp));
+  strncpy (buf, *pp, len);
+  buf[len] = '\0';
+
+  char *p = buf;
+  char *pend = p;
+
+  errno = 0;
+  *pv = f (p, &pend);
+  if (unlikely (errno || p == pend ||
+               /* Check if consumed whole buffer if is requested */
+               (whole_buffer && pend - p != end - *pp))) return false;
+
+  *pp += pend - p;
+  return true;
+}
+
+bool
+hb_parse_int (const char **pp, const char *end, int *pv, bool whole_buffer)
+{
+  return _parse_number<int> (pp, end, pv, whole_buffer,
+                            [] (const char *p, char **end)
+                            { return strtol (p, end, 10); });
+}
+
+bool
+hb_parse_uint (const char **pp, const char *end, unsigned int *pv,
+              bool whole_buffer, int base)
+{
+  return _parse_number<unsigned int> (pp, end, pv, whole_buffer,
+                                     [base] (const char *p, char **end)
+                                     { return strtoul (p, end, base); });
+}
+
+
+#if defined (HAVE_NEWLOCALE) && defined (HAVE_STRTOD_L)
+#define USE_XLOCALE 1
+#define HB_LOCALE_T locale_t
+#define HB_CREATE_LOCALE(locName) newlocale (LC_ALL_MASK, locName, nullptr)
+#define HB_FREE_LOCALE(loc) freelocale (loc)
+#elif defined(_MSC_VER)
+#define USE_XLOCALE 1
+#define HB_LOCALE_T _locale_t
+#define HB_CREATE_LOCALE(locName) _create_locale (LC_ALL, locName)
+#define HB_FREE_LOCALE(loc) _free_locale (loc)
+#define strtod_l(a, b, c) _strtod_l ((a), (b), (c))
+#endif
+
+#ifdef USE_XLOCALE
+
+#if HB_USE_ATEXIT
+static void free_static_C_locale ();
+#endif
+
+static struct hb_C_locale_lazy_loader_t : hb_lazy_loader_t<hb_remove_pointer<HB_LOCALE_T>,
+                                                         hb_C_locale_lazy_loader_t>
+{
+  static HB_LOCALE_T create ()
+  {
+    HB_LOCALE_T C_locale = HB_CREATE_LOCALE ("C");
+
+#if HB_USE_ATEXIT
+    atexit (free_static_C_locale);
+#endif
+
+    return C_locale;
+  }
+  static void destroy (HB_LOCALE_T p)
+  {
+    HB_FREE_LOCALE (p);
+  }
+  static HB_LOCALE_T get_null ()
+  {
+    return nullptr;
+  }
+} static_C_locale;
+
+#if HB_USE_ATEXIT
+static
+void free_static_C_locale ()
+{
+  static_C_locale.free_instance ();
+}
+#endif
+
+static HB_LOCALE_T
+get_C_locale ()
+{
+  return static_C_locale.get_unconst ();
+}
+#endif /* USE_XLOCALE */
+
+bool
+hb_parse_double (const char **pp, const char *end, double *pv,
+                bool whole_buffer)
+{
+  return _parse_number<double> (pp, end, pv, whole_buffer,
+                               [] (const char *p, char **end)
+                               {
+#ifdef USE_XLOCALE
+                                 return strtod_l (p, end, get_C_locale ());
+#else
+                                 return strtod_rl (p, end);
+#endif
+                               });
+}
similarity index 69%
rename from src/hb-warning.cc
rename to src/hb-number.hh
index 9fb4100..14d1260 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright © 2012  Google, Inc.
+ * Copyright © 2019  Ebrahim Byagowi
  *
  *  This is part of HarfBuzz, a text shaping library.
  *
  * 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
  */
 
-#include "hb.hh"
+#ifndef HB_NUMBER_HH
+#define HB_NUMBER_HH
 
-#if defined(HB_ATOMIC_INT_NIL)
-#error "Could not find any system to define atomic_int macros, library WILL NOT be thread-safe"
-#error "Check hb-atomic.hh for possible resolutions."
-#endif
+HB_INTERNAL bool
+hb_parse_int (const char **pp, const char *end, int *pv,
+             bool whole_buffer = false);
 
-#if defined(HB_MUTEX_IMPL_NIL)
-#error "Could not find any system to define mutex macros, library WILL NOT be thread-safe"
-#error "Check hb-mutex.hh for possible resolutions."
-#endif
+HB_INTERNAL bool
+hb_parse_uint (const char **pp, const char *end, unsigned int *pv,
+              bool whole_buffer = false, int base = 10);
+
+HB_INTERNAL bool
+hb_parse_double (const char **pp, const char *end, double *pv,
+                bool whole_buffer = false);
+
+#endif /* HB_NUMBER_HH */
index 68520f2..c470532 100644 (file)
@@ -62,7 +62,7 @@ struct hb_lockable_set_t
        old.fini ();
       }
       else {
-        item = nullptr;
+       item = nullptr;
        l.unlock ();
       }
     } else {
index 32a223c..cb1fdf1 100644 (file)
@@ -56,7 +56,7 @@ typedef struct TableRecord
 {
   int cmp (Tag t) const { return -t.cmp (tag); }
 
-  static int cmp (const void *pa, const void *pb)
+  HB_INTERNAL static int cmp (const void *pa, const void *pb)
   {
     const TableRecord *a = (const TableRecord *) pa;
     const TableRecord *b = (const TableRecord *) pb;
@@ -86,15 +86,15 @@ typedef struct OffsetTable
   const TableRecord& get_table (unsigned int i) const
   { return tables[i]; }
   unsigned int get_table_tags (unsigned int  start_offset,
-                                     unsigned int *table_count, /* IN/OUT */
-                                     hb_tag_t     *table_tags /* OUT */) const
+                              unsigned int *table_count, /* IN/OUT */
+                              hb_tag_t     *table_tags /* OUT */) const
   {
     if (table_count)
     {
       if (start_offset >= tables.len)
-        *table_count = 0;
+       *table_count = 0;
       else
-        *table_count = MIN<unsigned int> (*table_count, tables.len - start_offset);
+       *table_count = hb_min (*table_count, tables.len - start_offset);
 
       const TableRecord *sub_tables = tables.arrayZ + start_offset;
       unsigned int count = *table_count;
@@ -106,7 +106,7 @@ typedef struct OffsetTable
   bool find_table_index (hb_tag_t tag, unsigned int *table_index) const
   {
     Tag t;
-    t.set (tag);
+    t = tag;
     return tables.bfind (t, table_index, HB_BFIND_NOT_FOUND_STORE, Index::NOT_FOUND_INDEX);
   }
   const TableRecord& get_table_by_tag (hb_tag_t tag) const
@@ -127,7 +127,7 @@ typedef struct OffsetTable
     /* Alloc 12 for the OTHeader. */
     if (unlikely (!c->extend_min (*this))) return_trace (false);
     /* Write sfntVersion (bytes 0..3). */
-    sfnt_version.set (sfnt_tag);
+    sfnt_version = sfnt_tag;
     /* Take space for numTables, searchRange, entrySelector, RangeShift
      * and the TableRecords themselves.  */
     if (unlikely (!tables.serialize (c, items.length))) return_trace (false);
@@ -140,15 +140,16 @@ typedef struct OffsetTable
     {
       TableRecord &rec = tables.arrayZ[i];
       hb_blob_t *blob = items[i].blob;
-      rec.tag.set (items[i].tag);
-      rec.length.set (hb_blob_get_length (blob));
+      rec.tag = items[i].tag;
+      rec.length = blob->length;
       rec.offset.serialize (c, this);
 
       /* Allocate room for the table and copy it. */
       char *start = (char *) c->allocate_size<void> (rec.length);
-      if (unlikely (!start)) {return false;}
+      if (unlikely (!start)) return false;
 
-      memcpy (start, hb_blob_get_data (blob, nullptr), rec.length);
+      if (likely (rec.length))
+       memcpy (start, blob->data, rec.length);
 
       /* 4-byte alignment. */
       c->align (4);
@@ -159,7 +160,7 @@ typedef struct OffsetTable
       {
        head *h = (head *) start;
        checksum_adjustment = &h->checkSumAdjustment;
-       checksum_adjustment->set (0);
+       *checksum_adjustment = 0;
       }
 
       rec.checkSum.set_for_data (start, end - start);
@@ -177,10 +178,10 @@ typedef struct OffsetTable
       for (unsigned int i = 0; i < items.length; i++)
       {
        TableRecord &rec = tables.arrayZ[i];
-       checksum.set (checksum + rec.checkSum);
+       checksum = checksum + rec.checkSum;
       }
 
-      checksum_adjustment->set (0xB1B0AFBAu - checksum);
+      *checksum_adjustment = 0xB1B0AFBAu - checksum;
     }
 
     return_trace (true);
@@ -222,7 +223,7 @@ struct TTCHeaderVersion1
   Tag          ttcTag;         /* TrueType Collection ID string: 'ttcf' */
   FixedVersion<>version;       /* Version of the TTC Header (1.0),
                                 * 0x00010000u */
-  LArrayOf<LOffsetTo<OffsetTable> >
+  LArrayOf<LOffsetTo<OffsetTable>>
                table;          /* Array of offsets to the OffsetTable for each font
                                 * from the beginning of the file */
   public:
@@ -286,7 +287,7 @@ struct ResourceRecord
   { return CastR<OpenTypeFontFace> ((data_base+offset).arrayZ); }
 
   bool sanitize (hb_sanitize_context_t *c,
-                       const void *data_base) const
+                const void *data_base) const
   {
     TRACE_SANITIZE (this);
     return_trace (c->check_struct (this) &&
@@ -334,7 +335,7 @@ struct ResourceTypeRecord
   protected:
   Tag          tag;            /* Resource type. */
   HBUINT16     resCountM1;     /* Number of resources minus 1. */
-  NNOffsetTo<UnsizedArrayOf<ResourceRecord> >
+  NNOffsetTo<UnsizedArrayOf<ResourceRecord>>
                resourcesZ;     /* Offset from beginning of resource type list
                                 * to reference item list for this type. */
   public:
@@ -390,7 +391,7 @@ struct ResourceMap
   HBUINT32     reserved1;      /* Reserved for handle to next resource map */
   HBUINT16     resreved2;      /* Reserved for file reference number */
   HBUINT16     attrs;          /* Resource fork attribute */
-  NNOffsetTo<ArrayOfM1<ResourceTypeRecord> >
+  NNOffsetTo<ArrayOfM1<ResourceTypeRecord>>
                typeList;       /* Offset from beginning of map to
                                 * resource type list */
   Offset16     nameList;       /* Offset from beginning of map to
@@ -422,7 +423,7 @@ struct ResourceForkHeader
   }
 
   protected:
-  LNNOffsetTo<UnsizedArrayOf<HBUINT8> >
+  LNNOffsetTo<UnsizedArrayOf<HBUINT8>>
                data;           /* Offset from beginning of resource fork
                                 * to resource data */
   LNNOffsetTo<ResourceMap >
index 6abb898..af242ec 100644 (file)
@@ -52,22 +52,27 @@ namespace OT {
  * Int types
  */
 
-template <bool is_signed> struct hb_signedness_int;
-template <> struct hb_signedness_int<false> { typedef unsigned int value; };
-template <> struct hb_signedness_int<true>  { typedef   signed int value; };
-
 /* Integer types in big-endian order and no alignment requirement */
 template <typename Type, unsigned int Size>
 struct IntType
 {
   typedef Type type;
-  typedef typename hb_signedness_int<hb_is_signed<Type>::value>::value wide_type;
+  typedef hb_conditional<hb_is_signed (Type), signed, unsigned> wide_type;
 
-  void set (wide_type i) { v.set (i); }
+  IntType& operator = (wide_type i) { v = i; return *this; }
   operator wide_type () const { return v; }
-  bool operator == (const IntType<Type,Size> &o) const { return (Type) v == (Type) o.v; }
-  bool operator != (const IntType<Type,Size> &o) const { return !(*this == o); }
-  static int cmp (const IntType<Type,Size> *a, const IntType<Type,Size> *b) { return b->cmp (*a); }
+  bool operator == (const IntType &o) const { return (Type) v == (Type) o.v; }
+  bool operator != (const IntType &o) const { return !(*this == o); }
+
+  IntType& operator += (unsigned count) { *this = *this + count; return *this; }
+  IntType& operator -= (unsigned count) { *this = *this - count; return *this; }
+  IntType& operator ++ () { *this += 1; return *this; }
+  IntType& operator -- () { *this -= 1; return *this; }
+  IntType operator ++ (int) { IntType c (*this); ++*this; return c; }
+  IntType operator -- (int) { IntType c (*this); --*this; return c; }
+
+  HB_INTERNAL static int cmp (const IntType *a, const IntType *b)
+  { return b->cmp (*a); }
   template <typename Type2>
   int cmp (Type2 a) const
   {
@@ -110,19 +115,21 @@ typedef HBUINT16 UFWORD;
 /* 16-bit signed fixed number with the low 14 bits of fraction (2.14). */
 struct F2DOT14 : HBINT16
 {
+  F2DOT14& operator = (uint16_t i ) { HBINT16::operator= (i); return *this; }
   // 16384 means 1<<14
   float to_float () const  { return ((int32_t) v) / 16384.f; }
-  void set_float (float f) { v.set (round (f * 16384.f)); }
+  void set_float (float f) { v = roundf (f * 16384.f); }
   public:
   DEFINE_SIZE_STATIC (2);
 };
 
 /* 32-bit signed fixed-point number (16.16). */
-struct Fixed : HBINT32
+struct HBFixed : HBINT32
 {
+  HBFixed& operator = (uint32_t i) { HBINT32::operator= (i); return *this; }
   // 65536 means 1<<16
   float to_float () const  { return ((int32_t) v) / 65536.f; }
-  void set_float (float f) { v.set (round (f * 65536.f)); }
+  void set_float (float f) { v = roundf (f * 65536.f); }
   public:
   DEFINE_SIZE_STATIC (4);
 };
@@ -147,6 +154,7 @@ struct LONGDATETIME
  * system, feature, or baseline */
 struct Tag : HBUINT32
 {
+  Tag& operator = (hb_tag_t i) { HBUINT32::operator= (i); return *this; }
   /* What the char* converters return is NOT nul-terminated.  Print using "%.4s" */
   operator const char* () const { return reinterpret_cast<const char *> (&this->v); }
   operator char* ()             { return reinterpret_cast<char *> (&this->v); }
@@ -155,11 +163,15 @@ struct Tag : HBUINT32
 };
 
 /* Glyph index number, same as uint16 (length = 16 bits) */
-typedef HBUINT16 GlyphID;
+struct HBGlyphID : HBUINT16
+{
+  HBGlyphID& operator = (uint16_t i) { HBUINT16::operator= (i); return *this; }
+};
 
 /* Script/language-system/feature index */
 struct Index : HBUINT16 {
   static constexpr unsigned NOT_FOUND_INDEX = 0xFFFFu;
+  Index& operator = (uint16_t i) { HBUINT16::operator= (i); return *this; }
 };
 DECLARE_NULL_NAMESPACE_BYTES (OT, Index);
 
@@ -169,6 +181,8 @@ typedef Index NameID;
 template <typename Type, bool has_null=true>
 struct Offset : Type
 {
+  Offset& operator = (typename Type::type i) { Type::operator= (i); return *this; }
+
   typedef Type type;
 
   bool is_null () const { return has_null && 0 == *this; }
@@ -176,7 +190,7 @@ struct Offset : Type
   void *serialize (hb_serialize_context_t *c, const void *base)
   {
     void *t = c->start_embed<void> ();
-    this->set ((char *) t - (char *) base); /* TODO(serialize) Overflow? */
+    c->check_assign (*this, (unsigned) ((char *) t - (char *) base));
     return t;
   }
 
@@ -191,6 +205,8 @@ typedef Offset<HBUINT32> Offset32;
 /* CheckSum */
 struct CheckSum : HBUINT32
 {
+  CheckSum& operator = (uint32_t i) { HBUINT32::operator= (i); return *this; }
+
   /* This is reference implementation from the spec. */
   static uint32_t CalcTableChecksum (const HBUINT32 *Table, uint32_t Length)
   {
@@ -205,7 +221,7 @@ struct CheckSum : HBUINT32
 
   /* Note: data should be 4byte aligned and have 4byte padding at the end. */
   void set_for_data (const void *data, unsigned int length)
-  { set (CalcTableChecksum ((const HBUINT32 *) data, length)); }
+  { *this = CalcTableChecksum ((const HBUINT32 *) data, length); }
 
   public:
   DEFINE_SIZE_STATIC (4);
@@ -248,13 +264,18 @@ struct _hb_has_null
 template <typename Type>
 struct _hb_has_null<Type, true>
 {
-  static const Type *get_null () { return &Null(Type); }
-  static Type *get_crap ()       { return &Crap(Type); }
+  static const Type *get_null () { return &Null (Type); }
+  static       Type *get_crap () { return &Crap (Type); }
 };
 
 template <typename Type, typename OffsetType=HBUINT16, bool has_null=true>
 struct OffsetTo : Offset<OffsetType, has_null>
 {
+  HB_DELETE_COPY_ASSIGN (OffsetTo);
+  OffsetTo () = default;
+
+  OffsetTo& operator = (typename OffsetType::type i) { OffsetType::operator= (i); return *this; }
+
   const Type& operator () (const void *base) const
   {
     if (unlikely (this->is_null ())) return *_hb_has_null<Type, has_null>::get_null ();
@@ -266,22 +287,68 @@ struct OffsetTo : Offset<OffsetType, has_null>
     return StructAtOffset<Type> (base, *this);
   }
 
+  template <typename Base,
+           hb_enable_if (hb_is_convertible (const Base, const void *))>
+  friend const Type& operator + (const Base &base, const OffsetTo &offset) { return offset ((const void *) base); }
+  template <typename Base,
+           hb_enable_if (hb_is_convertible (const Base, const void *))>
+  friend const Type& operator + (const OffsetTo &offset, const Base &base) { return offset ((const void *) base); }
+  template <typename Base,
+           hb_enable_if (hb_is_convertible (Base, void *))>
+  friend Type& operator + (Base &&base, OffsetTo &offset) { return offset ((void *) base); }
+  template <typename Base,
+           hb_enable_if (hb_is_convertible (Base, void *))>
+  friend Type& operator + (OffsetTo &offset, Base &&base) { return offset ((void *) base); }
+
   Type& serialize (hb_serialize_context_t *c, const void *base)
   {
     return * (Type *) Offset<OffsetType>::serialize (c, base);
   }
 
-  template <typename T>
-  void serialize_subset (hb_subset_context_t *c, const T &src, const void *base)
+  template <typename ...Ts>
+  bool serialize_subset (hb_subset_context_t *c,
+                        const OffsetTo& src,
+                        const void *src_base,
+                        const void *dst_base,
+                        Ts&&... ds)
   {
-    if (&src == &Null (T))
-    {
-      this->set (0);
-      return;
-    }
-    serialize (c->serializer, base);
-    if (!src.subset (c))
-      this->set (0);
+    *this = 0;
+    if (src.is_null ())
+      return false;
+
+    auto *s = c->serializer;
+
+    s->push ();
+
+    bool ret = c->dispatch (src_base+src, hb_forward<Ts> (ds)...);
+
+    if (ret || !has_null)
+      s->add_link (*this, s->pop_pack (), dst_base);
+    else
+      s->pop_discard ();
+
+    return ret;
+  }
+
+  /* TODO: Somehow merge this with previous function into a serialize_dispatch(). */
+  template <typename ...Ts>
+  bool serialize_copy (hb_serialize_context_t *c,
+                      const OffsetTo& src,
+                      const void *src_base,
+                      const void *dst_base,
+                      Ts&&... ds)
+  {
+    *this = 0;
+    if (src.is_null ())
+      return false;
+
+    c->push ();
+
+    bool ret = c->copy (src_base+src, hb_forward<Ts> (ds)...);
+
+    c->add_link (*this, c->pop_pack (), dst_base);
+
+    return ret;
   }
 
   bool sanitize_shallow (hb_sanitize_context_t *c, const void *base) const
@@ -293,39 +360,13 @@ struct OffsetTo : Offset<OffsetType, has_null>
     return_trace (true);
   }
 
-  bool sanitize (hb_sanitize_context_t *c, const void *base) const
-  {
-    TRACE_SANITIZE (this);
-    return_trace (sanitize_shallow (c, base) &&
-                 (this->is_null () ||
-                  StructAtOffset<Type> (base, *this).sanitize (c) ||
-                  neuter (c)));
-  }
-  template <typename T1>
-  bool sanitize (hb_sanitize_context_t *c, const void *base, T1 d1) const
+  template <typename ...Ts>
+  bool sanitize (hb_sanitize_context_t *c, const void *base, Ts&&... ds) const
   {
     TRACE_SANITIZE (this);
     return_trace (sanitize_shallow (c, base) &&
                  (this->is_null () ||
-                  StructAtOffset<Type> (base, *this).sanitize (c, d1) ||
-                  neuter (c)));
-  }
-  template <typename T1, typename T2>
-  bool sanitize (hb_sanitize_context_t *c, const void *base, T1 d1, T2 d2) const
-  {
-    TRACE_SANITIZE (this);
-    return_trace (sanitize_shallow (c, base) &&
-                 (this->is_null () ||
-                  StructAtOffset<Type> (base, *this).sanitize (c, d1, d2) ||
-                  neuter (c)));
-  }
-  template <typename T1, typename T2, typename T3>
-  bool sanitize (hb_sanitize_context_t *c, const void *base, T1 d1, T2 d2, T3 d3) const
-  {
-    TRACE_SANITIZE (this);
-    return_trace (sanitize_shallow (c, base) &&
-                 (this->is_null () ||
-                  StructAtOffset<Type> (base, *this).sanitize (c, d1, d2, d3) ||
+                  c->dispatch (StructAtOffset<Type> (base, *this), hb_forward<Ts> (ds)...) ||
                   neuter (c)));
   }
 
@@ -338,14 +379,12 @@ struct OffsetTo : Offset<OffsetType, has_null>
   DEFINE_SIZE_STATIC (sizeof (OffsetType));
 };
 /* Partial specializations. */
-template <typename Type,                               bool has_null=true> struct   LOffsetTo : OffsetTo<Type, HBUINT32,   has_null> {};
-template <typename Type, typename OffsetType=HBUINT16                    > struct  NNOffsetTo : OffsetTo<Type, OffsetType, false> {};
-template <typename Type                                                  > struct LNNOffsetTo : OffsetTo<Type, HBUINT32,   false> {};
-
-template <typename Base, typename OffsetType, bool has_null, typename Type>
-static inline const Type& operator + (const Base &base, const OffsetTo<Type, OffsetType, has_null> &offset) { return offset (base); }
-template <typename Base, typename OffsetType, bool has_null, typename Type>
-static inline Type& operator + (Base &base, OffsetTo<Type, OffsetType, has_null> &offset) { return offset (base); }
+template <typename Type, bool has_null=true>
+using LOffsetTo = OffsetTo<Type, HBUINT32, has_null>;
+template <typename Type, typename OffsetType=HBUINT16>
+using NNOffsetTo = OffsetTo<Type, OffsetType, false>;
+template <typename Type>
+using LNNOffsetTo = LOffsetTo<Type, false>;
 
 
 /*
@@ -358,7 +397,7 @@ struct UnsizedArrayOf
   typedef Type item_t;
   static constexpr unsigned item_size = hb_static_size (Type);
 
-  HB_NO_CREATE_COPY_ASSIGN_TEMPLATE (UnsizedArrayOf, Type);
+  HB_DELETE_CREATE_COPY_ASSIGN (UnsizedArrayOf);
 
   const Type& operator [] (int i_) const
   {
@@ -384,7 +423,7 @@ struct UnsizedArrayOf
   { return hb_array (arrayZ, len); }
   hb_array_t<const Type> as_array (unsigned int len) const
   { return hb_array (arrayZ, len); }
-  operator hb_array_t<Type> ()             { return as_array (); }
+  operator hb_array_t<      Type> ()       { return as_array (); }
   operator hb_array_t<const Type> () const { return as_array (); }
 
   template <typename T>
@@ -397,38 +436,42 @@ struct UnsizedArrayOf
   void qsort (unsigned int len, unsigned int start = 0, unsigned int end = (unsigned int) -1)
   { as_array (len).qsort (start, end); }
 
-  bool sanitize (hb_sanitize_context_t *c, unsigned int count) const
+  bool serialize (hb_serialize_context_t *c, unsigned int items_len)
   {
-    TRACE_SANITIZE (this);
-    if (unlikely (!sanitize_shallow (c, count))) return_trace (false);
-
-    /* Note: for structs that do not reference other structs,
-     * we do not need to call their sanitize() as we already did
-     * a bound check on the aggregate array size.  We just include
-     * a small unreachable expression to make sure the structs
-     * pointed to do have a simple sanitize(), ie. they do not
-     * reference other structs via offsets.
-     */
-    (void) (false && arrayZ[0].sanitize (c));
-
+    TRACE_SERIALIZE (this);
+    if (unlikely (!c->extend (*this, items_len))) return_trace (false);
     return_trace (true);
   }
-  bool sanitize (hb_sanitize_context_t *c, unsigned int count, const void *base) const
+  template <typename Iterator,
+           hb_requires (hb_is_source_of (Iterator, Type))>
+  bool serialize (hb_serialize_context_t *c, Iterator items)
   {
-    TRACE_SANITIZE (this);
-    if (unlikely (!sanitize_shallow (c, count))) return_trace (false);
-    for (unsigned int i = 0; i < count; i++)
-      if (unlikely (!arrayZ[i].sanitize (c, base)))
-       return_trace (false);
+    TRACE_SERIALIZE (this);
+    unsigned count = items.len ();
+    if (unlikely (!serialize (c, count))) return_trace (false);
+    /* TODO Umm. Just exhaust the iterator instead?  Being extra
+     * cautious right now.. */
+    for (unsigned i = 0; i < count; i++, ++items)
+      arrayZ[i] = *items;
     return_trace (true);
   }
-  template <typename T>
-  bool sanitize (hb_sanitize_context_t *c, unsigned int count, const void *base, T user_data) const
+
+  UnsizedArrayOf* copy (hb_serialize_context_t *c, unsigned count) const
+  {
+    TRACE_SERIALIZE (this);
+    auto *out = c->start_embed (this);
+    if (unlikely (!as_array (count).copy (c))) return_trace (nullptr);
+    return_trace (out);
+  }
+
+  template <typename ...Ts>
+  bool sanitize (hb_sanitize_context_t *c, unsigned int count, Ts&&... ds) const
   {
     TRACE_SANITIZE (this);
     if (unlikely (!sanitize_shallow (c, count))) return_trace (false);
+    if (!sizeof... (Ts) && hb_is_trivially_copyable (Type)) return_trace (true);
     for (unsigned int i = 0; i < count; i++)
-      if (unlikely (!arrayZ[i].sanitize (c, base, user_data)))
+      if (unlikely (!c->dispatch (arrayZ[i], hb_forward<Ts> (ds)...)))
        return_trace (false);
     return_trace (true);
   }
@@ -440,14 +483,14 @@ struct UnsizedArrayOf
   }
 
   public:
-  Type         arrayZ[VAR];
+  Type         arrayZ[HB_VAR_ARRAY];
   public:
   DEFINE_SIZE_UNBOUNDED (0);
 };
 
 /* Unsized array of offset's */
 template <typename Type, typename OffsetType, bool has_null=true>
-struct UnsizedOffsetArrayOf : UnsizedArrayOf<OffsetTo<Type, OffsetType, has_null> > {};
+using UnsizedOffsetArrayOf = UnsizedArrayOf<OffsetTo<Type, OffsetType, has_null>>;
 
 /* Unsized array of offsets relative to the beginning of the array itself. */
 template <typename Type, typename OffsetType, bool has_null=true>
@@ -468,17 +511,12 @@ struct UnsizedOffsetListOf : UnsizedOffsetArrayOf<Type, OffsetType, has_null>
     return this+*p;
   }
 
-
-  bool sanitize (hb_sanitize_context_t *c, unsigned int count) const
-  {
-    TRACE_SANITIZE (this);
-    return_trace ((UnsizedOffsetArrayOf<Type, OffsetType, has_null>::sanitize (c, count, this)));
-  }
-  template <typename T>
-  bool sanitize (hb_sanitize_context_t *c, unsigned int count, T user_data) const
+  template <typename ...Ts>
+  bool sanitize (hb_sanitize_context_t *c, unsigned int count, Ts&&... ds) const
   {
     TRACE_SANITIZE (this);
-    return_trace ((UnsizedOffsetArrayOf<Type, OffsetType, has_null>::sanitize (c, count, this, user_data)));
+    return_trace ((UnsizedOffsetArrayOf<Type, OffsetType, has_null>
+                  ::sanitize (c, count, this, hb_forward<Ts> (ds)...)));
   }
 };
 
@@ -514,7 +552,7 @@ struct ArrayOf
   typedef Type item_t;
   static constexpr unsigned item_size = hb_static_size (Type);
 
-  HB_NO_CREATE_COPY_ASSIGN_TEMPLATE2 (ArrayOf, Type, LenType);
+  HB_DELETE_CREATE_COPY_ASSIGN (ArrayOf);
 
   const Type& operator [] (int i_) const
   {
@@ -532,74 +570,83 @@ struct ArrayOf
   unsigned int get_size () const
   { return len.static_size + len * Type::static_size; }
 
-  hb_array_t<Type> as_array ()
-  { return hb_array (arrayZ, len); }
-  hb_array_t<const Type> as_array () const
-  { return hb_array (arrayZ, len); }
-  operator hb_array_t<Type> (void)             { return as_array (); }
-  operator hb_array_t<const Type> (void) const { return as_array (); }
+  explicit operator bool () const { return len; }
+
+  void pop () { len--; }
+
+  hb_array_t<      Type> as_array ()       { return hb_array (arrayZ, len); }
+  hb_array_t<const Type> as_array () const { return hb_array (arrayZ, len); }
+
+  /* Iterator. */
+  typedef hb_array_t<const Type>   iter_t;
+  typedef hb_array_t<      Type> writer_t;
+    iter_t   iter () const { return as_array (); }
+  writer_t writer ()       { return as_array (); }
+  operator   iter_t () const { return   iter (); }
+  operator writer_t ()       { return writer (); }
 
   hb_array_t<const Type> sub_array (unsigned int start_offset, unsigned int count) const
-  { return as_array ().sub_array (start_offset, count);}
+  { return as_array ().sub_array (start_offset, count); }
   hb_array_t<const Type> sub_array (unsigned int start_offset, unsigned int *count = nullptr /* IN/OUT */) const
-  { return as_array ().sub_array (start_offset, count);}
+  { return as_array ().sub_array (start_offset, count); }
   hb_array_t<Type> sub_array (unsigned int start_offset, unsigned int count)
-  { return as_array ().sub_array (start_offset, count);}
+  { return as_array ().sub_array (start_offset, count); }
   hb_array_t<Type> sub_array (unsigned int start_offset, unsigned int *count = nullptr /* IN/OUT */)
-  { return as_array ().sub_array (start_offset, count);}
+  { return as_array ().sub_array (start_offset, count); }
 
   bool serialize (hb_serialize_context_t *c, unsigned int items_len)
   {
     TRACE_SERIALIZE (this);
     if (unlikely (!c->extend_min (*this))) return_trace (false);
-    len.set (items_len); /* TODO(serialize) Overflow? */
+    c->check_assign (len, items_len);
     if (unlikely (!c->extend (*this))) return_trace (false);
     return_trace (true);
   }
-  template <typename T>
-  bool serialize (hb_serialize_context_t *c, hb_array_t<const T> items)
+  template <typename Iterator,
+           hb_requires (hb_is_source_of (Iterator, Type))>
+  bool serialize (hb_serialize_context_t *c, Iterator items)
   {
     TRACE_SERIALIZE (this);
-    if (unlikely (!serialize (c, items.length))) return_trace (false);
-    for (unsigned int i = 0; i < items.length; i++)
-      hb_assign (arrayZ[i], items[i]);
+    unsigned count = items.len ();
+    if (unlikely (!serialize (c, count))) return_trace (false);
+    /* TODO Umm. Just exhaust the iterator instead?  Being extra
+     * cautious right now.. */
+    for (unsigned i = 0; i < count; i++, ++items)
+      arrayZ[i] = *items;
     return_trace (true);
   }
 
-  bool sanitize (hb_sanitize_context_t *c) const
+  Type* serialize_append (hb_serialize_context_t *c)
   {
-    TRACE_SANITIZE (this);
-    if (unlikely (!sanitize_shallow (c))) return_trace (false);
-
-    /* Note: for structs that do not reference other structs,
-     * we do not need to call their sanitize() as we already did
-     * a bound check on the aggregate array size.  We just include
-     * a small unreachable expression to make sure the structs
-     * pointed to do have a simple sanitize(), ie. they do not
-     * reference other structs via offsets.
-     */
-    (void) (false && arrayZ[0].sanitize (c));
-
-    return_trace (true);
+    TRACE_SERIALIZE (this);
+    len++;
+    if (unlikely (!len || !c->extend (*this)))
+    {
+      len--;
+      return_trace (nullptr);
+    }
+    return_trace (&arrayZ[len - 1]);
   }
-  bool sanitize (hb_sanitize_context_t *c, const void *base) const
+
+  ArrayOf* copy (hb_serialize_context_t *c) const
   {
-    TRACE_SANITIZE (this);
-    if (unlikely (!sanitize_shallow (c))) return_trace (false);
-    unsigned int count = len;
-    for (unsigned int i = 0; i < count; i++)
-      if (unlikely (!arrayZ[i].sanitize (c, base)))
-       return_trace (false);
-    return_trace (true);
+    TRACE_SERIALIZE (this);
+    auto *out = c->start_embed (this);
+    if (unlikely (!c->extend_min (out))) return_trace (nullptr);
+    c->check_assign (out->len, len);
+    if (unlikely (!as_array ().copy (c))) return_trace (nullptr);
+    return_trace (out);
   }
-  template <typename T>
-  bool sanitize (hb_sanitize_context_t *c, const void *base, T user_data) const
+
+  template <typename ...Ts>
+  bool sanitize (hb_sanitize_context_t *c, Ts&&... ds) const
   {
     TRACE_SANITIZE (this);
     if (unlikely (!sanitize_shallow (c))) return_trace (false);
+    if (!sizeof... (Ts) && hb_is_trivially_copyable (Type)) return_trace (true);
     unsigned int count = len;
     for (unsigned int i = 0; i < count; i++)
-      if (unlikely (!arrayZ[i].sanitize (c, base, user_data)))
+      if (unlikely (!c->dispatch (arrayZ[i], hb_forward<Ts> (ds)...)))
        return_trace (false);
     return_trace (true);
   }
@@ -622,20 +669,21 @@ struct ArrayOf
 
   public:
   LenType      len;
-  Type         arrayZ[VAR];
+  Type         arrayZ[HB_VAR_ARRAY];
   public:
   DEFINE_SIZE_ARRAY (sizeof (LenType), arrayZ);
 };
-template <typename Type> struct LArrayOf : ArrayOf<Type, HBUINT32> {};
-typedef ArrayOf<HBUINT8, HBUINT8> PString;
+template <typename Type>
+using LArrayOf = ArrayOf<Type, HBUINT32>;
+using PString = ArrayOf<HBUINT8, HBUINT8>;
 
 /* Array of Offset's */
 template <typename Type>
-struct OffsetArrayOf : ArrayOf<OffsetTo<Type, HBUINT16> > {};
+using OffsetArrayOf = ArrayOf<OffsetTo<Type, HBUINT16>>;
 template <typename Type>
-struct LOffsetArrayOf : ArrayOf<OffsetTo<Type, HBUINT32> > {};
+using LOffsetArrayOf = ArrayOf<OffsetTo<Type, HBUINT32>>;
 template <typename Type>
-struct LOffsetLArrayOf : ArrayOf<OffsetTo<Type, HBUINT32>, HBUINT32> {};
+using LOffsetLArrayOf = ArrayOf<OffsetTo<Type, HBUINT32>, HBUINT32>;
 
 /* Array of offsets relative to the beginning of the array itself. */
 template <typename Type>
@@ -661,20 +709,15 @@ struct OffsetListOf : OffsetArrayOf<Type>
     if (unlikely (!out)) return_trace (false);
     unsigned int count = this->len;
     for (unsigned int i = 0; i < count; i++)
-      out->arrayZ[i].serialize_subset (c, (*this)[i], out);
+      out->arrayZ[i].serialize_subset (c, this->arrayZ[i], this, out);
     return_trace (true);
   }
 
-  bool sanitize (hb_sanitize_context_t *c) const
+  template <typename ...Ts>
+  bool sanitize (hb_sanitize_context_t *c, Ts&&... ds) const
   {
     TRACE_SANITIZE (this);
-    return_trace (OffsetArrayOf<Type>::sanitize (c, this));
-  }
-  template <typename T>
-  bool sanitize (hb_sanitize_context_t *c, T user_data) const
-  {
-    TRACE_SANITIZE (this);
-    return_trace (OffsetArrayOf<Type>::sanitize (c, this, user_data));
+    return_trace (OffsetArrayOf<Type>::sanitize (c, this, hb_forward<Ts> (ds)...));
   }
 };
 
@@ -684,7 +727,7 @@ struct HeadlessArrayOf
 {
   static constexpr unsigned item_size = Type::static_size;
 
-  HB_NO_CREATE_COPY_ASSIGN_TEMPLATE2 (HeadlessArrayOf, Type, LenType);
+  HB_DELETE_CREATE_COPY_ASSIGN (HeadlessArrayOf);
 
   const Type& operator [] (int i_) const
   {
@@ -699,34 +742,53 @@ struct HeadlessArrayOf
     return arrayZ[i-1];
   }
   unsigned int get_size () const
-  { return lenP1.static_size + (lenP1 ? lenP1 - 1 : 0) * Type::static_size; }
+  { return lenP1.static_size + get_length () * Type::static_size; }
+
+  unsigned get_length () const { return lenP1 ? lenP1 - 1 : 0; }
+
+  hb_array_t<      Type> as_array ()       { return hb_array (arrayZ, get_length ()); }
+  hb_array_t<const Type> as_array () const { return hb_array (arrayZ, get_length ()); }
 
-  bool serialize (hb_serialize_context_t *c,
-                 hb_array_t<const Type> items)
+  /* Iterator. */
+  typedef hb_array_t<const Type>   iter_t;
+  typedef hb_array_t<      Type> writer_t;
+    iter_t   iter () const { return as_array (); }
+  writer_t writer ()       { return as_array (); }
+  operator   iter_t () const { return   iter (); }
+  operator writer_t ()       { return writer (); }
+
+  bool serialize (hb_serialize_context_t *c, unsigned int items_len)
   {
     TRACE_SERIALIZE (this);
     if (unlikely (!c->extend_min (*this))) return_trace (false);
-    lenP1.set (items.length + 1); /* TODO(serialize) Overflow? */
+    c->check_assign (lenP1, items_len + 1);
     if (unlikely (!c->extend (*this))) return_trace (false);
-    for (unsigned int i = 0; i < items.length; i++)
-      arrayZ[i] = items[i];
+    return_trace (true);
+  }
+  template <typename Iterator,
+           hb_requires (hb_is_source_of (Iterator, Type))>
+  bool serialize (hb_serialize_context_t *c, Iterator items)
+  {
+    TRACE_SERIALIZE (this);
+    unsigned count = items.len ();
+    if (unlikely (!serialize (c, count))) return_trace (false);
+    /* TODO Umm. Just exhaust the iterator instead?  Being extra
+     * cautious right now.. */
+    for (unsigned i = 0; i < count; i++, ++items)
+      arrayZ[i] = *items;
     return_trace (true);
   }
 
-  bool sanitize (hb_sanitize_context_t *c) const
+  template <typename ...Ts>
+  bool sanitize (hb_sanitize_context_t *c, Ts&&... ds) const
   {
     TRACE_SANITIZE (this);
     if (unlikely (!sanitize_shallow (c))) return_trace (false);
-
-    /* Note: for structs that do not reference other structs,
-     * we do not need to call their sanitize() as we already did
-     * a bound check on the aggregate array size.  We just include
-     * a small unreachable expression to make sure the structs
-     * pointed to do have a simple sanitize(), ie. they do not
-     * reference other structs via offsets.
-     */
-    (void) (false && arrayZ[0].sanitize (c));
-
+    if (!sizeof... (Ts) && hb_is_trivially_copyable (Type)) return_trace (true);
+    unsigned int count = get_length ();
+    for (unsigned int i = 0; i < count; i++)
+      if (unlikely (!c->dispatch (arrayZ[i], hb_forward<Ts> (ds)...)))
+       return_trace (false);
     return_trace (true);
   }
 
@@ -740,7 +802,7 @@ struct HeadlessArrayOf
 
   public:
   LenType      lenP1;
-  Type         arrayZ[VAR];
+  Type         arrayZ[HB_VAR_ARRAY];
   public:
   DEFINE_SIZE_ARRAY (sizeof (LenType), arrayZ);
 };
@@ -749,7 +811,7 @@ struct HeadlessArrayOf
 template <typename Type, typename LenType=HBUINT16>
 struct ArrayOfM1
 {
-  HB_NO_CREATE_COPY_ASSIGN_TEMPLATE2 (ArrayOfM1, Type, LenType);
+  HB_DELETE_CREATE_COPY_ASSIGN (ArrayOfM1);
 
   const Type& operator [] (int i_) const
   {
@@ -766,14 +828,14 @@ struct ArrayOfM1
   unsigned int get_size () const
   { return lenM1.static_size + (lenM1 + 1) * Type::static_size; }
 
-  template <typename T>
-  bool sanitize (hb_sanitize_context_t *c, const void *base, T user_data) const
+  template <typename ...Ts>
+  bool sanitize (hb_sanitize_context_t *c, Ts&&... ds) const
   {
     TRACE_SANITIZE (this);
     if (unlikely (!sanitize_shallow (c))) return_trace (false);
     unsigned int count = lenM1 + 1;
     for (unsigned int i = 0; i < count; i++)
-      if (unlikely (!arrayZ[i].sanitize (c, base, user_data)))
+      if (unlikely (!c->dispatch (arrayZ[i], hb_forward<Ts> (ds)...)))
        return_trace (false);
     return_trace (true);
   }
@@ -788,7 +850,7 @@ struct ArrayOfM1
 
   public:
   LenType      lenM1;
-  Type         arrayZ[VAR];
+  Type         arrayZ[HB_VAR_ARRAY];
   public:
   DEFINE_SIZE_ARRAY (sizeof (LenType), arrayZ);
 };
@@ -797,21 +859,40 @@ struct ArrayOfM1
 template <typename Type, typename LenType=HBUINT16>
 struct SortedArrayOf : ArrayOf<Type, LenType>
 {
-  hb_sorted_array_t<Type> as_array ()
-  { return hb_sorted_array (this->arrayZ, this->len); }
-  hb_sorted_array_t<const Type> as_array () const
-  { return hb_sorted_array (this->arrayZ, this->len); }
-  operator hb_sorted_array_t<Type> ()             { return as_array (); }
-  operator hb_sorted_array_t<const Type> () const { return as_array (); }
+  hb_sorted_array_t<      Type> as_array ()       { return hb_sorted_array (this->arrayZ, this->len); }
+  hb_sorted_array_t<const Type> as_array () const { return hb_sorted_array (this->arrayZ, this->len); }
+
+  /* Iterator. */
+  typedef hb_sorted_array_t<const Type>   iter_t;
+  typedef hb_sorted_array_t<      Type> writer_t;
+    iter_t   iter () const { return as_array (); }
+  writer_t writer ()       { return as_array (); }
+  operator   iter_t () const { return   iter (); }
+  operator writer_t ()       { return writer (); }
+
+  hb_sorted_array_t<const Type> sub_array (unsigned int start_offset, unsigned int count) const
+  { return as_array ().sub_array (start_offset, count); }
+  hb_sorted_array_t<const Type> sub_array (unsigned int start_offset, unsigned int *count = nullptr /* IN/OUT */) const
+  { return as_array ().sub_array (start_offset, count); }
+  hb_sorted_array_t<Type> sub_array (unsigned int start_offset, unsigned int count)
+  { return as_array ().sub_array (start_offset, count); }
+  hb_sorted_array_t<Type> sub_array (unsigned int start_offset, unsigned int *count = nullptr /* IN/OUT */)
+  { return as_array ().sub_array (start_offset, count); }
 
-  hb_array_t<const Type> sub_array (unsigned int start_offset, unsigned int count) const
-  { return as_array ().sub_array (start_offset, count);}
-  hb_array_t<const Type> sub_array (unsigned int start_offset, unsigned int *count = nullptr /* IN/OUT */) const
-  { return as_array ().sub_array (start_offset, count);}
-  hb_array_t<Type> sub_array (unsigned int start_offset, unsigned int count)
-  { return as_array ().sub_array (start_offset, count);}
-  hb_array_t<Type> sub_array (unsigned int start_offset, unsigned int *count = nullptr /* IN/OUT */)
-  { return as_array ().sub_array (start_offset, count);}
+  bool serialize (hb_serialize_context_t *c, unsigned int items_len)
+  {
+    TRACE_SERIALIZE (this);
+    bool ret = ArrayOf<Type, LenType>::serialize (c, items_len);
+    return_trace (ret);
+  }
+  template <typename Iterator,
+           hb_requires (hb_is_sorted_source_of (Iterator, Type))>
+  bool serialize (hb_serialize_context_t *c, Iterator items)
+  {
+    TRACE_SERIALIZE (this);
+    bool ret = ArrayOf<Type, LenType>::serialize (c, items);
+    return_trace (ret);
+  }
 
   template <typename T>
   Type &bsearch (const T &x, Type &not_found = Crap (Type))
@@ -821,8 +902,8 @@ struct SortedArrayOf : ArrayOf<Type, LenType>
   { return *as_array ().bsearch (x, &not_found); }
   template <typename T>
   bool bfind (const T &x, unsigned int *i = nullptr,
-                    hb_bfind_not_found_t not_found = HB_BFIND_NOT_FOUND_DONT_STORE,
-                    unsigned int to_store = (unsigned int) -1) const
+             hb_bfind_not_found_t not_found = HB_BFIND_NOT_FOUND_DONT_STORE,
+             unsigned int to_store = (unsigned int) -1) const
   { return as_array ().bfind (x, i, not_found, to_store); }
 };
 
@@ -841,15 +922,16 @@ struct BinSearchHeader
     return_trace (c->check_struct (this));
   }
 
-  void set (unsigned int v)
+  BinSearchHeader& operator = (unsigned int v)
   {
-    len.set (v);
+    len = v;
     assert (len == v);
-    entrySelector.set (MAX (1u, hb_bit_storage (v)) - 1);
-    searchRange.set (16 * (1u << entrySelector));
-    rangeShift.set (v * 16 > searchRange
-                   ? 16 * v - searchRange
-                   : 0);
+    entrySelector = hb_max (1u, hb_bit_storage (v)) - 1;
+    searchRange = 16 * (1u << entrySelector);
+    rangeShift = v * 16 > searchRange
+                ? 16 * v - searchRange
+                : 0;
+    return *this;
   }
 
   protected:
@@ -863,7 +945,7 @@ struct BinSearchHeader
 };
 
 template <typename Type, typename LenType=HBUINT16>
-struct BinSearchArrayOf : SortedArrayOf<Type, BinSearchHeader<LenType> > {};
+using BinSearchArrayOf = SortedArrayOf<Type, BinSearchHeader<LenType>>;
 
 
 struct VarSizedBinSearchHeader
@@ -893,7 +975,7 @@ struct VarSizedBinSearchArrayOf
 {
   static constexpr unsigned item_size = Type::static_size;
 
-  HB_NO_CREATE_COPY_ASSIGN_TEMPLATE (VarSizedBinSearchArrayOf, Type);
+  HB_DELETE_CREATE_COPY_ASSIGN (VarSizedBinSearchArrayOf);
 
   bool last_is_terminator () const
   {
@@ -907,7 +989,7 @@ struct VarSizedBinSearchArrayOf
     unsigned int count = Type::TerminationWordCount;
     for (unsigned int i = 0; i < count; i++)
       if (words[i] != 0xFFFFu)
-        return false;
+       return false;
     return true;
   }
 
@@ -928,40 +1010,15 @@ struct VarSizedBinSearchArrayOf
   unsigned int get_size () const
   { return header.static_size + header.nUnits * header.unitSize; }
 
-  bool sanitize (hb_sanitize_context_t *c) const
-  {
-    TRACE_SANITIZE (this);
-    if (unlikely (!sanitize_shallow (c))) return_trace (false);
-
-    /* Note: for structs that do not reference other structs,
-     * we do not need to call their sanitize() as we already did
-     * a bound check on the aggregate array size.  We just include
-     * a small unreachable expression to make sure the structs
-     * pointed to do have a simple sanitize(), ie. they do not
-     * reference other structs via offsets.
-     */
-    (void) (false && StructAtOffset<Type> (&bytesZ, 0).sanitize (c));
-
-    return_trace (true);
-  }
-  bool sanitize (hb_sanitize_context_t *c, const void *base) const
-  {
-    TRACE_SANITIZE (this);
-    if (unlikely (!sanitize_shallow (c))) return_trace (false);
-    unsigned int count = get_length ();
-    for (unsigned int i = 0; i < count; i++)
-      if (unlikely (!(*this)[i].sanitize (c, base)))
-       return_trace (false);
-    return_trace (true);
-  }
-  template <typename T>
-  bool sanitize (hb_sanitize_context_t *c, const void *base, T user_data) const
+  template <typename ...Ts>
+  bool sanitize (hb_sanitize_context_t *c, Ts&&... ds) const
   {
     TRACE_SANITIZE (this);
     if (unlikely (!sanitize_shallow (c))) return_trace (false);
+    if (!sizeof... (Ts) && hb_is_trivially_copyable (Type)) return_trace (true);
     unsigned int count = get_length ();
     for (unsigned int i = 0; i < count; i++)
-      if (unlikely (!(*this)[i].sanitize (c, base, user_data)))
+      if (unlikely (!(*this)[i].sanitize (c, hb_forward<Ts> (ds)...)))
        return_trace (false);
     return_trace (true);
   }
index 61e615c..6735c74 100644 (file)
@@ -27,6 +27,7 @@
 #define HB_OT_CFF_COMMON_HH
 
 #include "hb-open-type.hh"
+#include "hb-bimap.hh"
 #include "hb-ot-layout-common.hh"
 #include "hb-cff-interp-dict-common.hh"
 #include "hb-subset-plan.hh"
@@ -39,14 +40,14 @@ using namespace OT;
 
 /* utility macro */
 template<typename Type>
-static inline const Type& StructAtOffsetOrNull(const void *P, unsigned int offset)
-{ return offset? (* reinterpret_cast<const Type*> ((const char *) P + offset)): Null(Type); }
+static inline const Type& StructAtOffsetOrNull (const void *P, unsigned int offset)
+{ return offset ? StructAtOffset<Type> (P, offset) : Null (Type); }
 
-inline unsigned int calcOffSize(unsigned int dataSize)
+inline unsigned int calcOffSize (unsigned int dataSize)
 {
   unsigned int size = 1;
   unsigned int offset = dataSize + 1;
-  while ((offset & ~0xFF) != 0)
+  while (offset & ~0xFF)
   {
     size++;
     offset >>= 8;
@@ -57,8 +58,8 @@ inline unsigned int calcOffSize(unsigned int dataSize)
 
 struct code_pair_t
 {
-  hb_codepoint_t  code;
-  hb_codepoint_t  glyph;
+  hb_codepoint_t code;
+  hb_codepoint_t glyph;
 };
 
 typedef hb_vector_t<unsigned char> str_buff_t;
@@ -82,27 +83,17 @@ struct str_buff_vec_t : hb_vector_t<str_buff_t>
 template <typename COUNT>
 struct CFFIndex
 {
-  bool sanitize (hb_sanitize_context_t *c) const
-  {
-    TRACE_SANITIZE (this);
-    return_trace (likely ((count.sanitize (c) && count == 0) || /* empty INDEX */
-                         (c->check_struct (this) && offSize >= 1 && offSize <= 4 &&
-                          c->check_array (offsets, offSize, count + 1) &&
-                          c->check_array ((const HBUINT8*)data_base (), 1, max_offset () - 1))));
-  }
-
   static unsigned int calculate_offset_array_size (unsigned int offSize, unsigned int count)
   { return offSize * (count + 1); }
 
   unsigned int offset_array_size () const
   { return calculate_offset_array_size (offSize, count); }
 
-  static unsigned int calculate_serialized_size (unsigned int offSize, unsigned int count, unsigned int dataSize)
+  static unsigned int calculate_serialized_size (unsigned int offSize_, unsigned int count,
+                                                unsigned int dataSize)
   {
-    if (count == 0)
-      return COUNT::static_size;
-    else
-      return min_size + calculate_offset_array_size (offSize, count) + dataSize;
+    if (count == 0) return COUNT::static_size;
+    return min_size + calculate_offset_array_size (offSize_, count) + dataSize;
   }
 
   bool serialize (hb_serialize_context_t *c, const CFFIndex &src)
@@ -124,15 +115,15 @@ struct CFFIndex
     {
       COUNT *dest = c->allocate_min<COUNT> ();
       if (unlikely (dest == nullptr)) return_trace (false);
-      dest->set (0);
+      *dest = 0;
     }
     else
     {
       /* serialize CFFIndex header */
       if (unlikely (!c->extend_min (*this))) return_trace (false);
-      this->count.set (byteArray.length);
-      this->offSize.set (offSize_);
-      if (!unlikely (c->allocate_size<HBUINT8> (offSize_ * (byteArray.length + 1))))
+      this->count = byteArray.length;
+      this->offSize = offSize_;
+      if (unlikely (!c->allocate_size<HBUINT8> (offSize_ * (byteArray.length + 1))))
        return_trace (false);
 
       /* serialize indices */
@@ -166,9 +157,7 @@ struct CFFIndex
     byteArray.init ();
     byteArray.resize (buffArray.length);
     for (unsigned int i = 0; i < byteArray.length; i++)
-    {
-      byteArray[i] = byte_str_t (buffArray[i].arrayZ (), buffArray[i].length);
-    }
+      byteArray[i] = byte_str_t (buffArray[i].arrayZ, buffArray[i].length);
     bool result = this->serialize (c, offSize_, byteArray);
     byteArray.fini ();
     return result;
@@ -181,7 +170,7 @@ struct CFFIndex
     for (; size; size--)
     {
       --p;
-      p->set (offset & 0xFF);
+      *p = offset & 0xFF;
       offset >>= 8;
     }
   }
@@ -199,37 +188,38 @@ struct CFFIndex
 
   unsigned int length_at (unsigned int index) const
   {
-       if (likely ((offset_at (index + 1) >= offset_at (index)) &&
-                   (offset_at (index + 1) <= offset_at (count))))
-         return offset_at (index + 1) - offset_at (index);
-       else
-         return 0;
+    if (unlikely ((offset_at (index + 1) < offset_at (index)) ||
+                 (offset_at (index + 1) > offset_at (count))))
+      return 0;
+    return offset_at (index + 1) - offset_at (index);
   }
 
   const unsigned char *data_base () const
-  { return (const unsigned char *)this + min_size + offset_array_size (); }
+  { return (const unsigned char *) this + min_size + offset_array_size (); }
 
   unsigned int data_size () const { return HBINT8::static_size; }
 
   byte_str_t operator [] (unsigned int index) const
   {
-    if (likely (index < count))
-      return byte_str_t (data_base () + offset_at (index) - 1, length_at (index));
-    else
-      return Null(byte_str_t);
+    if (unlikely (index >= count)) return Null (byte_str_t);
+    return byte_str_t (data_base () + offset_at (index) - 1, length_at (index));
   }
 
   unsigned int get_size () const
   {
-    if (this != &Null(CFFIndex))
-    {
-      if (count > 0)
-       return min_size + offset_array_size () + (offset_at (count) - 1);
-      else
-       return count.static_size;  /* empty CFFIndex contains count only */
-    }
-    else
-      return 0;
+    if (this == &Null (CFFIndex)) return 0;
+    if (count > 0)
+      return min_size + offset_array_size () + (offset_at (count) - 1);
+    return count.static_size;  /* empty CFFIndex contains count only */
+  }
+
+  bool sanitize (hb_sanitize_context_t *c) const
+  {
+    TRACE_SANITIZE (this);
+    return_trace (likely ((c->check_struct (this) && count == 0) || /* empty INDEX */
+                         (c->check_struct (this) && offSize >= 1 && offSize <= 4 &&
+                          c->check_array (offsets, offSize, count + 1) &&
+                          c->check_array ((const HBUINT8*) data_base (), 1, max_offset () - 1))));
   }
 
   protected:
@@ -245,10 +235,10 @@ struct CFFIndex
   }
 
   public:
-  COUNT     count;     /* Number of object data. Note there are (count+1) offsets */
-  HBUINT8   offSize;      /* The byte size of each offset in the offsets array. */
-  HBUINT8   offsets[VAR]; /* The array of (count + 1) offsets into objects array (1-base). */
-  /* HBUINT8 data[VAR];      Object data */
+  COUNT                count;          /* Number of object data. Note there are (count+1) offsets */
+  HBUINT8      offSize;        /* The byte size of each offset in the offsets array. */
+  HBUINT8      offsets[HB_VAR_ARRAY];  /* The array of (count + 1) offsets into objects array (1-base). */
+  /* HBUINT8 data[HB_VAR_ARRAY];       Object data */
   public:
   DEFINE_SIZE_ARRAY (COUNT::static_size + HBUINT8::static_size, offsets);
 };
@@ -275,9 +265,9 @@ struct CFFIndexOf : CFFIndex<COUNT>
     TRACE_SERIALIZE (this);
     /* serialize CFFIndex header */
     if (unlikely (!c->extend_min (*this))) return_trace (false);
-    this->count.set (dataArrayLen);
-    this->offSize.set (offSize_);
-    if (!unlikely (c->allocate_size<HBUINT8> (offSize_ * (dataArrayLen + 1))))
+    this->count = dataArrayLen;
+    this->offSize = offSize_;
+    if (unlikely (!c->allocate_size<HBUINT8> (offSize_ * (dataArrayLen + 1))))
       return_trace (false);
 
     /* serialize indices */
@@ -293,7 +283,7 @@ struct CFFIndexOf : CFFIndex<COUNT>
     /* serialize data */
     for (unsigned int i = 0; i < dataArrayLen; i++)
     {
-      TYPE  *dest = c->start_embed<TYPE> ();
+      TYPE *dest = c->start_embed<TYPE> ();
       if (unlikely (dest == nullptr ||
                    !dest->serialize (c, dataArray[i], param1, param2)))
        return_trace (false);
@@ -310,7 +300,7 @@ struct CFFIndexOf : CFFIndex<COUNT>
                                                 const PARAM &param)
   {
     /* determine offset size */
-    unsigned int  totalDataSize = 0;
+    unsigned int totalDataSize = 0;
     for (unsigned int i = 0; i < dataArrayLen; i++)
     {
       unsigned int dataSize = TYPE::calculate_serialized_size (dataArray[i], param);
@@ -334,10 +324,9 @@ struct Dict : UnsizedByteStr
   {
     TRACE_SERIALIZE (this);
     for (unsigned int i = 0; i < dictval.get_count (); i++)
-    {
       if (unlikely (!opszr.serialize (c, dictval[i], param)))
        return_trace (false);
-    }
+
     return_trace (true);
   }
 
@@ -376,11 +365,11 @@ struct Dict : UnsizedByteStr
     if (unlikely (p == nullptr)) return_trace (false);
     if (Is_OpCode_ESC (op))
     {
-      p->set (OpCode_escape);
+      *p = OpCode_escape;
       op = Unmake_OpCode_ESC (op);
       p++;
     }
-    p->set (op);
+    *p = op;
     return_trace (true);
   }
 
@@ -391,14 +380,10 @@ struct Dict : UnsizedByteStr
   { return serialize_int_op<HBUINT16, 0, 0x7FFF> (c, op, value, OpCode_shortint); }
 
   static bool serialize_offset4_op (hb_serialize_context_t *c, op_code_t op, int value)
-  {
-    return serialize_uint4_op (c, op, value);
-  }
+  { return serialize_uint4_op (c, op, value); }
 
   static bool serialize_offset2_op (hb_serialize_context_t *c, op_code_t op, int value)
-  {
-    return serialize_uint2_op (c, op, value);
-  }
+  { return serialize_uint2_op (c, op, value); }
 };
 
 struct TopDict : Dict {};
@@ -414,57 +399,6 @@ struct table_info_t
   unsigned int    offSize;
 };
 
-/* used to remap font index or SID from fullset to subset.
- * set to CFF_UNDEF_CODE if excluded from subset */
-struct remap_t : hb_vector_t<hb_codepoint_t>
-{
-  void init () { SUPER::init (); }
-
-  void fini () { SUPER::fini (); }
-
-  bool reset (unsigned int size)
-  {
-    if (unlikely (!SUPER::resize (size)))
-      return false;
-    for (unsigned int i = 0; i < length; i++)
-      (*this)[i] = CFF_UNDEF_CODE;
-    count = 0;
-    return true;
-  }
-
-  bool identity (unsigned int size)
-  {
-    if (unlikely (!SUPER::resize (size)))
-      return false;
-    unsigned int i;
-    for (i = 0; i < length; i++)
-      (*this)[i] = i;
-    count = i;
-    return true;
-  }
-
-  bool excludes (hb_codepoint_t id) const
-  { return (id < length) && ((*this)[id] == CFF_UNDEF_CODE); }
-
-  bool includes (hb_codepoint_t id) const
-  { return !excludes (id); }
-
-  unsigned int add (unsigned int i)
-  {
-    if ((*this)[i] == CFF_UNDEF_CODE)
-      (*this)[i] = count++;
-    return (*this)[i];
-  }
-
-  hb_codepoint_t get_count () const { return count; }
-
-  protected:
-  hb_codepoint_t  count;
-
-  private:
-  typedef hb_vector_t<hb_codepoint_t> SUPER;
-};
-
 template <typename COUNT>
 struct FDArray : CFFIndexOf<COUNT, FontDict>
 {
@@ -477,13 +411,13 @@ struct FDArray : CFFIndexOf<COUNT, FontDict>
   {
     TRACE_SERIALIZE (this);
     if (unlikely (!c->extend_min (*this))) return_trace (false);
-    this->count.set (fontDicts.length);
-    this->offSize.set (offSize_);
-    if (!unlikely (c->allocate_size<HBUINT8> (offSize_ * (fontDicts.length + 1))))
+    this->count = fontDicts.length;
+    this->offSize = offSize_;
+    if (unlikely (!c->allocate_size<HBUINT8> (offSize_ * (fontDicts.length + 1))))
       return_trace (false);
 
     /* serialize font dict offsets */
-    unsigned int  offset = 1;
+    unsigned int offset = 1;
     unsigned int fid = 0;
     for (; fid < fontDicts.length; fid++)
     {
@@ -508,22 +442,22 @@ struct FDArray : CFFIndexOf<COUNT, FontDict>
                  unsigned int offSize_,
                  const hb_vector_t<DICTVAL> &fontDicts,
                  unsigned int fdCount,
-                 const remap_t &fdmap,
+                 const hb_inc_bimap_t &fdmap,
                  OP_SERIALIZER& opszr,
                  const hb_vector_t<table_info_t> &privateInfos)
   {
     TRACE_SERIALIZE (this);
     if (unlikely (!c->extend_min (*this))) return_trace (false);
-    this->count.set (fdCount);
-    this->offSize.set (offSize_);
-    if (!unlikely (c->allocate_size<HBUINT8> (offSize_ * (fdCount + 1))))
+    this->count = fdCount;
+    this->offSize = offSize_;
+    if (unlikely (!c->allocate_size<HBUINT8> (offSize_ * (fdCount + 1))))
       return_trace (false);
 
     /* serialize font dict offsets */
     unsigned int  offset = 1;
     unsigned int  fid = 0;
     for (unsigned i = 0; i < fontDicts.length; i++)
-      if (fdmap.includes (i))
+      if (fdmap.has (i))
       {
        if (unlikely (fid >= fdCount)) return_trace (false);
        CFFIndexOf<COUNT, FontDict>::set_offset_at (fid++, offset);
@@ -533,7 +467,7 @@ struct FDArray : CFFIndexOf<COUNT, FontDict>
 
     /* serialize font dicts */
     for (unsigned int i = 0; i < fontDicts.length; i++)
-      if (fdmap.includes (i))
+      if (fdmap.has (i))
       {
        FontDict *dict = c->start_embed<FontDict> ();
        if (unlikely (!dict->serialize (c, fontDicts[i], opszr, privateInfos[fdmap[i]])))
@@ -547,12 +481,12 @@ struct FDArray : CFFIndexOf<COUNT, FontDict>
   static unsigned int calculate_serialized_size (unsigned int &offSize_ /* OUT */,
                                                 const hb_vector_t<DICTVAL> &fontDicts,
                                                 unsigned int fdCount,
-                                                const remap_t &fdmap,
+                                                const hb_inc_bimap_t &fdmap,
                                                 OP_SERIALIZER& opszr)
   {
     unsigned int dictsSize = 0;
     for (unsigned int i = 0; i < fontDicts.len; i++)
-      if (fdmap.includes (i))
+      if (fdmap.has (i))
        dictsSize += FontDict::calculate_serialized_size (fontDicts[i], opszr);
 
     offSize_ = calcOffSize (dictsSize);
@@ -575,21 +509,20 @@ struct FDSelect0 {
   }
 
   hb_codepoint_t get_fd (hb_codepoint_t glyph) const
-  {
-    return (hb_codepoint_t)fds[glyph];
-  }
+  { return (hb_codepoint_t) fds[glyph]; }
 
   unsigned int get_size (unsigned int num_glyphs) const
   { return HBUINT8::static_size * num_glyphs; }
 
-  HBUINT8     fds[VAR];
+  HBUINT8     fds[HB_VAR_ARRAY];
 
-  DEFINE_SIZE_MIN (1);
+  DEFINE_SIZE_MIN (0);
 };
 
 template <typename GID_TYPE, typename FD_TYPE>
-struct FDSelect3_4_Range {
-  bool sanitize (hb_sanitize_context_t *c, const void */*nullptr*/, unsigned int fdcount) const
+struct FDSelect3_4_Range
+{
+  bool sanitize (hb_sanitize_context_t *c, const void * /*nullptr*/, unsigned int fdcount) const
   {
     TRACE_SANITIZE (this);
     return_trace (first < c->get_num_glyphs () && (fd < fdcount));
@@ -597,12 +530,13 @@ struct FDSelect3_4_Range {
 
   GID_TYPE    first;
   FD_TYPE     fd;
-
+  public:
   DEFINE_SIZE_STATIC (GID_TYPE::static_size + FD_TYPE::static_size);
 };
 
 template <typename GID_TYPE, typename FD_TYPE>
-struct FDSelect3_4 {
+struct FDSelect3_4
+{
   unsigned int get_size () const
   { return GID_TYPE::static_size * 2 + ranges.get_size (); }
 
@@ -614,10 +548,8 @@ struct FDSelect3_4 {
       return_trace (false);
 
     for (unsigned int i = 1; i < nRanges (); i++)
-    {
       if (unlikely (ranges[i - 1].first >= ranges[i].first))
-         return_trace (false);
-    }
+       return_trace (false);
 
     if (unlikely (!sentinel().sanitize (c) || (sentinel() != c->get_num_glyphs ())))
       return_trace (false);
@@ -632,13 +564,13 @@ struct FDSelect3_4 {
       if (glyph < ranges[i].first)
        break;
 
-    return (hb_codepoint_t)ranges[i - 1].fd;
+    return (hb_codepoint_t) ranges[i - 1].fd;
   }
 
-  GID_TYPE &nRanges () { return ranges.len; }
-  GID_TYPE nRanges () const { return ranges.len; }
-  GID_TYPE &sentinel ()  { return StructAfter<GID_TYPE> (ranges[nRanges () - 1]); }
-  const GID_TYPE &sentinel () const  { return StructAfter<GID_TYPE> (ranges[nRanges () - 1]); }
+  GID_TYPE        &nRanges ()       { return ranges.len; }
+  GID_TYPE         nRanges () const { return ranges.len; }
+  GID_TYPE       &sentinel ()       { return StructAfter<GID_TYPE> (ranges[nRanges () - 1]); }
+  const GID_TYPE &sentinel () const { return StructAfter<GID_TYPE> (ranges[nRanges () - 1]); }
 
   ArrayOf<FDSelect3_4_Range<GID_TYPE, FD_TYPE>, GID_TYPE> ranges;
   /* GID_TYPE sentinel */
@@ -649,17 +581,8 @@ struct FDSelect3_4 {
 typedef FDSelect3_4<HBUINT16, HBUINT8> FDSelect3;
 typedef FDSelect3_4_Range<HBUINT16, HBUINT8> FDSelect3_Range;
 
-struct FDSelect {
-  bool sanitize (hb_sanitize_context_t *c, unsigned int fdcount) const
-  {
-    TRACE_SANITIZE (this);
-
-    return_trace (likely (c->check_struct (this) && (format == 0 || format == 3) &&
-                         (format == 0)?
-                         u.format0.sanitize (c, fdcount):
-                         u.format3.sanitize (c, fdcount)));
-  }
-
+struct FDSelect
+{
   bool serialize (hb_serialize_context_t *c, const FDSelect &src, unsigned int num_glyphs)
   {
     TRACE_SERIALIZE (this);
@@ -675,30 +598,46 @@ struct FDSelect {
 
   unsigned int get_size (unsigned int num_glyphs) const
   {
-    unsigned int size = format.static_size;
-    if (format == 0)
-      size += u.format0.get_size (num_glyphs);
-    else
-      size += u.format3.get_size ();
-    return size;
+    switch (format)
+    {
+    case 0: return format.static_size + u.format0.get_size (num_glyphs);
+    case 3: return format.static_size + u.format3.get_size ();
+    default:return 0;
+    }
   }
 
   hb_codepoint_t get_fd (hb_codepoint_t glyph) const
   {
-    if (this == &Null(FDSelect))
-      return 0;
-    if (format == 0)
-      return u.format0.get_fd (glyph);
-    else
-      return u.format3.get_fd (glyph);
+    if (this == &Null (FDSelect)) return 0;
+
+    switch (format)
+    {
+    case 0: return u.format0.get_fd (glyph);
+    case 3: return u.format3.get_fd (glyph);
+    default:return 0;
+    }
   }
 
-  HBUINT8       format;
+  bool sanitize (hb_sanitize_context_t *c, unsigned int fdcount) const
+  {
+    TRACE_SANITIZE (this);
+    if (unlikely (!c->check_struct (this)))
+      return_trace (false);
+
+    switch (format)
+    {
+    case 0: return_trace (u.format0.sanitize (c, fdcount));
+    case 3: return_trace (u.format3.sanitize (c, fdcount));
+    default:return_trace (false);
+    }
+  }
+
+  HBUINT8      format;
   union {
-    FDSelect0   format0;
-    FDSelect3   format3;
+  FDSelect0    format0;
+  FDSelect3    format3;
   } u;
-
+  public:
   DEFINE_SIZE_MIN (1);
 };
 
index 8773c05..55abd11 100644 (file)
  * Adobe Author(s): Michiharu Ariza
  */
 
+#include "hb.hh"
+
+#ifndef HB_NO_CFF
+
 #include "hb-ot-cff1-table.hh"
 #include "hb-cff1-interp-cs.hh"
 
@@ -165,8 +169,8 @@ struct bounds_t
 {
   void init ()
   {
-    min.set_int (0x7FFFFFFF, 0x7FFFFFFF);
-    max.set_int (-0x80000000, -0x80000000);
+    min.set_int (INT_MAX, INT_MAX);
+    max.set_int (INT_MIN, INT_MIN);
   }
 
   void update (const point_t &pt)
@@ -199,14 +203,13 @@ struct bounds_t
     }
   }
 
-  bool empty () const
-  { return (min.x >= max.x) || (min.y >= max.y); }
+  bool empty () const { return (min.x >= max.x) || (min.y >= max.y); }
 
   point_t min;
   point_t max;
 };
 
-struct extents_param_t
+struct cff1_extents_param_t
 {
   void init (const OT::cff1::accelerator_t *_cff)
   {
@@ -215,25 +218,25 @@ struct extents_param_t
     bounds.init ();
   }
 
-  void start_path ()         { path_open = true; }
-  void end_path ()           { path_open = false; }
+  void start_path   ()       { path_open = true; }
+  void end_path     ()       { path_open = false; }
   bool is_path_open () const { return path_open; }
 
-  bool    path_open;
-  bounds_t  bounds;
+  bool path_open;
+  bounds_t bounds;
 
   const OT::cff1::accelerator_t *cff;
 };
 
-struct cff1_path_procs_extents_t : path_procs_t<cff1_path_procs_extents_t, cff1_cs_interp_env_t, extents_param_t>
+struct cff1_path_procs_extents_t : path_procs_t<cff1_path_procs_extents_t, cff1_cs_interp_env_t, cff1_extents_param_t>
 {
-  static void moveto (cff1_cs_interp_env_t &env, extents_param_t& param, const point_t &pt)
+  static void moveto (cff1_cs_interp_env_t &env, cff1_extents_param_t& param, const point_t &pt)
   {
     param.end_path ();
     env.moveto (pt);
   }
 
-  static void line (cff1_cs_interp_env_t &env, extents_param_t& param, const point_t &pt1)
+  static void line (cff1_cs_interp_env_t &env, cff1_extents_param_t& param, const point_t &pt1)
   {
     if (!param.is_path_open ())
     {
@@ -244,7 +247,7 @@ struct cff1_path_procs_extents_t : path_procs_t<cff1_path_procs_extents_t, cff1_
     param.bounds.update (env.get_pt ());
   }
 
-  static void curve (cff1_cs_interp_env_t &env, extents_param_t& param, const point_t &pt1, const point_t &pt2, const point_t &pt3)
+  static void curve (cff1_cs_interp_env_t &env, cff1_extents_param_t& param, const point_t &pt1, const point_t &pt2, const point_t &pt3)
   {
     if (!param.is_path_open ())
     {
@@ -261,9 +264,9 @@ struct cff1_path_procs_extents_t : path_procs_t<cff1_path_procs_extents_t, cff1_
 
 static bool _get_bounds (const OT::cff1::accelerator_t *cff, hb_codepoint_t glyph, bounds_t &bounds, bool in_seac=false);
 
-struct cff1_cs_opset_extents_t : cff1_cs_opset_t<cff1_cs_opset_extents_t, extents_param_t, cff1_path_procs_extents_t>
+struct cff1_cs_opset_extents_t : cff1_cs_opset_t<cff1_cs_opset_extents_t, cff1_extents_param_t, cff1_path_procs_extents_t>
 {
-  static void process_seac (cff1_cs_interp_env_t &env, extents_param_t& param)
+  static void process_seac (cff1_cs_interp_env_t &env, cff1_extents_param_t& param)
   {
     unsigned int  n = env.argStack.get_count ();
     point_t delta;
@@ -292,20 +295,25 @@ bool _get_bounds (const OT::cff1::accelerator_t *cff, hb_codepoint_t glyph, boun
   if (unlikely (!cff->is_valid () || (glyph >= cff->num_glyphs))) return false;
 
   unsigned int fd = cff->fdSelect->get_fd (glyph);
-  cff1_cs_interpreter_t<cff1_cs_opset_extents_t, extents_param_t> interp;
+  cff1_cs_interpreter_t<cff1_cs_opset_extents_t, cff1_extents_param_t> interp;
   const byte_str_t str = (*cff->charStrings)[glyph];
   interp.env.init (str, *cff, fd);
   interp.env.set_in_seac (in_seac);
-  extents_param_t  param;
+  cff1_extents_param_t  param;
   param.init (cff);
   if (unlikely (!interp.interpret (param))) return false;
   bounds = param.bounds;
   return true;
 }
 
-bool OT::cff1::accelerator_t::get_extents (hb_codepoint_t glyph, hb_glyph_extents_t *extents) const
+bool OT::cff1::accelerator_t::get_extents (hb_font_t *font, hb_codepoint_t glyph, hb_glyph_extents_t *extents) const
 {
-  bounds_t  bounds;
+#ifdef HB_NO_OT_FONT_CFF
+  /* XXX Remove check when this code moves to .hh file. */
+  return true;
+#endif
+
+  bounds_t bounds;
 
   if (!_get_bounds (this, glyph, bounds))
     return false;
@@ -317,8 +325,8 @@ bool OT::cff1::accelerator_t::get_extents (hb_codepoint_t glyph, hb_glyph_extent
   }
   else
   {
-    extents->x_bearing = (int32_t)bounds.min.x.floor ();
-    extents->width = (int32_t)bounds.max.x.ceil () - extents->x_bearing;
+    extents->x_bearing = font->em_scalef_x (bounds.min.x.to_real ());
+    extents->width = font->em_scalef_x (bounds.max.x.to_real () - bounds.min.x.to_real ());
   }
   if (bounds.min.y >= bounds.max.y)
   {
@@ -327,8 +335,8 @@ bool OT::cff1::accelerator_t::get_extents (hb_codepoint_t glyph, hb_glyph_extent
   }
   else
   {
-    extents->y_bearing = (int32_t)bounds.max.y.ceil ();
-    extents->height = (int32_t)bounds.min.y.floor () - extents->y_bearing;
+    extents->y_bearing = font->em_scalef_y (bounds.max.y.to_real ());
+    extents->height = font->em_scalef_y (bounds.min.y.to_real () - bounds.max.y.to_real ());
   }
 
   return true;
@@ -383,3 +391,6 @@ bool OT::cff1::accelerator_t::get_seac_components (hb_codepoint_t glyph, hb_code
   }
   return false;
 }
+
+
+#endif
index 9d39242..ad20651 100644 (file)
@@ -110,7 +110,8 @@ struct Encoding1 {
     {
       if (glyph <= ranges[i].nLeft)
       {
-       return (hb_codepoint_t)ranges[i].first + glyph;
+       hb_codepoint_t code = (hb_codepoint_t) ranges[i].first + glyph;
+       return (likely (code < 0x100) ? code: CFF_UNDEF_CODE);
       }
       glyph -= (ranges[i].nLeft + 1);
     }
@@ -160,21 +161,8 @@ struct CFF1SuppEncData {
   DEFINE_SIZE_ARRAY_SIZED (1, supps);
 };
 
-struct Encoding {
-  bool sanitize (hb_sanitize_context_t *c) const
-  {
-    TRACE_SANITIZE (this);
-
-    if (unlikely (!c->check_struct (this)))
-      return_trace (false);
-    unsigned int fmt = format & 0x7F;
-    if (unlikely (fmt > 1))
-      return_trace (false);
-    if (unlikely (!((fmt == 0)? u.format0.sanitize (c): u.format1.sanitize (c))))
-      return_trace (false);
-    return_trace (((format & 0x80) == 0) || suppEncData ().sanitize (c));
-  }
-
+struct Encoding
+{
   /* serialize a fullset Encoding */
   bool serialize (hb_serialize_context_t *c, const Encoding &src)
   {
@@ -196,46 +184,54 @@ struct Encoding {
     TRACE_SERIALIZE (this);
     Encoding *dest = c->extend_min (*this);
     if (unlikely (dest == nullptr)) return_trace (false);
-    dest->format.set (format | ((supp_codes.length > 0)? 0x80: 0));
-    if (format == 0)
+    dest->format = format | ((supp_codes.length > 0) ? 0x80 : 0);
+    switch (format) {
+    case 0:
     {
       Encoding0 *fmt0 = c->allocate_size<Encoding0> (Encoding0::min_size + HBUINT8::static_size * enc_count);
-    if (unlikely (fmt0 == nullptr)) return_trace (false);
-      fmt0->nCodes ().set (enc_count);
+      if (unlikely (fmt0 == nullptr)) return_trace (false);
+      fmt0->nCodes () = enc_count;
       unsigned int glyph = 0;
       for (unsigned int i = 0; i < code_ranges.length; i++)
       {
        hb_codepoint_t code = code_ranges[i].code;
        for (int left = (int)code_ranges[i].glyph; left >= 0; left--)
-         fmt0->codes[glyph++].set (code++);
+         fmt0->codes[glyph++] = code++;
        if (unlikely (!((glyph <= 0x100) && (code <= 0x100))))
          return_trace (false);
       }
     }
-    else
+    break;
+
+    case 1:
     {
       Encoding1 *fmt1 = c->allocate_size<Encoding1> (Encoding1::min_size + Encoding1_Range::static_size * code_ranges.length);
       if (unlikely (fmt1 == nullptr)) return_trace (false);
-      fmt1->nRanges ().set (code_ranges.length);
+      fmt1->nRanges () = code_ranges.length;
       for (unsigned int i = 0; i < code_ranges.length; i++)
       {
        if (unlikely (!((code_ranges[i].code <= 0xFF) && (code_ranges[i].glyph <= 0xFF))))
          return_trace (false);
-       fmt1->ranges[i].first.set (code_ranges[i].code);
-       fmt1->ranges[i].nLeft.set (code_ranges[i].glyph);
+       fmt1->ranges[i].first = code_ranges[i].code;
+       fmt1->ranges[i].nLeft = code_ranges[i].glyph;
       }
     }
-    if (supp_codes.length > 0)
+    break;
+
+    }
+
+    if (supp_codes.length)
     {
       CFF1SuppEncData *suppData = c->allocate_size<CFF1SuppEncData> (CFF1SuppEncData::min_size + SuppEncoding::static_size * supp_codes.length);
       if (unlikely (suppData == nullptr)) return_trace (false);
-      suppData->nSups ().set (supp_codes.length);
+      suppData->nSups () = supp_codes.length;
       for (unsigned int i = 0; i < supp_codes.length; i++)
       {
-       suppData->supps[i].code.set (supp_codes[i].code);
-       suppData->supps[i].glyph.set (supp_codes[i].glyph); /* actually SID */
+       suppData->supps[i].code = supp_codes[i].code;
+       suppData->supps[i].glyph = supp_codes[i].glyph; /* actually SID */
       }
     }
+
     return_trace (true);
   }
 
@@ -244,11 +240,13 @@ struct Encoding {
                                                 unsigned int enc_count,
                                                 unsigned int supp_count)
   {
-    unsigned int  size = min_size;
-    if (format == 0)
-      size += Encoding0::min_size + HBUINT8::static_size * enc_count;
-    else
-      size += Encoding1::min_size + Encoding1_Range::static_size * enc_count;
+    unsigned int size = min_size;
+    switch (format)
+    {
+    case 0: size += Encoding0::min_size + HBUINT8::static_size * enc_count; break;
+    case 1: size += Encoding1::min_size + Encoding1_Range::static_size * enc_count; break;
+    default:return 0;
+    }
     if (supp_count > 0)
       size += CFF1SuppEncData::min_size + SuppEncoding::static_size * supp_count;
     return size;
@@ -257,10 +255,11 @@ struct Encoding {
   unsigned int get_size () const
   {
     unsigned int size = min_size;
-    if (table_format () == 0)
-      size += u.format0.get_size ();
-    else
-      size += u.format1.get_size ();
+    switch (table_format ())
+    {
+    case 0: size += u.format0.get_size (); break;
+    case 1: size += u.format1.get_size (); break;
+    }
     if (has_supplement ())
       size += suppEncData ().get_size ();
     return size;
@@ -268,14 +267,16 @@ struct Encoding {
 
   hb_codepoint_t get_code (hb_codepoint_t glyph) const
   {
-    if (table_format () == 0)
-      return u.format0.get_code (glyph);
-    else
-      return u.format1.get_code (glyph);
+    switch (table_format ())
+    {
+    case 0: return u.format0.get_code (glyph);
+    case 1: return u.format1.get_code (glyph);
+    default:return 0;
+    }
   }
 
-  uint8_t table_format () const { return (format & 0x7F); }
-  bool  has_supplement () const { return (format & 0x80) != 0; }
+  uint8_t table_format () const { return format & 0x7F; }
+  bool  has_supplement () const { return format & 0x80; }
 
   void get_supplement_codes (hb_codepoint_t sid, hb_vector_t<hb_codepoint_t> &codes) const
   {
@@ -284,21 +285,37 @@ struct Encoding {
       suppEncData().get_codes (sid, codes);
   }
 
+  bool sanitize (hb_sanitize_context_t *c) const
+  {
+    TRACE_SANITIZE (this);
+    if (unlikely (!c->check_struct (this)))
+      return_trace (false);
+
+    switch (table_format ())
+    {
+    case 0: if (unlikely (!u.format0.sanitize (c))) { return_trace (false); } break;
+    case 1: if (unlikely (!u.format1.sanitize (c))) { return_trace (false); } break;
+    default:return_trace (false);
+    }
+    return_trace (likely (!has_supplement () || suppEncData ().sanitize (c)));
+  }
+
   protected:
   const CFF1SuppEncData &suppEncData () const
   {
-    if ((format & 0x7F) == 0)
-      return StructAfter<CFF1SuppEncData> (u.format0.codes[u.format0.nCodes ()-1]);
-    else
-      return StructAfter<CFF1SuppEncData> (u.format1.ranges[u.format1.nRanges ()-1]);
+    switch (table_format ())
+    {
+    case 0: return StructAfter<CFF1SuppEncData> (u.format0.codes[u.format0.nCodes ()-1]);
+    case 1: return StructAfter<CFF1SuppEncData> (u.format1.ranges[u.format1.nRanges ()-1]);
+    default:return Null (CFF1SuppEncData);
+    }
   }
 
   public:
-  HBUINT8       format;
-
+  HBUINT8      format;
   union {
-    Encoding0   format0;
-    Encoding1   format1;
+  Encoding0    format0;
+  Encoding1    format1;
   } u;
   /* CFF1SuppEncData  suppEncData; */
 
@@ -340,7 +357,7 @@ struct Charset0 {
     return HBUINT16::static_size * (num_glyphs - 1);
   }
 
-  HBUINT16  sids[VAR];
+  HBUINT16  sids[HB_VAR_ARRAY];
 
   DEFINE_SIZE_ARRAY(0, sids);
 };
@@ -422,7 +439,7 @@ struct Charset1_2 {
     return size;
   }
 
-  Charset_Range<TYPE>   ranges[VAR];
+  Charset_Range<TYPE>   ranges[HB_VAR_ARRAY];
 
   DEFINE_SIZE_ARRAY (0, ranges);
 };
@@ -432,23 +449,8 @@ typedef Charset1_2<HBUINT16>    Charset2;
 typedef Charset_Range<HBUINT8>  Charset1_Range;
 typedef Charset_Range<HBUINT16> Charset2_Range;
 
-struct Charset {
-  bool sanitize (hb_sanitize_context_t *c) const
-  {
-    TRACE_SANITIZE (this);
-
-    if (unlikely (!c->check_struct (this)))
-      return_trace (false);
-    if (format == 0)
-      return_trace (u.format0.sanitize (c, c->get_num_glyphs ()));
-    else if (format == 1)
-      return_trace (u.format1.sanitize (c, c->get_num_glyphs ()));
-    else if (likely (format == 2))
-      return_trace (u.format2.sanitize (c, c->get_num_glyphs ()));
-    else
-      return_trace (false);
-  }
-
+struct Charset
+{
   /* serialize a fullset Charset */
   bool serialize (hb_serialize_context_t *c, const Charset &src, unsigned int num_glyphs)
   {
@@ -469,20 +471,24 @@ struct Charset {
     TRACE_SERIALIZE (this);
     Charset *dest = c->extend_min (*this);
     if (unlikely (dest == nullptr)) return_trace (false);
-    dest->format.set (format);
-    if (format == 0)
+    dest->format = format;
+    switch (format)
+    {
+    case 0:
     {
       Charset0 *fmt0 = c->allocate_size<Charset0> (Charset0::min_size + HBUINT16::static_size * (num_glyphs - 1));
-    if (unlikely (fmt0 == nullptr)) return_trace (false);
+      if (unlikely (fmt0 == nullptr)) return_trace (false);
       unsigned int glyph = 0;
       for (unsigned int i = 0; i < sid_ranges.length; i++)
       {
        hb_codepoint_t sid = sid_ranges[i].code;
        for (int left = (int)sid_ranges[i].glyph; left >= 0; left--)
-         fmt0->sids[glyph++].set (sid++);
+         fmt0->sids[glyph++] = sid++;
       }
     }
-    else if (format == 1)
+    break;
+
+    case 1:
     {
       Charset1 *fmt1 = c->allocate_size<Charset1> (Charset1::min_size + Charset1_Range::static_size * sid_ranges.length);
       if (unlikely (fmt1 == nullptr)) return_trace (false);
@@ -490,11 +496,13 @@ struct Charset {
       {
        if (unlikely (!(sid_ranges[i].glyph <= 0xFF)))
          return_trace (false);
-       fmt1->ranges[i].first.set (sid_ranges[i].code);
-       fmt1->ranges[i].nLeft.set (sid_ranges[i].glyph);
+       fmt1->ranges[i].first = sid_ranges[i].code;
+       fmt1->ranges[i].nLeft = sid_ranges[i].glyph;
       }
     }
-    else /* format 2 */
+    break;
+
+    case 2:
     {
       Charset2 *fmt2 = c->allocate_size<Charset2> (Charset2::min_size + Charset2_Range::static_size * sid_ranges.length);
       if (unlikely (fmt2 == nullptr)) return_trace (false);
@@ -502,59 +510,75 @@ struct Charset {
       {
        if (unlikely (!(sid_ranges[i].glyph <= 0xFFFF)))
          return_trace (false);
-       fmt2->ranges[i].first.set (sid_ranges[i].code);
-       fmt2->ranges[i].nLeft.set (sid_ranges[i].glyph);
+       fmt2->ranges[i].first = sid_ranges[i].code;
+       fmt2->ranges[i].nLeft = sid_ranges[i].glyph;
       }
     }
+    break;
+
+    }
     return_trace (true);
   }
 
   /* parallel to above: calculate the size of a subset Charset */
-  static unsigned int calculate_serialized_size (
-                       uint8_t format,
-                       unsigned int count)
+  static unsigned int calculate_serialized_size (uint8_t format,
+                                                unsigned int count)
   {
-    unsigned int  size = min_size;
-    if (format == 0)
-      size += Charset0::min_size + HBUINT16::static_size * (count - 1);
-    else if (format == 1)
-      size += Charset1::min_size + Charset1_Range::static_size * count;
-    else
-      size += Charset2::min_size + Charset2_Range::static_size * count;
-
-    return size;
+    switch (format)
+    {
+    case 0: return min_size + Charset0::min_size + HBUINT16::static_size * (count - 1);
+    case 1: return min_size + Charset1::min_size + Charset1_Range::static_size * count;
+    case 2: return min_size + Charset2::min_size + Charset2_Range::static_size * count;
+    default:return 0;
+    }
   }
 
   unsigned int get_size (unsigned int num_glyphs) const
   {
-    unsigned int size = min_size;
-    if (format == 0)
-      size += u.format0.get_size (num_glyphs);
-    else if (format == 1)
-      size += u.format1.get_size (num_glyphs);
-    else
-      size += u.format2.get_size (num_glyphs);
-    return size;
+    switch (format)
+    {
+    case 0: return min_size + u.format0.get_size (num_glyphs);
+    case 1: return min_size + u.format1.get_size (num_glyphs);
+    case 2: return min_size + u.format2.get_size (num_glyphs);
+    default:return 0;
+    }
   }
 
   hb_codepoint_t get_sid (hb_codepoint_t glyph) const
   {
-    if (format == 0)
-      return u.format0.get_sid (glyph);
-    else if (format == 1)
-      return u.format1.get_sid (glyph);
-    else
-      return u.format2.get_sid (glyph);
+    switch (format)
+    {
+    case 0: return u.format0.get_sid (glyph);
+    case 1: return u.format1.get_sid (glyph);
+    case 2: return u.format2.get_sid (glyph);
+    default:return 0;
+    }
   }
 
   hb_codepoint_t get_glyph (hb_codepoint_t sid, unsigned int num_glyphs) const
   {
-    if (format == 0)
-      return u.format0.get_glyph (sid, num_glyphs);
-    else if (format == 1)
-      return u.format1.get_glyph (sid, num_glyphs);
-    else
-      return u.format2.get_glyph (sid, num_glyphs);
+    switch (format)
+    {
+    case 0: return u.format0.get_glyph (sid, num_glyphs);
+    case 1: return u.format1.get_glyph (sid, num_glyphs);
+    case 2: return u.format2.get_glyph (sid, num_glyphs);
+    default:return 0;
+    }
+  }
+
+  bool sanitize (hb_sanitize_context_t *c) const
+  {
+    TRACE_SANITIZE (this);
+    if (unlikely (!c->check_struct (this)))
+      return_trace (false);
+
+    switch (format)
+    {
+    case 0: return_trace (u.format0.sanitize (c, c->get_num_glyphs ()));
+    case 1: return_trace (u.format1.sanitize (c, c->get_num_glyphs ()));
+    case 2: return_trace (u.format2.sanitize (c, c->get_num_glyphs ()));
+    default:return_trace (false);
+    }
   }
 
   HBUINT8       format;
@@ -570,20 +594,20 @@ struct Charset {
 struct CFF1StringIndex : CFF1Index
 {
   bool serialize (hb_serialize_context_t *c, const CFF1StringIndex &strings,
-                 unsigned int offSize_, const remap_t &sidmap)
+                 unsigned int offSize_, const hb_inc_bimap_t &sidmap)
   {
     TRACE_SERIALIZE (this);
-    if (unlikely ((strings.count == 0) || (sidmap.get_count () == 0)))
+    if (unlikely ((strings.count == 0) || (sidmap.get_population () == 0)))
     {
-      if (!unlikely (c->extend_min (this->count)))
+      if (unlikely (!c->extend_min (this->count)))
        return_trace (false);
-      count.set (0);
+      count = 0;
       return_trace (true);
     }
 
     byte_str_array_t bytesArray;
     bytesArray.init ();
-    if (!bytesArray.resize (sidmap.get_count ()))
+    if (!bytesArray.resize (sidmap.get_population ()))
       return_trace (false);
     for (unsigned int i = 0; i < strings.count; i++)
     {
@@ -598,10 +622,10 @@ struct CFF1StringIndex : CFF1Index
   }
 
   /* in parallel to above */
-  unsigned int calculate_serialized_size (unsigned int &offSize /*OUT*/, const remap_t &sidmap) const
+  unsigned int calculate_serialized_size (unsigned int &offSize_ /*OUT*/, const hb_inc_bimap_t &sidmap) const
   {
-    offSize = 0;
-    if ((count == 0) || (sidmap.get_count () == 0))
+    offSize_ = 0;
+    if ((count == 0) || (sidmap.get_population () == 0))
       return count.static_size;
 
     unsigned int dataSize = 0;
@@ -609,8 +633,8 @@ struct CFF1StringIndex : CFF1Index
       if (sidmap[i] != CFF_UNDEF_CODE)
        dataSize += length_at (i);
 
-    offSize = calcOffSize(dataSize);
-    return CFF1Index::calculate_serialized_size (offSize, sidmap.get_count (), dataSize);
+    offSize_ = calcOffSize(dataSize);
+    return CFF1Index::calculate_serialized_size (offSize_, sidmap.get_population (), dataSize);
   }
 };
 
@@ -1131,7 +1155,7 @@ struct cff1
     }
 
     bool is_valid () const { return blob != nullptr; }
-    bool is_CID () const { return topDict.is_CID (); }
+    bool   is_CID () const { return topDict.is_CID (); }
 
     bool is_predef_charset () const { return topDict.CharsetOffset <= ExpertSubsetCharset; }
 
@@ -1172,7 +1196,7 @@ struct cff1
 
   struct accelerator_t : accelerator_templ_t<cff1_private_dict_opset_t, cff1_private_dict_values_t>
   {
-    HB_INTERNAL bool get_extents (hb_codepoint_t glyph, hb_glyph_extents_t *extents) const;
+    HB_INTERNAL bool get_extents (hb_font_t *font, hb_codepoint_t glyph, hb_glyph_extents_t *extents) const;
     HB_INTERNAL bool get_seac_components (hb_codepoint_t glyph, hb_codepoint_t *base, hb_codepoint_t *accent) const;
   };
 
@@ -1201,25 +1225,25 @@ struct cff1
 
     bool is_predef_encoding () const { return topDict.EncodingOffset <= ExpertEncoding; }
 
-    hb_codepoint_t  glyph_to_code (hb_codepoint_t glyph) const
+    hb_codepoint_t glyph_to_code (hb_codepoint_t glyph) const
     {
       if (encoding != &Null(Encoding))
        return encoding->get_code (glyph);
       else
       {
-       hb_codepoint_t  sid = glyph_to_sid (glyph);
+       hb_codepoint_t sid = glyph_to_sid (glyph);
        if (sid == 0) return 0;
-       hb_codepoint_t  code = 0;
+       hb_codepoint_t code = 0;
        switch (topDict.EncodingOffset)
        {
-         case  StandardEncoding:
-           code = lookup_standard_encoding_for_code (sid);
-           break;
-         case  ExpertEncoding:
-           code = lookup_expert_encoding_for_code (sid);
-           break;
-         default:
-           break;
+       case StandardEncoding:
+         code = lookup_standard_encoding_for_code (sid);
+         break;
+       case ExpertEncoding:
+         code = lookup_expert_encoding_for_code (sid);
+         break;
+       default:
+         break;
        }
        return code;
       }
index 7daa536..a2242b7 100644 (file)
  * Adobe Author(s): Michiharu Ariza
  */
 
+#include "hb.hh"
+
+#ifndef HB_NO_OT_FONT_CFF
+
 #include "hb-ot-cff2-table.hh"
 #include "hb-cff2-interp-cs.hh"
 
 using namespace CFF;
 
-struct extents_param_t
+struct cff2_extents_param_t
 {
   void init ()
   {
     path_open = false;
-    min_x.set_int (0x7FFFFFFF);
-    min_y.set_int (0x7FFFFFFF);
-    max_x.set_int (-0x80000000);
-    max_y.set_int (-0x80000000);
+    min_x.set_int (INT_MAX);
+    min_y.set_int (INT_MAX);
+    max_x.set_int (INT_MIN);
+    max_y.set_int (INT_MIN);
   }
 
-  void start_path ()         { path_open = true; }
-  void end_path ()           { path_open = false; }
+  void   start_path ()       { path_open = true; }
+  void     end_path ()       { path_open = false; }
   bool is_path_open () const { return path_open; }
 
   void update_bounds (const point_t &pt)
@@ -59,15 +63,15 @@ struct extents_param_t
   number_t max_y;
 };
 
-struct cff2_path_procs_extents_t : path_procs_t<cff2_path_procs_extents_t, cff2_cs_interp_env_t, extents_param_t>
+struct cff2_path_procs_extents_t : path_procs_t<cff2_path_procs_extents_t, cff2_cs_interp_env_t, cff2_extents_param_t>
 {
-  static void moveto (cff2_cs_interp_env_t &env, extents_param_t& param, const point_t &pt)
+  static void moveto (cff2_cs_interp_env_t &env, cff2_extents_param_t& param, const point_t &pt)
   {
     param.end_path ();
     env.moveto (pt);
   }
 
-  static void line (cff2_cs_interp_env_t &env, extents_param_t& param, const point_t &pt1)
+  static void line (cff2_cs_interp_env_t &env, cff2_extents_param_t& param, const point_t &pt1)
   {
     if (!param.is_path_open ())
     {
@@ -78,7 +82,7 @@ struct cff2_path_procs_extents_t : path_procs_t<cff2_path_procs_extents_t, cff2_
     param.update_bounds (env.get_pt ());
   }
 
-  static void curve (cff2_cs_interp_env_t &env, extents_param_t& param, const point_t &pt1, const point_t &pt2, const point_t &pt3)
+  static void curve (cff2_cs_interp_env_t &env, cff2_extents_param_t& param, const point_t &pt1, const point_t &pt2, const point_t &pt3)
   {
     if (!param.is_path_open ())
     {
@@ -93,21 +97,24 @@ struct cff2_path_procs_extents_t : path_procs_t<cff2_path_procs_extents_t, cff2_
   }
 };
 
-struct cff2_cs_opset_extents_t : cff2_cs_opset_t<cff2_cs_opset_extents_t, extents_param_t, cff2_path_procs_extents_t> {};
+struct cff2_cs_opset_extents_t : cff2_cs_opset_t<cff2_cs_opset_extents_t, cff2_extents_param_t, cff2_path_procs_extents_t> {};
 
 bool OT::cff2::accelerator_t::get_extents (hb_font_t *font,
                                           hb_codepoint_t glyph,
                                           hb_glyph_extents_t *extents) const
 {
+#ifdef HB_NO_OT_FONT_CFF
+  /* XXX Remove check when this code moves to .hh file. */
+  return true;
+#endif
+
   if (unlikely (!is_valid () || (glyph >= num_glyphs))) return false;
 
-  unsigned int num_coords;
-  const int *coords = hb_font_get_var_coords_normalized (font, &num_coords);
   unsigned int fd = fdSelect->get_fd (glyph);
-  cff2_cs_interpreter_t<cff2_cs_opset_extents_t, extents_param_t> interp;
+  cff2_cs_interpreter_t<cff2_cs_opset_extents_t, cff2_extents_param_t> interp;
   const byte_str_t str = (*charStrings)[glyph];
-  interp.env.init (str, *this, fd, coords, num_coords);
-  extents_param_t  param;
+  interp.env.init (str, *this, fd, font->coords, font->num_coords);
+  cff2_extents_param_t  param;
   param.init ();
   if (unlikely (!interp.interpret (param))) return false;
 
@@ -118,8 +125,8 @@ bool OT::cff2::accelerator_t::get_extents (hb_font_t *font,
   }
   else
   {
-    extents->x_bearing = (int32_t)param.min_x.floor ();
-    extents->width = (int32_t)param.max_x.ceil () - extents->x_bearing;
+    extents->x_bearing = font->em_scalef_x (param.min_x.to_real ());
+    extents->width = font->em_scalef_x (param.max_x.to_real () - param.min_x.to_real ());
   }
   if (param.min_y >= param.max_y)
   {
@@ -128,9 +135,12 @@ bool OT::cff2::accelerator_t::get_extents (hb_font_t *font,
   }
   else
   {
-    extents->y_bearing = (int32_t)param.max_y.ceil ();
-    extents->height = (int32_t)param.min_y.floor () - extents->y_bearing;
+    extents->y_bearing = font->em_scalef_y (param.max_y.to_real ());
+    extents->height = font->em_scalef_y (param.min_y.to_real () - param.max_y.to_real ());
   }
 
   return true;
 }
+
+
+#endif
index a7b0ba9..8646cde 100644 (file)
@@ -51,18 +51,6 @@ typedef FDSelect3_4_Range<HBUINT32, HBUINT16> FDSelect4_Range;
 
 struct CFF2FDSelect
 {
-  bool sanitize (hb_sanitize_context_t *c, unsigned int fdcount) const
-  {
-    TRACE_SANITIZE (this);
-
-    return_trace (likely (c->check_struct (this) && (format == 0 || format == 3 || format == 4) &&
-                         (format == 0)?
-                         u.format0.sanitize (c, fdcount):
-                           ((format == 3)?
-                           u.format3.sanitize (c, fdcount):
-                           u.format4.sanitize (c, fdcount))));
-  }
-
   bool serialize (hb_serialize_context_t *c, const CFF2FDSelect &src, unsigned int num_glyphs)
   {
     TRACE_SERIALIZE (this);
@@ -78,35 +66,51 @@ struct CFF2FDSelect
 
   unsigned int get_size (unsigned int num_glyphs) const
   {
-    unsigned int size = format.static_size;
-    if (format == 0)
-      size += u.format0.get_size (num_glyphs);
-    else if (format == 3)
-      size += u.format3.get_size ();
-    else
-      size += u.format4.get_size ();
-    return size;
+    switch (format)
+    {
+    case 0: return format.static_size + u.format0.get_size (num_glyphs);
+    case 3: return format.static_size + u.format3.get_size ();
+    case 4: return format.static_size + u.format4.get_size ();
+    default:return 0;
+    }
   }
 
   hb_codepoint_t get_fd (hb_codepoint_t glyph) const
   {
-    if (this == &Null(CFF2FDSelect))
+    if (this == &Null (CFF2FDSelect))
       return 0;
-    if (format == 0)
-      return u.format0.get_fd (glyph);
-    else if (format == 3)
-      return u.format3.get_fd (glyph);
-    else
-      return u.format4.get_fd (glyph);
+
+    switch (format)
+    {
+    case 0: return u.format0.get_fd (glyph);
+    case 3: return u.format3.get_fd (glyph);
+    case 4: return u.format4.get_fd (glyph);
+    default:return 0;
+    }
   }
 
-  HBUINT8       format;
+  bool sanitize (hb_sanitize_context_t *c, unsigned int fdcount) const
+  {
+    TRACE_SANITIZE (this);
+    if (unlikely (!c->check_struct (this)))
+      return_trace (false);
+
+    switch (format)
+    {
+    case 0: return_trace (u.format0.sanitize (c, fdcount));
+    case 3: return_trace (u.format3.sanitize (c, fdcount));
+    case 4: return_trace (u.format4.sanitize (c, fdcount));
+    default:return_trace (false);
+    }
+  }
+
+  HBUINT8      format;
   union {
-    FDSelect0   format0;
-    FDSelect3   format3;
-    FDSelect4   format4;
+  FDSelect0    format0;
+  FDSelect3    format3;
+  FDSelect4    format4;
   } u;
-
+  public:
   DEFINE_SIZE_MIN (2);
 };
 
index 0526c35..9ebd8e4 100644 (file)
@@ -74,154 +74,201 @@ struct CmapSubtableFormat0
 
 struct CmapSubtableFormat4
 {
-  struct segment_plan
-  {
-    HBUINT16 start_code;
-    HBUINT16 end_code;
-    bool use_delta;
-  };
 
-  bool serialize (hb_serialize_context_t *c,
-                 const hb_subset_plan_t *plan,
-                 const hb_vector_t<segment_plan> &segments)
+  template<typename Iterator,
+          hb_requires (hb_is_iterator (Iterator))>
+  HBUINT16* serialize_endcode_array (hb_serialize_context_t *c,
+                                    Iterator it)
   {
-    TRACE_SERIALIZE (this);
-
-    if (unlikely (!c->extend_min (*this))) return_trace (false);
-
-    this->format.set (4);
-    this->length.set (get_sub_table_size (segments));
-
-    this->segCountX2.set (segments.length * 2);
-    this->entrySelector.set (MAX (1u, hb_bit_storage (segments.length)) - 1);
-    this->searchRange.set (2 * (1u << this->entrySelector));
-    this->rangeShift.set (segments.length * 2 > this->searchRange
-                         ? 2 * segments.length - this->searchRange
-                         : 0);
-
-    HBUINT16 *end_count = c->allocate_size<HBUINT16> (HBUINT16::static_size * segments.length);
-    c->allocate_size<HBUINT16> (HBUINT16::static_size); // 2 bytes of padding.
-    HBUINT16 *start_count = c->allocate_size<HBUINT16> (HBUINT16::static_size * segments.length);
-    HBINT16 *id_delta = c->allocate_size<HBINT16> (HBUINT16::static_size * segments.length);
-    HBUINT16 *id_range_offset = c->allocate_size<HBUINT16> (HBUINT16::static_size * segments.length);
+    HBUINT16 *endCode = c->start_embed<HBUINT16> ();
+    hb_codepoint_t prev_endcp = 0xFFFF;
+
+    + it
+    | hb_apply ([&] (const hb_item_type<Iterator> _)
+               {
+                 if (prev_endcp != 0xFFFF && prev_endcp + 1u != _.first)
+                 {
+                   HBUINT16 end_code;
+                   end_code = prev_endcp;
+                   c->copy<HBUINT16> (end_code);
+                 }
+                 prev_endcp = _.first;
+               })
+    ;
 
-    if (id_range_offset == nullptr)
-      return_trace (false);
-
-    for (unsigned int i = 0; i < segments.length; i++)
     {
-      end_count[i].set (segments[i].end_code);
-      start_count[i].set (segments[i].start_code);
-      if (segments[i].use_delta)
+      // last endCode
+      HBUINT16 endcode;
+      endcode = prev_endcp;
+      if (unlikely (!c->copy<HBUINT16> (endcode))) return nullptr;
+      // There must be a final entry with end_code == 0xFFFF.
+      if (prev_endcp != 0xFFFF)
       {
-       hb_codepoint_t cp = segments[i].start_code;
-       hb_codepoint_t start_gid = 0;
-       if (unlikely (!plan->new_gid_for_codepoint (cp, &start_gid) && cp != 0xFFFF))
-         return_trace (false);
-       id_delta[i].set (start_gid - segments[i].start_code);
-      } else {
-       id_delta[i].set (0);
-       unsigned int num_codepoints = segments[i].end_code - segments[i].start_code + 1;
-       HBUINT16 *glyph_id_array = c->allocate_size<HBUINT16> (HBUINT16::static_size * num_codepoints);
-       if (glyph_id_array == nullptr)
-         return_trace (false);
-       // From the cmap spec:
-       //
-       // id_range_offset[i]/2
-       // + (cp - segments[i].start_code)
-       // + (id_range_offset + i)
-       // =
-       // glyph_id_array + (cp - segments[i].start_code)
-       //
-       // So, solve for id_range_offset[i]:
-       //
-       // id_range_offset[i]
-       // =
-       // 2 * (glyph_id_array - id_range_offset - i)
-       id_range_offset[i].set (2 * (
-           glyph_id_array - id_range_offset - i));
-       for (unsigned int j = 0; j < num_codepoints; j++)
-       {
-         hb_codepoint_t cp = segments[i].start_code + j;
-         hb_codepoint_t new_gid;
-         if (unlikely (!plan->new_gid_for_codepoint (cp, &new_gid)))
-           return_trace (false);
-         glyph_id_array[j].set (new_gid);
-       }
+       HBUINT16 finalcode;
+       finalcode = 0xFFFF;
+       if (unlikely (!c->copy<HBUINT16> (finalcode))) return nullptr;
       }
     }
 
-    return_trace (true);
+    return endCode;
   }
 
-  static size_t get_sub_table_size (const hb_vector_t<segment_plan> &segments)
+  template<typename Iterator,
+          hb_requires (hb_is_iterator (Iterator))>
+  HBUINT16* serialize_startcode_array (hb_serialize_context_t *c,
+                                      Iterator it)
   {
-    size_t segment_size = 0;
-    for (unsigned int i = 0; i < segments.length; i++)
+    HBUINT16 *startCode = c->start_embed<HBUINT16> ();
+    hb_codepoint_t prev_cp = 0xFFFF;
+
+    + it
+    | hb_apply ([&] (const hb_item_type<Iterator> _)
+               {
+                 if (prev_cp == 0xFFFF || prev_cp + 1u != _.first)
+                 {
+                   HBUINT16 start_code;
+                   start_code = _.first;
+                   c->copy<HBUINT16> (start_code);
+                 }
+
+                 prev_cp = _.first;
+               })
+    ;
+
+    // There must be a final entry with end_code == 0xFFFF.
+    if (it.len () == 0 || prev_cp != 0xFFFF)
     {
-      // Parallel array entries
-      segment_size +=
-           2  // end count
-         + 2  // start count
-         + 2  // delta
-         + 2; // range offset
-
-      if (!segments[i].use_delta)
-       // Add bytes for the glyph index array entries for this segment.
-       segment_size += (segments[i].end_code - segments[i].start_code + 1) * 2;
+      HBUINT16 finalcode;
+      finalcode = 0xFFFF;
+      if (unlikely (!c->copy<HBUINT16> (finalcode))) return nullptr;
     }
 
-    return min_size
-       + 2 // Padding
-       + segment_size;
+    return startCode;
   }
 
-  static bool create_sub_table_plan (const hb_subset_plan_t *plan,
-                                    hb_vector_t<segment_plan> *segments)
+  template<typename Iterator,
+          hb_requires (hb_is_iterator (Iterator))>
+  HBINT16* serialize_idDelta_array (hb_serialize_context_t *c,
+                                    Iterator it,
+                                    HBUINT16 *endCode,
+                                    HBUINT16 *startCode,
+                                    unsigned segcount)
   {
-    segment_plan *segment = nullptr;
-    hb_codepoint_t last_gid = 0;
+    unsigned i = 0;
+    hb_codepoint_t last_gid = 0, start_gid = 0, last_cp = 0xFFFF;
+    bool use_delta = true;
 
-    hb_codepoint_t cp = HB_SET_VALUE_INVALID;
-    while (plan->unicodes->next (&cp)) {
-      hb_codepoint_t new_gid;
-      if (unlikely (!plan->new_gid_for_codepoint (cp, &new_gid)))
-      {
-       DEBUG_MSG(SUBSET, nullptr, "Unable to find new gid for %04x", cp);
-       return false;
-      }
+    HBINT16 *idDelta = c->start_embed<HBINT16> ();
+    if ((char *)idDelta - (char *)startCode != (int) segcount * (int) HBINT16::static_size)
+      return nullptr;
 
-      /* Stop adding to cmap if we are now outside of unicode BMP. */
-      if (cp > 0xFFFF) break;
+    + it
+    | hb_apply ([&] (const hb_item_type<Iterator> _)
+               {
+                 if (_.first == startCode[i])
+                 {
+                   use_delta = true;
+                   start_gid = _.second;
+                 }
+                 else if (_.second != last_gid + 1) use_delta = false;
+
+                 if (_.first == endCode[i])
+                 {
+                   HBINT16 delta;
+                   if (use_delta) delta = (int)start_gid - (int)startCode[i];
+                   else delta = 0;
+                   c->copy<HBINT16> (delta);
+
+                   i++;
+                 }
+
+                 last_gid = _.second;
+                 last_cp = _.first;
+               })
+    ;
+
+    if (it.len () == 0 || last_cp != 0xFFFF)
+    {
+      HBINT16 delta;
+      delta = 1;
+      if (unlikely (!c->copy<HBINT16> (delta))) return nullptr;
+    }
 
-      if (!segment ||
-         cp != segment->end_code + 1u)
-      {
-       segment = segments->push ();
-       segment->start_code.set (cp);
-       segment->end_code.set (cp);
-       segment->use_delta = true;
-      } else {
-       segment->end_code.set (cp);
-       if (last_gid + 1u != new_gid)
-         // gid's are not consecutive in this segment so delta
-         // cannot be used.
-         segment->use_delta = false;
-      }
+    return idDelta;
+  }
 
-      last_gid = new_gid;
-    }
+  template<typename Iterator,
+          hb_requires (hb_is_iterator (Iterator))>
+  HBUINT16* serialize_rangeoffset_glyid (hb_serialize_context_t *c,
+                                        Iterator it,
+                                        HBUINT16 *endCode,
+                                        HBUINT16 *startCode,
+                                        HBINT16 *idDelta,
+                                        unsigned segcount)
+  {
+    HBUINT16 *idRangeOffset = c->allocate_size<HBUINT16> (HBUINT16::static_size * segcount);
+    if (unlikely (!c->check_success (idRangeOffset))) return nullptr;
+    if (unlikely ((char *)idRangeOffset - (char *)idDelta != (int) segcount * (int) HBINT16::static_size)) return nullptr;
+
+    + hb_range (segcount)
+    | hb_filter ([&] (const unsigned _) { return idDelta[_] == 0; })
+    | hb_apply ([&] (const unsigned i)
+               {
+                 idRangeOffset[i] = 2 * (c->start_embed<HBUINT16> () - idRangeOffset - i);
+
+                 + it
+                 | hb_filter ([&] (const hb_item_type<Iterator> _) { return _.first >= startCode[i] && _.first <= endCode[i]; })
+                 | hb_apply ([&] (const hb_item_type<Iterator> _)
+                             {
+                               HBUINT16 glyID;
+                               glyID = _.second;
+                               c->copy<HBUINT16> (glyID);
+                             })
+                 ;
+
+
+               })
+    ;
+
+    return idRangeOffset;
+  }
 
-    // There must be a final entry with end_code == 0xFFFF. Check if we need to add one.
-    if (segment == nullptr || segment->end_code != 0xFFFF)
-    {
-      segment = segments->push ();
-      segment->start_code.set (0xFFFF);
-      segment->end_code.set (0xFFFF);
-      segment->use_delta = true;
-    }
+  template<typename Iterator,
+          hb_requires (hb_is_iterator (Iterator))>
+  void serialize (hb_serialize_context_t *c,
+                 Iterator it)
+  {
+    unsigned table_initpos = c->length ();
+    if (unlikely (!c->extend_min (*this))) return;
+    this->format = 4;
 
-    return true;
+    //serialize endCode[]
+    HBUINT16 *endCode = serialize_endcode_array (c, it);
+    if (unlikely (!endCode)) return;
+
+    unsigned segcount = (c->length () - min_size) / HBUINT16::static_size;
+
+    // 2 bytes of padding.
+    if (unlikely (!c->allocate_size<HBUINT16> (HBUINT16::static_size))) return; // 2 bytes of padding.
+
+   // serialize startCode[]
+    HBUINT16 *startCode = serialize_startcode_array (c, it);
+    if (unlikely (!startCode)) return;
+
+    //serialize idDelta[]
+    HBINT16 *idDelta = serialize_idDelta_array (c, it, endCode, startCode, segcount);
+    if (unlikely (!idDelta)) return;
+
+    HBUINT16 *idRangeOffset = serialize_rangeoffset_glyid (c, it, endCode, startCode, idDelta, segcount);
+    if (unlikely (!c->check_success (idRangeOffset))) return;
+
+    if (unlikely (!c->check_assign(this->length, c->length () - table_initpos))) return;
+    this->segCountX2 = segcount * 2;
+    this->entrySelector = hb_max (1u, hb_bit_storage (segcount)) - 1;
+    this->searchRange = 2 * (1u << this->entrySelector);
+    this->rangeShift = segcount * 2 > this->searchRange
+                      ? 2 * segcount - this->searchRange
+                      : 0;
   }
 
   struct accelerator_t
@@ -286,10 +333,8 @@ struct CmapSubtableFormat4
       *glyph = gid;
       return true;
     }
-    static bool get_glyph_func (const void *obj, hb_codepoint_t codepoint, hb_codepoint_t *glyph)
-    {
-      return ((const accelerator_t *) obj)->get_glyph (codepoint, glyph);
-    }
+    HB_INTERNAL static bool get_glyph_func (const void *obj, hb_codepoint_t codepoint, hb_codepoint_t *glyph)
+    { return ((const accelerator_t *) obj)->get_glyph (codepoint, glyph); }
     void collect_unicodes (hb_set_t *out) const
     {
       unsigned int count = this->segCount;
@@ -297,14 +342,22 @@ struct CmapSubtableFormat4
        count--; /* Skip sentinel segment. */
       for (unsigned int i = 0; i < count; i++)
       {
+       hb_codepoint_t start = this->startCount[i];
+       hb_codepoint_t end = this->endCount[i];
        unsigned int rangeOffset = this->idRangeOffset[i];
        if (rangeOffset == 0)
-         out->add_range (this->startCount[i], this->endCount[i]);
+       {
+         for (hb_codepoint_t codepoint = start; codepoint <= end; codepoint++)
+         {
+           hb_codepoint_t gid = (codepoint + this->idDelta[i]) & 0xFFFFu;
+           if (unlikely (!gid))
+             continue;
+           out->add (codepoint);
+         }
+       }
        else
        {
-         for (hb_codepoint_t codepoint = this->startCount[i];
-              codepoint <= this->endCount[i];
-              codepoint++)
+         for (hb_codepoint_t codepoint = start; codepoint <= end; codepoint++)
          {
            unsigned int index = rangeOffset / 2 + (codepoint - this->startCount[i]) + i - this->segCount;
            if (unlikely (index >= this->glyphIdArrayLength))
@@ -349,7 +402,7 @@ struct CmapSubtableFormat4
       /* Some broken fonts have too long of a "length" value.
        * If that is the case, just change the value to truncate
        * the subtable at the end of the blob. */
-      uint16_t new_length = (uint16_t) MIN ((uintptr_t) 65535,
+      uint16_t new_length = (uint16_t) hb_min ((uintptr_t) 65535,
                                            (uintptr_t) (c->end -
                                                         (char *) this));
       if (!c->try_set (&length, new_length))
@@ -451,7 +504,7 @@ struct CmapSubtableTrimmed
   UINT         length;         /* Byte length of this subtable. */
   UINT         language;       /* Ignore. */
   UINT         startCharCode;  /* First character code covered. */
-  ArrayOf<GlyphID, UINT>
+  ArrayOf<HBGlyphID, UINT>
                glyphIdArray;   /* Array of glyph index values for character
                                 * codes in the range. */
   public:
@@ -477,10 +530,18 @@ struct CmapSubtableLongSegmented
 
   void collect_unicodes (hb_set_t *out) const
   {
-    for (unsigned int i = 0; i < this->groups.len; i++) {
-      out->add_range (this->groups[i].startCharCode,
-                     MIN ((hb_codepoint_t) this->groups[i].endCharCode,
-                          (hb_codepoint_t) HB_UNICODE_MAX));
+    for (unsigned int i = 0; i < this->groups.len; i++)
+    {
+      hb_codepoint_t start = this->groups[i].startCharCode;
+      hb_codepoint_t end = hb_min ((hb_codepoint_t) this->groups[i].endCharCode,
+                                  (hb_codepoint_t) HB_UNICODE_MAX);
+      for (hb_codepoint_t codepoint = start; codepoint <= end; codepoint++)
+      {
+       hb_codepoint_t gid = T::group_get_glyph (this->groups[i], codepoint);
+       if (unlikely (!gid))
+         continue;
+       out->add (codepoint);
+      }
     }
   }
 
@@ -490,15 +551,6 @@ struct CmapSubtableLongSegmented
     return_trace (c->check_struct (this) && groups.sanitize (c));
   }
 
-  bool serialize (hb_serialize_context_t *c,
-                 const hb_vector_t<CmapSubtableLongGroup> &group_data)
-  {
-    TRACE_SERIALIZE (this);
-    if (unlikely (!c->extend_min (*this))) return_trace (false);
-    if (unlikely (!groups.serialize (c, group_data.as_array ()))) return_trace (false);
-    return true;
-  }
-
   protected:
   HBUINT16     format;         /* Subtable format; set to 12. */
   HBUINT16     reserved;       /* Reserved; set to 0. */
@@ -518,63 +570,70 @@ struct CmapSubtableFormat12 : CmapSubtableLongSegmented<CmapSubtableFormat12>
           group.glyphID + (u - group.startCharCode) : 0; }
 
 
-  bool serialize (hb_serialize_context_t *c,
-                 const hb_vector_t<CmapSubtableLongGroup> &groups)
+  template<typename Iterator,
+          hb_requires (hb_is_iterator (Iterator))>
+  void serialize (hb_serialize_context_t *c,
+                 Iterator it)
   {
-    if (unlikely (!c->extend_min (*this))) return false;
-
-    this->format.set (12);
-    this->reserved.set (0);
-    this->length.set (get_sub_table_size (groups));
-
-    return CmapSubtableLongSegmented<CmapSubtableFormat12>::serialize (c, groups);
+    if (it.len () == 0) return;
+    unsigned table_initpos = c->length ();
+    if (unlikely (!c->extend_min (*this))) return;
+
+    hb_codepoint_t startCharCode = 0xFFFF, endCharCode = 0xFFFF;
+    hb_codepoint_t glyphID = 0;
+
+    + it
+    | hb_apply ([&] (const hb_item_type<Iterator> _)
+             {
+               if (startCharCode == 0xFFFF)
+               {
+                 startCharCode = _.first;
+                 endCharCode = _.first;
+                 glyphID = _.second;
+               }
+               else if (!_is_gid_consecutive (endCharCode, startCharCode, glyphID, _.first, _.second))
+               {
+                 CmapSubtableLongGroup  grouprecord;
+                 grouprecord.startCharCode = startCharCode;
+                 grouprecord.endCharCode = endCharCode;
+                 grouprecord.glyphID = glyphID;
+                 c->copy<CmapSubtableLongGroup> (grouprecord);
+
+                 startCharCode = _.first;
+                 endCharCode = _.first;
+                 glyphID = _.second;
+               }
+               else
+               {
+                 endCharCode = _.first;
+               }
+             })
+    ;
+
+    CmapSubtableLongGroup record;
+    record.startCharCode = startCharCode;
+    record.endCharCode = endCharCode;
+    record.glyphID = glyphID;
+    c->copy<CmapSubtableLongGroup> (record);
+
+    this->format = 12;
+    this->reserved = 0;
+    this->length = c->length () - table_initpos;
+    this->groups.len = (this->length - min_size)/CmapSubtableLongGroup::static_size;
   }
 
-  static size_t get_sub_table_size (const hb_vector_t<CmapSubtableLongGroup> &groups)
-  {
-    return 16 + 12 * groups.length;
-  }
+  static size_t get_sub_table_size (const hb_sorted_vector_t<CmapSubtableLongGroup> &groups_data)
+  { return 16 + 12 * groups_data.length; }
 
-  static bool create_sub_table_plan (const hb_subset_plan_t *plan,
-                                    hb_vector_t<CmapSubtableLongGroup> *groups)
-  {
-    CmapSubtableLongGroup *group = nullptr;
-
-    hb_codepoint_t cp = HB_SET_VALUE_INVALID;
-    while (plan->unicodes->next (&cp)) {
-      hb_codepoint_t new_gid;
-      if (unlikely (!plan->new_gid_for_codepoint (cp, &new_gid)))
-      {
-       DEBUG_MSG(SUBSET, nullptr, "Unable to find new gid for %04x", cp);
-       return false;
-      }
-
-      if (!group || !_is_gid_consecutive (group, cp, new_gid))
-      {
-       group = groups->push ();
-       group->startCharCode.set (cp);
-       group->endCharCode.set (cp);
-       group->glyphID.set (new_gid);
-      }
-      else group->endCharCode.set (cp);
-    }
-
-    DEBUG_MSG(SUBSET, nullptr, "cmap");
-    for (unsigned int i = 0; i < groups->length; i++) {
-      CmapSubtableLongGroup& group = (*groups)[i];
-      DEBUG_MSG(SUBSET, nullptr, "  %d: U+%04X-U+%04X, gid %d-%d", i, (uint32_t) group.startCharCode, (uint32_t) group.endCharCode, (uint32_t) group.glyphID, (uint32_t) group.glyphID + ((uint32_t) group.endCharCode - (uint32_t) group.startCharCode));
-    }
-
-    return true;
-  }
-
- private:
-  static bool _is_gid_consecutive (CmapSubtableLongGroup *group,
+  private:
+  static bool _is_gid_consecutive (hb_codepoint_t endCharCode,
+                                  hb_codepoint_t startCharCode,
+                                  hb_codepoint_t glyphID,
                                   hb_codepoint_t cp,
                                   hb_codepoint_t new_gid)
   {
-    return (cp - 1 == group->endCharCode) &&
-       new_gid == group->glyphID + (cp - group->startCharCode);
+    return (cp - 1 == endCharCode) &&
+       new_gid == glyphID + (cp - startCharCode);
   }
 
 };
@@ -623,12 +682,69 @@ struct DefaultUVS : SortedArrayOf<UnicodeValueRange, HBUINT32>
     for (unsigned int i = 0; i < count; i++)
     {
       hb_codepoint_t first = arrayZ[i].startUnicodeValue;
-      hb_codepoint_t last = MIN ((hb_codepoint_t) (first + arrayZ[i].additionalCount),
+      hb_codepoint_t last = hb_min ((hb_codepoint_t) (first + arrayZ[i].additionalCount),
                                 (hb_codepoint_t) HB_UNICODE_MAX);
       out->add_range (first, last);
     }
   }
 
+  DefaultUVS* copy (hb_serialize_context_t *c,
+                   const hb_set_t *unicodes) const
+  {
+    DefaultUVS *out = c->start_embed<DefaultUVS> ();
+    if (unlikely (!out)) return nullptr;
+    auto snap = c->snapshot ();
+
+    HBUINT32 len;
+    len = 0;
+    if (unlikely (!c->copy<HBUINT32> (len))) return nullptr;
+    unsigned init_len = c->length ();
+
+    hb_codepoint_t lastCode = HB_MAP_VALUE_INVALID;
+    int count = -1;
+
+    for (const UnicodeValueRange& _ : as_array ())
+    {
+      for (const unsigned addcnt : hb_range ((unsigned) _.additionalCount + 1))
+      {
+       unsigned curEntry = (unsigned) _.startUnicodeValue + addcnt;
+       if (!unicodes->has (curEntry)) continue;
+       count += 1;
+       if (lastCode == HB_MAP_VALUE_INVALID)
+         lastCode = curEntry;
+       else if (lastCode + count != curEntry)
+       {
+         UnicodeValueRange rec;
+         rec.startUnicodeValue = lastCode;
+         rec.additionalCount = count - 1;
+         c->copy<UnicodeValueRange> (rec);
+
+         lastCode = curEntry;
+         count = 0;
+       }
+      }
+    }
+
+    if (lastCode != HB_MAP_VALUE_INVALID)
+    {
+      UnicodeValueRange rec;
+      rec.startUnicodeValue = lastCode;
+      rec.additionalCount = count;
+      c->copy<UnicodeValueRange> (rec);
+    }
+
+    if (c->length () - init_len == 0)
+    {
+      c->revert (snap);
+      return nullptr;
+    }
+    else
+    {
+      if (unlikely (!c->check_assign (out->len, (c->length () - init_len) / UnicodeValueRange::static_size))) return nullptr;
+      return out;
+    }
+  }
+
   public:
   DEFINE_SIZE_ARRAY (4, *this);
 };
@@ -636,9 +752,7 @@ struct DefaultUVS : SortedArrayOf<UnicodeValueRange, HBUINT32>
 struct UVSMapping
 {
   int cmp (const hb_codepoint_t &codepoint) const
-  {
-    return unicodeValue.cmp (codepoint);
-  }
+  { return unicodeValue.cmp (codepoint); }
 
   bool sanitize (hb_sanitize_context_t *c) const
   {
@@ -647,7 +761,7 @@ struct UVSMapping
   }
 
   HBUINT24     unicodeValue;   /* Base Unicode value of the UVS */
-  GlyphID      glyphID;        /* Glyph ID of the UVS */
+  HBGlyphID    glyphID;        /* Glyph ID of the UVS */
   public:
   DEFINE_SIZE_STATIC (5);
 };
@@ -661,6 +775,49 @@ struct NonDefaultUVS : SortedArrayOf<UVSMapping, HBUINT32>
       out->add (arrayZ[i].glyphID);
   }
 
+  void closure_glyphs (const hb_set_t      *unicodes,
+                      hb_set_t            *glyphset) const
+  {
+    + as_array ()
+    | hb_filter (unicodes, &UVSMapping::unicodeValue)
+    | hb_map (&UVSMapping::glyphID)
+    | hb_sink (glyphset)
+    ;
+  }
+
+  NonDefaultUVS* copy (hb_serialize_context_t *c,
+                      const hb_set_t *unicodes,
+                      const hb_set_t *glyphs,
+                      const hb_map_t *glyph_map) const
+  {
+    NonDefaultUVS *out = c->start_embed<NonDefaultUVS> ();
+    if (unlikely (!out)) return nullptr;
+
+    auto it =
+    + as_array ()
+    | hb_filter ([&] (const UVSMapping& _)
+                {
+                  return unicodes->has (_.unicodeValue) || glyphs->has (_.glyphID);
+                })
+    ;
+
+    if (!it) return nullptr;
+
+    HBUINT32 len;
+    len = it.len ();
+    if (unlikely (!c->copy<HBUINT32> (len))) return nullptr;
+
+    for (const UVSMapping& _ : it)
+    {
+      UVSMapping mapping;
+      mapping.unicodeValue = _.unicodeValue;
+      mapping.glyphID = glyph_map->get (_.glyphID);
+      c->copy<UVSMapping> (mapping);
+    }
+
+    return out;
+  }
+
   public:
   DEFINE_SIZE_ARRAY (4, *this);
 };
@@ -689,9 +846,7 @@ struct VariationSelectorRecord
   }
 
   int cmp (const hb_codepoint_t &variation_selector) const
-  {
-    return varSelector.cmp (variation_selector);
-  }
+  { return varSelector.cmp (variation_selector); }
 
   bool sanitize (hb_sanitize_context_t *c, const void *base) const
   {
@@ -701,6 +856,52 @@ struct VariationSelectorRecord
                  nonDefaultUVS.sanitize (c, base));
   }
 
+  VariationSelectorRecord* copy (hb_serialize_context_t *c,
+                                const hb_set_t *unicodes,
+                                const hb_set_t *glyphs,
+                                const hb_map_t *glyph_map,
+                                const void *src_base,
+                                const void *dst_base) const
+  {
+    auto snap = c->snapshot ();
+    auto *out = c->embed<VariationSelectorRecord> (*this);
+    if (unlikely (!out)) return nullptr;
+
+    out->defaultUVS = 0;
+    out->nonDefaultUVS = 0;
+
+    bool drop = true;
+
+    if (defaultUVS != 0)
+    {
+      c->push ();
+      if (c->copy (src_base+defaultUVS, unicodes))
+      {
+       c->add_link (out->defaultUVS, c->pop_pack (), dst_base);
+       drop = false;
+      }
+      else c->pop_discard ();
+    }
+
+    if (nonDefaultUVS != 0)
+    {
+      c->push ();
+      if (c->copy (src_base+nonDefaultUVS, unicodes, glyphs, glyph_map))
+      {
+       c->add_link (out->nonDefaultUVS, c->pop_pack (), dst_base);
+       drop = false;
+      }
+      else c->pop_discard ();
+    }
+
+    if (drop)
+    {
+      c->revert (snap);
+      return nullptr;
+    }
+    else return out;
+  }
+
   HBUINT24     varSelector;    /* Variation selector. */
   LOffsetTo<DefaultUVS>
                defaultUVS;     /* Offset to Default UVS Table.  May be 0. */
@@ -715,9 +916,7 @@ struct CmapSubtableFormat14
   glyph_variant_t get_glyph_variant (hb_codepoint_t codepoint,
                                     hb_codepoint_t variation_selector,
                                     hb_codepoint_t *glyph) const
-  {
-    return record.bsearch (variation_selector).get_glyph (codepoint, glyph, this);
-  }
+  { return record.bsearch (variation_selector).get_glyph (codepoint, glyph, this); }
 
   void collect_variation_selectors (hb_set_t *out) const
   {
@@ -727,8 +926,44 @@ struct CmapSubtableFormat14
   }
   void collect_variation_unicodes (hb_codepoint_t variation_selector,
                                   hb_set_t *out) const
+  { record.bsearch (variation_selector).collect_unicodes (out, this); }
+
+  void serialize (hb_serialize_context_t *c,
+                 const hb_set_t *unicodes,
+                 const hb_set_t *glyphs,
+                 const hb_map_t *glyph_map,
+                 const void *src_base)
+  {
+    auto snap = c->snapshot ();
+    unsigned table_initpos = c->length ();
+    const char* init_tail = c->tail;
+
+    if (unlikely (!c->extend_min (*this))) return;
+    this->format = 14;
+
+    const CmapSubtableFormat14 *src_tbl = reinterpret_cast<const CmapSubtableFormat14*> (src_base);
+    for (const VariationSelectorRecord& _ : src_tbl->record)
+      c->copy (_, unicodes, glyphs, glyph_map, src_base, this);
+
+    if (c->length () - table_initpos == CmapSubtableFormat14::min_size)
+      c->revert (snap);
+    else
+    {
+      int tail_len = init_tail - c->tail;
+      c->check_assign (this->length, c->length () - table_initpos + tail_len);
+      c->check_assign (this->record.len, (c->length () - table_initpos - CmapSubtableFormat14::min_size) / VariationSelectorRecord::static_size);
+    }
+  }
+
+  void closure_glyphs (const hb_set_t      *unicodes,
+                      hb_set_t            *glyphset) const
   {
-    record.bsearch (variation_selector).collect_unicodes (out, this);
+    + hb_iter (record)
+    | hb_filter (hb_bool, &VariationSelectorRecord::nonDefaultUVS)
+    | hb_map (&VariationSelectorRecord::nonDefaultUVS)
+    | hb_map (hb_add (this))
+    | hb_apply ([=] (const NonDefaultUVS& _) { _.closure_glyphs (unicodes, glyphset); })
+    ;
   }
 
   bool sanitize (hb_sanitize_context_t *c) const
@@ -780,6 +1015,22 @@ struct CmapSubtable
     }
   }
 
+  template<typename Iterator,
+          hb_requires (hb_is_iterator (Iterator))>
+  void serialize (hb_serialize_context_t *c,
+                 Iterator it,
+                 unsigned format,
+                 const hb_subset_plan_t *plan,
+                 const void *src_base)
+  {
+    switch (format) {
+    case  4: u.format4.serialize (c, it);  return;
+    case 12: u.format12.serialize (c, it); return;
+    case 14: u.format14.serialize (c, plan->unicodes, plan->_glyphset, plan->glyph_map, src_base); return;
+    default: return;
+    }
+  }
+
   bool sanitize (hb_sanitize_context_t *c) const
   {
     TRACE_SANITIZE (this);
@@ -831,6 +1082,41 @@ struct EncodingRecord
                  subtable.sanitize (c, base));
   }
 
+  template<typename Iterator,
+          hb_requires (hb_is_iterator (Iterator))>
+  EncodingRecord* copy (hb_serialize_context_t *c,
+                       Iterator it,
+                       unsigned format,
+                       const void *src_base,
+                       const void *dst_base,
+                       const hb_subset_plan_t *plan,
+                       /* INOUT */ unsigned *objidx) const
+  {
+    TRACE_SERIALIZE (this);
+    auto snap = c->snapshot ();
+    auto *out = c->embed (this);
+    if (unlikely (!out)) return_trace (nullptr);
+    out->subtable = 0;
+
+    if (*objidx == 0)
+    {
+      CmapSubtable *cmapsubtable = c->push<CmapSubtable> ();
+      unsigned origin_length = c->length ();
+      cmapsubtable->serialize (c, it, format, plan, &(src_base+subtable));
+      if (c->length () - origin_length > 0) *objidx = c->pop_pack ();
+      else c->pop_discard ();
+    }
+
+    if (*objidx == 0)
+    {
+      c->revert (snap);
+      return_trace (nullptr);
+    }
+
+    c->add_link (out->subtable, *objidx, dst_base);
+    return_trace (out);
+  }
+
   HBUINT16     platformID;     /* Platform ID. */
   HBUINT16     encodingID;     /* Platform-specific encoding ID. */
   LOffsetTo<CmapSubtable>
@@ -843,124 +1129,99 @@ struct cmap
 {
   static constexpr hb_tag_t tableTag = HB_OT_TAG_cmap;
 
-  struct subset_plan
+  template<typename Iterator, typename EncodingRecIter,
+          hb_requires (hb_is_iterator (Iterator))>
+  void serialize (hb_serialize_context_t *c,
+                 Iterator it,
+                 EncodingRecIter encodingrec_iter,
+                 const void *src_base,
+                 const hb_subset_plan_t *plan)
   {
-    size_t final_size () const
+    if (unlikely (!c->extend_min ((*this))))  return;
+    this->version = 0;
+
+    unsigned format4objidx = 0, format12objidx = 0, format14objidx = 0;
+
+    for (const EncodingRecord& _ : encodingrec_iter)
     {
-      return 4 // header
-         +  8 * 3 // 3 EncodingRecord
-         +  CmapSubtableFormat4::get_sub_table_size (this->format4_segments)
-         +  CmapSubtableFormat12::get_sub_table_size (this->format12_groups);
+      unsigned format = (src_base+_.subtable).u.format;
+
+      if (format == 4) c->copy (_, it, 4u, src_base, this, plan, &format4objidx);
+      else if (format == 12) c->copy (_, it, 12u, src_base, this, plan, &format12objidx);
+      else if (format == 14) c->copy (_, it, 14u, src_base, this, plan, &format14objidx);
     }
 
-    hb_vector_t<CmapSubtableFormat4::segment_plan> format4_segments;
-    hb_vector_t<CmapSubtableLongGroup> format12_groups;
-  };
+    c->check_assign(this->encodingRecord.len, (c->length () - cmap::min_size)/EncodingRecord::static_size);
+  }
 
-  bool _create_plan (const hb_subset_plan_t *plan,
-                    subset_plan *cmap_plan) const
+  void closure_glyphs (const hb_set_t      *unicodes,
+                      hb_set_t            *glyphset) const
   {
-    if (unlikely (!CmapSubtableFormat4::create_sub_table_plan (plan, &cmap_plan->format4_segments)))
-      return false;
-
-    return CmapSubtableFormat12::create_sub_table_plan (plan, &cmap_plan->format12_groups);
+    + hb_iter (encodingRecord)
+    | hb_map (&EncodingRecord::subtable)
+    | hb_map (hb_add (this))
+    | hb_filter ([&] (const CmapSubtable& _) { return _.u.format == 14; })
+    | hb_apply ([=] (const CmapSubtable& _) { _.u.format14.closure_glyphs (unicodes, glyphset); })
+    ;
   }
 
-  bool _subset (const hb_subset_plan_t *plan,
-               const subset_plan &cmap_subset_plan,
-               size_t dest_sz,
-               void *dest) const
+  bool subset (hb_subset_context_t *c) const
   {
-    hb_serialize_context_t c (dest, dest_sz);
+    TRACE_SUBSET (this);
 
-    cmap *table = c.start_serialize<cmap> ();
-    if (unlikely (!c.extend_min (*table)))
-    {
-      return false;
-    }
+    cmap *cmap_prime = c->serializer->start_embed<cmap> ();
+    if (unlikely (!c->serializer->check_success (cmap_prime))) return_trace (false);
 
-    table->version.set (0);
+    auto encodingrec_iter =
+    + hb_iter (encodingRecord)
+    | hb_filter ([&] (const EncodingRecord& _)
+               {
+                 if ((_.platformID == 0 && _.encodingID == 3) ||
+                     (_.platformID == 0 && _.encodingID == 4) ||
+                     (_.platformID == 3 && _.encodingID == 1) ||
+                     (_.platformID == 3 && _.encodingID == 10) ||
+                     (this + _.subtable).u.format == 14)
+                   return true;
 
-    if (unlikely (!table->encodingRecord.serialize (&c, /* numTables */ 3)))
-      return false;
+                 return false;
+               })
+    ;
 
-    // TODO(grieger): Convert the below to a for loop
 
-    // Format 4, Plat 0 Encoding Record
-    EncodingRecord &format4_plat0_rec = table->encodingRecord[0];
-    format4_plat0_rec.platformID.set (0); // Unicode
-    format4_plat0_rec.encodingID.set (3);
+    if (unlikely (!encodingrec_iter.len ())) return_trace (false);
 
-    // Format 4, Plat 3 Encoding Record
-    EncodingRecord &format4_plat3_rec = table->encodingRecord[1];
-    format4_plat3_rec.platformID.set (3); // Windows
-    format4_plat3_rec.encodingID.set (1); // Unicode BMP
+    const EncodingRecord *unicode_bmp= nullptr, *unicode_ucs4 = nullptr, *ms_bmp = nullptr, *ms_ucs4 = nullptr;
+    bool has_format12 = false;
 
-    // Format 12 Encoding Record
-    EncodingRecord &format12_rec = table->encodingRecord[2];
-    format12_rec.platformID.set (3); // Windows
-    format12_rec.encodingID.set (10); // Unicode UCS-4
-
-    // Write out format 4 sub table
+    for (const EncodingRecord& _ : encodingrec_iter)
     {
-      CmapSubtable &subtable = format4_plat0_rec.subtable.serialize (&c, table);
-      format4_plat3_rec.subtable.set (format4_plat0_rec.subtable);
-      subtable.u.format.set (4);
-
-      CmapSubtableFormat4 &format4 = subtable.u.format4;
-      if (unlikely (!format4.serialize (&c, plan, cmap_subset_plan.format4_segments)))
-       return false;
+      unsigned format = (this + _.subtable).u.format;
+      if (format == 12) has_format12 = true;
+
+      const EncodingRecord *table = hb_addressof (_);
+      if      (_.platformID == 0 && _.encodingID ==  3) unicode_bmp = table;
+      else if (_.platformID == 0 && _.encodingID ==  4) unicode_ucs4 = table;
+      else if (_.platformID == 3 && _.encodingID ==  1) ms_bmp = table;
+      else if (_.platformID == 3 && _.encodingID == 10) ms_ucs4 = table;
     }
 
-    // Write out format 12 sub table.
-    {
-      CmapSubtable &subtable = format12_rec.subtable.serialize (&c, table);
-      subtable.u.format.set (12);
-
-      CmapSubtableFormat12 &format12 = subtable.u.format12;
-      if (unlikely (!format12.serialize (&c, cmap_subset_plan.format12_groups)))
-       return false;
-    }
-
-    c.end_serialize ();
-
-    return true;
-  }
-
-  bool subset (hb_subset_plan_t *plan) const
-  {
-    subset_plan cmap_subset_plan;
-
-    if (unlikely (!_create_plan (plan, &cmap_subset_plan)))
-    {
-      DEBUG_MSG(SUBSET, nullptr, "Failed to generate a cmap subsetting plan.");
-      return false;
-    }
-
-    // We now know how big our blob needs to be
-    size_t dest_sz = cmap_subset_plan.final_size ();
-    void *dest = malloc (dest_sz);
-    if (unlikely (!dest)) {
-      DEBUG_MSG(SUBSET, nullptr, "Unable to alloc %lu for cmap subset output", (unsigned long) dest_sz);
-      return false;
-    }
-
-    if (unlikely (!_subset (plan, cmap_subset_plan, dest_sz, dest)))
-    {
-      DEBUG_MSG(SUBSET, nullptr, "Failed to perform subsetting of cmap.");
-      free (dest);
-      return false;
-    }
-
-    // all done, write the blob into dest
-    hb_blob_t *cmap_prime = hb_blob_create ((const char *) dest,
-                                           dest_sz,
-                                           HB_MEMORY_MODE_READONLY,
-                                           dest,
-                                           free);
-    bool result =  plan->add_table (HB_OT_TAG_cmap, cmap_prime);
-    hb_blob_destroy (cmap_prime);
-    return result;
+    if (unlikely (!unicode_bmp && !ms_bmp)) return_trace (false);
+    if (unlikely (has_format12 && (!unicode_ucs4 && !ms_ucs4))) return_trace (false);
+
+    auto it =
+    + hb_iter (c->plan->unicodes)
+    | hb_map ([&] (hb_codepoint_t _)
+             {
+               hb_codepoint_t new_gid = HB_MAP_VALUE_INVALID;
+               c->plan->new_gid_for_codepoint (_, &new_gid);
+               return hb_pair_t<hb_codepoint_t, hb_codepoint_t> (_, new_gid);
+             })
+    | hb_filter ([&] (const hb_pair_t<hb_codepoint_t, hb_codepoint_t> _)
+                { return (_.second != HB_MAP_VALUE_INVALID); })
+    ;
+
+    cmap_prime->serialize (c->serializer, it, encodingrec_iter, this, c->plan);
+    return_trace (true);
   }
 
   const CmapSubtable *find_best_subtable (bool *symbol = nullptr) const
@@ -969,6 +1230,15 @@ struct cmap
 
     const CmapSubtable *subtable;
 
+    /* Symbol subtable.
+     * Prefer symbol if available.
+     * https://github.com/harfbuzz/harfbuzz/issues/1918 */
+    if ((subtable = this->find_subtable (3, 0)))
+    {
+      if (symbol) *symbol = true;
+      return subtable;
+    }
+
     /* 32-bit subtables. */
     if ((subtable = this->find_subtable (3, 10))) return subtable;
     if ((subtable = this->find_subtable (0, 6))) return subtable;
@@ -981,13 +1251,6 @@ struct cmap
     if ((subtable = this->find_subtable (0, 1))) return subtable;
     if ((subtable = this->find_subtable (0, 0))) return subtable;
 
-    /* Symbol subtable. */
-    if ((subtable = this->find_subtable (3, 0)))
-    {
-      if (symbol) *symbol = true;
-      return subtable;
-    }
-
     /* Meh. */
     return &Null (CmapSubtable);
   }
@@ -1008,9 +1271,9 @@ struct cmap
 
       this->get_glyph_data = subtable;
       if (unlikely (symbol))
-      {
        this->get_glyph_funcZ = get_glyph_from_symbol<CmapSubtable>;
-      } else {
+      else
+      {
        switch (subtable->u.format) {
        /* Accelerate format 4 and format 12. */
        default:
@@ -1020,20 +1283,20 @@ struct cmap
          this->get_glyph_funcZ = get_glyph_from<CmapSubtableFormat12>;
          break;
        case  4:
-         {
-           this->format4_accel.init (&subtable->u.format4);
-           this->get_glyph_data = &this->format4_accel;
-           this->get_glyph_funcZ = this->format4_accel.get_glyph_func;
-         }
+       {
+         this->format4_accel.init (&subtable->u.format4);
+         this->get_glyph_data = &this->format4_accel;
+         this->get_glyph_funcZ = this->format4_accel.get_glyph_func;
          break;
        }
+       }
       }
     }
 
     void fini () { this->table.destroy (); }
 
     bool get_nominal_glyph (hb_codepoint_t  unicode,
-                                  hb_codepoint_t *glyph) const
+                           hb_codepoint_t *glyph) const
     {
       if (unlikely (!this->get_glyph_funcZ)) return false;
       return this->get_glyph_funcZ (this->get_glyph_data, unicode, glyph);
@@ -1077,18 +1340,12 @@ struct cmap
     }
 
     void collect_unicodes (hb_set_t *out) const
-    {
-      subtable->collect_unicodes (out);
-    }
+    { subtable->collect_unicodes (out); }
     void collect_variation_selectors (hb_set_t *out) const
-    {
-      subtable_uvs->collect_variation_selectors (out);
-    }
+    { subtable_uvs->collect_variation_selectors (out); }
     void collect_variation_unicodes (hb_codepoint_t variation_selector,
                                     hb_set_t *out) const
-    {
-      subtable_uvs->collect_variation_unicodes (variation_selector, out);
-    }
+    { subtable_uvs->collect_variation_unicodes (variation_selector, out); }
 
     protected:
     typedef bool (*hb_cmap_get_glyph_func_t) (const void *obj,
@@ -1096,18 +1353,18 @@ struct cmap
                                              hb_codepoint_t *glyph);
 
     template <typename Type>
-    static bool get_glyph_from (const void *obj,
-                               hb_codepoint_t codepoint,
-                               hb_codepoint_t *glyph)
+    HB_INTERNAL static bool get_glyph_from (const void *obj,
+                                           hb_codepoint_t codepoint,
+                                           hb_codepoint_t *glyph)
     {
       const Type *typed_obj = (const Type *) obj;
       return typed_obj->get_glyph (codepoint, glyph);
     }
 
     template <typename Type>
-    static bool get_glyph_from_symbol (const void *obj,
-                                             hb_codepoint_t codepoint,
-                                             hb_codepoint_t *glyph)
+    HB_INTERNAL static bool get_glyph_from_symbol (const void *obj,
+                                                  hb_codepoint_t codepoint,
+                                                  hb_codepoint_t *glyph)
     {
       const Type *typed_obj = (const Type *) obj;
       if (likely (typed_obj->get_glyph (codepoint, glyph)))
@@ -1135,6 +1392,7 @@ struct cmap
 
     CmapSubtableFormat4::accelerator_t format4_accel;
 
+    public:
     hb_blob_ptr_t<cmap> table;
   };
 
@@ -1144,8 +1402,8 @@ struct cmap
                                     unsigned int encoding_id) const
   {
     EncodingRecord key;
-    key.platformID.set (platform_id);
-    key.encodingID.set (encoding_id);
+    key.platformID = platform_id;
+    key.encodingID = encoding_id;
 
     const EncodingRecord &result = encodingRecord.bsearch (key);
     if (!result.subtable)
@@ -1154,6 +1412,28 @@ struct cmap
     return &(this+result.subtable);
   }
 
+  const EncodingRecord *find_encodingrec (unsigned int platform_id,
+                                   unsigned int encoding_id) const
+  {
+    EncodingRecord key;
+    key.platformID = platform_id;
+    key.encodingID = encoding_id;
+
+    return encodingRecord.as_array ().bsearch (key);
+  }
+
+  bool find_subtable (unsigned format) const
+  {
+    auto it =
+    + hb_iter (encodingRecord)
+    | hb_map (&EncodingRecord::subtable)
+    | hb_map (hb_add (this))
+    | hb_filter ([&] (const CmapSubtable& _) { return _.u.format == format; })
+    ;
+
+    return it.len ();
+  }
+
   public:
 
   bool sanitize (hb_sanitize_context_t *c) const
index 333ceaa..3498d3b 100644 (file)
@@ -51,12 +51,12 @@ struct SmallGlyphMetrics
     return_trace (c->check_struct (this));
   }
 
-  void get_extents (hb_glyph_extents_t *extents) const
+  void get_extents (hb_font_t *font, hb_glyph_extents_t *extents) const
   {
-    extents->x_bearing = bearingX;
-    extents->y_bearing = bearingY;
-    extents->width = width;
-    extents->height = - (hb_position_t) height;
+    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 (-height);
   }
 
   HBUINT8      height;
@@ -144,7 +144,7 @@ struct IndexSubtableFormat1Or3
   }
 
   IndexSubtableHeader  header;
-  UnsizedArrayOf<Offset<OffsetType> >
+  UnsizedArrayOf<Offset<OffsetType>>
                        offsetArrayZ;
   public:
   DEFINE_SIZE_ARRAY(8, offsetArrayZ);
@@ -226,8 +226,8 @@ struct IndexSubtableRecord
                                                   offset, length, format);
   }
 
-  GlyphID                      firstGlyphIndex;
-  GlyphID                      lastGlyphIndex;
+  HBGlyphID                    firstGlyphIndex;
+  HBGlyphID                    lastGlyphIndex;
   LOffsetTo<IndexSubtable>     offsetToSubtable;
   public:
   DEFINE_SIZE_STATIC(8);
@@ -251,7 +251,7 @@ struct IndexSubtableArray
       unsigned int firstGlyphIndex = indexSubtablesZ[i].firstGlyphIndex;
       unsigned int lastGlyphIndex = indexSubtablesZ[i].lastGlyphIndex;
       if (firstGlyphIndex <= glyph && glyph <= lastGlyphIndex)
-        return &indexSubtablesZ[i];
+       return &indexSubtablesZ[i];
     }
     return nullptr;
   }
@@ -290,8 +290,8 @@ struct BitmapSizeTable
   HBUINT32             colorRef;
   SBitLineMetrics      horizontal;
   SBitLineMetrics      vertical;
-  GlyphID              startGlyphIndex;
-  GlyphID              endGlyphIndex;
+  HBGlyphID            startGlyphIndex;
+  HBGlyphID            endGlyphIndex;
   HBUINT8              ppemX;
   HBUINT8              ppemY;
   HBUINT8              bitDepth;
@@ -349,15 +349,15 @@ struct CBLC
     if (unlikely (!count))
       return Null(BitmapSizeTable);
 
-    unsigned int requested_ppem = MAX (font->x_ppem, font->y_ppem);
+    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 = MAX (sizeTables[0].ppemX, sizeTables[0].ppemY);
+    unsigned int best_ppem = hb_max (sizeTables[0].ppemX, sizeTables[0].ppemY);
 
     for (unsigned int i = 1; i < count; i++)
     {
-      unsigned int ppem = MAX (sizeTables[i].ppemX, sizeTables[i].ppemY);
+      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))
       {
@@ -424,7 +424,7 @@ struct CBDT
              return false;
            const GlyphBitmapDataFormat17& glyphFormat17 =
                StructAtOffset<GlyphBitmapDataFormat17> (this->cbdt, image_offset);
-           glyphFormat17.glyphMetrics.get_extents (extents);
+           glyphFormat17.glyphMetrics.get_extents (font, extents);
            break;
          }
          case 18: {
@@ -432,7 +432,7 @@ struct CBDT
              return false;
            const GlyphBitmapDataFormat18& glyphFormat18 =
                StructAtOffset<GlyphBitmapDataFormat18> (this->cbdt, image_offset);
-           glyphFormat18.glyphMetrics.get_extents (extents);
+           glyphFormat18.glyphMetrics.get_extents (font, extents);
            break;
          }
          default:
@@ -442,18 +442,18 @@ struct CBDT
       }
 
       /* Convert to font units. */
-      double x_scale = upem / (double) strike.ppemX;
-      double y_scale = upem / (double) strike.ppemY;
-      extents->x_bearing = round (extents->x_bearing * x_scale);
-      extents->y_bearing = round (extents->y_bearing * y_scale);
-      extents->width = round (extents->width * x_scale);
-      extents->height = round (extents->height * y_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
+                             hb_codepoint_t  glyph) const
     {
       const void *base;
       const BitmapSizeTable &strike = this->cblc->choose_strike (font);
index a57911a..e2ed7c6 100644 (file)
@@ -39,14 +39,16 @@ namespace OT {
 
 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:
-  GlyphID      glyphId;        /* Glyph ID of layer glyph */
+  protected:
+  HBGlyphID    glyphId;        /* Glyph ID of layer glyph */
   Index                colorIdx;       /* Index value to use with a
                                 * selected color palette.
                                 * An index value of 0xFFFF
@@ -73,7 +75,7 @@ struct BaseGlyphRecord
   }
 
   public:
-  GlyphID      glyphId;        /* Glyph ID of reference glyph */
+  HBGlyphID    glyphId;        /* Glyph ID of reference glyph */
   HBUINT16     firstLayerIdx;  /* Index (from beginning of
                                 * the Layer Records) to the
                                 * layer record. There will be
@@ -98,18 +100,14 @@ struct COLR
   {
     const BaseGlyphRecord &record = (this+baseGlyphsZ).bsearch (numBaseGlyphs, glyph);
 
-    hb_array_t<const LayerRecord> all_layers ((this+layersZ).arrayZ, numLayers);
+    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)
     {
-      hb_array_t<const LayerRecord> segment_layers = glyph_layers.sub_array (start_offset, *count);
-      *count = segment_layers.length;
-      for (unsigned int i = 0; i < segment_layers.length; i++)
-      {
-        layers[i].glyph = segment_layers.arrayZ[i].glyphId;
-        layers[i].color_index = segment_layers.arrayZ[i].colorIdx;
-      }
+      + glyph_layers.sub_array (start_offset, count)
+      | hb_sink (hb_array (layers, *count))
+      ;
     }
     return glyph_layers.length;
   }
@@ -125,9 +123,9 @@ struct COLR
   protected:
   HBUINT16     version;        /* Table version number (starts at 0). */
   HBUINT16     numBaseGlyphs;  /* Number of Base Glyph Records. */
-  LNNOffsetTo<SortedUnsizedArrayOf<BaseGlyphRecord> >
+  LNNOffsetTo<SortedUnsizedArrayOf<BaseGlyphRecord>>
                baseGlyphsZ;    /* Offset to Base Glyph records. */
-  LNNOffsetTo<UnsizedArrayOf<LayerRecord> >
+  LNNOffsetTo<UnsizedArrayOf<LayerRecord>>
                layersZ;        /* Offset to Layer Records. */
   HBUINT16     numLayers;      /* Number of Layer Records. */
   public:
index 4070493..1b3c7fc 100644 (file)
@@ -87,15 +87,15 @@ struct CPALV1Tail
   }
 
   protected:
-  LNNOffsetTo<UnsizedArrayOf<HBUINT32> >
+  LNNOffsetTo<UnsizedArrayOf<HBUINT32>>
                paletteFlagsZ;          /* Offset from the beginning of CPAL table to
                                         * the Palette Type Array. Set to 0 if no array
                                         * is provided. */
-  LNNOffsetTo<UnsizedArrayOf<NameID> >
+  LNNOffsetTo<UnsizedArrayOf<NameID>>
                paletteLabelsZ;         /* Offset from the beginning of CPAL table to
                                         * the palette labels array. Set to 0 if no
                                         * array is provided. */
-  LNNOffsetTo<UnsizedArrayOf<NameID> >
+  LNNOffsetTo<UnsizedArrayOf<NameID>>
                colorLabelsZ;           /* Offset from the beginning of CPAL table to
                                         * the color labels array. Set to 0
                                         * if no array is provided. */
@@ -115,7 +115,7 @@ struct CPAL
   { return min_size + numPalettes * sizeof (colorRecordIndicesZ[0]); }
 
   unsigned int get_palette_count () const { return numPalettes; }
-  unsigned int get_color_count () const   { return numColors; }
+  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); }
@@ -144,10 +144,10 @@ struct CPAL
     {
       hb_array_t<const BGRAColor> segment_colors = palette_colors.sub_array (start_offset, *color_count);
       /* Always return numColors colors per palette even if it has out-of-bounds start index. */
-      unsigned int count = MIN<unsigned int> (MAX<int> (numColors - start_offset, 0), *color_count);
+      unsigned int count = hb_min ((unsigned) hb_max ((int) (numColors - start_offset), 0), *color_count);
       *color_count = count;
       for (unsigned int i = 0; i < count; i++)
-        colors[i] = segment_colors[i]; /* Bound-checked read. */
+       colors[i] = segment_colors[i]; /* Bound-checked read. */
     }
     return numColors;
   }
@@ -176,7 +176,7 @@ struct CPAL
   HBUINT16     numPalettes;            /* Number of palettes in the table. */
   HBUINT16     numColorRecords;        /* Total number of color records, combined for
                                         * all palettes. */
-  LNNOffsetTo<UnsizedArrayOf<BGRAColor> >
+  LNNOffsetTo<UnsizedArrayOf<BGRAColor>>
                colorRecordsZ;          /* Offset from the beginning of CPAL table to
                                         * the first ColorRecord. */
   UnsizedArrayOf<HBUINT16>
index f6bdbb3..35d3fd5 100644 (file)
@@ -121,11 +121,11 @@ struct SBIXStrike
   HBUINT16     resolution;     /* The device pixel density (in PPI) for which this
                                 * strike was designed. (E.g., 96 PPI, 192 PPI.) */
   protected:
-  UnsizedArrayOf<LOffsetTo<SBIXGlyph> >
+  UnsizedArrayOf<LOffsetTo<SBIXGlyph>>
                imageOffsetsZ;  /* Offset from the beginning of the strike data header
                                 * to bitmap data for an individual glyph ID. */
   public:
-  DEFINE_SIZE_STATIC (8);
+  DEFINE_SIZE_ARRAY (4, imageOffsetsZ);
 };
 
 struct sbix
@@ -173,11 +173,11 @@ struct sbix
     {
       unsigned count = table->strikes.len;
       if (unlikely (!count))
-        return Null(SBIXStrike);
+       return Null(SBIXStrike);
 
-      unsigned int requested_ppem = MAX (font->x_ppem, font->y_ppem);
+      unsigned int requested_ppem = hb_max (font->x_ppem, font->y_ppem);
       if (!requested_ppem)
-        requested_ppem = 1<<30; /* Choose largest strike. */
+       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;
@@ -201,7 +201,7 @@ struct sbix
       HBUINT8  signature[8];
       struct
       {
-        struct
+       struct
        {
          HBUINT32      length;
          Tag           type;
@@ -226,7 +226,7 @@ struct sbix
       /* Following code is safe to call even without data.
        * But faster to short-circuit. */
       if (!has_data ())
-        return false;
+       return false;
 
       int x_offset = 0, y_offset = 0;
       unsigned int strike_ppem = 0;
@@ -235,18 +235,25 @@ struct sbix
       const PNGHeader &png = *blob->as<PNGHeader>();
 
       extents->x_bearing = x_offset;
-      extents->y_bearing = y_offset;
+      extents->y_bearing = png.IHDR.height + y_offset;
       extents->width     = png.IHDR.width;
-      extents->height    = png.IHDR.height;
+      extents->height    = -png.IHDR.height;
 
       /* Convert to font units. */
       if (strike_ppem)
       {
-       double scale = font->face->get_upem () / (double) strike_ppem;
-       extents->x_bearing = round (extents->x_bearing * scale);
-       extents->y_bearing = round (extents->y_bearing * scale);
-       extents->width = round (extents->width * scale);
-       extents->height = round (extents->height * scale);
+       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);
index 6e8eddf..926d61e 100644 (file)
@@ -62,7 +62,7 @@ struct SVGDocumentIndexEntry
                                 * this index entry. */
   HBUINT16     endGlyphID;     /* The last glyph ID in the range described by
                                 * this index entry. Must be >= startGlyphID. */
-  LNNOffsetTo<UnsizedArrayOf<HBUINT8> >
+  LNNOffsetTo<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.
@@ -107,7 +107,7 @@ struct SVG
 
   protected:
   HBUINT16     version;        /* Table version (starting at 0). */
-  LOffsetTo<SortedArrayOf<SVGDocumentIndexEntry> >
+  LOffsetTo<SortedArrayOf<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. */
index 791135b..0e7203a 100644 (file)
  * Google Author(s): Sascha Brawer, Behdad Esfahbod
  */
 
-#include "hb-open-type.hh"
+#include "hb.hh"
+
+#ifndef HB_NO_COLOR
+
+#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 "hb-ot-face.hh"
-#include "hb-ot.h"
 
 #include <stdlib.h>
 #include <string.h>
 
-#include "hb-ot-layout.hh"
-
 
 /**
  * SECTION:hb-ot-color
@@ -47,6 +48,8 @@
  * @include: hb-ot.h
  *
  * Functions for fetching color-font information from OpenType font faces.
+ *
+ * HarfBuzz supports `COLR`/`CPAL`, `sbix`, `CBDT`, and `SVG` color fonts.
  **/
 
 
 
 /**
  * hb_ot_color_has_palettes:
- * @face: a font face.
+ * @face: #hb_face_t to work upon
+ *
+ * Tests whether a face includes a `CPAL` color-palette table.
  *
- * Returns: whether CPAL table is available.
+ * Return value: true if data found, false otherwise
  *
  * Since: 2.1.0
  */
@@ -71,10 +76,11 @@ hb_ot_color_has_palettes (hb_face_t *face)
 
 /**
  * hb_ot_color_palette_get_count:
- * @face: a font face.
+ * @face: #hb_face_t to work upon
  *
- * Returns: the number of color palettes in @face, or zero if @face has
- * no colors.
+ * Fetches the number of color palettes in a face.
+ *
+ * Return value: the number of palettes found
  *
  * Since: 2.1.0
  */
@@ -86,13 +92,16 @@ hb_ot_color_palette_get_count (hb_face_t *face)
 
 /**
  * hb_ot_color_palette_get_name_id:
- * @face:    a font face.
- * @palette_index: the index of the color palette whose name is being requested.
+ * @face: #hb_face_t to work upon
+ * @palette_index: The index of the color palette 
+ *
+ * Fetches the `name` table Name ID that provides display names for
+ * a `CPAL` color palette. 
  *
- * Retrieves the name id of a color palette. For example, a color font can
- * have themed palettes like "Spring", "Summer", "Fall", and "Winter".
+ * Palette display names can be generic (e.g., "Default") or provide
+ * specific, themed names (e.g., "Spring", "Summer", "Fall", and "Winter").
  *
- * Returns: an identifier within @face's `name` table.
+ * Return value: the Named ID found for the palette. 
  * If the requested palette has no name the result is #HB_OT_NAME_ID_INVALID.
  *
  * Since: 2.1.0
@@ -106,10 +115,16 @@ hb_ot_color_palette_get_name_id (hb_face_t *face,
 
 /**
  * hb_ot_color_palette_color_get_name_id:
- * @face:        a font face.
- * @color_index: palette entry index.
+ * @face: #hb_face_t to work upon
+ * @color_index: The index of the color
  *
- * Returns: Name ID associated with a palette entry, e.g. eye color
+ * Fetches the `name` table Name ID that provides display names for
+ * the specificed color in a face's `CPAL` color palette. 
+ *
+ * Display names can be generic (e.g., "Background") or specific
+ * (e.g., "Eye color").
+ *
+ * Return value: the Name ID found for the color.
  *
  * Since: 2.1.0
  */
@@ -122,10 +137,12 @@ hb_ot_color_palette_color_get_name_id (hb_face_t *face,
 
 /**
  * hb_ot_color_palette_get_flags:
- * @face:          a font face
- * @palette_index: the index of the color palette whose flags are being requested
+ * @face: #hb_face_t to work upon
+ * @palette_index: The index of the color palette
+ *
+ * Fetches the flags defined for a color palette.
  *
- * Returns: the flags for the requested color palette.
+ * Return value: the #hb_ot_color_palette_flags_t of the requested color palette
  *
  * Since: 2.1.0
  */
@@ -138,25 +155,22 @@ hb_ot_color_palette_get_flags (hb_face_t *face,
 
 /**
  * hb_ot_color_palette_get_colors:
- * @face:         a font face.
- * @palette_index:the index of the color palette whose colors
- *                are being requested.
- * @start_offset: the index of the first color being requested.
- * @color_count:  (inout) (optional): on input, how many colors
- *                can be maximally stored into the @colors array;
- *                on output, how many colors were actually stored.
- * @colors: (array length=color_count) (out) (optional):
- *                an array of #hb_color_t records. After calling
- *                this function, @colors will be filled with
- *                the palette colors. If @colors is NULL, the function
- *                will just return the number of total colors
- *                without storing any actual colors; this can be used
- *                for allocating a buffer of suitable size before calling
- *                hb_ot_color_palette_get_colors() a second time.
- *
- * Retrieves the colors in a color palette.
- *
- * Returns: the total number of colors in the palette.
+ * @face: #hb_face_t to work upon
+ * @palette_index: the index of the color palette to query
+ * @start_offset: offset of the first color to retrieve
+ * @color_count: (inout) (optional): Input = the maximum number of colors to return;
+ *               Output = the actual number of colors returned (may be zero)
+ * @colors: (out) (array length=color_count) (nullable): The array of #hb_color_t records found
+ *
+ * Fetches a list of the colors in a color palette.
+ *
+ * After calling this function, @colors will be filled with the palette
+ * colors. If @colors is NULL, the function will just return the number
+ * of total colors without storing any actual colors; this can be used
+ * for allocating a buffer of suitable size before calling
+ * hb_ot_color_palette_get_colors() a second time.
+ *
+ * Return value: the total number of colors in the palette
  *
  * Since: 2.1.0
  */
@@ -177,9 +191,11 @@ hb_ot_color_palette_get_colors (hb_face_t     *face,
 
 /**
  * hb_ot_color_has_layers:
- * @face: a font face.
+ * @face: #hb_face_t to work upon
+ *
+ * Tests whether a face includes any `COLR` color layers.
  *
- * Returns: whether COLR table is available.
+ * Return value: true if data found, false otherwise
  *
  * Since: 2.1.0
  */
@@ -191,14 +207,17 @@ hb_ot_color_has_layers (hb_face_t *face)
 
 /**
  * hb_ot_color_glyph_get_layers:
- * @face:         a font face.
- * @glyph:        a layered color glyph id.
- * @start_offset: starting offset of layers.
- * @count:  (inout) (optional): gets number of layers available to be written on buffer
- *                             and returns number of written layers.
- * @layers: (array length=count) (out) (optional): layers buffer to buffer.
+ * @face: #hb_face_t to work upon
+ * @glyph: The glyph index to query
+ * @start_offset: offset of the first layer to retrieve
+ * @layer_count: (inout) (optional): Input = the maximum number of layers to return;
+ *         Output = the actual number of layers returned (may be zero)
+ * @layers: (out) (array length=layer_count) (nullable): The array of layers found
+ *
+ * Fetches a list of all color layers for the specified glyph index in the specified
+ * face. The list returned will begin at the offset provided.
  *
- * Returns: Total number of layers a layered color glyph have.
+ * Return value: Total number of layers available for the glyph index queried
  *
  * Since: 2.1.0
  */
@@ -206,10 +225,10 @@ unsigned int
 hb_ot_color_glyph_get_layers (hb_face_t           *face,
                              hb_codepoint_t       glyph,
                              unsigned int         start_offset,
-                             unsigned int        *count, /* IN/OUT.  May be NULL. */
+                             unsigned int        *layer_count, /* IN/OUT.  May be NULL. */
                              hb_ot_color_layer_t *layers /* OUT.     May be NULL. */)
 {
-  return face->table.COLR->get_glyph_layers (glyph, start_offset, count, layers);
+  return face->table.COLR->get_glyph_layers (glyph, start_offset, layer_count, layers);
 }
 
 
@@ -219,11 +238,11 @@ hb_ot_color_glyph_get_layers (hb_face_t           *face,
 
 /**
  * hb_ot_color_has_svg:
- * @face: a font face.
+ * @face: #hb_face_t to work upon.
  *
- * Check whether @face has SVG glyph images.
+ * Tests whether a face includes any `SVG` glyph images.
  *
- * Returns true if available, false otherwise.
+ * Return value: true if data found, false otherwise.
  *
  * Since: 2.1.0
  */
@@ -235,12 +254,12 @@ hb_ot_color_has_svg (hb_face_t *face)
 
 /**
  * hb_ot_color_glyph_reference_svg:
- * @face:  a font face.
- * @glyph: a svg glyph index.
+ * @face: #hb_face_t to work upon
+ * @glyph: a svg glyph index
  *
- * Get SVG document for a glyph. The blob may be either plain text or gzip-encoded.
+ * Fetches the SVG document for a glyph. The blob may be either plain text or gzip-encoded.
  *
- * Returns: (transfer full): respective svg blob of the glyph, if available.
+ * Return value: (transfer full): An #hb_blob_t containing the SVG document of the glyph, if available
  *
  * Since: 2.1.0
  */
@@ -257,11 +276,11 @@ hb_ot_color_glyph_reference_svg (hb_face_t *face, hb_codepoint_t glyph)
 
 /**
  * hb_ot_color_has_png:
- * @face: a font face.
+ * @face: #hb_face_t to work upon
  *
- * Check whether @face has PNG glyph images (either CBDT or sbix tables).
+ * Tests whether a face has PNG glyph images (either in `CBDT` or `sbix` tables).
  *
- * Returns true if available, false otherwise.
+ * Return value: true if data found, false otherwise
  *
  * Since: 2.1.0
  */
@@ -273,14 +292,14 @@ hb_ot_color_has_png (hb_face_t *face)
 
 /**
  * hb_ot_color_glyph_reference_png:
- * @font:  a font object, not face. upem should be set on
- *        that font object if one wants to get optimal png blob, otherwise
- *        return the biggest one
- * @glyph: a glyph index.
+ * @font: #hb_font_t to work upon
+ * @glyph: a glyph index
  *
- * Get PNG image for a glyph.
+ * Fetches the PNG image for a glyph. This function takes a font object, not a face object,
+ * as input. To get an optimally sized PNG blob, the UPEM value must be set on the @font
+ * object. If UPEM is unset, the blob returned will be the largest PNG available.
  *
- * Returns: (transfer full): respective PNG blob of the glyph, if available.
+ * Return value: (transfer full): An #hb_blob_t containing the PNG image for the glyph, if available
  *
  * Since: 2.1.0
  */
@@ -297,3 +316,6 @@ hb_ot_color_glyph_reference_png (hb_font_t *font, hb_codepoint_t  glyph)
 
   return blob;
 }
+
+
+#endif
index 49646bf..63ef20a 100644 (file)
@@ -59,11 +59,11 @@ hb_ot_color_palette_color_get_name_id (hb_face_t *face,
 
 /**
  * hb_ot_color_palette_flags_t:
- * @HB_OT_COLOR_PALETTE_FLAG_DEFAULT: default indicating that there is nothing special
+ * @HB_OT_COLOR_PALETTE_FLAG_DEFAULT: Default indicating that there is nothing special
  *   to note about a color palette.
- * @HB_OT_COLOR_PALETTE_FLAG_USABLE_WITH_LIGHT_BACKGROUND: flag indicating that the color
+ * @HB_OT_COLOR_PALETTE_FLAG_USABLE_WITH_LIGHT_BACKGROUND: Flag indicating that the color
  *   palette is appropriate to use when displaying the font on a light background such as white.
- * @HB_OT_COLOR_PALETTE_FLAG_USABLE_WITH_DARK_BACKGROUND: flag indicating that the color
+ * @HB_OT_COLOR_PALETTE_FLAG_USABLE_WITH_DARK_BACKGROUND: Flag indicating that the color
  *   palette is appropriate to use when displaying the font on a dark background such as black.
  *
  * Since: 2.1.0
@@ -110,7 +110,7 @@ HB_EXTERN unsigned int
 hb_ot_color_glyph_get_layers (hb_face_t           *face,
                              hb_codepoint_t       glyph,
                              unsigned int         start_offset,
-                             unsigned int        *count, /* IN/OUT.  May be NULL. */
+                             unsigned int        *layer_count, /* IN/OUT.  May be NULL. */
                              hb_ot_color_layer_t *layers /* OUT.     May be NULL. */);
 
 /*
index bce51b7..bc72f8a 100644 (file)
@@ -40,6 +40,10 @@ HB_BEGIN_DECLS
 #ifndef HB_DISABLE_DEPRECATED
 
 
+/* https://github.com/harfbuzz/harfbuzz/issues/1734 */
+#define HB_MATH_GLYPH_PART_FLAG_EXTENDER HB_OT_MATH_GLYPH_PART_FLAG_EXTENDER
+
+
 /* 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_ot_layout_table_choose_script (hb_face_t      *face,
diff --git a/src/hb-ot-face-table-list.hh b/src/hb-ot-face-table-list.hh
new file mode 100644 (file)
index 0000000..6fa9baf
--- /dev/null
@@ -0,0 +1,139 @@
+/*
+ * Copyright © 2007,2008,2009  Red Hat, Inc.
+ * Copyright © 2012,2013  Google, Inc.
+ * Copyright © 2019, Facebook 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
+ * Facebook Author(s): Behdad Esfahbod
+ */
+
+#ifndef HB_OT_FACE_TABLE_LIST_HH
+#define HB_OT_FACE_TABLE_LIST_HH
+#endif /* HB_OT_FACE_TABLE_LIST_HH */ /* Dummy header guards */
+
+#ifndef HB_OT_ACCELERATOR
+#define HB_OT_ACCELERATOR(Namespace, Type) HB_OT_TABLE (Namespace, Type)
+#define _HB_OT_ACCELERATOR_UNDEF
+#endif
+
+
+/* This lists font tables that the hb_face_t will contain and lazily
+ * load.  Don't add a table unless it's used though.  This is not
+ * exactly free. */
+
+/* v--- Add new tables in the right place here. */
+
+
+/* OpenType fundamentals. */
+HB_OT_TABLE (OT, head)
+#if !defined(HB_NO_FACE_COLLECT_UNICODES) || !defined(HB_NO_OT_FONT)
+HB_OT_ACCELERATOR (OT, cmap)
+#endif
+HB_OT_TABLE (OT, hhea)
+HB_OT_ACCELERATOR (OT, hmtx)
+HB_OT_TABLE (OT, OS2)
+#if !defined(HB_NO_OT_FONT_GLYPH_NAMES) || !defined(HB_NO_METRICS)
+HB_OT_ACCELERATOR (OT, post)
+#endif
+#ifndef HB_NO_NAME
+HB_OT_ACCELERATOR (OT, name)
+#endif
+#ifndef HB_NO_STAT
+HB_OT_TABLE (OT, STAT)
+#endif
+#ifndef HB_NO_META
+HB_OT_ACCELERATOR (OT, meta)
+#endif
+
+/* Vertical layout. */
+HB_OT_TABLE (OT, vhea)
+HB_OT_ACCELERATOR (OT, vmtx)
+
+/* TrueType outlines. */
+HB_OT_ACCELERATOR (OT, glyf)
+
+/* CFF outlines. */
+#ifndef HB_NO_CFF
+HB_OT_ACCELERATOR (OT, cff1)
+HB_OT_ACCELERATOR (OT, cff2)
+HB_OT_TABLE (OT, VORG)
+#endif
+
+/* OpenType variations. */
+#ifndef HB_NO_VAR
+HB_OT_TABLE (OT, fvar)
+HB_OT_TABLE (OT, avar)
+HB_OT_ACCELERATOR (OT, gvar)
+HB_OT_TABLE (OT, MVAR)
+#endif
+
+/* Legacy kern. */
+#ifndef HB_NO_OT_KERN
+HB_OT_TABLE (OT, kern)
+#endif
+
+/* OpenType shaping. */
+#ifndef HB_NO_OT_LAYOUT
+HB_OT_ACCELERATOR (OT, GDEF)
+HB_OT_ACCELERATOR (OT, GSUB)
+HB_OT_ACCELERATOR (OT, GPOS)
+//HB_OT_TABLE (OT, JSTF)
+#endif
+
+/* OpenType baseline. */
+#ifndef HB_NO_BASE
+HB_OT_TABLE (OT, BASE)
+#endif
+
+/* AAT shaping. */
+#ifndef HB_NO_AAT
+HB_OT_TABLE (AAT, morx)
+HB_OT_TABLE (AAT, mort)
+HB_OT_TABLE (AAT, kerx)
+HB_OT_TABLE (AAT, ankr)
+HB_OT_TABLE (AAT, trak)
+HB_OT_TABLE (AAT, lcar)
+HB_OT_TABLE (AAT, ltag)
+HB_OT_TABLE (AAT, feat)
+// HB_OT_TABLE (AAT, opbd)
+#endif
+
+/* OpenType color fonts. */
+#ifndef HB_NO_COLOR
+HB_OT_TABLE (OT, COLR)
+HB_OT_TABLE (OT, CPAL)
+HB_OT_ACCELERATOR (OT, CBDT)
+HB_OT_ACCELERATOR (OT, sbix)
+HB_OT_ACCELERATOR (OT, SVG)
+#endif
+
+/* OpenType math. */
+#ifndef HB_NO_MATH
+HB_OT_TABLE (OT, MATH)
+#endif
+
+
+#ifdef _HB_OT_ACCELERATOR_UNDEF
+#undef HB_OT_ACCELERATOR
+#endif
index 9b17526..5ef8df4 100644 (file)
@@ -32,6 +32,7 @@
 #include "hb-ot-cff2-table.hh"
 #include "hb-ot-hmtx-table.hh"
 #include "hb-ot-kern-table.hh"
+#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"
@@ -46,16 +47,12 @@ void hb_ot_face_t::init0 (hb_face_t *face)
 {
   this->face = face;
 #define HB_OT_TABLE(Namespace, Type) Type.init0 ();
-#define HB_OT_ACCELERATOR(Namespace, Type) HB_OT_TABLE (Namespace, Type)
-  HB_OT_TABLES
-#undef HB_OT_ACCELERATOR
+#include "hb-ot-face-table-list.hh"
 #undef HB_OT_TABLE
 }
 void hb_ot_face_t::fini ()
 {
 #define HB_OT_TABLE(Namespace, Type) Type.fini ();
-#define HB_OT_ACCELERATOR(Namespace, Type) HB_OT_TABLE (Namespace, Type)
-  HB_OT_TABLES
-#undef HB_OT_ACCELERATOR
+#include "hb-ot-face-table-list.hh"
 #undef HB_OT_TABLE
 }
index 7f47ba6..e24d380 100644 (file)
  * hb_ot_face_t
  */
 
-#define HB_OT_TABLES \
-    /* OpenType fundamentals. */ \
-    HB_OT_TABLE(OT, head) \
-    HB_OT_ACCELERATOR(OT, cmap) \
-    HB_OT_ACCELERATOR(OT, hmtx) \
-    HB_OT_ACCELERATOR(OT, vmtx) \
-    HB_OT_ACCELERATOR(OT, post) \
-    HB_OT_TABLE(OT, kern) \
-    HB_OT_ACCELERATOR(OT, glyf) \
-    HB_OT_ACCELERATOR(OT, cff1) \
-    HB_OT_ACCELERATOR(OT, cff2) \
-    HB_OT_TABLE(OT, VORG) \
-    HB_OT_ACCELERATOR(OT, name) \
-    HB_OT_TABLE(OT, OS2) \
-    HB_OT_TABLE(OT, STAT) \
-    /* OpenType shaping. */ \
-    HB_OT_ACCELERATOR(OT, GDEF) \
-    HB_OT_ACCELERATOR(OT, GSUB) \
-    HB_OT_ACCELERATOR(OT, GPOS) \
-    HB_OT_TABLE(OT, BASE) \
-    HB_OT_TABLE(OT, JSTF) \
-    /* AAT shaping. */ \
-    HB_OT_TABLE(AAT, mort) \
-    HB_OT_TABLE(AAT, morx) \
-    HB_OT_TABLE(AAT, kerx) \
-    HB_OT_TABLE(AAT, ankr) \
-    HB_OT_TABLE(AAT, trak) \
-    HB_OT_TABLE(AAT, lcar) \
-    HB_OT_TABLE(AAT, ltag) \
-    HB_OT_TABLE(AAT, feat) \
-    /* OpenType variations. */ \
-    HB_OT_TABLE(OT, fvar) \
-    HB_OT_TABLE(OT, avar) \
-    HB_OT_TABLE(OT, MVAR) \
-    /* OpenType math. */ \
-    HB_OT_TABLE(OT, MATH) \
-    /* OpenType color fonts. */ \
-    HB_OT_TABLE(OT, COLR) \
-    HB_OT_TABLE(OT, CPAL) \
-    HB_OT_ACCELERATOR(OT, CBDT) \
-    HB_OT_ACCELERATOR(OT, sbix) \
-    HB_OT_ACCELERATOR(OT, SVG) \
-    /* */
-
 /* Declare tables. */
 #define HB_OT_TABLE(Namespace, Type) namespace Namespace { struct Type; }
 #define HB_OT_ACCELERATOR(Namespace, Type) HB_OT_TABLE (Namespace, Type##_accelerator_t)
-HB_OT_TABLES
+#include "hb-ot-face-table-list.hh"
 #undef HB_OT_ACCELERATOR
 #undef HB_OT_TABLE
 
@@ -100,9 +56,7 @@ struct hb_ot_face_t
   {
     ORDER_ZERO,
 #define HB_OT_TABLE(Namespace, Type) HB_OT_TABLE_ORDER (Namespace, Type),
-#define HB_OT_ACCELERATOR(Namespace, Type) HB_OT_TABLE (Namespace, Type)
-    HB_OT_TABLES
-#undef HB_OT_ACCELERATOR
+#include "hb-ot-face-table-list.hh"
 #undef HB_OT_TABLE
   };
 
@@ -111,7 +65,7 @@ struct hb_ot_face_t
   hb_table_lazy_loader_t<Namespace::Type, HB_OT_TABLE_ORDER (Namespace, Type)> Type;
 #define HB_OT_ACCELERATOR(Namespace, Type) \
   hb_face_lazy_loader_t<Namespace::Type##_accelerator_t, HB_OT_TABLE_ORDER (Namespace, Type)> Type;
-  HB_OT_TABLES
+#include "hb-ot-face-table-list.hh"
 #undef HB_OT_ACCELERATOR
 #undef HB_OT_TABLE
 };
index 94a9fdc..96f94e4 100644 (file)
@@ -26,6 +26,8 @@
 
 #include "hb.hh"
 
+#ifndef HB_NO_OT_FONT
+
 #include "hb-ot.h"
 
 #include "hb-font.hh"
@@ -37,7 +39,6 @@
 #include "hb-ot-cff1-table.hh"
 #include "hb-ot-cff2-table.hh"
 #include "hb-ot-hmtx-table.hh"
-#include "hb-ot-kern-table.hh"
 #include "hb-ot-os2-table.hh"
 #include "hb-ot-post-table.hh"
 #include "hb-ot-stat-table.hh" // Just so we compile it; unused otherwise.
@@ -149,19 +150,21 @@ hb_ot_get_glyph_v_origin (hb_font_t *font,
 
   *x = font->get_glyph_h_advance (glyph) / 2;
 
+#ifndef HB_NO_OT_FONT_CFF
   const OT::VORG &VORG = *ot_face->VORG;
   if (VORG.has_data ())
   {
     *y = font->em_scale_y (VORG.get_y_origin (glyph));
     return true;
   }
+#endif
 
   hb_glyph_extents_t extents = {0};
-  if (ot_face->glyf->get_extents (glyph, &extents))
+  if (ot_face->glyf->get_extents (font, glyph, &extents))
   {
     const OT::vmtx_accelerator_t &vmtx = *ot_face->vmtx;
-    hb_position_t tsb = vmtx.get_side_bearing (glyph);
-    *y = font->em_scale_y (extents.y_bearing + tsb);
+    hb_position_t tsb = vmtx.get_side_bearing (font, glyph);
+    *y = extents.y_bearing + font->em_scale_y (tsb);
     return true;
   }
 
@@ -180,73 +183,67 @@ hb_ot_get_glyph_extents (hb_font_t *font,
                         void *user_data HB_UNUSED)
 {
   const hb_ot_face_t *ot_face = (const hb_ot_face_t *) font_data;
-  bool ret = ot_face->sbix->get_extents (font, glyph, extents);
-  if (!ret)
-    ret = ot_face->glyf->get_extents (glyph, extents);
-  if (!ret)
-    ret = ot_face->cff1->get_extents (glyph, extents);
-  if (!ret)
-    ret = ot_face->cff2->get_extents (font, glyph, extents);
-  if (!ret)
-    ret = ot_face->CBDT->get_extents (font, glyph, extents);
+  bool ret = false;
+
+#if !defined(HB_NO_OT_FONT_BITMAP) && !defined(HB_NO_COLOR)
+  if (!ret) ret = ot_face->sbix->get_extents (font, glyph, extents);
+#endif
+  if (!ret) ret = ot_face->glyf->get_extents (font, glyph, extents);
+#ifndef HB_NO_OT_FONT_CFF
+  if (!ret) ret = ot_face->cff1->get_extents (font, glyph, extents);
+  if (!ret) ret = ot_face->cff2->get_extents (font, glyph, extents);
+#endif
+#if !defined(HB_NO_OT_FONT_BITMAP) && !defined(HB_NO_COLOR)
+  if (!ret) ret = ot_face->CBDT->get_extents (font, glyph, extents);
+#endif
+
   // TODO Hook up side-bearings variations.
-  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);
   return ret;
 }
 
+#ifndef HB_NO_OT_FONT_GLYPH_NAMES
 static hb_bool_t
 hb_ot_get_glyph_name (hb_font_t *font HB_UNUSED,
-                      void *font_data,
-                      hb_codepoint_t glyph,
-                      char *name, unsigned int size,
-                      void *user_data HB_UNUSED)
+                     void *font_data,
+                     hb_codepoint_t glyph,
+                     char *name, unsigned int size,
+                     void *user_data HB_UNUSED)
 {
   const hb_ot_face_t *ot_face = (const hb_ot_face_t *) font_data;
   return ot_face->post->get_glyph_name (glyph, name, size);
 }
-
 static hb_bool_t
 hb_ot_get_glyph_from_name (hb_font_t *font HB_UNUSED,
-                           void *font_data,
-                           const char *name, int len,
-                           hb_codepoint_t *glyph,
-                           void *user_data HB_UNUSED)
+                          void *font_data,
+                          const char *name, int len,
+                          hb_codepoint_t *glyph,
+                          void *user_data HB_UNUSED)
 {
   const hb_ot_face_t *ot_face = (const hb_ot_face_t *) font_data;
   return ot_face->post->get_glyph_from_name (name, len, glyph);
 }
+#endif
 
 static hb_bool_t
 hb_ot_get_font_h_extents (hb_font_t *font,
-                         void *font_data,
+                         void *font_data HB_UNUSED,
                          hb_font_extents_t *metrics,
                          void *user_data HB_UNUSED)
 {
-  const hb_ot_face_t *ot_face = (const hb_ot_face_t *) font_data;
-  const OT::hmtx_accelerator_t &hmtx = *ot_face->hmtx;
-  metrics->ascender = font->em_scale_y (hmtx.ascender);
-  metrics->descender = font->em_scale_y (hmtx.descender);
-  metrics->line_gap = font->em_scale_y (hmtx.line_gap);
-  // TODO Hook up variations.
-  return hmtx.has_font_extents;
+  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);
 }
 
 static hb_bool_t
 hb_ot_get_font_v_extents (hb_font_t *font,
-                         void *font_data,
+                         void *font_data HB_UNUSED,
                          hb_font_extents_t *metrics,
                          void *user_data HB_UNUSED)
 {
-  const hb_ot_face_t *ot_face = (const hb_ot_face_t *) font_data;
-  const OT::vmtx_accelerator_t &vmtx = *ot_face->vmtx;
-  metrics->ascender = font->em_scale_x (vmtx.ascender);
-  metrics->descender = font->em_scale_x (vmtx.descender);
-  metrics->line_gap = font->em_scale_x (vmtx.line_gap);
-  // TODO Hook up variations.
-  return vmtx.has_font_extents;
+  return _hb_ot_metrics_get_position_common (font, HB_OT_METRICS_TAG_VERTICAL_ASCENDER, &metrics->ascender) &&
+        _hb_ot_metrics_get_position_common (font, HB_OT_METRICS_TAG_VERTICAL_DESCENDER, &metrics->descender) &&
+        _hb_ot_metrics_get_position_common (font, HB_OT_METRICS_TAG_VERTICAL_LINE_GAP, &metrics->line_gap);
 }
 
 #if HB_USE_ATEXIT
@@ -270,8 +267,10 @@ static struct hb_ot_font_funcs_lazy_loader_t : hb_font_funcs_lazy_loader_t<hb_ot
     hb_font_funcs_set_glyph_v_origin_func (funcs, hb_ot_get_glyph_v_origin, nullptr, nullptr);
     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);
+#ifndef HB_NO_OT_FONT_GLYPH_NAMES
     hb_font_funcs_set_glyph_name_func (funcs, hb_ot_get_glyph_name, nullptr, nullptr);
     hb_font_funcs_set_glyph_from_name_func (funcs, hb_ot_get_glyph_from_name, nullptr, nullptr);
+#endif
 
     hb_font_funcs_make_immutable (funcs);
 
@@ -311,3 +310,20 @@ hb_ot_font_set_funcs (hb_font_t *font)
                     &font->face->table,
                     nullptr);
 }
+
+#ifndef HB_NO_VAR
+int
+_glyf_get_side_bearing_var (hb_font_t *font, hb_codepoint_t glyph, bool is_vertical)
+{
+  return font->face->table.glyf->get_side_bearing_var (font, glyph, is_vertical);
+}
+
+unsigned
+_glyf_get_advance_var (hb_font_t *font, hb_codepoint_t glyph, bool is_vertical)
+{
+  return font->face->table.glyf->get_advance_var (font, glyph, is_vertical);
+}
+#endif
+
+
+#endif
index c2b38b0..571e50e 100644 (file)
@@ -1,5 +1,7 @@
 /*
  * Copyright © 2015  Google, Inc.
+ * Copyright © 2019  Adobe Inc.
+ * Copyright © 2019  Ebrahim Byagowi
  *
  *  This is part of HarfBuzz, a text shaping library.
  *
@@ -21,7 +23,8 @@
  * 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
+ * Google Author(s): Behdad Esfahbod, Garret Rieger, Roderick Sheeter
+ * Adobe Author(s): Michiharu Ariza
  */
 
 #ifndef HB_OT_GLYF_TABLE_HH
 
 #include "hb-open-type.hh"
 #include "hb-ot-head-table.hh"
-#include "hb-subset-glyf.hh"
+#include "hb-ot-hmtx-table.hh"
+#include "hb-ot-var-gvar-table.hh"
+
+#include <float.h>
 
 namespace OT {
 
@@ -54,11 +60,12 @@ struct loca
   }
 
   protected:
-  UnsizedArrayOf<HBUINT8>      dataZ;          /* Location data. */
+  UnsizedArrayOf<HBUINT8>
+               dataZ;  /* Location data. */
   public:
-  DEFINE_SIZE_MIN (0); /* In reality, this is UNBOUNDED() type; but since we always
-                       * check the size externally, allow Null() object of it by
-                       * defining it MIN() instead. */
+  DEFINE_SIZE_MIN (0); /* In reality, this is UNBOUNDED() type; but since we always
+                        * check the size externally, allow Null() object of it by
+                        * defining it _MIN instead. */
 };
 
 
@@ -76,29 +83,128 @@ struct glyf
   bool sanitize (hb_sanitize_context_t *c HB_UNUSED) const
   {
     TRACE_SANITIZE (this);
-    /* We don't check for anything specific here.  The users of the
-     * struct do all the hard work... */
+    /* Runtime checks as eager sanitizing each glyph is costy */
     return_trace (true);
   }
 
-  bool subset (hb_subset_plan_t *plan) const
+  template<typename Iterator,
+          hb_requires (hb_is_source_of (Iterator, unsigned int))>
+  static bool
+  _add_loca_and_head (hb_subset_plan_t * plan, Iterator padded_offsets)
   {
-    hb_blob_t *glyf_prime = nullptr;
-    hb_blob_t *loca_prime = nullptr;
-
-    bool success = true;
-    bool use_short_loca = false;
-    if (hb_subset_glyf_and_loca (plan, &use_short_loca, &glyf_prime, &loca_prime)) {
-      success = success && plan->add_table (HB_OT_TAG_glyf, glyf_prime);
-      success = success && plan->add_table (HB_OT_TAG_loca, loca_prime);
-      success = success && _add_head_and_set_loca_version (plan, use_short_loca);
-    } else {
-      success = false;
-    }
-    hb_blob_destroy (loca_prime);
-    hb_blob_destroy (glyf_prime);
+    unsigned max_offset = + padded_offsets | hb_reduce(hb_add, 0);
+    unsigned num_offsets = padded_offsets.len () + 1;
+    bool use_short_loca = max_offset < 0x1FFFF;
+    unsigned entry_size = use_short_loca ? 2 : 4;
+    char *loca_prime_data = (char *) calloc (entry_size, num_offsets);
+
+    if (unlikely (!loca_prime_data)) return false;
+
+    DEBUG_MSG (SUBSET, nullptr, "loca entry_size %d num_offsets %d "
+                               "max_offset %d size %d",
+              entry_size, num_offsets, max_offset, entry_size * num_offsets);
+
+    if (use_short_loca)
+      _write_loca (padded_offsets, 1, hb_array ((HBUINT16*) loca_prime_data, num_offsets));
+    else
+      _write_loca (padded_offsets, 0, hb_array ((HBUINT32*) loca_prime_data, num_offsets));
+
+    hb_blob_t * loca_blob = hb_blob_create (loca_prime_data,
+                                           entry_size * num_offsets,
+                                           HB_MEMORY_MODE_WRITABLE,
+                                           loca_prime_data,
+                                           free);
+
+    bool result = plan->add_table (HB_OT_TAG_loca, loca_blob)
+                 && _add_head_and_set_loca_version (plan, use_short_loca);
+
+    hb_blob_destroy (loca_blob);
+    return result;
+  }
 
-    return success;
+  template<typename IteratorIn, typename IteratorOut,
+          hb_requires (hb_is_source_of (IteratorIn, unsigned int)),
+          hb_requires (hb_is_sink_of (IteratorOut, unsigned))>
+  static void
+  _write_loca (IteratorIn it, unsigned right_shift, IteratorOut dest)
+  {
+    unsigned int offset = 0;
+    dest << 0;
+    + it
+    | hb_map ([=, &offset] (unsigned int padded_size)
+             {
+               offset += padded_size;
+               DEBUG_MSG (SUBSET, nullptr, "loca entry offset %d", offset);
+               return offset >> right_shift;
+             })
+    | hb_sink (dest)
+    ;
+  }
+
+  /* requires source of SubsetGlyph complains the identifier isn't declared */
+  template <typename Iterator>
+  bool serialize (hb_serialize_context_t *c,
+                 Iterator it,
+                 const hb_subset_plan_t *plan)
+  {
+    TRACE_SERIALIZE (this);
+    for (const auto &_ : it) _.serialize (c, plan);
+    return_trace (true);
+  }
+
+  /* Byte region(s) per glyph to output
+     unpadded, hints removed if so requested
+     If we fail to process a glyph we produce an empty (0-length) glyph */
+  bool subset (hb_subset_context_t *c) const
+  {
+    TRACE_SUBSET (this);
+
+    glyf *glyf_prime = c->serializer->start_embed <glyf> ();
+    if (unlikely (!c->serializer->check_success (glyf_prime))) return_trace (false);
+
+    hb_vector_t<SubsetGlyph> glyphs;
+    _populate_subset_glyphs (c->plan, &glyphs);
+
+    glyf_prime->serialize (c->serializer, hb_iter (glyphs), c->plan);
+
+    auto padded_offsets =
+    + hb_iter (glyphs)
+    | hb_map (&SubsetGlyph::padded_size)
+    ;
+
+    if (c->serializer->in_error ()) return_trace (false);
+    return_trace (c->serializer->check_success (_add_loca_and_head (c->plan,
+                                                                   padded_offsets)));
+  }
+
+  template <typename SubsetGlyph>
+  void
+  _populate_subset_glyphs (const hb_subset_plan_t   *plan,
+                          hb_vector_t<SubsetGlyph> *glyphs /* OUT */) const
+  {
+    OT::glyf::accelerator_t glyf;
+    glyf.init (plan->source);
+
+    + hb_range (plan->num_output_glyphs ())
+    | hb_map ([&] (hb_codepoint_t new_gid)
+             {
+               SubsetGlyph subset_glyph = {0};
+               subset_glyph.new_gid = new_gid;
+
+               /* should never fail: all old gids should be mapped */
+               if (!plan->old_gid_for_new_gid (new_gid, &subset_glyph.old_gid))
+                 return subset_glyph;
+
+               subset_glyph.source_glyph = glyf.glyph_for_gid (subset_glyph.old_gid, true);
+               if (plan->drop_hints) subset_glyph.drop_hints_bytes ();
+               else subset_glyph.dest_start = subset_glyph.source_glyph.get_bytes ();
+
+               return subset_glyph;
+             })
+    | hb_sink (glyphs)
+    ;
+
+    glyf.fini ();
   }
 
   static bool
@@ -112,30 +218,17 @@ struct glyf
       return false;
 
     head *head_prime = (head *) hb_blob_get_data_writable (head_prime_blob, nullptr);
-    head_prime->indexToLocFormat.set (use_short_loca ? 0 : 1);
+    head_prime->indexToLocFormat = use_short_loca ? 0 : 1;
     bool success = plan->add_table (HB_OT_TAG_head, head_prime_blob);
 
     hb_blob_destroy (head_prime_blob);
     return success;
   }
 
-  struct GlyphHeader
-  {
-    HBINT16            numberOfContours;       /* If the number of contours is
-                                                * greater than or equal to zero,
-                                                * this is a simple glyph; if negative,
-                                                * this is a composite glyph. */
-    FWORD              xMin;                   /* Minimum x for coordinate data. */
-    FWORD              yMin;                   /* Minimum y for coordinate data. */
-    FWORD              xMax;                   /* Maximum x for coordinate data. */
-    FWORD              yMax;                   /* Maximum y for coordinate data. */
-
-    DEFINE_SIZE_STATIC (10);
-  };
-
-  struct CompositeGlyphHeader
+  struct CompositeGlyphChain
   {
-    enum composite_glyph_flag_t {
+    enum composite_glyph_flag_t
+    {
       ARG_1_AND_2_ARE_WORDS =      0x0001,
       ARGS_ARE_XY_VALUES =         0x0002,
       ROUND_XY_TO_GRID =           0x0004,
@@ -150,180 +243,247 @@ struct glyf
       UNSCALED_COMPONENT_OFFSET =  0x1000
     };
 
-    HBUINT16 flags;
-    GlyphID  glyphIndex;
-
     unsigned int get_size () const
     {
       unsigned int size = min_size;
-      // arg1 and 2 are int16
+      /* arg1 and 2 are int16 */
       if (flags & ARG_1_AND_2_ARE_WORDS) size += 4;
-      // arg1 and 2 are int8
+      /* arg1 and 2 are int8 */
       else size += 2;
 
-      // One x 16 bit (scale)
+      /* One x 16 bit (scale) */
       if (flags & WE_HAVE_A_SCALE) size += 2;
-      // Two x 16 bit (xscale, yscale)
+      /* Two x 16 bit (xscale, yscale) */
       else if (flags & WE_HAVE_AN_X_AND_Y_SCALE) size += 4;
-      // Four x 16 bit (xscale, scale01, scale10, yscale)
+      /* Four x 16 bit (xscale, scale01, scale10, yscale) */
       else if (flags & WE_HAVE_A_TWO_BY_TWO) size += 8;
 
       return size;
     }
 
-    struct Iterator
+    bool is_use_my_metrics () const { return   flags & USE_MY_METRICS; }
+    bool is_anchored ()       const { return !(flags & ARGS_ARE_XY_VALUES); }
+    void get_anchor_points (unsigned int &point1, unsigned int &point2) const
     {
-      const char *glyph_start;
-      const char *glyph_end;
-      const CompositeGlyphHeader *current;
+      const HBUINT8 *p = &StructAfter<const HBUINT8> (glyphIndex);
+      if (flags & ARG_1_AND_2_ARE_WORDS)
+      {
+       point1 = ((const HBUINT16 *) p)[0];
+       point2 = ((const HBUINT16 *) p)[1];
+      }
+      else
+      {
+       point1 = p[0];
+       point2 = p[1];
+      }
+    }
 
-      bool move_to_next ()
+    void transform_points (contour_point_vector_t &points) const
+    {
+      float matrix[4];
+      contour_point_t trans;
+      if (get_transformation (matrix, trans))
       {
-       if (current->flags & CompositeGlyphHeader::MORE_COMPONENTS)
+       if (scaled_offsets ())
        {
-         const CompositeGlyphHeader *possible =
-           &StructAfter<CompositeGlyphHeader, CompositeGlyphHeader> (*current);
-         if (!in_range (possible))
-           return false;
-         current = possible;
-         return true;
+         points.translate (trans);
+         points.transform (matrix);
+       }
+       else
+       {
+         points.transform (matrix);
+         points.translate (trans);
        }
-       return false;
       }
+    }
 
-      bool in_range (const CompositeGlyphHeader *composite) const
-      {
-       return (const char *) composite >= glyph_start
-         && ((const char *) composite + CompositeGlyphHeader::min_size) <= glyph_end
-         && ((const char *) composite + composite->get_size ()) <= glyph_end;
-      }
-    };
+    protected:
+    bool scaled_offsets () const
+    { return (flags & (SCALED_COMPONENT_OFFSET | UNSCALED_COMPONENT_OFFSET)) == SCALED_COMPONENT_OFFSET; }
 
-    static bool get_iterator (const char * glyph_data,
-                             unsigned int length,
-                             CompositeGlyphHeader::Iterator *iterator /* OUT */)
+    bool get_transformation (float (&matrix)[4], contour_point_t &trans) const
     {
-      if (length < GlyphHeader::static_size)
-       return false; /* Empty glyph; zero extents. */
+      matrix[0] = matrix[3] = 1.f;
+      matrix[1] = matrix[2] = 0.f;
 
-      const GlyphHeader &glyph_header = StructAtOffset<GlyphHeader> (glyph_data, 0);
-      if (glyph_header.numberOfContours < 0)
+      int tx, ty;
+      const HBINT8 *p = &StructAfter<const HBINT8> (glyphIndex);
+      if (flags & ARG_1_AND_2_ARE_WORDS)
       {
-       const CompositeGlyphHeader *possible =
-         &StructAfter<CompositeGlyphHeader, GlyphHeader> (glyph_header);
-
-       iterator->glyph_start = glyph_data;
-       iterator->glyph_end = (const char *) glyph_data + length;
-       if (!iterator->in_range (possible))
-         return false;
-       iterator->current = possible;
-       return true;
+       tx = *(const HBINT16 *) p;
+       p += HBINT16::static_size;
+       ty = *(const HBINT16 *) p;
+       p += HBINT16::static_size;
       }
+      else
+      {
+       tx = *p++;
+       ty = *p++;
+      }
+      if (is_anchored ()) tx = ty = 0;
 
-      return false;
+      trans.init ((float) tx, (float) ty);
+
+      {
+       const F2DOT14 *points = (const F2DOT14 *) p;
+       if (flags & WE_HAVE_A_SCALE)
+       {
+         matrix[0] = matrix[3] = points[0].to_float ();
+         return true;
+       }
+       else if (flags & WE_HAVE_AN_X_AND_Y_SCALE)
+       {
+         matrix[0] = points[0].to_float ();
+         matrix[3] = points[1].to_float ();
+         return true;
+       }
+       else if (flags & WE_HAVE_A_TWO_BY_TWO)
+       {
+         matrix[0] = points[0].to_float ();
+         matrix[1] = points[1].to_float ();
+         matrix[2] = points[2].to_float ();
+         matrix[3] = points[3].to_float ();
+         return true;
+       }
+      }
+      return tx || ty;
     }
 
+    public:
+    HBUINT16   flags;
+    HBGlyphID  glyphIndex;
+    public:
     DEFINE_SIZE_MIN (4);
   };
 
-  struct accelerator_t
+  struct composite_iter_t : hb_iter_with_fallback_t<composite_iter_t, const CompositeGlyphChain &>
   {
-    void init (hb_face_t *face)
+    typedef const CompositeGlyphChain *__item_t__;
+    composite_iter_t (hb_bytes_t glyph_, __item_t__ current_) :
+      glyph (glyph_), current (current_)
+    { if (!in_range (current)) current = nullptr; }
+    composite_iter_t () : glyph (hb_bytes_t ()), current (nullptr) {}
+
+    const CompositeGlyphChain &__item__ () const { return *current; }
+    bool __more__ () const { return current; }
+    void __next__ ()
     {
-      memset (this, 0, sizeof (accelerator_t));
+      if (!(current->flags & CompositeGlyphChain::MORE_COMPONENTS)) { current = nullptr; return; }
 
-      const OT::head &head = *face->table.head;
-      if (head.indexToLocFormat > 1 || head.glyphDataFormat != 0)
-       /* Unknown format.  Leave num_glyphs=0, that takes care of disabling us. */
-       return;
-      short_offset = 0 == head.indexToLocFormat;
-
-      loca_table = hb_sanitize_context_t ().reference_table<loca> (face);
-      glyf_table = hb_sanitize_context_t ().reference_table<glyf> (face);
-
-      num_glyphs = MAX (1u, loca_table.get_length () / (short_offset ? 2 : 4)) - 1;
+      const CompositeGlyphChain *possible = &StructAfter<CompositeGlyphChain,
+                                                        CompositeGlyphChain> (*current);
+      if (!in_range (possible)) { current = nullptr; return; }
+      current = possible;
     }
+    bool operator != (const composite_iter_t& o) const
+    { return glyph != o.glyph || current != o.current; }
 
-    void fini ()
+    bool in_range (const CompositeGlyphChain *composite) const
     {
-      loca_table.destroy ();
-      glyf_table.destroy ();
+      return glyph.in_range (composite, CompositeGlyphChain::min_size)
+         && glyph.in_range (composite, composite->get_size ());
     }
 
-    /*
-     * Returns true if the referenced glyph is a valid glyph and a composite glyph.
-     * If true is returned a pointer to the composite glyph will be written into
-     * composite.
-     */
-    bool get_composite (hb_codepoint_t glyph,
-                       CompositeGlyphHeader::Iterator *composite /* OUT */) const
+    private:
+    hb_bytes_t glyph;
+    __item_t__ current;
+  };
+
+  struct Glyph
+  {
+    private:
+    struct GlyphHeader
     {
-      if (unlikely (!num_glyphs))
-       return false;
+      bool has_data () const { return numberOfContours; }
 
-      unsigned int start_offset, end_offset;
-      if (!get_offsets (glyph, &start_offset, &end_offset))
-       return false; /* glyph not found */
+      bool get_extents (hb_font_t *font, hb_codepoint_t gid, hb_glyph_extents_t *extents) const
+      {
+       /* Undocumented rasterizer behavior: shift glyph to the left by (lsb - xMin), i.e., xMin = lsb */
+       /* extents->x_bearing = hb_min (glyph_header.xMin, glyph_header.xMax); */
+       extents->x_bearing = font->em_scale_x (font->face->table.hmtx->get_side_bearing (gid));
+       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));
 
-      return CompositeGlyphHeader::get_iterator ((const char *) this->glyf_table + start_offset,
-                                                end_offset - start_offset,
-                                                composite);
-    }
+       return true;
+      }
 
-    enum simple_glyph_flag_t {
-      FLAG_ON_CURVE = 0x01,
-      FLAG_X_SHORT = 0x02,
-      FLAG_Y_SHORT = 0x04,
-      FLAG_REPEAT = 0x08,
-      FLAG_X_SAME = 0x10,
-      FLAG_Y_SAME = 0x20,
-      FLAG_RESERVED1 = 0x40,
-      FLAG_RESERVED2 = 0x80
+      HBINT16  numberOfContours;
+                       /* If the number of contours is
+                        * greater than or equal to zero,
+                        * this is a simple glyph; if negative,
+                        * this is a composite glyph. */
+      FWORD    xMin;   /* Minimum x for coordinate data. */
+      FWORD    yMin;   /* Minimum y for coordinate data. */
+      FWORD    xMax;   /* Maximum x for coordinate data. */
+      FWORD    yMax;   /* Maximum y for coordinate data. */
+      public:
+      DEFINE_SIZE_STATIC (10);
     };
 
-    /* based on FontTools _g_l_y_f.py::trim */
-    bool remove_padding (unsigned int start_offset,
-                               unsigned int *end_offset) const
+    struct SimpleGlyph
     {
-      if (*end_offset - start_offset < GlyphHeader::static_size) return true;
+      const GlyphHeader &header;
+      hb_bytes_t bytes;
+      SimpleGlyph (const GlyphHeader &header_, hb_bytes_t bytes_) :
+       header (header_), bytes (bytes_) {}
 
-      const char *glyph = ((const char *) glyf_table) + start_offset;
-      const char * const glyph_end = glyph + (*end_offset - start_offset);
-      const GlyphHeader &glyph_header = StructAtOffset<GlyphHeader> (glyph, 0);
-      int16_t num_contours = (int16_t) glyph_header.numberOfContours;
+      unsigned int instruction_len_offset () const
+      { return GlyphHeader::static_size + 2 * header.numberOfContours; }
 
-      if (num_contours < 0)
-       /* Trimming for composites not implemented.
-        * If removing hints it falls out of that. */
-       return true;
-      else if (num_contours > 0)
+      unsigned int length (unsigned int instruction_len) const
+      { return instruction_len_offset () + 2 + instruction_len; }
+
+      unsigned int instructions_length () const
+      {
+       unsigned int instruction_length_offset = instruction_len_offset ();
+       if (unlikely (instruction_length_offset + 2 > bytes.length)) return 0;
+
+       const HBUINT16 &instructionLength = StructAtOffset<HBUINT16> (&bytes, instruction_length_offset);
+       /* Out of bounds of the current glyph */
+       if (unlikely (length (instructionLength) > bytes.length)) return 0;
+       return instructionLength;
+      }
+
+      enum simple_glyph_flag_t
       {
+       FLAG_ON_CURVE  = 0x01,
+       FLAG_X_SHORT   = 0x02,
+       FLAG_Y_SHORT   = 0x04,
+       FLAG_REPEAT    = 0x08,
+       FLAG_X_SAME    = 0x10,
+       FLAG_Y_SAME    = 0x20,
+       FLAG_RESERVED1 = 0x40,
+       FLAG_RESERVED2 = 0x80
+      };
+
+      const Glyph trim_padding () const
+      {
+       /* based on FontTools _g_l_y_f.py::trim */
+       const char *glyph = bytes.arrayZ;
+       const char *glyph_end = glyph + bytes.length;
        /* simple glyph w/contours, possibly trimmable */
-       glyph += GlyphHeader::static_size + 2 * num_contours;
+       glyph += instruction_len_offset ();
 
-       if (unlikely (glyph + 2 >= glyph_end)) return false;
-       uint16_t nCoordinates = (uint16_t) StructAtOffset<HBUINT16> (glyph - 2, 0) + 1;
-       uint16_t nInstructions = (uint16_t) StructAtOffset<HBUINT16> (glyph, 0);
+       if (unlikely (glyph + 2 >= glyph_end)) return Glyph ();
+       unsigned int num_coordinates = StructAtOffset<HBUINT16> (glyph - 2, 0) + 1;
+       unsigned int num_instructions = StructAtOffset<HBUINT16> (glyph, 0);
 
-       glyph += 2 + nInstructions;
-       if (unlikely (glyph + 2 >= glyph_end)) return false;
+       glyph += 2 + num_instructions;
+       if (unlikely (glyph + 2 >= glyph_end)) return Glyph ();
 
-       unsigned int coordBytes = 0;
-       unsigned int coordsWithFlags = 0;
+       unsigned int coord_bytes = 0;
+       unsigned int coords_with_flags = 0;
        while (glyph < glyph_end)
        {
-         uint8_t flag = (uint8_t) *glyph;
+         uint8_t flag = *glyph;
          glyph++;
 
          unsigned int repeat = 1;
          if (flag & FLAG_REPEAT)
          {
-           if (glyph >= glyph_end)
-           {
-             DEBUG_MSG(SUBSET, nullptr, "Bad flag");
-             return false;
-           }
-           repeat = ((uint8_t) *glyph) + 1;
+           if (unlikely (glyph >= glyph_end)) return Glyph ();
+           repeat = *glyph + 1;
            glyph++;
          }
 
@@ -335,128 +495,548 @@ struct glyf
          if (flag & FLAG_Y_SHORT) yBytes = 1;
          else if ((flag & FLAG_Y_SAME) == 0) yBytes = 2;
 
-         coordBytes += (xBytes + yBytes) * repeat;
-         coordsWithFlags += repeat;
-         if (coordsWithFlags >= nCoordinates)
-           break;
+         coord_bytes += (xBytes + yBytes) * repeat;
+         coords_with_flags += repeat;
+         if (coords_with_flags >= num_coordinates) break;
        }
 
-       if (coordsWithFlags != nCoordinates)
+       if (unlikely (coords_with_flags != num_coordinates)) return Glyph ();
+       return Glyph (bytes.sub_array (0, bytes.length + coord_bytes - (glyph_end - glyph)));
+      }
+
+      /* zero instruction length */
+      void drop_hints ()
+      {
+       GlyphHeader &glyph_header = const_cast<GlyphHeader &> (header);
+       (HBUINT16 &) StructAtOffset<HBUINT16> (&glyph_header, instruction_len_offset ()) = 0;
+      }
+
+      void drop_hints_bytes (hb_bytes_t &dest_start, hb_bytes_t &dest_end) const
+      {
+       unsigned int instructions_len = instructions_length ();
+       unsigned int glyph_length = length (instructions_len);
+       dest_start = bytes.sub_array (0, glyph_length - instructions_len);
+       dest_end = bytes.sub_array (glyph_length, bytes.length - glyph_length);
+      }
+
+      struct x_setter_t
+      {
+       void set (contour_point_t &point, float v) const { point.x = v; }
+       bool is_short (uint8_t flag) const { return flag & FLAG_X_SHORT; }
+       bool is_same  (uint8_t flag) const { return flag & FLAG_X_SAME; }
+      };
+
+      struct y_setter_t
+      {
+       void set (contour_point_t &point, float v) const { point.y = v; }
+       bool is_short (uint8_t flag) const { return flag & FLAG_Y_SHORT; }
+       bool is_same  (uint8_t flag) const { return flag & FLAG_Y_SAME; }
+      };
+
+      template <typename T>
+      static bool read_points (const HBUINT8 *&p /* IN/OUT */,
+                              contour_point_vector_t &points_ /* IN/OUT */,
+                              const hb_bytes_t &bytes)
+      {
+       T coord_setter;
+       float v = 0;
+       for (unsigned int i = 0; i < points_.length - PHANTOM_COUNT; i++)
        {
-         DEBUG_MSG(SUBSET, nullptr, "Expect %d coords to have flags, got flags for %d", nCoordinates, coordsWithFlags);
-         return false;
+         uint8_t flag = points_[i].flag;
+         if (coord_setter.is_short (flag))
+         {
+           if (unlikely (!bytes.in_range (p))) return false;
+           if (coord_setter.is_same (flag))
+             v += *p++;
+           else
+             v -= *p++;
+         }
+         else
+         {
+           if (!coord_setter.is_same (flag))
+           {
+             if (unlikely (!bytes.in_range ((const HBUINT16 *) p))) return false;
+             v += *(const HBINT16 *) p;
+             p += HBINT16::static_size;
+           }
+         }
+         coord_setter.set (points_[i], v);
        }
-       glyph += coordBytes;
+       return true;
+      }
+
+      bool get_contour_points (contour_point_vector_t &points_ /* OUT */,
+                              hb_vector_t<unsigned int> &end_points_ /* OUT */,
+                              const bool phantom_only=false) const
+      {
+       const HBUINT16 *endPtsOfContours = &StructAfter<HBUINT16> (header);
+       int num_contours = header.numberOfContours;
+       if (unlikely (!bytes.in_range (&endPtsOfContours[num_contours + 1]))) return false;
+       unsigned int num_points = endPtsOfContours[num_contours - 1] + 1;
+
+       points_.resize (num_points + PHANTOM_COUNT);
+       for (unsigned int i = 0; i < points_.length; i++) points_[i].init ();
+       if (phantom_only) return true;
+
+       /* Read simple glyph points if !phantom_only */
+       end_points_.resize (num_contours);
+
+       for (int i = 0; i < num_contours; i++)
+         end_points_[i] = endPtsOfContours[i];
+
+       /* Skip instructions */
+       const HBUINT8 *p = &StructAtOffset<HBUINT8> (&endPtsOfContours[num_contours + 1],
+                                                    endPtsOfContours[num_contours]);
 
-       if (glyph < glyph_end)
-         *end_offset -= glyph_end - glyph;
+       /* Read flags */
+       for (unsigned int i = 0; i < num_points; i++)
+       {
+         if (unlikely (!bytes.in_range (p))) return false;
+         uint8_t flag = *p++;
+         points_[i].flag = flag;
+         if (flag & FLAG_REPEAT)
+         {
+           if (unlikely (!bytes.in_range (p))) return false;
+           unsigned int repeat_count = *p++;
+           while ((repeat_count-- > 0) && (++i < num_points))
+             points_[i].flag = flag;
+         }
+       }
+
+       /* Read x & y coordinates */
+       return (read_points<x_setter_t> (p, points_, bytes) &&
+               read_points<y_setter_t> (p, points_, bytes));
       }
-      return true;
-    }
+    };
 
-    bool get_offsets (hb_codepoint_t  glyph,
-                     unsigned int   *start_offset /* OUT */,
-                     unsigned int   *end_offset   /* OUT */) const
+    struct CompositeGlyph
     {
-      if (unlikely (glyph >= num_glyphs))
-       return false;
+      const GlyphHeader &header;
+      hb_bytes_t bytes;
+      CompositeGlyph (const GlyphHeader &header_, hb_bytes_t bytes_) :
+       header (header_), bytes (bytes_) {}
 
-      if (short_offset)
+      composite_iter_t get_iterator () const
+      { return composite_iter_t (bytes, &StructAfter<CompositeGlyphChain, GlyphHeader> (header)); }
+
+      unsigned int instructions_length (hb_bytes_t bytes) const
       {
-       const HBUINT16 *offsets = (const HBUINT16 *) loca_table->dataZ.arrayZ;
-       *start_offset = 2 * offsets[glyph];
-       *end_offset   = 2 * offsets[glyph + 1];
+       unsigned int start = bytes.length;
+       unsigned int end = bytes.length;
+       const CompositeGlyphChain *last = nullptr;
+       for (auto &item : get_iterator ())
+         last = &item;
+       if (unlikely (!last)) return 0;
+
+       if ((uint16_t) last->flags & CompositeGlyphChain::WE_HAVE_INSTRUCTIONS)
+         start = (char *) last - &bytes + last->get_size ();
+       if (unlikely (start > end)) return 0;
+       return end - start;
       }
-      else
+
+      /* Trimming for composites not implemented.
+       * If removing hints it falls out of that. */
+      const Glyph trim_padding () const { return Glyph (bytes); }
+
+      /* remove WE_HAVE_INSTRUCTIONS flag from composite glyph */
+      void drop_hints ()
       {
-       const HBUINT32 *offsets = (const HBUINT32 *) loca_table->dataZ.arrayZ;
+       for (const auto &_ : get_iterator ())
+         *const_cast<OT::HBUINT16 *> (&_.flags) = (uint16_t) _.flags & ~OT::glyf::CompositeGlyphChain::WE_HAVE_INSTRUCTIONS;
+      }
+
+      /* Chop instructions off the end */
+      void drop_hints_bytes (hb_bytes_t &dest_start) const
+      { dest_start = bytes.sub_array (0, bytes.length - instructions_length (bytes)); }
+
+      bool get_contour_points (contour_point_vector_t &points_ /* OUT */,
+                              hb_vector_t<unsigned int> &end_points_ /* OUT */,
+                              const bool phantom_only=false) const
+      {
+       /* add one pseudo point for each component in composite glyph */
+       unsigned int num_points = hb_len (get_iterator ());
+       points_.resize (num_points + PHANTOM_COUNT);
+       for (unsigned int i = 0; i < points_.length; i++) points_[i].init ();
+       return true;
+      }
+    };
+
+    enum glyph_type_t { EMPTY, SIMPLE, COMPOSITE };
+
+    enum phantom_point_index_t
+    {
+      PHANTOM_LEFT   = 0,
+      PHANTOM_RIGHT  = 1,
+      PHANTOM_TOP    = 2,
+      PHANTOM_BOTTOM = 3,
+      PHANTOM_COUNT  = 4
+    };
+
+    public:
+    composite_iter_t get_composite_iterator () const
+    {
+      if (type != COMPOSITE) return composite_iter_t ();
+      return CompositeGlyph (*header, bytes).get_iterator ();
+    }
 
-       *start_offset = offsets[glyph];
-       *end_offset   = offsets[glyph + 1];
+    const Glyph trim_padding () const
+    {
+      switch (type) {
+      case COMPOSITE: return CompositeGlyph (*header, bytes).trim_padding ();
+      case SIMPLE:    return SimpleGlyph (*header, bytes).trim_padding ();
+      default:        return bytes;
       }
+    }
 
-      if (*start_offset > *end_offset || *end_offset > glyf_table.get_length ())
-       return false;
+    void drop_hints ()
+    {
+      switch (type) {
+      case COMPOSITE: CompositeGlyph (*header, bytes).drop_hints (); return;
+      case SIMPLE:    SimpleGlyph (*header, bytes).drop_hints (); return;
+      default:        return;
+      }
+    }
 
-      return true;
+    void drop_hints_bytes (hb_bytes_t &dest_start, hb_bytes_t &dest_end) const
+    {
+      switch (type) {
+      case COMPOSITE: CompositeGlyph (*header, bytes).drop_hints_bytes (dest_start); return;
+      case SIMPLE:    SimpleGlyph (*header, bytes).drop_hints_bytes (dest_start, dest_end); return;
+      default:        return;
+      }
+    }
+
+    /* for a simple glyph, return contour end points, flags, along with coordinate points
+     * for a composite glyph, return pseudo component points
+     * in both cases points trailed with four phantom points
+     */
+    bool get_contour_points (contour_point_vector_t &points_ /* OUT */,
+                            hb_vector_t<unsigned int> &end_points_ /* OUT */,
+                            const bool phantom_only=false) const
+    {
+      switch (type) {
+      case COMPOSITE: return CompositeGlyph (*header, bytes).get_contour_points (points_, end_points_, phantom_only);
+      case SIMPLE:    return SimpleGlyph (*header, bytes).get_contour_points (points_, end_points_, phantom_only);
+      default:
+       /* empty glyph */
+       points_.resize (PHANTOM_COUNT);
+       for (unsigned int i = 0; i < points_.length; i++) points_[i].init ();
+       return true;
+      }
+    }
+
+    bool is_simple_glyph ()    const { return type == SIMPLE; }
+    bool is_composite_glyph () const { return type == COMPOSITE; }
+
+    bool get_extents (hb_font_t *font, hb_codepoint_t gid, hb_glyph_extents_t *extents) const
+    {
+      if (type == EMPTY) return true; /* Empty glyph; zero extents. */
+      return header->get_extents (font, gid, extents);
+    }
+
+    hb_bytes_t get_bytes ()          const { return bytes; }
+    const GlyphHeader &get_header () const { return *header; }
+
+    Glyph (hb_bytes_t bytes_ = hb_bytes_t ()) :
+      bytes (bytes_), header (bytes.as<GlyphHeader> ())
+    {
+      int num_contours = header->numberOfContours;
+      if (unlikely (num_contours == 0)) type = EMPTY;
+      else if (num_contours > 0) type = SIMPLE;
+      else type = COMPOSITE; /* negative numbers */
+    }
+
+    protected:
+    hb_bytes_t bytes;
+    const GlyphHeader *header;
+    unsigned type;
+  };
+
+  struct accelerator_t
+  {
+    void init (hb_face_t *face_)
+    {
+      short_offset = false;
+      num_glyphs = 0;
+      loca_table = nullptr;
+      glyf_table = nullptr;
+      face = face_;
+      const OT::head &head = *face->table.head;
+      if (head.indexToLocFormat > 1 || head.glyphDataFormat > 0)
+       /* Unknown format.  Leave num_glyphs=0, that takes care of disabling us. */
+       return;
+      short_offset = 0 == head.indexToLocFormat;
+
+      loca_table = hb_sanitize_context_t ().reference_table<loca> (face);
+      glyf_table = hb_sanitize_context_t ().reference_table<glyf> (face);
+
+      num_glyphs = hb_max (1u, loca_table.get_length () / (short_offset ? 2 : 4)) - 1;
+    }
+
+    void fini ()
+    {
+      loca_table.destroy ();
+      glyf_table.destroy ();
+    }
+
+    enum phantom_point_index_t
+    {
+      PHANTOM_LEFT   = 0,
+      PHANTOM_RIGHT  = 1,
+      PHANTOM_TOP    = 2,
+      PHANTOM_BOTTOM = 3,
+      PHANTOM_COUNT  = 4
+    };
+
+    protected:
+
+    void init_phantom_points (hb_codepoint_t gid, hb_array_t<contour_point_t> &phantoms /* IN/OUT */) const
+    {
+      const Glyph &glyph = glyph_for_gid (gid);
+      int h_delta = (int) glyph.get_header ().xMin - face->table.hmtx->get_side_bearing (gid);
+      int v_orig  = (int) glyph.get_header ().yMax + face->table.vmtx->get_side_bearing (gid);
+      unsigned int h_adv = face->table.hmtx->get_advance (gid);
+      unsigned int v_adv = face->table.vmtx->get_advance (gid);
+
+      phantoms[PHANTOM_LEFT].x = h_delta;
+      phantoms[PHANTOM_RIGHT].x = h_adv + h_delta;
+      phantoms[PHANTOM_TOP].y = v_orig;
+      phantoms[PHANTOM_BOTTOM].y = v_orig - (int) v_adv;
     }
 
-    bool get_instruction_offsets (unsigned int start_offset,
-                                 unsigned int end_offset,
-                                 unsigned int *instruction_start /* OUT */,
-                                 unsigned int *instruction_end /* OUT */) const
+    struct contour_bounds_t
     {
-      if (end_offset - start_offset < GlyphHeader::static_size)
+      contour_bounds_t () { min_x = min_y = FLT_MAX; max_x = max_y = -FLT_MAX; }
+
+      void add (const contour_point_t &p)
       {
-       *instruction_start = 0;
-       *instruction_end = 0;
-       return true; /* Empty glyph; no instructions. */
+       min_x = hb_min (min_x, p.x);
+       min_y = hb_min (min_y, p.y);
+       max_x = hb_max (max_x, p.x);
+       max_y = hb_max (max_y, p.y);
       }
-      const GlyphHeader &glyph_header = StructAtOffset<GlyphHeader> (glyf_table, start_offset);
-      int16_t num_contours = (int16_t) glyph_header.numberOfContours;
-      if (num_contours < 0)
+
+      bool empty () const { return (min_x >= max_x) || (min_y >= max_y); }
+
+      void get_extents (hb_font_t *font, hb_glyph_extents_t *extents)
       {
-       CompositeGlyphHeader::Iterator composite_it;
-       if (unlikely (!CompositeGlyphHeader::get_iterator (
-           (const char*) this->glyf_table + start_offset,
-            end_offset - start_offset, &composite_it))) return false;
-       const CompositeGlyphHeader *last;
-       do {
-         last = composite_it.current;
-       } while (composite_it.move_to_next ());
-
-       if ((uint16_t) last->flags & CompositeGlyphHeader::WE_HAVE_INSTRUCTIONS)
-         *instruction_start = ((char *) last - (char *) glyf_table->dataZ.arrayZ) + last->get_size ();
-       else
-         *instruction_start = end_offset;
-       *instruction_end = end_offset;
-       if (unlikely (*instruction_start > *instruction_end))
+       if (unlikely (empty ()))
        {
-         DEBUG_MSG(SUBSET, nullptr, "Invalid instruction offset, %d is outside [%d, %d]", *instruction_start, start_offset, end_offset);
-         return false;
+         extents->width = 0;
+         extents->x_bearing = 0;
+         extents->height = 0;
+         extents->y_bearing = 0;
+         return;
        }
+       extents->x_bearing = font->em_scalef_x (min_x);
+       extents->width = font->em_scalef_x (max_x - min_x);
+       extents->y_bearing = font->em_scalef_y (max_y);
+       extents->height = font->em_scalef_y (min_y - max_y);
       }
-      else
+
+      protected:
+      float min_x, min_y, max_x, max_y;
+    };
+
+#ifndef HB_NO_VAR
+    /* Note: Recursively calls itself.
+     * all_points includes phantom points
+     */
+    bool get_points_var (hb_codepoint_t gid,
+                        const int *coords, unsigned int coord_count,
+                        contour_point_vector_t &all_points /* OUT */,
+                        unsigned int depth = 0) const
+    {
+      if (unlikely (depth++ > HB_MAX_NESTING_LEVEL)) return false;
+      contour_point_vector_t points;
+      hb_vector_t<unsigned int> end_points;
+      const Glyph &glyph = glyph_for_gid (gid);
+      if (unlikely (!glyph.get_contour_points (points, end_points))) return false;
+      hb_array_t<contour_point_t> phantoms = points.sub_array (points.length - PHANTOM_COUNT, PHANTOM_COUNT);
+      init_phantom_points (gid, phantoms);
+      if (unlikely (!face->table.gvar->apply_deltas_to_points (gid, coords, coord_count, points.as_array (), end_points.as_array ()))) return false;
+
+      unsigned int comp_index = 0;
+      if (glyph.is_simple_glyph ())
+       all_points.extend (points.as_array ());
+      else if (glyph.is_composite_glyph ())
       {
-       unsigned int instruction_length_offset = start_offset + GlyphHeader::static_size + 2 * num_contours;
-       if (unlikely (instruction_length_offset + 2 > end_offset))
+       for (auto &item : glyph.get_composite_iterator ())
        {
-         DEBUG_MSG(SUBSET, nullptr, "Glyph size is too short, missing field instructionLength.");
-         return false;
-       }
+         contour_point_vector_t comp_points;
+         if (unlikely (!get_points_var (item.glyphIndex, coords, coord_count,
+                                        comp_points, depth))
+                       || comp_points.length < PHANTOM_COUNT)
+           return false;
 
-       const HBUINT16 &instruction_length = StructAtOffset<HBUINT16> (glyf_table, instruction_length_offset);
-       unsigned int start = instruction_length_offset + 2;
-       unsigned int end = start + (uint16_t) instruction_length;
-       if (unlikely (end > end_offset)) // Out of bounds of the current glyph
-       {
-         DEBUG_MSG(SUBSET, nullptr, "The instructions array overruns the glyph's boundaries.");
-         return false;
+         /* Copy phantom points from component if USE_MY_METRICS flag set */
+         if (item.is_use_my_metrics ())
+           for (unsigned int i = 0; i < PHANTOM_COUNT; i++)
+             phantoms[i] = comp_points[comp_points.length - PHANTOM_COUNT + i];
+
+         /* Apply component transformation & translation */
+         item.transform_points (comp_points);
+
+         /* Apply translatation from gvar */
+         comp_points.translate (points[comp_index]);
+
+         if (item.is_anchored ())
+         {
+           unsigned int p1, p2;
+           item.get_anchor_points (p1, p2);
+           if (likely (p1 < all_points.length && p2 < comp_points.length))
+           {
+             contour_point_t delta;
+             delta.init (all_points[p1].x - comp_points[p2].x,
+                         all_points[p1].y - comp_points[p2].y);
+
+             comp_points.translate (delta);
+           }
+         }
+
+         all_points.extend (comp_points.sub_array (0, comp_points.length - PHANTOM_COUNT));
+
+         comp_index++;
        }
 
-       *instruction_start = start;
-       *instruction_end = end;
+       all_points.extend (phantoms);
+      }
+      else return false;
+
+      return true;
+    }
+
+    bool get_points_bearing_applied (hb_font_t *font, hb_codepoint_t gid, contour_point_vector_t &all_points) const
+    {
+      if (unlikely (!get_points_var (gid, font->coords, font->num_coords, all_points) ||
+                   all_points.length < PHANTOM_COUNT)) return false;
+
+      /* Undocumented rasterizer behavior:
+       * Shift points horizontally by the updated left side bearing
+       */
+      contour_point_t delta;
+      delta.init (-all_points[all_points.length - PHANTOM_COUNT + PHANTOM_LEFT].x, 0.f);
+      if (delta.x) all_points.translate (delta);
+      return true;
+    }
+
+    protected:
+
+    bool get_var_extents_and_phantoms (hb_font_t *font, hb_codepoint_t gid,
+                                      hb_glyph_extents_t *extents=nullptr /* OUT */,
+                                      contour_point_vector_t *phantoms=nullptr /* OUT */) const
+    {
+      contour_point_vector_t all_points;
+      if (!unlikely (get_points_bearing_applied (font, gid, all_points))) return false;
+      if (extents)
+      {
+       contour_bounds_t bounds;
+       for (unsigned int i = 0; i + PHANTOM_COUNT < all_points.length; i++)
+         bounds.add (all_points[i]);
+       bounds.get_extents (font, extents);
       }
+      if (phantoms)
+       for (unsigned int i = 0; i < PHANTOM_COUNT; i++)
+         (*phantoms)[i] = all_points[all_points.length - PHANTOM_COUNT + i];
       return true;
     }
 
-    bool get_extents (hb_codepoint_t glyph, hb_glyph_extents_t *extents) const
+    bool get_var_metrics (hb_font_t *font, hb_codepoint_t gid,
+                         contour_point_vector_t &phantoms) const
+    { return get_var_extents_and_phantoms (font, gid, nullptr, &phantoms); }
+
+    bool get_extents_var (hb_font_t *font, hb_codepoint_t gid,
+                         hb_glyph_extents_t *extents) const
+    { return get_var_extents_and_phantoms (font, gid, extents); }
+#endif
+
+    public:
+#ifndef HB_NO_VAR
+    unsigned int get_advance_var (hb_font_t *font, hb_codepoint_t gid,
+                                 bool is_vertical) const
+    {
+      bool success = false;
+      contour_point_vector_t phantoms;
+      phantoms.resize (PHANTOM_COUNT);
+
+      if (likely (font->num_coords == face->table.gvar->get_axis_count ()))
+       success = get_var_metrics (font, gid, phantoms);
+
+      if (unlikely (!success))
+       return is_vertical ? face->table.vmtx->get_advance (gid) : face->table.hmtx->get_advance (gid);
+
+      if (is_vertical)
+       return roundf (phantoms[PHANTOM_TOP].y - phantoms[PHANTOM_BOTTOM].y);
+      else
+       return roundf (phantoms[PHANTOM_RIGHT].x - phantoms[PHANTOM_LEFT].x);
+    }
+
+    int get_side_bearing_var (hb_font_t *font, hb_codepoint_t gid, bool is_vertical) const
+    {
+      hb_glyph_extents_t extents;
+      contour_point_vector_t phantoms;
+      phantoms.resize (PHANTOM_COUNT);
+
+      if (unlikely (!get_var_extents_and_phantoms (font, gid, &extents, &phantoms)))
+       return is_vertical ? face->table.vmtx->get_side_bearing (gid) : face->table.hmtx->get_side_bearing (gid);
+
+      return is_vertical ? ceil (phantoms[PHANTOM_TOP].y) - extents.y_bearing : floor (phantoms[PHANTOM_LEFT].x);
+    }
+#endif
+
+    bool get_extents (hb_font_t *font, hb_codepoint_t gid, hb_glyph_extents_t *extents) const
+    {
+#ifndef HB_NO_VAR
+      unsigned int coord_count;
+      const int *coords = hb_font_get_var_coords_normalized (font, &coord_count);
+      if (coords && coord_count > 0 && coord_count == face->table.gvar->get_axis_count ())
+       return get_extents_var (font, gid, extents);
+#endif
+
+      if (unlikely (gid >= num_glyphs)) return false;
+
+      return glyph_for_gid (gid).get_extents (font, gid, extents);
+    }
+
+    const Glyph
+    glyph_for_gid (hb_codepoint_t gid, bool needs_padding_removal = false) const
     {
       unsigned int start_offset, end_offset;
-      if (!get_offsets (glyph, &start_offset, &end_offset))
-       return false;
+      if (unlikely (gid >= num_glyphs)) return Glyph ();
+
+      if (short_offset)
+      {
+       const HBUINT16 *offsets = (const HBUINT16 *) loca_table->dataZ.arrayZ;
+       start_offset = 2 * offsets[gid];
+       end_offset   = 2 * offsets[gid + 1];
+      }
+      else
+      {
+       const HBUINT32 *offsets = (const HBUINT32 *) loca_table->dataZ.arrayZ;
+       start_offset = offsets[gid];
+       end_offset   = offsets[gid + 1];
+      }
 
-      if (end_offset - start_offset < GlyphHeader::static_size)
-       return true; /* Empty glyph; zero extents. */
+      if (unlikely (start_offset > end_offset || end_offset > glyf_table.get_length ()))
+       return Glyph ();
 
-      const GlyphHeader &glyph_header = StructAtOffset<GlyphHeader> (glyf_table, start_offset);
+      Glyph glyph (hb_bytes_t ((const char *) this->glyf_table + start_offset,
+                              end_offset - start_offset));
+      return needs_padding_removal ? glyph.trim_padding () : glyph;
+    }
+
+    void
+    add_gid_and_children (hb_codepoint_t gid, hb_set_t *gids_to_retain,
+                         unsigned int depth = 0) const
+    {
+      if (unlikely (depth++ > HB_MAX_NESTING_LEVEL)) return;
+      /* Check if is already visited */
+      if (gids_to_retain->has (gid)) return;
 
-      extents->x_bearing = MIN (glyph_header.xMin, glyph_header.xMax);
-      extents->y_bearing = MAX (glyph_header.yMin, glyph_header.yMax);
-      extents->width     = MAX (glyph_header.xMin, glyph_header.xMax) - extents->x_bearing;
-      extents->height    = MIN (glyph_header.yMin, glyph_header.yMax) - extents->y_bearing;
+      gids_to_retain->add (gid);
 
-      return true;
+      for (auto &item : glyph_for_gid (gid).get_composite_iterator ())
+        add_gid_and_children (item.glyphIndex, gids_to_retain, depth);
     }
 
     private:
@@ -464,14 +1044,66 @@ struct glyf
     unsigned int num_glyphs;
     hb_blob_ptr_t<loca> loca_table;
     hb_blob_ptr_t<glyf> glyf_table;
+    hb_face_t *face;
+  };
+
+  struct SubsetGlyph
+  {
+    hb_codepoint_t new_gid;
+    hb_codepoint_t old_gid;
+    Glyph source_glyph;
+    hb_bytes_t dest_start;  /* region of source_glyph to copy first */
+    hb_bytes_t dest_end;    /* region of source_glyph to copy second */
+
+    bool serialize (hb_serialize_context_t *c,
+                   const hb_subset_plan_t *plan) const
+    {
+      TRACE_SERIALIZE (this);
+
+      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 = padding ();
+      DEBUG_MSG (SUBSET, nullptr, "serialize %d byte glyph, width %d pad %d", dest_glyph.length, dest_glyph.length  + pad_length, pad_length);
+
+      HBUINT8 pad;
+      pad = 0;
+      while (pad_length > 0)
+      {
+       c->embed (pad);
+       pad_length--;
+      }
+
+      if (!unlikely (dest_glyph.length)) return_trace (true);
+
+      /* update components gids */
+      for (auto &_ : Glyph (dest_glyph).get_composite_iterator ())
+      {
+       hb_codepoint_t new_gid;
+       if (plan->new_gid_for_old_gid (_.glyphIndex, &new_gid))
+         ((OT::glyf::CompositeGlyphChain *) &_)->glyphIndex = new_gid;
+      }
+
+      if (plan->drop_hints) Glyph (dest_glyph).drop_hints ();
+
+      return_trace (true);
+    }
+
+    void drop_hints_bytes ()
+    { source_glyph.drop_hints_bytes (dest_start, dest_end); }
+
+    unsigned int      length () const { return dest_start.length + dest_end.length; }
+    /* pad to 2 to ensure 2-byte loca will be ok */
+    unsigned int     padding () const { return length () % 2; }
+    unsigned int padded_size () const { return length () + padding (); }
   };
 
   protected:
-  UnsizedArrayOf<HBUINT8>      dataZ;          /* Glyphs data. */
+  UnsizedArrayOf<HBUINT8>
+               dataZ;  /* Glyphs data. */
   public:
-  DEFINE_SIZE_MIN (0); /* In reality, this is UNBOUNDED() type; but since we always
-                       * check the size externally, allow Null() object of it by
-                       * defining it MIN() instead. */
+  DEFINE_SIZE_MIN (0); /* In reality, this is UNBOUNDED() type; but since we always
+                        * check the size externally, allow Null() object of it by
+                        * defining it _MIN instead. */
 };
 
 struct glyf_accelerator_t : glyf::accelerator_t {};
index 953ccab..96c1d1f 100644 (file)
@@ -41,71 +41,31 @@ namespace OT {
 
 struct DeviceRecord
 {
-  struct SubsetView
-  {
-    const DeviceRecord *source_device_record;
-    unsigned int sizeDeviceRecord;
-    hb_subset_plan_t *subset_plan;
-
-    void init (const DeviceRecord *source_device_record,
-              unsigned int sizeDeviceRecord,
-              hb_subset_plan_t   *subset_plan)
-    {
-      this->source_device_record = source_device_record;
-      this->sizeDeviceRecord = sizeDeviceRecord;
-      this->subset_plan = subset_plan;
-    }
-
-    unsigned int len () const
-    { return this->subset_plan->num_output_glyphs (); }
-
-    const HBUINT8* operator [] (unsigned int new_gid) const
-    {
-      if (unlikely (new_gid >= len ())) return nullptr;
-
-      hb_codepoint_t old_gid;
-      if (!this->subset_plan->old_gid_for_new_gid (new_gid, &old_gid))
-        return &Null(HBUINT8);
-
-      if (old_gid >= sizeDeviceRecord - DeviceRecord::min_size)
-        return nullptr;
-      return &(this->source_device_record->widthsZ[old_gid]);
-    }
-  };
-
-  static unsigned int get_size (unsigned int count)
+  static unsigned int get_size (unsigned count)
   { return hb_ceil_to_4 (min_size + count * HBUINT8::static_size); }
 
-  bool serialize (hb_serialize_context_t *c, const SubsetView &subset_view)
+  template<typename Iterator,
+          hb_requires (hb_is_iterator (Iterator))>
+  bool serialize (hb_serialize_context_t *c, unsigned pixelSize, Iterator it)
   {
     TRACE_SERIALIZE (this);
 
-    unsigned int size = get_size (subset_view.len ());
-    if (unlikely (!c->allocate_size<DeviceRecord> (size)))
-    {
-      DEBUG_MSG(SUBSET, nullptr, "Couldn't allocate enough space for DeviceRecord: %d.",
-                size);
-      return_trace (false);
-    }
-
-    this->pixelSize.set (subset_view.source_device_record->pixelSize);
-    this->maxWidth.set (subset_view.source_device_record->maxWidth);
-
-    for (unsigned int i = 0; i < subset_view.len (); i++)
-    {
-      const HBUINT8 *width = subset_view[i];
-      if (!width)
-      {
-       DEBUG_MSG(SUBSET, nullptr, "HDMX width for new gid %d is missing.", i);
-       return_trace (false);
-      }
-      widthsZ[i].set (*width);
-    }
+    unsigned length = it.len ();
+
+    if (unlikely (!c->extend (*this, length)))  return_trace (false);
+
+    this->pixelSize = pixelSize;
+    this->maxWidth =
+    + it
+    | hb_reduce (hb_max, 0u);
+
+    + it
+    | hb_sink (widthsZ.as_array (length));
 
     return_trace (true);
   }
 
-  bool sanitize (hb_sanitize_context_t *c, unsigned int sizeDeviceRecord) const
+  bool sanitize (hb_sanitize_context_t *c, unsigned sizeDeviceRecord) const
   {
     TRACE_SANITIZE (this);
     return_trace (likely (c->check_struct (this) &&
@@ -135,62 +95,63 @@ struct hdmx
     return StructAtOffset<DeviceRecord> (&this->firstDeviceRecord, i * sizeDeviceRecord);
   }
 
-  bool serialize (hb_serialize_context_t *c, const hdmx *source_hdmx, hb_subset_plan_t *plan)
+  template<typename Iterator,
+          hb_requires (hb_is_iterator (Iterator))>
+  bool serialize (hb_serialize_context_t *c, unsigned version, Iterator it)
   {
     TRACE_SERIALIZE (this);
 
     if (unlikely (!c->extend_min ((*this))))  return_trace (false);
 
-    this->version.set (source_hdmx->version);
-    this->numRecords.set (source_hdmx->numRecords);
-    this->sizeDeviceRecord.set (DeviceRecord::get_size (plan->num_output_glyphs ()));
+    this->version = version;
+    this->numRecords = it.len ();
+    this->sizeDeviceRecord = DeviceRecord::get_size (it ? (*it).second.len () : 0);
 
-    for (unsigned int i = 0; i < source_hdmx->numRecords; i++)
-    {
-      DeviceRecord::SubsetView subset_view;
-      subset_view.init (&(*source_hdmx)[i], source_hdmx->sizeDeviceRecord, plan);
+    + it
+    | hb_apply ([c] (const hb_item_type<Iterator>& _) {
+                 c->start_embed<DeviceRecord> ()->serialize (c, _.first, _.second);
+               })
+    ;
 
-      if (!c->start_embed<DeviceRecord> ()->serialize (c, subset_view))
-       return_trace (false);
-    }
-
-    return_trace (true);
+    return_trace (c->successful);
   }
 
-  static size_t get_subsetted_size (const hdmx *source_hdmx, hb_subset_plan_t *plan)
+
+  bool subset (hb_subset_context_t *c) const
   {
-    return min_size + source_hdmx->numRecords * DeviceRecord::get_size (plan->num_output_glyphs ());
+    TRACE_SUBSET (this);
+
+    hdmx *hdmx_prime = c->serializer->start_embed <hdmx> ();
+    if (unlikely (!hdmx_prime)) return_trace (false);
+
+    auto it =
+    + hb_range ((unsigned) numRecords)
+    | hb_map ([c, this] (unsigned _)
+       {
+         const DeviceRecord *device_record =
+           &StructAtOffset<DeviceRecord> (&firstDeviceRecord,
+                                          _ * sizeDeviceRecord);
+         auto row =
+           + hb_range (c->plan->num_output_glyphs ())
+           | hb_map (c->plan->reverse_glyph_map)
+           | hb_map ([=] (hb_codepoint_t _)
+                     {
+                       if (c->plan->is_empty_glyph (_))
+                         return Null(HBUINT8);
+                       return device_record->widthsZ.as_array (get_num_glyphs ()) [_];
+                     })
+           ;
+         return hb_pair ((unsigned) device_record->pixelSize, +row);
+       })
+    ;
+
+    hdmx_prime->serialize (c->serializer, version, it);
+    return_trace (true);
   }
 
-  bool subset (hb_subset_plan_t *plan) const
+  unsigned get_num_glyphs () const
   {
-    size_t dest_size = get_subsetted_size (this, plan);
-    hdmx *dest = (hdmx *) malloc (dest_size);
-    if (unlikely (!dest))
-    {
-      DEBUG_MSG(SUBSET, nullptr, "Unable to alloc %lu for hdmx subset output.", (unsigned long) dest_size);
-      return false;
-    }
-
-    hb_serialize_context_t c (dest, dest_size);
-    hdmx *hdmx_prime = c.start_serialize<hdmx> ();
-    if (!hdmx_prime || !hdmx_prime->serialize (&c, this, plan))
-    {
-      free (dest);
-      DEBUG_MSG(SUBSET, nullptr, "Failed to serialize write new hdmx.");
-      return false;
-    }
-    c.end_serialize ();
-
-    hb_blob_t *hdmx_prime_blob = hb_blob_create ((const char *) dest,
-                                                dest_size,
-                                                HB_MEMORY_MODE_READONLY,
-                                                dest,
-                                                free);
-    bool result = plan->add_table (HB_OT_TAG_hdmx, hdmx_prime_blob);
-    hb_blob_destroy (hdmx_prime_blob);
-
-    return result;
+    return sizeDeviceRecord - DeviceRecord::min_size;
   }
 
   bool sanitize (hb_sanitize_context_t *c) const
index c3155b7..778b6c5 100644 (file)
@@ -45,6 +45,8 @@ namespace OT {
 template <typename T>
 struct _hea
 {
+  bool has_data () const { return version.major; }
+
   bool sanitize (hb_sanitize_context_t *c) const
   {
     TRACE_SANITIZE (this);
index 9ef1f57..e20b372 100644 (file)
@@ -29,8 +29,8 @@
 
 #include "hb-open-type.hh"
 #include "hb-ot-hhea-table.hh"
-#include "hb-ot-os2-table.hh"
 #include "hb-ot-var-hvar-table.hh"
+#include "hb-ot-metrics.hh"
 
 /*
  * hmtx -- Horizontal Metrics
 #define HB_OT_TAG_vmtx HB_TAG('v','m','t','x')
 
 
+HB_INTERNAL int
+_glyf_get_side_bearing_var (hb_font_t *font, hb_codepoint_t glyph, bool is_vertical);
+
+HB_INTERNAL unsigned
+_glyf_get_advance_var (hb_font_t *font, hb_codepoint_t glyph, bool is_vertical);
+
+
 namespace OT {
 
 
@@ -53,6 +60,7 @@ struct LongMetric
   DEFINE_SIZE_STATIC (4);
 };
 
+
 template <typename T, typename H>
 struct hmtxvmtx
 {
@@ -66,7 +74,7 @@ struct hmtxvmtx
 
 
   bool subset_update_header (hb_subset_plan_t *plan,
-                             unsigned int num_hmetrics) const
+                            unsigned int num_hmetrics) const
   {
     hb_blob_t *src_blob = hb_sanitize_context_t ().reference_table<H> (plan->source, H::tableTag);
     hb_blob_t *dest_blob = hb_blob_copy_writable_or_fail (src_blob);
@@ -78,7 +86,7 @@ struct hmtxvmtx
 
     unsigned int length;
     H *table = (H *) hb_blob_get_data (dest_blob, &length);
-    table->numberOfLongMetrics.set (num_hmetrics);
+    table->numberOfLongMetrics = num_hmetrics;
 
     bool result = plan->add_table (H::tableTag, dest_blob);
     hb_blob_destroy (dest_blob);
@@ -86,74 +94,68 @@ struct hmtxvmtx
     return result;
   }
 
-  bool subset (hb_subset_plan_t *plan) const
+  template<typename Iterator,
+          hb_requires (hb_is_iterator (Iterator))>
+  void serialize (hb_serialize_context_t *c,
+                 Iterator it,
+                 unsigned num_advances)
   {
-    typename T::accelerator_t _mtx;
-    _mtx.init (plan->source);
-
-    /* All the trailing glyphs with the same advance can use one LongMetric
-     * and just keep LSB */
-    unsigned int num_output_glyphs = plan->num_output_glyphs ();
-    unsigned int num_advances = _mtx.num_advances_for_subset (plan);
-
-    /* alloc the new table */
-    size_t dest_sz = num_advances * 4
-                 + (num_output_glyphs - num_advances) * 2;
-    void *dest = (void *) malloc (dest_sz);
-    if (unlikely (!dest))
-    {
-      return false;
-    }
-    DEBUG_MSG(SUBSET, nullptr, "%c%c%c%c in src has %d advances, %d lsbs", HB_UNTAG(T::tableTag), _mtx.num_advances, _mtx.num_metrics - _mtx.num_advances);
-    DEBUG_MSG(SUBSET, nullptr, "%c%c%c%c in dest has %d advances, %d lsbs, %u bytes",
-              HB_UNTAG(T::tableTag), num_advances, num_output_glyphs - num_advances, (unsigned int) dest_sz);
+    unsigned idx = 0;
+    + it
+    | hb_apply ([c, &idx, num_advances] (const hb_item_type<Iterator>& _)
+               {
+                 if (idx < num_advances)
+                 {
+                   LongMetric lm;
+                   lm.advance = _.first;
+                   lm.sb = _.second;
+                   if (unlikely (!c->embed<LongMetric> (&lm))) return;
+                 }
+                 else
+                 {
+                   FWORD *sb = c->allocate_size<FWORD> (FWORD::static_size);
+                   if (unlikely (!sb)) return;
+                   *sb = _.second;
+                 }
+                 idx++;
+               })
+    ;
+  }
 
-    // Copy everything over
-    char * dest_pos = (char *) dest;
+  bool subset (hb_subset_context_t *c) const
+  {
+    TRACE_SUBSET (this);
 
-    bool failed = false;
-    for (unsigned int i = 0; i < num_output_glyphs; i++)
-    {
-      unsigned int side_bearing = 0;
-      unsigned int advance = 0;
-      hb_codepoint_t old_gid;
-      if (plan->old_gid_for_new_gid (i, &old_gid))
-      {
-        // Glyph is not an empty glyph so copy advance and side bearing
-        // from the input font.
-        side_bearing = _mtx.get_side_bearing (old_gid);
-        advance = _mtx.get_advance (old_gid);
-      }
+    T *table_prime = c->serializer->start_embed <T> ();
+    if (unlikely (!table_prime)) return_trace (false);
+
+    accelerator_t _mtx;
+    _mtx.init (c->plan->source);
+    unsigned num_advances = _mtx.num_advances_for_subset (c->plan);
+
+    auto it =
+    + hb_range (c->plan->num_output_glyphs ())
+    | hb_map ([c, &_mtx] (unsigned _)
+             {
+               hb_codepoint_t old_gid;
+               if (!c->plan->old_gid_for_new_gid (_, &old_gid))
+                 return hb_pair (0u, 0);
+               return hb_pair (_mtx.get_advance (old_gid), _mtx.get_side_bearing (old_gid));
+             })
+    ;
+
+    table_prime->serialize (c->serializer, it, num_advances);
 
-      bool has_advance = i < num_advances;
-      if (has_advance)
-      {
-        ((LongMetric *) dest_pos)->advance.set (advance);
-        ((LongMetric *) dest_pos)->sb.set (side_bearing);
-      }
-      else
-      {
-        ((FWORD *) dest_pos)->set (side_bearing);
-      }
-      dest_pos += (has_advance ? 4 : 2);
-    }
     _mtx.fini ();
 
+    if (unlikely (c->serializer->ran_out_of_room || c->serializer->in_error ()))
+      return_trace (false);
+
     // Amend header num hmetrics
-    if (failed || unlikely (!subset_update_header (plan, num_advances)))
-    {
-      free (dest);
-      return false;
-    }
+    if (unlikely (!subset_update_header (c->plan, num_advances)))
+      return_trace (false);
 
-    hb_blob_t *result = hb_blob_create ((const char *)dest,
-                                        dest_sz,
-                                        HB_MEMORY_MODE_READONLY,
-                                        dest,
-                                        free);
-    bool success = plan->add_table (T::tableTag, result);
-    hb_blob_destroy (result);
-    return success;
+    return_trace (true);
   }
 
   struct accelerator_t
@@ -161,32 +163,11 @@ struct hmtxvmtx
     friend struct hmtxvmtx;
 
     void init (hb_face_t *face,
-               unsigned int default_advance_ = 0)
+              unsigned int default_advance_ = 0)
     {
       default_advance = default_advance_ ? default_advance_ : hb_face_get_upem (face);
 
-      bool got_font_extents = false;
-      if (T::os2Tag != HB_TAG_NONE && face->table.OS2->is_typo_metrics ())
-      {
-       ascender = abs (face->table.OS2->sTypoAscender);
-       descender = -abs (face->table.OS2->sTypoDescender);
-       line_gap = face->table.OS2->sTypoLineGap;
-       got_font_extents = (ascender | descender) != 0;
-      }
-
-      hb_blob_t *_hea_blob = hb_sanitize_context_t().reference_table<H> (face);
-      const H *_hea_table = _hea_blob->as<H> ();
-      num_advances = _hea_table->numberOfLongMetrics;
-      if (!got_font_extents)
-      {
-       ascender = abs (_hea_table->ascender);
-       descender = -abs (_hea_table->descender);
-       line_gap = _hea_table->lineGap;
-       got_font_extents = (ascender | descender) != 0;
-      }
-      hb_blob_destroy (_hea_blob);
-
-      has_font_extents = got_font_extents;
+      num_advances = T::is_horizontal ? face->table.hhea->numberOfLongMetrics : face->table.vhea->numberOfLongMetrics;
 
       table = hb_sanitize_context_t().reference_table<hmtxvmtx> (face, T::tableTag);
 
@@ -214,19 +195,35 @@ struct hmtxvmtx
       var_table.destroy ();
     }
 
-    /* TODO Add variations version. */
-    unsigned int get_side_bearing (hb_codepoint_t glyph) const
+    int get_side_bearing (hb_codepoint_t glyph) const
     {
       if (glyph < num_advances)
-        return table->longMetricZ[glyph].sb;
+       return table->longMetricZ[glyph].sb;
 
       if (unlikely (glyph >= num_metrics))
-        return 0;
+       return 0;
 
       const FWORD *bearings = (const FWORD *) &table->longMetricZ[num_advances];
       return bearings[glyph - num_advances];
     }
 
+    int get_side_bearing (hb_font_t *font, hb_codepoint_t glyph) const
+    {
+      int side_bearing = get_side_bearing (glyph);
+
+#ifndef HB_NO_VAR
+      if (unlikely (glyph >= num_metrics) || !font->num_coords)
+       return side_bearing;
+
+      if (var_table.get_length ())
+        return side_bearing + var_table->get_side_bearing_var (glyph, font->coords, font->num_coords); // TODO Optimize?!
+
+      return _glyf_get_side_bearing_var (font, glyph, T::tableTag == HB_OT_TAG_vmtx);
+#else
+      return side_bearing;
+#endif
+    }
+
     unsigned int get_advance (hb_codepoint_t glyph) const
     {
       if (unlikely (glyph >= num_metrics))
@@ -240,30 +237,37 @@ struct hmtxvmtx
          return default_advance;
       }
 
-      return table->longMetricZ[MIN (glyph, (uint32_t) num_advances - 1)].advance;
+      return table->longMetricZ[hb_min (glyph, (uint32_t) num_advances - 1)].advance;
     }
 
     unsigned int get_advance (hb_codepoint_t  glyph,
                              hb_font_t      *font) const
     {
       unsigned int advance = get_advance (glyph);
-      if (likely (glyph < num_metrics))
-      {
-       advance += (font->num_coords ? var_table->get_advance_var (glyph, font->coords, font->num_coords) : 0); // TODO Optimize?!
-      }
+
+#ifndef HB_NO_VAR
+      if (unlikely (glyph >= num_metrics) || !font->num_coords)
+       return advance;
+
+      if (var_table.get_length ())
+       return advance + roundf (var_table->get_advance_var (font, glyph)); // TODO Optimize?!
+
+      return _glyf_get_advance_var (font, glyph, T::tableTag == HB_OT_TAG_vmtx);
+#else
       return advance;
+#endif
     }
 
     unsigned int num_advances_for_subset (const hb_subset_plan_t *plan) const
     {
       unsigned int num_advances = plan->num_output_glyphs ();
       unsigned int last_advance = _advance_for_new_gid (plan,
-                                                        num_advances - 1);
+                                                       num_advances - 1);
       while (num_advances > 1 &&
-             last_advance == _advance_for_new_gid (plan,
-                                                   num_advances - 2))
+            last_advance == _advance_for_new_gid (plan,
+                                                  num_advances - 2))
       {
-        num_advances--;
+       num_advances--;
       }
 
       return num_advances;
@@ -271,21 +275,15 @@ struct hmtxvmtx
 
     private:
     unsigned int _advance_for_new_gid (const hb_subset_plan_t *plan,
-                                       hb_codepoint_t new_gid) const
+                                      hb_codepoint_t new_gid) const
     {
       hb_codepoint_t old_gid;
       if (!plan->old_gid_for_new_gid (new_gid, &old_gid))
-        return 0;
+       return 0;
 
       return get_advance (old_gid);
     }
 
-    public:
-    bool has_font_extents;
-    int ascender;
-    int descender;
-    int line_gap;
-
     protected:
     unsigned int num_metrics;
     unsigned int num_advances;
@@ -325,12 +323,12 @@ struct hmtxvmtx
 struct hmtx : hmtxvmtx<hmtx, hhea> {
   static constexpr hb_tag_t tableTag = HB_OT_TAG_hmtx;
   static constexpr hb_tag_t variationsTag = HB_OT_TAG_HVAR;
-  static constexpr hb_tag_t os2Tag = HB_OT_TAG_OS2;
+  static constexpr bool is_horizontal = true;
 };
 struct vmtx : hmtxvmtx<vmtx, vhea> {
   static constexpr hb_tag_t tableTag = HB_OT_TAG_vmtx;
   static constexpr hb_tag_t variationsTag = HB_OT_TAG_VVAR;
-  static constexpr hb_tag_t os2Tag = HB_TAG_NONE;
+  static constexpr bool is_horizontal = false;
 };
 
 struct hmtx_accelerator_t : hmtx::accelerator_t {};
index ec6a3c8..36e5a35 100644 (file)
@@ -47,9 +47,9 @@ struct KernSubTableFormat3
   int get_kerning (hb_codepoint_t left, hb_codepoint_t right) const
   {
     hb_array_t<const FWORD> kernValue = kernValueZ.as_array (kernValueCount);
-    hb_array_t<const HBUINT8> leftClass = StructAfter<const UnsizedArrayOf<HBUINT8> > (kernValue).as_array (glyphCount);
-    hb_array_t<const HBUINT8> rightClass = StructAfter<const UnsizedArrayOf<HBUINT8> > (leftClass).as_array (glyphCount);
-    hb_array_t<const HBUINT8> kernIndex = StructAfter<const UnsizedArrayOf<HBUINT8> > (rightClass).as_array (leftClassCount * rightClassCount);
+    hb_array_t<const HBUINT8> leftClass = StructAfter<const UnsizedArrayOf<HBUINT8>> (kernValue).as_array (glyphCount);
+    hb_array_t<const HBUINT8> rightClass = StructAfter<const UnsizedArrayOf<HBUINT8>> (leftClass).as_array (glyphCount);
+    hb_array_t<const HBUINT8> kernIndex = StructAfter<const UnsizedArrayOf<HBUINT8>> (rightClass).as_array (leftClassCount * rightClassCount);
 
     unsigned int leftC = leftClass[left];
     unsigned int rightC = rightClass[right];
@@ -121,16 +121,20 @@ struct KernSubTable
     }
   }
 
-  template <typename context_t>
-  typename context_t::return_t dispatch (context_t *c) const
+  template <typename context_t, typename ...Ts>
+  typename context_t::return_t dispatch (context_t *c, Ts&&... ds) const
   {
     unsigned int subtable_type = get_type ();
     TRACE_DISPATCH (this, subtable_type);
     switch (subtable_type) {
     case 0:    return_trace (c->dispatch (u.format0));
-    case 1:    return_trace (u.header.apple ? c->dispatch (u.format1) : c->default_return_value ());
+#ifndef HB_NO_AAT_SHAPE
+    case 1:    return_trace (u.header.apple ? c->dispatch (u.format1, hb_forward<Ts> (ds)...) : c->default_return_value ());
+#endif
     case 2:    return_trace (c->dispatch (u.format2));
-    case 3:    return_trace (u.header.apple ? c->dispatch (u.format3) : c->default_return_value ());
+#ifndef HB_NO_AAT_SHAPE
+    case 3:    return_trace (u.header.apple ? c->dispatch (u.format3, hb_forward<Ts> (ds)...) : c->default_return_value ());
+#endif
     default:   return_trace (c->default_return_value ());
     }
   }
@@ -163,8 +167,8 @@ struct KernOTSubTableHeader
   static constexpr bool apple = false;
   typedef AAT::ObsoleteTypes Types;
 
-  unsigned int tuple_count () const { return 0; }
-  bool is_horizontal () const { return (coverage & Horizontal); }
+  unsigned   tuple_count () const { return 0; }
+  bool     is_horizontal () const { return (coverage & Horizontal); }
 
   enum Coverage
   {
@@ -218,8 +222,8 @@ struct KernAATSubTableHeader
   static constexpr bool apple = true;
   typedef AAT::ObsoleteTypes Types;
 
-  unsigned int tuple_count () const { return 0; }
-  bool is_horizontal () const       { return !(coverage & Vertical); }
+  unsigned   tuple_count () const { return 0; }
+  bool     is_horizontal () const { return !(coverage & Vertical); }
 
   enum Coverage
   {
@@ -271,14 +275,16 @@ struct kern
 {
   static constexpr hb_tag_t tableTag = HB_OT_TAG_kern;
 
-  bool has_data () const { return u.version32; }
-  unsigned int get_type () const { return u.major; }
+  bool     has_data () const { return u.version32; }
+  unsigned get_type () const { return u.major; }
 
   bool has_state_machine () const
   {
     switch (get_type ()) {
     case 0: return u.ot.has_state_machine ();
+#ifndef HB_NO_AAT_SHAPE
     case 1: return u.aat.has_state_machine ();
+#endif
     default:return false;
     }
   }
@@ -287,7 +293,9 @@ struct kern
   {
     switch (get_type ()) {
     case 0: return u.ot.has_cross_stream ();
+#ifndef HB_NO_AAT_SHAPE
     case 1: return u.aat.has_cross_stream ();
+#endif
     default:return false;
     }
   }
@@ -296,7 +304,9 @@ struct kern
   {
     switch (get_type ()) {
     case 0: return u.ot.get_h_kerning (left, right);
+#ifndef HB_NO_AAT_SHAPE
     case 1: return u.aat.get_h_kerning (left, right);
+#endif
     default:return 0;
     }
   }
@@ -304,14 +314,16 @@ struct kern
   bool apply (AAT::hb_aat_apply_context_t *c) const
   { return dispatch (c); }
 
-  template <typename context_t>
-  typename context_t::return_t dispatch (context_t *c) const
+  template <typename context_t, typename ...Ts>
+  typename context_t::return_t dispatch (context_t *c, Ts&&... ds) const
   {
     unsigned int subtable_type = get_type ();
     TRACE_DISPATCH (this, subtable_type);
     switch (subtable_type) {
-    case 0:    return_trace (c->dispatch (u.ot));
-    case 1:    return_trace (c->dispatch (u.aat));
+    case 0:    return_trace (c->dispatch (u.ot, hb_forward<Ts> (ds)...));
+#ifndef HB_NO_AAT_SHAPE
+    case 1:    return_trace (c->dispatch (u.aat, hb_forward<Ts> (ds)...));
+#endif
     default:   return_trace (c->default_return_value ());
     }
   }
@@ -328,7 +340,9 @@ struct kern
   HBUINT32             version32;
   HBUINT16             major;
   KernOT               ot;
+#ifndef HB_NO_AAT_SHAPE
   KernAAT              aat;
+#endif
   } u;
   public:
   DEFINE_SIZE_UNION (4, version32);
index dd0fba1..02fe14f 100644 (file)
@@ -1,7 +1,7 @@
 /*
- * Copyright © 2016 Elie Roux <elie.roux@telecom-bretagne.eu>
+ * Copyright © 2016  Elie Roux <elie.roux@telecom-bretagne.eu>
  * Copyright © 2018  Google, Inc.
- * Copyright © 2018  Ebrahim Byagowi
+ * Copyright © 2018-2019  Ebrahim Byagowi
  *
  *  This is part of HarfBuzz, a text shaping library.
  *
@@ -32,9 +32,6 @@
 #include "hb-open-type.hh"
 #include "hb-ot-layout-common.hh"
 
-/* To be removed */
-typedef hb_tag_t hb_ot_layout_baseline_t;
-
 namespace OT {
 
 /*
@@ -76,7 +73,7 @@ struct BaseCoordFormat2
   protected:
   HBUINT16     format;         /* Format identifier--format = 2 */
   FWORD                coordinate;     /* X or Y value, in design units */
-  GlyphID      referenceGlyph; /* Glyph ID of control glyph */
+  HBGlyphID    referenceGlyph; /* Glyph ID of control glyph */
   HBUINT16     coordPoint;     /* Index of contour point on the
                                 * reference glyph */
   public:
@@ -116,9 +113,11 @@ struct BaseCoordFormat3
 
 struct BaseCoord
 {
-  hb_position_t get_coord (hb_font_t *font,
+  bool has_data () const { return u.format; }
+
+  hb_position_t get_coord (hb_font_t            *font,
                           const VariationStore &var_store,
-                          hb_direction_t direction) const
+                          hb_direction_t        direction) const
   {
     switch (u.format) {
     case 1: return u.format1.get_coord ();
@@ -142,10 +141,10 @@ struct BaseCoord
 
   protected:
   union {
-    HBUINT16           format;
-    BaseCoordFormat1   format1;
-    BaseCoordFormat2   format2;
-    BaseCoordFormat3   format3;
+  HBUINT16             format;
+  BaseCoordFormat1     format1;
+  BaseCoordFormat2     format2;
+  BaseCoordFormat3     format3;
   } u;
   public:
   DEFINE_SIZE_UNION (2, format);
@@ -153,14 +152,9 @@ struct BaseCoord
 
 struct FeatMinMaxRecord
 {
-  static int cmp (const void *key_, const void *entry_)
-  {
-    hb_tag_t key = * (hb_tag_t *) key_;
-    const FeatMinMaxRecord &entry = * (const FeatMinMaxRecord *) entry_;
-    return key < (unsigned int) entry.tag ? -1 :
-          key > (unsigned int) entry.tag ? 1 :
-          0;
-  }
+  int cmp (hb_tag_t key) const { return tag.cmp (key); }
+
+  bool has_data () const { return tag; }
 
   void get_min_max (const BaseCoord **min, const BaseCoord **max) const
   {
@@ -195,17 +189,12 @@ struct FeatMinMaxRecord
 struct MinMax
 {
   void get_min_max (hb_tag_t          feature_tag,
-                          const BaseCoord **min,
-                          const BaseCoord **max) const
+                   const BaseCoord **min,
+                   const BaseCoord **max) const
   {
-    /* TODO Replace hb_bsearch() with .bsearch(). */
-    const FeatMinMaxRecord *minMaxCoord = (const FeatMinMaxRecord *)
-                                         hb_bsearch (&feature_tag, featMinMaxRecords.arrayZ,
-                                                     featMinMaxRecords.len,
-                                                     FeatMinMaxRecord::static_size,
-                                                     FeatMinMaxRecord::cmp);
-    if (minMaxCoord)
-      minMaxCoord->get_min_max (min, max);
+    const FeatMinMaxRecord &minMaxCoord = featMinMaxRecords.bsearch (feature_tag);
+    if (minMaxCoord.has_data ())
+      minMaxCoord.get_min_max (min, max);
     else
     {
       if (likely (min)) *min = &(this+minCoord);
@@ -271,17 +260,11 @@ struct BaseValues
 
 struct BaseLangSysRecord
 {
-  static int cmp (const void *key_, const void *entry_)
-  {
-    hb_tag_t key = * (hb_tag_t *) key_;
-    const BaseLangSysRecord &entry = * (const BaseLangSysRecord *) entry_;
-    return key < (unsigned int) entry.baseLangSysTag ? -1 :
-          key > (unsigned int) entry.baseLangSysTag ? 1 :
-          0;
-  }
+  int cmp (hb_tag_t key) const { return baseLangSysTag.cmp (key); }
+
+  bool has_data () const { return baseLangSysTag; }
 
-  const MinMax &get_min_max () const
-  { return this+minMax; }
+  const MinMax &get_min_max () const { return this+minMax; }
 
   bool sanitize (hb_sanitize_context_t *c, const void *base) const
   {
@@ -303,19 +286,14 @@ struct BaseScript
 {
   const MinMax &get_min_max (hb_tag_t language_tag) const
   {
-    /* TODO Replace hb_bsearch() with .bsearch(). */
-    const BaseLangSysRecord* record = (const BaseLangSysRecord *)
-                                     hb_bsearch (&language_tag, baseLangSysRecords.arrayZ,
-                                                 baseLangSysRecords.len,
-                                                 BaseLangSysRecord::static_size,
-                                                 BaseLangSysRecord::cmp);
-    return record ? record->get_min_max () : this+defaultMinMax;
+    const BaseLangSysRecord& record = baseLangSysRecords.bsearch (language_tag);
+    return record.has_data () ? record.get_min_max () : this+defaultMinMax;
   }
 
   const BaseCoord &get_base_coord (int baseline_tag_index) const
   { return (this+baseValues).get_base_coord (baseline_tag_index); }
 
-  bool is_empty () const { return !baseValues; }
+  bool has_data () const { return baseValues; }
 
   bool sanitize (hb_sanitize_context_t *c) const
   {
@@ -345,14 +323,9 @@ struct BaseScript
 struct BaseScriptList;
 struct BaseScriptRecord
 {
-  static int cmp (const void *key_, const void *entry_)
-  {
-    hb_tag_t key = * (hb_tag_t *) key_;
-    const BaseScriptRecord &entry = * (const BaseScriptRecord *) entry_;
-    return key < (unsigned int) entry.baseScriptTag ? -1 :
-          key > (unsigned int) entry.baseScriptTag ? 1 :
-          0;
-  }
+  int cmp (hb_tag_t key) const { return baseScriptTag.cmp (key); }
+
+  bool has_data () const { return baseScriptTag; }
 
   const BaseScript &get_base_script (const BaseScriptList *list) const
   { return list+baseScript; }
@@ -376,22 +349,11 @@ struct BaseScriptRecord
 
 struct BaseScriptList
 {
-  const BaseScriptRecord *find_record (hb_tag_t script) const
-  {
-    /* TODO Replace hb_bsearch() with .bsearch(). */
-    return (const BaseScriptRecord *) hb_bsearch (&script, baseScriptRecords.arrayZ,
-                                                 baseScriptRecords.len,
-                                                 BaseScriptRecord::static_size,
-                                                 BaseScriptRecord::cmp);
-  }
-
-  /* TODO: Or client should handle fallback? */
   const BaseScript &get_base_script (hb_tag_t script) const
   {
-    const BaseScriptRecord *record = find_record (script);
-    if (!record) record = find_record ((hb_script_t) HB_TAG ('D','F','L','T'));
-
-    return record ? record->get_base_script (this) : Null (BaseScript);
+    const BaseScriptRecord *record = &baseScriptRecords.bsearch (script);
+    if (!record->has_data ()) record = &baseScriptRecords.bsearch (HB_TAG ('D','F','L','T'));
+    return record->has_data () ? record->get_base_script (this) : Null (BaseScript);
   }
 
   bool sanitize (hb_sanitize_context_t *c) const
@@ -411,15 +373,20 @@ struct BaseScriptList
 
 struct Axis
 {
-  bool get_baseline (hb_ot_layout_baseline_t   baseline,
-                           hb_tag_t                  script_tag,
-                           hb_tag_t                  language_tag,
-                           const BaseCoord         **coord) const
+  bool get_baseline (hb_tag_t          baseline_tag,
+                    hb_tag_t          script_tag,
+                    hb_tag_t          language_tag,
+                    const BaseCoord **coord) const
   {
     const BaseScript &base_script = (this+baseScriptList).get_base_script (script_tag);
-    if (base_script.is_empty ()) return false;
+    if (!base_script.has_data ()) return false;
 
-    if (likely (coord)) *coord = &base_script.get_base_coord ((this+baseTagList).bsearch (baseline));
+    if (likely (coord))
+    {
+      unsigned int tag_index = 0;
+      (this+baseTagList).bfind (baseline_tag, &tag_index);
+      *coord = &base_script.get_base_coord (tag_index);
+    }
 
     return true;
   }
@@ -431,7 +398,7 @@ struct Axis
                    const BaseCoord **max_coord) const
   {
     const BaseScript &base_script = (this+baseScriptList).get_base_script (script_tag);
-    if (base_script.is_empty ()) return false;
+    if (!base_script.has_data ()) return false;
 
     base_script.get_min_max (language_tag).get_min_max (feature_tag, min_coord, max_coord);
 
@@ -447,7 +414,7 @@ struct Axis
   }
 
   protected:
-  OffsetTo<SortedArrayOf<Tag> >
+  OffsetTo<SortedArrayOf<Tag>>
                baseTagList;    /* Offset to BaseTagList table, from beginning
                                 * of Axis table (may be NULL)
                                 * Array of 4-byte baseline identification tags — must
@@ -472,20 +439,21 @@ struct BASE
   const VariationStore &get_var_store () const
   { return version.to_int () < 0x00010001u ? Null (VariationStore) : this+varStore; }
 
-  bool get_baseline (hb_font_t               *font,
-                    hb_ot_layout_baseline_t  baseline,
-                    hb_direction_t           direction,
-                    hb_tag_t                 script_tag,
-                    hb_tag_t                 language_tag,
-                    hb_position_t           *base) const
+  bool get_baseline (hb_font_t      *font,
+                    hb_tag_t        baseline_tag,
+                    hb_direction_t  direction,
+                    hb_tag_t        script_tag,
+                    hb_tag_t        language_tag,
+                    hb_position_t  *base) const
   {
-    const BaseCoord *base_coord;
-    if (!get_axis (direction).get_baseline (baseline, script_tag, language_tag, &base_coord))
+    const BaseCoord *base_coord = nullptr;
+    if (unlikely (!get_axis (direction).get_baseline (baseline_tag, script_tag, language_tag, &base_coord) ||
+                 !base_coord || !base_coord->has_data ()))
       return false;
 
-    if (likely (base && base_coord)) *base = base_coord->get_coord (font,
-                                                                   get_var_store (),
-                                                                   direction);
+    if (likely (base))
+      *base = base_coord->get_coord (font, get_var_store (), direction);
+
     return true;
   }
 
index 9b17225..fa08140 100644 (file)
@@ -33,6 +33,7 @@
 #include "hb-ot-layout.hh"
 #include "hb-open-type.hh"
 #include "hb-set.hh"
+#include "hb-bimap.hh"
 
 
 #ifndef HB_MAX_NESTING_LEVEL
@@ -66,6 +67,75 @@ namespace OT {
 #define NOT_COVERED            ((unsigned int) -1)
 
 
+template<typename Iterator>
+static inline void Coverage_serialize (hb_serialize_context_t *c,
+                                      Iterator it);
+
+template<typename Iterator>
+static inline void ClassDef_serialize (hb_serialize_context_t *c,
+                                       Iterator it);
+
+static void ClassDef_remap_and_serialize (hb_serialize_context_t *c,
+                                          const hb_set_t &glyphset,
+                                          const hb_map_t &gid_klass_map,
+                                          hb_sorted_vector_t<HBGlyphID> glyphs,
+                                          hb_sorted_vector_t<unsigned> klasses,
+                                          hb_map_t *klass_map /*INOUT*/);
+
+
+template<typename OutputArray>
+struct subset_offset_array_t
+{
+  subset_offset_array_t
+  (hb_subset_context_t *subset_context,
+   OutputArray& out,
+   const void *src_base,
+   const void *dest_base)
+      : _subset_context(subset_context), _out (out), _src_base (src_base), _dest_base (dest_base) {}
+
+  template <typename T>
+  bool
+  operator ()
+  (T&& offset)
+  {
+    auto *o = _out.serialize_append (_subset_context->serializer);
+    if (unlikely (!o)) return false;
+    auto snap = _subset_context->serializer->snapshot ();
+    bool ret = o->serialize_subset (_subset_context, offset, _src_base, _dest_base);
+    if (!ret)
+    {
+      _out.pop ();
+      _subset_context->serializer->revert (snap);
+    }
+    return ret;
+  }
+
+  private:
+  hb_subset_context_t *_subset_context;
+  OutputArray &_out;
+  const void *_src_base;
+  const void *_dest_base;
+};
+
+/*
+ * Helper to subset an array of offsets. Subsets the thing pointed to by each offset
+ * and discards the offset in the array if the subset operation results in an empty
+ * thing.
+ */
+struct
+{
+  template<typename OutputArray>
+  subset_offset_array_t<OutputArray>
+  operator ()
+  (hb_subset_context_t *subset_context,
+   OutputArray& out,
+   const void *src_base,
+   const void *dest_base) const
+  {
+    return subset_offset_array_t<OutputArray> (subset_context, out, src_base, dest_base);
+  }
+}
+HB_FUNCOBJ (subset_offset_array);
 
 /*
  *
@@ -83,6 +153,26 @@ struct Record_sanitize_closure_t {
   const void *list_base;
 };
 
+struct RecordList_subset_context_t {
+
+  RecordList_subset_context_t() : script_count (0), langsys_count (0)
+  {}
+
+  bool visitScript ()
+  {
+    return script_count++ < HB_MAX_SCRIPTS;
+  }
+
+  bool visitLangSys ()
+  {
+    return langsys_count++ < HB_MAX_LANGSYS;
+  }
+
+  private:
+  unsigned int script_count;
+  unsigned int langsys_count;
+};
+
 template <typename Type>
 struct Record
 {
@@ -104,7 +194,7 @@ struct Record
 };
 
 template <typename Type>
-struct RecordArrayOf : SortedArrayOf<Record<Type> >
+struct RecordArrayOf : SortedArrayOf<Record<Type>>
 {
   const OffsetTo<Type>& get_offset (unsigned int i) const
   { return (*this)[i].offset; }
@@ -139,11 +229,26 @@ struct RecordListOf : RecordArrayOf<Type>
   bool subset (hb_subset_context_t *c) const
   {
     TRACE_SUBSET (this);
-    struct RecordListOf<Type> *out = c->serializer->embed (*this);
-    if (unlikely (!out)) return_trace (false);
+    auto *out = c->serializer->start_embed (*this);
+    if (unlikely (!c->serializer->extend_min (out))) return_trace (false);
+
+    RecordList_subset_context_t record_list_context;
+
     unsigned int count = this->len;
     for (unsigned int i = 0; i < count; i++)
-      out->get_offset (i).serialize_subset (c, (*this)[i], out);
+    {
+      auto *record = out->serialize_append (c->serializer);
+      if (unlikely (!record)) return false;
+      auto snap = c->serializer->snapshot ();
+      if (record->offset.serialize_subset (c, this->get_offset (i), this, out, &record_list_context))
+      {
+        record->tag = this->get_tag(i);
+        continue;
+      }
+      out->pop ();
+      c->serializer->revert (snap);
+    }
+
     return_trace (true);
   }
 
@@ -173,8 +278,8 @@ struct RangeRecord
   bool add_coverage (set_t *glyphs) const
   { return glyphs->add_range (start, end); }
 
-  GlyphID      start;          /* First GlyphID in the range */
-  GlyphID      end;            /* Last GlyphID in the range */
+  HBGlyphID    start;          /* First GlyphID in the range */
+  HBGlyphID    end;            /* Last GlyphID in the range */
   HBUINT16     value;          /* Value */
   public:
   DEFINE_SIZE_STATIC (6);
@@ -208,7 +313,6 @@ struct Script;
 struct LangSys;
 struct Feature;
 
-
 struct LangSys
 {
   unsigned int get_feature_count () const
@@ -227,13 +331,13 @@ struct LangSys
   {
     if (reqFeatureIndex == 0xFFFFu)
       return Index::NOT_FOUND_INDEX;
-   return reqFeatureIndex;;
+   return reqFeatureIndex;
   }
 
-  bool subset (hb_subset_context_t *c) const
+  LangSys* copy (hb_serialize_context_t *c) const
   {
-    TRACE_SUBSET (this);
-    return_trace (c->serializer->embed (*this));
+    TRACE_SERIALIZE (this);
+    return_trace (c->embed (*this));
   }
 
   bool sanitize (hb_sanitize_context_t *c,
@@ -275,15 +379,33 @@ struct Script
   bool has_default_lang_sys () const           { return defaultLangSys != 0; }
   const LangSys& get_default_lang_sys () const { return this+defaultLangSys; }
 
-  bool subset (hb_subset_context_t *c) const
+  bool subset (hb_subset_context_t *c, RecordList_subset_context_t *record_list_context) const
   {
     TRACE_SUBSET (this);
-    struct Script *out = c->serializer->embed (*this);
-    if (unlikely (!out)) return_trace (false);
-    out->defaultLangSys.serialize_subset (c, this+defaultLangSys, out);
-    unsigned int count = langSys.len;
-    for (unsigned int i = 0; i < count; i++)
-      out->langSys.arrayZ[i].offset.serialize_subset (c, this+langSys[i].offset, out);
+    if (!record_list_context->visitScript ()) return_trace (false);
+
+    auto *out = c->serializer->start_embed (*this);
+    if (unlikely (!c->serializer->extend_min (out))) return_trace (false);
+
+    out->defaultLangSys.serialize_copy (c->serializer, defaultLangSys, this, out);
+
+    for (const auto &src: langSys)
+    {
+      if (!record_list_context->visitLangSys ()) {
+        continue;
+      }
+
+      auto snap = c->serializer->snapshot ();
+      auto *lang_sys = c->serializer->embed (src);
+
+      if (likely(lang_sys)
+          && lang_sys->offset.serialize_copy (c->serializer, src.offset, this, out))
+      {
+        out->langSys.len++;
+        continue;
+      }
+      c->serializer->revert (snap);
+    }
     return_trace (true);
   }
 
@@ -500,6 +622,9 @@ struct FeatureParams
 {
   bool sanitize (hb_sanitize_context_t *c, hb_tag_t tag) const
   {
+#ifdef HB_NO_LAYOUT_FEATURE_PARAMS
+    return true;
+#endif
     TRACE_SANITIZE (this);
     if (tag == HB_TAG ('s','i','z','e'))
       return_trace (u.size.sanitize (c));
@@ -510,26 +635,26 @@ struct FeatureParams
     return_trace (true);
   }
 
+#ifndef HB_NO_LAYOUT_FEATURE_PARAMS
   const FeatureParamsSize& get_size_params (hb_tag_t tag) const
   {
     if (tag == HB_TAG ('s','i','z','e'))
       return u.size;
     return Null (FeatureParamsSize);
   }
-
   const FeatureParamsStylisticSet& get_stylistic_set_params (hb_tag_t tag) const
   {
     if ((tag & 0xFFFF0000u) == HB_TAG ('s','s','\0','\0')) /* ssXX */
       return u.stylisticSet;
     return Null (FeatureParamsStylisticSet);
   }
-
   const FeatureParamsCharacterVariants& get_character_variants_params (hb_tag_t tag) const
   {
     if ((tag & 0xFFFF0000u) == HB_TAG ('c','v','\0','\0')) /* cvXX */
       return u.characterVariants;
     return Null (FeatureParamsCharacterVariants);
   }
+#endif
 
   private:
   union {
@@ -538,7 +663,7 @@ struct FeatureParams
   FeatureParamsCharacterVariants       characterVariants;
   } u;
   public:
-  DEFINE_SIZE_STATIC (17);
+  DEFINE_SIZE_MIN (0);
 };
 
 struct Feature
@@ -557,12 +682,12 @@ struct Feature
   const FeatureParams &get_feature_params () const
   { return this+featureParams; }
 
-  bool subset (hb_subset_context_t *c) const
+  bool subset (hb_subset_context_t *c, RecordList_subset_context_t *r) const
   {
     TRACE_SUBSET (this);
-    struct Feature *out = c->serializer->embed (*this);
+    auto *out = c->serializer->embed (*this);
     if (unlikely (!out)) return_trace (false);
-    out->featureParams.set (0); /* TODO(subset) FeatureParams. */
+    out->featureParams = 0; /* TODO(subset) FeatureParams. */
     return_trace (true);
   }
 
@@ -584,25 +709,25 @@ struct Feature
      * Adobe tools, only the 'size' feature had FeatureParams defined.
      */
 
-    OffsetTo<FeatureParams> orig_offset = featureParams;
+    if (likely (featureParams.is_null ()))
+      return_trace (true);
+
+    unsigned int orig_offset = featureParams;
     if (unlikely (!featureParams.sanitize (c, this, closure ? closure->tag : HB_TAG_NONE)))
       return_trace (false);
 
-    if (likely (orig_offset.is_null ()))
-      return_trace (true);
-
     if (featureParams == 0 && closure &&
        closure->tag == HB_TAG ('s','i','z','e') &&
        closure->list_base && closure->list_base < this)
     {
-      unsigned int new_offset_int = (unsigned int) orig_offset -
+      unsigned int new_offset_int = orig_offset -
                                    (((char *) this) - ((char *) closure->list_base));
 
       OffsetTo<FeatureParams> new_offset;
-      /* Check that it did not overflow. */
-      new_offset.set (new_offset_int);
+      /* Check that it would not overflow. */
+      new_offset = new_offset_int;
       if (new_offset == new_offset_int &&
-         c->try_set (&featureParams, new_offset) &&
+         c->try_set (&featureParams, new_offset_int) &&
          !featureParams.sanitize (c, this, closure ? closure->tag : HB_TAG_NONE))
        return_trace (false);
     }
@@ -649,15 +774,18 @@ struct Lookup
   unsigned int get_subtable_count () const { return subTable.len; }
 
   template <typename TSubTable>
-  const TSubTable& get_subtable (unsigned int i) const
-  { return this+CastR<OffsetArrayOf<TSubTable> > (subTable)[i]; }
-
-  template <typename TSubTable>
   const OffsetArrayOf<TSubTable>& get_subtables () const
-  { return CastR<OffsetArrayOf<TSubTable> > (subTable); }
+  { return CastR<OffsetArrayOf<TSubTable>> (subTable); }
   template <typename TSubTable>
   OffsetArrayOf<TSubTable>& get_subtables ()
-  { return CastR<OffsetArrayOf<TSubTable> > (subTable); }
+  { return CastR<OffsetArrayOf<TSubTable>> (subTable); }
+
+  template <typename TSubTable>
+  const TSubTable& get_subtable (unsigned int i) const
+  { return this+get_subtables<TSubTable> ()[i]; }
+  template <typename TSubTable>
+  TSubTable& get_subtable (unsigned int i)
+  { return this+get_subtables<TSubTable> ()[i]; }
 
   unsigned int get_size () const
   {
@@ -683,14 +811,14 @@ struct Lookup
     return flag;
   }
 
-  template <typename TSubTable, typename context_t>
-  typename context_t::return_t dispatch (context_t *c) const
+  template <typename TSubTable, typename context_t, typename ...Ts>
+  typename context_t::return_t dispatch (context_t *c, Ts&&... ds) const
   {
     unsigned int lookup_type = get_type ();
     TRACE_DISPATCH (this, lookup_type);
     unsigned int count = get_subtable_count ();
     for (unsigned int i = 0; i < count; i++) {
-      typename context_t::return_t r = get_subtable<TSubTable> (i).dispatch (c, lookup_type);
+      typename context_t::return_t r = get_subtable<TSubTable> (i).dispatch (c, lookup_type, hb_forward<Ts> (ds)...);
       if (c->stop_sublookup_iteration (r))
        return_trace (r);
     }
@@ -704,40 +832,23 @@ struct Lookup
   {
     TRACE_SERIALIZE (this);
     if (unlikely (!c->extend_min (*this))) return_trace (false);
-    lookupType.set (lookup_type);
-    lookupFlag.set (lookup_props & 0xFFFFu);
+    lookupType = lookup_type;
+    lookupFlag = lookup_props & 0xFFFFu;
     if (unlikely (!subTable.serialize (c, num_subtables))) return_trace (false);
     if (lookupFlag & LookupFlag::UseMarkFilteringSet)
     {
       if (unlikely (!c->extend (*this))) return_trace (false);
       HBUINT16 &markFilteringSet = StructAfter<HBUINT16> (subTable);
-      markFilteringSet.set (lookup_props >> 16);
+      markFilteringSet = lookup_props >> 16;
     }
     return_trace (true);
   }
 
-  /* Older compilers need this to NOT be locally defined in a function. */
-  template <typename TSubTable>
-  struct SubTableSubsetWrapper
-  {
-    SubTableSubsetWrapper (const TSubTable &subtable_,
-                          unsigned int lookup_type_) :
-                            subtable (subtable_),
-                            lookup_type (lookup_type_) {}
-
-    bool subset (hb_subset_context_t *c) const
-    { return subtable.dispatch (c, lookup_type); }
-
-    private:
-    const TSubTable &subtable;
-    unsigned int lookup_type;
-  };
-
   template <typename TSubTable>
   bool subset (hb_subset_context_t *c) const
   {
     TRACE_SUBSET (this);
-    struct Lookup *out = c->serializer->embed (*this);
+    auto *out = c->serializer->embed (*this);
     if (unlikely (!out)) return_trace (false);
 
     /* Subset the actual subtables. */
@@ -747,23 +858,11 @@ struct Lookup
     OffsetArrayOf<TSubTable>& out_subtables = out->get_subtables<TSubTable> ();
     unsigned int count = subTable.len;
     for (unsigned int i = 0; i < count; i++)
-    {
-      SubTableSubsetWrapper<TSubTable> wrapper (this+subtables[i], get_type ());
-
-      out_subtables[i].serialize_subset (c, wrapper, out);
-    }
+      out_subtables[i].serialize_subset (c, subtables[i], this, out, get_type ());
 
     return_trace (true);
   }
 
-  /* Older compilers need this to NOT be locally defined in a function. */
-  template <typename TSubTable>
-  struct SubTableSanitizeWrapper : TSubTable
-  {
-    bool sanitize (hb_sanitize_context_t *c, unsigned int lookup_type) const
-    { return this->dispatch (c, lookup_type); }
-  };
-
   template <typename TSubTable>
   bool sanitize (hb_sanitize_context_t *c) const
   {
@@ -775,16 +874,21 @@ struct Lookup
       if (!markFilteringSet.sanitize (c)) return_trace (false);
     }
 
-    if (unlikely (!CastR<OffsetArrayOf<SubTableSanitizeWrapper<TSubTable> > > (subTable)
-                  .sanitize (c, this, get_type ())))
+    if (unlikely (!get_subtables<TSubTable> ().sanitize (c, this, get_type ())))
       return_trace (false);
 
-    if (unlikely (get_type () == TSubTable::Extension))
+    if (unlikely (get_type () == TSubTable::Extension && !c->get_edit_count ()))
     {
       /* The spec says all subtables of an Extension lookup should
        * have the same type, which shall not be the Extension type
        * itself (but we already checked for that).
-       * This is specially important if one has a reverse type! */
+       * This is specially important if one has a reverse type!
+       *
+       * We only do this if sanitizer edit_count is zero.  Otherwise,
+       * some of the subtables might have become insane after they
+       * were sanity-checked by the edits of subsequent subtables.
+       * https://bugs.chromium.org/p/chromium/issues/detail?id=960331
+       */
       unsigned int type = get_subtable<TSubTable> (0).u.extension.get_type ();
       unsigned int count = get_subtable_count ();
       for (unsigned int i = 1; i < count; i++)
@@ -792,7 +896,6 @@ struct Lookup
          return_trace (false);
     }
     return_trace (true);
-    return_trace (true);
   }
 
   private:
@@ -800,7 +903,7 @@ struct Lookup
   HBUINT16     lookupFlag;             /* Lookup qualifiers */
   ArrayOf<Offset16>
                subTable;               /* Array of SubTables */
-/*HBUINT16     markFilteringSetX[VAR];*//* Index (base 0) into GDEF mark glyph sets
+/*HBUINT16     markFilteringSetX[HB_VAR_ARRAY];*//* Index (base 0) into GDEF mark glyph sets
                                         * structure. This field is only present if bit
                                         * UseMarkFilteringSet of lookup flags is set. */
   public:
@@ -826,8 +929,9 @@ struct CoverageFormat1
     return i;
   }
 
-  bool serialize (hb_serialize_context_t *c,
-                 hb_array_t<const GlyphID> glyphs)
+  template <typename Iterator,
+      hb_requires (hb_is_sorted_source_of (Iterator, hb_codepoint_t))>
+  bool serialize (hb_serialize_context_t *c, Iterator glyphs)
   {
     TRACE_SERIALIZE (this);
     return_trace (glyphArray.serialize (c, glyphs));
@@ -853,19 +957,19 @@ struct CoverageFormat1
 
   template <typename set_t>
   bool add_coverage (set_t *glyphs) const
-  {
-    return glyphs->add_sorted_array (glyphArray.arrayZ, glyphArray.len);
-  }
+  { return glyphs->add_sorted_array (glyphArray.arrayZ, glyphArray.len); }
 
   public:
   /* Older compilers need this to be public. */
-  struct Iter {
+  struct iter_t
+  {
     void init (const struct CoverageFormat1 &c_) { c = &c_; i = 0; }
     void fini () {}
-    bool more () { return i < c->glyphArray.len; }
+    bool more () const { return i < c->glyphArray.len; }
     void next () { i++; }
-    hb_codepoint_t get_glyph () { return c->glyphArray[i]; }
-    unsigned int get_coverage () { return i; }
+    hb_codepoint_t get_glyph () const { return c->glyphArray[i]; }
+    bool operator != (const iter_t& o) const
+    { return i != o.i || c != o.c; }
 
     private:
     const struct CoverageFormat1 *c;
@@ -875,7 +979,7 @@ struct CoverageFormat1
 
   protected:
   HBUINT16     coverageFormat; /* Format identifier--format = 1 */
-  SortedArrayOf<GlyphID>
+  SortedArrayOf<HBGlyphID>
                glyphArray;     /* Array of GlyphIDs--in numerical order */
   public:
   DEFINE_SIZE_ARRAY (4, glyphArray);
@@ -894,38 +998,48 @@ struct CoverageFormat2
           NOT_COVERED;
   }
 
-  bool serialize (hb_serialize_context_t *c,
-                 hb_array_t<const GlyphID> glyphs)
+  template <typename Iterator,
+      hb_requires (hb_is_sorted_source_of (Iterator, hb_codepoint_t))>
+  bool serialize (hb_serialize_context_t *c, Iterator glyphs)
   {
     TRACE_SERIALIZE (this);
     if (unlikely (!c->extend_min (*this))) return_trace (false);
 
-    if (unlikely (!glyphs.length))
+    if (unlikely (!glyphs))
     {
-      rangeRecord.len.set (0);
+      rangeRecord.len = 0;
       return_trace (true);
     }
 
-    unsigned int num_ranges = 1;
-    for (unsigned int i = 1; i < glyphs.length; i++)
-      if (glyphs[i - 1] + 1 != glyphs[i])
+    /* TODO(iter) Write more efficiently? */
+
+    unsigned num_ranges = 0;
+    hb_codepoint_t last = (hb_codepoint_t) -2;
+    for (auto g: glyphs)
+    {
+      if (last + 1 != g)
        num_ranges++;
-    rangeRecord.len.set (num_ranges);
-    if (unlikely (!c->extend (rangeRecord))) return_trace (false);
+      last = g;
+    }
 
-    unsigned int range = 0;
-    rangeRecord[range].start = glyphs[0];
-    rangeRecord[range].value.set (0);
-    for (unsigned int i = 1; i < glyphs.length; i++)
+    if (unlikely (!rangeRecord.serialize (c, num_ranges))) return_trace (false);
+
+    unsigned count = 0;
+    unsigned range = (unsigned) -1;
+    last = (hb_codepoint_t) -2;
+    for (auto g: glyphs)
     {
-      if (glyphs[i - 1] + 1 != glyphs[i])
+      if (last + 1 != g)
       {
        range++;
-       rangeRecord[range].start = glyphs[i];
-       rangeRecord[range].value.set (i);
+       rangeRecord[range].start = g;
+       rangeRecord[range].value = count;
       }
-      rangeRecord[range].end = glyphs[i];
+      rangeRecord[range].end = g;
+      last = g;
+      count++;
     }
+
     return_trace (true);
   }
 
@@ -972,7 +1086,7 @@ struct CoverageFormat2
 
   public:
   /* Older compilers need this to be public. */
-  struct Iter
+  struct iter_t
   {
     void init (const CoverageFormat2 &c_)
     {
@@ -987,7 +1101,7 @@ struct CoverageFormat2
       }
     }
     void fini () {}
-    bool more () { return i < c->rangeRecord.len; }
+    bool more () const { return i < c->rangeRecord.len; }
     void next ()
     {
       if (j >= c->rangeRecord[i].end)
@@ -995,23 +1109,27 @@ struct CoverageFormat2
        i++;
        if (more ())
        {
-         hb_codepoint_t old = j;
+         unsigned int old = coverage;
          j = c->rangeRecord[i].start;
-         if (unlikely (j <= old))
+         coverage = c->rangeRecord[i].value;
+         if (unlikely (coverage != old + 1))
          {
-           /* Broken table. Skip. Important to avoid DoS. */
+           /* Broken table. Skip. Important to avoid DoS.
+            * Also, our callers depend on coverage being
+            * consecutive and monotonically increasing,
+            * ie. iota(). */
           i = c->rangeRecord.len;
           return;
          }
-         coverage = c->rangeRecord[i].value;
        }
        return;
       }
       coverage++;
       j++;
     }
-    hb_codepoint_t get_glyph () { return j; }
-    unsigned int get_coverage () { return coverage; }
+    hb_codepoint_t get_glyph () const { return j; }
+    bool operator != (const iter_t& o) const
+    { return i != o.i || j != o.j || c != o.c; }
 
     private:
     const struct CoverageFormat2 *c;
@@ -1032,6 +1150,15 @@ struct CoverageFormat2
 
 struct Coverage
 {
+  /* Has interface. */
+  static constexpr unsigned SENTINEL = NOT_COVERED;
+  typedef unsigned int value_t;
+  value_t operator [] (hb_codepoint_t k) const { return get (k); }
+  bool has (hb_codepoint_t k) const { return (*this)[k] != SENTINEL; }
+  /* Predicate. */
+  bool operator () (hb_codepoint_t k) const { return has (k); }
+
+  unsigned int get (hb_codepoint_t k) const { return get_coverage (k); }
   unsigned int get_coverage (hb_codepoint_t glyph_id) const
   {
     switch (u.format) {
@@ -1041,17 +1168,24 @@ struct Coverage
     }
   }
 
-  bool serialize (hb_serialize_context_t *c,
-                 hb_array_t<const GlyphID> glyphs)
+  template <typename Iterator,
+      hb_requires (hb_is_sorted_source_of (Iterator, hb_codepoint_t))>
+  bool serialize (hb_serialize_context_t *c, Iterator glyphs)
   {
     TRACE_SERIALIZE (this);
     if (unlikely (!c->extend_min (*this))) return_trace (false);
 
-    unsigned int num_ranges = 1;
-    for (unsigned int i = 1; i < glyphs.length; i++)
-      if (glyphs[i - 1] + 1 != glyphs[i])
+    unsigned count = 0;
+    unsigned num_ranges = 0;
+    hb_codepoint_t last = (hb_codepoint_t) -2;
+    for (auto g: glyphs)
+    {
+      if (last + 1 != g)
        num_ranges++;
-    u.format.set (glyphs.length * 2 < num_ranges * 3 ? 1 : 2);
+      last = g;
+      count++;
+    }
+    u.format = count <= num_ranges * 3 ? 1 : 2;
 
     switch (u.format)
     {
@@ -1061,6 +1195,23 @@ struct Coverage
     }
   }
 
+  bool subset (hb_subset_context_t *c) const
+  {
+    TRACE_SUBSET (this);
+    const hb_set_t &glyphset = *c->plan->glyphset ();
+    const hb_map_t &glyph_map = *c->plan->glyph_map;
+
+    auto it =
+    + iter ()
+    | hb_filter (glyphset)
+    | hb_map_retains_sorting (glyph_map)
+    ;
+
+    bool ret = bool (it);
+    Coverage_serialize (c->serializer, it);
+    return_trace (ret);
+  }
+
   bool sanitize (hb_sanitize_context_t *c) const
   {
     TRACE_SANITIZE (this);
@@ -1105,9 +1256,10 @@ struct Coverage
     }
   }
 
-  struct Iter
+  struct iter_t : hb_iter_with_fallback_t<iter_t, hb_codepoint_t>
   {
-    Iter (const Coverage &c_)
+    static constexpr bool is_sorted_iterator = true;
+    iter_t (const Coverage &c_ = Null(Coverage))
     {
       memset (this, 0, sizeof (*this));
       format = c_.u.format;
@@ -1118,7 +1270,7 @@ struct Coverage
       default:                              return;
       }
     }
-    bool more ()
+    bool __more__ () const
     {
       switch (format)
       {
@@ -1127,7 +1279,7 @@ struct Coverage
       default:return false;
       }
     }
-    void next ()
+    void __next__ ()
     {
       switch (format)
       {
@@ -1136,7 +1288,10 @@ struct Coverage
       default:                  break;
       }
     }
-    hb_codepoint_t get_glyph ()
+    typedef hb_codepoint_t __item_t__;
+    __item_t__ __item__ () const { return get_glyph (); }
+
+    hb_codepoint_t get_glyph () const
     {
       switch (format)
       {
@@ -1145,23 +1300,25 @@ struct Coverage
       default:return 0;
       }
     }
-    unsigned int get_coverage ()
+    bool operator != (const iter_t& o) const
     {
+      if (format != o.format) return true;
       switch (format)
       {
-      case 1: return u.format1.get_coverage ();
-      case 2: return u.format2.get_coverage ();
-      default:return -1;
+      case 1: return u.format1 != o.u.format1;
+      case 2: return u.format2 != o.u.format2;
+      default:return false;
       }
     }
 
     private:
     unsigned int format;
     union {
-    CoverageFormat2::Iter      format2; /* Put this one first since it's larger; helps shut up compiler. */
-    CoverageFormat1::Iter      format1;
+    CoverageFormat2::iter_t    format2; /* Put this one first since it's larger; helps shut up compiler. */
+    CoverageFormat1::iter_t    format1;
     } u;
   };
+  iter_t iter () const { return iter_t (*this); }
 
   protected:
   union {
@@ -1173,15 +1330,51 @@ struct Coverage
   DEFINE_SIZE_UNION (2, format);
 };
 
+template<typename Iterator>
+static inline void
+Coverage_serialize (hb_serialize_context_t *c,
+                    Iterator it)
+{ c->start_embed<Coverage> ()->serialize (c, it); }
+
+static void ClassDef_remap_and_serialize (hb_serialize_context_t *c,
+                                          const hb_set_t &glyphset,
+                                          const hb_map_t &gid_klass_map,
+                                          hb_sorted_vector_t<HBGlyphID> glyphs,
+                                          hb_sorted_vector_t<unsigned> klasses,
+                                          hb_map_t *klass_map /*INOUT*/)
+{
+  bool has_no_match = glyphset.get_population () > gid_klass_map.get_population ();
+  
+  hb_map_t m;
+  if (!klass_map) klass_map = &m;
+
+  if (has_no_match) klass_map->set (0, 0);
+  unsigned idx = klass_map->has (0) ? 1 : 0;
+  for (const unsigned k: klasses.iter ())
+  {
+    if (klass_map->has (k)) continue;
+    klass_map->set (k, idx);
+    idx++;
+  }
+  
+  auto it =
+  + glyphs.iter ()
+  | hb_map_retains_sorting ([&] (const HBGlyphID& gid) -> hb_pair_t<hb_codepoint_t, HBUINT16>
+                            {
+                              HBUINT16 new_klass;
+                              new_klass = klass_map->get (gid_klass_map[gid]);
+                              return hb_pair ((hb_codepoint_t)gid, new_klass);
+                            })
+  ;
+  
+  c->propagate_error (glyphs, klasses);
+  ClassDef_serialize (c, it);
+}
 
 /*
  * Class Definition Table
  */
 
-static inline void ClassDef_serialize (hb_serialize_context_t *c,
-                                      hb_array_t<const GlyphID> glyphs,
-                                      hb_array_t<const HBUINT16> klasses);
-
 struct ClassDefFormat1
 {
   friend struct ClassDef;
@@ -1192,54 +1385,54 @@ struct ClassDefFormat1
     return classValue[(unsigned int) (glyph_id - startGlyph)];
   }
 
+  template<typename Iterator,
+          hb_requires (hb_is_iterator (Iterator))>
   bool serialize (hb_serialize_context_t *c,
-                 hb_array_t<const HBUINT16> glyphs,
-                 hb_array_t<const HBUINT16> klasses)
+                  Iterator it)
   {
     TRACE_SERIALIZE (this);
     if (unlikely (!c->extend_min (*this))) return_trace (false);
 
-    if (unlikely (!glyphs.length))
+    if (unlikely (!it))
     {
-      startGlyph.set (0);
-      classValue.len.set (0);
+      startGlyph = 0;
+      classValue.len = 0;
       return_trace (true);
     }
 
-    hb_codepoint_t glyph_min = glyphs[0];
-    hb_codepoint_t glyph_max = glyphs[glyphs.length - 1];
-
-    startGlyph.set (glyph_min);
-    classValue.len.set (glyph_max - glyph_min + 1);
-    if (unlikely (!c->extend (classValue))) return_trace (false);
-
-    for (unsigned int i = 0; i < glyphs.length; i++)
-      classValue[glyphs[i] - glyph_min] = klasses[i];
-
+    startGlyph = (*it).first;
+    classValue.serialize (c, + it
+                             | hb_map (hb_second));
     return_trace (true);
   }
 
-  bool subset (hb_subset_context_t *c) const
+  bool subset (hb_subset_context_t *c,
+               hb_map_t *klass_map = nullptr /*OUT*/) const
   {
     TRACE_SUBSET (this);
     const hb_set_t &glyphset = *c->plan->glyphset ();
     const hb_map_t &glyph_map = *c->plan->glyph_map;
-    hb_vector_t<GlyphID> glyphs;
-    hb_vector_t<HBUINT16> klasses;
+   
+    hb_sorted_vector_t<HBGlyphID> glyphs;
+    hb_sorted_vector_t<unsigned> orig_klasses;
+    hb_map_t gid_org_klass_map;
 
     hb_codepoint_t start = startGlyph;
     hb_codepoint_t end   = start + classValue.len;
-    for (hb_codepoint_t g = start; g < end; g++)
+    for (const hb_codepoint_t gid : + hb_range (start, end)
+                                   | hb_filter (glyphset))
     {
-      unsigned int value = classValue[g - start];
-      if (!value) continue;
-      if (!glyphset.has (g)) continue;
-      glyphs.push()->set (glyph_map[g]);
-      klasses.push()->set (value);
+      unsigned klass = classValue[gid - start];
+      if (!klass) continue;
+
+      glyphs.push (glyph_map[gid]);
+      gid_org_klass_map.set (glyph_map[gid], klass);
+      orig_klasses.push (klass);
     }
-    c->serializer->propagate_error (glyphs, klasses);
-    ClassDef_serialize (c->serializer, glyphs, klasses);
-    return_trace (glyphs.length);
+
+    ClassDef_remap_and_serialize (c->serializer, glyphset, gid_org_klass_map,
+                                  glyphs, orig_klasses, klass_map);
+    return_trace ((bool) glyphs);
   }
 
   bool sanitize (hb_sanitize_context_t *c) const
@@ -1311,7 +1504,7 @@ struct ClassDefFormat1
 
   protected:
   HBUINT16     classFormat;    /* Format identifier--format = 1 */
-  GlyphID      startGlyph;     /* First GlyphID of the classValueArray */
+  HBGlyphID    startGlyph;     /* First GlyphID of the classValueArray */
   ArrayOf<HBUINT16>
                classValue;     /* Array of Class Values--one per GlyphID */
   public:
@@ -1328,69 +1521,90 @@ struct ClassDefFormat2
     return rangeRecord.bsearch (glyph_id).value;
   }
 
+  template<typename Iterator,
+          hb_requires (hb_is_iterator (Iterator))>
   bool serialize (hb_serialize_context_t *c,
-                 hb_array_t<const HBUINT16> glyphs,
-                 hb_array_t<const HBUINT16> klasses)
+                  Iterator it)
   {
     TRACE_SERIALIZE (this);
     if (unlikely (!c->extend_min (*this))) return_trace (false);
 
-    if (unlikely (!glyphs.length))
+    if (unlikely (!it))
     {
-      rangeRecord.len.set (0);
+      rangeRecord.len = 0;
       return_trace (true);
     }
 
-    unsigned int num_ranges = 1;
-    for (unsigned int i = 1; i < glyphs.length; i++)
-      if (glyphs[i - 1] + 1 != glyphs[i] ||
-         klasses[i - 1] != klasses[i])
-       num_ranges++;
-    rangeRecord.len.set (num_ranges);
-    if (unlikely (!c->extend (rangeRecord))) return_trace (false);
+    unsigned num_ranges = 1;
+    hb_codepoint_t prev_gid = (*it).first;
+    unsigned prev_klass = (*it).second;
+
+    RangeRecord range_rec;
+    range_rec.start = prev_gid;
+    range_rec.end = prev_gid;
+    range_rec.value = prev_klass;
+
+    RangeRecord *record = c->copy (range_rec);
+    if (unlikely (!record)) return_trace (false);
 
-    unsigned int range = 0;
-    rangeRecord[range].start = glyphs[0];
-    rangeRecord[range].value.set (klasses[0]);
-    for (unsigned int i = 1; i < glyphs.length; i++)
+    for (const auto gid_klass_pair : + (++it))
     {
-      if (glyphs[i - 1] + 1 != glyphs[i] ||
-         klasses[i - 1] != klasses[i])
+      hb_codepoint_t cur_gid = gid_klass_pair.first;
+      unsigned cur_klass = gid_klass_pair.second;
+
+      if (cur_gid != prev_gid + 1 ||
+          cur_klass != prev_klass)
       {
-       range++;
-       rangeRecord[range].start = glyphs[i];
-       rangeRecord[range].value = klasses[i];
+        if (unlikely (!record)) break;
+        record->end = prev_gid;
+        num_ranges++;
+
+        range_rec.start = cur_gid;
+        range_rec.end = cur_gid;
+        range_rec.value = cur_klass;
+
+        record = c->copy (range_rec);
       }
-      rangeRecord[range].end = glyphs[i];
+
+      prev_klass = cur_klass;
+      prev_gid = cur_gid;
     }
+
+    if (likely (record)) record->end = prev_gid;
+    rangeRecord.len = num_ranges;
     return_trace (true);
   }
 
-  bool subset (hb_subset_context_t *c) const
+  bool subset (hb_subset_context_t *c,
+               hb_map_t *klass_map = nullptr /*OUT*/) const
   {
     TRACE_SUBSET (this);
     const hb_set_t &glyphset = *c->plan->glyphset ();
     const hb_map_t &glyph_map = *c->plan->glyph_map;
-    hb_vector_t<GlyphID> glyphs;
-    hb_vector_t<HBUINT16> klasses;
 
-    unsigned int count = rangeRecord.len;
-    for (unsigned int i = 0; i < count; i++)
+    hb_sorted_vector_t<HBGlyphID> glyphs;
+    hb_sorted_vector_t<unsigned> orig_klasses;
+    hb_map_t gid_org_klass_map;
+
+    unsigned count = rangeRecord.len;
+    for (unsigned i = 0; i < count; i++)
     {
-      unsigned int value = rangeRecord[i].value;
-      if (!value) continue;
+      unsigned klass = rangeRecord[i].value;
+      if (!klass) continue;
       hb_codepoint_t start = rangeRecord[i].start;
       hb_codepoint_t end   = rangeRecord[i].end + 1;
       for (hb_codepoint_t g = start; g < end; g++)
       {
        if (!glyphset.has (g)) continue;
-       glyphs.push ()->set (glyph_map[g]);
-       klasses.push ()->set (value);
+       glyphs.push (glyph_map[g]);
+        gid_org_klass_map.set (glyph_map[g], klass);
+        orig_klasses.push (klass);
       }
     }
-    c->serializer->propagate_error (glyphs, klasses);
-    ClassDef_serialize (c->serializer, glyphs, klasses);
-    return_trace (glyphs.length);
+
+    ClassDef_remap_and_serialize (c->serializer, glyphset, gid_org_klass_map,
+                                  glyphs, orig_klasses, klass_map);
+    return_trace ((bool) glyphs);
   }
 
   bool sanitize (hb_sanitize_context_t *c) const
@@ -1468,6 +1682,15 @@ struct ClassDefFormat2
 
 struct ClassDef
 {
+  /* Has interface. */
+  static constexpr unsigned SENTINEL = 0;
+  typedef unsigned int value_t;
+  value_t operator [] (hb_codepoint_t k) const { return get (k); }
+  bool has (hb_codepoint_t k) const { return (*this)[k] != SENTINEL; }
+  /* Projection. */
+  hb_codepoint_t operator () (hb_codepoint_t k) const { return get (k); }
+
+  unsigned int get (hb_codepoint_t k) const { return get_class (k); }
   unsigned int get_class (hb_codepoint_t glyph_id) const
   {
     switch (u.format) {
@@ -1477,44 +1700,57 @@ struct ClassDef
     }
   }
 
-  bool serialize (hb_serialize_context_t *c,
-                 hb_array_t<const GlyphID> glyphs,
-                 hb_array_t<const HBUINT16> klasses)
+  template<typename Iterator,
+          hb_requires (hb_is_iterator (Iterator))>
+  bool serialize (hb_serialize_context_t *c, Iterator it)
   {
     TRACE_SERIALIZE (this);
     if (unlikely (!c->extend_min (*this))) return_trace (false);
 
-    unsigned int format = 2;
-    if (glyphs.length)
+    unsigned format = 2;
+    if (likely (it))
     {
-      hb_codepoint_t glyph_min = glyphs[0];
-      hb_codepoint_t glyph_max = glyphs[glyphs.length - 1];
+      hb_codepoint_t glyph_min = (*it).first;
+      hb_codepoint_t glyph_max = + it
+                                | hb_map (hb_first)
+                                 | hb_reduce (hb_max, 0u);
 
-      unsigned int num_ranges = 1;
-      for (unsigned int i = 1; i < glyphs.length; i++)
-       if (glyphs[i - 1] + 1 != glyphs[i] ||
-           klasses[i - 1] != klasses[i])
-         num_ranges++;
+      unsigned num_ranges = 1;
+      hb_codepoint_t prev_gid = glyph_min;
+      unsigned prev_klass = (*it).second;
+
+      for (const auto gid_klass_pair : it)
+      {
+        hb_codepoint_t cur_gid = gid_klass_pair.first;
+        unsigned cur_klass = gid_klass_pair.second;
+        if (cur_gid != prev_gid + 1 ||
+            cur_klass != prev_klass)
+          num_ranges++;
+
+        prev_gid = cur_gid;
+        prev_klass = cur_klass;
+      }
 
       if (1 + (glyph_max - glyph_min + 1) < num_ranges * 3)
-        format = 1;
+       format = 1;
     }
-    u.format.set (format);
+    u.format = format;
 
     switch (u.format)
     {
-    case 1: return_trace (u.format1.serialize (c, glyphs, klasses));
-    case 2: return_trace (u.format2.serialize (c, glyphs, klasses));
+    case 1: return_trace (u.format1.serialize (c, it));
+    case 2: return_trace (u.format2.serialize (c, it));
     default:return_trace (false);
     }
   }
 
-  bool subset (hb_subset_context_t *c) const
+  bool subset (hb_subset_context_t *c,
+               hb_map_t *klass_map = nullptr /*OUT*/) const
   {
     TRACE_SUBSET (this);
     switch (u.format) {
-    case 1: return_trace (u.format1.subset (c));
-    case 2: return_trace (u.format2.subset (c));
+    case 1: return_trace (u.format1.subset (c, klass_map));
+    case 2: return_trace (u.format2.subset (c, klass_map));
     default:return_trace (false);
     }
   }
@@ -1581,10 +1817,10 @@ struct ClassDef
   DEFINE_SIZE_UNION (2, format);
 };
 
+template<typename Iterator>
 static inline void ClassDef_serialize (hb_serialize_context_t *c,
-                                      hb_array_t<const GlyphID> glyphs,
-                                      hb_array_t<const HBUINT16> klasses)
-{ c->start_embed<ClassDef> ()->serialize (c, glyphs, klasses); }
+                                       Iterator it)
+{ c->start_embed<ClassDef> ()->serialize (c, it); }
 
 
 /*
@@ -1662,6 +1898,21 @@ struct VarRegionList
                  axesZ.sanitize (c, (unsigned int) axisCount * (unsigned int) regionCount));
   }
 
+  bool serialize (hb_serialize_context_t *c, const VarRegionList *src, const hb_bimap_t &region_map)
+  {
+    TRACE_SERIALIZE (this);
+    VarRegionList *out = c->allocate_min<VarRegionList> ();
+    if (unlikely (!out)) return_trace (false);
+    axisCount = src->axisCount;
+    regionCount = region_map.get_population ();
+    if (unlikely (!c->allocate_size<VarRegionList> (get_size () - min_size))) return_trace (false);
+    for (unsigned int r = 0; r < regionCount; r++)
+      memcpy (&axesZ[axisCount * r], &src->axesZ[axisCount * region_map.backward (r)], VarRegionAxis::static_size * axisCount);
+
+    return_trace (true);
+  }
+
+  unsigned int get_size () const { return min_size + VarRegionAxis::static_size * axisCount * regionCount; }
   unsigned int get_region_count () const { return regionCount; }
 
   protected:
@@ -1694,7 +1945,7 @@ struct VarData
    unsigned int count = regionIndices.len;
    unsigned int scount = shortCount;
 
-   const HBUINT8 *bytes = &StructAfter<HBUINT8> (regionIndices);
+   const HBUINT8 *bytes = get_delta_bytes ();
    const HBUINT8 *row = bytes + inner * (scount + count);
 
    float delta = 0.;
@@ -1717,15 +1968,15 @@ struct VarData
   }
 
   void get_scalars (int *coords, unsigned int coord_count,
-                    const VarRegionList &regions,
-                    float *scalars /*OUT */,
-                    unsigned int num_scalars) const
+                   const VarRegionList &regions,
+                   float *scalars /*OUT */,
+                   unsigned int num_scalars) const
   {
-    assert (num_scalars == regionIndices.len);
-   for (unsigned int i = 0; i < num_scalars; i++)
-   {
-     scalars[i] = regions.evaluate (regionIndices.arrayZ[i], coords, coord_count);
-   }
+    unsigned count = hb_min (num_scalars, regionIndices.len);
+    for (unsigned int i = 0; i < count; i++)
+      scalars[i] = regions.evaluate (regionIndices.arrayZ[i], coords, coord_count);
+    for (unsigned int i = count; i < num_scalars; i++)
+      scalars[i] = 0.f;
   }
 
   bool sanitize (hb_sanitize_context_t *c) const
@@ -1734,11 +1985,117 @@ struct VarData
     return_trace (c->check_struct (this) &&
                  regionIndices.sanitize (c) &&
                  shortCount <= regionIndices.len &&
-                 c->check_range (&StructAfter<HBUINT8> (regionIndices),
+                 c->check_range (get_delta_bytes (),
                                  itemCount,
                                  get_row_size ()));
   }
 
+  bool serialize (hb_serialize_context_t *c,
+                 const VarData *src,
+                 const hb_inc_bimap_t &inner_map,
+                 const hb_bimap_t &region_map)
+  {
+    TRACE_SERIALIZE (this);
+    if (unlikely (!c->extend_min (*this))) return_trace (false);
+    itemCount = inner_map.get_next_value ();
+
+    /* Optimize short count */
+    unsigned short ri_count = src->regionIndices.len;
+    enum delta_size_t { kZero=0, kByte, kShort };
+    hb_vector_t<delta_size_t> delta_sz;
+    hb_vector_t<unsigned int> ri_map;  /* maps old index to new index */
+    delta_sz.resize (ri_count);
+    ri_map.resize (ri_count);
+    unsigned int new_short_count = 0;
+    unsigned int r;
+    for (r = 0; r < ri_count; r++)
+    {
+      delta_sz[r] = kZero;
+      for (unsigned int i = 0; i < inner_map.get_next_value (); i++)
+      {
+       unsigned int old = inner_map.backward (i);
+       int16_t delta = src->get_item_delta (old, r);
+       if (delta < -128 || 127 < delta)
+       {
+         delta_sz[r] = kShort;
+         new_short_count++;
+         break;
+       }
+       else if (delta != 0)
+         delta_sz[r] = kByte;
+      }
+    }
+    unsigned int short_index = 0;
+    unsigned int byte_index = new_short_count;
+    unsigned int new_ri_count = 0;
+    for (r = 0; r < ri_count; r++)
+      if (delta_sz[r])
+      {
+       ri_map[r] = (delta_sz[r] == kShort)? short_index++ : byte_index++;
+       new_ri_count++;
+      }
+
+    shortCount = new_short_count;
+    regionIndices.len = new_ri_count;
+
+    unsigned int size = regionIndices.get_size () - HBUINT16::static_size/*regionIndices.len*/ + (get_row_size () * itemCount);
+    if (unlikely (!c->allocate_size<HBUINT8> (size)))
+      return_trace (false);
+
+    for (r = 0; r < ri_count; r++)
+      if (delta_sz[r]) regionIndices[ri_map[r]] = region_map[src->regionIndices[r]];
+
+    for (unsigned int i = 0; i < itemCount; i++)
+    {
+      unsigned int     old = inner_map.backward (i);
+      for (unsigned int r = 0; r < ri_count; r++)
+       if (delta_sz[r]) set_item_delta (i, ri_map[r], src->get_item_delta (old, r));
+    }
+
+    return_trace (true);
+  }
+
+  void collect_region_refs (hb_inc_bimap_t &region_map, const hb_inc_bimap_t &inner_map) const
+  {
+    for (unsigned int r = 0; r < regionIndices.len; r++)
+    {
+      unsigned int region = regionIndices[r];
+      if (region_map.has (region)) continue;
+      for (unsigned int i = 0; i < inner_map.get_next_value (); i++)
+       if (get_item_delta (inner_map.backward (i), r) != 0)
+       {
+         region_map.add (region);
+         break;
+       }
+    }
+  }
+
+  protected:
+  const HBUINT8 *get_delta_bytes () const
+  { return &StructAfter<HBUINT8> (regionIndices); }
+
+  HBUINT8 *get_delta_bytes ()
+  { return &StructAfter<HBUINT8> (regionIndices); }
+
+  int16_t get_item_delta (unsigned int item, unsigned int region) const
+  {
+    if ( item >= itemCount || unlikely (region >= regionIndices.len)) return 0;
+    const HBINT8 *p = (const HBINT8 *)get_delta_bytes () + item * get_row_size ();
+    if (region < shortCount)
+      return ((const HBINT16 *)p)[region];
+    else
+      return (p + HBINT16::static_size * shortCount)[region - shortCount];
+  }
+
+  void set_item_delta (unsigned int item, unsigned int region, int16_t delta)
+  {
+    HBINT8 *p = (HBINT8 *)get_delta_bytes () + item * get_row_size ();
+    if (region < shortCount)
+      ((HBINT16 *)p)[region] = delta;
+    else
+      (p + HBINT16::static_size * shortCount)[region - shortCount] = delta;
+  }
+
   protected:
   HBUINT16             itemCount;
   HBUINT16             shortCount;
@@ -1753,8 +2110,12 @@ struct VariationStore
   float get_delta (unsigned int outer, unsigned int inner,
                   const int *coords, unsigned int coord_count) const
   {
+#ifdef HB_NO_VAR
+    return 0.f;
+#endif
+
     if (unlikely (outer >= dataSets.len))
-      return 0.;
+      return 0.f;
 
     return (this+dataSets[outer]).get_delta (inner,
                                             coords, coord_count,
@@ -1771,6 +2132,10 @@ struct VariationStore
 
   bool sanitize (hb_sanitize_context_t *c) const
   {
+#ifdef HB_NO_VAR
+    return true;
+#endif
+
     TRACE_SANITIZE (this);
     return_trace (c->check_struct (this) &&
                  format == 1 &&
@@ -1778,6 +2143,43 @@ struct VariationStore
                  dataSets.sanitize (c, this));
   }
 
+  bool serialize (hb_serialize_context_t *c,
+                 const VariationStore *src,
+                 const hb_array_t <hb_inc_bimap_t> &inner_maps)
+  {
+    TRACE_SERIALIZE (this);
+    unsigned int set_count = 0;
+    for (unsigned int i = 0; i < inner_maps.length; i++)
+      if (inner_maps[i].get_population () > 0) set_count++;
+
+    unsigned int size = min_size + HBUINT32::static_size * set_count;
+    if (unlikely (!c->allocate_size<HBUINT32> (size))) return_trace (false);
+    format = 1;
+
+    hb_inc_bimap_t region_map;
+    for (unsigned int i = 0; i < inner_maps.length; i++)
+      (src+src->dataSets[i]).collect_region_refs (region_map, inner_maps[i]);
+    region_map.sort ();
+
+    if (unlikely (!regions.serialize (c, this)
+                 .serialize (c, &(src+src->regions), region_map))) return_trace (false);
+
+    /* TODO: The following code could be simplified when
+     * OffsetListOf::subset () can take a custom param to be passed to VarData::serialize ()
+     */
+    dataSets.len = set_count;
+    unsigned int set_index = 0;
+    for (unsigned int i = 0; i < inner_maps.length; i++)
+    {
+      if (inner_maps[i].get_population () == 0) continue;
+      if (unlikely (!dataSets[set_index++].serialize (c, this)
+                     .serialize (c, &(src+src->dataSets[i]), inner_maps[i], region_map)))
+       return_trace (false);
+    }
+
+    return_trace (true);
+  }
+
   unsigned int get_region_index_count (unsigned int ivs) const
   { return (this+dataSets[ivs]).get_region_index_count (); }
 
@@ -1786,10 +2188,18 @@ struct VariationStore
                    float *scalars /*OUT*/,
                    unsigned int num_scalars) const
   {
+#ifdef HB_NO_VAR
+    for (unsigned i = 0; i < num_scalars; i++)
+      scalars[i] = 0.f;
+    return;
+#endif
+
     (this+dataSets[ivs]).get_scalars (coords, coord_count, this+regions,
-                                      &scalars[0], num_scalars);
+                                     &scalars[0], num_scalars);
   }
 
+  unsigned int get_sub_table_count () const { return dataSets.len; }
+
   protected:
   HBUINT16                             format;
   LOffsetTo<VarRegionList>             regions;
@@ -1975,10 +2385,10 @@ struct FeatureVariations
     return (this+record.substitutions).find_substitute (feature_index);
   }
 
-  bool subset (hb_subset_context_t *c) const
+  FeatureVariations* copy (hb_serialize_context_t *c) const
   {
-    TRACE_SUBSET (this);
-    return_trace (c->serializer->embed (*this));
+    TRACE_SERIALIZE (this);
+    return_trace (c->embed (*this));
   }
 
   bool sanitize (hb_sanitize_context_t *c) const
@@ -2014,6 +2424,8 @@ struct HintingDevice
   hb_position_t get_y_delta (hb_font_t *font) const
   { return get_delta (font->y_ppem, font->y_scale); }
 
+  public:
+
   unsigned int get_size () const
   {
     unsigned int f = deltaFormat;
@@ -2027,6 +2439,12 @@ struct HintingDevice
     return_trace (c->check_struct (this) && c->check_range (this, this->get_size ()));
   }
 
+  HintingDevice* copy (hb_serialize_context_t *c) const
+  {
+    TRACE_SERIALIZE (this);
+    return_trace (c->embed<HintingDevice> (this));
+  }
+
   private:
 
   int get_delta (unsigned int ppem, int scale) const
@@ -2088,6 +2506,12 @@ struct VariationDevice
   hb_position_t get_y_delta (hb_font_t *font, const VariationStore &store) const
   { return font->em_scalef_y (get_delta (font, store)); }
 
+  VariationDevice* copy (hb_serialize_context_t *c) const
+  {
+    TRACE_SERIALIZE (this);
+    return_trace (c->embed<VariationDevice> (this));
+  }
+
   bool sanitize (hb_sanitize_context_t *c) const
   {
     TRACE_SANITIZE (this);
@@ -2126,10 +2550,14 @@ struct Device
   {
     switch (u.b.format)
     {
+#ifndef HB_NO_HINTING
     case 1: case 2: case 3:
       return u.hinting.get_x_delta (font);
+#endif
+#ifndef HB_NO_VAR
     case 0x8000:
       return u.variation.get_x_delta (font, store);
+#endif
     default:
       return 0;
     }
@@ -2139,9 +2567,13 @@ struct Device
     switch (u.b.format)
     {
     case 1: case 2: case 3:
+#ifndef HB_NO_HINTING
       return u.hinting.get_y_delta (font);
+#endif
+#ifndef HB_NO_VAR
     case 0x8000:
       return u.variation.get_y_delta (font, store);
+#endif
     default:
       return 0;
     }
@@ -2152,20 +2584,45 @@ struct Device
     TRACE_SANITIZE (this);
     if (!u.b.format.sanitize (c)) return_trace (false);
     switch (u.b.format) {
+#ifndef HB_NO_HINTING
     case 1: case 2: case 3:
       return_trace (u.hinting.sanitize (c));
+#endif
+#ifndef HB_NO_VAR
     case 0x8000:
       return_trace (u.variation.sanitize (c));
+#endif
     default:
       return_trace (true);
     }
   }
 
+  Device* copy (hb_serialize_context_t *c) const
+  {
+    TRACE_SERIALIZE (this);
+    switch (u.b.format) {
+#ifndef HB_NO_HINTING
+    case 1:
+    case 2:
+    case 3:
+      return_trace (reinterpret_cast<Device *> (u.hinting.copy (c)));
+#endif
+#ifndef HB_NO_VAR
+    case 0x8000:
+      return_trace (reinterpret_cast<Device *> (u.variation.copy (c)));
+#endif
+    default:
+      return_trace (nullptr);
+    }
+  }
+
   protected:
   union {
   DeviceHeader         b;
   HintingDevice                hinting;
+#ifndef HB_NO_VAR
   VariationDevice      variation;
+#endif
   } u;
   public:
   DEFINE_SIZE_UNION (6, b);
index 06c26fb..dc751d8 100644 (file)
@@ -149,8 +149,8 @@ struct CaretValueFormat3
                                 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);
+          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 sanitize (hb_sanitize_context_t *c) const
@@ -220,7 +220,7 @@ struct LigGlyph
   {
     if (caret_count)
     {
-      hb_array_t <const OffsetTo<CaretValue> > array = carets.sub_array (start_offset, caret_count);
+      hb_array_t <const OffsetTo<CaretValue>> array = carets.sub_array (start_offset, caret_count);
       unsigned int count = array.length;
       for (unsigned int i = 0; i < count; i++)
        caret_array[i] = (this+array[i]).get_caret_value (font, direction, glyph_id, var_store);
@@ -296,7 +296,7 @@ struct MarkGlyphSetsFormat1
 
   protected:
   HBUINT16     format;                 /* Format identifier--format = 1 */
-  ArrayOf<LOffsetTo<Coverage> >
+  ArrayOf<LOffsetTo<Coverage>>
                coverage;               /* Array of long offsets to mark set
                                         * coverage tables */
   public:
@@ -439,19 +439,19 @@ struct GDEF
   bool subset (hb_subset_context_t *c) const
   {
     TRACE_SUBSET (this);
-    struct GDEF *out = c->serializer->embed (*this);
+    auto *out = c->serializer->embed (*this);
     if (unlikely (!out)) return_trace (false);
 
-    out->glyphClassDef.serialize_subset (c, this+glyphClassDef, out);
-    out->attachList.set (0);//TODO(subset) serialize_subset (c, this+attachList, out);
-    out->ligCaretList.set (0);//TODO(subset) serialize_subset (c, this+ligCaretList, out);
-    out->markAttachClassDef.serialize_subset (c, this+markAttachClassDef, out);
+    out->glyphClassDef.serialize_subset (c, glyphClassDef, this, out);
+    out->attachList = 0;//TODO(subset) serialize_subset (c, attachList, this, out);
+    out->ligCaretList = 0;//TODO(subset) serialize_subset (c, ligCaretList, this, out);
+    out->markAttachClassDef.serialize_subset (c, markAttachClassDef, this, out);
 
     if (version.to_int () >= 0x00010002u)
-      out->markGlyphSetsDef.set (0);// TODO(subset) serialize_subset (c, this+markGlyphSetsDef, out);
+      out->markGlyphSetsDef = 0;// TODO(subset) serialize_subset (c, markGlyphSetsDef, this, out);
 
     if (version.to_int () >= 0x00010003u)
-      out->varStore.set (0);// TODO(subset) serialize_subset (c, this+varStore, out);
+      out->varStore = 0;// TODO(subset) serialize_subset (c, varStore, this, out);
 
     return_trace (true);
   }
index e17a282..024312d 100644 (file)
@@ -101,10 +101,10 @@ struct ValueFormat : HBUINT16
   unsigned int get_len () const  { return hb_popcount ((unsigned int) *this); }
   unsigned int get_size () const { return get_len () * Value::static_size; }
 
-  bool apply_value (hb_ot_apply_context_t   *c,
-                   const void           *base,
-                   const Value          *values,
-                   hb_glyph_position_t  &glyph_pos) const
+  bool apply_value (hb_ot_apply_context_t *c,
+                   const void            *base,
+                   const Value           *values,
+                   hb_glyph_position_t   &glyph_pos) const
   {
     bool ret = false;
     unsigned int format = *this;
@@ -173,15 +173,15 @@ struct ValueFormat : HBUINT16
     return true;
   }
 
-  static OffsetTo<Device>& get_device (Value* value)
-  { return *CastP<OffsetTo<Device> > (value); }
-  static const OffsetTo<Device>& get_device (const Value* value, bool *worked=nullptr)
+  HB_INTERNAL static OffsetTo<Device>& get_device (Value* value)
+  { return *CastP<OffsetTo<Device>> (value); }
+  HB_INTERNAL static const OffsetTo<Device>& get_device (const Value* value, bool *worked=nullptr)
   {
     if (worked) *worked |= bool (*value);
-    return *CastP<OffsetTo<Device> > (value);
+    return *CastP<OffsetTo<Device>> (value);
   }
 
-  static const HBINT16& get_short (const Value* value, bool *worked=nullptr)
+  HB_INTERNAL static const HBINT16& get_short (const Value* value, bool *worked=nullptr)
   {
     if (worked) *worked |= bool (*value);
     return *CastP<HBINT16> (value);
@@ -236,6 +236,11 @@ struct ValueFormat : HBUINT16
   }
 };
 
+template<typename Iterator>
+static inline void SinglePos_serialize (hb_serialize_context_t *c,
+                                       Iterator it,
+                                       ValueFormat valFormat);
+
 
 struct AnchorFormat1
 {
@@ -253,6 +258,12 @@ struct AnchorFormat1
     return_trace (c->check_struct (this));
   }
 
+  AnchorFormat1* copy (hb_serialize_context_t *c) const
+  {
+    TRACE_SERIALIZE (this);
+    return_trace (c->embed<AnchorFormat1> (this));
+  }
+
   protected:
   HBUINT16     format;                 /* Format identifier--format = 1 */
   FWORD                xCoordinate;            /* Horizontal value--in design units */
@@ -267,6 +278,13 @@ struct AnchorFormat2
                   float *x, float *y) const
   {
     hb_font_t *font = c->font;
+
+#ifdef HB_NO_HINTING
+    *x = font->em_fscale_x (xCoordinate);
+    *y = font->em_fscale_y (yCoordinate);
+    return;
+#endif
+
     unsigned int x_ppem = font->x_ppem;
     unsigned int y_ppem = font->y_ppem;
     hb_position_t cx = 0, cy = 0;
@@ -284,6 +302,12 @@ struct AnchorFormat2
     return_trace (c->check_struct (this));
   }
 
+  AnchorFormat2* copy (hb_serialize_context_t *c) const
+  {
+    TRACE_SERIALIZE (this);
+    return_trace (c->embed<AnchorFormat2> (this));
+  }
+
   protected:
   HBUINT16     format;                 /* Format identifier--format = 2 */
   FWORD                xCoordinate;            /* Horizontal value--in design units */
@@ -314,6 +338,17 @@ struct AnchorFormat3
     return_trace (c->check_struct (this) && xDeviceTable.sanitize (c, this) && yDeviceTable.sanitize (c, this));
   }
 
+  AnchorFormat3* copy (hb_serialize_context_t *c) const
+  {
+    TRACE_SERIALIZE (this);
+    auto *out = c->embed<AnchorFormat3> (this);
+    if (unlikely (!out)) return_trace (nullptr);
+
+    out->xDeviceTable.serialize_copy (c, xDeviceTable, this, out);
+    out->yDeviceTable.serialize_copy (c, yDeviceTable, this, out);
+    return_trace (out);
+  }
+
   protected:
   HBUINT16     format;                 /* Format identifier--format = 3 */
   FWORD                xCoordinate;            /* Horizontal value--in design units */
@@ -356,6 +391,17 @@ struct Anchor
     }
   }
 
+  Anchor* copy (hb_serialize_context_t *c) const
+  {
+    TRACE_SERIALIZE (this);
+    switch (u.format) {
+    case 1: return_trace (reinterpret_cast<Anchor *> (u.format1.copy (c)));
+    case 2: return_trace (reinterpret_cast<Anchor *> (u.format2.copy (c)));
+    case 3: return_trace (reinterpret_cast<Anchor *> (u.format3.copy (c)));
+    default:return_trace (nullptr);
+    }
+  }
+
   protected:
   union {
   HBUINT16             format;         /* Format identifier */
@@ -393,7 +439,7 @@ struct AnchorMatrix
 
   HBUINT16     rows;                   /* Number of rows */
   protected:
-  UnsizedArrayOf<OffsetTo<Anchor> >
+  UnsizedArrayOf<OffsetTo<Anchor>>
                matrixZ;                /* Matrix of offsets to Anchor tables--
                                         * from beginning of AnchorMatrix table */
   public:
@@ -446,8 +492,8 @@ struct MarkArray : ArrayOf<MarkRecord>      /* Array of MarkRecords--in Coverage orde
     glyph_anchor.get_anchor (c, buffer->info[glyph_pos].codepoint, &base_x, &base_y);
 
     hb_glyph_position_t &o = buffer->cur_pos();
-    o.x_offset = round (base_x - mark_x);
-    o.y_offset = round (base_y - mark_y);
+    o.x_offset = roundf (base_x - mark_x);
+    o.y_offset = roundf (base_y - mark_y);
     o.attach_type() = ATTACH_TYPE_MARK;
     o.attach_chain() = (int) glyph_pos - (int) buffer->idx;
     buffer->scratch_flags |= HB_BUFFER_SCRATCH_FLAG_HAS_GPOS_ATTACHMENT;
@@ -489,11 +535,42 @@ struct SinglePosFormat1
     return_trace (true);
   }
 
+  template<typename Iterator,
+          hb_requires (hb_is_iterator (Iterator))>
+  void serialize (hb_serialize_context_t *c,
+                 Iterator it,
+                 ValueFormat valFormat)
+  {
+    if (unlikely (!c->extend_min (*this))) return;
+    if (unlikely (!c->check_assign (valueFormat, valFormat))) return;
+
+    for (const auto &_ : hb_second (*it))
+      c->copy (_);
+
+    auto glyphs =
+    + it
+    | hb_map_retains_sorting (hb_first)
+    ;
+
+    coverage.serialize (c, this).serialize (c, glyphs);
+  }
+
   bool subset (hb_subset_context_t *c) const
   {
     TRACE_SUBSET (this);
-    // TODO(subset)
-    return_trace (false);
+    const hb_set_t &glyphset = *c->plan->glyphset ();
+    const hb_map_t &glyph_map = *c->plan->glyph_map;
+
+    auto it =
+    + hb_iter (this+coverage)
+    | hb_filter (glyphset)
+    | hb_map_retains_sorting (glyph_map)
+    | hb_zip (hb_repeat (values.as_array (valueFormat.get_len ())))
+    ;
+
+    bool ret = bool (it);
+    SinglePos_serialize (c->serializer, it, valueFormat);
+    return_trace (ret);
   }
 
   bool sanitize (hb_sanitize_context_t *c) const
@@ -545,11 +622,51 @@ struct SinglePosFormat2
     return_trace (true);
   }
 
+  template<typename Iterator,
+          hb_requires (hb_is_iterator (Iterator))>
+  void serialize (hb_serialize_context_t *c,
+                 Iterator it,
+                 ValueFormat valFormat)
+  {
+    if (unlikely (!c->extend_min (*this))) return;
+    if (unlikely (!c->check_assign (valueFormat, valFormat))) return;
+    if (unlikely (!c->check_assign (valueCount, it.len ()))) return;
+
+    for (const auto iter : it)
+      for (const auto &_ : iter.second)
+       c->copy (_);
+
+    auto glyphs =
+    + it
+    | hb_map_retains_sorting (hb_first)
+    ;
+
+    coverage.serialize (c, this).serialize (c, glyphs);
+  }
+
   bool subset (hb_subset_context_t *c) const
   {
     TRACE_SUBSET (this);
-    // TODO(subset)
-    return_trace (false);
+    const hb_set_t &glyphset = *c->plan->glyphset ();
+    const hb_map_t &glyph_map = *c->plan->glyph_map;
+
+    unsigned sub_length = valueFormat.get_len ();
+    auto values_array = values.as_array (valueCount * sub_length);
+
+    auto it =
+    + hb_zip (this+coverage, hb_range ((unsigned) valueCount))
+    | hb_filter (glyphset, hb_first)
+    | hb_map_retains_sorting ([&] (const hb_pair_t<hb_codepoint_t, unsigned>& _)
+                             {
+                               return hb_pair (glyph_map[_.first],
+                                               values_array.sub_array (_.second * sub_length,
+                                                                       sub_length));
+                             })
+    ;
+
+    bool ret = bool (it);
+    SinglePos_serialize (c->serializer, it, valueFormat);
+    return_trace (ret);
   }
 
   bool sanitize (hb_sanitize_context_t *c) const
@@ -576,14 +693,50 @@ struct SinglePosFormat2
 
 struct SinglePos
 {
-  template <typename context_t>
-  typename context_t::return_t dispatch (context_t *c) const
+  template<typename Iterator,
+          hb_requires (hb_is_iterator (Iterator))>
+  unsigned get_format (Iterator glyph_val_iter_pairs)
+  {
+    hb_array_t<const Value> first_val_iter = hb_second (*glyph_val_iter_pairs);
+
+    for (const auto iter : glyph_val_iter_pairs)
+      for (const auto _ : hb_zip (iter.second, first_val_iter))
+       if (_.first != _.second)
+         return 2;
+
+    return 1;
+  }
+
+
+  template<typename Iterator,
+          hb_requires (hb_is_iterator (Iterator))>
+  void serialize (hb_serialize_context_t *c,
+                 Iterator glyph_val_iter_pairs,
+                 ValueFormat valFormat)
+  {
+    if (unlikely (!c->extend_min (u.format))) return;
+    unsigned format = 2;
+
+    if (glyph_val_iter_pairs) format = get_format (glyph_val_iter_pairs);
+
+    u.format = format;
+    switch (u.format) {
+    case 1: u.format1.serialize (c, glyph_val_iter_pairs, valFormat);
+           return;
+    case 2: u.format2.serialize (c, glyph_val_iter_pairs, valFormat);
+           return;
+    default:return;
+    }
+  }
+
+  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));
-    case 2: return_trace (c->dispatch (u.format2));
+    case 1: return_trace (c->dispatch (u.format1, hb_forward<Ts> (ds)...));
+    case 2: return_trace (c->dispatch (u.format2, hb_forward<Ts> (ds)...));
     default:return_trace (c->default_return_value ());
     }
   }
@@ -596,13 +749,32 @@ struct SinglePos
   } u;
 };
 
+template<typename Iterator>
+static inline void
+SinglePos_serialize (hb_serialize_context_t *c,
+                    Iterator it,
+                    ValueFormat valFormat)
+{ c->start_embed<SinglePos> ()->serialize (c, it, valFormat); }
+
 
 struct PairValueRecord
 {
   friend struct PairSet;
 
+  bool serialize (hb_serialize_context_t *c,
+                  unsigned length,
+                  const hb_map_t &glyph_map) const
+  {
+    TRACE_SERIALIZE (this);
+    auto *out = c->start_embed (*this);
+    if (unlikely (!c->extend_min (out))) return_trace (false);
+    
+    out->secondGlyph = glyph_map[secondGlyph];
+    return_trace (c->copy (values, length));
+  }
+
   protected:
-  GlyphID      secondGlyph;            /* GlyphID of second glyph in the
+  HBGlyphID    secondGlyph;            /* GlyphID of second glyph in the
                                         * pair--first glyph is listed in the
                                         * Coverage table */
   ValueRecord  values;                 /* Positioning data for the first glyph
@@ -616,7 +788,7 @@ struct PairSet
   friend struct PairPosFormat1;
 
   bool intersects (const hb_set_t *glyphs,
-                         const ValueFormat *valueFormats) const
+                  const ValueFormat *valueFormats) const
   {
     unsigned int len1 = valueFormats[0].get_len ();
     unsigned int len2 = valueFormats[1].get_len ();
@@ -686,6 +858,37 @@ struct PairSet
     return_trace (false);
   }
 
+  bool subset (hb_subset_context_t *c,
+               const ValueFormat valueFormats[2]) const
+  {
+    TRACE_SUBSET (this);
+    auto snap = c->serializer->snapshot ();
+
+    auto *out = c->serializer->start_embed (*this);
+    if (unlikely (!c->serializer->extend_min (out))) return_trace (false);
+    out->len = 0;
+
+    const hb_set_t &glyphset = *c->plan->glyphset ();
+    const hb_map_t &glyph_map = *c->plan->glyph_map;
+
+    unsigned len1 = valueFormats[0].get_len ();
+    unsigned len2 = valueFormats[1].get_len ();
+    unsigned record_size = HBUINT16::static_size + Value::static_size * (len1 + len2);
+
+    const PairValueRecord *record = &firstPairValueRecord;
+    unsigned count = len, num = 0;
+    for (unsigned i = 0; i < count; i++)
+    {
+      if (!glyphset.has (record->secondGlyph)) continue;
+      if (record->serialize (c->serializer, len1 + len2, glyph_map)) num++;
+      record = &StructAtOffset<const PairValueRecord> (record, record_size);
+    }
+
+    out->len = num;
+    if (!num) c->serializer->revert (snap);
+    return_trace (num);
+  }
+
   struct sanitize_closure_t
   {
     const void *base;
@@ -722,16 +925,14 @@ struct PairPosFormat1
 {
   bool intersects (const hb_set_t *glyphs) const
   {
-    unsigned int count = pairSet.len;
-    for (Coverage::Iter iter (this+coverage); iter.more (); iter.next ())
-    {
-      if (unlikely (iter.get_coverage () >= count))
-       break; /* Work around malicious fonts. https://github.com/harfbuzz/harfbuzz/issues/363 */
-      if (glyphs->has (iter.get_glyph ()) &&
-         (this+pairSet[iter.get_coverage ()]).intersects (glyphs, valueFormat))
-       return true;
-    }
-    return false;
+    return
+    + hb_zip (this+coverage, pairSet)
+    | hb_filter (*glyphs, hb_first)
+    | hb_map (hb_second)
+    | hb_map ([glyphs, this] (const OffsetTo<PairSet> &_)
+             { return (this+_).intersects (glyphs, valueFormat); })
+    | hb_any
+    ;
   }
 
   void collect_glyphs (hb_collect_glyphs_context_t *c) const
@@ -761,8 +962,43 @@ struct PairPosFormat1
   bool subset (hb_subset_context_t *c) const
   {
     TRACE_SUBSET (this);
-    // TODO(subset)
-    return_trace (false);
+
+    const hb_set_t &glyphset = *c->plan->glyphset ();
+    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);
+    out->format = format;
+    out->valueFormat[0] = valueFormat[0];
+    out->valueFormat[1] = valueFormat[1];
+
+    hb_sorted_vector_t<hb_codepoint_t> new_coverage;
+
+    + hb_zip (this+coverage, pairSet)
+    | hb_filter (glyphset, hb_first)
+    | hb_filter ([this, c, out] (const OffsetTo<PairSet>& _)
+                {
+                  auto *o = out->pairSet.serialize_append (c->serializer);
+                  if (unlikely (!o)) return false;
+                  auto snap = c->serializer->snapshot ();
+                  bool ret = o->serialize_subset (c, _, this, out, valueFormat);
+                  if (!ret)
+                  {
+                    out->pairSet.pop ();
+                    c->serializer->revert (snap);
+                  }
+                  return ret;
+                },
+                hb_second)
+    | hb_map (hb_first)
+    | hb_map (glyph_map)
+    | hb_sink (new_coverage)
+    ;
+
+    out->coverage.serialize (c->serializer, out)
+                .serialize (c->serializer, new_coverage.iter ());
+
+    return_trace (bool (new_coverage));
   }
 
   bool sanitize (hb_sanitize_context_t *c) const
@@ -853,8 +1089,49 @@ struct PairPosFormat2
   bool subset (hb_subset_context_t *c) const
   {
     TRACE_SUBSET (this);
-    // TODO(subset)
-    return_trace (false);
+    auto *out = c->serializer->start_embed (*this);
+    if (unlikely (!c->serializer->extend_min (out))) return_trace (false);
+    out->format = format;
+    out->valueFormat1 = valueFormat1;
+    out->valueFormat2 = valueFormat2;
+
+    hb_map_t klass1_map;
+    out->classDef1.serialize_subset (c, classDef1, this, out, &klass1_map);
+    out->class1Count = klass1_map.get_population ();
+
+    hb_map_t klass2_map;
+    out->classDef2.serialize_subset (c, classDef2, this, out, &klass2_map);
+    out->class2Count = klass2_map.get_population ();
+
+    unsigned record_len = valueFormat1.get_len () + valueFormat2.get_len ();
+
+    + hb_range ((unsigned) class1Count)
+    | hb_filter (klass1_map)
+    | hb_apply ([&] (const unsigned class1_idx)
+                {
+                  + hb_range ((unsigned) class2Count)
+                  | hb_filter (klass2_map)
+                  | hb_apply ([&] (const unsigned class2_idx)
+                              {
+                                unsigned idx = (class1_idx * (unsigned) class2Count + class2_idx) * record_len;
+                                for (unsigned i = 0; i < record_len; i++)
+                                  c->serializer->copy (values[idx+i]);
+                              })
+                  ;
+                })
+    ;
+
+    const hb_set_t &glyphset = *c->plan->glyphset ();
+    const hb_map_t &glyph_map = *c->plan->glyph_map;
+
+    auto it =
+    + hb_iter (this+coverage)
+    | hb_filter (glyphset)
+    | hb_map_retains_sorting (glyph_map)
+    ;
+
+    out->coverage.serialize (c->serializer, out).serialize (c->serializer, it);
+    return_trace (out->class1Count && out->class2Count && bool (it));
   }
 
   bool sanitize (hb_sanitize_context_t *c) const
@@ -909,14 +1186,14 @@ struct PairPosFormat2
 
 struct PairPos
 {
-  template <typename context_t>
-  typename context_t::return_t dispatch (context_t *c) const
+  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));
-    case 2: return_trace (c->dispatch (u.format2));
+    case 1: return_trace (c->dispatch (u.format1, hb_forward<Ts> (ds)...));
+    case 2: return_trace (c->dispatch (u.format2, hb_forward<Ts> (ds)...));
     default:return_trace (c->default_return_value ());
     }
   }
@@ -940,6 +1217,19 @@ struct EntryExitRecord
     return_trace (entryAnchor.sanitize (c, base) && exitAnchor.sanitize (c, base));
   }
 
+  EntryExitRecord* copy (hb_serialize_context_t *c,
+                        const void *src_base,
+                        const void *dst_base) const
+  {
+    TRACE_SERIALIZE (this);
+    auto *out = c->embed (this);
+    if (unlikely (!out)) return_trace (nullptr);
+
+    out->entryAnchor.serialize_copy (c, entryAnchor, src_base, dst_base);
+    out->exitAnchor.serialize_copy (c, exitAnchor, src_base, dst_base);
+    return_trace (out);
+  }
+
   protected:
   OffsetTo<Anchor>
                entryAnchor;            /* Offset to EntryAnchor table--from
@@ -995,32 +1285,32 @@ struct CursivePosFormat1
     /* Main-direction adjustment */
     switch (c->direction) {
       case HB_DIRECTION_LTR:
-       pos[i].x_advance  = round (exit_x) + pos[i].x_offset;
+       pos[i].x_advance  = roundf (exit_x) + pos[i].x_offset;
 
-       d = round (entry_x) + pos[j].x_offset;
+       d = roundf (entry_x) + pos[j].x_offset;
        pos[j].x_advance -= d;
        pos[j].x_offset  -= d;
        break;
       case HB_DIRECTION_RTL:
-       d = round (exit_x) + pos[i].x_offset;
+       d = roundf (exit_x) + pos[i].x_offset;
        pos[i].x_advance -= d;
        pos[i].x_offset  -= d;
 
-       pos[j].x_advance  = round (entry_x) + pos[j].x_offset;
+       pos[j].x_advance  = roundf (entry_x) + pos[j].x_offset;
        break;
       case HB_DIRECTION_TTB:
-       pos[i].y_advance  = round (exit_y) + pos[i].y_offset;
+       pos[i].y_advance  = roundf (exit_y) + pos[i].y_offset;
 
-       d = round (entry_y) + pos[j].y_offset;
+       d = roundf (entry_y) + pos[j].y_offset;
        pos[j].y_advance -= d;
        pos[j].y_offset  -= d;
        break;
       case HB_DIRECTION_BTT:
-       d = round (exit_y) + pos[i].y_offset;
+       d = roundf (exit_y) + pos[i].y_offset;
        pos[i].y_advance -= d;
        pos[i].y_offset  -= d;
 
-       pos[j].y_advance  = round (entry_y);
+       pos[j].y_advance  = roundf (entry_y);
        break;
       case HB_DIRECTION_INVALID:
       default:
@@ -1067,11 +1357,47 @@ struct CursivePosFormat1
     return_trace (true);
   }
 
+  template <typename Iterator,
+           hb_requires (hb_is_iterator (Iterator))>
+  void serialize (hb_serialize_context_t *c,
+                 Iterator it,
+                 const void *src_base)
+  {
+    if (unlikely (!c->extend_min ((*this)))) return;
+    this->format = 1;
+    this->entryExitRecord.len = it.len ();
+
+    for (const EntryExitRecord& entry_record : + it
+                                              | hb_map (hb_second))
+      c->copy (entry_record, src_base, this);
+
+    auto glyphs =
+    + it
+    | hb_map_retains_sorting (hb_first)
+    ;
+
+    coverage.serialize (c, this).serialize (c, glyphs);
+  }
+
   bool subset (hb_subset_context_t *c) const
   {
     TRACE_SUBSET (this);
-    // TODO(subset)
-    return_trace (false);
+    const hb_set_t &glyphset = *c->plan->glyphset ();
+    const hb_map_t &glyph_map = *c->plan->glyph_map;
+
+    auto *out = c->serializer->start_embed (*this);
+    if (unlikely (!out)) return_trace (false);
+
+    auto it =
+    + hb_zip (this+coverage, entryExitRecord)
+    | hb_filter (glyphset, hb_first)
+    | hb_map_retains_sorting ([&] (hb_pair_t<hb_codepoint_t, const EntryExitRecord&> p) -> hb_pair_t<hb_codepoint_t, const EntryExitRecord&>
+                             { return hb_pair (glyph_map[p.first], p.second);})
+    ;
+
+    bool ret = bool (it);
+    out->serialize (c->serializer, it, this);
+    return_trace (ret);
   }
 
   bool sanitize (hb_sanitize_context_t *c) const
@@ -1094,13 +1420,13 @@ struct CursivePosFormat1
 
 struct CursivePos
 {
-  template <typename context_t>
-  typename context_t::return_t dispatch (context_t *c) const
+  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));
+    case 1: return_trace (c->dispatch (u.format1, hb_forward<Ts> (ds)...));
     default:return_trace (c->default_return_value ());
     }
   }
@@ -1210,13 +1536,13 @@ struct MarkBasePosFormat1
 
 struct MarkBasePos
 {
-  template <typename context_t>
-  typename context_t::return_t dispatch (context_t *c) const
+  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));
+    case 1: return_trace (c->dispatch (u.format1, hb_forward<Ts> (ds)...));
     default:return_trace (c->default_return_value ());
     }
   }
@@ -1289,7 +1615,7 @@ struct MarkLigPosFormat1
     unsigned int mark_id = _hb_glyph_info_get_lig_id (&buffer->cur());
     unsigned int mark_comp = _hb_glyph_info_get_lig_comp (&buffer->cur());
     if (lig_id && lig_id == mark_id && mark_comp > 0)
-      comp_index = MIN (comp_count, _hb_glyph_info_get_lig_comp (&buffer->cur())) - 1;
+      comp_index = hb_min (comp_count, _hb_glyph_info_get_lig_comp (&buffer->cur())) - 1;
     else
       comp_index = comp_count - 1;
 
@@ -1335,13 +1661,13 @@ struct MarkLigPosFormat1
 
 struct MarkLigPos
 {
-  template <typename context_t>
-  typename context_t::return_t dispatch (context_t *c) const
+  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));
+    case 1: return_trace (c->dispatch (u.format1, hb_forward<Ts> (ds)...));
     default:return_trace (c->default_return_value ());
     }
   }
@@ -1457,13 +1783,13 @@ struct MarkMarkPosFormat1
 
 struct MarkMarkPos
 {
-  template <typename context_t>
-  typename context_t::return_t dispatch (context_t *c) const
+  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));
+    case 1: return_trace (c->dispatch (u.format1, hb_forward<Ts> (ds)...));
     default:return_trace (c->default_return_value ());
     }
   }
@@ -1509,20 +1835,20 @@ struct PosLookupSubTable
     Extension          = 9
   };
 
-  template <typename context_t>
-  typename context_t::return_t dispatch (context_t *c, unsigned int lookup_type) const
+  template <typename context_t, typename ...Ts>
+  typename context_t::return_t dispatch (context_t *c, unsigned int lookup_type, Ts&&... ds) const
   {
     TRACE_DISPATCH (this, lookup_type);
     switch (lookup_type) {
-    case Single:               return_trace (u.single.dispatch (c));
-    case Pair:                 return_trace (u.pair.dispatch (c));
-    case Cursive:              return_trace (u.cursive.dispatch (c));
-    case MarkBase:             return_trace (u.markBase.dispatch (c));
-    case MarkLig:              return_trace (u.markLig.dispatch (c));
-    case MarkMark:             return_trace (u.markMark.dispatch (c));
-    case Context:              return_trace (u.context.dispatch (c));
-    case ChainContext:         return_trace (u.chainContext.dispatch (c));
-    case Extension:            return_trace (u.extension.dispatch (c));
+    case Single:               return_trace (u.single.dispatch (c, hb_forward<Ts> (ds)...));
+    case Pair:                 return_trace (u.pair.dispatch (c, hb_forward<Ts> (ds)...));
+    case Cursive:              return_trace (u.cursive.dispatch (c, hb_forward<Ts> (ds)...));
+    case MarkBase:             return_trace (u.markBase.dispatch (c, hb_forward<Ts> (ds)...));
+    case MarkLig:              return_trace (u.markLig.dispatch (c, hb_forward<Ts> (ds)...));
+    case MarkMark:             return_trace (u.markMark.dispatch (c, hb_forward<Ts> (ds)...));
+    case Context:              return_trace (u.context.dispatch (c, hb_forward<Ts> (ds)...));
+    case ChainContext:         return_trace (u.chainContext.dispatch (c, hb_forward<Ts> (ds)...));
+    case Extension:            return_trace (u.extension.dispatch (c, hb_forward<Ts> (ds)...));
     default:                   return_trace (c->default_return_value ());
     }
   }
@@ -1578,14 +1904,14 @@ struct PosLookup : Lookup
     dispatch (&c);
   }
 
-  static bool apply_recurse_func (hb_ot_apply_context_t *c, unsigned int lookup_index);
+  HB_INTERNAL static bool apply_recurse_func (hb_ot_apply_context_t *c, unsigned int lookup_index);
 
   template <typename context_t>
   static typename context_t::return_t dispatch_recurse_func (context_t *c, unsigned int lookup_index);
 
-  template <typename context_t>
-  typename context_t::return_t dispatch (context_t *c) const
-  { return Lookup::dispatch<SubTable> (c); }
+  template <typename context_t, typename ...Ts>
+  typename context_t::return_t dispatch (context_t *c, Ts&&... ds) const
+  { return Lookup::dispatch<SubTable> (c, hb_forward<Ts> (ds)...); }
 
   bool subset (hb_subset_context_t *c) const
   { return Lookup::subset<SubTable> (c); }
@@ -1732,13 +2058,13 @@ struct GPOS_accelerator_t : GPOS::accelerator_t {};
 
 /* Out-of-class implementation for methods recursing */
 
+#ifndef HB_NO_OT_LAYOUT
 template <typename context_t>
 /*static*/ inline typename context_t::return_t PosLookup::dispatch_recurse_func (context_t *c, unsigned int lookup_index)
 {
   const PosLookup &l = c->face->table.GPOS.get_relaxed ()->table->get_lookup (lookup_index);
   return l.dispatch (c);
 }
-
 /*static*/ inline bool PosLookup::apply_recurse_func (hb_ot_apply_context_t *c, unsigned int lookup_index)
 {
   const PosLookup &l = c->face->table.GPOS.get_relaxed ()->table->get_lookup (lookup_index);
@@ -1751,6 +2077,7 @@ template <typename context_t>
   c->set_lookup_props (saved_lookup_props);
   return ret;
 }
+#endif
 
 
 } /* namespace OT */
index cc10634..fc21cb0 100644 (file)
 
 namespace OT {
 
+typedef hb_pair_t<hb_codepoint_t, hb_codepoint_t> hb_codepoint_pair_t;
 
+template<typename Iterator>
 static inline void SingleSubst_serialize (hb_serialize_context_t *c,
-                                         hb_array_t<const GlyphID> glyphs,
-                                         hb_array_t<const GlyphID> substitutes);
+                                         Iterator it);
+
 
 struct SingleSubstFormat1
 {
@@ -46,35 +48,28 @@ struct SingleSubstFormat1
 
   void closure (hb_closure_context_t *c) const
   {
-    for (Coverage::Iter iter (this+coverage); iter.more (); iter.next ())
-    {
-      /* TODO Switch to range-based API to work around malicious fonts.
-       * https://github.com/harfbuzz/harfbuzz/issues/363 */
-      hb_codepoint_t glyph_id = iter.get_glyph ();
-      if (c->glyphs->has (glyph_id))
-       c->out->add ((glyph_id + deltaGlyphID) & 0xFFFFu);
-    }
+    unsigned d = deltaGlyphID;
+    + hb_iter (this+coverage)
+    | hb_filter (*c->glyphs)
+    | hb_map ([d] (hb_codepoint_t g) { return (g + d) & 0xFFFFu; })
+    | hb_sink (c->output)
+    ;
   }
 
   void collect_glyphs (hb_collect_glyphs_context_t *c) const
   {
     if (unlikely (!(this+coverage).add_coverage (c->input))) return;
-    for (Coverage::Iter iter (this+coverage); iter.more (); iter.next ())
-    {
-      /* TODO Switch to range-based API to work around malicious fonts.
-       * https://github.com/harfbuzz/harfbuzz/issues/363 */
-      hb_codepoint_t glyph_id = iter.get_glyph ();
-      c->output->add ((glyph_id + deltaGlyphID) & 0xFFFFu);
-    }
+    unsigned d = deltaGlyphID;
+    + hb_iter (this+coverage)
+    | hb_map ([d] (hb_codepoint_t g) { return (g + d) & 0xFFFFu; })
+    | hb_sink (c->output)
+    ;
   }
 
   const Coverage &get_coverage () const { return this+coverage; }
 
   bool would_apply (hb_would_apply_context_t *c) const
-  {
-    TRACE_WOULD_APPLY (this);
-    return_trace (c->len == 1 && (this+coverage).get_coverage (c->glyphs[0]) != NOT_COVERED);
-  }
+  { return c->len == 1 && (this+coverage).get_coverage (c->glyphs[0]) != NOT_COVERED; }
 
   bool apply (hb_ot_apply_context_t *c) const
   {
@@ -91,34 +86,41 @@ struct SingleSubstFormat1
     return_trace (true);
   }
 
+  template<typename Iterator,
+          hb_requires (hb_is_sorted_source_of (Iterator, hb_codepoint_t))>
   bool serialize (hb_serialize_context_t *c,
-                 hb_array_t<const GlyphID> glyphs,
-                 int delta)
+                 Iterator glyphs,
+                 unsigned delta)
   {
     TRACE_SERIALIZE (this);
     if (unlikely (!c->extend_min (*this))) return_trace (false);
     if (unlikely (!coverage.serialize (c, this).serialize (c, glyphs))) return_trace (false);
-    deltaGlyphID.set (delta); /* TODO(serialize) overflow? */
+    c->check_assign (deltaGlyphID, delta);
     return_trace (true);
   }
 
   bool subset (hb_subset_context_t *c) const
   {
     TRACE_SUBSET (this);
-    const hb_set_t &glyphset = *c->plan->glyphset ();
+    const hb_set_t &glyphset = *c->plan->glyphset_gsub ();
     const hb_map_t &glyph_map = *c->plan->glyph_map;
-    hb_vector_t<GlyphID> from;
-    hb_vector_t<GlyphID> to;
+
     hb_codepoint_t delta = deltaGlyphID;
-    for (Coverage::Iter iter (this+coverage); iter.more (); iter.next ())
-    {
-      if (!glyphset.has (iter.get_glyph ())) continue;
-      from.push ()->set (glyph_map[iter.get_glyph ()]);
-      to.push ()->set (glyph_map[(iter.get_glyph () + delta) & 0xFFFF]);
-    }
-    c->serializer->propagate_error (from, to);
-    SingleSubst_serialize (c->serializer, from, to);
-    return_trace (from.length);
+
+    auto it =
+    + hb_iter (this+coverage)
+    | hb_filter (glyphset)
+    | hb_map_retains_sorting ([&] (hb_codepoint_t g) {
+                               return hb_codepoint_pair_t (g,
+                                                           (g + delta) & 0xFFFF); })
+    | hb_filter (glyphset, hb_second)
+    | hb_map_retains_sorting ([&] (hb_codepoint_pair_t p) -> hb_codepoint_pair_t
+                             { return hb_pair (glyph_map[p.first], glyph_map[p.second]); })
+    ;
+
+    bool ret = bool (it);
+    SingleSubst_serialize (c->serializer, it);
+    return_trace (ret);
   }
 
   bool sanitize (hb_sanitize_context_t *c) const
@@ -132,8 +134,8 @@ struct SingleSubstFormat1
   OffsetTo<Coverage>
                coverage;               /* Offset to Coverage table--from
                                         * beginning of Substitution table */
-  HBINT16      deltaGlyphID;           /* Add to original GlyphID to get
-                                        * substitute GlyphID */
+  HBUINT16     deltaGlyphID;           /* Add to original GlyphID to get
+                                        * substitute GlyphID, modulo 0x10000 */
   public:
   DEFINE_SIZE_STATIC (6);
 };
@@ -145,35 +147,26 @@ struct SingleSubstFormat2
 
   void closure (hb_closure_context_t *c) const
   {
-    unsigned int count = substitute.len;
-    for (Coverage::Iter iter (this+coverage); iter.more (); iter.next ())
-    {
-      if (unlikely (iter.get_coverage () >= count))
-        break; /* Work around malicious fonts. https://github.com/harfbuzz/harfbuzz/issues/363 */
-      if (c->glyphs->has (iter.get_glyph ()))
-       c->out->add (substitute[iter.get_coverage ()]);
-    }
+    + hb_zip (this+coverage, substitute)
+    | hb_filter (*c->glyphs, hb_first)
+    | hb_map (hb_second)
+    | hb_sink (c->output)
+    ;
   }
 
   void collect_glyphs (hb_collect_glyphs_context_t *c) const
   {
     if (unlikely (!(this+coverage).add_coverage (c->input))) return;
-    unsigned int count = substitute.len;
-    for (Coverage::Iter iter (this+coverage); iter.more (); iter.next ())
-    {
-      if (unlikely (iter.get_coverage () >= count))
-        break; /* Work around malicious fonts. https://github.com/harfbuzz/harfbuzz/issues/363 */
-      c->output->add (substitute[iter.get_coverage ()]);
-    }
+    + hb_zip (this+coverage, substitute)
+    | hb_map (hb_second)
+    | hb_sink (c->output)
+    ;
   }
 
   const Coverage &get_coverage () const { return this+coverage; }
 
   bool would_apply (hb_would_apply_context_t *c) const
-  {
-    TRACE_WOULD_APPLY (this);
-    return_trace (c->len == 1 && (this+coverage).get_coverage (c->glyphs[0]) != NOT_COVERED);
-  }
+  { return c->len == 1 && (this+coverage).get_coverage (c->glyphs[0]) != NOT_COVERED; }
 
   bool apply (hb_ot_apply_context_t *c) const
   {
@@ -188,11 +181,21 @@ struct SingleSubstFormat2
     return_trace (true);
   }
 
+  template<typename Iterator,
+          hb_requires (hb_is_sorted_source_of (Iterator,
+                                               hb_codepoint_pair_t))>
   bool serialize (hb_serialize_context_t *c,
-                 hb_array_t<const GlyphID> glyphs,
-                 hb_array_t<const GlyphID> substitutes)
+                 Iterator it)
   {
     TRACE_SERIALIZE (this);
+    auto substitutes =
+      + it
+      | hb_map (hb_second)
+      ;
+    auto glyphs =
+      + it
+      | hb_map_retains_sorting (hb_first)
+      ;
     if (unlikely (!c->extend_min (*this))) return_trace (false);
     if (unlikely (!substitute.serialize (c, substitutes))) return_trace (false);
     if (unlikely (!coverage.serialize (c, this).serialize (c, glyphs))) return_trace (false);
@@ -202,19 +205,20 @@ struct SingleSubstFormat2
   bool subset (hb_subset_context_t *c) const
   {
     TRACE_SUBSET (this);
-    const hb_set_t &glyphset = *c->plan->glyphset ();
+    const hb_set_t &glyphset = *c->plan->glyphset_gsub ();
     const hb_map_t &glyph_map = *c->plan->glyph_map;
-    hb_vector_t<GlyphID> from;
-    hb_vector_t<GlyphID> to;
-    for (Coverage::Iter iter (this+coverage); iter.more (); iter.next ())
-    {
-      if (!glyphset.has (iter.get_glyph ())) continue;
-      from.push ()->set (glyph_map[iter.get_glyph ()]);
-      to.push ()->set (glyph_map[substitute[iter.get_coverage ()]]);
-    }
-    c->serializer->propagate_error (from, to);
-    SingleSubst_serialize (c->serializer, from, to);
-    return_trace (from.length);
+
+    auto it =
+    + hb_zip (this+coverage, substitute)
+    | hb_filter (glyphset, hb_first)
+    | hb_filter (glyphset, hb_second)
+    | hb_map_retains_sorting ([&] (hb_pair_t<hb_codepoint_t, const HBGlyphID &> p) -> hb_codepoint_pair_t
+                             { return hb_pair (glyph_map[p.first], glyph_map[p.second]); })
+    ;
+
+    bool ret = bool (it);
+    SingleSubst_serialize (c->serializer, it);
+    return_trace (ret);
   }
 
   bool sanitize (hb_sanitize_context_t *c) const
@@ -228,7 +232,7 @@ struct SingleSubstFormat2
   OffsetTo<Coverage>
                coverage;               /* Offset to Coverage table--from
                                         * beginning of Substitution table */
-  ArrayOf<GlyphID>
+  ArrayOf<HBGlyphID>
                substitute;             /* Array of substitute
                                         * GlyphIDs--ordered by Coverage Index */
   public:
@@ -237,41 +241,45 @@ struct SingleSubstFormat2
 
 struct SingleSubst
 {
+
+  template<typename Iterator,
+          hb_requires (hb_is_sorted_source_of (Iterator,
+                                               const hb_codepoint_pair_t))>
   bool serialize (hb_serialize_context_t *c,
-                 hb_array_t<const GlyphID> glyphs,
-                 hb_array_t<const GlyphID> substitutes)
+                 Iterator glyphs)
   {
     TRACE_SERIALIZE (this);
     if (unlikely (!c->extend_min (u.format))) return_trace (false);
-    unsigned int format = 2;
-    int delta = 0;
-    if (glyphs.length)
+    unsigned format = 2;
+    unsigned delta = 0;
+    if (glyphs)
     {
       format = 1;
-      /* TODO(serialize) check for wrap-around */
-      delta = substitutes[0] - glyphs[0];
-      for (unsigned int i = 1; i < glyphs.length; i++)
-       if (delta != (int) (substitutes[i] - glyphs[i])) {
-         format = 2;
-         break;
-       }
+      auto get_delta = [=] (hb_codepoint_pair_t _) {
+                        return (unsigned) (_.second - _.first) & 0xFFFF;
+                      };
+      delta = get_delta (*glyphs);
+      if (!hb_all (++(+glyphs), delta, get_delta)) format = 2;
     }
-    u.format.set (format);
+    u.format = format;
     switch (u.format) {
-    case 1: return_trace (u.format1.serialize (c, glyphs, delta));
-    case 2: return_trace (u.format2.serialize (c, glyphs, substitutes));
+    case 1: return_trace (u.format1.serialize (c,
+                                              + glyphs
+                                              | hb_map_retains_sorting (hb_first),
+                                              delta));
+    case 2: return_trace (u.format2.serialize (c, glyphs));
     default:return_trace (false);
     }
   }
 
-  template <typename context_t>
-  typename context_t::return_t dispatch (context_t *c) const
+  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));
-    case 2: return_trace (c->dispatch (u.format2));
+    case 1: return_trace (c->dispatch (u.format1, hb_forward<Ts> (ds)...));
+    case 2: return_trace (c->dispatch (u.format2, hb_forward<Ts> (ds)...));
     default:return_trace (c->default_return_value ());
     }
   }
@@ -284,20 +292,19 @@ struct SingleSubst
   } u;
 };
 
+template<typename Iterator>
 static inline void
 SingleSubst_serialize (hb_serialize_context_t *c,
-                      hb_array_t<const GlyphID> glyphs,
-                      hb_array_t<const GlyphID> substitutes)
-{ c->start_embed<SingleSubst> ()->serialize (c, glyphs, substitutes); }
+                      Iterator it)
+{ c->start_embed<SingleSubst> ()->serialize (c, it); }
 
 struct Sequence
 {
+  bool intersects (const hb_set_t *glyphs) const
+  { return hb_all (substitute, glyphs); }
+
   void closure (hb_closure_context_t *c) const
-  {
-    unsigned int count = substitute.len;
-    for (unsigned int i = 0; i < count; i++)
-      c->out->add (substitute[i]);
-  }
+  { c->output->add_array (substitute.arrayZ, substitute.len); }
 
   void collect_glyphs (hb_collect_glyphs_context_t *c) const
   { c->output->add_array (substitute.arrayZ, substitute.len); }
@@ -334,11 +341,30 @@ struct Sequence
     return_trace (true);
   }
 
+  template <typename Iterator,
+           hb_requires (hb_is_source_of (Iterator, hb_codepoint_t))>
   bool serialize (hb_serialize_context_t *c,
-                 hb_array_t<const GlyphID> glyphs)
+                 Iterator subst)
   {
     TRACE_SERIALIZE (this);
-    return_trace (substitute.serialize (c, glyphs));
+    return_trace (substitute.serialize (c, subst));
+  }
+
+  bool subset (hb_subset_context_t *c) const
+  {
+    TRACE_SUBSET (this);
+    const hb_set_t &glyphset = *c->plan->glyphset ();
+    const hb_map_t &glyph_map = *c->plan->glyph_map;
+
+    if (!intersects (&glyphset)) return_trace (false);
+
+    auto it =
+      + hb_iter (substitute)
+      | hb_map (glyph_map)
+      ;
+
+    auto *out = c->serializer->start_embed (*this);
+    return_trace (out->serialize (c->serializer, it));
   }
 
   bool sanitize (hb_sanitize_context_t *c) const
@@ -348,7 +374,7 @@ struct Sequence
   }
 
   protected:
-  ArrayOf<GlyphID>
+  ArrayOf<HBGlyphID>
                substitute;             /* String of GlyphIDs to substitute */
   public:
   DEFINE_SIZE_ARRAY (2, substitute);
@@ -361,31 +387,28 @@ struct MultipleSubstFormat1
 
   void closure (hb_closure_context_t *c) const
   {
-    unsigned int count = sequence.len;
-    for (Coverage::Iter iter (this+coverage); iter.more (); iter.next ())
-    {
-      if (unlikely (iter.get_coverage () >= count))
-        break; /* Work around malicious fonts. https://github.com/harfbuzz/harfbuzz/issues/363 */
-      if (c->glyphs->has (iter.get_glyph ()))
-       (this+sequence[iter.get_coverage ()]).closure (c);
-    }
+    + hb_zip (this+coverage, sequence)
+    | hb_filter (*c->glyphs, hb_first)
+    | hb_map (hb_second)
+    | hb_map (hb_add (this))
+    | hb_apply ([c] (const Sequence &_) { _.closure (c); })
+    ;
   }
 
   void collect_glyphs (hb_collect_glyphs_context_t *c) const
   {
     if (unlikely (!(this+coverage).add_coverage (c->input))) return;
-    unsigned int count = sequence.len;
-    for (unsigned int i = 0; i < count; i++)
-      (this+sequence[i]).collect_glyphs (c);
+    + hb_zip (this+coverage, sequence)
+    | hb_map (hb_second)
+    | hb_map (hb_add (this))
+    | hb_apply ([c] (const Sequence &_) { _.collect_glyphs (c); })
+    ;
   }
 
   const Coverage &get_coverage () const { return this+coverage; }
 
   bool would_apply (hb_would_apply_context_t *c) const
-  {
-    TRACE_WOULD_APPLY (this);
-    return_trace (c->len == 1 && (this+coverage).get_coverage (c->glyphs[0]) != NOT_COVERED);
-  }
+  { return c->len == 1 && (this+coverage).get_coverage (c->glyphs[0]) != NOT_COVERED; }
 
   bool apply (hb_ot_apply_context_t *c) const
   {
@@ -398,9 +421,9 @@ struct MultipleSubstFormat1
   }
 
   bool serialize (hb_serialize_context_t *c,
-                 hb_array_t<const GlyphID> glyphs,
+                 hb_sorted_array_t<const HBGlyphID> glyphs,
                  hb_array_t<const unsigned int> substitute_len_list,
-                 hb_array_t<const GlyphID> substitute_glyphs_list)
+                 hb_array_t<const HBGlyphID> substitute_glyphs_list)
   {
     TRACE_SERIALIZE (this);
     if (unlikely (!c->extend_min (*this))) return_trace (false);
@@ -419,8 +442,24 @@ struct MultipleSubstFormat1
   bool subset (hb_subset_context_t *c) const
   {
     TRACE_SUBSET (this);
-    // TODO(subset)
-    return_trace (false);
+    const hb_set_t &glyphset = *c->plan->glyphset ();
+    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);
+    out->format = format;
+
+    hb_sorted_vector_t<hb_codepoint_t> new_coverage;
+    + hb_zip (this+coverage, sequence)
+    | hb_filter (glyphset, hb_first)
+    | hb_filter (subset_offset_array (c, out->sequence, this, out), hb_second)
+    | hb_map (hb_first)
+    | hb_map (glyph_map)
+    | hb_sink (new_coverage)
+    ;
+    out->coverage.serialize (c->serializer, out)
+                .serialize (c->serializer, new_coverage.iter ());
+    return_trace (bool (new_coverage));
   }
 
   bool sanitize (hb_sanitize_context_t *c) const
@@ -444,27 +483,27 @@ struct MultipleSubstFormat1
 struct MultipleSubst
 {
   bool serialize (hb_serialize_context_t *c,
-                 hb_array_t<const GlyphID> glyphs,
+                 hb_sorted_array_t<const HBGlyphID> glyphs,
                  hb_array_t<const unsigned int> substitute_len_list,
-                 hb_array_t<const GlyphID> substitute_glyphs_list)
+                 hb_array_t<const HBGlyphID> substitute_glyphs_list)
   {
     TRACE_SERIALIZE (this);
     if (unlikely (!c->extend_min (u.format))) return_trace (false);
     unsigned int format = 1;
-    u.format.set (format);
+    u.format = format;
     switch (u.format) {
     case 1: return_trace (u.format1.serialize (c, glyphs, substitute_len_list, substitute_glyphs_list));
     default:return_trace (false);
     }
   }
 
-  template <typename context_t>
-  typename context_t::return_t dispatch (context_t *c) const
+  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));
+    case 1: return_trace (c->dispatch (u.format1, hb_forward<Ts> (ds)...));
     default:return_trace (c->default_return_value ());
     }
   }
@@ -478,12 +517,11 @@ struct MultipleSubst
 
 struct AlternateSet
 {
+  bool intersects (const hb_set_t *glyphs) const
+  { return hb_any (alternates, glyphs); }
+
   void closure (hb_closure_context_t *c) const
-  {
-    unsigned int count = alternates.len;
-    for (unsigned int i = 0; i < count; i++)
-      c->out->add (alternates[i]);
-  }
+  { c->output->add_array (alternates.arrayZ, alternates.len); }
 
   void collect_glyphs (hb_collect_glyphs_context_t *c) const
   { c->output->add_array (alternates.arrayZ, alternates.len); }
@@ -502,7 +540,7 @@ struct AlternateSet
     unsigned int shift = hb_ctz (lookup_mask);
     unsigned int alt_index = ((lookup_mask & glyph_mask) >> shift);
 
-    /* If alt_index is MAX, randomize feature if it is the rand feature. */
+    /* If alt_index is MAX_VALUE, randomize feature if it is the rand feature. */
     if (alt_index == HB_OT_MAP_MAX_VALUE && c->random)
       alt_index = c->random_number () % count + 1;
 
@@ -513,11 +551,30 @@ struct AlternateSet
     return_trace (true);
   }
 
+  template <typename Iterator,
+           hb_requires (hb_is_source_of (Iterator, hb_codepoint_t))>
   bool serialize (hb_serialize_context_t *c,
-                 hb_array_t<const GlyphID> glyphs)
+                 Iterator alts)
   {
     TRACE_SERIALIZE (this);
-    return_trace (alternates.serialize (c, glyphs));
+    return_trace (alternates.serialize (c, alts));
+  }
+
+  bool subset (hb_subset_context_t *c) const
+  {
+    TRACE_SUBSET (this);
+    const hb_set_t &glyphset = *c->plan->glyphset ();
+    const hb_map_t &glyph_map = *c->plan->glyph_map;
+
+    auto it =
+      + hb_iter (alternates)
+      | hb_filter (glyphset)
+      | hb_map (glyph_map)
+      ;
+
+    auto *out = c->serializer->start_embed (*this);
+    return_trace (out->serialize (c->serializer, it) &&
+                 out->alternates);
   }
 
   bool sanitize (hb_sanitize_context_t *c) const
@@ -527,7 +584,7 @@ struct AlternateSet
   }
 
   protected:
-  ArrayOf<GlyphID>
+  ArrayOf<HBGlyphID>
                alternates;             /* Array of alternate GlyphIDs--in
                                         * arbitrary order */
   public:
@@ -541,35 +598,27 @@ struct AlternateSubstFormat1
 
   void closure (hb_closure_context_t *c) const
   {
-    unsigned int count = alternateSet.len;
-    for (Coverage::Iter iter (this+coverage); iter.more (); iter.next ())
-    {
-      if (unlikely (iter.get_coverage () >= count))
-       break; /* Work around malicious fonts. https://github.com/harfbuzz/harfbuzz/issues/363 */
-      if (c->glyphs->has (iter.get_glyph ()))
-       (this+alternateSet[iter.get_coverage ()]).closure (c);
-    }
+    + hb_zip (this+coverage, alternateSet)
+    | hb_map (hb_second)
+    | hb_map (hb_add (this))
+    | hb_apply ([c] (const AlternateSet &_) { _.closure (c); })
+    ;
   }
 
   void collect_glyphs (hb_collect_glyphs_context_t *c) const
   {
     if (unlikely (!(this+coverage).add_coverage (c->input))) return;
-    unsigned int count = alternateSet.len;
-    for (Coverage::Iter iter (this+coverage); iter.more (); iter.next ())
-    {
-      if (unlikely (iter.get_coverage () >= count))
-       break; /* Work around malicious fonts. https://github.com/harfbuzz/harfbuzz/issues/363 */
-      (this+alternateSet[iter.get_coverage ()]).collect_glyphs (c);
-    }
+    + hb_zip (this+coverage, alternateSet)
+    | hb_map (hb_second)
+    | hb_map (hb_add (this))
+    | hb_apply ([c] (const AlternateSet &_) { _.collect_glyphs (c); })
+    ;
   }
 
   const Coverage &get_coverage () const { return this+coverage; }
 
   bool would_apply (hb_would_apply_context_t *c) const
-  {
-    TRACE_WOULD_APPLY (this);
-    return_trace (c->len == 1 && (this+coverage).get_coverage (c->glyphs[0]) != NOT_COVERED);
-  }
+  { return c->len == 1 && (this+coverage).get_coverage (c->glyphs[0]) != NOT_COVERED; }
 
   bool apply (hb_ot_apply_context_t *c) const
   {
@@ -582,9 +631,9 @@ struct AlternateSubstFormat1
   }
 
   bool serialize (hb_serialize_context_t *c,
-                 hb_array_t<const GlyphID> glyphs,
+                 hb_sorted_array_t<const HBGlyphID> glyphs,
                  hb_array_t<const unsigned int> alternate_len_list,
-                 hb_array_t<const GlyphID> alternate_glyphs_list)
+                 hb_array_t<const HBGlyphID> alternate_glyphs_list)
   {
     TRACE_SERIALIZE (this);
     if (unlikely (!c->extend_min (*this))) return_trace (false);
@@ -603,8 +652,24 @@ struct AlternateSubstFormat1
   bool subset (hb_subset_context_t *c) const
   {
     TRACE_SUBSET (this);
-    // TODO(subset)
-    return_trace (false);
+    const hb_set_t &glyphset = *c->plan->glyphset ();
+    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);
+    out->format = format;
+
+    hb_sorted_vector_t<hb_codepoint_t> new_coverage;
+    + hb_zip (this+coverage, alternateSet)
+    | hb_filter (glyphset, hb_first)
+    | hb_filter (subset_offset_array (c, out->alternateSet, this, out), hb_second)
+    | hb_map (hb_first)
+    | hb_map (glyph_map)
+    | hb_sink (new_coverage)
+    ;
+    out->coverage.serialize (c->serializer, out)
+                .serialize (c->serializer, new_coverage.iter ());
+    return_trace (bool (new_coverage));
   }
 
   bool sanitize (hb_sanitize_context_t *c) const
@@ -628,27 +693,27 @@ struct AlternateSubstFormat1
 struct AlternateSubst
 {
   bool serialize (hb_serialize_context_t *c,
-                 hb_array_t<const GlyphID> glyphs,
+                 hb_sorted_array_t<const HBGlyphID> glyphs,
                  hb_array_t<const unsigned int> alternate_len_list,
-                 hb_array_t<const GlyphID> alternate_glyphs_list)
+                 hb_array_t<const HBGlyphID> alternate_glyphs_list)
   {
     TRACE_SERIALIZE (this);
     if (unlikely (!c->extend_min (u.format))) return_trace (false);
     unsigned int format = 1;
-    u.format.set (format);
+    u.format = format;
     switch (u.format) {
     case 1: return_trace (u.format1.serialize (c, glyphs, alternate_len_list, alternate_glyphs_list));
     default:return_trace (false);
     }
   }
 
-  template <typename context_t>
-  typename context_t::return_t dispatch (context_t *c) const
+  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));
+    case 1: return_trace (c->dispatch (u.format1, hb_forward<Ts> (ds)...));
     default:return_trace (c->default_return_value ());
     }
   }
@@ -664,40 +729,30 @@ struct AlternateSubst
 struct Ligature
 {
   bool intersects (const hb_set_t *glyphs) const
-  {
-    unsigned int count = component.lenP1;
-    for (unsigned int i = 1; i < count; i++)
-      if (!glyphs->has (component[i]))
-        return false;
-    return true;
-  }
+  { return hb_all (component, glyphs); }
 
   void closure (hb_closure_context_t *c) const
   {
-    unsigned int count = component.lenP1;
-    for (unsigned int i = 1; i < count; i++)
-      if (!c->glyphs->has (component[i]))
-        return;
-    c->out->add (ligGlyph);
+    if (!intersects (c->glyphs)) return;
+    c->output->add (ligGlyph);
   }
 
   void collect_glyphs (hb_collect_glyphs_context_t *c) const
   {
-    c->input->add_array (component.arrayZ, component.lenP1 ? component.lenP1 - 1 : 0);
+    c->input->add_array (component.arrayZ, component.get_length ());
     c->output->add (ligGlyph);
   }
 
   bool would_apply (hb_would_apply_context_t *c) const
   {
-    TRACE_WOULD_APPLY (this);
     if (c->len != component.lenP1)
-      return_trace (false);
+      return false;
 
     for (unsigned int i = 1; i < c->len; i++)
       if (likely (c->glyphs[i] != component[i]))
-       return_trace (false);
+       return false;
 
-    return_trace (true);
+    return true;
   }
 
   bool apply (hb_ot_apply_context_t *c) const
@@ -739,9 +794,11 @@ struct Ligature
     return_trace (true);
   }
 
+  template <typename Iterator,
+           hb_requires (hb_is_source_of (Iterator, hb_codepoint_t))>
   bool serialize (hb_serialize_context_t *c,
-                 GlyphID ligature,
-                 hb_array_t<const GlyphID> components /* Starting from second */)
+                 hb_codepoint_t ligature,
+                 Iterator components /* Starting from second */)
   {
     TRACE_SERIALIZE (this);
     if (unlikely (!c->extend_min (*this))) return_trace (false);
@@ -750,6 +807,25 @@ struct Ligature
     return_trace (true);
   }
 
+  bool subset (hb_subset_context_t *c) const
+  {
+    TRACE_SUBSET (this);
+    const hb_set_t &glyphset = *c->plan->glyphset ();
+    const hb_map_t &glyph_map = *c->plan->glyph_map;
+
+    if (!intersects (&glyphset) || !glyphset.has (ligGlyph)) return_trace (false);
+
+    auto it =
+      + hb_iter (component)
+      | hb_map (glyph_map)
+      ;
+
+    auto *out = c->serializer->start_embed (*this);
+    return_trace (out->serialize (c->serializer,
+                                  glyph_map[ligGlyph],
+                                  it));
+  }
+
   public:
   bool sanitize (hb_sanitize_context_t *c) const
   {
@@ -758,8 +834,8 @@ struct Ligature
   }
 
   protected:
-  GlyphID      ligGlyph;               /* GlyphID of ligature to substitute */
-  HeadlessArrayOf<GlyphID>
+  HBGlyphID    ligGlyph;               /* GlyphID of ligature to substitute */
+  HeadlessArrayOf<HBGlyphID>
                component;              /* Array of component GlyphIDs--start
                                         * with the second  component--ordered
                                         * in writing direction */
@@ -771,38 +847,38 @@ struct LigatureSet
 {
   bool intersects (const hb_set_t *glyphs) const
   {
-    unsigned int num_ligs = ligature.len;
-    for (unsigned int i = 0; i < num_ligs; i++)
-      if ((this+ligature[i]).intersects (glyphs))
-        return true;
-    return false;
+    return
+    + hb_iter (ligature)
+    | hb_map (hb_add (this))
+    | hb_map ([glyphs] (const Ligature &_) { return _.intersects (glyphs); })
+    | hb_any
+    ;
   }
 
   void closure (hb_closure_context_t *c) const
   {
-    unsigned int num_ligs = ligature.len;
-    for (unsigned int i = 0; i < num_ligs; i++)
-      (this+ligature[i]).closure (c);
+    + hb_iter (ligature)
+    | hb_map (hb_add (this))
+    | hb_apply ([c] (const Ligature &_) { _.closure (c); })
+    ;
   }
 
   void collect_glyphs (hb_collect_glyphs_context_t *c) const
   {
-    unsigned int num_ligs = ligature.len;
-    for (unsigned int i = 0; i < num_ligs; i++)
-      (this+ligature[i]).collect_glyphs (c);
+    + hb_iter (ligature)
+    | hb_map (hb_add (this))
+    | hb_apply ([c] (const Ligature &_) { _.collect_glyphs (c); })
+    ;
   }
 
   bool would_apply (hb_would_apply_context_t *c) const
   {
-    TRACE_WOULD_APPLY (this);
-    unsigned int num_ligs = ligature.len;
-    for (unsigned int i = 0; i < num_ligs; i++)
-    {
-      const Ligature &lig = this+ligature[i];
-      if (lig.would_apply (c))
-        return_trace (true);
-    }
-    return_trace (false);
+    return
+    + hb_iter (ligature)
+    | hb_map (hb_add (this))
+    | hb_map ([c] (const Ligature &_) { return _.would_apply (c); })
+    | hb_any
+    ;
   }
 
   bool apply (hb_ot_apply_context_t *c) const
@@ -819,16 +895,16 @@ struct LigatureSet
   }
 
   bool serialize (hb_serialize_context_t *c,
-                 hb_array_t<const GlyphID> ligatures,
+                 hb_array_t<const HBGlyphID> ligatures,
                  hb_array_t<const unsigned int> component_count_list,
-                 hb_array_t<const GlyphID> &component_list /* Starting from second for each ligature */)
+                 hb_array_t<const HBGlyphID> &component_list /* Starting from second for each ligature */)
   {
     TRACE_SERIALIZE (this);
     if (unlikely (!c->extend_min (*this))) return_trace (false);
     if (unlikely (!ligature.serialize (c, ligatures.length))) return_trace (false);
     for (unsigned int i = 0; i < ligatures.length; i++)
     {
-      unsigned int component_count = MAX<int> (component_count_list[i] - 1, 0);
+      unsigned int component_count = (unsigned) hb_max ((int) component_count_list[i] - 1, 0);
       if (unlikely (!ligature[i].serialize (c, this)
                                .serialize (c,
                                            ligatures[i],
@@ -839,6 +915,19 @@ struct LigatureSet
     return_trace (true);
   }
 
+  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 (ligature)
+    | hb_filter (subset_offset_array (c, out->ligature, this, out))
+    | hb_drain
+    ;
+    return_trace (bool (out->ligature));
+  }
+
   bool sanitize (hb_sanitize_context_t *c) const
   {
     TRACE_SANITIZE (this);
@@ -857,52 +946,46 @@ struct LigatureSubstFormat1
 {
   bool intersects (const hb_set_t *glyphs) const
   {
-    unsigned int count = ligatureSet.len;
-    for (Coverage::Iter iter (this+coverage); iter.more (); iter.next ())
-    {
-      if (unlikely (iter.get_coverage () >= count))
-        break; /* Work around malicious fonts. https://github.com/harfbuzz/harfbuzz/issues/363 */
-      if (glyphs->has (iter.get_glyph ()) &&
-         (this+ligatureSet[iter.get_coverage ()]).intersects (glyphs))
-        return true;
-    }
-    return false;
+    return
+    + hb_zip (this+coverage, ligatureSet)
+    | hb_filter (*glyphs, hb_first)
+    | hb_map (hb_second)
+    | hb_map ([this, glyphs] (const OffsetTo<LigatureSet> &_)
+             { return (this+_).intersects (glyphs); })
+    | hb_any
+    ;
   }
 
   void closure (hb_closure_context_t *c) const
   {
-    unsigned int count = ligatureSet.len;
-    for (Coverage::Iter iter (this+coverage); iter.more (); iter.next ())
-    {
-      if (unlikely (iter.get_coverage () >= count))
-        break; /* Work around malicious fonts. https://github.com/harfbuzz/harfbuzz/issues/363 */
-      if (c->glyphs->has (iter.get_glyph ()))
-       (this+ligatureSet[iter.get_coverage ()]).closure (c);
-    }
+    + hb_zip (this+coverage, ligatureSet)
+    | hb_filter (*c->glyphs, hb_first)
+    | hb_map (hb_second)
+    | hb_map (hb_add (this))
+    | hb_apply ([c] (const LigatureSet &_) { _.closure (c); })
+    ;
   }
 
   void collect_glyphs (hb_collect_glyphs_context_t *c) const
   {
     if (unlikely (!(this+coverage).add_coverage (c->input))) return;
-    unsigned int count = ligatureSet.len;
-    for (Coverage::Iter iter (this+coverage); iter.more (); iter.next ())
-    {
-      if (unlikely (iter.get_coverage () >= count))
-        break; /* Work around malicious fonts. https://github.com/harfbuzz/harfbuzz/issues/363 */
-      (this+ligatureSet[iter.get_coverage ()]).collect_glyphs (c);
-    }
+
+    + hb_zip (this+coverage, ligatureSet)
+    | hb_map (hb_second)
+    | hb_map (hb_add (this))
+    | hb_apply ([c] (const LigatureSet &_) { _.collect_glyphs (c); })
+    ;
   }
 
   const Coverage &get_coverage () const { return this+coverage; }
 
   bool would_apply (hb_would_apply_context_t *c) const
   {
-    TRACE_WOULD_APPLY (this);
     unsigned int index = (this+coverage).get_coverage (c->glyphs[0]);
-    if (likely (index == NOT_COVERED)) return_trace (false);
+    if (likely (index == NOT_COVERED)) return false;
 
     const LigatureSet &lig_set = this+ligatureSet[index];
-    return_trace (lig_set.would_apply (c));
+    return lig_set.would_apply (c);
   }
 
   bool apply (hb_ot_apply_context_t *c) const
@@ -917,11 +1000,11 @@ struct LigatureSubstFormat1
   }
 
   bool serialize (hb_serialize_context_t *c,
-                 hb_array_t<const GlyphID> first_glyphs,
+                 hb_sorted_array_t<const HBGlyphID> first_glyphs,
                  hb_array_t<const unsigned int> ligature_per_first_glyph_count_list,
-                 hb_array_t<const GlyphID> ligatures_list,
+                 hb_array_t<const HBGlyphID> ligatures_list,
                  hb_array_t<const unsigned int> component_count_list,
-                 hb_array_t<const GlyphID> component_list /* Starting from second for each ligature */)
+                 hb_array_t<const HBGlyphID> component_list /* Starting from second for each ligature */)
   {
     TRACE_SERIALIZE (this);
     if (unlikely (!c->extend_min (*this))) return_trace (false);
@@ -943,8 +1026,24 @@ struct LigatureSubstFormat1
   bool subset (hb_subset_context_t *c) const
   {
     TRACE_SUBSET (this);
-    // TODO(subset)
-    return_trace (false);
+    const hb_set_t &glyphset = *c->plan->glyphset ();
+    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);
+    out->format = format;
+
+    hb_sorted_vector_t<hb_codepoint_t> new_coverage;
+    + hb_zip (this+coverage, ligatureSet)
+    | hb_filter (glyphset, hb_first)
+    | hb_filter (subset_offset_array (c, out->ligatureSet, this, out), hb_second)
+    | hb_map (hb_first)
+    | hb_map (glyph_map)
+    | hb_sink (new_coverage)
+    ;
+    out->coverage.serialize (c->serializer, out)
+                .serialize (c->serializer, new_coverage.iter ());
+    return_trace (bool (new_coverage));
   }
 
   bool sanitize (hb_sanitize_context_t *c) const
@@ -968,16 +1067,16 @@ struct LigatureSubstFormat1
 struct LigatureSubst
 {
   bool serialize (hb_serialize_context_t *c,
-                 hb_array_t<const GlyphID> first_glyphs,
+                 hb_sorted_array_t<const HBGlyphID> first_glyphs,
                  hb_array_t<const unsigned int> ligature_per_first_glyph_count_list,
-                 hb_array_t<const GlyphID> ligatures_list,
+                 hb_array_t<const HBGlyphID> ligatures_list,
                  hb_array_t<const unsigned int> component_count_list,
-                 hb_array_t<const GlyphID> component_list /* Starting from second for each ligature */)
+                 hb_array_t<const HBGlyphID> component_list /* Starting from second for each ligature */)
   {
     TRACE_SERIALIZE (this);
     if (unlikely (!c->extend_min (u.format))) return_trace (false);
     unsigned int format = 1;
-    u.format.set (format);
+    u.format = format;
     switch (u.format) {
     case 1: return_trace (u.format1.serialize (c,
                                               first_glyphs,
@@ -989,13 +1088,13 @@ struct LigatureSubst
     }
   }
 
-  template <typename context_t>
-  typename context_t::return_t dispatch (context_t *c) const
+  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));
+    case 1: return_trace (c->dispatch (u.format1, hb_forward<Ts> (ds)...));
     default:return_trace (c->default_return_value ());
     }
   }
@@ -1027,48 +1126,35 @@ struct ReverseChainSingleSubstFormat1
     if (!(this+coverage).intersects (glyphs))
       return false;
 
-    const OffsetArrayOf<Coverage> &lookahead = StructAfter<OffsetArrayOf<Coverage> > (backtrack);
+    const OffsetArrayOf<Coverage> &lookahead = StructAfter<OffsetArrayOf<Coverage>> (backtrack);
 
     unsigned int count;
 
     count = backtrack.len;
     for (unsigned int i = 0; i < count; i++)
       if (!(this+backtrack[i]).intersects (glyphs))
-        return false;
+       return false;
 
     count = lookahead.len;
     for (unsigned int i = 0; i < count; i++)
       if (!(this+lookahead[i]).intersects (glyphs))
-        return false;
+       return false;
 
     return true;
   }
 
   void closure (hb_closure_context_t *c) const
   {
-    const OffsetArrayOf<Coverage> &lookahead = StructAfter<OffsetArrayOf<Coverage> > (backtrack);
-
-    unsigned int count;
-
-    count = backtrack.len;
-    for (unsigned int i = 0; i < count; i++)
-      if (!(this+backtrack[i]).intersects (c->glyphs))
-        return;
+    if (!intersects (c->glyphs)) return;
 
-    count = lookahead.len;
-    for (unsigned int i = 0; i < count; i++)
-      if (!(this+lookahead[i]).intersects (c->glyphs))
-        return;
+    const OffsetArrayOf<Coverage> &lookahead = StructAfter<OffsetArrayOf<Coverage>> (backtrack);
+    const ArrayOf<HBGlyphID> &substitute = StructAfter<ArrayOf<HBGlyphID>> (lookahead);
 
-    const ArrayOf<GlyphID> &substitute = StructAfter<ArrayOf<GlyphID> > (lookahead);
-    count = substitute.len;
-    for (Coverage::Iter iter (this+coverage); iter.more (); iter.next ())
-    {
-      if (unlikely (iter.get_coverage () >= count))
-        break; /* Work around malicious fonts. https://github.com/harfbuzz/harfbuzz/issues/363 */
-      if (c->glyphs->has (iter.get_glyph ()))
-       c->out->add (substitute[iter.get_coverage ()]);
-    }
+    + hb_zip (this+coverage, substitute)
+    | hb_filter (*c->glyphs, hb_first)
+    | hb_map (hb_second)
+    | hb_sink (c->output)
+    ;
   }
 
   void collect_glyphs (hb_collect_glyphs_context_t *c) const
@@ -1081,12 +1167,12 @@ struct ReverseChainSingleSubstFormat1
     for (unsigned int i = 0; i < count; i++)
       if (unlikely (!(this+backtrack[i]).add_coverage (c->before))) return;
 
-    const OffsetArrayOf<Coverage> &lookahead = StructAfter<OffsetArrayOf<Coverage> > (backtrack);
+    const OffsetArrayOf<Coverage> &lookahead = StructAfter<OffsetArrayOf<Coverage>> (backtrack);
     count = lookahead.len;
     for (unsigned int i = 0; i < count; i++)
       if (unlikely (!(this+lookahead[i]).add_coverage (c->after))) return;
 
-    const ArrayOf<GlyphID> &substitute = StructAfter<ArrayOf<GlyphID> > (lookahead);
+    const ArrayOf<HBGlyphID> &substitute = StructAfter<ArrayOf<HBGlyphID>> (lookahead);
     count = substitute.len;
     c->output->add_array (substitute.arrayZ, substitute.len);
   }
@@ -1094,10 +1180,7 @@ struct ReverseChainSingleSubstFormat1
   const Coverage &get_coverage () const { return this+coverage; }
 
   bool would_apply (hb_would_apply_context_t *c) const
-  {
-    TRACE_WOULD_APPLY (this);
-    return_trace (c->len == 1 && (this+coverage).get_coverage (c->glyphs[0]) != NOT_COVERED);
-  }
+  { return c->len == 1 && (this+coverage).get_coverage (c->glyphs[0]) != NOT_COVERED; }
 
   bool apply (hb_ot_apply_context_t *c) const
   {
@@ -1108,15 +1191,15 @@ struct ReverseChainSingleSubstFormat1
     unsigned int index = (this+coverage).get_coverage (c->buffer->cur().codepoint);
     if (likely (index == NOT_COVERED)) return_trace (false);
 
-    const OffsetArrayOf<Coverage> &lookahead = StructAfter<OffsetArrayOf<Coverage> > (backtrack);
-    const ArrayOf<GlyphID> &substitute = StructAfter<ArrayOf<GlyphID> > (lookahead);
+    const OffsetArrayOf<Coverage> &lookahead = StructAfter<OffsetArrayOf<Coverage>> (backtrack);
+    const ArrayOf<HBGlyphID> &substitute = StructAfter<ArrayOf<HBGlyphID>> (lookahead);
 
   unsigned int start_index = 0, end_index = 0;
     if (match_backtrack (c,
                         backtrack.len, (HBUINT16 *) backtrack.arrayZ,
                         match_coverage, this,
                         &start_index) &&
-        match_lookahead (c,
+       match_lookahead (c,
                         lookahead.len, (HBUINT16 *) lookahead.arrayZ,
                         match_coverage, this,
                         1, &end_index))
@@ -1144,10 +1227,10 @@ struct ReverseChainSingleSubstFormat1
     TRACE_SANITIZE (this);
     if (!(coverage.sanitize (c, this) && backtrack.sanitize (c, this)))
       return_trace (false);
-    const OffsetArrayOf<Coverage> &lookahead = StructAfter<OffsetArrayOf<Coverage> > (backtrack);
+    const OffsetArrayOf<Coverage> &lookahead = StructAfter<OffsetArrayOf<Coverage>> (backtrack);
     if (!lookahead.sanitize (c, this))
       return_trace (false);
-    const ArrayOf<GlyphID> &substitute = StructAfter<ArrayOf<GlyphID> > (lookahead);
+    const ArrayOf<HBGlyphID> &substitute = StructAfter<ArrayOf<HBGlyphID>> (lookahead);
     return_trace (substitute.sanitize (c));
   }
 
@@ -1164,7 +1247,7 @@ struct ReverseChainSingleSubstFormat1
                lookaheadX;             /* Array of coverage tables
                                         * in lookahead sequence, in glyph
                                         * sequence order */
-  ArrayOf<GlyphID>
+  ArrayOf<HBGlyphID>
                substituteX;            /* Array of substitute
                                         * GlyphIDs--ordered by Coverage Index */
   public:
@@ -1173,13 +1256,13 @@ struct ReverseChainSingleSubstFormat1
 
 struct ReverseChainSingleSubst
 {
-  template <typename context_t>
-  typename context_t::return_t dispatch (context_t *c) const
+  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));
+    case 1: return_trace (c->dispatch (u.format1, hb_forward<Ts> (ds)...));
     default:return_trace (c->default_return_value ());
     }
   }
@@ -1213,19 +1296,19 @@ struct SubstLookupSubTable
     ReverseChainSingle = 8
   };
 
-  template <typename context_t>
-  typename context_t::return_t dispatch (context_t *c, unsigned int lookup_type) const
+  template <typename context_t, typename ...Ts>
+  typename context_t::return_t dispatch (context_t *c, unsigned int lookup_type, Ts&&... ds) const
   {
     TRACE_DISPATCH (this, lookup_type);
     switch (lookup_type) {
-    case Single:               return_trace (u.single.dispatch (c));
-    case Multiple:             return_trace (u.multiple.dispatch (c));
-    case Alternate:            return_trace (u.alternate.dispatch (c));
-    case Ligature:             return_trace (u.ligature.dispatch (c));
-    case Context:              return_trace (u.context.dispatch (c));
-    case ChainContext:         return_trace (u.chainContext.dispatch (c));
-    case Extension:            return_trace (u.extension.dispatch (c));
-    case ReverseChainSingle:   return_trace (u.reverseChainContextSingle.dispatch (c));
+    case Single:               return_trace (u.single.dispatch (c, hb_forward<Ts> (ds)...));
+    case Multiple:             return_trace (u.multiple.dispatch (c, hb_forward<Ts> (ds)...));
+    case Alternate:            return_trace (u.alternate.dispatch (c, hb_forward<Ts> (ds)...));
+    case Ligature:             return_trace (u.ligature.dispatch (c, hb_forward<Ts> (ds)...));
+    case Context:              return_trace (u.context.dispatch (c, hb_forward<Ts> (ds)...));
+    case ChainContext:         return_trace (u.chainContext.dispatch (c, hb_forward<Ts> (ds)...));
+    case Extension:            return_trace (u.extension.dispatch (c, hb_forward<Ts> (ds)...));
+    case ReverseChainSingle:   return_trace (u.reverseChainContextSingle.dispatch (c, hb_forward<Ts> (ds)...));
     default:                   return_trace (c->default_return_value ());
     }
   }
@@ -1253,7 +1336,7 @@ struct SubstLookup : Lookup
   const SubTable& get_subtable (unsigned int i) const
   { return Lookup::get_subtable<SubTable> (i); }
 
-  static bool lookup_type_is_reverse (unsigned int lookup_type)
+  HB_INTERNAL static bool lookup_type_is_reverse (unsigned int lookup_type)
   { return lookup_type == SubTable::ReverseChainSingle; }
 
   bool is_reverse () const
@@ -1306,81 +1389,84 @@ struct SubstLookup : Lookup
   bool would_apply (hb_would_apply_context_t *c,
                    const hb_ot_layout_lookup_accelerator_t *accel) const
   {
-    TRACE_WOULD_APPLY (this);
-    if (unlikely (!c->len))  return_trace (false);
-    if (!accel->may_have (c->glyphs[0]))  return_trace (false);
-      return_trace (dispatch (c));
+    if (unlikely (!c->len)) return false;
+    if (!accel->may_have (c->glyphs[0])) return false;
+      return dispatch (c);
   }
 
-  static bool apply_recurse_func (hb_ot_apply_context_t *c, unsigned int lookup_index);
+  HB_INTERNAL static bool apply_recurse_func (hb_ot_apply_context_t *c, unsigned int lookup_index);
 
   SubTable& serialize_subtable (hb_serialize_context_t *c,
-                                      unsigned int i)
+                               unsigned int i)
   { return get_subtables<SubTable> ()[i].serialize (c, this); }
 
   bool serialize_single (hb_serialize_context_t *c,
                         uint32_t lookup_props,
-                        hb_array_t<const GlyphID> glyphs,
-                        hb_array_t<const GlyphID> substitutes)
+                        hb_sorted_array_t<const HBGlyphID> glyphs,
+                        hb_array_t<const HBGlyphID> substitutes)
   {
     TRACE_SERIALIZE (this);
     if (unlikely (!Lookup::serialize (c, SubTable::Single, lookup_props, 1))) return_trace (false);
-    return_trace (serialize_subtable (c, 0).u.single.serialize (c, glyphs, substitutes));
+    return_trace (serialize_subtable (c, 0).u.single.
+                 serialize (c, hb_zip (glyphs, substitutes)));
   }
 
   bool serialize_multiple (hb_serialize_context_t *c,
                           uint32_t lookup_props,
-                          hb_array_t<const GlyphID> glyphs,
+                          hb_sorted_array_t<const HBGlyphID> glyphs,
                           hb_array_t<const unsigned int> substitute_len_list,
-                          hb_array_t<const GlyphID> substitute_glyphs_list)
+                          hb_array_t<const HBGlyphID> substitute_glyphs_list)
   {
     TRACE_SERIALIZE (this);
     if (unlikely (!Lookup::serialize (c, SubTable::Multiple, lookup_props, 1))) return_trace (false);
-    return_trace (serialize_subtable (c, 0).u.multiple.serialize (c,
-                                                                 glyphs,
-                                                                 substitute_len_list,
-                                                                 substitute_glyphs_list));
+    return_trace (serialize_subtable (c, 0).u.multiple.
+                 serialize (c,
+                            glyphs,
+                            substitute_len_list,
+                            substitute_glyphs_list));
   }
 
   bool serialize_alternate (hb_serialize_context_t *c,
                            uint32_t lookup_props,
-                           hb_array_t<const GlyphID> glyphs,
+                           hb_sorted_array_t<const HBGlyphID> glyphs,
                            hb_array_t<const unsigned int> alternate_len_list,
-                           hb_array_t<const GlyphID> alternate_glyphs_list)
+                           hb_array_t<const HBGlyphID> alternate_glyphs_list)
   {
     TRACE_SERIALIZE (this);
     if (unlikely (!Lookup::serialize (c, SubTable::Alternate, lookup_props, 1))) return_trace (false);
-    return_trace (serialize_subtable (c, 0).u.alternate.serialize (c,
-                                                                  glyphs,
-                                                                  alternate_len_list,
-                                                                  alternate_glyphs_list));
+    return_trace (serialize_subtable (c, 0).u.alternate.
+                 serialize (c,
+                            glyphs,
+                            alternate_len_list,
+                            alternate_glyphs_list));
   }
 
   bool serialize_ligature (hb_serialize_context_t *c,
                           uint32_t lookup_props,
-                          hb_array_t<const GlyphID> first_glyphs,
+                          hb_sorted_array_t<const HBGlyphID> first_glyphs,
                           hb_array_t<const unsigned int> ligature_per_first_glyph_count_list,
-                          hb_array_t<const GlyphID> ligatures_list,
+                          hb_array_t<const HBGlyphID> ligatures_list,
                           hb_array_t<const unsigned int> component_count_list,
-                          hb_array_t<const GlyphID> component_list /* Starting from second for each ligature */)
+                          hb_array_t<const HBGlyphID> component_list /* Starting from second for each ligature */)
   {
     TRACE_SERIALIZE (this);
     if (unlikely (!Lookup::serialize (c, SubTable::Ligature, lookup_props, 1))) return_trace (false);
-    return_trace (serialize_subtable (c, 0).u.ligature.serialize (c,
-                                                                 first_glyphs,
-                                                                 ligature_per_first_glyph_count_list,
-                                                                 ligatures_list,
-                                                                 component_count_list,
-                                                                 component_list));
+    return_trace (serialize_subtable (c, 0).u.ligature.
+                 serialize (c,
+                            first_glyphs,
+                            ligature_per_first_glyph_count_list,
+                            ligatures_list,
+                            component_count_list,
+                            component_list));
   }
 
   template <typename context_t>
-  static typename context_t::return_t dispatch_recurse_func (context_t *c, unsigned int lookup_index);
+  HB_INTERNAL static typename context_t::return_t dispatch_recurse_func (context_t *c, unsigned int lookup_index);
 
-  static hb_closure_context_t::return_t dispatch_closure_recurse_func (hb_closure_context_t *c, unsigned int lookup_index)
+  HB_INTERNAL static hb_closure_context_t::return_t dispatch_closure_recurse_func (hb_closure_context_t *c, unsigned int lookup_index)
   {
     if (!c->should_visit_lookup (lookup_index))
-      return HB_VOID;
+      return hb_empty_t ();
 
     hb_closure_context_t::return_t ret = dispatch_recurse_func (c, lookup_index);
 
@@ -1392,9 +1478,9 @@ struct SubstLookup : Lookup
     return ret;
   }
 
-  template <typename context_t>
-  typename context_t::return_t dispatch (context_t *c) const
-  { return Lookup::dispatch<SubTable> (c); }
+  template <typename context_t, typename ...Ts>
+  typename context_t::return_t dispatch (context_t *c, Ts&&... ds) const
+  { return Lookup::dispatch<SubTable> (c, hb_forward<Ts> (ds)...); }
 
   bool subset (hb_subset_context_t *c) const
   { return Lookup::subset<SubTable> (c); }
@@ -1433,6 +1519,7 @@ struct GSUB_accelerator_t : GSUB::accelerator_t {};
 
 /* Out-of-class implementation for methods recursing */
 
+#ifndef HB_NO_OT_LAYOUT
 /*static*/ inline bool ExtensionSubst::is_reverse () const
 {
   unsigned int type = get_type ();
@@ -1440,14 +1527,12 @@ struct GSUB_accelerator_t : GSUB::accelerator_t {};
     return CastR<ExtensionSubst> (get_subtable<SubTable>()).is_reverse ();
   return SubstLookup::lookup_type_is_reverse (type);
 }
-
 template <typename context_t>
 /*static*/ inline typename context_t::return_t SubstLookup::dispatch_recurse_func (context_t *c, unsigned int lookup_index)
 {
   const SubstLookup &l = c->face->table.GSUB.get_relaxed ()->table->get_lookup (lookup_index);
   return l.dispatch (c);
 }
-
 /*static*/ inline bool SubstLookup::apply_recurse_func (hb_ot_apply_context_t *c, unsigned int lookup_index)
 {
   const SubstLookup &l = c->face->table.GSUB.get_relaxed ()->table->get_lookup (lookup_index);
@@ -1460,6 +1545,8 @@ template <typename context_t>
   c->set_lookup_props (saved_lookup_props);
   return ret;
 }
+#endif
+
 
 } /* namespace OT */
 
index 88d834d..579d178 100644 (file)
@@ -59,13 +59,13 @@ struct hb_intersects_context_t :
 };
 
 struct hb_closure_context_t :
-       hb_dispatch_context_t<hb_closure_context_t, hb_void_t, 0>
+       hb_dispatch_context_t<hb_closure_context_t, hb_empty_t, 0>
 {
   const char *get_name () { return "CLOSURE"; }
   typedef return_t (*recurse_func_t) (hb_closure_context_t *c, unsigned int lookup_index);
   template <typename T>
-  return_t dispatch (const T &obj) { obj.closure (this); return HB_VOID; }
-  static return_t default_return_value () { return HB_VOID; }
+  return_t dispatch (const T &obj) { obj.closure (this); return hb_empty_t (); }
+  static return_t default_return_value () { return hb_empty_t (); }
   void recurse (unsigned int lookup_index)
   {
     if (unlikely (nesting_level_left == 0 || !recurse_func))
@@ -92,7 +92,7 @@ struct hb_closure_context_t :
 
   hb_face_t *face;
   hb_set_t *glyphs;
-  hb_set_t out[1];
+  hb_set_t output[1];
   recurse_func_t recurse_func;
   unsigned int nesting_level_left;
   unsigned int debug_depth;
@@ -114,8 +114,8 @@ struct hb_closure_context_t :
 
   void flush ()
   {
-    hb_set_union (glyphs, out);
-    hb_set_clear (out);
+    hb_set_union (glyphs, output);
+    hb_set_clear (output);
   }
 
   private:
@@ -124,7 +124,7 @@ struct hb_closure_context_t :
 
 
 struct hb_would_apply_context_t :
-       hb_dispatch_context_t<hb_would_apply_context_t, bool, HB_DEBUG_WOULD_APPLY>
+       hb_dispatch_context_t<hb_would_apply_context_t, bool, 0>
 {
   const char *get_name () { return "WOULD_APPLY"; }
   template <typename T>
@@ -151,13 +151,13 @@ struct hb_would_apply_context_t :
 
 
 struct hb_collect_glyphs_context_t :
-       hb_dispatch_context_t<hb_collect_glyphs_context_t, hb_void_t, 0>
+       hb_dispatch_context_t<hb_collect_glyphs_context_t, hb_empty_t, 0>
 {
   const char *get_name () { return "COLLECT_GLYPHS"; }
   typedef return_t (*recurse_func_t) (hb_collect_glyphs_context_t *c, unsigned int lookup_index);
   template <typename T>
-  return_t dispatch (const T &obj) { obj.collect_glyphs (this); return HB_VOID; }
-  static return_t default_return_value () { return HB_VOID; }
+  return_t dispatch (const T &obj) { obj.collect_glyphs (this); return hb_empty_t (); }
+  static return_t default_return_value () { return hb_empty_t (); }
   void recurse (unsigned int lookup_index)
   {
     if (unlikely (nesting_level_left == 0 || !recurse_func))
@@ -286,7 +286,7 @@ struct hb_ot_apply_context_t :
     };
 
     may_match_t may_match (const hb_glyph_info_t &info,
-                                 const HBUINT16        *glyph_data) const
+                          const HBUINT16        *glyph_data) const
     {
       if (!(info.mask & mask) ||
          (syllable && syllable != info.syllable ()))
@@ -387,7 +387,7 @@ struct hb_ot_apply_context_t :
             skip == matcher_t::SKIP_NO))
        {
          num_items--;
-         match_glyph_data++;
+         if (match_glyph_data) match_glyph_data++;
          return true;
        }
 
@@ -414,7 +414,7 @@ struct hb_ot_apply_context_t :
             skip == matcher_t::SKIP_NO))
        {
          num_items--;
-         match_glyph_data++;
+         if (match_glyph_data) match_glyph_data++;
          return true;
        }
 
@@ -483,7 +483,13 @@ struct hb_ot_apply_context_t :
                        iter_input (), iter_context (),
                        font (font_), face (font->face), buffer (buffer_),
                        recurse_func (nullptr),
-                       gdef (*face->table.GDEF->table),
+                       gdef (
+#ifndef HB_NO_OT_LAYOUT
+                             *face->table.GDEF->table
+#else
+                             Null(GDEF)
+#endif
+                            ),
                        var_store (gdef.get_var_store ()),
                        direction (buffer_->props.direction),
                        lookup_mask (1),
@@ -610,10 +616,10 @@ struct hb_ot_apply_context_t :
 
 
 struct hb_get_subtables_context_t :
-       hb_dispatch_context_t<hb_get_subtables_context_t, hb_void_t, HB_DEBUG_APPLY>
+       hb_dispatch_context_t<hb_get_subtables_context_t, hb_empty_t, HB_DEBUG_APPLY>
 {
   template <typename Type>
-  static bool apply_to (const void *obj, OT::hb_ot_apply_context_t *c)
+  HB_INTERNAL static bool apply_to (const void *obj, OT::hb_ot_apply_context_t *c)
   {
     const Type *typed_obj = (const Type *) obj;
     return typed_obj->apply (c);
@@ -652,9 +658,9 @@ struct hb_get_subtables_context_t :
   {
     hb_applicable_t *entry = array.push();
     entry->init (obj, apply_to<T>);
-    return HB_VOID;
+    return hb_empty_t ();
   }
-  static return_t default_return_value () { return HB_VOID; }
+  static return_t default_return_value () { return hb_empty_t (); }
 
   hb_get_subtables_context_t (array_t &array_) :
                              array (array_),
@@ -706,10 +712,9 @@ static inline bool intersects_array (const hb_set_t *glyphs,
                                     intersects_func_t intersects_func,
                                     const void *intersects_data)
 {
-  for (unsigned int i = 0; i < count; i++)
-    if (likely (!intersects_func (glyphs, values[i], intersects_data)))
-      return false;
-  return true;
+  for (const HBUINT16 &_ : + hb_iter (values, count))
+    if (intersects_func (glyphs, _, intersects_data)) return true;
+  return false;
 }
 
 
@@ -734,8 +739,10 @@ static inline void collect_array (hb_collect_glyphs_context_t *c HB_UNUSED,
                                  collect_glyphs_func_t collect_func,
                                  const void *collect_data)
 {
-  for (unsigned int i = 0; i < count; i++)
-    collect_func (glyphs, values[i], collect_data);
+  return
+  + hb_iter (values, count)
+  | hb_apply ([&] (const HBUINT16 &_) { collect_func (glyphs, _, collect_data); })
+  ;
 }
 
 
@@ -846,7 +853,7 @@ static inline bool match_input (hb_ot_apply_context_t *c,
        if (ligbase == LIGBASE_NOT_CHECKED)
        {
          bool found = false;
-         const hb_glyph_info_t *out = buffer->out_info;
+         const auto *out = buffer->out_info;
          unsigned int j = buffer->out_len;
          while (j && _hb_glyph_info_get_lig_id (&out[j - 1]) == first_lig_id)
          {
@@ -970,7 +977,7 @@ static inline bool ligate_input (hb_ot_apply_context_t *c,
        if (this_comp == 0)
          this_comp = last_num_components;
        unsigned int new_lig_comp = components_so_far - last_num_components +
-                                   MIN (this_comp, last_num_components);
+                                   hb_min (this_comp, last_num_components);
          _hb_glyph_info_set_lig_props_for_mark (&buffer->cur(), lig_id, new_lig_comp);
       }
       buffer->next_glyph ();
@@ -992,7 +999,7 @@ static inline bool ligate_input (hb_ot_apply_context_t *c,
        if (!this_comp)
          break;
        unsigned int new_lig_comp = components_so_far - last_num_components +
-                                   MIN (this_comp, last_num_components);
+                                   hb_min (this_comp, last_num_components);
        _hb_glyph_info_set_lig_props_for_mark (&buffer->info[i], lig_id, new_lig_comp);
       } else
        break;
@@ -1170,7 +1177,7 @@ static inline bool apply_lookup (hb_ot_apply_context_t *c,
     else
     {
       /* NOTE: delta is negative. */
-      delta = MAX (delta, (int) next - (int) count);
+      delta = hb_max (delta, (int) next - (int) count);
       next -= delta;
     }
 
@@ -1296,7 +1303,7 @@ struct Rule
 
   void closure (hb_closure_context_t *c, ContextClosureLookupContext &lookup_context) const
   {
-    const UnsizedArrayOf<LookupRecord> &lookupRecord = StructAfter<UnsizedArrayOf<LookupRecord> >
+    const UnsizedArrayOf<LookupRecord> &lookupRecord = StructAfter<UnsizedArrayOf<LookupRecord>>
                                                       (inputZ.as_array ((inputCount ? inputCount - 1 : 0)));
     context_closure_lookup (c,
                            inputCount, inputZ.arrayZ,
@@ -1307,7 +1314,7 @@ struct Rule
   void collect_glyphs (hb_collect_glyphs_context_t *c,
                       ContextCollectGlyphsLookupContext &lookup_context) const
   {
-    const UnsizedArrayOf<LookupRecord> &lookupRecord = StructAfter<UnsizedArrayOf<LookupRecord> >
+    const UnsizedArrayOf<LookupRecord> &lookupRecord = StructAfter<UnsizedArrayOf<LookupRecord>>
                                                       (inputZ.as_array (inputCount ? inputCount - 1 : 0));
     context_collect_glyphs_lookup (c,
                                   inputCount, inputZ.arrayZ,
@@ -1318,17 +1325,19 @@ struct Rule
   bool would_apply (hb_would_apply_context_t *c,
                    ContextApplyLookupContext &lookup_context) const
   {
-    TRACE_WOULD_APPLY (this);
-    const UnsizedArrayOf<LookupRecord> &lookupRecord = StructAfter<UnsizedArrayOf<LookupRecord> >
+    const UnsizedArrayOf<LookupRecord> &lookupRecord = StructAfter<UnsizedArrayOf<LookupRecord>>
                                                       (inputZ.as_array (inputCount ? inputCount - 1 : 0));
-    return_trace (context_would_apply_lookup (c, inputCount, inputZ.arrayZ, lookupCount, lookupRecord.arrayZ, lookup_context));
+    return context_would_apply_lookup (c,
+                                      inputCount, inputZ.arrayZ,
+                                      lookupCount, lookupRecord.arrayZ,
+                                      lookup_context);
   }
 
   bool apply (hb_ot_apply_context_t *c,
              ContextApplyLookupContext &lookup_context) const
   {
     TRACE_APPLY (this);
-    const UnsizedArrayOf<LookupRecord> &lookupRecord = StructAfter<UnsizedArrayOf<LookupRecord> >
+    const UnsizedArrayOf<LookupRecord> &lookupRecord = StructAfter<UnsizedArrayOf<LookupRecord>>
                                                       (inputZ.as_array (inputCount ? inputCount - 1 : 0));
     return_trace (context_apply_lookup (c, inputCount, inputZ.arrayZ, lookupCount, lookupRecord.arrayZ, lookup_context));
   }
@@ -1364,53 +1373,56 @@ struct RuleSet
   bool intersects (const hb_set_t *glyphs,
                   ContextClosureLookupContext &lookup_context) const
   {
-    unsigned int num_rules = rule.len;
-    for (unsigned int i = 0; i < num_rules; i++)
-      if ((this+rule[i]).intersects (glyphs, lookup_context))
-       return true;
-    return false;
+    return
+    + hb_iter (rule)
+    | hb_map (hb_add (this))
+    | hb_map ([&] (const Rule &_) { return _.intersects (glyphs, lookup_context); })
+    | hb_any
+    ;
   }
 
   void closure (hb_closure_context_t *c,
                ContextClosureLookupContext &lookup_context) const
   {
-    unsigned int num_rules = rule.len;
-    for (unsigned int i = 0; i < num_rules; i++)
-      (this+rule[i]).closure (c, lookup_context);
+    return
+    + hb_iter (rule)
+    | hb_map (hb_add (this))
+    | hb_apply ([&] (const Rule &_) { _.closure (c, lookup_context); })
+    ;
   }
 
   void collect_glyphs (hb_collect_glyphs_context_t *c,
                       ContextCollectGlyphsLookupContext &lookup_context) const
   {
-    unsigned int num_rules = rule.len;
-    for (unsigned int i = 0; i < num_rules; i++)
-      (this+rule[i]).collect_glyphs (c, lookup_context);
+    return
+    + hb_iter (rule)
+    | hb_map (hb_add (this))
+    | hb_apply ([&] (const Rule &_) { _.collect_glyphs (c, lookup_context); })
+    ;
   }
 
   bool would_apply (hb_would_apply_context_t *c,
                    ContextApplyLookupContext &lookup_context) const
   {
-    TRACE_WOULD_APPLY (this);
-    unsigned int num_rules = rule.len;
-    for (unsigned int i = 0; i < num_rules; i++)
-    {
-      if ((this+rule[i]).would_apply (c, lookup_context))
-       return_trace (true);
-    }
-    return_trace (false);
+    return
+    + hb_iter (rule)
+    | hb_map (hb_add (this))
+    | hb_map ([&] (const Rule &_) { return _.would_apply (c, lookup_context); })
+    | hb_any
+    ;
   }
 
   bool apply (hb_ot_apply_context_t *c,
              ContextApplyLookupContext &lookup_context) const
   {
     TRACE_APPLY (this);
-    unsigned int num_rules = rule.len;
-    for (unsigned int i = 0; i < num_rules; i++)
-    {
-      if ((this+rule[i]).apply (c, lookup_context))
-       return_trace (true);
-    }
-    return_trace (false);
+    return_trace (
+    + hb_iter (rule)
+    | hb_map (hb_add (this))
+    | hb_map ([&] (const Rule &_) { return _.apply (c, lookup_context); })
+    | hb_any
+    )
+    ;
   }
 
   bool sanitize (hb_sanitize_context_t *c) const
@@ -1437,16 +1449,14 @@ struct ContextFormat1
       nullptr
     };
 
-    unsigned int count = ruleSet.len;
-    for (Coverage::Iter iter (this+coverage); iter.more (); iter.next ())
-    {
-      if (unlikely (iter.get_coverage () >= count))
-       break; /* Work around malicious fonts. https://github.com/harfbuzz/harfbuzz/issues/363 */
-      if (glyphs->has (iter.get_glyph ()) &&
-         (this+ruleSet[iter.get_coverage ()]).intersects (glyphs, lookup_context))
-       return true;
-    }
-    return false;
+    return
+    + hb_zip (this+coverage, ruleSet)
+    | hb_filter (*glyphs, hb_first)
+    | hb_map (hb_second)
+    | hb_map (hb_add (this))
+    | hb_map ([&] (const RuleSet &_) { return _.intersects (glyphs, lookup_context); })
+    | hb_any
+    ;
   }
 
   void closure (hb_closure_context_t *c) const
@@ -1456,14 +1466,12 @@ struct ContextFormat1
       nullptr
     };
 
-    unsigned int count = ruleSet.len;
-    for (Coverage::Iter iter (this+coverage); iter.more (); iter.next ())
-    {
-      if (unlikely (iter.get_coverage () >= count))
-       break; /* Work around malicious fonts. https://github.com/harfbuzz/harfbuzz/issues/363 */
-      if (c->glyphs->has (iter.get_glyph ()))
-       (this+ruleSet[iter.get_coverage ()]).closure (c, lookup_context);
-    }
+    + hb_zip (this+coverage, ruleSet)
+    | hb_filter (*c->glyphs, hb_first)
+    | hb_map (hb_second)
+    | hb_map (hb_add (this))
+    | hb_apply ([&] (const RuleSet &_) { _.closure (c, lookup_context); })
+    ;
   }
 
   void collect_glyphs (hb_collect_glyphs_context_t *c) const
@@ -1475,21 +1483,20 @@ struct ContextFormat1
       nullptr
     };
 
-    unsigned int count = ruleSet.len;
-    for (unsigned int i = 0; i < count; i++)
-      (this+ruleSet[i]).collect_glyphs (c, lookup_context);
+    + hb_iter (ruleSet)
+    | hb_map (hb_add (this))
+    | hb_apply ([&] (const RuleSet &_) { _.collect_glyphs (c, lookup_context); })
+    ;
   }
 
   bool would_apply (hb_would_apply_context_t *c) const
   {
-    TRACE_WOULD_APPLY (this);
-
     const RuleSet &rule_set = this+ruleSet[(this+coverage).get_coverage (c->glyphs[0])];
     struct ContextApplyLookupContext lookup_context = {
       {match_glyph},
       nullptr
     };
-    return_trace (rule_set.would_apply (c, lookup_context));
+    return rule_set.would_apply (c, lookup_context);
   }
 
   const Coverage &get_coverage () const { return this+coverage; }
@@ -1549,13 +1556,13 @@ struct ContextFormat2
       &class_def
     };
 
-    unsigned int count = ruleSet.len;
-    for (unsigned int i = 0; i < count; i++)
-      if (class_def.intersects_class (glyphs, i) &&
-         (this+ruleSet[i]).intersects (glyphs, lookup_context))
-       return true;
-
-    return false;
+    return
+    + hb_enumerate (ruleSet)
+    | hb_map ([&] (const hb_pair_t<unsigned, const OffsetTo<RuleSet> &> p)
+             { return class_def.intersects_class (glyphs, p.first) &&
+                      (this+p.second).intersects (glyphs, lookup_context); })
+    | hb_any
+    ;
   }
 
   void closure (hb_closure_context_t *c) const
@@ -1570,12 +1577,15 @@ struct ContextFormat2
       &class_def
     };
 
-    unsigned int count = ruleSet.len;
-    for (unsigned int i = 0; i < count; i++)
-      if (class_def.intersects_class (c->glyphs, i)) {
-       const RuleSet &rule_set = this+ruleSet[i];
-       rule_set.closure (c, lookup_context);
-      }
+    return
+    + hb_enumerate (ruleSet)
+    | hb_filter ([&] (unsigned _)
+                { return class_def.intersects_class (c->glyphs, _); },
+                hb_first)
+    | hb_map (hb_second)
+    | hb_map (hb_add (this))
+    | hb_apply ([&] (const RuleSet &_) { _.closure (c, lookup_context); })
+    ;
   }
 
   void collect_glyphs (hb_collect_glyphs_context_t *c) const
@@ -1588,15 +1598,14 @@ struct ContextFormat2
       &class_def
     };
 
-    unsigned int count = ruleSet.len;
-    for (unsigned int i = 0; i < count; i++)
-      (this+ruleSet[i]).collect_glyphs (c, lookup_context);
+    + hb_iter (ruleSet)
+    | hb_map (hb_add (this))
+    | hb_apply ([&] (const RuleSet &_) { _.collect_glyphs (c, lookup_context); })
+    ;
   }
 
   bool would_apply (hb_would_apply_context_t *c) const
   {
-    TRACE_WOULD_APPLY (this);
-
     const ClassDef &class_def = this+classDef;
     unsigned int index = class_def.get_class (c->glyphs[0]);
     const RuleSet &rule_set = this+ruleSet[index];
@@ -1604,7 +1613,7 @@ struct ContextFormat2
       {match_class},
       &class_def
     };
-    return_trace (rule_set.would_apply (c, lookup_context));
+    return rule_set.would_apply (c, lookup_context);
   }
 
   const Coverage &get_coverage () const { return this+coverage; }
@@ -1704,14 +1713,15 @@ struct ContextFormat3
 
   bool would_apply (hb_would_apply_context_t *c) const
   {
-    TRACE_WOULD_APPLY (this);
-
     const LookupRecord *lookupRecord = &StructAfter<LookupRecord> (coverageZ.as_array (glyphCount));
     struct ContextApplyLookupContext lookup_context = {
       {match_coverage},
       this
     };
-    return_trace (context_would_apply_lookup (c, glyphCount, (const HBUINT16 *) (coverageZ.arrayZ + 1), lookupCount, lookupRecord, lookup_context));
+    return context_would_apply_lookup (c,
+                                      glyphCount, (const HBUINT16 *) (coverageZ.arrayZ + 1),
+                                      lookupCount, lookupRecord,
+                                      lookup_context);
   }
 
   const Coverage &get_coverage () const { return this+coverageZ[0]; }
@@ -1755,7 +1765,7 @@ struct ContextFormat3
   HBUINT16     glyphCount;             /* Number of glyphs in the input glyph
                                         * sequence */
   HBUINT16     lookupCount;            /* Number of LookupRecords */
-  UnsizedArrayOf<OffsetTo<Coverage> >
+  UnsizedArrayOf<OffsetTo<Coverage>>
                coverageZ;              /* Array of offsets to Coverage
                                         * table in glyph sequence order */
 /*UnsizedArrayOf<LookupRecord>
@@ -1767,15 +1777,15 @@ struct ContextFormat3
 
 struct Context
 {
-  template <typename context_t>
-  typename context_t::return_t dispatch (context_t *c) const
+  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));
-    case 2: return_trace (c->dispatch (u.format2));
-    case 3: return_trace (c->dispatch (u.format3));
+    case 1: return_trace (c->dispatch (u.format1, hb_forward<Ts> (ds)...));
+    case 2: return_trace (c->dispatch (u.format2, hb_forward<Ts> (ds)...));
+    case 3: return_trace (c->dispatch (u.format3, hb_forward<Ts> (ds)...));
     default:return_trace (c->default_return_value ());
     }
   }
@@ -1927,8 +1937,8 @@ struct ChainRule
 {
   bool intersects (const hb_set_t *glyphs, ChainContextClosureLookupContext &lookup_context) const
   {
-    const HeadlessArrayOf<HBUINT16> &input = StructAfter<HeadlessArrayOf<HBUINT16> > (backtrack);
-    const ArrayOf<HBUINT16> &lookahead = StructAfter<ArrayOf<HBUINT16> > (input);
+    const HeadlessArrayOf<HBUINT16> &input = StructAfter<HeadlessArrayOf<HBUINT16>> (backtrack);
+    const ArrayOf<HBUINT16> &lookahead = StructAfter<ArrayOf<HBUINT16>> (input);
     return chain_context_intersects (glyphs,
                                     backtrack.len, backtrack.arrayZ,
                                     input.lenP1, input.arrayZ,
@@ -1939,9 +1949,9 @@ struct ChainRule
   void closure (hb_closure_context_t *c,
                ChainContextClosureLookupContext &lookup_context) const
   {
-    const HeadlessArrayOf<HBUINT16> &input = StructAfter<HeadlessArrayOf<HBUINT16> > (backtrack);
-    const ArrayOf<HBUINT16> &lookahead = StructAfter<ArrayOf<HBUINT16> > (input);
-    const ArrayOf<LookupRecord> &lookup = StructAfter<ArrayOf<LookupRecord> > (lookahead);
+    const HeadlessArrayOf<HBUINT16> &input = StructAfter<HeadlessArrayOf<HBUINT16>> (backtrack);
+    const ArrayOf<HBUINT16> &lookahead = StructAfter<ArrayOf<HBUINT16>> (input);
+    const ArrayOf<LookupRecord> &lookup = StructAfter<ArrayOf<LookupRecord>> (lookahead);
     chain_context_closure_lookup (c,
                                  backtrack.len, backtrack.arrayZ,
                                  input.lenP1, input.arrayZ,
@@ -1953,9 +1963,9 @@ struct ChainRule
   void collect_glyphs (hb_collect_glyphs_context_t *c,
                       ChainContextCollectGlyphsLookupContext &lookup_context) const
   {
-    const HeadlessArrayOf<HBUINT16> &input = StructAfter<HeadlessArrayOf<HBUINT16> > (backtrack);
-    const ArrayOf<HBUINT16> &lookahead = StructAfter<ArrayOf<HBUINT16> > (input);
-    const ArrayOf<LookupRecord> &lookup = StructAfter<ArrayOf<LookupRecord> > (lookahead);
+    const HeadlessArrayOf<HBUINT16> &input = StructAfter<HeadlessArrayOf<HBUINT16>> (backtrack);
+    const ArrayOf<HBUINT16> &lookahead = StructAfter<ArrayOf<HBUINT16>> (input);
+    const ArrayOf<LookupRecord> &lookup = StructAfter<ArrayOf<LookupRecord>> (lookahead);
     chain_context_collect_glyphs_lookup (c,
                                         backtrack.len, backtrack.arrayZ,
                                         input.lenP1, input.arrayZ,
@@ -1967,23 +1977,22 @@ struct ChainRule
   bool would_apply (hb_would_apply_context_t *c,
                    ChainContextApplyLookupContext &lookup_context) const
   {
-    TRACE_WOULD_APPLY (this);
-    const HeadlessArrayOf<HBUINT16> &input = StructAfter<HeadlessArrayOf<HBUINT16> > (backtrack);
-    const ArrayOf<HBUINT16> &lookahead = StructAfter<ArrayOf<HBUINT16> > (input);
-    const ArrayOf<LookupRecord> &lookup = StructAfter<ArrayOf<LookupRecord> > (lookahead);
-    return_trace (chain_context_would_apply_lookup (c,
-                                                   backtrack.len, backtrack.arrayZ,
-                                                   input.lenP1, input.arrayZ,
-                                                   lookahead.len, lookahead.arrayZ, lookup.len,
-                                                   lookup.arrayZ, lookup_context));
+    const HeadlessArrayOf<HBUINT16> &input = StructAfter<HeadlessArrayOf<HBUINT16>> (backtrack);
+    const ArrayOf<HBUINT16> &lookahead = StructAfter<ArrayOf<HBUINT16>> (input);
+    const ArrayOf<LookupRecord> &lookup = StructAfter<ArrayOf<LookupRecord>> (lookahead);
+    return chain_context_would_apply_lookup (c,
+                                            backtrack.len, backtrack.arrayZ,
+                                            input.lenP1, input.arrayZ,
+                                            lookahead.len, lookahead.arrayZ, lookup.len,
+                                            lookup.arrayZ, lookup_context);
   }
 
   bool apply (hb_ot_apply_context_t *c, ChainContextApplyLookupContext &lookup_context) const
   {
     TRACE_APPLY (this);
-    const HeadlessArrayOf<HBUINT16> &input = StructAfter<HeadlessArrayOf<HBUINT16> > (backtrack);
-    const ArrayOf<HBUINT16> &lookahead = StructAfter<ArrayOf<HBUINT16> > (input);
-    const ArrayOf<LookupRecord> &lookup = StructAfter<ArrayOf<LookupRecord> > (lookahead);
+    const HeadlessArrayOf<HBUINT16> &input = StructAfter<HeadlessArrayOf<HBUINT16>> (backtrack);
+    const ArrayOf<HBUINT16> &lookahead = StructAfter<ArrayOf<HBUINT16>> (input);
+    const ArrayOf<LookupRecord> &lookup = StructAfter<ArrayOf<LookupRecord>> (lookahead);
     return_trace (chain_context_apply_lookup (c,
                                              backtrack.len, backtrack.arrayZ,
                                              input.lenP1, input.arrayZ,
@@ -1991,15 +2000,92 @@ struct ChainRule
                                              lookup.arrayZ, lookup_context));
   }
 
+  template<typename Iterator,
+          hb_requires (hb_is_iterator (Iterator))>
+  void serialize_array (hb_serialize_context_t *c,
+                        HBUINT16 len,
+                        Iterator it) const
+  {
+    c->copy (len);
+    for (const auto g : it)
+    {
+      HBUINT16 gid;
+      gid = g;
+      c->copy (gid);
+    }
+  }
+
+  ChainRule* copy (hb_serialize_context_t *c,
+                  const hb_map_t *backtrack_map,
+                  const hb_map_t *input_map = nullptr,
+                  const hb_map_t *lookahead_map = nullptr) const
+  {
+    TRACE_SERIALIZE (this);
+    auto *out = c->start_embed (this);
+    if (unlikely (!out)) return_trace (nullptr);
+
+    const hb_map_t *mapping = backtrack_map;
+    serialize_array (c, backtrack.len, + backtrack.iter ()
+                                      | hb_map (mapping));
+
+    const HeadlessArrayOf<HBUINT16> &input = StructAfter<HeadlessArrayOf<HBUINT16>> (backtrack);
+    if (input_map) mapping = input_map;
+    serialize_array (c, input.lenP1, + input.iter ()
+                                    | hb_map (mapping));
+
+    const ArrayOf<HBUINT16> &lookahead = StructAfter<ArrayOf<HBUINT16>> (input);
+    if (lookahead_map) mapping = lookahead_map;
+    serialize_array (c, lookahead.len, + lookahead.iter ()
+                                      | hb_map (mapping));
+
+    const ArrayOf<LookupRecord> &lookup = StructAfter<ArrayOf<LookupRecord>> (lookahead);
+    c->copy (lookup);
+
+    return_trace (out);
+  }
+
+  bool subset (hb_subset_context_t *c,
+               const hb_map_t *backtrack_map = nullptr,
+               const hb_map_t *input_map = nullptr,
+               const hb_map_t *lookahead_map = nullptr) const
+  {
+    TRACE_SUBSET (this);
+
+    const HeadlessArrayOf<HBUINT16> &input = StructAfter<HeadlessArrayOf<HBUINT16>> (backtrack);
+    const ArrayOf<HBUINT16> &lookahead = StructAfter<ArrayOf<HBUINT16>> (input);
+
+    if (!backtrack_map)
+    {
+      const hb_set_t &glyphset = *c->plan->glyphset ();
+      if (!hb_all (backtrack, glyphset) ||
+          !hb_all (input, glyphset) ||
+          !hb_all (lookahead, glyphset))
+        return_trace (false);
+
+      copy (c->serializer, c->plan->glyph_map);
+    }
+    else
+    {
+      if (!hb_all (backtrack, backtrack_map) ||
+          !hb_all (input, input_map) ||
+          !hb_all (lookahead, lookahead_map))
+        return_trace (false);
+
+      copy (c->serializer, backtrack_map, input_map, lookahead_map);
+    }
+
+    return_trace (true);
+  }
+
   bool sanitize (hb_sanitize_context_t *c) const
   {
     TRACE_SANITIZE (this);
     if (!backtrack.sanitize (c)) return_trace (false);
-    const HeadlessArrayOf<HBUINT16> &input = StructAfter<HeadlessArrayOf<HBUINT16> > (backtrack);
+    const HeadlessArrayOf<HBUINT16> &input = StructAfter<HeadlessArrayOf<HBUINT16>> (backtrack);
     if (!input.sanitize (c)) return_trace (false);
-    const ArrayOf<HBUINT16> &lookahead = StructAfter<ArrayOf<HBUINT16> > (input);
+    const ArrayOf<HBUINT16> &lookahead = StructAfter<ArrayOf<HBUINT16>> (input);
     if (!lookahead.sanitize (c)) return_trace (false);
-    const ArrayOf<LookupRecord> &lookup = StructAfter<ArrayOf<LookupRecord> > (lookahead);
+    const ArrayOf<LookupRecord> &lookup = StructAfter<ArrayOf<LookupRecord>> (lookahead);
     return_trace (lookup.sanitize (c));
   }
 
@@ -2025,46 +2111,85 @@ struct ChainRuleSet
 {
   bool intersects (const hb_set_t *glyphs, ChainContextClosureLookupContext &lookup_context) const
   {
-    unsigned int num_rules = rule.len;
-    for (unsigned int i = 0; i < num_rules; i++)
-      if ((this+rule[i]).intersects (glyphs, lookup_context))
-       return true;
-    return false;
+    return
+    + hb_iter (rule)
+    | hb_map (hb_add (this))
+    | hb_map ([&] (const ChainRule &_) { return _.intersects (glyphs, lookup_context); })
+    | hb_any
+    ;
   }
   void closure (hb_closure_context_t *c, ChainContextClosureLookupContext &lookup_context) const
   {
-    unsigned int num_rules = rule.len;
-    for (unsigned int i = 0; i < num_rules; i++)
-      (this+rule[i]).closure (c, lookup_context);
+    return
+    + hb_iter (rule)
+    | hb_map (hb_add (this))
+    | hb_apply ([&] (const ChainRule &_) { _.closure (c, lookup_context); })
+    ;
   }
 
   void collect_glyphs (hb_collect_glyphs_context_t *c, ChainContextCollectGlyphsLookupContext &lookup_context) const
   {
-    unsigned int num_rules = rule.len;
-    for (unsigned int i = 0; i < num_rules; i++)
-      (this+rule[i]).collect_glyphs (c, lookup_context);
+    return
+    + hb_iter (rule)
+    | hb_map (hb_add (this))
+    | hb_apply ([&] (const ChainRule &_) { _.collect_glyphs (c, lookup_context); })
+    ;
   }
 
   bool would_apply (hb_would_apply_context_t *c, ChainContextApplyLookupContext &lookup_context) const
   {
-    TRACE_WOULD_APPLY (this);
-    unsigned int num_rules = rule.len;
-    for (unsigned int i = 0; i < num_rules; i++)
-      if ((this+rule[i]).would_apply (c, lookup_context))
-       return_trace (true);
-
-    return_trace (false);
+    return
+    + hb_iter (rule)
+    | hb_map (hb_add (this))
+    | hb_map ([&] (const ChainRule &_) { return _.would_apply (c, lookup_context); })
+    | hb_any
+    ;
   }
 
   bool apply (hb_ot_apply_context_t *c, ChainContextApplyLookupContext &lookup_context) const
   {
     TRACE_APPLY (this);
-    unsigned int num_rules = rule.len;
-    for (unsigned int i = 0; i < num_rules; i++)
-      if ((this+rule[i]).apply (c, lookup_context))
-       return_trace (true);
+    return_trace (
+    + hb_iter (rule)
+    | hb_map (hb_add (this))
+    | hb_map ([&] (const ChainRule &_) { return _.apply (c, lookup_context); })
+    | hb_any
+    )
+    ;
+  }
 
-    return_trace (false);
+  bool subset (hb_subset_context_t *c,
+               const hb_map_t *backtrack_klass_map = nullptr,
+               const hb_map_t *input_klass_map = nullptr,
+               const hb_map_t *lookahead_klass_map = nullptr) const
+  {
+    TRACE_SUBSET (this);
+
+    auto snap = c->serializer->snapshot ();
+    auto *out = c->serializer->start_embed (*this);
+    if (unlikely (!c->serializer->extend_min (out))) return_trace (false);
+
+    for (const OffsetTo<ChainRule>& _ : rule)
+    {
+      if (!_) continue;
+      auto *o = out->rule.serialize_append (c->serializer);
+      if (unlikely (!o)) continue;
+
+      auto o_snap = c->serializer->snapshot ();
+      if (!o->serialize_subset (c, _, this, out,
+                                backtrack_klass_map,
+                                input_klass_map,
+                                lookahead_klass_map))
+      {
+        out->rule.pop ();
+        c->serializer->revert (o_snap);
+      }
+    }
+
+    bool ret = bool (out->rule);
+    if (!ret) c->serializer->revert (snap);
+
+    return_trace (ret);
   }
 
   bool sanitize (hb_sanitize_context_t *c) const
@@ -2090,16 +2215,14 @@ struct ChainContextFormat1
       {nullptr, nullptr, nullptr}
     };
 
-    unsigned int count = ruleSet.len;
-    for (Coverage::Iter iter (this+coverage); iter.more (); iter.next ())
-    {
-      if (unlikely (iter.get_coverage () >= count))
-       break; /* Work around malicious fonts. https://github.com/harfbuzz/harfbuzz/issues/363 */
-      if (glyphs->has (iter.get_glyph ()) &&
-         (this+ruleSet[iter.get_coverage ()]).intersects (glyphs, lookup_context))
-       return true;
-    }
-    return false;
+    return
+    + hb_zip (this+coverage, ruleSet)
+    | hb_filter (*glyphs, hb_first)
+    | hb_map (hb_second)
+    | hb_map (hb_add (this))
+    | hb_map ([&] (const ChainRuleSet &_) { return _.intersects (glyphs, lookup_context); })
+    | hb_any
+    ;
   }
 
   void closure (hb_closure_context_t *c) const
@@ -2109,14 +2232,12 @@ struct ChainContextFormat1
       {nullptr, nullptr, nullptr}
     };
 
-    unsigned int count = ruleSet.len;
-    for (Coverage::Iter iter (this+coverage); iter.more (); iter.next ())
-    {
-      if (unlikely (iter.get_coverage () >= count))
-       break; /* Work around malicious fonts. https://github.com/harfbuzz/harfbuzz/issues/363 */
-      if (c->glyphs->has (iter.get_glyph ()))
-       (this+ruleSet[iter.get_coverage ()]).closure (c, lookup_context);
-    }
+    + hb_zip (this+coverage, ruleSet)
+    | hb_filter (*c->glyphs, hb_first)
+    | hb_map (hb_second)
+    | hb_map (hb_add (this))
+    | hb_apply ([&] (const ChainRuleSet &_) { _.closure (c, lookup_context); })
+    ;
   }
 
   void collect_glyphs (hb_collect_glyphs_context_t *c) const
@@ -2128,21 +2249,20 @@ struct ChainContextFormat1
       {nullptr, nullptr, nullptr}
     };
 
-    unsigned int count = ruleSet.len;
-    for (unsigned int i = 0; i < count; i++)
-      (this+ruleSet[i]).collect_glyphs (c, lookup_context);
+    + hb_iter (ruleSet)
+    | hb_map (hb_add (this))
+    | hb_apply ([&] (const ChainRuleSet &_) { _.collect_glyphs (c, lookup_context); })
+    ;
   }
 
   bool would_apply (hb_would_apply_context_t *c) const
   {
-    TRACE_WOULD_APPLY (this);
-
     const ChainRuleSet &rule_set = this+ruleSet[(this+coverage).get_coverage (c->glyphs[0])];
     struct ChainContextApplyLookupContext lookup_context = {
       {match_glyph},
       {nullptr, nullptr, nullptr}
     };
-    return_trace (rule_set.would_apply (c, lookup_context));
+    return rule_set.would_apply (c, lookup_context);
   }
 
   const Coverage &get_coverage () const { return this+coverage; }
@@ -2164,8 +2284,25 @@ struct ChainContextFormat1
   bool subset (hb_subset_context_t *c) const
   {
     TRACE_SUBSET (this);
-    // TODO(subset)
-    return_trace (false);
+    const hb_set_t &glyphset = *c->plan->glyphset ();
+    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);
+    out->format = format;
+
+    hb_sorted_vector_t<hb_codepoint_t> new_coverage;
+    + hb_zip (this+coverage, ruleSet)
+    | hb_filter (glyphset, hb_first)
+    | hb_filter (subset_offset_array (c, out->ruleSet, this, out), hb_second)
+    | hb_map (hb_first)
+    | hb_map (glyph_map)
+    | hb_sink (new_coverage)
+    ;
+
+    out->coverage.serialize (c->serializer, out)
+                .serialize (c->serializer, new_coverage.iter ());
+    return_trace (bool (new_coverage));
   }
 
   bool sanitize (hb_sanitize_context_t *c) const
@@ -2204,13 +2341,13 @@ struct ChainContextFormat2
        &lookahead_class_def}
     };
 
-    unsigned int count = ruleSet.len;
-    for (unsigned int i = 0; i < count; i++)
-      if (input_class_def.intersects_class (glyphs, i) &&
-         (this+ruleSet[i]).intersects (glyphs, lookup_context))
-       return true;
-
-    return false;
+    return
+    + hb_enumerate (ruleSet)
+    | hb_map ([&] (const hb_pair_t<unsigned, const OffsetTo<ChainRuleSet> &> p)
+             { return input_class_def.intersects_class (glyphs, p.first) &&
+                      (this+p.second).intersects (glyphs, lookup_context); })
+    | hb_any
+    ;
   }
   void closure (hb_closure_context_t *c) const
   {
@@ -2228,12 +2365,15 @@ struct ChainContextFormat2
        &lookahead_class_def}
     };
 
-    unsigned int count = ruleSet.len;
-    for (unsigned int i = 0; i < count; i++)
-      if (input_class_def.intersects_class (c->glyphs, i)) {
-       const ChainRuleSet &rule_set = this+ruleSet[i];
-       rule_set.closure (c, lookup_context);
-      }
+    return
+    + hb_enumerate (ruleSet)
+    | hb_filter ([&] (unsigned _)
+                { return input_class_def.intersects_class (c->glyphs, _); },
+                hb_first)
+    | hb_map (hb_second)
+    | hb_map (hb_add (this))
+    | hb_apply ([&] (const ChainRuleSet &_) { _.closure (c, lookup_context); })
+    ;
   }
 
   void collect_glyphs (hb_collect_glyphs_context_t *c) const
@@ -2251,15 +2391,14 @@ struct ChainContextFormat2
        &lookahead_class_def}
     };
 
-    unsigned int count = ruleSet.len;
-    for (unsigned int i = 0; i < count; i++)
-      (this+ruleSet[i]).collect_glyphs (c, lookup_context);
+    + hb_iter (ruleSet)
+    | hb_map (hb_add (this))
+    | hb_apply ([&] (const ChainRuleSet &_) { _.collect_glyphs (c, lookup_context); })
+    ;
   }
 
   bool would_apply (hb_would_apply_context_t *c) const
   {
-    TRACE_WOULD_APPLY (this);
-
     const ClassDef &backtrack_class_def = this+backtrackClassDef;
     const ClassDef &input_class_def = this+inputClassDef;
     const ClassDef &lookahead_class_def = this+lookaheadClassDef;
@@ -2272,7 +2411,7 @@ struct ChainContextFormat2
        &input_class_def,
        &lookahead_class_def}
     };
-    return_trace (rule_set.would_apply (c, lookup_context));
+    return rule_set.would_apply (c, lookup_context);
   }
 
   const Coverage &get_coverage () const { return this+coverage; }
@@ -2301,8 +2440,54 @@ struct ChainContextFormat2
   bool subset (hb_subset_context_t *c) const
   {
     TRACE_SUBSET (this);
-    // TODO(subset)
-    return_trace (false);
+    auto *out = c->serializer->start_embed (*this);
+    if (unlikely (!c->serializer->extend_min (out))) return_trace (false);
+    out->format = format;
+    out->coverage.serialize_subset (c, coverage, this, out);
+
+    hb_map_t backtrack_klass_map;
+    out->backtrackClassDef.serialize_subset (c, backtrackClassDef, this, out, &backtrack_klass_map);
+
+    // subset inputClassDef based on glyphs survived in Coverage subsetting
+    hb_map_t input_klass_map;
+    out->inputClassDef.serialize_subset (c, inputClassDef, this, out, &input_klass_map);
+
+    hb_map_t lookahead_klass_map;
+    out->lookaheadClassDef.serialize_subset (c, lookaheadClassDef, this, out, &lookahead_klass_map);
+
+    hb_vector_t<unsigned> rulesets;
+    bool ret = true;
+    for (const OffsetTo<ChainRuleSet>& _ : + hb_enumerate (ruleSet)
+                                          | hb_filter (input_klass_map, hb_first)
+                                          | hb_map (hb_second))
+    {
+      auto *o = out->ruleSet.serialize_append (c->serializer);
+      if (unlikely (!o))
+      {
+        ret = false;
+        break;
+      }
+      if (!o->serialize_subset (c, _, this, out,
+                                &backtrack_klass_map,
+                                &input_klass_map,
+                                &lookahead_klass_map))
+      {
+        rulesets.push (0);
+      }
+      else rulesets.push (1);
+    }
+
+    if (!ret) return_trace (ret);
+
+    //prune empty trailing ruleSets
+    unsigned count = rulesets.length;
+    while (count > 0 && rulesets[count-1] == 0)
+    {
+      out->ruleSet.pop ();
+      count--;
+    }
+
+    return_trace (bool (out->ruleSet));
   }
 
   bool sanitize (hb_sanitize_context_t *c) const
@@ -2343,12 +2528,12 @@ struct ChainContextFormat3
 {
   bool intersects (const hb_set_t *glyphs) const
   {
-    const OffsetArrayOf<Coverage> &input = StructAfter<OffsetArrayOf<Coverage> > (backtrack);
+    const OffsetArrayOf<Coverage> &input = StructAfter<OffsetArrayOf<Coverage>> (backtrack);
 
     if (!(this+input[0]).intersects (glyphs))
       return false;
 
-    const OffsetArrayOf<Coverage> &lookahead = StructAfter<OffsetArrayOf<Coverage> > (input);
+    const OffsetArrayOf<Coverage> &lookahead = StructAfter<OffsetArrayOf<Coverage>> (input);
     struct ChainContextClosureLookupContext lookup_context = {
       {intersects_coverage},
       {this, this, this}
@@ -2362,13 +2547,13 @@ struct ChainContextFormat3
 
   void closure (hb_closure_context_t *c) const
   {
-    const OffsetArrayOf<Coverage> &input = StructAfter<OffsetArrayOf<Coverage> > (backtrack);
+    const OffsetArrayOf<Coverage> &input = StructAfter<OffsetArrayOf<Coverage>> (backtrack);
 
     if (!(this+input[0]).intersects (c->glyphs))
       return;
 
-    const OffsetArrayOf<Coverage> &lookahead = StructAfter<OffsetArrayOf<Coverage> > (input);
-    const ArrayOf<LookupRecord> &lookup = StructAfter<ArrayOf<LookupRecord> > (lookahead);
+    const OffsetArrayOf<Coverage> &lookahead = StructAfter<OffsetArrayOf<Coverage>> (input);
+    const ArrayOf<LookupRecord> &lookup = StructAfter<ArrayOf<LookupRecord>> (lookahead);
     struct ChainContextClosureLookupContext lookup_context = {
       {intersects_coverage},
       {this, this, this}
@@ -2383,12 +2568,12 @@ struct ChainContextFormat3
 
   void collect_glyphs (hb_collect_glyphs_context_t *c) const
   {
-    const OffsetArrayOf<Coverage> &input = StructAfter<OffsetArrayOf<Coverage> > (backtrack);
+    const OffsetArrayOf<Coverage> &input = StructAfter<OffsetArrayOf<Coverage>> (backtrack);
 
     (this+input[0]).add_coverage (c->input);
 
-    const OffsetArrayOf<Coverage> &lookahead = StructAfter<OffsetArrayOf<Coverage> > (input);
-    const ArrayOf<LookupRecord> &lookup = StructAfter<ArrayOf<LookupRecord> > (lookahead);
+    const OffsetArrayOf<Coverage> &lookahead = StructAfter<OffsetArrayOf<Coverage>> (input);
+    const ArrayOf<LookupRecord> &lookup = StructAfter<ArrayOf<LookupRecord>> (lookahead);
     struct ChainContextCollectGlyphsLookupContext lookup_context = {
       {collect_coverage},
       {this, this, this}
@@ -2403,38 +2588,36 @@ struct ChainContextFormat3
 
   bool would_apply (hb_would_apply_context_t *c) const
   {
-    TRACE_WOULD_APPLY (this);
-
-    const OffsetArrayOf<Coverage> &input = StructAfter<OffsetArrayOf<Coverage> > (backtrack);
-    const OffsetArrayOf<Coverage> &lookahead = StructAfter<OffsetArrayOf<Coverage> > (input);
-    const ArrayOf<LookupRecord> &lookup = StructAfter<ArrayOf<LookupRecord> > (lookahead);
+    const OffsetArrayOf<Coverage> &input = StructAfter<OffsetArrayOf<Coverage>> (backtrack);
+    const OffsetArrayOf<Coverage> &lookahead = StructAfter<OffsetArrayOf<Coverage>> (input);
+    const ArrayOf<LookupRecord> &lookup = StructAfter<ArrayOf<LookupRecord>> (lookahead);
     struct ChainContextApplyLookupContext lookup_context = {
       {match_coverage},
       {this, this, this}
     };
-    return_trace (chain_context_would_apply_lookup (c,
-                                                   backtrack.len, (const HBUINT16 *) backtrack.arrayZ,
-                                                   input.len, (const HBUINT16 *) input.arrayZ + 1,
-                                                   lookahead.len, (const HBUINT16 *) lookahead.arrayZ,
-                                                   lookup.len, lookup.arrayZ, lookup_context));
+    return chain_context_would_apply_lookup (c,
+                                            backtrack.len, (const HBUINT16 *) backtrack.arrayZ,
+                                            input.len, (const HBUINT16 *) input.arrayZ + 1,
+                                            lookahead.len, (const HBUINT16 *) lookahead.arrayZ,
+                                            lookup.len, lookup.arrayZ, lookup_context);
   }
 
   const Coverage &get_coverage () const
   {
-    const OffsetArrayOf<Coverage> &input = StructAfter<OffsetArrayOf<Coverage> > (backtrack);
+    const OffsetArrayOf<Coverage> &input = StructAfter<OffsetArrayOf<Coverage>> (backtrack);
     return this+input[0];
   }
 
   bool apply (hb_ot_apply_context_t *c) const
   {
     TRACE_APPLY (this);
-    const OffsetArrayOf<Coverage> &input = StructAfter<OffsetArrayOf<Coverage> > (backtrack);
+    const OffsetArrayOf<Coverage> &input = StructAfter<OffsetArrayOf<Coverage>> (backtrack);
 
     unsigned int index = (this+input[0]).get_coverage (c->buffer->cur().codepoint);
     if (likely (index == NOT_COVERED)) return_trace (false);
 
-    const OffsetArrayOf<Coverage> &lookahead = StructAfter<OffsetArrayOf<Coverage> > (input);
-    const ArrayOf<LookupRecord> &lookup = StructAfter<ArrayOf<LookupRecord> > (lookahead);
+    const OffsetArrayOf<Coverage> &lookahead = StructAfter<OffsetArrayOf<Coverage>> (input);
+    const ArrayOf<LookupRecord> &lookup = StructAfter<ArrayOf<LookupRecord>> (lookahead);
     struct ChainContextApplyLookupContext lookup_context = {
       {match_coverage},
       {this, this, this}
@@ -2446,23 +2629,58 @@ struct ChainContextFormat3
                                              lookup.len, lookup.arrayZ, lookup_context));
   }
 
+  template<typename Iterator,
+          hb_requires (hb_is_iterator (Iterator))>
+  bool serialize_coverage_offsets (hb_subset_context_t *c,
+                                   Iterator it,
+                                  const void* src_base,
+                                  const void* dst_base) const
+  {
+    TRACE_SERIALIZE (this);
+    auto *out = c->serializer->start_embed<OffsetArrayOf<Coverage>> ();
+
+    if (unlikely (!c->serializer->allocate_size<HBUINT16> (HBUINT16::static_size))) return_trace (false);
+
+    + it
+    | hb_apply (subset_offset_array (c, *out, src_base, dst_base))
+    ;
+
+    return_trace (out->len);
+  }
+
   bool subset (hb_subset_context_t *c) const
   {
     TRACE_SUBSET (this);
-    // TODO(subset)
-    return_trace (false);
+
+    auto *out = c->serializer->start_embed (this);
+    if (unlikely (!out)) return_trace (false);
+    if (unlikely (!c->serializer->embed (this->format))) return_trace (false);
+
+    if (!serialize_coverage_offsets (c, backtrack.iter (), this, out))
+      return_trace (false);
+
+    const OffsetArrayOf<Coverage> &input = StructAfter<OffsetArrayOf<Coverage>> (backtrack);
+    if (!serialize_coverage_offsets (c, input.iter (), this, out))
+      return_trace (false);
+
+    const OffsetArrayOf<Coverage> &lookahead = StructAfter<OffsetArrayOf<Coverage>> (input);
+    if (!serialize_coverage_offsets (c, lookahead.iter (), this, out))
+      return_trace (false);
+
+    const ArrayOf<LookupRecord> &lookup = StructAfter<ArrayOf<LookupRecord>> (lookahead);
+    return_trace (c->serializer->copy (lookup));
   }
 
   bool sanitize (hb_sanitize_context_t *c) const
   {
     TRACE_SANITIZE (this);
     if (!backtrack.sanitize (c, this)) return_trace (false);
-    const OffsetArrayOf<Coverage> &input = StructAfter<OffsetArrayOf<Coverage> > (backtrack);
+    const OffsetArrayOf<Coverage> &input = StructAfter<OffsetArrayOf<Coverage>> (backtrack);
     if (!input.sanitize (c, this)) return_trace (false);
     if (!input.len) return_trace (false); /* To be consistent with Context. */
-    const OffsetArrayOf<Coverage> &lookahead = StructAfter<OffsetArrayOf<Coverage> > (input);
+    const OffsetArrayOf<Coverage> &lookahead = StructAfter<OffsetArrayOf<Coverage>> (input);
     if (!lookahead.sanitize (c, this)) return_trace (false);
-    const ArrayOf<LookupRecord> &lookup = StructAfter<ArrayOf<LookupRecord> > (lookahead);
+    const ArrayOf<LookupRecord> &lookup = StructAfter<ArrayOf<LookupRecord>> (lookahead);
     return_trace (lookup.sanitize (c));
   }
 
@@ -2489,15 +2707,15 @@ struct ChainContextFormat3
 
 struct ChainContext
 {
-  template <typename context_t>
-  typename context_t::return_t dispatch (context_t *c) const
+  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));
-    case 2: return_trace (c->dispatch (u.format2));
-    case 3: return_trace (c->dispatch (u.format3));
+    case 1: return_trace (c->dispatch (u.format1, hb_forward<Ts> (ds)...));
+    case 2: return_trace (c->dispatch (u.format2, hb_forward<Ts> (ds)...));
+    case 3: return_trace (c->dispatch (u.format3, hb_forward<Ts> (ds)...));
     default:return_trace (c->default_return_value ());
     }
   }
@@ -2519,18 +2737,14 @@ struct ExtensionFormat1
 
   template <typename X>
   const X& get_subtable () const
-  {
-    unsigned int offset = extensionOffset;
-    if (unlikely (!offset)) return Null(typename T::SubTable);
-    return StructAtOffset<typename T::SubTable> (this, offset);
-  }
+  { return this + CastR<LOffsetTo<typename T::SubTable>> (extensionOffset); }
 
-  template <typename context_t>
-  typename context_t::return_t dispatch (context_t *c) const
+  template <typename context_t, typename ...Ts>
+  typename context_t::return_t dispatch (context_t *c, Ts&&... ds) const
   {
     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 ()));
+    return_trace (get_subtable<typename T::SubTable> ().dispatch (c, get_type (), hb_forward<Ts> (ds)...));
   }
 
   /* This is called from may_dispatch() above with hb_sanitize_context_t. */
@@ -2538,7 +2752,6 @@ struct ExtensionFormat1
   {
     TRACE_SANITIZE (this);
     return_trace (c->check_struct (this) &&
-                 extensionOffset != 0 &&
                  extensionLookupType != T::SubTable::Extension);
   }
 
@@ -2547,7 +2760,7 @@ struct ExtensionFormat1
   HBUINT16     extensionLookupType;    /* Lookup type of subtable referenced
                                         * by ExtensionOffset (i.e. the
                                         * extension subtable). */
-  HBUINT32     extensionOffset;        /* Offset to the extension subtable,
+  Offset32     extensionOffset;        /* Offset to the extension subtable,
                                         * of lookup type subtable. */
   public:
   DEFINE_SIZE_STATIC (8);
@@ -2572,13 +2785,13 @@ struct Extension
     }
   }
 
-  template <typename context_t>
-  typename context_t::return_t dispatch (context_t *c) const
+  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 (u.format1.dispatch (c));
+    case 1: return_trace (u.format1.dispatch (c, hb_forward<Ts> (ds)...));
     default:return_trace (c->default_return_value ());
     }
   }
@@ -2661,11 +2874,17 @@ struct GSUBGPOS
 
   bool find_variations_index (const int *coords, unsigned int num_coords,
                              unsigned int *index) const
-  { return (version.to_int () >= 0x00010001u ? this+featureVars : Null(FeatureVariations))
-          .find_index (coords, num_coords, index); }
+  {
+#ifdef HB_NOVAR
+    return false;
+#endif
+    return (version.to_int () >= 0x00010001u ? this+featureVars : Null(FeatureVariations))
+           .find_index (coords, num_coords, index);
+  }
   const Feature& get_feature_variation (unsigned int feature_index,
                                        unsigned int variations_index) const
   {
+#ifndef HB_NO_VAR
     if (FeatureVariations::NOT_FOUND_INDEX != variations_index &&
        version.to_int () >= 0x00010001u)
     {
@@ -2674,6 +2893,7 @@ struct GSUBGPOS
       if (feature)
        return *feature;
     }
+#endif
     return get_feature (feature_index);
   }
 
@@ -2681,21 +2901,24 @@ struct GSUBGPOS
   bool subset (hb_subset_context_t *c) const
   {
     TRACE_SUBSET (this);
-    struct GSUBGPOS *out = c->serializer->embed (*this);
+    auto *out = c->serializer->embed (*this);
     if (unlikely (!out)) return_trace (false);
 
-    out->scriptList.serialize_subset (c, this+scriptList, out);
-    out->featureList.serialize_subset (c, this+featureList, out);
+    out->scriptList.serialize_subset (c, scriptList, this, out);
+    out->featureList.serialize_subset (c, featureList, this, out);
 
     typedef OffsetListOf<TLookup> TLookupList;
     /* TODO Use intersects() to count how many subtables survive? */
-    CastR<OffsetTo<TLookupList> > (out->lookupList)
+    CastR<OffsetTo<TLookupList>> (out->lookupList)
       .serialize_subset (c,
-                        this+CastR<const OffsetTo<TLookupList> > (lookupList),
+                        CastR<OffsetTo<TLookupList>> (lookupList),
+                        this,
                         out);
 
+#ifndef HB_NO_VAR
     if (version.to_int () >= 0x00010001u)
-     out->featureVars.serialize_subset (c, this+featureVars, out);
+     out->featureVars.serialize_copy (c->serializer, featureVars, this, out);
+#endif
 
     return_trace (true);
   }
@@ -2711,12 +2934,19 @@ struct GSUBGPOS
   {
     TRACE_SANITIZE (this);
     typedef OffsetListOf<TLookup> TLookupList;
-    return_trace (version.sanitize (c) &&
-                 likely (version.major == 1) &&
-                 scriptList.sanitize (c, this) &&
-                 featureList.sanitize (c, this) &&
-                 CastR<OffsetTo<TLookupList> > (lookupList).sanitize (c, this) &&
-                 (version.to_int () < 0x00010001u || featureVars.sanitize (c, this)));
+    if (unlikely (!(version.sanitize (c) &&
+                   likely (version.major == 1) &&
+                   scriptList.sanitize (c, this) &&
+                   featureList.sanitize (c, this) &&
+                   CastR<OffsetTo<TLookupList>> (lookupList).sanitize (c, this))))
+      return_trace (false);
+
+#ifndef HB_NO_VAR
+    if (unlikely (!(version.to_int () < 0x00010001u || featureVars.sanitize (c, this))))
+      return_trace (false);
+#endif
+
+    return_trace (true);
   }
 
   template <typename T>
index 1dd31d5..53eb623 100644 (file)
@@ -136,7 +136,7 @@ struct JstfLangSys : OffsetListOf<JstfPriority>
  * ExtenderGlyphs -- Extender Glyph Table
  */
 
-typedef SortedArrayOf<GlyphID> ExtenderGlyphs;
+typedef SortedArrayOf<HBGlyphID> ExtenderGlyphs;
 
 
 /*
index 1365a3e..fba3ad1 100644 (file)
  * Google Author(s): Behdad Esfahbod
  */
 
+#include "hb.hh"
+
+#ifndef HB_NO_OT_LAYOUT
+
+#ifdef HB_NO_OT_TAG
+#error "Cannot compile hb-ot-layout.cc with HB_NO_OT_TAG."
+#endif
+
 #include "hb-open-type.hh"
 #include "hb-ot-layout.hh"
 #include "hb-ot-face.hh"
@@ -35,7 +43,6 @@
 #include "hb-map.hh"
 
 #include "hb-ot-kern-table.hh"
-#include "hb-ot-gasp-table.hh" // Just so we compile it; unused otherwise.
 #include "hb-ot-layout-gdef-table.hh"
 #include "hb-ot-layout-gsub-table.hh"
 #include "hb-ot-layout-gpos-table.hh"
@@ -47,6 +54,7 @@
 #include "hb-aat-layout-lcar-table.hh"
 #include "hb-aat-layout-morx-table.hh"
 
+#include "hb-aat-layout-opbd-table.hh" // Just so we compile it; unused otherwise.
 
 /**
  * SECTION:hb-ot-layout
  * kern
  */
 
+#ifndef HB_NO_OT_KERN
+/**
+ * hb_ot_layout_has_kerning:
+ * @face: The #hb_face_t to work on
+ *
+ * Tests whether a face includes any kerning data in the 'kern' table.
+ * Does NOT test for kerning lookups in the GPOS table.
+ *
+ * Return value: true if data found, false otherwise
+ *
+ **/
 bool
 hb_ot_layout_has_kerning (hb_face_t *face)
 {
   return face->table.kern->has_data ();
 }
 
+/**
+ * hb_ot_layout_has_machine_kerning:
+ * @face: The #hb_face_t to work on
+ *
+ * Tests whether a face includes any state-machine kerning in the 'kern' table.
+ * Does NOT examine the GPOS table.
+ *
+ * Return value: true if data found, false otherwise
+ *
+ **/
 bool
 hb_ot_layout_has_machine_kerning (hb_face_t *face)
 {
   return face->table.kern->has_state_machine ();
 }
 
+/**
+ * hb_ot_layout_has_cross_kerning:
+ * @face: The #hb_face_t to work on
+ *
+ * Tests whether a face has any cross-stream kerning (i.e., kerns
+ * that make adjustments perpendicular to the direction of the text
+ * flow: Y adjustments in horizontal text or X adjustments in
+ * vertical text) in the 'kern' table.
+ *
+ * Does NOT examine the GPOS table.
+ *
+ * Return value: true is data found, false otherwise
+ *
+ **/
 bool
 hb_ot_layout_has_cross_kerning (hb_face_t *face)
 {
@@ -92,6 +135,7 @@ hb_ot_layout_kern (const hb_ot_shape_plan_t *plan,
 
   kern.apply (&c);
 }
+#endif
 
 
 /*
@@ -102,6 +146,9 @@ bool
 OT::GDEF::is_blacklisted (hb_blob_t *blob,
                          hb_face_t *face) const
 {
+#ifdef HB_NO_OT_LAYOUT_BLACKLIST
+  return false;
+#endif
   /* The ugly business of blacklisting individual fonts' tables happen here!
    * See this thread for why we finally had to bend in and do this:
    * https://lists.freedesktop.org/archives/harfbuzz/2016-February/005489.html
@@ -119,84 +166,82 @@ OT::GDEF::is_blacklisted (hb_blob_t *blob,
    *     https://bugzilla.mozilla.org/show_bug.cgi?id=1279693
    *     https://bugzilla.mozilla.org/show_bug.cgi?id=1279875
    */
-#define ENCODE(x,y,z) (((uint64_t) (x) << 48) | ((uint64_t) (y) << 24) | (uint64_t) (z))
-  switch ENCODE(blob->length,
-               face->table.GSUB->table.get_length (),
-               face->table.GPOS->table.get_length ())
+  switch HB_CODEPOINT_ENCODE3(blob->length,
+                             face->table.GSUB->table.get_length (),
+                             face->table.GPOS->table.get_length ())
   {
     /* sha1sum:c5ee92f0bca4bfb7d06c4d03e8cf9f9cf75d2e8a Windows 7? timesi.ttf */
-    case ENCODE (442, 2874, 42038):
+    case HB_CODEPOINT_ENCODE3 (442, 2874, 42038):
     /* sha1sum:37fc8c16a0894ab7b749e35579856c73c840867b Windows 7? timesbi.ttf */
-    case ENCODE (430, 2874, 40662):
+    case HB_CODEPOINT_ENCODE3 (430, 2874, 40662):
     /* sha1sum:19fc45110ea6cd3cdd0a5faca256a3797a069a80 Windows 7 timesi.ttf */
-    case ENCODE (442, 2874, 39116):
+    case HB_CODEPOINT_ENCODE3 (442, 2874, 39116):
     /* sha1sum:6d2d3c9ed5b7de87bc84eae0df95ee5232ecde26 Windows 7 timesbi.ttf */
-    case ENCODE (430, 2874, 39374):
+    case HB_CODEPOINT_ENCODE3 (430, 2874, 39374):
     /* sha1sum:8583225a8b49667c077b3525333f84af08c6bcd8 OS X 10.11.3 Times New Roman Italic.ttf */
-    case ENCODE (490, 3046, 41638):
+    case HB_CODEPOINT_ENCODE3 (490, 3046, 41638):
     /* sha1sum:ec0f5a8751845355b7c3271d11f9918a966cb8c9 OS X 10.11.3 Times New Roman Bold Italic.ttf */
-    case ENCODE (478, 3046, 41902):
+    case HB_CODEPOINT_ENCODE3 (478, 3046, 41902):
     /* sha1sum:96eda93f7d33e79962451c6c39a6b51ee893ce8c  tahoma.ttf from Windows 8 */
-    case ENCODE (898, 12554, 46470):
+    case HB_CODEPOINT_ENCODE3 (898, 12554, 46470):
     /* sha1sum:20928dc06014e0cd120b6fc942d0c3b1a46ac2bc  tahomabd.ttf from Windows 8 */
-    case ENCODE (910, 12566, 47732):
+    case HB_CODEPOINT_ENCODE3 (910, 12566, 47732):
     /* sha1sum:4f95b7e4878f60fa3a39ca269618dfde9721a79e  tahoma.ttf from Windows 8.1 */
-    case ENCODE (928, 23298, 59332):
+    case HB_CODEPOINT_ENCODE3 (928, 23298, 59332):
     /* sha1sum:6d400781948517c3c0441ba42acb309584b73033  tahomabd.ttf from Windows 8.1 */
-    case ENCODE (940, 23310, 60732):
+    case HB_CODEPOINT_ENCODE3 (940, 23310, 60732):
     /* tahoma.ttf v6.04 from Windows 8.1 x64, see https://bugzilla.mozilla.org/show_bug.cgi?id=1279925 */
-    case ENCODE (964, 23836, 60072):
+    case HB_CODEPOINT_ENCODE3 (964, 23836, 60072):
     /* tahomabd.ttf v6.04 from Windows 8.1 x64, see https://bugzilla.mozilla.org/show_bug.cgi?id=1279925 */
-    case ENCODE (976, 23832, 61456):
+    case HB_CODEPOINT_ENCODE3 (976, 23832, 61456):
     /* sha1sum:e55fa2dfe957a9f7ec26be516a0e30b0c925f846  tahoma.ttf from Windows 10 */
-    case ENCODE (994, 24474, 60336):
+    case HB_CODEPOINT_ENCODE3 (994, 24474, 60336):
     /* sha1sum:7199385abb4c2cc81c83a151a7599b6368e92343  tahomabd.ttf from Windows 10 */
-    case ENCODE (1006, 24470, 61740):
+    case HB_CODEPOINT_ENCODE3 (1006, 24470, 61740):
     /* tahoma.ttf v6.91 from Windows 10 x64, see https://bugzilla.mozilla.org/show_bug.cgi?id=1279925 */
-    case ENCODE (1006, 24576, 61346):
+    case HB_CODEPOINT_ENCODE3 (1006, 24576, 61346):
     /* tahomabd.ttf v6.91 from Windows 10 x64, see https://bugzilla.mozilla.org/show_bug.cgi?id=1279925 */
-    case ENCODE (1018, 24572, 62828):
+    case HB_CODEPOINT_ENCODE3 (1018, 24572, 62828):
     /* sha1sum:b9c84d820c49850d3d27ec498be93955b82772b5  tahoma.ttf from Windows 10 AU */
-    case ENCODE (1006, 24576, 61352):
+    case HB_CODEPOINT_ENCODE3 (1006, 24576, 61352):
     /* sha1sum:2bdfaab28174bdadd2f3d4200a30a7ae31db79d2  tahomabd.ttf from Windows 10 AU */
-    case ENCODE (1018, 24572, 62834):
+    case HB_CODEPOINT_ENCODE3 (1018, 24572, 62834):
     /* sha1sum:b0d36cf5a2fbe746a3dd277bffc6756a820807a7  Tahoma.ttf from Mac OS X 10.9 */
-    case ENCODE (832, 7324, 47162):
+    case HB_CODEPOINT_ENCODE3 (832, 7324, 47162):
     /* sha1sum:12fc4538e84d461771b30c18b5eb6bd434e30fba  Tahoma Bold.ttf from Mac OS X 10.9 */
-    case ENCODE (844, 7302, 45474):
+    case HB_CODEPOINT_ENCODE3 (844, 7302, 45474):
     /* sha1sum:eb8afadd28e9cf963e886b23a30b44ab4fd83acc  himalaya.ttf from Windows 7 */
-    case ENCODE (180, 13054, 7254):
+    case HB_CODEPOINT_ENCODE3 (180, 13054, 7254):
     /* sha1sum:73da7f025b238a3f737aa1fde22577a6370f77b0  himalaya.ttf from Windows 8 */
-    case ENCODE (192, 12638, 7254):
+    case HB_CODEPOINT_ENCODE3 (192, 12638, 7254):
     /* sha1sum:6e80fd1c0b059bbee49272401583160dc1e6a427  himalaya.ttf from Windows 8.1 */
-    case ENCODE (192, 12690, 7254):
+    case HB_CODEPOINT_ENCODE3 (192, 12690, 7254):
     /* 8d9267aea9cd2c852ecfb9f12a6e834bfaeafe44  cantarell-fonts-0.0.21/otf/Cantarell-Regular.otf */
     /* 983988ff7b47439ab79aeaf9a45bd4a2c5b9d371  cantarell-fonts-0.0.21/otf/Cantarell-Oblique.otf */
-    case ENCODE (188, 248, 3852):
+    case HB_CODEPOINT_ENCODE3 (188, 248, 3852):
     /* 2c0c90c6f6087ffbfea76589c93113a9cbb0e75f  cantarell-fonts-0.0.21/otf/Cantarell-Bold.otf */
     /* 55461f5b853c6da88069ffcdf7f4dd3f8d7e3e6b  cantarell-fonts-0.0.21/otf/Cantarell-Bold-Oblique.otf */
-    case ENCODE (188, 264, 3426):
+    case HB_CODEPOINT_ENCODE3 (188, 264, 3426):
     /* d125afa82a77a6475ac0e74e7c207914af84b37a padauk-2.80/Padauk.ttf RHEL 7.2 */
-    case ENCODE (1058, 47032, 11818):
+    case HB_CODEPOINT_ENCODE3 (1058, 47032, 11818):
     /* 0f7b80437227b90a577cc078c0216160ae61b031 padauk-2.80/Padauk-Bold.ttf RHEL 7.2*/
-    case ENCODE (1046, 47030, 12600):
+    case HB_CODEPOINT_ENCODE3 (1046, 47030, 12600):
     /* d3dde9aa0a6b7f8f6a89ef1002e9aaa11b882290 padauk-2.80/Padauk.ttf Ubuntu 16.04 */
-    case ENCODE (1058, 71796, 16770):
+    case HB_CODEPOINT_ENCODE3 (1058, 71796, 16770):
     /* 5f3c98ccccae8a953be2d122c1b3a77fd805093f padauk-2.80/Padauk-Bold.ttf Ubuntu 16.04 */
-    case ENCODE (1046, 71790, 17862):
+    case HB_CODEPOINT_ENCODE3 (1046, 71790, 17862):
     /* 6c93b63b64e8b2c93f5e824e78caca555dc887c7 padauk-2.80/Padauk-book.ttf */
-    case ENCODE (1046, 71788, 17112):
+    case HB_CODEPOINT_ENCODE3 (1046, 71788, 17112):
     /* d89b1664058359b8ec82e35d3531931125991fb9 padauk-2.80/Padauk-bookbold.ttf */
-    case ENCODE (1058, 71794, 17514):
+    case HB_CODEPOINT_ENCODE3 (1058, 71794, 17514):
     /* 824cfd193aaf6234b2b4dc0cf3c6ef576c0d00ef padauk-3.0/Padauk-book.ttf */
-    case ENCODE (1330, 109904, 57938):
+    case HB_CODEPOINT_ENCODE3 (1330, 109904, 57938):
     /* 91fcc10cf15e012d27571e075b3b4dfe31754a8a padauk-3.0/Padauk-bookbold.ttf */
-    case ENCODE (1330, 109904, 58972):
+    case HB_CODEPOINT_ENCODE3 (1330, 109904, 58972):
     /* sha1sum: c26e41d567ed821bed997e937bc0c41435689e85  Padauk.ttf
      *  "Padauk Regular" "Version 2.5", see https://crbug.com/681813 */
-    case ENCODE (1004, 59092, 14836):
+    case HB_CODEPOINT_ENCODE3 (1004, 59092, 14836):
       return true;
-#undef ENCODE
   }
   return false;
 }
@@ -219,6 +264,15 @@ _hb_ot_layout_set_glyph_props (hb_font_t *font,
 
 /* Public API */
 
+/**
+ * hb_ot_layout_has_glyph_classes:
+ * @face: #hb_face_t to work upon
+ *
+ * Tests whether a face has any glyph classes defined in its GDEF table.
+ *
+ * Return value: true if data found, false otherwise
+ *
+ **/
 hb_bool_t
 hb_ot_layout_has_glyph_classes (hb_face_t *face)
 {
@@ -227,6 +281,13 @@ hb_ot_layout_has_glyph_classes (hb_face_t *face)
 
 /**
  * hb_ot_layout_get_glyph_class:
+ * @face: The #hb_face_t to work on
+ * @glyph: The #hb_codepoint_t code point to query
+ *
+ * Fetches the GDEF class of the requested glyph in the specified face.
+ *
+ * Return value: The #hb_ot_layout_glyph_class_t glyph class of the given code
+ * point in the GDEF table of the face.
  *
  * Since: 0.9.7
  **/
@@ -239,6 +300,13 @@ hb_ot_layout_get_glyph_class (hb_face_t      *face,
 
 /**
  * hb_ot_layout_get_glyphs_in_class:
+ * @face: The #hb_face_t to work on
+ * @klass: The #hb_ot_layout_glyph_class_t GDEF class to retrieve
+ * @glyphs: (out): The #hb_set_t set of all glyphs belonging to the requested
+ *          class.
+ *
+ * Retrieves the set of all glyphs from the face that belong to the requested
+ * glyph class in the face's GDEF table.
  *
  * Since: 0.9.7
  **/
@@ -250,6 +318,23 @@ hb_ot_layout_get_glyphs_in_class (hb_face_t                  *face,
   return face->table.GDEF->table->get_glyphs_in_class (klass, glyphs);
 }
 
+
+#ifndef HB_NO_LAYOUT_UNUSED
+/**
+ * hb_ot_layout_get_attach_points:
+ * @face: The #hb_face_t to work on
+ * @glyph: The #hb_codepoint_t code point to query
+ * @start_offset: offset of the first attachment point to retrieve
+ * @point_count: (inout) (allow-none): Input = the maximum number of attachment points to return;
+ *               Output = the actual number of attachment points returned (may be zero)
+ * @point_array: (out) (array length=point_count): The array of attachment points found for the query
+ *
+ * Fetches a list of all attachment points for the specified glyph in the GDEF
+ * table of the face. The list returned will begin at the offset provided.
+ *
+ * Useful if the client program wishes to cache the list.
+ *
+ **/
 unsigned int
 hb_ot_layout_get_attach_points (hb_face_t      *face,
                                hb_codepoint_t  glyph,
@@ -262,7 +347,20 @@ hb_ot_layout_get_attach_points (hb_face_t      *face,
                                                     point_count,
                                                     point_array);
 }
-
+/**
+ * hb_ot_layout_get_ligature_carets:
+ * @font: The #hb_font_t to work on
+ * @direction: The #hb_direction_t text direction to use
+ * @glyph: The #hb_codepoint_t code point to query
+ * @start_offset: offset of the first caret position to retrieve
+ * @caret_count: (inout) (allow-none): Input = the maximum number of caret positions to return;
+ *               Output = the actual number of caret positions returned (may be zero)
+ * @caret_array: (out) (array length=caret_count): The array of caret positions found for the query
+ *
+ * Fetches a list of the caret positions defined for a ligature glyph in the GDEF
+ * table of the font. The list returned will begin at the offset provided.
+ *
+ **/
 unsigned int
 hb_ot_layout_get_ligature_carets (hb_font_t      *font,
                                  hb_direction_t  direction,
@@ -278,9 +376,16 @@ hb_ot_layout_get_ligature_carets (hb_font_t      *font,
     if (caret_count) *caret_count = result_caret_count;
   }
   else
+  {
+#ifndef HB_NO_AAT
     result = font->face->table.lcar->get_lig_carets (font, direction, glyph, start_offset, caret_count, caret_array);
+#else
+    if (caret_count) *caret_count = 0;
+#endif
+  }
   return result;
 }
+#endif
 
 
 /*
@@ -291,6 +396,11 @@ bool
 OT::GSUB::is_blacklisted (hb_blob_t *blob HB_UNUSED,
                          hb_face_t *face) const
 {
+#ifdef HB_NO_OT_LAYOUT_BLACKLIST
+  return false;
+#endif
+
+#ifndef HB_NO_AAT_SHAPE
   /* Mac OS X prefers morx over GSUB.  It also ships with various Indic fonts,
    * all by 'MUTF' foundry (Tamil MN, Tamil Sangam MN, etc.), that have broken
    * GSUB/GPOS tables.  Some have GSUB with zero scripts, those are ignored by
@@ -308,6 +418,7 @@ OT::GSUB::is_blacklisted (hb_blob_t *blob HB_UNUSED,
   if (unlikely (face->table.OS2->achVendID == HB_TAG ('M','U','T','F') &&
                face->table.morx->has_data ()))
     return true;
+#endif
 
   return false;
 }
@@ -316,6 +427,9 @@ bool
 OT::GPOS::is_blacklisted (hb_blob_t *blob HB_UNUSED,
                          hb_face_t *face HB_UNUSED) const
 {
+#ifdef HB_NO_OT_LAYOUT_BLACKLIST
+  return false;
+#endif
   return false;
 }
 
@@ -331,6 +445,19 @@ get_gsubgpos_table (hb_face_t *face,
 }
 
 
+/**
+ * hb_ot_layout_table_get_script_tags:
+ * @face: #hb_face_t to work upon
+ * @table_tag: HB_OT_TAG_GSUB or HB_OT_TAG_GPOS
+ * @start_offset: offset of the first script tag to retrieve
+ * @script_count: (inout) (allow-none): Input = the maximum number of script tags to return;
+ *                Output = the actual number of script tags returned (may be zero)
+ * @script_tags: (out) (array length=script_count): The array of #hb_tag_t script tags found for the query
+ *
+ * Fetches a list of all scripts enumerated in the specified face's GSUB table
+ * or GPOS table. The list returned will begin at the offset provided.
+ *
+ **/
 unsigned int
 hb_ot_layout_table_get_script_tags (hb_face_t    *face,
                                    hb_tag_t      table_tag,
@@ -345,11 +472,24 @@ hb_ot_layout_table_get_script_tags (hb_face_t    *face,
 
 #define HB_OT_TAG_LATIN_SCRIPT         HB_TAG ('l', 'a', 't', 'n')
 
+/**
+ * hb_ot_layout_table_find_script:
+ * @face: #hb_face_t to work upon
+ * @table_tag: HB_OT_TAG_GSUB or HB_OT_TAG_GPOS
+ * @script_tag: #hb_tag_t of the script tag requested
+ * @script_index: (out): The index of the requested script tag
+ *
+ * Fetches the index if a given script tag in the specified face's GSUB table
+ * or GPOS table.
+ *
+ * Return value: true if the script is found, false otherwise
+ *
+ **/
 hb_bool_t
 hb_ot_layout_table_find_script (hb_face_t    *face,
                                hb_tag_t      table_tag,
                                hb_tag_t      script_tag,
-                               unsigned int *script_index)
+                               unsigned int *script_index /* OUT */)
 {
   static_assert ((OT::Index::NOT_FOUND_INDEX == HB_OT_LAYOUT_NO_SCRIPT_INDEX), "");
   const OT::GSUBGPOS &g = get_gsubgpos_table (face, table_tag);
@@ -375,20 +515,38 @@ hb_ot_layout_table_find_script (hb_face_t    *face,
   return false;
 }
 
+#ifndef HB_DISABLE_DEPRECATED
+/**
+ * hb_ot_layout_table_choose_script:
+ * @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
+ *
+ * Deprecated since 2.0.0
+ **/
 hb_bool_t
 hb_ot_layout_table_choose_script (hb_face_t      *face,
                                  hb_tag_t        table_tag,
                                  const hb_tag_t *script_tags,
-                                 unsigned int   *script_index,
-                                 hb_tag_t       *chosen_script)
+                                 unsigned int   *script_index  /* OUT */,
+                                 hb_tag_t       *chosen_script /* OUT */)
 {
   const hb_tag_t *t;
   for (t = script_tags; *t; t++);
   return hb_ot_layout_table_select_script (face, table_tag, t - script_tags, script_tags, script_index, chosen_script);
 }
+#endif
 
 /**
  * hb_ot_layout_table_select_script:
+ * @face: #hb_face_t to work upon
+ * @table_tag: HB_OT_TAG_GSUB or HB_OT_TAG_GPOS
+ * @script_count: Number of script tags in the array
+ * @script_tags: Array of #hb_tag_t script tags
+ * @script_index: (out): The index of the requested script
+ * @chosen_script: (out): #hb_tag_t of the requested script
  *
  * Since: 2.0.0
  **/
@@ -409,7 +567,7 @@ hb_ot_layout_table_select_script (hb_face_t      *face,
     if (g.find_script_index (script_tags[i], script_index))
     {
       if (chosen_script)
-        *chosen_script = script_tags[i];
+       *chosen_script = script_tags[i];
       return true;
     }
   }
@@ -442,6 +600,19 @@ hb_ot_layout_table_select_script (hb_face_t      *face,
   return false;
 }
 
+
+/**
+ * hb_ot_layout_table_get_feature_tags:
+ * @face: #hb_face_t to work upon
+ * @table_tag: HB_OT_TAG_GSUB or HB_OT_TAG_GPOS
+ * @start_offset: offset of the first feature tag to retrieve
+ * @feature_count: (inout) (allow-none): Input = the maximum number of feature tags to return;
+ *                 Output = the actual number of feature tags returned (may be zero)
+ * @feature_tags: (out) (array length=feature_count): Array of feature tags found in the table
+ *
+ * Fetches a list of all feature tags in the given face's GSUB or GPOS table.
+ *
+ **/
 unsigned int
 hb_ot_layout_table_get_feature_tags (hb_face_t    *face,
                                     hb_tag_t      table_tag,
@@ -454,11 +625,24 @@ hb_ot_layout_table_get_feature_tags (hb_face_t    *face,
   return g.get_feature_tags (start_offset, feature_count, feature_tags);
 }
 
+
+/**
+ * hb_ot_layout_table_find_feature:
+ * @face: #hb_face_t to work upon
+ * @table_tag: HB_OT_TAG_GSUB or HB_OT_TAG_GPOS
+ * @feature_tag: The #hb_tag_t og the requested feature tag
+ * @feature_index: (out): The index of the requested feature
+ *
+ * Fetches the index for a given feature tag in the specified face's GSUB table
+ * or GPOS table.
+ *
+ * Return value: true if the feature is found, false otherwise
+ **/
 bool
 hb_ot_layout_table_find_feature (hb_face_t    *face,
                                 hb_tag_t      table_tag,
                                 hb_tag_t      feature_tag,
-                                unsigned int *feature_index)
+                                unsigned int *feature_index /* OUT */)
 {
   static_assert ((OT::Index::NOT_FOUND_INDEX == HB_OT_LAYOUT_NO_FEATURE_INDEX), "");
   const OT::GSUBGPOS &g = get_gsubgpos_table (face, table_tag);
@@ -477,6 +661,20 @@ hb_ot_layout_table_find_feature (hb_face_t    *face,
 }
 
 
+/**
+ * hb_ot_layout_script_get_language_tags:
+ * @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
+ * @start_offset: offset of the first language tag to retrieve
+ * @language_count: (inout) (allow-none): Input = the maximum number of language tags to return;
+ *                  Output = the actual number of language tags returned (may be zero)
+ * @language_tags: (out) (array length=language_count): Array of language tags found in the table
+ *
+ * Fetches a list of language tags in the given face's GSUB or GPOS table, underneath
+ * the specified script index. The list returned will begin at the offset provided.
+ *
+ **/
 unsigned int
 hb_ot_layout_script_get_language_tags (hb_face_t    *face,
                                       hb_tag_t      table_tag,
@@ -490,6 +688,24 @@ hb_ot_layout_script_get_language_tags (hb_face_t    *face,
   return s.get_lang_sys_tags (start_offset, language_count, language_tags);
 }
 
+
+#ifndef HB_DISABLE_DEPRECATED
+/**
+ * hb_ot_layout_script_find_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_tag: The #hb_tag_t of the requested language
+ * @language_index: The index of the requested language
+ *
+ * Fetches the index of a given language tag in the specified face's GSUB table
+ * or GPOS table, underneath the specified script tag.
+ *
+ * Return value: true if the language tag is found, false otherwise
+ *
+ * Since: ??
+ * Deprecated: ??
+ **/
 hb_bool_t
 hb_ot_layout_script_find_language (hb_face_t    *face,
                                   hb_tag_t      table_tag,
@@ -504,9 +720,22 @@ hb_ot_layout_script_find_language (hb_face_t    *face,
                                              &language_tag,
                                              language_index);
 }
+#endif
+
 
 /**
  * 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 a given language tag in the specified face's GSUB table
+ * or GPOS table, underneath the specified script index.
+ *
+ * Return value: true if the language tag is found, false otherwise
  *
  * Since: 2.0.0
  **/
@@ -536,6 +765,21 @@ hb_ot_layout_script_select_language (hb_face_t      *face,
   return false;
 }
 
+
+/**
+ * hb_ot_layout_language_get_required_feature_index:
+ * @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_index: The index of the requested language tag
+ * @feature_index: (out): The index of the requested feature
+ *
+ * Fetches the index of a requested feature in the given face's GSUB or GPOS table,
+ * underneath the specified script and language.
+ *
+ * Return value: true if the feature is found, false otherwise
+ *
+ **/
 hb_bool_t
 hb_ot_layout_language_get_required_feature_index (hb_face_t    *face,
                                                  hb_tag_t      table_tag,
@@ -551,8 +795,20 @@ hb_ot_layout_language_get_required_feature_index (hb_face_t    *face,
                                                     nullptr);
 }
 
+
 /**
  * hb_ot_layout_language_get_required_feature:
+ * @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_index: The index of the requested language tag
+ * @feature_index: The index of the requested feature
+ * @feature_tag: (out): The #hb_tag_t of the requested feature
+ *
+ * Fetches the tag of a requested feature index in the given face's GSUB or GPOS table,
+ * underneath the specified script and language.
+ *
+ * Return value: true if the feature is found, false otherwise
  *
  * Since: 0.9.30
  **/
@@ -574,6 +830,22 @@ hb_ot_layout_language_get_required_feature (hb_face_t    *face,
   return l.has_required_feature ();
 }
 
+
+/**
+ * hb_ot_layout_language_get_feature_indexes:
+ * @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_index: The index of the requested language tag
+ * @start_offset: offset of the first feature tag to retrieve
+ * @feature_count: (inout) (allow-none): Input = the maximum number of feature tags to return;
+ *                 Output: the actual number of feature tags returned (may be zero)
+ * @feature_indexes: (out) (array length=feature_count): The array of feature indexes found for the query
+ *
+ * Fetches a list of all features in the specified face's GSUB table
+ * or GPOS table, underneath the specified script and language. The list
+ * returned will begin at the offset provided.
+ **/
 unsigned int
 hb_ot_layout_language_get_feature_indexes (hb_face_t    *face,
                                           hb_tag_t      table_tag,
@@ -589,6 +861,23 @@ hb_ot_layout_language_get_feature_indexes (hb_face_t    *face,
   return l.get_feature_indexes (start_offset, feature_count, feature_indexes);
 }
 
+
+/**
+ * hb_ot_layout_language_get_feature_tags:
+ * @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_index: The index of the requested language tag
+ * @start_offset: offset of the first feature tag to retrieve
+ * @feature_count: (inout) (allow-none): Input = the maximum number of feature tags to return;
+ *                 Output = the actual number of feature tags returned (may be zero)
+ * @feature_tags: (out) (array length=feature_count): The array of #hb_tag_t feature tags found for the query
+ *
+ * Fetches a list of all features in the specified face's GSUB table
+ * or GPOS table, underneath the specified script and language. The list
+ * returned will begin at the offset provided.
+ *
+ **/
 unsigned int
 hb_ot_layout_language_get_feature_tags (hb_face_t    *face,
                                        hb_tag_t      table_tag,
@@ -614,13 +903,28 @@ hb_ot_layout_language_get_feature_tags (hb_face_t    *face,
 }
 
 
+/**
+ * hb_ot_layout_language_find_feature:
+ * @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_index: The index of the requested language tag
+ * @feature_tag: #hb_tag_t of the feature tag requested
+ * @feature_index: (out): The index of the requested feature
+ *
+ * Fetches the index of a given feature tag in the specified face's GSUB table
+ * or GPOS table, underneath the specified script and language.
+ *
+ * Return value: true if the feature is found, false otherwise
+ *
+ **/
 hb_bool_t
 hb_ot_layout_language_find_feature (hb_face_t    *face,
                                    hb_tag_t      table_tag,
                                    unsigned int  script_index,
                                    unsigned int  language_index,
                                    hb_tag_t      feature_tag,
-                                   unsigned int *feature_index)
+                                   unsigned int *feature_index /* OUT */)
 {
   static_assert ((OT::Index::NOT_FOUND_INDEX == HB_OT_LAYOUT_NO_FEATURE_INDEX), "");
   const OT::GSUBGPOS &g = get_gsubgpos_table (face, table_tag);
@@ -640,8 +944,20 @@ hb_ot_layout_language_find_feature (hb_face_t    *face,
   return false;
 }
 
+
 /**
  * hb_ot_layout_feature_get_lookups:
+ * @face: #hb_face_t to work upon
+ * @table_tag: HB_OT_TAG_GSUB or HB_OT_TAG_GPOS
+ * @feature_index: The index of the requested feature
+ * @start_offset: offset of the first lookup to retrieve
+ * @lookup_count: (inout) (allow-none): Input = the maximum number of lookups to return;
+ *                Output = the actual number of lookups returned (may be zero)
+ * @lookup_indexes: (out) (array length=lookup_count): The array of lookup indexes found for the query
+ *
+ * Fetches a list of all lookups enumerated for the specified feature, in
+ * the specified face's GSUB table or GPOS table. The list returned will
+ * begin at the offset provided.
  *
  * Since: 0.9.7
  **/
@@ -662,8 +978,14 @@ hb_ot_layout_feature_get_lookups (hb_face_t    *face,
                                                           lookup_indexes);
 }
 
+
 /**
  * hb_ot_layout_table_get_lookup_count:
+ * @face: #hb_face_t to work upon
+ * @table_tag: HB_OT_TAG_GSUB or HB_OT_TAG_GPOS
+ *
+ * Fetches the total number of lookups enumerated in the specified
+ * face's GSUB table or GPOS table.
  *
  * Since: 0.9.22
  **/
@@ -677,9 +999,9 @@ hb_ot_layout_table_get_lookup_count (hb_face_t    *face,
 
 struct hb_collect_features_context_t
 {
-  hb_collect_features_context_t (hb_face_t       *face,
-                                hb_tag_t         table_tag,
-                                hb_set_t        *feature_indexes_)
+  hb_collect_features_context_t (hb_face_t *face,
+                                hb_tag_t   table_tag,
+                                hb_set_t  *feature_indexes_)
     : g (get_gsubgpos_table (face, table_tag)),
       feature_indexes (feature_indexes_),
       script_count(0),langsys_count(0) {}
@@ -805,18 +1127,31 @@ script_collect_features (hb_collect_features_context_t *c,
   }
 }
 
+
 /**
  * hb_ot_layout_collect_features:
+ * @face: #hb_face_t to work upon
+ * @table_tag: HB_OT_TAG_GSUB or HB_OT_TAG_GPOS
+ * @scripts: The array of scripts to collect features for
+ * @languages: The array of languages to collect features for
+ * @features: The array of features to collect
+ * @feature_indexes: (out): The array of feature indexes found for the query
+ *
+ * Fetches a list of all feature indexes in the specified face's GSUB table
+ * or GPOS table, underneath the specified scripts, languages, and features.
+ * If no list of scripts is provided, all scripts will be queried. If no list
+ * of languages is provided, all languages will be queried. If no list of
+ * features is provided, all features will be queried.
  *
  * Since: 1.8.5
  **/
 void
 hb_ot_layout_collect_features (hb_face_t      *face,
-                               hb_tag_t        table_tag,
-                               const hb_tag_t *scripts,
-                               const hb_tag_t *languages,
-                               const hb_tag_t *features,
-                               hb_set_t       *feature_indexes /* OUT */)
+                              hb_tag_t        table_tag,
+                              const hb_tag_t *scripts,
+                              const hb_tag_t *languages,
+                              const hb_tag_t *features,
+                              hb_set_t       *feature_indexes /* OUT */)
 {
   hb_collect_features_context_t c (face, table_tag, feature_indexes);
   if (!scripts)
@@ -843,8 +1178,21 @@ hb_ot_layout_collect_features (hb_face_t      *face,
   }
 }
 
+
 /**
  * hb_ot_layout_collect_lookups:
+ * @face: #hb_face_t to work upon
+ * @table_tag: HB_OT_TAG_GSUB or HB_OT_TAG_GPOS
+ * @scripts: The array of scripts to collect lookups for
+ * @languages: The array of languages to collect lookups for
+ * @features: The array of features to collect lookups for
+ * @lookup_indexes: (out): The array of lookup indexes found for the query
+ *
+ * Fetches a list of all feature-lookup indexes in the specified face's GSUB
+ * table or GPOS table, underneath the specified scripts, languages, and
+ * features. If no list of scripts is provided, all scripts will be queried.
+ * If no list of languages is provided, all languages will be queried. If no
+ * list of features is provided, all features will be queried.
  *
  * Since: 0.9.8
  **/
@@ -866,8 +1214,20 @@ hb_ot_layout_collect_lookups (hb_face_t      *face,
     g.get_feature (feature_index).add_lookup_indexes_to (lookup_indexes);
 }
 
+
+#ifndef HB_NO_LAYOUT_COLLECT_GLYPHS
 /**
  * hb_ot_layout_lookup_collect_glyphs:
+ * @face: #hb_face_t to work upon
+ * @table_tag: HB_OT_TAG_GSUB or HB_OT_TAG_GPOS
+ * @lookup_index: The index of the feature lookup to query
+ * @glyphs_before: (out): Array of glyphs preceding the substitution range
+ * @glyphs_input: (out): Array of input glyphs that would be substituted by the lookup
+ * @glyphs_after: (out): Array of glyphs following the substition range
+ * @glyphs_output: (out): Array of glyphs that would be the substitued output of the lookup
+ *
+ * Fetches a list of all glyphs affected by the specified lookup in the
+ * specified face's GSUB table or GPOS table.
  *
  * Since: 0.9.7
  **/
@@ -902,10 +1262,24 @@ hb_ot_layout_lookup_collect_glyphs (hb_face_t    *face,
     }
   }
 }
+#endif
 
 
 /* Variations support */
 
+
+/**
+ * hb_ot_layout_table_find_feature_variations:
+ * @face: #hb_face_t to work upon
+ * @table_tag: HB_OT_TAG_GSUB or HB_OT_TAG_GPOS
+ * @coords: The variation coordinates to query
+ * @num_coords: The number of variation coorinates
+ * @variations_index: (out): The array of feature variations found for the query
+ *
+ * Fetches a list of feature variations in the specified face's GSUB table
+ * or GPOS table, at the specified variation coordinates.
+ *
+ **/
 hb_bool_t
 hb_ot_layout_table_find_feature_variations (hb_face_t    *face,
                                            hb_tag_t      table_tag,
@@ -918,6 +1292,23 @@ hb_ot_layout_table_find_feature_variations (hb_face_t    *face,
   return g.find_variations_index (coords, num_coords, variations_index);
 }
 
+
+/**
+ * hb_ot_layout_feature_with_variations_get_lookups:
+ * @face: #hb_face_t to work upon
+ * @table_tag: HB_OT_TAG_GSUB or HB_OT_TAG_GPOS
+ * @feature_index: The index of the feature to query
+ * @variations_index: The index of the feature variation to query
+ * @start_offset: offset of the first lookup to retrieve
+ * @lookup_count: (inout) (allow-none): Input = the maximum number of lookups to return;
+ *                Output = the actual number of lookups returned (may be zero)
+ * @lookup_indexes: (out) (array length=lookup_count): The array of lookups found for the query
+ *
+ * Fetches a list of all lookups enumerated for the specified feature, in
+ * the specified face's GSUB table or GPOS table, enabled at the specified
+ * variations index. The list returned will begin at the offset provided.
+ *
+ **/
 unsigned int
 hb_ot_layout_feature_with_variations_get_lookups (hb_face_t    *face,
                                                  hb_tag_t      table_tag,
@@ -940,14 +1331,35 @@ hb_ot_layout_feature_with_variations_get_lookups (hb_face_t    *face,
  * OT::GSUB
  */
 
+
+/**
+ * hb_ot_layout_has_substitution:
+ * @face: #hb_face_t to work upon
+ *
+ * Tests whether the specified face includes any GSUB substitutions.
+ *
+ * Return value: true if data found, false otherwise
+ *
+ **/
 hb_bool_t
 hb_ot_layout_has_substitution (hb_face_t *face)
 {
   return face->table.GSUB->table->has_data ();
 }
 
+
 /**
  * hb_ot_layout_lookup_would_substitute:
+ * @face: #hb_face_t to work upon
+ * @lookup_index: The index of the lookup to query
+ * @glyphs: The sequence of glyphs to query for substitution
+ * @glyphs_length: The length of the glyph sequence
+ * @zero_context: #hb_bool_t indicating whether substitutions should be context-free
+ *
+ * Tests whether a specified lookup in the specified face would
+ * trigger a substitution on the given glyph sequence.
+ *
+ * Return value: true if a substitution would be triggered, false otherwise
  *
  * Since: 0.9.7
  **/
@@ -966,6 +1378,16 @@ hb_ot_layout_lookup_would_substitute (hb_face_t            *face,
   return l.would_apply (&c, &face->table.GSUB->accels[lookup_index]);
 }
 
+
+/**
+ * hb_ot_layout_substitute_start:
+ * @font: #hb_font_t to use
+ * @buffer: #hb_buffer_t buffer to work upon
+ *
+ * Called before substitution lookups are performed, to ensure that glyph
+ * class and other properties are set on the glyphs in the buffer.
+ *
+ **/
 void
 hb_ot_layout_substitute_start (hb_font_t    *font,
                               hb_buffer_t  *buffer)
@@ -1025,13 +1447,19 @@ hb_ot_layout_delete_glyphs_inplace (hb_buffer_t *buffer,
 
 /**
  * hb_ot_layout_lookup_substitute_closure:
+ * @face: #hb_face_t to work upon
+ * @lookup_index: index of the feature lookup to query
+ * @glyphs: (out): Array of glyphs comprising the transitive closure of the lookup
+ *
+ * Compute the transitive closure of glyphs needed for a
+ * specified lookup.
  *
  * Since: 0.9.7
  **/
 void
 hb_ot_layout_lookup_substitute_closure (hb_face_t    *face,
                                        unsigned int  lookup_index,
-                                       hb_set_t     *glyphs)
+                                       hb_set_t     *glyphs /* OUT */)
 {
   hb_map_t done_lookups;
   OT::hb_closure_context_t c (face, glyphs, &done_lookups);
@@ -1043,6 +1471,9 @@ hb_ot_layout_lookup_substitute_closure (hb_face_t    *face,
 
 /**
  * hb_ot_layout_lookups_substitute_closure:
+ * @face: #hb_face_t to work upon
+ * @lookups: The set of lookups to query
+ * @glyphs: (out): Array of glyphs comprising the transitive closure of the lookups
  *
  * Compute the transitive closure of glyphs needed for all of the
  * provided lookups.
@@ -1051,8 +1482,8 @@ hb_ot_layout_lookup_substitute_closure (hb_face_t    *face,
  **/
 void
 hb_ot_layout_lookups_substitute_closure (hb_face_t      *face,
-                                         const hb_set_t *lookups,
-                                         hb_set_t       *glyphs)
+                                        const hb_set_t *lookups,
+                                        hb_set_t       *glyphs /* OUT */)
 {
   hb_map_t done_lookups;
   OT::hb_closure_context_t c (face, glyphs, &done_lookups);
@@ -1066,12 +1497,12 @@ hb_ot_layout_lookups_substitute_closure (hb_face_t      *face,
     if (lookups != nullptr)
     {
       for (hb_codepoint_t lookup_index = HB_SET_VALUE_INVALID; hb_set_next (lookups, &lookup_index);)
-        gsub.get_lookup (lookup_index).closure (&c, lookup_index);
+       gsub.get_lookup (lookup_index).closure (&c, lookup_index);
     }
     else
     {
       for (unsigned int i = 0; i < gsub.get_lookup_count (); i++)
-        gsub.get_lookup (i).closure (&c, i);
+       gsub.get_lookup (i).closure (&c, i);
     }
   } while (iteration_count++ <= HB_CLOSURE_MAX_STAGES &&
           glyphs_length != glyphs->get_population ());
@@ -1081,32 +1512,85 @@ hb_ot_layout_lookups_substitute_closure (hb_face_t      *face,
  * OT::GPOS
  */
 
+
+/**
+ * hb_ot_layout_has_positioning:
+ * @face: #hb_face_t to work upon
+ *
+ * Return value: true if the face has GPOS data, false otherwise
+ *
+ **/
 hb_bool_t
 hb_ot_layout_has_positioning (hb_face_t *face)
 {
   return face->table.GPOS->table->has_data ();
 }
 
+/**
+ * hb_ot_layout_position_start:
+ * @font: #hb_font_t to use
+ * @buffer: #hb_buffer_t buffer to work upon
+ *
+ * Called before positioning lookups are performed, to ensure that glyph
+ * attachment types and glyph-attachment chains are set for the glyphs in the buffer.
+ *
+ **/
 void
 hb_ot_layout_position_start (hb_font_t *font, hb_buffer_t *buffer)
 {
   OT::GPOS::position_start (font, buffer);
 }
 
+
+/**
+ * hb_ot_layout_position_finish_advances:
+ * @font: #hb_font_t to use
+ * @buffer: #hb_buffer_t buffer to work upon
+ *
+ * Called after positioning lookups are performed, to finish glyph advances.
+ *
+ **/
 void
 hb_ot_layout_position_finish_advances (hb_font_t *font, hb_buffer_t *buffer)
 {
   OT::GPOS::position_finish_advances (font, buffer);
 }
 
+/**
+ * hb_ot_layout_position_finish_offsets:
+ * @font: #hb_font_t to use
+ * @buffer: #hb_buffer_t buffer to work upon
+ *
+ * Called after positioning lookups are performed, to finish glyph offsets.
+ *
+ **/
 void
 hb_ot_layout_position_finish_offsets (hb_font_t *font, hb_buffer_t *buffer)
 {
   OT::GPOS::position_finish_offsets (font, buffer);
 }
 
+
+#ifndef HB_NO_LAYOUT_FEATURE_PARAMS
 /**
  * hb_ot_layout_get_size_params:
+ * @face: #hb_face_t to work upon
+ * @design_size: (out): The design size of the face
+ * @subfamily_id: (out): The identifier of the face within the font subfamily
+ * @subfamily_name_id: (out): The ‘name’ table name ID of the face within the font subfamily
+ * @range_start: (out): The minimum size of the recommended size range for the face
+ * @range_end: (out): The maximum size of the recommended size range for the face
+ *
+ * Fetches optical-size feature data (i.e., the `size` feature from GPOS). Note that
+ * the subfamily_id and the subfamily name string (accessible via the subfamily_name_id)
+ * as used here are defined as pertaining only to fonts within a font family that differ
+ * specifically in their respective size ranges; other ways to differentiate fonts within
+ * a subfamily are not covered by the `size` feature.
+ *
+ * For more information on this distinction, see the `size` documentation at
+ * https://docs.microsoft.com/en-us/typography/opentype/spec/features_pt#tag-39size39
+ *
+ * Return value: true if data found, false otherwise
  *
  * Since: 0.9.10
  **/
@@ -1150,7 +1634,6 @@ hb_ot_layout_get_size_params (hb_face_t       *face,
 
   return false;
 }
-
 /**
  * hb_ot_layout_feature_get_name_ids:
  * @face: #hb_face_t to work upon
@@ -1225,24 +1708,26 @@ hb_ot_layout_feature_get_name_ids (hb_face_t       *face,
   if (first_param_id) *first_param_id = HB_OT_NAME_ID_INVALID;
   return false;
 }
-
 /**
  * hb_ot_layout_feature_get_characters:
  * @face: #hb_face_t to work upon
  * @table_tag: table tag to query, "GSUB" or "GPOS".
  * @feature_index: index of feature to query.
- * @start_offset: In case the resulting char_count was equal to its input value, there
- *                is a chance there were more characters on the tag so this API can be
- *                called with an offset till resulting char_count gets to a number
- *                lower than input buffer (or consider using just a bigger buffer for
- *                one shot copying).
- * @char_count: (inout) (allow-none): The count of characters for which this feature
- *              provides glyph variants. (May be zero.)
- * @characters: (out caller-allocates) (array length=char_count): A buffer pointer. The Unicode codepoints
- *              of the characters for which this feature provides glyph variants.
- *
- * Fetches characters listed by designer under feature parameters for "Character
- * Variant" ("cvXX") features.
+ * @start_offset: offset of the first character to retrieve
+ * @char_count: (inout) (allow-none): Input = the maximum number of characters to return;
+ *              Output = the actual number of characters returned (may be zero)
+ * @characters: (out caller-allocates) (array length=char_count): A buffer pointer.
+ *              The Unicode codepoints of the characters for which this feature provides
+ *               glyph variants.
+ *
+ * Fetches a list of the characters defined as having a variant under the specified
+ * "Character Variant" ("cvXX") feature tag.
+ *
+ * <note>Note: If the char_count output value is equal to its input value, then there
+ *       is a chance there were more characters defined under the feature tag than were
+ *       returned. This function can be called with incrementally larger start_offset
+ *       until the char_count output value is lower than its input value, or the size
+ *       of the characters array can be increased.</note>
  *
  * Return value: Number of total sample characters in the cvXX feature.
  *
@@ -1269,13 +1754,14 @@ hb_ot_layout_feature_get_characters (hb_face_t      *face,
   unsigned int len = 0;
   if (char_count && characters && start_offset < cv_params.characters.len)
   {
-    len = MIN (cv_params.characters.len - start_offset, *char_count);
+    len = hb_min (cv_params.characters.len - start_offset, *char_count);
     for (unsigned int i = 0; i < len; ++i)
       characters[i] = cv_params.characters[start_offset + i];
   }
   if (char_count) *char_count = len;
   return cv_params.characters.len;
 }
+#endif
 
 
 /*
@@ -1459,60 +1945,36 @@ hb_ot_layout_substitute_lookup (OT::hb_ot_apply_context_t *c,
   apply_string<GSUBProxy> (c, lookup, accel);
 }
 
-#if 0
-static const OT::BASE& _get_base (hb_face_t *face)
-{
-  return *face->table.BASE;
-}
-
+#ifndef HB_NO_BASE
+/**
+ * hb_ot_layout_get_baseline:
+ * @font: a font
+ * @baseline_tag: a baseline tag
+ * @direction: text direction.
+ * @script_tag:  script tag.
+ * @language_tag: language tag.
+ * @coord: (out): baseline value if found.
+ *
+ * Fetches a baseline value from the face.
+ *
+ * Return value: if found baseline value in the the font.
+ *
+ * Since: 2.6.0
+ **/
 hb_bool_t
-hb_ot_layout_get_baseline (hb_font_t               *font,
-                          hb_ot_layout_baseline_t  baseline,
-                          hb_direction_t           direction,
-                          hb_tag_t                 script_tag,
-                          hb_tag_t                 language_tag,
-                          hb_position_t           *coord        /* OUT.  May be NULL. */)
+hb_ot_layout_get_baseline (hb_font_t                   *font,
+                          hb_ot_layout_baseline_tag_t  baseline_tag,
+                          hb_direction_t               direction,
+                          hb_tag_t                     script_tag,
+                          hb_tag_t                     language_tag,
+                          hb_position_t               *coord        /* OUT.  May be NULL. */)
 {
-  const OT::BASE &base = _get_base (font->face);
-  bool result = base.get_baseline (font, baseline, direction, script_tag,
-                                  language_tag, coord);
-
-  /* TODO: Simulate https://docs.microsoft.com/en-us/typography/opentype/spec/baselinetags#ideographic-em-box */
-  if (!result && coord) *coord = 0;
+  bool result = font->face->table.BASE->get_baseline (font, baseline_tag, direction, script_tag, language_tag, coord);
 
-  if (coord) *coord = font->em_scale_dir (*coord, direction);
+  if (result && coord)
+    *coord = HB_DIRECTION_IS_HORIZONTAL (direction) ? font->em_scale_y (*coord) : font->em_scale_x (*coord);
 
   return result;
 }
-
-/* To be moved to public header */
-/*
- * BASE
- */
-
-/**
- * hb_ot_layout_baseline_t:
- *
- * https://docs.microsoft.com/en-us/typography/opentype/spec/baselinetags
- *
- * Since: DONTREPLACEME
- */
-typedef enum {
-  HB_OT_LAYOUT_BASELINE_HANG = HB_TAG('h','a','n','g'),
-  HB_OT_LAYOUT_BASELINE_ICFB = HB_TAG('i','c','f','b'),
-  HB_OT_LAYOUT_BASELINE_ICFT = HB_TAG('i','c','f','t'),
-  HB_OT_LAYOUT_BASELINE_IDEO = HB_TAG('i','d','e','o'),
-  HB_OT_LAYOUT_BASELINE_IDTB = HB_TAG('i','d','t','b'),
-  HB_OT_LAYOUT_BASELINE_MATH = HB_TAG('m','a','t','h'),
-  HB_OT_LAYOUT_BASELINE_ROMN = HB_TAG('r','o','m','n')
-} hb_ot_layout_baseline_t;
-
-HB_EXTERN hb_bool_t
-hb_ot_layout_get_baseline (hb_font_t               *font,
-                          hb_ot_layout_baseline_t  baseline,
-                          hb_direction_t           direction,
-                          hb_tag_t                 script_tag,
-                          hb_tag_t                 language_tag,
-                          hb_position_t           *coord        /* OUT.  May be NULL. */);
-
+#endif
 #endif
index e473954..7e8a897 100644 (file)
@@ -93,6 +93,17 @@ hb_ot_tags_to_script_and_language (hb_tag_t       script_tag,
 HB_EXTERN hb_bool_t
 hb_ot_layout_has_glyph_classes (hb_face_t *face);
 
+/**
+ * hb_ot_layout_glyph_class_t:
+ * @HB_OT_LAYOUT_GLYPH_CLASS_UNCLASSIFIED: Glyphs not matching the other classifications
+ * @HB_OT_LAYOUT_GLYPH_CLASS_BASE_GLYPH: Spacing, single characters, capable of accepting marks
+ * @HB_OT_LAYOUT_GLYPH_CLASS_LIGATURE: Glyphs that represent ligation of multiple characters
+ * @HB_OT_LAYOUT_GLYPH_CLASS_MARK: Non-spacing, combining glyphs that represent marks
+ * @HB_OT_LAYOUT_GLYPH_CLASS_COMPONENT: Spacing glyphs that represent part of a single character
+ *
+ * The GDEF classes defined for glyphs.
+ *
+ **/
 typedef enum {
   HB_OT_LAYOUT_GLYPH_CLASS_UNCLASSIFIED        = 0,
   HB_OT_LAYOUT_GLYPH_CLASS_BASE_GLYPH  = 1,
@@ -238,11 +249,11 @@ hb_ot_layout_table_get_lookup_count (hb_face_t    *face,
 
 HB_EXTERN void
 hb_ot_layout_collect_features (hb_face_t      *face,
-                               hb_tag_t        table_tag,
-                               const hb_tag_t *scripts,
-                               const hb_tag_t *languages,
-                               const hb_tag_t *features,
-                               hb_set_t       *feature_indexes /* OUT */);
+                              hb_tag_t        table_tag,
+                              const hb_tag_t *scripts,
+                              const hb_tag_t *languages,
+                              const hb_tag_t *features,
+                              hb_set_t       *feature_indexes /* OUT */);
 
 HB_EXTERN void
 hb_ot_layout_collect_lookups (hb_face_t      *face,
@@ -322,14 +333,14 @@ hb_ot_layout_lookup_would_substitute (hb_face_t            *face,
 
 HB_EXTERN void
 hb_ot_layout_lookup_substitute_closure (hb_face_t    *face,
-                                       unsigned int  lookup_index,
-                                       hb_set_t     *glyphs
+                                       unsigned int  lookup_index,
+                                       hb_set_t     *glyphs
                                        /*TODO , hb_bool_t  inclusive */);
 
 HB_EXTERN void
 hb_ot_layout_lookups_substitute_closure (hb_face_t      *face,
-                                         const hb_set_t *lookups,
-                                         hb_set_t       *glyphs);
+                                        const hb_set_t *lookups,
+                                        hb_set_t       *glyphs);
 
 
 #ifdef HB_NOT_IMPLEMENTED
@@ -391,6 +402,55 @@ hb_ot_layout_feature_get_characters (hb_face_t      *face,
                                     unsigned int   *char_count    /* IN/OUT.  May be NULL */,
                                     hb_codepoint_t *characters    /* OUT.     May be NULL */);
 
+/*
+ * BASE
+ */
+
+/**
+ * hb_ot_layout_baseline_tag_t:
+ * @HB_OT_LAYOUT_BASELINE_TAG_ROMAN: The baseline used by alphabetic scripts such as Latin, Cyrillic and Greek.
+ * In vertical writing mode, the alphabetic baseline for characters rotated 90 degrees clockwise.
+ * (This would not apply to alphabetic characters that remain upright in vertical writing mode, since these
+ * characters are not rotated.)
+ * @HB_OT_LAYOUT_BASELINE_TAG_HANGING: The hanging baseline. In horizontal direction, this is the horizontal
+ * line from which syllables seem, to hang in Tibetan and other similar scripts. In vertical writing mode,
+ * for Tibetan (or some other similar script) characters rotated 90 degrees clockwise.
+ * @HB_OT_LAYOUT_BASELINE_TAG_IDEO_FACE_BOTTOM_OR_LEFT: Ideographic character face bottom or left edge,
+ * if the direction is horizontal or vertical, respectively.
+ * @HB_OT_LAYOUT_BASELINE_TAG_IDEO_FACE_TOP_OR_RIGHT: Ideographic character face top or right edge,
+ * if the direction is horizontal or vertical, respectively.
+ * @HB_OT_LAYOUT_BASELINE_TAG_IDEO_EMBOX_BOTTOM_OR_LEFT: Ideographic em-box bottom or left edge,
+ * if the direction is horizontal or vertical, respectively.
+ * @HB_OT_LAYOUT_BASELINE_TAG_IDEO_EMBOX_TOP_OR_RIGHT: Ideographic em-box top or right edge baseline,
+ * if the direction is horizontal or vertical, respectively.
+ * @HB_OT_LAYOUT_BASELINE_TAG_MATH: The baseline about which mathematical characters are centered.
+ * In vertical writing mode when mathematical characters rotated 90 degrees clockwise, are centered.
+ *
+ * Baseline tags from https://docs.microsoft.com/en-us/typography/opentype/spec/baselinetags
+ *
+ * Since: 2.6.0
+ */
+typedef enum {
+  HB_OT_LAYOUT_BASELINE_TAG_ROMAN                      = HB_TAG ('r','o','m','n'),
+  HB_OT_LAYOUT_BASELINE_TAG_HANGING                    = HB_TAG ('h','a','n','g'),
+  HB_OT_LAYOUT_BASELINE_TAG_IDEO_FACE_BOTTOM_OR_LEFT   = HB_TAG ('i','c','f','b'),
+  HB_OT_LAYOUT_BASELINE_TAG_IDEO_FACE_TOP_OR_RIGHT     = HB_TAG ('i','c','f','t'),
+  HB_OT_LAYOUT_BASELINE_TAG_IDEO_EMBOX_BOTTOM_OR_LEFT  = HB_TAG ('i','d','e','o'),
+  HB_OT_LAYOUT_BASELINE_TAG_IDEO_EMBOX_TOP_OR_RIGHT    = HB_TAG ('i','d','t','p'),
+  HB_OT_LAYOUT_BASELINE_TAG_MATH                       = HB_TAG ('m','a','t','h'),
+
+  _HB_OT_LAYOUT_BASELINE_TAG_MAX_VALUE = HB_TAG_MAX_SIGNED /*< skip >*/
+} hb_ot_layout_baseline_tag_t;
+
+HB_EXTERN hb_bool_t
+hb_ot_layout_get_baseline (hb_font_t                   *font,
+                          hb_ot_layout_baseline_tag_t  baseline_tag,
+                          hb_direction_t               direction,
+                          hb_tag_t                     script_tag,
+                          hb_tag_t                     language_tag,
+                          hb_position_t               *coord        /* OUT.  May be NULL. */);
+
+
 HB_END_DECLS
 
 #endif /* HB_OT_LAYOUT_H */
index be7ef02..f3bb155 100644 (file)
@@ -168,6 +168,17 @@ _hb_next_syllable (hb_buffer_t *buffer, unsigned int start)
   return start;
 }
 
+static inline void
+_hb_clear_syllables (const hb_ot_shape_plan_t *plan HB_UNUSED,
+                    hb_font_t *font HB_UNUSED,
+                    hb_buffer_t *buffer)
+{
+  hb_glyph_info_t *info = buffer->info;
+  unsigned int count = buffer->len;
+  for (unsigned int i = 0; i < count; i++)
+    info[i].syllable() = 0;
+}
+
 
 /* unicode_props */
 
@@ -551,6 +562,17 @@ _hb_glyph_info_clear_substituted (hb_glyph_info_t *info)
   info->glyph_props() &= ~(HB_OT_LAYOUT_GLYPH_PROPS_SUBSTITUTED);
 }
 
+static inline void
+_hb_clear_substitution_flags (const hb_ot_shape_plan_t *plan HB_UNUSED,
+                             hb_font_t *font HB_UNUSED,
+                             hb_buffer_t *buffer)
+{
+  hb_glyph_info_t *info = buffer->info;
+  unsigned int count = buffer->len;
+  for (unsigned int i = 0; i < count; i++)
+    _hb_glyph_info_clear_substituted (&info[i]);
+}
+
 
 /* Allocation / deallocation. */
 
index ef0bcc7..e4bb4b6 100644 (file)
  * Google Author(s): Behdad Esfahbod
  */
 
+#include "hb.hh"
+
+#ifndef HB_NO_OT_SHAPE
+
 #include "hb-ot-map.hh"
 #include "hb-ot-shape.hh"
 #include "hb-ot-layout.hh"
@@ -34,7 +38,7 @@
 void hb_ot_map_t::collect_lookups (unsigned int table_index, hb_set_t *lookups_out) const
 {
   for (unsigned int i = 0; i < lookups[table_index].length; i++)
-    hb_set_add (lookups_out, lookups[table_index][i].index);
+    lookups_out->add (lookups[table_index][i].index);
 }
 
 
@@ -187,13 +191,14 @@ hb_ot_map_builder_t::compile (hb_ot_map_t                  &m,
          feature_infos[j].max_value = feature_infos[i].max_value;
          feature_infos[j].default_value = feature_infos[i].default_value;
        } else {
-         feature_infos[j].flags &= ~F_GLOBAL;
-         feature_infos[j].max_value = MAX (feature_infos[j].max_value, feature_infos[i].max_value);
+         if (feature_infos[j].flags & F_GLOBAL)
+           feature_infos[j].flags ^= F_GLOBAL;
+         feature_infos[j].max_value = hb_max (feature_infos[j].max_value, feature_infos[i].max_value);
          /* Inherit default_value from j */
        }
        feature_infos[j].flags |= (feature_infos[i].flags & F_HAS_FALLBACK);
-       feature_infos[j].stage[0] = MIN (feature_infos[j].stage[0], feature_infos[i].stage[0]);
-       feature_infos[j].stage[1] = MIN (feature_infos[j].stage[1], feature_infos[i].stage[1]);
+       feature_infos[j].stage[0] = hb_min (feature_infos[j].stage[0], feature_infos[i].stage[0]);
+       feature_infos[j].stage[1] = hb_min (feature_infos[j].stage[1], feature_infos[i].stage[1]);
       }
     feature_infos.shrink (j + 1);
   }
@@ -213,34 +218,34 @@ hb_ot_map_builder_t::compile (hb_ot_map_t                  &m,
       bits_needed = 0;
     else
       /* Limit bits per feature. */
-      bits_needed = MIN(HB_OT_MAP_MAX_BITS, hb_bit_storage (info->max_value));
+      bits_needed = hb_min (HB_OT_MAP_MAX_BITS, hb_bit_storage (info->max_value));
 
     if (!info->max_value || next_bit + bits_needed > 8 * sizeof (hb_mask_t))
       continue; /* Feature disabled, or not enough bits. */
 
 
-    hb_bool_t found = false;
+    bool found = false;
     unsigned int feature_index[2];
     for (unsigned int table_index = 0; table_index < 2; table_index++)
     {
       if (required_feature_tag[table_index] == info->tag)
        required_feature_stage[table_index] = info->stage[table_index];
 
-      found |= hb_ot_layout_language_find_feature (face,
-                                                  table_tags[table_index],
-                                                  script_index[table_index],
-                                                  language_index[table_index],
-                                                  info->tag,
-                                                  &feature_index[table_index]);
+      found |= (bool) hb_ot_layout_language_find_feature (face,
+                                                         table_tags[table_index],
+                                                         script_index[table_index],
+                                                         language_index[table_index],
+                                                         info->tag,
+                                                         &feature_index[table_index]);
     }
     if (!found && (info->flags & F_GLOBAL_SEARCH))
     {
       for (unsigned int table_index = 0; table_index < 2; table_index++)
       {
-       found |= hb_ot_layout_table_find_feature (face,
-                                                 table_tags[table_index],
-                                                 info->tag,
-                                                 &feature_index[table_index]);
+       found |= (bool) hb_ot_layout_table_find_feature (face,
+                                                        table_tags[table_index],
+                                                        info->tag,
+                                                        &feature_index[table_index]);
       }
     }
     if (!found && !(info->flags & F_HAS_FALLBACK))
@@ -293,7 +298,7 @@ hb_ot_map_builder_t::compile (hb_ot_map_t                  &m,
                     global_bit_mask);
 
       for (unsigned i = 0; i < m.features.length; i++)
-        if (m.features[i].stage[table_index] == stage)
+       if (m.features[i].stage[table_index] == stage)
          add_lookups (m, table_index,
                       m.features[i].index[table_index],
                       key.variations_index[table_index],
@@ -332,3 +337,6 @@ hb_ot_map_builder_t::compile (hb_ot_map_t                  &m,
     }
   }
 }
+
+
+#endif
index 28407c2..0a4827d 100644 (file)
@@ -68,7 +68,7 @@ struct hb_ot_map_t
     unsigned short random : 1;
     hb_mask_t mask;
 
-    static int cmp (const void *pa, const void *pb)
+    HB_INTERNAL static int cmp (const void *pa, const void *pb)
     {
       const lookup_map_t *a = (const lookup_map_t *) pa;
       const lookup_map_t *b = (const lookup_map_t *) pb;
@@ -154,8 +154,8 @@ struct hb_ot_map_t
 
   HB_INTERNAL void collect_lookups (unsigned int table_index, hb_set_t *lookups) const;
   template <typename Proxy>
-  HB_INTERNAL inline void apply (const Proxy &proxy,
-                                const struct hb_ot_shape_plan_t *plan, hb_font_t *font, hb_buffer_t *buffer) const;
+  HB_INTERNAL void apply (const Proxy &proxy,
+                         const struct hb_ot_shape_plan_t *plan, hb_font_t *font, hb_buffer_t *buffer) const;
   HB_INTERNAL void substitute (const struct hb_ot_shape_plan_t *plan, hb_font_t *font, hb_buffer_t *buffer) const;
   HB_INTERNAL void position (const struct hb_ot_shape_plan_t *plan, hb_font_t *font, hb_buffer_t *buffer) const;
 
@@ -167,7 +167,7 @@ struct hb_ot_map_t
 
   hb_mask_t global_mask;
 
-  hb_vector_t<feature_map_t> features;
+  hb_sorted_vector_t<feature_map_t> features;
   hb_vector_t<lookup_map_t> lookups[2]; /* GSUB/GPOS */
   hb_vector_t<stage_map_t> stages[2]; /* GSUB/GPOS */
 };
@@ -247,7 +247,7 @@ struct hb_ot_map_builder_t
     unsigned int default_value; /* for non-global features, what should the unset glyphs take */
     unsigned int stage[2]; /* GSUB/GPOS */
 
-    static int cmp (const void *pa, const void *pb)
+    HB_INTERNAL static int cmp (const void *pa, const void *pb)
     {
       const feature_info_t *a = (const feature_info_t *) pa;
       const feature_info_t *b = (const feature_info_t *) pb;
index 62bf072..7529e0c 100644 (file)
@@ -423,7 +423,7 @@ struct MathGlyphVariantRecord
   }
 
   protected:
-  GlyphID variantGlyph;       /* Glyph ID for the variant. */
+  HBGlyphID variantGlyph;       /* Glyph ID for the variant. */
   HBUINT16  advanceMeasurement; /* Advance width/height, in design units, of the
                                 * variant, in the direction of requested
                                 * glyph extension. */
@@ -453,16 +453,16 @@ struct MathGlyphPartRecord
   }
 
   void extract (hb_ot_math_glyph_part_t &out,
-               int scale,
+               int64_t mult,
                hb_font_t *font) const
   {
     out.glyph                  = glyph;
 
-    out.start_connector_length = font->em_scale (startConnectorLength, scale);
-    out.end_connector_length   = font->em_scale (endConnectorLength, scale);
-    out.full_advance           = font->em_scale (fullAdvance, scale);
+    out.start_connector_length = font->em_mult (startConnectorLength, mult);
+    out.end_connector_length   = font->em_mult (endConnectorLength, mult);
+    out.full_advance           = font->em_mult (fullAdvance, mult);
 
-    static_assert ((unsigned int) HB_MATH_GLYPH_PART_FLAG_EXTENDER ==
+    static_assert ((unsigned int) HB_OT_MATH_GLYPH_PART_FLAG_EXTENDER ==
                   (unsigned int) PartFlags::Extender, "");
 
     out.flags = (hb_ot_math_glyph_part_flags_t)
@@ -471,7 +471,7 @@ struct MathGlyphPartRecord
   }
 
   protected:
-  GlyphID   glyph;               /* Glyph ID for the part. */
+  HBGlyphID   glyph;             /* Glyph ID for the part. */
   HBUINT16    startConnectorLength; /* Advance width/ height of the straight bar
                                   * connector material, in design units, is at
                                   * the beginning of the glyph, in the
@@ -508,11 +508,11 @@ struct MathGlyphAssembly
   {
     if (parts_count)
     {
-      int scale = font->dir_scale (direction);
+      int64_t mult = font->dir_mult (direction);
       hb_array_t<const MathGlyphPartRecord> arr = partRecords.sub_array (start_offset, parts_count);
       unsigned int count = arr.length;
       for (unsigned int i = 0; i < count; i++)
-       arr[i].extract (parts[i], scale, font);
+       arr[i].extract (parts[i], mult, font);
     }
 
     if (italics_correction)
@@ -553,13 +553,13 @@ struct MathGlyphConstruction
   {
     if (variants_count)
     {
-      int scale = font->dir_scale (direction);
+      int64_t mult = font->dir_mult (direction);
       hb_array_t<const MathGlyphVariantRecord> arr = mathGlyphVariantRecord.sub_array (start_offset, variants_count);
       unsigned int count = arr.length;
       for (unsigned int i = 0; i < count; i++)
       {
        variants[i].glyph = arr[i].variantGlyph;
-       variants[i].advance = font->em_scale (arr[i].advanceMeasurement, scale);
+       variants[i].advance = font->em_mult (arr[i].advanceMeasurement, mult);
       }
     }
     return mathGlyphVariantRecord.len;
@@ -664,7 +664,7 @@ struct MathVariants
   /* Array of offsets to MathGlyphConstruction tables - from the beginning of
      the MathVariants table, for shapes growing in vertical/horizontal
      direction. */
-  UnsizedArrayOf<OffsetTo<MathGlyphConstruction> >
+  UnsizedArrayOf<OffsetTo<MathGlyphConstruction>>
                        glyphConstruction;
 
   public:
index bd31bf5..9d8c6e7 100644 (file)
  * Igalia Author(s): Frédéric Wang
  */
 
-#include "hb-open-type.hh"
+#include "hb.hh"
+
+#ifndef HB_NO_MATH
 
-#include "hb-ot-face.hh"
 #include "hb-ot-math-table.hh"
 
 
  * @include: hb-ot.h
  *
  * Functions for fetching mathematics layout data from OpenType fonts.
+ *
+ * HarfBuzz itself does not implement a math layout solution. The
+ * functions and types provided can be used by client programs to access
+ * the font data necessary for typesetting OpenType Math layout.
+ *
  **/
 
 
  * hb_ot_math_has_data:
  * @face: #hb_face_t to test
  *
- * This function allows to verify the presence of an OpenType MATH table on the
- * face.
+ * Tests whether a face has a `MATH` table.
  *
- * Return value: true if face has a MATH table, false otherwise
+ * Return value: true if the table is found, false otherwise
  *
  * Since: 1.3.3
  **/
@@ -63,16 +68,18 @@ hb_ot_math_has_data (hb_face_t *face)
 
 /**
  * hb_ot_math_get_constant:
- * @font: #hb_font_t from which to retrieve the value
+ * @font: #hb_font_t to work upon
  * @constant: #hb_ot_math_constant_t the constant to retrieve
  *
- * This function returns the requested math constants as a #hb_position_t.
- * If the request constant is HB_OT_MATH_CONSTANT_SCRIPT_PERCENT_SCALE_DOWN,
- * HB_OT_MATH_CONSTANT_SCRIPT_SCRIPT_PERCENT_SCALE_DOWN or
- * HB_OT_MATH_CONSTANT_SCRIPT_PERCENT_SCALE_DOWN then the return value is
- * actually an integer between 0 and 100 representing that percentage.
+ * Fetches the specified math constant. For most constants, the value returned
+ * is an #hb_position_t.
+ *
+ * However, if the requested constant is #HB_OT_MATH_CONSTANT_SCRIPT_PERCENT_SCALE_DOWN,
+ * #HB_OT_MATH_CONSTANT_SCRIPT_SCRIPT_PERCENT_SCALE_DOWN or
+ * #HB_OT_MATH_CONSTANT_SCRIPT_PERCENT_SCALE_DOWN, then the return value is
+ * an integer between 0 and 100 representing that percentage.
  *
- * Return value: the requested constant or 0
+ * Return value: the requested constant or zero
  *
  * Since: 1.3.3
  **/
@@ -85,10 +92,13 @@ hb_ot_math_get_constant (hb_font_t *font,
 
 /**
  * hb_ot_math_get_glyph_italics_correction:
- * @font: #hb_font_t from which to retrieve the value
- * @glyph: glyph index from which to retrieve the value
+ * @font: #hb_font_t to work upon
+ * @glyph: The glyph index from which to retrieve the value
  *
- * Return value: the italics correction of the glyph or 0
+ * Fetches an italics-correction value (if one exists) for the specified
+ * glyph index.
+ *
+  * Return value: the italics correction of the glyph or zero
  *
  * Since: 1.3.3
  **/
@@ -101,10 +111,20 @@ hb_ot_math_get_glyph_italics_correction (hb_font_t *font,
 
 /**
  * hb_ot_math_get_glyph_top_accent_attachment:
- * @font: #hb_font_t from which to retrieve the value
- * @glyph: glyph index from which to retrieve the value
+ * @font: #hb_font_t to work upon
+ * @glyph: The glyph index from which to retrieve the value
+ *
+ * Fetches a top-accent-attachment value (if one exists) for the specified
+ * glyph index.
+ *
+ * For any glyph that does not have a top-accent-attachment value - that is,
+ * a glyph not covered by the `MathTopAccentAttachment` table (or, when
+ * @font has no `MathTopAccentAttachment` table or no `MATH` table, any
+ * glyph) - the function synthesizes a value, returning the position at
+ * one-half the glyph's advance width.
  *
- * Return value: the top accent attachment of the glyph or 0
+ * Return value: the top accent attachment of the glyph or 0.5 * the advance
+ *               width of @glyph
  *
  * Since: 1.3.3
  **/
@@ -117,8 +137,10 @@ hb_ot_math_get_glyph_top_accent_attachment (hb_font_t *font,
 
 /**
  * hb_ot_math_is_glyph_extended_shape:
- * @face: a #hb_face_t to test
- * @glyph: a glyph index to test
+ * @face: #hb_face_t to work upon
+ * @glyph: The glyph index to test
+ *
+ * Tests whether the given glyph index is an extended shape in the face.
  *
  * Return value: true if the glyph is an extended shape, false otherwise
  *
@@ -133,18 +155,20 @@ hb_ot_math_is_glyph_extended_shape (hb_face_t *face,
 
 /**
  * hb_ot_math_get_glyph_kerning:
- * @font: #hb_font_t from which to retrieve the value
- * @glyph: glyph index from which to retrieve the value
- * @kern: the #hb_ot_math_kern_t from which to retrieve the value
+ * @font: #hb_font_t to work upon
+ * @glyph: The glyph index from which to retrieve the value
+ * @kern: The #hb_ot_math_kern_t from which to retrieve the value
  * @correction_height: the correction height to use to determine the kerning.
  *
- * This function tries to retrieve the MathKern table for the specified font,
- * glyph and #hb_ot_math_kern_t. Then it browses the list of heights from the
- * MathKern table to find one value that is greater or equal to specified
- * correction_height. If one is found the corresponding value from the list of
- * kerns is returned and otherwise the last kern value is returned.
+ * Fetches the math kerning (cut-ins) value for the specified font, glyph index, and
+ * @kern. 
+ *
+ * If the MathKern table is found, the function examines it to find a height
+ * value that is greater or equal to @correction_height. If such a height
+ * value is found, corresponding kerning value from the table is returned. If
+ * no such height value is found, the last kerning value is returned.
  *
- * Return value: requested kerning or 0
+ * Return value: requested kerning value or zero
  *
  * Since: 1.3.3
  **/
@@ -162,20 +186,24 @@ hb_ot_math_get_glyph_kerning (hb_font_t *font,
 
 /**
  * hb_ot_math_get_glyph_variants:
- * @font: #hb_font_t from which to retrieve the values
- * @glyph: index of the glyph to stretch
- * @direction: direction of the stretching
+ * @font: #hb_font_t to work upon
+ * @glyph: The index of the glyph to stretch
+ * @direction: The direction of the stretching (horizontal or vertical)
  * @start_offset: offset of the first variant to retrieve
- * @variants_count: maximum number of variants to retrieve after start_offset
- * (IN) and actual number of variants retrieved (OUT)
- * @variants: array of size at least @variants_count to store the result
+ * @variants_count: (inout): Input = the maximum number of variants to return;
+ *                           Output = the actual number of variants returned
+ * @variants: (out) (array length=variants_count): array of variants returned
  *
- * This function tries to retrieve the MathGlyphConstruction for the specified
- * font, glyph and direction. Note that only the value of
- * #HB_DIRECTION_IS_HORIZONTAL is considered. It provides the corresponding list
- * of size variants as an array of hb_ot_math_glyph_variant_t structs.
+ * Fetches the MathGlyphConstruction for the specified font, glyph index, and
+ * direction. The corresponding list of size variants is returned as a list of
+ * #hb_ot_math_glyph_variant_t structs.
  *
- * Return value: the total number of size variants available or 0
+ * <note>The @direction parameter is only used to select between horizontal
+ * or vertical directions for the construction. Even though all #hb_direction_t
+ * values are accepted, only the result of #HB_DIRECTION_IS_HORIZONTAL is
+ * considered.</note> 
+ *
+ * Return value: the total number of size variants available or zero
  *
  * Since: 1.3.3
  **/
@@ -195,15 +223,19 @@ hb_ot_math_get_glyph_variants (hb_font_t *font,
 
 /**
  * hb_ot_math_get_min_connector_overlap:
- * @font: #hb_font_t from which to retrieve the value
- * @direction: direction of the stretching
+ * @font: #hb_font_t to work upon
+ * @direction: direction of the stretching (horizontal or vertical)
+ *
+ * Fetches the MathVariants table for the specified font and returns the
+ * minimum overlap of connecting glyphs that are required to draw a glyph
+ * assembly in the specified direction.
  *
- * This function tries to retrieve the MathVariants table for the specified
- * font and returns the minimum overlap of connecting glyphs to draw a glyph
- * assembly in the specified direction. Note that only the value of
- * #HB_DIRECTION_IS_HORIZONTAL is considered.
+ * <note>The @direction parameter is only used to select between horizontal
+ * or vertical directions for the construction. Even though all #hb_direction_t
+ * values are accepted, only the result of #HB_DIRECTION_IS_HORIZONTAL is
+ * considered.</note> 
  *
- * Return value: requested min connector overlap or 0
+ * Return value: requested minimum connector overlap or zero
  *
  * Since: 1.3.3
  **/
@@ -216,19 +248,24 @@ hb_ot_math_get_min_connector_overlap (hb_font_t *font,
 
 /**
  * hb_ot_math_get_glyph_assembly:
- * @font: #hb_font_t from which to retrieve the values
- * @glyph: index of the glyph to stretch
- * @direction: direction of the stretching
+ * @font: #hb_font_t to work upon
+ * @glyph: The index of the glyph to stretch
+ * @direction: direction of the stretching (horizontal or vertical)
  * @start_offset: offset of the first glyph part to retrieve
- * @parts_count: maximum number of glyph parts to retrieve after start_offset
- * (IN) and actual number of parts retrieved (OUT)
- * @parts: array of size at least @parts_count to store the result
- * @italics_correction: italic correction of the glyph assembly
+ * @parts_count: (inout): Input = maximum number of glyph parts to return;
+ *               Output = actual number of parts returned
+ * @parts: (out) (array length=parts_count): the glyph parts returned
+ * @italics_correction: (out): italics correction of the glyph assembly
  *
- * This function tries to retrieve the GlyphAssembly for the specified font,
- * glyph and direction. Note that only the value of #HB_DIRECTION_IS_HORIZONTAL
- * is considered. It provides the information necessary to draw the glyph
- * assembly as an array of #hb_ot_math_glyph_part_t.
+ * Fetches the GlyphAssembly for the specified font, glyph index, and direction.
+ * Returned are a list of #hb_ot_math_glyph_part_t glyph parts that can be
+ * used to draw the glyph and an italics-correction value (if one is defined
+ * in the font).
+ *
+ * <note>The @direction parameter is only used to select between horizontal
+ * or vertical directions for the construction. Even though all #hb_direction_t
+ * values are accepted, only the result of #HB_DIRECTION_IS_HORIZONTAL is
+ * considered.</note> 
  *
  * Return value: the total number of parts in the glyph assembly
  *
@@ -251,3 +288,6 @@ hb_ot_math_get_glyph_assembly (hb_font_t *font,
                                                                 parts,
                                                                 italics_correction);
 }
+
+
+#endif
index 521a5ca..ad864a7 100644 (file)
@@ -50,6 +50,9 @@ HB_BEGIN_DECLS
 /**
  * hb_ot_math_constant_t:
  *
+ * The 'MATH' table constants specified at
+ * https://docs.microsoft.com/en-us/typography/opentype/spec/math
+ *
  * Since: 1.3.3
  */
 typedef enum {
@@ -114,6 +117,9 @@ typedef enum {
 /**
  * hb_ot_math_kern_t:
  *
+ * The math kerning-table types defined for the four corners
+ * of a glyph.
+ *
  * Since: 1.3.3
  */
 typedef enum {
@@ -125,6 +131,10 @@ typedef enum {
 
 /**
  * hb_ot_math_glyph_variant_t:
+ * @glyph: The glyph index of the variant
+ * @advance: The advance width of the variant
+ *
+ * Data type to hold math-variant information for a glyph.
  *
  * Since: 1.3.3
  */
@@ -136,14 +146,25 @@ typedef struct hb_ot_math_glyph_variant_t {
 /**
  * hb_ot_math_glyph_part_flags_t:
  *
+ * Flags for math glyph parts.
+ *
  * Since: 1.3.3
  */
 typedef enum { /*< flags >*/
-  HB_MATH_GLYPH_PART_FLAG_EXTENDER     = 0x00000001u  /* Extender glyph */
+  HB_OT_MATH_GLYPH_PART_FLAG_EXTENDER  = 0x00000001u  /* Extender glyph */
 } hb_ot_math_glyph_part_flags_t;
 
 /**
  * hb_ot_math_glyph_part_t:
+ * @glyph: The glyph index of the variant part
+ * @start_connector_length: The length of the connector on the starting side of the variant part
+ * @end_connector_length: The length of the connector on the ending side of the variant part
+ * @full_advance: The total advance of the part
+ * @flags: #hb_ot_math_glyph_part_flags_t flags for the part
+ * 
+ * Data type to hold information for a "part" component of a math-variant glyph.
+ * Large variants for stretchable math glyphs (such as parentheses) can be constructed
+ * on the fly from parts.
  *
  * Since: 1.3.3
  */
index 10bd592..1c25eda 100644 (file)
@@ -77,7 +77,7 @@ struct maxp
 
   void set_num_glyphs (unsigned int count)
   {
-    numGlyphs.set (count);
+    numGlyphs = count;
   }
 
   bool sanitize (hb_sanitize_context_t *c) const
@@ -94,46 +94,42 @@ struct maxp
     return_trace (likely (version.major == 0 && version.minor == 0x5000u));
   }
 
-  bool subset (hb_subset_plan_t *plan) const
+  bool subset (hb_subset_context_t *c) const
   {
-    hb_blob_t *maxp_blob = hb_sanitize_context_t().reference_table<maxp> (plan->source);
-    hb_blob_t *maxp_prime_blob = hb_blob_copy_writable_or_fail (maxp_blob);
-    hb_blob_destroy (maxp_blob);
+    TRACE_SUBSET (this);
+    maxp *maxp_prime = c->serializer->embed (this);
+    if (unlikely (!maxp_prime)) return_trace (false);
 
-    if (unlikely (!maxp_prime_blob)) {
-      return false;
-    }
-    maxp *maxp_prime = (maxp *) hb_blob_get_data (maxp_prime_blob, nullptr);
+    maxp_prime->numGlyphs = c->plan->num_output_glyphs ();
+    if (maxp_prime->version.major == 1)
+    {
+      const maxpV1Tail *src_v1 = &StructAfter<maxpV1Tail> (*this);
+      maxpV1Tail *dest_v1 = c->serializer->embed<maxpV1Tail> (src_v1);
+      if (unlikely (!dest_v1)) return_trace (false);
 
-    maxp_prime->set_num_glyphs (plan->num_output_glyphs ());
-    if (plan->drop_hints)
-      drop_hint_fields (plan, maxp_prime);
+      if (c->plan->drop_hints)
+       drop_hint_fields (dest_v1);
+    }
 
-    bool result = plan->add_table (HB_OT_TAG_maxp, maxp_prime_blob);
-    hb_blob_destroy (maxp_prime_blob);
-    return result;
+    return_trace (true);
   }
 
-  static void drop_hint_fields (hb_subset_plan_t *plan HB_UNUSED, maxp *maxp_prime)
+  static void drop_hint_fields (maxpV1Tail* dest_v1)
   {
-    if (maxp_prime->version.major == 1)
-    {
-      maxpV1Tail &v1 = StructAfter<maxpV1Tail> (*maxp_prime);
-      v1.maxZones.set (1);
-      v1.maxTwilightPoints.set (0);
-      v1.maxStorage.set (0);
-      v1.maxFunctionDefs.set (0);
-      v1.maxInstructionDefs.set (0);
-      v1.maxStackElements.set (0);
-      v1.maxSizeOfInstructions.set (0);
-    }
+    dest_v1->maxZones = 1;
+    dest_v1->maxTwilightPoints = 0;
+    dest_v1->maxStorage = 0;
+    dest_v1->maxFunctionDefs = 0;
+    dest_v1->maxInstructionDefs = 0;
+    dest_v1->maxStackElements = 0;
+    dest_v1->maxSizeOfInstructions = 0;
   }
 
   protected:
   FixedVersion<>version;               /* Version of the maxp table (0.5 or 1.0),
                                         * 0x00005000u or 0x00010000u. */
   HBUINT16     numGlyphs;              /* The number of glyphs in the font. */
-/*maxpV1Tail   v1Tail[VAR]; */
+/*maxpV1Tail   v1Tail[HB_VAR_ARRAY]; */
   public:
   DEFINE_SIZE_STATIC (6);
 };
diff --git a/src/hb-ot-meta-table.hh b/src/hb-ot-meta-table.hh
new file mode 100644 (file)
index 0000000..43a02d6
--- /dev/null
@@ -0,0 +1,126 @@
+/*
+ * Copyright © 2019  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_META_TABLE_HH
+#define HB_OT_META_TABLE_HH
+
+#include "hb-open-type.hh"
+
+/*
+ * meta -- Metadata Table
+ * https://docs.microsoft.com/en-us/typography/opentype/spec/meta
+ * https://developer.apple.com/fonts/TrueType-Reference-Manual/RM06/Chap6meta.html
+ */
+#define HB_OT_TAG_meta HB_TAG ('m','e','t','a')
+
+
+namespace OT {
+
+
+struct DataMap
+{
+  int cmp (hb_tag_t a) const { return tag.cmp (a); }
+
+  hb_tag_t get_tag () const { return tag; }
+
+  hb_blob_t *reference_entry (hb_blob_t *meta_blob) const
+  { return hb_blob_create_sub_blob (meta_blob, dataZ, dataLength); }
+
+  bool sanitize (hb_sanitize_context_t *c, const void *base) const
+  {
+    TRACE_SANITIZE (this);
+    return_trace (likely (c->check_struct (this) &&
+                         dataZ.sanitize (c, base, dataLength)));
+  }
+
+  protected:
+  Tag          tag;            /* A tag indicating the type of metadata. */
+  LOffsetTo<UnsizedArrayOf<HBUINT8>>
+               dataZ;          /* Offset in bytes from the beginning of the
+                                * metadata table to the data for this tag. */
+  HBUINT32     dataLength;     /* Length of the data. The data is not required to
+                                * be padded to any byte boundary. */
+  public:
+  DEFINE_SIZE_STATIC (12);
+};
+
+struct meta
+{
+  static constexpr hb_tag_t tableTag = HB_OT_TAG_meta;
+
+  struct accelerator_t
+  {
+    void init (hb_face_t *face)
+    { table = hb_sanitize_context_t ().reference_table<meta> (face); }
+    void fini () { table.destroy (); }
+
+    hb_blob_t *reference_entry (hb_tag_t tag) const
+    { return table->dataMaps.lsearch (tag).reference_entry (table.get_blob ()); }
+
+    unsigned int get_entries (unsigned int      start_offset,
+                             unsigned int     *count,
+                             hb_ot_meta_tag_t *entries) const
+    {
+      if (count)
+      {
+       + table->dataMaps.sub_array (start_offset, count)
+       | hb_map (&DataMap::get_tag)
+       | hb_map ([](hb_tag_t tag) { return (hb_ot_meta_tag_t) tag; })
+       | hb_sink (hb_array (entries, *count))
+       ;
+      }
+      return table->dataMaps.len;
+    }
+
+    private:
+    hb_blob_ptr_t<meta> table;
+  };
+
+  bool sanitize (hb_sanitize_context_t *c) const
+  {
+    TRACE_SANITIZE (this);
+    return_trace (likely (c->check_struct (this) &&
+                         version == 1 &&
+                         dataMaps.sanitize (c, this)));
+  }
+
+  protected:
+  HBUINT32     version;        /* Version number of the metadata table — set to 1. */
+  HBUINT32     flags;          /* Flags — currently unused; set to 0. */
+  HBUINT32     dataOffset;     /* Per Apple specification:
+                                * Offset from the beginning of the table to the data.
+                                * Per OT specification:
+                                * Reserved. Not used; should be set to 0. */
+  LArrayOf<DataMap>
+               dataMaps;       /* Array of data map records. */
+  public:
+  DEFINE_SIZE_ARRAY (16, dataMaps);
+};
+
+struct meta_accelerator_t : meta::accelerator_t {};
+
+} /* namespace OT */
+
+
+#endif /* HB_OT_META_TABLE_HH */
diff --git a/src/hb-ot-meta.cc b/src/hb-ot-meta.cc
new file mode 100644 (file)
index 0000000..a1e081b
--- /dev/null
@@ -0,0 +1,77 @@
+/*
+ * Copyright © 2019  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.
+ */
+
+#include "hb.hh"
+
+#ifndef HB_NO_META
+
+#include "hb-ot-meta-table.hh"
+
+/**
+ * SECTION:hb-ot-meta
+ * @title: hb-ot-meta
+ * @short_description: OpenType Metadata
+ * @include: hb-ot.h
+ *
+ * Functions for fetching metadata from fonts.
+ **/
+
+/**
+ * hb_ot_meta_reference_entry:
+ * @face: a face object
+ * @start_offset: iteration's start offset
+ * @entries_count:(inout) (allow-none): buffer size as input, filled size as output
+ * @entries: (out caller-allocates) (array length=entries_count): entries tags buffer
+ *
+ * Return value: Number of all available feature types.
+ *
+ * Since: 2.6.0
+ **/
+unsigned int
+hb_ot_meta_get_entry_tags (hb_face_t        *face,
+                          unsigned int      start_offset,
+                          unsigned int     *entries_count, /* IN/OUT.  May be NULL. */
+                          hb_ot_meta_tag_t *entries        /* OUT.     May be NULL. */)
+{
+  return face->table.meta->get_entries (start_offset, entries_count, entries);
+}
+
+/**
+ * hb_ot_meta_reference_entry:
+ * @face: a #hb_face_t object.
+ * @meta_tag: tag of metadata you like to have.
+ *
+ * It fetches metadata entry of a given tag from a font.
+ *
+ * Returns: (transfer full): A blob containing the blob.
+ *
+ * Since: 2.6.0
+ **/
+hb_blob_t *
+hb_ot_meta_reference_entry (hb_face_t *face, hb_ot_meta_tag_t meta_tag)
+{
+  return face->table.meta->reference_entry (meta_tag);
+}
+
+#endif
diff --git a/src/hb-ot-meta.h b/src/hb-ot-meta.h
new file mode 100644 (file)
index 0000000..0278d84
--- /dev/null
@@ -0,0 +1,71 @@
+/*
+ * Copyright © 2019  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_H_IN
+#error "Include <hb-ot.h> instead."
+#endif
+
+#ifndef HB_OT_META_H
+#define HB_OT_META_H
+
+#include "hb.h"
+
+HB_BEGIN_DECLS
+
+/**
+ * hb_ot_meta_tag_t:
+ * @HB_OT_META_TAG_DESIGN_LANGUAGES: Design languages. Text, using only
+ * Basic Latin (ASCII) characters. Indicates languages and/or scripts
+ * for the user audiences that the font was primarily designed for.
+ * @HB_OT_META_TAG_SUPPORTED_LANGUAGES: Supported languages. Text, using
+ * only Basic Latin (ASCII) characters. Indicates languages and/or scripts
+ * that the font is declared to be capable of supporting.
+ *
+ * Known metadata tags from https://docs.microsoft.com/en-us/typography/opentype/spec/meta
+ *
+ * Since: 2.6.0
+ **/
+typedef enum {
+/*
+   HB_OT_META_TAG_APPL         = HB_TAG ('a','p','p','l'),
+   HB_OT_META_TAG_BILD         = HB_TAG ('b','i','l','d'),
+*/
+  HB_OT_META_TAG_DESIGN_LANGUAGES      = HB_TAG ('d','l','n','g'),
+  HB_OT_META_TAG_SUPPORTED_LANGUAGES   = HB_TAG ('s','l','n','g'),
+
+  _HB_OT_META_TAG_MAX_VALUE = HB_TAG_MAX_SIGNED /*< skip >*/
+} hb_ot_meta_tag_t;
+
+HB_EXTERN unsigned int
+hb_ot_meta_get_entry_tags (hb_face_t        *face,
+                          unsigned int      start_offset,
+                          unsigned int     *entries_count, /* IN/OUT.  May be NULL. */
+                          hb_ot_meta_tag_t *entries        /* OUT.     May be NULL. */);
+
+HB_EXTERN hb_blob_t *
+hb_ot_meta_reference_entry (hb_face_t *face, hb_ot_meta_tag_t meta_tag);
+
+HB_END_DECLS
+
+#endif /* HB_OT_META_H */
diff --git a/src/hb-ot-metrics.cc b/src/hb-ot-metrics.cc
new file mode 100644 (file)
index 0000000..181ac4d
--- /dev/null
@@ -0,0 +1,231 @@
+/*
+ * Copyright © 2018-2019  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.
+ */
+
+#include "hb.hh"
+
+#include "hb-ot-var-mvar-table.hh"
+#include "hb-ot-gasp-table.hh" // Just so we compile it; unused otherwise.
+#include "hb-ot-os2-table.hh"
+#include "hb-ot-post-table.hh"
+#include "hb-ot-hhea-table.hh"
+#include "hb-ot-metrics.hh"
+#include "hb-ot-face.hh"
+
+
+static float
+_fix_ascender_descender (float value, hb_ot_metrics_tag_t metrics_tag)
+{
+  if (metrics_tag == HB_OT_METRICS_TAG_HORIZONTAL_ASCENDER ||
+      metrics_tag == HB_OT_METRICS_TAG_VERTICAL_ASCENDER)
+    return fabs ((double) value);
+  if (metrics_tag == HB_OT_METRICS_TAG_HORIZONTAL_DESCENDER ||
+      metrics_tag == HB_OT_METRICS_TAG_VERTICAL_DESCENDER)
+    return -fabs ((double) value);
+  return value;
+}
+
+/* The common part of _get_position logic needed on hb-ot-font and here
+   to be able to have slim builds without the not always needed parts */
+bool
+_hb_ot_metrics_get_position_common (hb_font_t           *font,
+                                   hb_ot_metrics_tag_t  metrics_tag,
+                                   hb_position_t       *position     /* OUT.  May be NULL. */)
+{
+  hb_face_t *face = font->face;
+  switch ((unsigned) metrics_tag)
+  {
+#ifndef HB_NO_VAR
+#define GET_VAR face->table.MVAR->get_var (metrics_tag, font->coords, font->num_coords)
+#else
+#define GET_VAR .0f
+#endif
+#define GET_METRIC_X(TABLE, ATTR) \
+  (face->table.TABLE->has_data () && \
+    (position && (*position = font->em_scalef_x (_fix_ascender_descender ( \
+      face->table.TABLE->ATTR + GET_VAR, metrics_tag))), true))
+#define GET_METRIC_Y(TABLE, ATTR) \
+  (face->table.TABLE->has_data () && \
+    (position && (*position = font->em_scalef_y (_fix_ascender_descender ( \
+      face->table.TABLE->ATTR + GET_VAR, metrics_tag))), true))
+  case HB_OT_METRICS_TAG_HORIZONTAL_ASCENDER:
+    return (face->table.OS2->use_typo_metrics () && GET_METRIC_Y (OS2, sTypoAscender)) ||
+          GET_METRIC_Y (hhea, ascender);
+  case HB_OT_METRICS_TAG_HORIZONTAL_DESCENDER:
+    return (face->table.OS2->use_typo_metrics () && GET_METRIC_Y (OS2, sTypoDescender)) ||
+          GET_METRIC_Y (hhea, descender);
+  case HB_OT_METRICS_TAG_HORIZONTAL_LINE_GAP:
+    return (face->table.OS2->use_typo_metrics () && GET_METRIC_Y (OS2, sTypoLineGap)) ||
+          GET_METRIC_Y (hhea, lineGap);
+  case HB_OT_METRICS_TAG_VERTICAL_ASCENDER:  return GET_METRIC_X (vhea, ascender);
+  case HB_OT_METRICS_TAG_VERTICAL_DESCENDER: return GET_METRIC_X (vhea, descender);
+  case HB_OT_METRICS_TAG_VERTICAL_LINE_GAP:  return GET_METRIC_X (vhea, lineGap);
+#undef GET_METRIC_Y
+#undef GET_METRIC_X
+#undef GET_VAR
+  default:                               assert (0); return false;
+  }
+}
+
+#ifndef HB_NO_METRICS
+
+#if 0
+static bool
+_get_gasp (hb_face_t *face, float *result, hb_ot_metrics_tag_t metrics_tag)
+{
+  const OT::GaspRange& range = face->table.gasp->get_gasp_range (metrics_tag - HB_TAG ('g','s','p','0'));
+  if (&range == &Null (OT::GaspRange)) return false;
+  if (result) *result = range.rangeMaxPPEM + font->face->table.MVAR->get_var (metrics_tag, font->coords, font->num_coords);
+  return true;
+}
+#endif
+
+/* Private tags for https://github.com/harfbuzz/harfbuzz/issues/1866 */
+#define _HB_OT_METRICS_TAG_HORIZONTAL_ASCENDER_OS2   HB_TAG ('O','a','s','c')
+#define _HB_OT_METRICS_TAG_HORIZONTAL_ASCENDER_HHEA  HB_TAG ('H','a','s','c')
+#define _HB_OT_METRICS_TAG_HORIZONTAL_DESCENDER_OS2  HB_TAG ('O','d','s','c')
+#define _HB_OT_METRICS_TAG_HORIZONTAL_DESCENDER_HHEA HB_TAG ('H','d','s','c')
+#define _HB_OT_METRICS_TAG_HORIZONTAL_LINE_GAP_OS2   HB_TAG ('O','l','g','p')
+#define _HB_OT_METRICS_TAG_HORIZONTAL_LINE_GAP_HHEA  HB_TAG ('H','l','g','p')
+
+/**
+ * hb_ot_metrics_get_position:
+ * @font: a #hb_font_t object.
+ * @metrics_tag: tag of metrics value you like to fetch.
+ * @position: (out) (optional): result of metrics value from the font.
+ *
+ * It fetches metrics value corresponding to a given tag from a font.
+ *
+ * Returns: Whether found the requested metrics in the font.
+ * Since: 2.6.0
+ **/
+hb_bool_t
+hb_ot_metrics_get_position (hb_font_t           *font,
+                           hb_ot_metrics_tag_t  metrics_tag,
+                           hb_position_t       *position     /* OUT.  May be NULL. */)
+{
+  hb_face_t *face = font->face;
+  switch ((unsigned) metrics_tag)
+  {
+  case HB_OT_METRICS_TAG_HORIZONTAL_ASCENDER:
+  case HB_OT_METRICS_TAG_HORIZONTAL_DESCENDER:
+  case HB_OT_METRICS_TAG_HORIZONTAL_LINE_GAP:
+  case HB_OT_METRICS_TAG_VERTICAL_ASCENDER:
+  case HB_OT_METRICS_TAG_VERTICAL_DESCENDER:
+  case HB_OT_METRICS_TAG_VERTICAL_LINE_GAP:           return _hb_ot_metrics_get_position_common (font, metrics_tag, position);
+#ifndef HB_NO_VAR
+#define GET_VAR hb_ot_metrics_get_variation (font, metrics_tag)
+#else
+#define GET_VAR 0
+#endif
+#define GET_METRIC_X(TABLE, ATTR) \
+  (face->table.TABLE->has_data () && \
+    (position && (*position = font->em_scalef_x (face->table.TABLE->ATTR + GET_VAR)), true))
+#define GET_METRIC_Y(TABLE, ATTR) \
+  (face->table.TABLE->has_data () && \
+    (position && (*position = font->em_scalef_y (face->table.TABLE->ATTR + GET_VAR)), true))
+  case HB_OT_METRICS_TAG_HORIZONTAL_CLIPPING_ASCENT:  return GET_METRIC_Y (OS2, usWinAscent);
+  case HB_OT_METRICS_TAG_HORIZONTAL_CLIPPING_DESCENT: return GET_METRIC_Y (OS2, usWinDescent);
+  case HB_OT_METRICS_TAG_HORIZONTAL_CARET_RISE:       return GET_METRIC_Y (hhea, caretSlopeRise);
+  case HB_OT_METRICS_TAG_HORIZONTAL_CARET_RUN:        return GET_METRIC_X (hhea, caretSlopeRun);
+  case HB_OT_METRICS_TAG_HORIZONTAL_CARET_OFFSET:     return GET_METRIC_X (hhea, caretOffset);
+  case HB_OT_METRICS_TAG_VERTICAL_CARET_RISE:         return GET_METRIC_X (vhea, caretSlopeRise);
+  case HB_OT_METRICS_TAG_VERTICAL_CARET_RUN:          return GET_METRIC_Y (vhea, caretSlopeRun);
+  case HB_OT_METRICS_TAG_VERTICAL_CARET_OFFSET:       return GET_METRIC_Y (vhea, caretOffset);
+  case HB_OT_METRICS_TAG_X_HEIGHT:                    return GET_METRIC_Y (OS2->v2 (), sxHeight);
+  case HB_OT_METRICS_TAG_CAP_HEIGHT:                  return GET_METRIC_Y (OS2->v2 (), sCapHeight);
+  case HB_OT_METRICS_TAG_SUBSCRIPT_EM_X_SIZE:         return GET_METRIC_X (OS2, ySubscriptXSize);
+  case HB_OT_METRICS_TAG_SUBSCRIPT_EM_Y_SIZE:         return GET_METRIC_Y (OS2, ySubscriptYSize);
+  case HB_OT_METRICS_TAG_SUBSCRIPT_EM_X_OFFSET:       return GET_METRIC_X (OS2, ySubscriptXOffset);
+  case HB_OT_METRICS_TAG_SUBSCRIPT_EM_Y_OFFSET:       return GET_METRIC_Y (OS2, ySubscriptYOffset);
+  case HB_OT_METRICS_TAG_SUPERSCRIPT_EM_X_SIZE:       return GET_METRIC_X (OS2, ySuperscriptXSize);
+  case HB_OT_METRICS_TAG_SUPERSCRIPT_EM_Y_SIZE:       return GET_METRIC_Y (OS2, ySuperscriptYSize);
+  case HB_OT_METRICS_TAG_SUPERSCRIPT_EM_X_OFFSET:     return GET_METRIC_X (OS2, ySuperscriptXOffset);
+  case HB_OT_METRICS_TAG_SUPERSCRIPT_EM_Y_OFFSET:     return GET_METRIC_Y (OS2, ySuperscriptYOffset);
+  case HB_OT_METRICS_TAG_STRIKEOUT_SIZE:              return GET_METRIC_Y (OS2, yStrikeoutSize);
+  case HB_OT_METRICS_TAG_STRIKEOUT_OFFSET:            return GET_METRIC_Y (OS2, yStrikeoutPosition);
+  case HB_OT_METRICS_TAG_UNDERLINE_SIZE:              return GET_METRIC_Y (post->table, underlineThickness);
+  case HB_OT_METRICS_TAG_UNDERLINE_OFFSET:            return GET_METRIC_Y (post->table, underlinePosition);
+
+  /* Private tags */
+  case _HB_OT_METRICS_TAG_HORIZONTAL_ASCENDER_OS2:    return GET_METRIC_Y (OS2, sTypoAscender);
+  case _HB_OT_METRICS_TAG_HORIZONTAL_ASCENDER_HHEA:   return GET_METRIC_Y (hhea, ascender);
+  case _HB_OT_METRICS_TAG_HORIZONTAL_DESCENDER_OS2:   return GET_METRIC_Y (OS2, sTypoDescender);
+  case _HB_OT_METRICS_TAG_HORIZONTAL_DESCENDER_HHEA:  return GET_METRIC_Y (hhea, descender);
+  case _HB_OT_METRICS_TAG_HORIZONTAL_LINE_GAP_OS2:    return GET_METRIC_Y (OS2, sTypoLineGap);
+  case _HB_OT_METRICS_TAG_HORIZONTAL_LINE_GAP_HHEA:   return GET_METRIC_Y (hhea, lineGap);
+#undef GET_METRIC_Y
+#undef GET_METRIC_X
+#undef GET_VAR
+  default:                                        return false;
+  }
+}
+
+#ifndef HB_NO_VAR
+/**
+ * hb_ot_metrics_get_variation:
+ * @font:
+ * @metrics_tag:
+ *
+ * Returns:
+ *
+ * Since: 2.6.0
+ **/
+float
+hb_ot_metrics_get_variation (hb_font_t *font, hb_ot_metrics_tag_t metrics_tag)
+{
+  return font->face->table.MVAR->get_var (metrics_tag, font->coords, font->num_coords);
+}
+
+/**
+ * hb_ot_metrics_get_x_variation:
+ * @font:
+ * @metrics_tag:
+ *
+ * Returns:
+ *
+ * Since: 2.6.0
+ **/
+hb_position_t
+hb_ot_metrics_get_x_variation (hb_font_t *font, hb_ot_metrics_tag_t metrics_tag)
+{
+  return font->em_scalef_x (hb_ot_metrics_get_variation (font, metrics_tag));
+}
+
+/**
+ * hb_ot_metrics_get_y_variation:
+ * @font:
+ * @metrics_tag:
+ *
+ * Returns:
+ *
+ * Since: 2.6.0
+ **/
+hb_position_t
+hb_ot_metrics_get_y_variation (hb_font_t *font, hb_ot_metrics_tag_t metrics_tag)
+{
+  return font->em_scalef_y (hb_ot_metrics_get_variation (font, metrics_tag));
+}
+#endif
+
+#endif
diff --git a/src/hb-ot-metrics.h b/src/hb-ot-metrics.h
new file mode 100644 (file)
index 0000000..42c7363
--- /dev/null
@@ -0,0 +1,122 @@
+/*
+ * 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_H_IN
+#error "Include <hb-ot.h> instead."
+#endif
+
+#ifndef HB_OT_METRICS_H
+#define HB_OT_METRICS_H
+
+#include "hb.h"
+#include "hb-ot-name.h"
+
+HB_BEGIN_DECLS
+
+
+/**
+ * hb_ot_metrics_tag_t:
+ * @HB_OT_METRICS_TAG_HORIZONTAL_ASCENDER: horizontal ascender.
+ * @HB_OT_METRICS_TAG_HORIZONTAL_DESCENDER: horizontal descender.
+ * @HB_OT_METRICS_TAG_HORIZONTAL_LINE_GAP: horizontal line gap.
+ * @HB_OT_METRICS_TAG_HORIZONTAL_CLIPPING_ASCENT: horizontal clipping ascent.
+ * @HB_OT_METRICS_TAG_HORIZONTAL_CLIPPING_DESCENT: horizontal clipping descent.
+ * @HB_OT_METRICS_TAG_VERTICAL_ASCENDER: vertical ascender.
+ * @HB_OT_METRICS_TAG_VERTICAL_DESCENDER: vertical descender.
+ * @HB_OT_METRICS_TAG_VERTICAL_LINE_GAP: vertical line gap.
+ * @HB_OT_METRICS_TAG_HORIZONTAL_CARET_RISE: horizontal caret rise.
+ * @HB_OT_METRICS_TAG_HORIZONTAL_CARET_RUN: horizontal caret run.
+ * @HB_OT_METRICS_TAG_HORIZONTAL_CARET_OFFSET: horizontal caret offset.
+ * @HB_OT_METRICS_TAG_VERTICAL_CARET_RISE: vertical caret rise.
+ * @HB_OT_METRICS_TAG_VERTICAL_CARET_RUN: vertical caret run.
+ * @HB_OT_METRICS_TAG_VERTICAL_CARET_OFFSET: vertical caret offset.
+ * @HB_OT_METRICS_TAG_X_HEIGHT: x height.
+ * @HB_OT_METRICS_TAG_CAP_HEIGHT: cap height.
+ * @HB_OT_METRICS_TAG_SUBSCRIPT_EM_X_SIZE: subscript em x size.
+ * @HB_OT_METRICS_TAG_SUBSCRIPT_EM_Y_SIZE: subscript em y size.
+ * @HB_OT_METRICS_TAG_SUBSCRIPT_EM_X_OFFSET: subscript em x offset.
+ * @HB_OT_METRICS_TAG_SUBSCRIPT_EM_Y_OFFSET: subscript em y offset.
+ * @HB_OT_METRICS_TAG_SUPERSCRIPT_EM_X_SIZE: superscript em x size.
+ * @HB_OT_METRICS_TAG_SUPERSCRIPT_EM_Y_SIZE: superscript em y size.
+ * @HB_OT_METRICS_TAG_SUPERSCRIPT_EM_X_OFFSET: superscript em x offset.
+ * @HB_OT_METRICS_TAG_SUPERSCRIPT_EM_Y_OFFSET: superscript em y offset.
+ * @HB_OT_METRICS_TAG_STRIKEOUT_SIZE: strikeout size.
+ * @HB_OT_METRICS_TAG_STRIKEOUT_OFFSET: strikeout offset.
+ * @HB_OT_METRICS_TAG_UNDERLINE_SIZE: underline size.
+ * @HB_OT_METRICS_TAG_UNDERLINE_OFFSET: underline offset.
+ *
+ * From https://docs.microsoft.com/en-us/typography/opentype/spec/mvar#value-tags
+ *
+ * Since: 2.6.0
+ **/
+typedef enum {
+  HB_OT_METRICS_TAG_HORIZONTAL_ASCENDER                = HB_TAG ('h','a','s','c'),
+  HB_OT_METRICS_TAG_HORIZONTAL_DESCENDER       = HB_TAG ('h','d','s','c'),
+  HB_OT_METRICS_TAG_HORIZONTAL_LINE_GAP                = HB_TAG ('h','l','g','p'),
+  HB_OT_METRICS_TAG_HORIZONTAL_CLIPPING_ASCENT = HB_TAG ('h','c','l','a'),
+  HB_OT_METRICS_TAG_HORIZONTAL_CLIPPING_DESCENT        = HB_TAG ('h','c','l','d'),
+  HB_OT_METRICS_TAG_VERTICAL_ASCENDER          = HB_TAG ('v','a','s','c'),
+  HB_OT_METRICS_TAG_VERTICAL_DESCENDER         = HB_TAG ('v','d','s','c'),
+  HB_OT_METRICS_TAG_VERTICAL_LINE_GAP          = HB_TAG ('v','l','g','p'),
+  HB_OT_METRICS_TAG_HORIZONTAL_CARET_RISE      = HB_TAG ('h','c','r','s'),
+  HB_OT_METRICS_TAG_HORIZONTAL_CARET_RUN       = HB_TAG ('h','c','r','n'),
+  HB_OT_METRICS_TAG_HORIZONTAL_CARET_OFFSET    = HB_TAG ('h','c','o','f'),
+  HB_OT_METRICS_TAG_VERTICAL_CARET_RISE                = HB_TAG ('v','c','r','s'),
+  HB_OT_METRICS_TAG_VERTICAL_CARET_RUN         = HB_TAG ('v','c','r','n'),
+  HB_OT_METRICS_TAG_VERTICAL_CARET_OFFSET      = HB_TAG ('v','c','o','f'),
+  HB_OT_METRICS_TAG_X_HEIGHT                   = HB_TAG ('x','h','g','t'),
+  HB_OT_METRICS_TAG_CAP_HEIGHT                 = HB_TAG ('c','p','h','t'),
+  HB_OT_METRICS_TAG_SUBSCRIPT_EM_X_SIZE                = HB_TAG ('s','b','x','s'),
+  HB_OT_METRICS_TAG_SUBSCRIPT_EM_Y_SIZE                = HB_TAG ('s','b','y','s'),
+  HB_OT_METRICS_TAG_SUBSCRIPT_EM_X_OFFSET      = HB_TAG ('s','b','x','o'),
+  HB_OT_METRICS_TAG_SUBSCRIPT_EM_Y_OFFSET      = HB_TAG ('s','b','y','o'),
+  HB_OT_METRICS_TAG_SUPERSCRIPT_EM_X_SIZE      = HB_TAG ('s','p','x','s'),
+  HB_OT_METRICS_TAG_SUPERSCRIPT_EM_Y_SIZE      = HB_TAG ('s','p','y','s'),
+  HB_OT_METRICS_TAG_SUPERSCRIPT_EM_X_OFFSET    = HB_TAG ('s','p','x','o'),
+  HB_OT_METRICS_TAG_SUPERSCRIPT_EM_Y_OFFSET    = HB_TAG ('s','p','y','o'),
+  HB_OT_METRICS_TAG_STRIKEOUT_SIZE             = HB_TAG ('s','t','r','s'),
+  HB_OT_METRICS_TAG_STRIKEOUT_OFFSET           = HB_TAG ('s','t','r','o'),
+  HB_OT_METRICS_TAG_UNDERLINE_SIZE             = HB_TAG ('u','n','d','s'),
+  HB_OT_METRICS_TAG_UNDERLINE_OFFSET           = HB_TAG ('u','n','d','o'),
+
+  _HB_OT_METRICS_TAG_MAX_VALUE = HB_TAG_MAX_SIGNED /*< skip >*/
+} hb_ot_metrics_tag_t;
+
+HB_EXTERN hb_bool_t
+hb_ot_metrics_get_position (hb_font_t           *font,
+                           hb_ot_metrics_tag_t  metrics_tag,
+                           hb_position_t       *position     /* OUT.  May be NULL. */);
+
+HB_EXTERN float
+hb_ot_metrics_get_variation (hb_font_t *font, hb_ot_metrics_tag_t metrics_tag);
+
+HB_EXTERN hb_position_t
+hb_ot_metrics_get_x_variation (hb_font_t *font, hb_ot_metrics_tag_t metrics_tag);
+
+HB_EXTERN hb_position_t
+hb_ot_metrics_get_y_variation (hb_font_t *font, hb_ot_metrics_tag_t metrics_tag);
+
+HB_END_DECLS
+
+#endif /* HB_OT_METRICS_H */
similarity index 73%
rename from src/hb-subset-glyf.hh
rename to src/hb-ot-metrics.hh
index 99cf8f0..19a5e9e 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright © 2018  Google, Inc.
+ * Copyright © 2018  Ebrahim Byagowi
  *
  *  This is part of HarfBuzz, a text shaping library.
  *
  * FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS
  * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
  * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
- *
- * Google Author(s): Garret Rieger
  */
 
-#ifndef HB_SUBSET_GLYF_HH
-#define HB_SUBSET_GLYF_HH
+#ifndef HB_OT_METRICS_HH
+#define HB_OT_METRICS_HH
 
 #include "hb.hh"
 
-#include "hb-subset.hh"
-
 HB_INTERNAL bool
-hb_subset_glyf_and_loca (hb_subset_plan_t *plan,
-                        bool             *use_short_loca, /* OUT */
-                        hb_blob_t       **glyf_prime      /* OUT */,
-                        hb_blob_t       **loca_prime      /* OUT */);
+_hb_ot_metrics_get_position_common (hb_font_t           *font,
+                                   hb_ot_metrics_tag_t  metrics_tag,
+                                   hb_position_t       *position     /* OUT.  May be NULL. */);
 
-#endif /* HB_SUBSET_GLYF_HH */
+#endif /* HB_OT_METRICS_HH */
similarity index 98%
rename from src/hb-ot-name-language.cc
rename to src/hb-ot-name-language-static.hh
index 0e37e0a..580e763 100644 (file)
@@ -24,6 +24,9 @@
  * Google Author(s): Behdad Esfahbod
  */
 
+#ifndef HB_OT_NAME_LANGUAGE_STATIC_HH
+#define HB_OT_NAME_LANGUAGE_STATIC_HH
+
 #include "hb-ot-name-language.hh"
 
 /* Following two tables were generated by joining FreeType, FontConfig,
@@ -427,6 +430,9 @@ _hb_ot_name_language_for (unsigned int code,
                          const hb_ot_language_map_t *array,
                          unsigned int len)
 {
+#ifdef HB_NO_OT_NAME_LANGUAGE
+  return HB_LANGUAGE_INVALID;
+#endif
   const hb_ot_language_map_t *entry = (const hb_ot_language_map_t *)
                                      hb_bsearch (&code,
                                                  array,
@@ -455,3 +461,5 @@ _hb_ot_name_language_for_mac_code (unsigned int code)
                                   hb_mac_language_map,
                                   ARRAY_LENGTH (hb_mac_language_map));
 }
+
+#endif /* HB_OT_NAME_LANGUAGE_STATIC_HH */
index c8ababd..84be04c 100644 (file)
@@ -51,6 +51,7 @@ 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;
 
@@ -60,9 +61,12 @@ struct NameRecord
     if (p == 1)
       return _hb_ot_name_language_for_mac_code (l);
 
+#ifndef HB_NO_OT_NAME_LANGUAGE_AAT
     if (p == 0)
-      return _hb_aat_language_get (face, l);
+      return face->table.ltag->get_language (l);
+#endif
 
+#endif
     return HB_LANGUAGE_INVALID;
   }
 
@@ -93,11 +97,21 @@ struct NameRecord
     return UNSUPPORTED;
   }
 
+  NameRecord* copy (hb_serialize_context_t *c,
+                   const void *src_base,
+                   const void *dst_base) const
+  {
+    TRACE_SERIALIZE (this);
+    auto *out = c->embed (this);
+    if (unlikely (!out)) return_trace (nullptr);
+    out->offset.serialize_copy (c, offset, src_base, dst_base, length);
+    return_trace (out);
+  }
+
   bool sanitize (hb_sanitize_context_t *c, const void *base) const
   {
     TRACE_SANITIZE (this);
-    /* We can check from base all the way up to the end of string... */
-    return_trace (c->check_struct (this) && c->check_range ((char *) base, (unsigned int) length + offset));
+    return_trace (c->check_struct (this) && offset.sanitize (c, base, length));
   }
 
   HBUINT16     platformID;     /* Platform ID. */
@@ -105,7 +119,8 @@ struct NameRecord
   HBUINT16     languageID;     /* Language ID. */
   HBUINT16     nameID;         /* Name ID. */
   HBUINT16     length;         /* String length (in bytes). */
-  HBUINT16     offset;         /* String offset from start of storage area (in bytes). */
+  NNOffsetTo<UnsizedArrayOf<HBUINT8>>
+               offset;         /* String offset from start of storage area (in bytes). */
   public:
   DEFINE_SIZE_STATIC (12);
 };
@@ -156,15 +171,56 @@ struct 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)
+  {
+    TRACE_SERIALIZE (this);
+
+    if (unlikely (!c->extend_min ((*this))))  return_trace (false);
+
+    this->format = 0;
+    this->count = it.len ();
+
+    auto snap = c->snapshot ();
+    this->nameRecordZ.serialize (c, this->count);
+    if (unlikely (!c->check_assign (this->stringOffset, c->length ()))) return_trace (false);
+    c->revert (snap);
+
+    const void *dst_string_pool = &(this + this->stringOffset);
+
+    for (const auto &_ : it) c->copy (_, src_string_pool, dst_string_pool);
+
+    if (unlikely (c->ran_out_of_room)) return_trace (false);
+
+    assert (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);
+
+    auto it =
+    + nameRecordZ.as_array (count)
+    | hb_filter (c->plan->name_ids, &NameRecord::nameID)
+    ;
+
+    name_prime->serialize (c->serializer, it, hb_addressof (this + stringOffset));
+    return_trace (name_prime->count);
+  }
+
   bool sanitize_records (hb_sanitize_context_t *c) const
   {
     TRACE_SANITIZE (this);
     const void *string_pool = (this+stringOffset).arrayZ;
-    unsigned int _count = count;
-    /* Move to run-time?! */
-    for (unsigned int i = 0; i < _count; i++)
-      if (!nameRecordZ[i].sanitize (c, string_pool)) return_trace (false);
-    return_trace (true);
+    return_trace (nameRecordZ.sanitize (c, count, string_pool));
   }
 
   bool sanitize (hb_sanitize_context_t *c) const
@@ -173,7 +229,8 @@ struct name
     return_trace (c->check_struct (this) &&
                  likely (format == 0 || format == 1) &&
                  c->check_array (nameRecordZ.arrayZ, count) &&
-                 c->check_range (this, stringOffset));
+                 c->check_range (this, stringOffset) &&
+                 sanitize_records (c));
   }
 
   struct accelerator_t
@@ -206,10 +263,10 @@ struct name
       unsigned int j = 0;
       for (unsigned int i = 0; i < this->names.length; i++)
       {
-        if (this->names[i].entry_score == UNSUPPORTED ||
+       if (this->names[i].entry_score == UNSUPPORTED ||
            this->names[i].language == HB_LANGUAGE_INVALID)
          continue;
-        if (i &&
+       if (i &&
            this->names[i - 1].name_id  == this->names[i].name_id &&
            this->names[i - 1].language == this->names[i].language)
          continue;
@@ -236,10 +293,10 @@ struct name
                                                    sizeof (key),
                                                    _hb_ot_name_entry_cmp_key);
       if (!entry)
-        return -1;
+       return -1;
 
       if (width)
-        *width = entry->entry_score < 10 ? 2 : 1;
+       *width = entry->entry_score < 10 ? 2 : 1;
 
       return entry->entry_index;
     }
@@ -263,7 +320,7 @@ struct name
   /* We only implement format 0 for now. */
   HBUINT16     format;                 /* Format selector (=0/1). */
   HBUINT16     count;                  /* Number of name records. */
-  NNOffsetTo<UnsizedArrayOf<HBUINT8> >
+  NNOffsetTo<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. */
@@ -271,6 +328,9 @@ struct name
   DEFINE_SIZE_ARRAY (6, nameRecordZ);
 };
 
+#undef entry_index
+#undef entry_score
+
 struct name_accelerator_t : name::accelerator_t {};
 
 } /* namespace OT */
index 907ae6a..10122b8 100644 (file)
 
 #include "hb.hh"
 
+#ifndef HB_NO_NAME
+
 #include "hb-ot-name-table.hh"
 
-#include "hb-ot-face.hh"
 #include "hb-utf.hh"
 
 
@@ -89,11 +90,11 @@ hb_ot_name_convert_utf (hb_bytes_t                       bytes,
       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. */
+       break; /* Out-of-room. */
 
       dst = dst_next;
       src = src_next;
-    };
+    }
 
     *text_size = dst - text;
     *dst = 0; /* NUL-terminate. */
@@ -105,7 +106,7 @@ hb_ot_name_convert_utf (hb_bytes_t                       bytes,
   {
     src = in_utf_t::next (src, src_end, &unicode, replacement);
     dst_len += out_utf_t::encode_len (unicode);
-  };
+  }
   return dst_len;
 }
 
@@ -222,3 +223,6 @@ hb_ot_name_get_utf32 (hb_face_t       *face,
 {
   return hb_ot_name_get_utf<hb_utf32_t> (face, name_id, language, text_size, text);
 }
+
+
+#endif
index 68dd63e..f6b1503 100644 (file)
@@ -59,6 +59,10 @@ struct OS2V1Tail
 
 struct OS2V2Tail
 {
+  bool has_data () const { return sxHeight || sCapHeight; }
+
+  const OS2V2Tail * operator -> () const { return this; }
+
   bool sanitize (hb_sanitize_context_t *c) const
   {
     TRACE_SANITIZE (this);
@@ -77,6 +81,23 @@ struct OS2V2Tail
 
 struct OS2V5Tail
 {
+  inline bool get_optical_size (unsigned int *lower, unsigned int *upper) const
+  {
+    unsigned int lower_optical_size = usLowerOpticalPointSize;
+    unsigned int upper_optical_size = usUpperOpticalPointSize;
+
+    /* Per https://docs.microsoft.com/en-us/typography/opentype/spec/os2#lps */
+    if (lower_optical_size < upper_optical_size &&
+       lower_optical_size >= 1 && lower_optical_size <= 0xFFFE &&
+       upper_optical_size >= 2 && upper_optical_size <= 0xFFFF)
+    {
+      *lower = lower_optical_size;
+      *upper = upper_optical_size;
+      return true;
+    }
+    return false;
+  }
+
   bool sanitize (hb_sanitize_context_t *c) const
   {
     TRACE_SANITIZE (this);
@@ -94,7 +115,7 @@ struct OS2
 {
   static constexpr hb_tag_t tableTag = HB_OT_TAG_OS2;
 
-  bool has_data () const { return this != &Null (OS2); }
+  bool has_data () const { return usWeightClass || usWidthClass || usFirstCharIndex || usLastCharIndex; }
 
   const OS2V1Tail &v1 () const { return version >= 1 ? v1X : Null (OS2V1Tail); }
   const OS2V2Tail &v2 () const { return version >= 2 ? v2X : Null (OS2V2Tail); }
@@ -113,9 +134,9 @@ struct OS2
     OBLIQUE            = 1u<<9
   };
 
-  bool is_italic () const       { return fsSelection & ITALIC; }
-  bool is_oblique () const      { return fsSelection & OBLIQUE; }
-  bool is_typo_metrics () const { return fsSelection & USE_TYPO_METRICS; }
+  bool        is_italic () const { return fsSelection & ITALIC; }
+  bool       is_oblique () const { return fsSelection & OBLIQUE; }
+  bool use_typo_metrics () const { return fsSelection & USE_TYPO_METRICS; }
 
   enum width_class_t {
     FWIDTH_ULTRA_CONDENSED     = 1, /* 50% */
@@ -145,36 +166,28 @@ struct OS2
     }
   }
 
-  bool subset (hb_subset_plan_t *plan) const
+  bool subset (hb_subset_context_t *c) const
   {
-    hb_blob_t *os2_blob = hb_sanitize_context_t ().reference_table<OS2> (plan->source);
-    hb_blob_t *os2_prime_blob = hb_blob_create_sub_blob (os2_blob, 0, -1);
-    // TODO(grieger): move to hb_blob_copy_writable_or_fail
-    hb_blob_destroy (os2_blob);
-
-    OS2 *os2_prime = (OS2 *) hb_blob_get_data_writable (os2_prime_blob, nullptr);
-    if (unlikely (!os2_prime)) {
-      hb_blob_destroy (os2_prime_blob);
-      return false;
-    }
+    TRACE_SUBSET (this);
+    OS2 *os2_prime = c->serializer->embed (this);
+    if (unlikely (!os2_prime)) return_trace (false);
 
     uint16_t min_cp, max_cp;
-    find_min_and_max_codepoint (plan->unicodes, &min_cp, &max_cp);
-    os2_prime->usFirstCharIndex.set (min_cp);
-    os2_prime->usLastCharIndex.set (max_cp);
+    find_min_and_max_codepoint (c->plan->unicodes, &min_cp, &max_cp);
+    os2_prime->usFirstCharIndex = min_cp;
+    os2_prime->usLastCharIndex = max_cp;
 
-    _update_unicode_ranges (plan->unicodes, os2_prime->ulUnicodeRange);
-    bool result = plan->add_table (HB_OT_TAG_OS2, os2_prime_blob);
+    _update_unicode_ranges (c->plan->unicodes, os2_prime->ulUnicodeRange);
 
-    hb_blob_destroy (os2_prime_blob);
-    return result;
+    return_trace (true);
   }
 
   void _update_unicode_ranges (const hb_set_t *codepoints,
                               HBUINT32 ulUnicodeRange[4]) const
   {
+    HBUINT32   newBits[4];
     for (unsigned int i = 0; i < 4; i++)
-      ulUnicodeRange[i].set (0);
+      newBits[i] = 0;
 
     hb_codepoint_t cp = HB_SET_VALUE_INVALID;
     while (codepoints->next (&cp)) {
@@ -184,26 +197,30 @@ struct OS2
        unsigned int block = bit / 32;
        unsigned int bit_in_block = bit % 32;
        unsigned int mask = 1 << bit_in_block;
-       ulUnicodeRange[block].set (ulUnicodeRange[block] | mask);
+       newBits[block] = newBits[block] | mask;
       }
       if (cp >= 0x10000 && cp <= 0x110000)
       {
        /* the spec says that bit 57 ("Non Plane 0") implies that there's
           at least one codepoint beyond the BMP; so I also include all
           the non-BMP codepoints here */
-       ulUnicodeRange[1].set (ulUnicodeRange[1] | (1 << 25));
+       newBits[1] = newBits[1] | (1 << 25);
       }
     }
+
+    for (unsigned int i = 0; i < 4; i++)
+      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 */)
+                                         uint16_t *min_cp, /* OUT */
+                                         uint16_t *max_cp  /* OUT */)
   {
     *min_cp = codepoints->get_min ();
     *max_cp = codepoints->get_max ();
   }
 
+  /* https://github.com/Microsoft/Font-Validator/blob/520aaae/OTFontFileVal/val_OS2.cs#L644-L681 */
   enum font_page_t {
     HEBREW_FONT_PAGE           = 0xB100, // Hebrew Windows 3.1 font page
     SIMP_ARABIC_FONT_PAGE      = 0xB200, // Simplified Arabic Windows 3.1 font page
@@ -213,11 +230,18 @@ struct OS2
     TRAD_FARSI_FONT_PAGE       = 0xBB00, // Traditional Farsi Windows 3.1 font page
     THAI_FONT_PAGE             = 0xDE00  // Thai Windows 3.1 font page
   };
-
-  // https://github.com/Microsoft/Font-Validator/blob/520aaae/OTFontFileVal/val_OS2.cs#L644-L681
   font_page_t get_font_page () const
   { return (font_page_t) (version == 0 ? fsSelection & 0xFF00 : 0); }
 
+  unsigned get_size () const
+  {
+    unsigned result = min_size;
+    if (version >= 1) result += v1X.get_size ();
+    if (version >= 2) result += v2X.get_size ();
+    if (version >= 5) result += v5X.get_size ();
+    return result;
+  }
+
   bool sanitize (hb_sanitize_context_t *c) const
   {
     TRACE_SANITIZE (this);
index 43c1143..38302f5 100644 (file)
@@ -73,26 +73,25 @@ struct post
 {
   static constexpr hb_tag_t tableTag = HB_OT_TAG_post;
 
-  bool subset (hb_subset_plan_t *plan) const
+  void serialize (hb_serialize_context_t *c) const
   {
-    unsigned int post_prime_length;
-    hb_blob_t *post_blob = hb_sanitize_context_t ().reference_table<post>(plan->source);
-    hb_blob_t *post_prime_blob = hb_blob_create_sub_blob (post_blob, 0, post::min_size);
-    post *post_prime = (post *) hb_blob_get_data_writable (post_prime_blob, &post_prime_length);
-    hb_blob_destroy (post_blob);
+    post *post_prime = c->allocate_min<post> ();
+    if (unlikely (!post_prime))  return;
 
-    if (unlikely (!post_prime || post_prime_length != post::min_size))
-    {
-      hb_blob_destroy (post_prime_blob);
-      DEBUG_MSG(SUBSET, nullptr, "Invalid source post table with length %d.", post_prime_length);
-      return false;
-    }
+    memcpy (post_prime, this, post::min_size);
+    post_prime->version.major = 3; // Version 3 does not have any glyph names.
+  }
+
+  bool subset (hb_subset_context_t *c) const
+  {
+    TRACE_SUBSET (this);
+    post *post_prime = c->serializer->start_embed<post> ();
+    if (unlikely (!post_prime)) return_trace (false);
 
-    post_prime->version.major.set (3); // Version 3 does not have any glyph names.
-    bool result = plan->add_table (HB_OT_TAG_post, post_prime_blob);
-    hb_blob_destroy (post_prime_blob);
+    serialize (c->serializer);
+    if (c->serializer->in_error () || c->serializer->ran_out_of_room) return_trace (false);
 
-    return result;
+    return_trace (true);
   }
 
   struct accelerator_t
@@ -131,7 +130,7 @@ struct post
       hb_bytes_t s = find_glyph_name (glyph);
       if (!s.length) return false;
       if (!buf_len) return true;
-      unsigned int len = MIN (buf_len - 1, s.length);
+      unsigned int len = hb_min (buf_len - 1, s.length);
       strncpy (buf, s.arrayZ, len);
       buf[len] = '\0';
       return true;
@@ -158,7 +157,7 @@ struct post
 
        for (unsigned int i = 0; i < count; i++)
          gids[i] = i;
-       hb_sort_r (gids, count, sizeof (gids[0]), cmp_gids, (void *) this);
+       hb_qsort (gids, count, sizeof (gids[0]), cmp_gids, (void *) this);
 
        if (unlikely (!gids_sorted_by_name.cmpexch (nullptr, gids)))
        {
@@ -168,8 +167,8 @@ struct post
       }
 
       hb_bytes_t st (name, len);
-      const uint16_t *gid = (const uint16_t *) hb_bsearch_r (hb_addressof (st), gids, count,
-                                                            sizeof (gids[0]), cmp_key, (void *) this);
+      const uint16_t *gid = (const uint16_t *) hb_bsearch (hb_addressof (st), gids, count,
+                                                          sizeof (gids[0]), cmp_key, (void *) this);
       if (gid)
       {
        *glyph = *gid;
@@ -179,6 +178,8 @@ struct post
       return false;
     }
 
+    hb_blob_ptr_t<post> table;
+
     protected:
 
     unsigned int get_glyph_count () const
@@ -238,7 +239,6 @@ struct post
     }
 
     private:
-    hb_blob_ptr_t<post> table;
     uint32_t version;
     const ArrayOf<HBUINT16> *glyphNameIndex;
     hb_vector_t<uint32_t> index_to_offset;
@@ -246,6 +246,8 @@ struct post
     hb_atomic_ptr_t<uint16_t *> gids_sorted_by_name;
   };
 
+  bool has_data () const { return version.to_int (); }
+
   bool sanitize (hb_sanitize_context_t *c) const
   {
     TRACE_SANITIZE (this);
@@ -260,7 +262,7 @@ struct post
                                         * 0x00020000 for version 2.0
                                         * 0x00025000 for version 2.5 (deprecated)
                                         * 0x00030000 for version 3.0 */
-  Fixed                italicAngle;            /* Italic angle in counter-clockwise degrees
+  HBFixed              italicAngle;            /* Italic angle in counter-clockwise degrees
                                         * from the vertical. Zero for upright text,
                                         * negative for text that leans to the right
                                         * (forward). */
index 2a1f2f8..2a7a8eb 100644 (file)
@@ -49,8 +49,8 @@ arabic_fallback_synthesize_lookup_single (const hb_ot_shape_plan_t *plan HB_UNUS
                                          hb_font_t *font,
                                          unsigned int feature_index)
 {
-  OT::GlyphID glyphs[SHAPING_TABLE_LAST - SHAPING_TABLE_FIRST + 1];
-  OT::GlyphID substitutes[SHAPING_TABLE_LAST - SHAPING_TABLE_FIRST + 1];
+  OT::HBGlyphID glyphs[SHAPING_TABLE_LAST - SHAPING_TABLE_FIRST + 1];
+  OT::HBGlyphID substitutes[SHAPING_TABLE_LAST - SHAPING_TABLE_FIRST + 1];
   unsigned int num_glyphs = 0;
 
   /* Populate arrays */
@@ -66,8 +66,8 @@ arabic_fallback_synthesize_lookup_single (const hb_ot_shape_plan_t *plan HB_UNUS
        u_glyph > 0xFFFFu || s_glyph > 0xFFFFu)
       continue;
 
-    glyphs[num_glyphs].set (u_glyph);
-    substitutes[num_glyphs].set (s_glyph);
+    glyphs[num_glyphs] = u_glyph;
+    substitutes[num_glyphs] = s_glyph;
 
     num_glyphs++;
   }
@@ -77,7 +77,9 @@ arabic_fallback_synthesize_lookup_single (const hb_ot_shape_plan_t *plan HB_UNUS
 
   /* Bubble-sort or something equally good!
    * May not be good-enough for presidential candidate interviews, but good-enough for us... */
-  hb_stable_sort (&glyphs[0], num_glyphs, (int(*)(const OT::GlyphID*, const OT::GlyphID *)) OT::GlyphID::cmp, &substitutes[0]);
+  hb_stable_sort (&glyphs[0], num_glyphs,
+                 (int(*)(const OT::HBUINT16*, const OT::HBUINT16 *)) OT::HBGlyphID::cmp,
+                 &substitutes[0]);
 
 
   /* Each glyph takes four bytes max, and there's some overhead. */
@@ -86,10 +88,9 @@ arabic_fallback_synthesize_lookup_single (const hb_ot_shape_plan_t *plan HB_UNUS
   OT::SubstLookup *lookup = c.start_serialize<OT::SubstLookup> ();
   bool ret = lookup->serialize_single (&c,
                                       OT::LookupFlag::IgnoreMarks,
-                                      hb_array (glyphs, num_glyphs),
+                                      hb_sorted_array (glyphs, num_glyphs),
                                       hb_array (substitutes, num_glyphs));
   c.end_serialize ();
-  /* TODO sanitize the results? */
 
   return ret ? c.copy<OT::SubstLookup> () : nullptr;
 }
@@ -98,15 +99,15 @@ static OT::SubstLookup *
 arabic_fallback_synthesize_lookup_ligature (const hb_ot_shape_plan_t *plan HB_UNUSED,
                                            hb_font_t *font)
 {
-  OT::GlyphID first_glyphs[ARRAY_LENGTH_CONST (ligature_table)];
+  OT::HBGlyphID first_glyphs[ARRAY_LENGTH_CONST (ligature_table)];
   unsigned int first_glyphs_indirection[ARRAY_LENGTH_CONST (ligature_table)];
   unsigned int ligature_per_first_glyph_count_list[ARRAY_LENGTH_CONST (first_glyphs)];
   unsigned int num_first_glyphs = 0;
 
   /* We know that all our ligatures are 2-component */
-  OT::GlyphID ligature_list[ARRAY_LENGTH_CONST (first_glyphs) * ARRAY_LENGTH_CONST(ligature_table[0].ligatures)];
+  OT::HBGlyphID ligature_list[ARRAY_LENGTH_CONST (first_glyphs) * ARRAY_LENGTH_CONST(ligature_table[0].ligatures)];
   unsigned int component_count_list[ARRAY_LENGTH_CONST (ligature_list)];
-  OT::GlyphID component_list[ARRAY_LENGTH_CONST (ligature_list) * 1/* One extra component per ligature */];
+  OT::HBGlyphID component_list[ARRAY_LENGTH_CONST (ligature_list) * 1/* One extra component per ligature */];
   unsigned int num_ligatures = 0;
 
   /* Populate arrays */
@@ -118,12 +119,14 @@ arabic_fallback_synthesize_lookup_ligature (const hb_ot_shape_plan_t *plan HB_UN
     hb_codepoint_t first_glyph;
     if (!hb_font_get_glyph (font, first_u, 0, &first_glyph))
       continue;
-    first_glyphs[num_first_glyphs].set (first_glyph);
+    first_glyphs[num_first_glyphs] = first_glyph;
     ligature_per_first_glyph_count_list[num_first_glyphs] = 0;
     first_glyphs_indirection[num_first_glyphs] = first_glyph_idx;
     num_first_glyphs++;
   }
-  hb_stable_sort (&first_glyphs[0], num_first_glyphs, (int(*)(const OT::GlyphID*, const OT::GlyphID *)) OT::GlyphID::cmp, &first_glyphs_indirection[0]);
+  hb_stable_sort (&first_glyphs[0], num_first_glyphs,
+                 (int(*)(const OT::HBUINT16*, const OT::HBUINT16 *)) OT::HBGlyphID::cmp,
+                 &first_glyphs_indirection[0]);
 
   /* Now that the first-glyphs are sorted, walk again, populate ligatures. */
   for (unsigned int i = 0; i < num_first_glyphs; i++)
@@ -142,9 +145,9 @@ arabic_fallback_synthesize_lookup_ligature (const hb_ot_shape_plan_t *plan HB_UN
 
       ligature_per_first_glyph_count_list[i]++;
 
-      ligature_list[num_ligatures].set (ligature_glyph);
+      ligature_list[num_ligatures] = ligature_glyph;
       component_count_list[num_ligatures] = 2;
-      component_list[num_ligatures].set (second_glyph);
+      component_list[num_ligatures] = second_glyph;
       num_ligatures++;
     }
   }
@@ -159,7 +162,7 @@ arabic_fallback_synthesize_lookup_ligature (const hb_ot_shape_plan_t *plan HB_UN
   OT::SubstLookup *lookup = c.start_serialize<OT::SubstLookup> ();
   bool ret = lookup->serialize_ligature (&c,
                                         OT::LookupFlag::IgnoreMarks,
-                                        hb_array (first_glyphs, num_first_glyphs),
+                                        hb_sorted_array (first_glyphs, num_first_glyphs),
                                         hb_array (ligature_per_first_glyph_count_list, num_first_glyphs),
                                         hb_array (ligature_list, num_ligatures),
                                         hb_array (component_count_list, num_ligatures),
@@ -227,8 +230,8 @@ arabic_fallback_plan_init_win1256 (arabic_fallback_plan_t *fallback_plan HB_UNUS
     return false;
 
   const Manifest &manifest = reinterpret_cast<const Manifest&> (arabic_win1256_gsub_lookups.manifest);
-  static_assert (sizeof (arabic_win1256_gsub_lookups.manifestData) / sizeof (ManifestLookup)
-                <= ARABIC_FALLBACK_MAX_LOOKUPS, "");
+  static_assert (sizeof (arabic_win1256_gsub_lookups.manifestData) ==
+                ARABIC_FALLBACK_MAX_LOOKUPS * sizeof (ManifestLookup), "");
   /* TODO sanitize the table? */
 
   unsigned j = 0;
index bdebde0..f92e637 100644 (file)
@@ -25,6 +25,9 @@
  */
 
 #include "hb.hh"
+
+#ifndef HB_NO_OT_SHAPE
+
 #include "hb-ot-shape-complex-arabic.hh"
 #include "hb-ot-shape.hh"
 
@@ -383,6 +386,10 @@ arabic_fallback_shape (const hb_ot_shape_plan_t *plan,
                       hb_font_t *font,
                       hb_buffer_t *buffer)
 {
+#ifdef HB_NO_OT_SHAPE_COMPLEX_ARABIC_FALLBACK
+  return;
+#endif
+
   const arabic_shape_plan_t *arabic_plan = (const arabic_shape_plan_t *) plan->data;
 
   if (!arabic_plan->do_fallback)
@@ -469,13 +476,13 @@ apply_stch (const hb_ot_shape_plan_t *plan HB_UNUSED,
     {
       if (!hb_in_range<uint8_t> (info[i - 1].arabic_shaping_action(), STCH_FIXED, STCH_REPEATING))
       {
-        if (step == CUT)
+       if (step == CUT)
        {
          --j;
          info[j] = info[i - 1];
          pos[j] = pos[i - 1];
        }
-        continue;
+       continue;
       }
 
       /* Yay, justification! */
@@ -533,10 +540,10 @@ apply_stch (const hb_ot_shape_plan_t *plan HB_UNUSED,
       hb_position_t shortfall = sign * w_remaining - sign * w_repeating * (n_copies + 1);
       if (shortfall > 0 && n_repeating > 0)
       {
-        ++n_copies;
-        hb_position_t excess = (n_copies + 1) * sign * w_repeating - sign * w_remaining;
-        if (excess > 0)
-          extra_repeat_overlap = excess / (n_copies * n_repeating);
+       ++n_copies;
+       hb_position_t excess = (n_copies + 1) * sign * w_repeating - sign * w_remaining;
+       if (excess > 0)
+         extra_repeat_overlap = excess / (n_copies * n_repeating);
       }
 
       if (step == MEASURE)
@@ -576,7 +583,7 @@ apply_stch (const hb_ot_shape_plan_t *plan HB_UNUSED,
     if (step == MEASURE)
     {
       if (unlikely (!buffer->ensure (count + extra_glyphs_needed)))
-        break;
+       break;
     }
     else
     {
@@ -706,3 +713,6 @@ const hb_ot_complex_shaper_t _hb_ot_complex_shaper_arabic =
   HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_GDEF_LATE,
   true, /* fallback_position */
 };
+
+
+#endif
index 97923ec..a921f16 100644 (file)
  * Google Author(s): Behdad Esfahbod
  */
 
+#include "hb.hh"
+
+#ifndef HB_NO_OT_SHAPE
+
 #include "hb-ot-shape-complex.hh"
 
 
@@ -44,3 +48,6 @@ const hb_ot_complex_shaper_t _hb_ot_complex_shaper_default =
   HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_GDEF_LATE,
   true, /* fallback_position */
 };
+
+
+#endif
index f084f6a..f5915f4 100644 (file)
  * Google Author(s): Behdad Esfahbod
  */
 
+#include "hb.hh"
+
+#ifndef HB_NO_OT_SHAPE
+
 #include "hb-ot-shape-complex.hh"
 
 
@@ -200,7 +204,7 @@ preprocess_text_hangul (const hb_ot_shape_plan_t *plan HB_UNUSED,
       if (start < end && end == buffer->out_len)
       {
        /* Tone mark follows a valid syllable; move it in front, unless it's zero width. */
-        buffer->unsafe_to_break_from_outbuffer (start, buffer->idx);
+       buffer->unsafe_to_break_from_outbuffer (start, buffer->idx);
        buffer->next_glyph ();
        if (!is_zero_width_char (font, u))
        {
@@ -350,9 +354,9 @@ preprocess_text_hangul (const hb_ot_shape_plan_t *plan HB_UNUSED,
           */
          if (has_glyph && !tindex)
          {
-            buffer->next_glyph ();
-            s_len++;
-          }
+           buffer->next_glyph ();
+           s_len++;
+         }
 
          if (unlikely (!buffer->successful))
            return;
@@ -361,7 +365,7 @@ preprocess_text_hangul (const hb_ot_shape_plan_t *plan HB_UNUSED,
           * that are now in buffer->out_info.
           */
          hb_glyph_info_t *info = buffer->out_info;
-          end = start + s_len;
+         end = start + s_len;
 
          unsigned int i = start;
          info[i++].hangul_shaping_feature() = LJMO;
@@ -379,7 +383,7 @@ preprocess_text_hangul (const hb_ot_shape_plan_t *plan HB_UNUSED,
 
       if (has_glyph)
       {
-        /* We didn't decompose the S, so just advance past it. */
+       /* We didn't decompose the S, so just advance past it. */
        end = start + 1;
        buffer->next_glyph ();
        continue;
@@ -430,3 +434,6 @@ const hb_ot_complex_shaper_t _hb_ot_complex_shaper_hangul =
   HB_OT_SHAPE_ZERO_WIDTH_MARKS_NONE,
   false, /* fallback_position */
 };
+
+
+#endif
index 90c36c0..334d3de 100644 (file)
  * Google Author(s): Behdad Esfahbod
  */
 
+#include "hb.hh"
+
+#ifndef HB_NO_OT_SHAPE
+
 #include "hb-ot-shape-complex.hh"
 
 
@@ -70,6 +74,10 @@ compose_hebrew (const hb_ot_shape_normalize_context_t *c,
 
   bool found = (bool) c->unicode->compose (a, b, ab);
 
+#ifdef HB_NO_OT_SHAPE_COMPLEX_HEBREW_FALLBACK
+  return found;
+#endif
+
   if (!found && !c->plan->has_gpos_mark)
   {
       /* Special-case Hebrew presentation forms that are excluded from
@@ -172,3 +180,6 @@ const hb_ot_complex_shaper_t _hb_ot_complex_shaper_hebrew =
   HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_GDEF_LATE,
   true, /* fallback_position */
 };
+
+
+#endif
index 08b90e9..670b6bf 100644 (file)
 
 #line 36 "hb-ot-shape-complex-indic-machine.hh"
 static const unsigned char _indic_syllable_machine_trans_keys[] = {
-       8u, 8u, 4u, 8u, 5u, 7u, 7u, 7u, 5u, 8u, 5u, 7u, 7u, 7u, 5u, 8u, 
-       5u, 7u, 7u, 7u, 5u, 8u, 5u, 7u, 7u, 7u, 4u, 8u, 6u, 6u, 16u, 16u, 
-       4u, 8u, 6u, 6u, 16u, 16u, 4u, 8u, 6u, 6u, 16u, 16u, 4u, 8u, 6u, 6u, 
-       16u, 16u, 4u, 13u, 4u, 8u, 4u, 13u, 4u, 8u, 4u, 13u, 4u, 8u, 4u, 13u, 
-       4u, 8u, 4u, 13u, 8u, 8u, 4u, 8u, 5u, 7u, 7u, 7u, 5u, 8u, 5u, 7u, 
-       7u, 7u, 5u, 8u, 5u, 7u, 7u, 7u, 5u, 8u, 5u, 7u, 7u, 7u, 4u, 8u, 
-       6u, 6u, 16u, 16u, 4u, 8u, 6u, 6u, 16u, 16u, 4u, 8u, 6u, 6u, 16u, 16u, 
-       4u, 8u, 6u, 6u, 16u, 16u, 4u, 13u, 4u, 8u, 4u, 13u, 4u, 8u, 4u, 13u, 
-       4u, 8u, 4u, 13u, 4u, 8u, 4u, 13u, 8u, 8u, 4u, 8u, 5u, 7u, 7u, 7u, 
-       5u, 8u, 5u, 7u, 7u, 7u, 5u, 8u, 5u, 7u, 7u, 7u, 5u, 8u, 5u, 7u, 
-       7u, 7u, 4u, 8u, 6u, 6u, 16u, 16u, 4u, 8u, 6u, 6u, 16u, 16u, 4u, 8u, 
-       6u, 6u, 16u, 16u, 4u, 8u, 6u, 6u, 16u, 16u, 4u, 13u, 4u, 8u, 4u, 13u, 
-       4u, 8u, 4u, 13u, 4u, 8u, 4u, 13u, 4u, 8u, 8u, 8u, 4u, 8u, 5u, 7u, 
-       7u, 7u, 5u, 8u, 5u, 7u, 7u, 7u, 5u, 8u, 5u, 7u, 7u, 7u, 5u, 8u, 
-       5u, 7u, 7u, 7u, 4u, 8u, 6u, 6u, 16u, 16u, 4u, 8u, 6u, 6u, 16u, 16u, 
-       4u, 8u, 6u, 6u, 16u, 16u, 4u, 8u, 6u, 6u, 16u, 16u, 4u, 13u, 4u, 8u, 
-       4u, 13u, 4u, 8u, 4u, 13u, 4u, 8u, 4u, 13u, 4u, 8u, 4u, 13u, 4u, 13u, 
-       5u, 8u, 8u, 8u, 1u, 19u, 3u, 17u, 3u, 17u, 4u, 17u, 1u, 16u, 3u, 17u, 
-       3u, 17u, 4u, 17u, 1u, 16u, 3u, 17u, 3u, 17u, 4u, 17u, 1u, 16u, 3u, 17u, 
-       3u, 17u, 4u, 17u, 1u, 16u, 3u, 17u, 3u, 17u, 4u, 17u, 5u, 10u, 5u, 10u, 
-       5u, 10u, 10u, 10u, 10u, 10u, 10u, 10u, 5u, 10u, 3u, 10u, 5u, 10u, 3u, 10u, 
-       4u, 10u, 5u, 10u, 3u, 10u, 4u, 10u, 5u, 10u, 3u, 10u, 4u, 10u, 5u, 10u, 
-       3u, 10u, 4u, 10u, 4u, 10u, 3u, 17u, 3u, 17u, 1u, 16u, 1u, 16u, 1u, 16u, 
-       3u, 17u, 3u, 17u, 1u, 16u, 1u, 16u, 1u, 16u, 3u, 17u, 3u, 17u, 1u, 16u, 
-       1u, 16u, 1u, 16u, 3u, 17u, 3u, 17u, 1u, 16u, 1u, 16u, 1u, 16u, 3u, 17u, 
-       3u, 17u, 3u, 17u, 3u, 17u, 4u, 17u, 1u, 16u, 3u, 17u, 3u, 17u, 4u, 17u, 
-       1u, 16u, 3u, 17u, 3u, 17u, 4u, 17u, 1u, 16u, 3u, 17u, 3u, 17u, 4u, 17u, 
-       1u, 16u, 3u, 17u, 3u, 17u, 4u, 17u, 5u, 10u, 5u, 10u, 5u, 10u, 10u, 10u, 
-       10u, 10u, 10u, 10u, 5u, 10u, 3u, 10u, 5u, 10u, 3u, 10u, 4u, 10u, 5u, 10u, 
-       3u, 10u, 4u, 10u, 5u, 10u, 3u, 10u, 4u, 10u, 5u, 10u, 3u, 10u, 4u, 10u, 
-       4u, 10u, 3u, 17u, 3u, 17u, 1u, 16u, 1u, 16u, 1u, 16u, 3u, 17u, 3u, 17u, 
-       1u, 16u, 1u, 16u, 1u, 16u, 3u, 17u, 3u, 17u, 1u, 16u, 1u, 16u, 1u, 16u, 
-       3u, 17u, 3u, 17u, 1u, 16u, 1u, 16u, 1u, 16u, 4u, 8u, 3u, 17u, 3u, 17u, 
-       4u, 17u, 1u, 16u, 3u, 17u, 3u, 17u, 4u, 17u, 1u, 16u, 3u, 17u, 3u, 17u, 
-       4u, 17u, 1u, 16u, 3u, 17u, 3u, 17u, 4u, 17u, 1u, 16u, 3u, 17u, 3u, 17u, 
-       4u, 17u, 5u, 10u, 5u, 10u, 5u, 10u, 10u, 10u, 10u, 10u, 10u, 10u, 5u, 10u, 
-       3u, 10u, 5u, 10u, 3u, 10u, 4u, 10u, 5u, 10u, 3u, 10u, 4u, 10u, 5u, 10u, 
-       3u, 10u, 4u, 10u, 5u, 10u, 3u, 10u, 4u, 10u, 4u, 10u, 3u, 17u, 3u, 17u, 
-       1u, 16u, 1u, 16u, 1u, 16u, 3u, 17u, 3u, 17u, 1u, 16u, 1u, 16u, 1u, 16u, 
-       3u, 17u, 3u, 17u, 1u, 16u, 1u, 16u, 1u, 16u, 3u, 17u, 3u, 17u, 1u, 16u, 
-       1u, 16u, 1u, 16u, 4u, 13u, 3u, 17u, 4u, 8u, 3u, 17u, 3u, 17u, 4u, 17u, 
-       1u, 16u, 3u, 17u, 3u, 17u, 4u, 17u, 1u, 16u, 3u, 17u, 3u, 17u, 4u, 17u, 
-       1u, 16u, 3u, 17u, 3u, 17u, 4u, 17u, 1u, 16u, 3u, 17u, 3u, 17u, 4u, 17u, 
-       5u, 10u, 5u, 10u, 5u, 10u, 10u, 10u, 10u, 10u, 10u, 10u, 5u, 10u, 3u, 10u, 
-       5u, 10u, 3u, 10u, 4u, 10u, 5u, 10u, 3u, 10u, 4u, 10u, 5u, 10u, 3u, 10u, 
-       4u, 10u, 5u, 10u, 3u, 10u, 4u, 10u, 4u, 10u, 3u, 17u, 3u, 17u, 1u, 16u, 
-       1u, 16u, 1u, 16u, 3u, 17u, 3u, 17u, 1u, 16u, 1u, 16u, 1u, 16u, 3u, 17u, 
-       3u, 17u, 1u, 16u, 1u, 16u, 1u, 16u, 3u, 17u, 3u, 17u, 1u, 16u, 1u, 16u, 
-       1u, 16u, 3u, 17u, 1u, 17u, 3u, 17u, 1u, 17u, 4u, 13u, 5u, 10u, 10u, 10u, 
-       10u, 10u, 10u, 10u, 5u, 10u, 1u, 16u, 3u, 10u, 5u, 10u, 5u, 10u, 10u, 10u, 
-       10u, 10u, 10u, 10u, 5u, 10u, 1u, 16u, 0
+       8u, 8u, 4u, 8u, 5u, 7u, 5u, 8u, 4u, 8u, 6u, 6u, 16u, 16u, 4u, 8u, 
+       4u, 13u, 4u, 8u, 8u, 8u, 5u, 7u, 5u, 8u, 4u, 8u, 6u, 6u, 16u, 16u, 
+       4u, 8u, 4u, 13u, 4u, 13u, 4u, 13u, 8u, 8u, 5u, 7u, 5u, 8u, 4u, 8u, 
+       6u, 6u, 16u, 16u, 4u, 8u, 4u, 8u, 4u, 13u, 8u, 8u, 5u, 7u, 5u, 8u, 
+       4u, 8u, 6u, 6u, 16u, 16u, 4u, 8u, 4u, 8u, 5u, 8u, 8u, 8u, 1u, 19u, 
+       3u, 17u, 3u, 17u, 4u, 17u, 1u, 16u, 5u, 10u, 5u, 10u, 10u, 10u, 5u, 10u, 
+       1u, 16u, 1u, 16u, 1u, 16u, 3u, 10u, 4u, 10u, 5u, 10u, 4u, 10u, 5u, 10u, 
+       3u, 10u, 5u, 10u, 3u, 17u, 3u, 17u, 3u, 17u, 3u, 17u, 4u, 17u, 1u, 16u, 
+       3u, 17u, 3u, 17u, 4u, 17u, 1u, 16u, 5u, 10u, 10u, 10u, 5u, 10u, 1u, 16u, 
+       1u, 16u, 3u, 10u, 4u, 10u, 5u, 10u, 4u, 10u, 5u, 10u, 5u, 10u, 3u, 10u, 
+       5u, 10u, 3u, 17u, 3u, 17u, 4u, 8u, 3u, 17u, 3u, 17u, 4u, 17u, 1u, 16u, 
+       3u, 17u, 1u, 16u, 5u, 10u, 10u, 10u, 5u, 10u, 1u, 16u, 1u, 16u, 3u, 10u, 
+       4u, 10u, 5u, 10u, 3u, 17u, 4u, 10u, 5u, 10u, 5u, 10u, 3u, 10u, 5u, 10u, 
+       3u, 17u, 4u, 13u, 4u, 8u, 3u, 17u, 3u, 17u, 4u, 17u, 1u, 16u, 3u, 17u, 
+       1u, 16u, 5u, 10u, 10u, 10u, 5u, 10u, 1u, 16u, 1u, 16u, 3u, 10u, 4u, 10u, 
+       5u, 10u, 3u, 17u, 4u, 10u, 5u, 10u, 5u, 10u, 3u, 10u, 5u, 10u, 1u, 17u, 
+       3u, 17u, 1u, 17u, 4u, 13u, 5u, 10u, 10u, 10u, 5u, 10u, 1u, 16u, 3u, 10u, 
+       5u, 10u, 5u, 10u, 10u, 10u, 5u, 10u, 1u, 16u, 0
 };
 
 static const char _indic_syllable_machine_key_spans[] = {
-       1, 5, 3, 1, 4, 3, 1, 4, 
-       3, 1, 4, 3, 1, 5, 1, 1, 
-       5, 1, 1, 5, 1, 1, 5, 1, 
-       1, 10, 5, 10, 5, 10, 5, 10, 
-       5, 10, 1, 5, 3, 1, 4, 3, 
-       1, 4, 3, 1, 4, 3, 1, 5, 
-       1, 1, 5, 1, 1, 5, 1, 1, 
-       5, 1, 1, 10, 5, 10, 5, 10, 
-       5, 10, 5, 10, 1, 5, 3, 1, 
-       4, 3, 1, 4, 3, 1, 4, 3, 
-       1, 5, 1, 1, 5, 1, 1, 5, 
-       1, 1, 5, 1, 1, 10, 5, 10, 
-       5, 10, 5, 10, 5, 1, 5, 3, 
-       1, 4, 3, 1, 4, 3, 1, 4, 
-       3, 1, 5, 1, 1, 5, 1, 1, 
-       5, 1, 1, 5, 1, 1, 10, 5, 
-       10, 5, 10, 5, 10, 5, 10, 10, 
-       4, 1, 19, 15, 15, 14, 16, 15, 
-       15, 14, 16, 15, 15, 14, 16, 15, 
-       15, 14, 16, 15, 15, 14, 6, 6, 
-       6, 1, 1, 1, 6, 8, 6, 8, 
-       7, 6, 8, 7, 6, 8, 7, 6, 
-       8, 7, 7, 15, 15, 16, 16, 16, 
-       15, 15, 16, 16, 16, 15, 15, 16, 
-       16, 16, 15, 15, 16, 16, 16, 15, 
-       15, 15, 15, 14, 16, 15, 15, 14, 
-       16, 15, 15, 14, 16, 15, 15, 14, 
-       16, 15, 15, 14, 6, 6, 6, 1, 
-       1, 1, 6, 8, 6, 8, 7, 6, 
-       8, 7, 6, 8, 7, 6, 8, 7, 
-       7, 15, 15, 16, 16, 16, 15, 15, 
-       16, 16, 16, 15, 15, 16, 16, 16, 
-       15, 15, 16, 16, 16, 5, 15, 15, 
-       14, 16, 15, 15, 14, 16, 15, 15, 
-       14, 16, 15, 15, 14, 16, 15, 15, 
-       14, 6, 6, 6, 1, 1, 1, 6, 
-       8, 6, 8, 7, 6, 8, 7, 6, 
-       8, 7, 6, 8, 7, 7, 15, 15, 
-       16, 16, 16, 15, 15, 16, 16, 16, 
-       15, 15, 16, 16, 16, 15, 15, 16, 
-       16, 16, 10, 15, 5, 15, 15, 14, 
-       16, 15, 15, 14, 16, 15, 15, 14, 
-       16, 15, 15, 14, 16, 15, 15, 14, 
-       6, 6, 6, 1, 1, 1, 6, 8, 
-       6, 8, 7, 6, 8, 7, 6, 8, 
-       7, 6, 8, 7, 7, 15, 15, 16, 
-       16, 16, 15, 15, 16, 16, 16, 15, 
-       15, 16, 16, 16, 15, 15, 16, 16, 
-       16, 15, 17, 15, 17, 10, 6, 1, 
-       1, 1, 6, 16, 8, 6, 6, 1, 
-       1, 1, 6, 16
+       1, 5, 3, 4, 5, 1, 1, 5, 
+       10, 5, 1, 3, 4, 5, 1, 1, 
+       5, 10, 10, 10, 1, 3, 4, 5, 
+       1, 1, 5, 5, 10, 1, 3, 4, 
+       5, 1, 1, 5, 5, 4, 1, 19, 
+       15, 15, 14, 16, 6, 6, 1, 6, 
+       16, 16, 16, 8, 7, 6, 7, 6, 
+       8, 6, 15, 15, 15, 15, 14, 16, 
+       15, 15, 14, 16, 6, 1, 6, 16, 
+       16, 8, 7, 6, 7, 6, 6, 8, 
+       6, 15, 15, 5, 15, 15, 14, 16, 
+       15, 16, 6, 1, 6, 16, 16, 8, 
+       7, 6, 15, 7, 6, 6, 8, 6, 
+       15, 10, 5, 15, 15, 14, 16, 15, 
+       16, 6, 1, 6, 16, 16, 8, 7, 
+       6, 15, 7, 6, 6, 8, 6, 17, 
+       15, 17, 10, 6, 1, 6, 16, 8, 
+       6, 6, 1, 6, 16
 };
 
 static const short _indic_syllable_machine_index_offsets[] = {
-       0, 2, 8, 12, 14, 19, 23, 25, 
-       30, 34, 36, 41, 45, 47, 53, 55, 
-       57, 63, 65, 67, 73, 75, 77, 83, 
-       85, 87, 98, 104, 115, 121, 132, 138, 
-       149, 155, 166, 168, 174, 178, 180, 185, 
-       189, 191, 196, 200, 202, 207, 211, 213, 
-       219, 221, 223, 229, 231, 233, 239, 241, 
-       243, 249, 251, 253, 264, 270, 281, 287, 
-       298, 304, 315, 321, 332, 334, 340, 344, 
-       346, 351, 355, 357, 362, 366, 368, 373, 
-       377, 379, 385, 387, 389, 395, 397, 399, 
-       405, 407, 409, 415, 417, 419, 430, 436, 
-       447, 453, 464, 470, 481, 487, 489, 495, 
-       499, 501, 506, 510, 512, 517, 521, 523, 
-       528, 532, 534, 540, 542, 544, 550, 552, 
-       554, 560, 562, 564, 570, 572, 574, 585, 
-       591, 602, 608, 619, 625, 636, 642, 653, 
-       664, 669, 671, 691, 707, 723, 738, 755, 
-       771, 787, 802, 819, 835, 851, 866, 883, 
-       899, 915, 930, 947, 963, 979, 994, 1001, 
-       1008, 1015, 1017, 1019, 1021, 1028, 1037, 1044, 
-       1053, 1061, 1068, 1077, 1085, 1092, 1101, 1109, 
-       1116, 1125, 1133, 1141, 1157, 1173, 1190, 1207, 
-       1224, 1240, 1256, 1273, 1290, 1307, 1323, 1339, 
-       1356, 1373, 1390, 1406, 1422, 1439, 1456, 1473, 
-       1489, 1505, 1521, 1537, 1552, 1569, 1585, 1601, 
-       1616, 1633, 1649, 1665, 1680, 1697, 1713, 1729, 
-       1744, 1761, 1777, 1793, 1808, 1815, 1822, 1829, 
-       1831, 1833, 1835, 1842, 1851, 1858, 1867, 1875, 
-       1882, 1891, 1899, 1906, 1915, 1923, 1930, 1939, 
-       1947, 1955, 1971, 1987, 2004, 2021, 2038, 2054, 
-       2070, 2087, 2104, 2121, 2137, 2153, 2170, 2187, 
-       2204, 2220, 2236, 2253, 2270, 2287, 2293, 2309, 
-       2325, 2340, 2357, 2373, 2389, 2404, 2421, 2437, 
-       2453, 2468, 2485, 2501, 2517, 2532, 2549, 2565, 
-       2581, 2596, 2603, 2610, 2617, 2619, 2621, 2623, 
-       2630, 2639, 2646, 2655, 2663, 2670, 2679, 2687, 
-       2694, 2703, 2711, 2718, 2727, 2735, 2743, 2759, 
-       2775, 2792, 2809, 2826, 2842, 2858, 2875, 2892, 
-       2909, 2925, 2941, 2958, 2975, 2992, 3008, 3024, 
-       3041, 3058, 3075, 3086, 3102, 3108, 3124, 3140, 
-       3155, 3172, 3188, 3204, 3219, 3236, 3252, 3268, 
-       3283, 3300, 3316, 3332, 3347, 3364, 3380, 3396, 
-       3411, 3418, 3425, 3432, 3434, 3436, 3438, 3445, 
-       3454, 3461, 3470, 3478, 3485, 3494, 3502, 3509, 
-       3518, 3526, 3533, 3542, 3550, 3558, 3574, 3590, 
-       3607, 3624, 3641, 3657, 3673, 3690, 3707, 3724, 
-       3740, 3756, 3773, 3790, 3807, 3823, 3839, 3856, 
-       3873, 3890, 3906, 3924, 3940, 3958, 3969, 3976, 
-       3978, 3980, 3982, 3989, 4006, 4015, 4022, 4029, 
-       4031, 4033, 4035, 4042
+       0, 2, 8, 12, 17, 23, 25, 27, 
+       33, 44, 50, 52, 56, 61, 67, 69, 
+       71, 77, 88, 99, 110, 112, 116, 121, 
+       127, 129, 131, 137, 143, 154, 156, 160, 
+       165, 171, 173, 175, 181, 187, 192, 194, 
+       214, 230, 246, 261, 278, 285, 292, 294, 
+       301, 318, 335, 352, 361, 369, 376, 384, 
+       391, 400, 407, 423, 439, 455, 471, 486, 
+       503, 519, 535, 550, 567, 574, 576, 583, 
+       600, 617, 626, 634, 641, 649, 656, 663, 
+       672, 679, 695, 711, 717, 733, 749, 764, 
+       781, 797, 814, 821, 823, 830, 847, 864, 
+       873, 881, 888, 904, 912, 919, 926, 935, 
+       942, 958, 969, 975, 991, 1007, 1022, 1039, 
+       1055, 1072, 1079, 1081, 1088, 1105, 1122, 1131, 
+       1139, 1146, 1162, 1170, 1177, 1184, 1193, 1200, 
+       1218, 1234, 1252, 1263, 1270, 1272, 1279, 1296, 
+       1305, 1312, 1319, 1321, 1328
 };
 
-static const short _indic_syllable_machine_indicies[] = {
+static const unsigned char _indic_syllable_machine_indicies[] = {
        1, 0, 2, 3, 3, 4, 1, 0, 
-       5, 5, 4, 0, 4, 0, 6, 6, 
-       7, 1, 0, 8, 8, 7, 0, 7, 
-       0, 9, 9, 10, 1, 0, 11, 11, 
-       10, 0, 10, 0, 12, 12, 13, 1, 
-       0, 14, 14, 13, 0, 13, 0, 15, 
-       0, 0, 0, 1, 0, 16, 0, 17, 
-       0, 18, 12, 12, 13, 1, 0, 19, 
-       0, 20, 0, 21, 9, 9, 10, 1, 
-       0, 22, 0, 23, 0, 24, 6, 6, 
-       7, 1, 0, 25, 0, 26, 0, 2, 
-       3, 3, 4, 1, 0, 0, 0, 0, 
-       27, 0, 28, 3, 3, 4, 1, 0, 
-       28, 3, 3, 4, 1, 0, 0, 0, 
-       0, 29, 0, 30, 3, 3, 4, 1, 
-       0, 30, 3, 3, 4, 1, 0, 0, 
-       0, 0, 31, 0, 32, 3, 3, 4, 
-       1, 0, 32, 3, 3, 4, 1, 0, 
-       0, 0, 0, 33, 0, 34, 3, 3, 
-       4, 1, 0, 34, 3, 3, 4, 1, 
-       0, 0, 0, 0, 35, 0, 37, 36, 
-       38, 39, 39, 40, 37, 36, 41, 41, 
-       40, 36, 40, 36, 42, 42, 43, 37, 
-       36, 44, 44, 43, 36, 43, 36, 45, 
-       45, 46, 37, 36, 47, 47, 46, 36, 
-       46, 36, 48, 48, 49, 37, 36, 50, 
-       50, 49, 36, 49, 36, 51, 36, 36, 
-       36, 37, 36, 52, 36, 53, 36, 54, 
-       48, 48, 49, 37, 36, 55, 36, 56, 
-       36, 57, 45, 45, 46, 37, 36, 58, 
-       36, 59, 36, 60, 42, 42, 43, 37, 
-       36, 61, 36, 62, 36, 38, 39, 39, 
-       40, 37, 36, 36, 36, 36, 63, 36, 
-       64, 39, 39, 40, 37, 36, 64, 39, 
-       39, 40, 37, 36, 36, 36, 36, 65, 
-       36, 66, 39, 39, 40, 37, 36, 66, 
-       39, 39, 40, 37, 36, 36, 36, 36, 
-       67, 36, 68, 39, 39, 40, 37, 36, 
-       68, 39, 39, 40, 37, 36, 36, 36, 
-       36, 69, 36, 70, 39, 39, 40, 37, 
-       36, 70, 39, 39, 40, 37, 36, 36, 
-       36, 36, 71, 36, 73, 72, 74, 75, 
-       75, 76, 73, 72, 78, 78, 76, 77, 
-       76, 77, 79, 79, 80, 73, 72, 81, 
-       81, 80, 72, 80, 72, 82, 82, 83, 
-       73, 72, 84, 84, 83, 72, 83, 72, 
-       85, 85, 86, 73, 72, 87, 87, 86, 
-       72, 86, 72, 88, 72, 72, 72, 73, 
-       72, 89, 72, 90, 72, 91, 85, 85, 
-       86, 73, 72, 92, 72, 93, 72, 94, 
-       82, 82, 83, 73, 72, 95, 72, 96, 
-       72, 97, 79, 79, 80, 73, 72, 98, 
-       72, 99, 72, 74, 75, 75, 76, 73, 
-       72, 72, 72, 72, 100, 72, 101, 75, 
-       75, 76, 73, 72, 101, 75, 75, 76, 
-       73, 72, 72, 72, 72, 102, 72, 103, 
-       75, 75, 76, 73, 72, 103, 75, 75, 
-       76, 73, 72, 72, 72, 72, 104, 72, 
-       105, 75, 75, 76, 73, 72, 105, 75, 
-       75, 76, 73, 72, 72, 72, 72, 106, 
-       72, 107, 75, 75, 76, 73, 72, 109, 
-       108, 110, 111, 111, 112, 109, 108, 113, 
-       113, 112, 108, 112, 108, 114, 114, 115, 
-       109, 108, 116, 116, 115, 108, 115, 108, 
-       117, 117, 118, 109, 108, 119, 119, 118, 
-       108, 118, 108, 120, 120, 121, 109, 108, 
-       122, 122, 121, 108, 121, 108, 123, 108, 
-       108, 108, 109, 108, 124, 108, 125, 108, 
-       126, 120, 120, 121, 109, 108, 127, 108, 
-       128, 108, 129, 117, 117, 118, 109, 108, 
-       130, 108, 131, 108, 132, 114, 114, 115, 
-       109, 108, 133, 108, 134, 108, 110, 111, 
-       111, 112, 109, 108, 108, 108, 108, 135, 
-       108, 136, 111, 111, 112, 109, 108, 136, 
-       111, 111, 112, 109, 108, 108, 108, 108, 
-       137, 108, 138, 111, 111, 112, 109, 108, 
-       138, 111, 111, 112, 109, 108, 108, 108, 
-       108, 139, 108, 140, 111, 111, 112, 109, 
-       108, 140, 111, 111, 112, 109, 108, 108, 
-       108, 108, 141, 108, 142, 111, 111, 112, 
-       109, 108, 142, 111, 111, 112, 109, 108, 
-       108, 108, 108, 143, 108, 107, 75, 75, 
-       76, 73, 72, 72, 72, 72, 144, 72, 
-       78, 78, 76, 1, 0, 146, 145, 148, 
-       149, 150, 151, 152, 153, 76, 73, 147, 
-       154, 155, 155, 144, 147, 156, 157, 158, 
-       159, 160, 147, 162, 163, 164, 165, 4, 
-       1, 161, 166, 161, 161, 35, 161, 161, 
-       161, 167, 161, 168, 163, 169, 169, 4, 
-       1, 161, 166, 161, 161, 161, 161, 161, 
-       161, 167, 161, 163, 169, 169, 4, 1, 
-       161, 166, 161, 161, 161, 161, 161, 161, 
-       167, 161, 170, 161, 161, 161, 17, 171, 
-       161, 1, 161, 166, 161, 161, 161, 161, 
-       161, 170, 161, 172, 173, 174, 175, 4, 
-       1, 161, 166, 161, 161, 33, 161, 161, 
-       161, 167, 161, 176, 173, 177, 177, 4, 
-       1, 161, 166, 161, 161, 161, 161, 161, 
-       161, 167, 161, 173, 177, 177, 4, 1, 
-       161, 166, 161, 161, 161, 161, 161, 161, 
-       167, 161, 178, 161, 161, 161, 17, 179, 
-       161, 1, 161, 166, 161, 161, 161, 161, 
-       161, 178, 161, 180, 181, 182, 183, 4, 
-       1, 161, 166, 161, 161, 31, 161, 161, 
-       161, 167, 161, 184, 181, 185, 185, 4, 
-       1, 161, 166, 161, 161, 161, 161, 161, 
-       161, 167, 161, 181, 185, 185, 4, 1, 
-       161, 166, 161, 161, 161, 161, 161, 161, 
-       167, 161, 186, 161, 161, 161, 17, 187, 
-       161, 1, 161, 166, 161, 161, 161, 161, 
-       161, 186, 161, 188, 189, 190, 191, 4, 
-       1, 161, 166, 161, 161, 29, 161, 161, 
-       161, 167, 161, 192, 189, 193, 193, 4, 
-       1, 161, 166, 161, 161, 161, 161, 161, 
-       161, 167, 161, 189, 193, 193, 4, 1, 
-       161, 166, 161, 161, 161, 161, 161, 161, 
-       167, 161, 194, 161, 161, 161, 17, 195, 
-       161, 1, 161, 166, 161, 161, 161, 161, 
-       161, 194, 161, 196, 197, 198, 199, 4, 
-       1, 161, 166, 161, 161, 27, 161, 161, 
-       161, 167, 161, 200, 197, 201, 201, 4, 
-       1, 161, 166, 161, 161, 161, 161, 161, 
-       161, 167, 161, 197, 201, 201, 4, 1, 
-       161, 166, 161, 161, 161, 161, 161, 161, 
-       167, 161, 17, 202, 161, 1, 161, 166, 
-       161, 203, 203, 161, 1, 161, 166, 161, 
-       204, 161, 161, 205, 161, 166, 161, 166, 
-       161, 206, 161, 207, 161, 204, 161, 161, 
-       161, 161, 166, 161, 17, 161, 203, 203, 
-       161, 1, 161, 166, 161, 203, 202, 161, 
-       1, 161, 166, 161, 208, 26, 209, 210, 
-       7, 1, 161, 166, 161, 26, 209, 210, 
-       7, 1, 161, 166, 161, 209, 209, 7, 
-       1, 161, 166, 161, 211, 23, 212, 213, 
-       10, 1, 161, 166, 161, 23, 212, 213, 
-       10, 1, 161, 166, 161, 212, 212, 10, 
-       1, 161, 166, 161, 214, 20, 215, 216, 
-       13, 1, 161, 166, 161, 20, 215, 216, 
-       13, 1, 161, 166, 161, 215, 215, 13, 
-       1, 161, 166, 161, 217, 17, 203, 218, 
-       161, 1, 161, 166, 161, 17, 203, 218, 
-       161, 1, 161, 166, 161, 197, 201, 201, 
-       4, 1, 161, 166, 161, 196, 197, 201, 
-       201, 4, 1, 161, 166, 161, 161, 161, 
-       161, 161, 161, 167, 161, 196, 197, 198, 
-       201, 4, 1, 161, 166, 161, 161, 27, 
-       161, 161, 161, 167, 161, 194, 161, 219, 
-       161, 203, 203, 161, 1, 161, 166, 161, 
-       161, 161, 161, 161, 194, 161, 194, 161, 
-       161, 161, 203, 203, 161, 1, 161, 166, 
-       161, 161, 161, 161, 161, 194, 161, 194, 
-       161, 161, 161, 203, 195, 161, 1, 161, 
-       166, 161, 161, 161, 161, 161, 194, 161, 
-       188, 189, 193, 193, 4, 1, 161, 166, 
-       161, 161, 161, 161, 161, 161, 167, 161, 
-       188, 189, 190, 193, 4, 1, 161, 166, 
-       161, 161, 29, 161, 161, 161, 167, 161, 
-       186, 161, 220, 161, 203, 203, 161, 1, 
-       161, 166, 161, 161, 161, 161, 161, 186, 
-       161, 186, 161, 161, 161, 203, 203, 161, 
-       1, 161, 166, 161, 161, 161, 161, 161, 
-       186, 161, 186, 161, 161, 161, 203, 187, 
-       161, 1, 161, 166, 161, 161, 161, 161, 
-       161, 186, 161, 180, 181, 185, 185, 4, 
-       1, 161, 166, 161, 161, 161, 161, 161, 
-       161, 167, 161, 180, 181, 182, 185, 4, 
-       1, 161, 166, 161, 161, 31, 161, 161, 
-       161, 167, 161, 178, 161, 221, 161, 203, 
-       203, 161, 1, 161, 166, 161, 161, 161, 
-       161, 161, 178, 161, 178, 161, 161, 161, 
-       203, 203, 161, 1, 161, 166, 161, 161, 
-       161, 161, 161, 178, 161, 178, 161, 161, 
-       161, 203, 179, 161, 1, 161, 166, 161, 
-       161, 161, 161, 161, 178, 161, 172, 173, 
-       177, 177, 4, 1, 161, 166, 161, 161, 
-       161, 161, 161, 161, 167, 161, 172, 173, 
-       174, 177, 4, 1, 161, 166, 161, 161, 
-       33, 161, 161, 161, 167, 161, 170, 161, 
-       222, 161, 203, 203, 161, 1, 161, 166, 
-       161, 161, 161, 161, 161, 170, 161, 170, 
-       161, 161, 161, 203, 203, 161, 1, 161, 
-       166, 161, 161, 161, 161, 161, 170, 161, 
-       170, 161, 161, 161, 203, 171, 161, 1, 
-       161, 166, 161, 161, 161, 161, 161, 170, 
-       161, 162, 163, 169, 169, 4, 1, 161, 
-       166, 161, 161, 161, 161, 161, 161, 167, 
-       161, 162, 163, 164, 169, 4, 1, 161, 
-       166, 161, 161, 35, 161, 161, 161, 167, 
-       161, 224, 225, 226, 227, 40, 37, 223, 
-       228, 223, 223, 71, 223, 223, 223, 229, 
-       223, 230, 225, 231, 227, 40, 37, 223, 
-       228, 223, 223, 223, 223, 223, 223, 229, 
-       223, 225, 231, 227, 40, 37, 223, 228, 
-       223, 223, 223, 223, 223, 223, 229, 223, 
-       232, 223, 223, 223, 53, 233, 223, 37, 
-       223, 228, 223, 223, 223, 223, 223, 232, 
-       223, 234, 235, 236, 237, 40, 37, 223, 
-       228, 223, 223, 69, 223, 223, 223, 229, 
-       223, 238, 235, 239, 239, 40, 37, 223, 
-       228, 223, 223, 223, 223, 223, 223, 229, 
-       223, 235, 239, 239, 40, 37, 223, 228, 
-       223, 223, 223, 223, 223, 223, 229, 223, 
-       240, 223, 223, 223, 53, 241, 223, 37, 
-       223, 228, 223, 223, 223, 223, 223, 240, 
-       223, 242, 243, 244, 245, 40, 37, 223, 
-       228, 223, 223, 67, 223, 223, 223, 229, 
-       223, 246, 243, 247, 247, 40, 37, 223, 
-       228, 223, 223, 223, 223, 223, 223, 229, 
-       223, 243, 247, 247, 40, 37, 223, 228, 
-       223, 223, 223, 223, 223, 223, 229, 223, 
-       248, 223, 223, 223, 53, 249, 223, 37, 
-       223, 228, 223, 223, 223, 223, 223, 248, 
-       223, 250, 251, 252, 253, 40, 37, 223, 
-       228, 223, 223, 65, 223, 223, 223, 229, 
-       223, 254, 251, 255, 255, 40, 37, 223, 
-       228, 223, 223, 223, 223, 223, 223, 229, 
-       223, 251, 255, 255, 40, 37, 223, 228, 
-       223, 223, 223, 223, 223, 223, 229, 223, 
-       256, 223, 223, 223, 53, 257, 223, 37, 
-       223, 228, 223, 223, 223, 223, 223, 256, 
-       223, 258, 259, 260, 261, 40, 37, 223, 
-       228, 223, 223, 63, 223, 223, 223, 229, 
-       223, 262, 259, 263, 263, 40, 37, 223, 
-       228, 223, 223, 223, 223, 223, 223, 229, 
-       223, 259, 263, 263, 40, 37, 223, 228, 
-       223, 223, 223, 223, 223, 223, 229, 223, 
-       53, 264, 223, 37, 223, 228, 223, 265, 
-       265, 223, 37, 223, 228, 223, 266, 223, 
-       223, 267, 223, 228, 223, 228, 223, 268, 
-       223, 269, 223, 266, 223, 223, 223, 223, 
-       228, 223, 53, 223, 265, 265, 223, 37, 
-       223, 228, 223, 265, 264, 223, 37, 223, 
-       228, 223, 270, 62, 271, 272, 43, 37, 
-       223, 228, 223, 62, 271, 272, 43, 37, 
-       223, 228, 223, 271, 271, 43, 37, 223, 
-       228, 223, 273, 59, 274, 275, 46, 37, 
-       223, 228, 223, 59, 274, 275, 46, 37, 
-       223, 228, 223, 274, 274, 46, 37, 223, 
-       228, 223, 276, 56, 277, 278, 49, 37, 
-       223, 228, 223, 56, 277, 278, 49, 37, 
-       223, 228, 223, 277, 277, 49, 37, 223, 
-       228, 223, 279, 53, 265, 280, 223, 37, 
-       223, 228, 223, 53, 265, 280, 223, 37, 
-       223, 228, 223, 259, 263, 263, 40, 37, 
-       223, 228, 223, 258, 259, 263, 263, 40, 
-       37, 223, 228, 223, 223, 223, 223, 223, 
-       223, 229, 223, 258, 259, 260, 263, 40, 
-       37, 223, 228, 223, 223, 63, 223, 223, 
-       223, 229, 223, 256, 223, 281, 223, 265, 
-       265, 223, 37, 223, 228, 223, 223, 223, 
-       223, 223, 256, 223, 256, 223, 223, 223, 
-       265, 265, 223, 37, 223, 228, 223, 223, 
-       223, 223, 223, 256, 223, 256, 223, 223, 
-       223, 265, 257, 223, 37, 223, 228, 223, 
-       223, 223, 223, 223, 256, 223, 250, 251, 
-       255, 255, 40, 37, 223, 228, 223, 223, 
-       223, 223, 223, 223, 229, 223, 250, 251, 
-       252, 255, 40, 37, 223, 228, 223, 223, 
-       65, 223, 223, 223, 229, 223, 248, 223, 
-       282, 223, 265, 265, 223, 37, 223, 228, 
-       223, 223, 223, 223, 223, 248, 223, 248, 
-       223, 223, 223, 265, 265, 223, 37, 223, 
-       228, 223, 223, 223, 223, 223, 248, 223, 
-       248, 223, 223, 223, 265, 249, 223, 37, 
-       223, 228, 223, 223, 223, 223, 223, 248, 
-       223, 242, 243, 247, 247, 40, 37, 223, 
-       228, 223, 223, 223, 223, 223, 223, 229, 
-       223, 242, 243, 244, 247, 40, 37, 223, 
-       228, 223, 223, 67, 223, 223, 223, 229, 
-       223, 240, 223, 283, 223, 265, 265, 223, 
-       37, 223, 228, 223, 223, 223, 223, 223, 
-       240, 223, 240, 223, 223, 223, 265, 265, 
-       223, 37, 223, 228, 223, 223, 223, 223, 
-       223, 240, 223, 240, 223, 223, 223, 265, 
-       241, 223, 37, 223, 228, 223, 223, 223, 
-       223, 223, 240, 223, 234, 235, 239, 239, 
-       40, 37, 223, 228, 223, 223, 223, 223, 
-       223, 223, 229, 223, 234, 235, 236, 239, 
-       40, 37, 223, 228, 223, 223, 69, 223, 
-       223, 223, 229, 223, 232, 223, 284, 223, 
-       265, 265, 223, 37, 223, 228, 223, 223, 
-       223, 223, 223, 232, 223, 232, 223, 223, 
-       223, 265, 265, 223, 37, 223, 228, 223, 
-       223, 223, 223, 223, 232, 223, 232, 223, 
-       223, 223, 265, 233, 223, 37, 223, 228, 
-       223, 223, 223, 223, 223, 232, 223, 70, 
-       39, 39, 40, 37, 223, 224, 225, 231, 
-       227, 40, 37, 223, 228, 223, 223, 223, 
-       223, 223, 223, 229, 223, 286, 151, 287, 
-       287, 76, 73, 285, 154, 285, 285, 285, 
-       285, 285, 285, 158, 285, 151, 287, 287, 
-       76, 73, 285, 154, 285, 285, 285, 285, 
-       285, 285, 158, 285, 288, 285, 285, 285, 
-       90, 289, 285, 73, 285, 154, 285, 285, 
-       285, 285, 285, 288, 285, 290, 291, 292, 
-       293, 76, 73, 285, 154, 285, 285, 106, 
-       285, 285, 285, 158, 285, 294, 291, 295, 
-       295, 76, 73, 285, 154, 285, 285, 285, 
-       285, 285, 285, 158, 285, 291, 295, 295, 
-       76, 73, 285, 154, 285, 285, 285, 285, 
-       285, 285, 158, 285, 296, 285, 285, 285, 
-       90, 297, 285, 73, 285, 154, 285, 285, 
-       285, 285, 285, 296, 285, 298, 299, 300, 
-       301, 76, 73, 285, 154, 285, 285, 104, 
-       285, 285, 285, 158, 285, 302, 299, 303, 
-       303, 76, 73, 285, 154, 285, 285, 285, 
-       285, 285, 285, 158, 285, 299, 303, 303, 
-       76, 73, 285, 154, 285, 285, 285, 285, 
-       285, 285, 158, 285, 304, 285, 285, 285, 
-       90, 305, 285, 73, 285, 154, 285, 285, 
-       285, 285, 285, 304, 285, 306, 307, 308, 
-       309, 76, 73, 285, 154, 285, 285, 102, 
-       285, 285, 285, 158, 285, 310, 307, 311, 
-       311, 76, 73, 285, 154, 285, 285, 285, 
-       285, 285, 285, 158, 285, 307, 311, 311, 
-       76, 73, 285, 154, 285, 285, 285, 285, 
-       285, 285, 158, 285, 312, 285, 285, 285, 
-       90, 313, 285, 73, 285, 154, 285, 285, 
-       285, 285, 285, 312, 285, 314, 315, 316, 
-       317, 76, 73, 285, 154, 285, 285, 100, 
-       285, 285, 285, 158, 285, 318, 315, 319, 
-       319, 76, 73, 285, 154, 285, 285, 285, 
-       285, 285, 285, 158, 285, 315, 319, 319, 
-       76, 73, 285, 154, 285, 285, 285, 285, 
-       285, 285, 158, 285, 90, 320, 285, 73, 
-       285, 154, 285, 321, 321, 285, 73, 285, 
-       154, 285, 322, 285, 285, 323, 285, 154, 
-       285, 154, 285, 324, 285, 325, 285, 322, 
-       285, 285, 285, 285, 154, 285, 90, 285, 
-       321, 321, 285, 73, 285, 154, 285, 321, 
-       320, 285, 73, 285, 154, 285, 326, 99, 
-       327, 328, 80, 73, 285, 154, 285, 99, 
-       327, 328, 80, 73, 285, 154, 285, 327, 
-       327, 80, 73, 285, 154, 285, 329, 96, 
-       330, 331, 83, 73, 285, 154, 285, 96, 
-       330, 331, 83, 73, 285, 154, 285, 330, 
-       330, 83, 73, 285, 154, 285, 332, 93, 
-       333, 334, 86, 73, 285, 154, 285, 93, 
-       333, 334, 86, 73, 285, 154, 285, 333, 
-       333, 86, 73, 285, 154, 285, 335, 90, 
-       321, 336, 285, 73, 285, 154, 285, 90, 
-       321, 336, 285, 73, 285, 154, 285, 315, 
-       319, 319, 76, 73, 285, 154, 285, 314, 
-       315, 319, 319, 76, 73, 285, 154, 285, 
-       285, 285, 285, 285, 285, 158, 285, 314, 
-       315, 316, 319, 76, 73, 285, 154, 285, 
-       285, 100, 285, 285, 285, 158, 285, 312, 
-       285, 337, 285, 321, 321, 285, 73, 285, 
-       154, 285, 285, 285, 285, 285, 312, 285, 
-       312, 285, 285, 285, 321, 321, 285, 73, 
-       285, 154, 285, 285, 285, 285, 285, 312, 
-       285, 312, 285, 285, 285, 321, 313, 285, 
-       73, 285, 154, 285, 285, 285, 285, 285, 
-       312, 285, 306, 307, 311, 311, 76, 73, 
-       285, 154, 285, 285, 285, 285, 285, 285, 
-       158, 285, 306, 307, 308, 311, 76, 73, 
-       285, 154, 285, 285, 102, 285, 285, 285, 
-       158, 285, 304, 285, 338, 285, 321, 321, 
-       285, 73, 285, 154, 285, 285, 285, 285, 
-       285, 304, 285, 304, 285, 285, 285, 321, 
-       321, 285, 73, 285, 154, 285, 285, 285, 
-       285, 285, 304, 285, 304, 285, 285, 285, 
-       321, 305, 285, 73, 285, 154, 285, 285, 
-       285, 285, 285, 304, 285, 298, 299, 303, 
-       303, 76, 73, 285, 154, 285, 285, 285, 
-       285, 285, 285, 158, 285, 298, 299, 300, 
-       303, 76, 73, 285, 154, 285, 285, 104, 
-       285, 285, 285, 158, 285, 296, 285, 339, 
-       285, 321, 321, 285, 73, 285, 154, 285, 
-       285, 285, 285, 285, 296, 285, 296, 285, 
-       285, 285, 321, 321, 285, 73, 285, 154, 
-       285, 285, 285, 285, 285, 296, 285, 296, 
-       285, 285, 285, 321, 297, 285, 73, 285, 
-       154, 285, 285, 285, 285, 285, 296, 285, 
-       290, 291, 295, 295, 76, 73, 285, 154, 
-       285, 285, 285, 285, 285, 285, 158, 285, 
-       290, 291, 292, 295, 76, 73, 285, 154, 
-       285, 285, 106, 285, 285, 285, 158, 285, 
-       288, 285, 340, 285, 321, 321, 285, 73, 
-       285, 154, 285, 285, 285, 285, 285, 288, 
-       285, 288, 285, 285, 285, 321, 321, 285, 
-       73, 285, 154, 285, 285, 285, 285, 285, 
-       288, 285, 288, 285, 285, 285, 321, 289, 
-       285, 73, 285, 154, 285, 285, 285, 285, 
-       285, 288, 285, 107, 75, 75, 76, 73, 
-       341, 341, 341, 341, 144, 341, 150, 151, 
-       287, 287, 76, 73, 285, 154, 285, 285, 
-       285, 285, 285, 285, 158, 285, 107, 75, 
-       75, 76, 73, 341, 343, 344, 345, 346, 
-       112, 109, 342, 347, 342, 342, 143, 342, 
-       342, 342, 348, 342, 349, 344, 346, 346, 
-       112, 109, 342, 347, 342, 342, 342, 342, 
-       342, 342, 348, 342, 344, 346, 346, 112, 
-       109, 342, 347, 342, 342, 342, 342, 342, 
-       342, 348, 342, 350, 342, 342, 342, 125, 
-       351, 342, 109, 342, 347, 342, 342, 342, 
-       342, 342, 350, 342, 352, 353, 354, 355, 
-       112, 109, 342, 347, 342, 342, 141, 342, 
-       342, 342, 348, 342, 356, 353, 357, 357, 
-       112, 109, 342, 347, 342, 342, 342, 342, 
-       342, 342, 348, 342, 353, 357, 357, 112, 
-       109, 342, 347, 342, 342, 342, 342, 342, 
-       342, 348, 342, 358, 342, 342, 342, 125, 
-       359, 342, 109, 342, 347, 342, 342, 342, 
-       342, 342, 358, 342, 360, 361, 362, 363, 
-       112, 109, 342, 347, 342, 342, 139, 342, 
-       342, 342, 348, 342, 364, 361, 365, 365, 
-       112, 109, 342, 347, 342, 342, 342, 342, 
-       342, 342, 348, 342, 361, 365, 365, 112, 
-       109, 342, 347, 342, 342, 342, 342, 342, 
-       342, 348, 342, 366, 342, 342, 342, 125, 
-       367, 342, 109, 342, 347, 342, 342, 342, 
-       342, 342, 366, 342, 368, 369, 370, 371, 
-       112, 109, 342, 347, 342, 342, 137, 342, 
-       342, 342, 348, 342, 372, 369, 373, 373, 
-       112, 109, 342, 347, 342, 342, 342, 342, 
-       342, 342, 348, 342, 369, 373, 373, 112, 
-       109, 342, 347, 342, 342, 342, 342, 342, 
-       342, 348, 342, 374, 342, 342, 342, 125, 
-       375, 342, 109, 342, 347, 342, 342, 342, 
-       342, 342, 374, 342, 376, 377, 378, 379, 
-       112, 109, 342, 347, 342, 342, 135, 342, 
-       342, 342, 348, 342, 380, 377, 381, 381, 
-       112, 109, 342, 347, 342, 342, 342, 342, 
-       342, 342, 348, 342, 377, 381, 381, 112, 
-       109, 342, 347, 342, 342, 342, 342, 342, 
-       342, 348, 342, 125, 382, 342, 109, 342, 
-       347, 342, 383, 383, 342, 109, 342, 347, 
-       342, 384, 342, 342, 385, 342, 347, 342, 
-       347, 342, 386, 342, 387, 342, 384, 342, 
-       342, 342, 342, 347, 342, 125, 342, 383, 
-       383, 342, 109, 342, 347, 342, 383, 382, 
-       342, 109, 342, 347, 342, 388, 134, 389, 
-       390, 115, 109, 342, 347, 342, 134, 389, 
-       390, 115, 109, 342, 347, 342, 389, 389, 
-       115, 109, 342, 347, 342, 391, 131, 392, 
-       393, 118, 109, 342, 347, 342, 131, 392, 
-       393, 118, 109, 342, 347, 342, 392, 392, 
-       118, 109, 342, 347, 342, 394, 128, 395, 
-       396, 121, 109, 342, 347, 342, 128, 395, 
-       396, 121, 109, 342, 347, 342, 395, 395, 
-       121, 109, 342, 347, 342, 397, 125, 383, 
-       398, 342, 109, 342, 347, 342, 125, 383, 
-       398, 342, 109, 342, 347, 342, 377, 381, 
-       381, 112, 109, 342, 347, 342, 376, 377, 
-       381, 381, 112, 109, 342, 347, 342, 342, 
-       342, 342, 342, 342, 348, 342, 376, 377, 
-       378, 381, 112, 109, 342, 347, 342, 342, 
-       135, 342, 342, 342, 348, 342, 374, 342, 
-       399, 342, 383, 383, 342, 109, 342, 347, 
-       342, 342, 342, 342, 342, 374, 342, 374, 
-       342, 342, 342, 383, 383, 342, 109, 342, 
-       347, 342, 342, 342, 342, 342, 374, 342, 
-       374, 342, 342, 342, 383, 375, 342, 109, 
-       342, 347, 342, 342, 342, 342, 342, 374, 
-       342, 368, 369, 373, 373, 112, 109, 342, 
-       347, 342, 342, 342, 342, 342, 342, 348, 
-       342, 368, 369, 370, 373, 112, 109, 342, 
-       347, 342, 342, 137, 342, 342, 342, 348, 
-       342, 366, 342, 400, 342, 383, 383, 342, 
-       109, 342, 347, 342, 342, 342, 342, 342, 
-       366, 342, 366, 342, 342, 342, 383, 383, 
-       342, 109, 342, 347, 342, 342, 342, 342, 
-       342, 366, 342, 366, 342, 342, 342, 383, 
-       367, 342, 109, 342, 347, 342, 342, 342, 
-       342, 342, 366, 342, 360, 361, 365, 365, 
-       112, 109, 342, 347, 342, 342, 342, 342, 
-       342, 342, 348, 342, 360, 361, 362, 365, 
-       112, 109, 342, 347, 342, 342, 139, 342, 
-       342, 342, 348, 342, 358, 342, 401, 342, 
-       383, 383, 342, 109, 342, 347, 342, 342, 
-       342, 342, 342, 358, 342, 358, 342, 342, 
-       342, 383, 383, 342, 109, 342, 347, 342, 
-       342, 342, 342, 342, 358, 342, 358, 342, 
-       342, 342, 383, 359, 342, 109, 342, 347, 
-       342, 342, 342, 342, 342, 358, 342, 352, 
-       353, 357, 357, 112, 109, 342, 347, 342, 
-       342, 342, 342, 342, 342, 348, 342, 352, 
-       353, 354, 357, 112, 109, 342, 347, 342, 
-       342, 141, 342, 342, 342, 348, 342, 350, 
-       342, 402, 342, 383, 383, 342, 109, 342, 
-       347, 342, 342, 342, 342, 342, 350, 342, 
-       350, 342, 342, 342, 383, 383, 342, 109, 
-       342, 347, 342, 342, 342, 342, 342, 350, 
-       342, 350, 342, 342, 342, 383, 351, 342, 
-       109, 342, 347, 342, 342, 342, 342, 342, 
-       350, 342, 343, 344, 346, 346, 112, 109, 
-       342, 347, 342, 342, 342, 342, 342, 342, 
-       348, 342, 148, 149, 150, 151, 403, 287, 
-       76, 73, 285, 154, 155, 155, 144, 285, 
-       285, 148, 158, 285, 162, 404, 164, 165, 
-       4, 1, 161, 166, 161, 161, 35, 161, 
-       161, 161, 167, 161, 170, 149, 150, 151, 
-       405, 406, 76, 407, 161, 408, 161, 155, 
-       144, 161, 161, 170, 158, 161, 107, 409, 
-       409, 76, 407, 161, 166, 161, 161, 144, 
-       161, 410, 161, 161, 411, 161, 408, 161, 
-       408, 161, 412, 161, 207, 161, 410, 161, 
-       161, 161, 161, 408, 161, 170, 161, 222, 
-       107, 409, 409, 76, 407, 161, 166, 161, 
-       161, 161, 161, 161, 170, 161, 414, 413, 
-       415, 415, 413, 146, 413, 416, 413, 415, 
-       415, 413, 146, 413, 416, 413, 417, 413, 
-       413, 418, 413, 416, 413, 416, 413, 419, 
-       413, 420, 413, 417, 413, 413, 413, 413, 
-       416, 413, 148, 341, 341, 341, 341, 341, 
-       341, 341, 341, 341, 155, 341, 341, 341, 
-       341, 148, 341, 0
+       3, 3, 4, 0, 3, 3, 4, 1, 
+       0, 5, 3, 3, 4, 1, 0, 6, 
+       0, 7, 0, 8, 3, 3, 4, 1, 
+       0, 2, 3, 3, 4, 1, 0, 0, 
+       0, 0, 9, 0, 11, 12, 12, 13, 
+       14, 10, 14, 10, 12, 12, 13, 10, 
+       12, 12, 13, 14, 10, 15, 12, 12, 
+       13, 14, 10, 16, 10, 17, 10, 18, 
+       12, 12, 13, 14, 10, 11, 12, 12, 
+       13, 14, 10, 10, 10, 10, 19, 10, 
+       11, 12, 12, 13, 14, 10, 10, 10, 
+       10, 20, 10, 22, 23, 23, 24, 25, 
+       21, 21, 21, 21, 26, 21, 25, 21, 
+       23, 23, 24, 27, 23, 23, 24, 25, 
+       21, 28, 23, 23, 24, 25, 21, 29, 
+       21, 30, 21, 22, 23, 23, 24, 25, 
+       21, 31, 23, 23, 24, 25, 21, 33, 
+       34, 34, 35, 36, 32, 32, 32, 32, 
+       37, 32, 36, 32, 34, 34, 35, 32, 
+       34, 34, 35, 36, 32, 38, 34, 34, 
+       35, 36, 32, 39, 32, 40, 32, 33, 
+       34, 34, 35, 36, 32, 41, 34, 34, 
+       35, 36, 32, 23, 23, 24, 1, 0, 
+       43, 42, 45, 46, 47, 48, 49, 50, 
+       24, 25, 44, 51, 52, 52, 26, 44, 
+       53, 54, 55, 56, 57, 44, 59, 60, 
+       61, 62, 4, 1, 58, 63, 58, 58, 
+       9, 58, 58, 58, 64, 58, 65, 60, 
+       66, 66, 4, 1, 58, 63, 58, 58, 
+       58, 58, 58, 58, 64, 58, 60, 66, 
+       66, 4, 1, 58, 63, 58, 58, 58, 
+       58, 58, 58, 64, 58, 45, 58, 58, 
+       58, 67, 68, 58, 1, 58, 63, 58, 
+       58, 58, 58, 58, 45, 58, 69, 69, 
+       58, 1, 58, 63, 58, 63, 58, 58, 
+       70, 58, 63, 58, 63, 58, 63, 58, 
+       58, 58, 58, 63, 58, 45, 58, 71, 
+       58, 69, 69, 58, 1, 58, 63, 58, 
+       58, 58, 58, 58, 45, 58, 45, 58, 
+       58, 58, 69, 69, 58, 1, 58, 63, 
+       58, 58, 58, 58, 58, 45, 58, 45, 
+       58, 58, 58, 69, 68, 58, 1, 58, 
+       63, 58, 58, 58, 58, 58, 45, 58, 
+       72, 7, 73, 74, 4, 1, 58, 63, 
+       58, 7, 73, 74, 4, 1, 58, 63, 
+       58, 73, 73, 4, 1, 58, 63, 58, 
+       75, 76, 76, 4, 1, 58, 63, 58, 
+       67, 77, 58, 1, 58, 63, 58, 67, 
+       58, 69, 69, 58, 1, 58, 63, 58, 
+       69, 77, 58, 1, 58, 63, 58, 59, 
+       60, 66, 66, 4, 1, 58, 63, 58, 
+       58, 58, 58, 58, 58, 64, 58, 59, 
+       60, 61, 66, 4, 1, 58, 63, 58, 
+       58, 9, 58, 58, 58, 64, 58, 79, 
+       80, 81, 82, 13, 14, 78, 83, 78, 
+       78, 20, 78, 78, 78, 84, 78, 85, 
+       80, 86, 82, 13, 14, 78, 83, 78, 
+       78, 78, 78, 78, 78, 84, 78, 80, 
+       86, 82, 13, 14, 78, 83, 78, 78, 
+       78, 78, 78, 78, 84, 78, 87, 78, 
+       78, 78, 88, 89, 78, 14, 78, 83, 
+       78, 78, 78, 78, 78, 87, 78, 90, 
+       80, 91, 92, 13, 14, 78, 83, 78, 
+       78, 19, 78, 78, 78, 84, 78, 93, 
+       80, 86, 86, 13, 14, 78, 83, 78, 
+       78, 78, 78, 78, 78, 84, 78, 80, 
+       86, 86, 13, 14, 78, 83, 78, 78, 
+       78, 78, 78, 78, 84, 78, 87, 78, 
+       78, 78, 94, 89, 78, 14, 78, 83, 
+       78, 78, 78, 78, 78, 87, 78, 83, 
+       78, 78, 95, 78, 83, 78, 83, 78, 
+       83, 78, 78, 78, 78, 83, 78, 87, 
+       78, 96, 78, 94, 94, 78, 14, 78, 
+       83, 78, 78, 78, 78, 78, 87, 78, 
+       87, 78, 78, 78, 94, 94, 78, 14, 
+       78, 83, 78, 78, 78, 78, 78, 87, 
+       78, 97, 17, 98, 99, 13, 14, 78, 
+       83, 78, 17, 98, 99, 13, 14, 78, 
+       83, 78, 98, 98, 13, 14, 78, 83, 
+       78, 100, 101, 101, 13, 14, 78, 83, 
+       78, 88, 102, 78, 14, 78, 83, 78, 
+       94, 94, 78, 14, 78, 83, 78, 88, 
+       78, 94, 94, 78, 14, 78, 83, 78, 
+       94, 102, 78, 14, 78, 83, 78, 90, 
+       80, 86, 86, 13, 14, 78, 83, 78, 
+       78, 78, 78, 78, 78, 84, 78, 90, 
+       80, 91, 86, 13, 14, 78, 83, 78, 
+       78, 19, 78, 78, 78, 84, 78, 11, 
+       12, 12, 13, 14, 78, 79, 80, 86, 
+       82, 13, 14, 78, 83, 78, 78, 78, 
+       78, 78, 78, 84, 78, 104, 48, 105, 
+       105, 24, 25, 103, 51, 103, 103, 103, 
+       103, 103, 103, 55, 103, 48, 105, 105, 
+       24, 25, 103, 51, 103, 103, 103, 103, 
+       103, 103, 55, 103, 106, 103, 103, 103, 
+       107, 108, 103, 25, 103, 51, 103, 103, 
+       103, 103, 103, 106, 103, 47, 48, 109, 
+       110, 24, 25, 103, 51, 103, 103, 26, 
+       103, 103, 103, 55, 103, 106, 103, 103, 
+       103, 111, 108, 103, 25, 103, 51, 103, 
+       103, 103, 103, 103, 106, 103, 51, 103, 
+       103, 112, 103, 51, 103, 51, 103, 51, 
+       103, 103, 103, 103, 51, 103, 106, 103, 
+       113, 103, 111, 111, 103, 25, 103, 51, 
+       103, 103, 103, 103, 103, 106, 103, 106, 
+       103, 103, 103, 111, 111, 103, 25, 103, 
+       51, 103, 103, 103, 103, 103, 106, 103, 
+       114, 30, 115, 116, 24, 25, 103, 51, 
+       103, 30, 115, 116, 24, 25, 103, 51, 
+       103, 115, 115, 24, 25, 103, 51, 103, 
+       47, 48, 105, 105, 24, 25, 103, 51, 
+       103, 103, 103, 103, 103, 103, 55, 103, 
+       117, 118, 118, 24, 25, 103, 51, 103, 
+       107, 119, 103, 25, 103, 51, 103, 111, 
+       111, 103, 25, 103, 51, 103, 107, 103, 
+       111, 111, 103, 25, 103, 51, 103, 111, 
+       119, 103, 25, 103, 51, 103, 47, 48, 
+       109, 105, 24, 25, 103, 51, 103, 103, 
+       26, 103, 103, 103, 55, 103, 22, 23, 
+       23, 24, 25, 120, 120, 120, 120, 26, 
+       120, 22, 23, 23, 24, 25, 120, 122, 
+       123, 124, 125, 35, 36, 121, 126, 121, 
+       121, 37, 121, 121, 121, 127, 121, 128, 
+       123, 125, 125, 35, 36, 121, 126, 121, 
+       121, 121, 121, 121, 121, 127, 121, 123, 
+       125, 125, 35, 36, 121, 126, 121, 121, 
+       121, 121, 121, 121, 127, 121, 129, 121, 
+       121, 121, 130, 131, 121, 36, 121, 126, 
+       121, 121, 121, 121, 121, 129, 121, 122, 
+       123, 124, 52, 35, 36, 121, 126, 121, 
+       121, 37, 121, 121, 121, 127, 121, 129, 
+       121, 121, 121, 132, 131, 121, 36, 121, 
+       126, 121, 121, 121, 121, 121, 129, 121, 
+       126, 121, 121, 133, 121, 126, 121, 126, 
+       121, 126, 121, 121, 121, 121, 126, 121, 
+       129, 121, 134, 121, 132, 132, 121, 36, 
+       121, 126, 121, 121, 121, 121, 121, 129, 
+       121, 129, 121, 121, 121, 132, 132, 121, 
+       36, 121, 126, 121, 121, 121, 121, 121, 
+       129, 121, 135, 40, 136, 137, 35, 36, 
+       121, 126, 121, 40, 136, 137, 35, 36, 
+       121, 126, 121, 136, 136, 35, 36, 121, 
+       126, 121, 122, 123, 125, 125, 35, 36, 
+       121, 126, 121, 121, 121, 121, 121, 121, 
+       127, 121, 138, 139, 139, 35, 36, 121, 
+       126, 121, 130, 140, 121, 36, 121, 126, 
+       121, 132, 132, 121, 36, 121, 126, 121, 
+       130, 121, 132, 132, 121, 36, 121, 126, 
+       121, 132, 140, 121, 36, 121, 126, 121, 
+       45, 46, 47, 48, 109, 105, 24, 25, 
+       103, 51, 52, 52, 26, 103, 103, 45, 
+       55, 103, 59, 141, 61, 62, 4, 1, 
+       58, 63, 58, 58, 9, 58, 58, 58, 
+       64, 58, 45, 46, 47, 48, 142, 143, 
+       24, 144, 58, 145, 58, 52, 26, 58, 
+       58, 45, 55, 58, 22, 146, 146, 24, 
+       144, 58, 63, 58, 58, 26, 58, 145, 
+       58, 58, 147, 58, 145, 58, 145, 58, 
+       145, 58, 58, 58, 58, 145, 58, 45, 
+       58, 71, 22, 146, 146, 24, 144, 58, 
+       63, 58, 58, 58, 58, 58, 45, 58, 
+       149, 148, 150, 150, 148, 43, 148, 151, 
+       148, 150, 150, 148, 43, 148, 151, 148, 
+       151, 148, 148, 152, 148, 151, 148, 151, 
+       148, 151, 148, 148, 148, 148, 151, 148, 
+       45, 120, 120, 120, 120, 120, 120, 120, 
+       120, 120, 52, 120, 120, 120, 120, 45, 
+       120, 0
 };
 
-static const short _indic_syllable_machine_trans_targs[] = {
-       138, 160, 166, 2, 167, 3, 5, 170, 
-       6, 8, 173, 9, 11, 176, 12, 14, 
-       15, 159, 17, 18, 175, 20, 21, 172, 
-       23, 24, 169, 179, 183, 184, 188, 189, 
-       193, 194, 198, 199, 138, 222, 228, 36, 
-       229, 37, 39, 232, 40, 42, 235, 43, 
-       45, 238, 46, 48, 49, 221, 51, 52, 
-       237, 54, 55, 234, 57, 58, 231, 241, 
-       245, 246, 250, 251, 255, 256, 260, 262, 
-       138, 283, 289, 70, 290, 138, 71, 73, 
-       293, 74, 76, 296, 77, 79, 299, 80, 
-       82, 83, 282, 85, 86, 298, 88, 89, 
-       295, 91, 92, 292, 302, 306, 307, 311, 
-       312, 316, 317, 321, 138, 346, 352, 103, 
-       353, 104, 106, 356, 107, 109, 359, 110, 
-       112, 362, 113, 115, 116, 345, 118, 119, 
-       361, 121, 122, 358, 124, 125, 355, 365, 
-       369, 370, 374, 375, 379, 380, 384, 385, 
-       323, 138, 398, 138, 139, 201, 263, 265, 
-       322, 324, 285, 325, 386, 387, 301, 396, 
-       403, 138, 140, 142, 33, 200, 162, 178, 
-       141, 32, 143, 196, 144, 146, 31, 195, 
-       145, 30, 147, 191, 148, 150, 29, 190, 
-       149, 28, 151, 186, 152, 154, 27, 185, 
-       153, 26, 155, 181, 156, 158, 25, 180, 
-       157, 1, 165, 0, 161, 164, 163, 138, 
-       168, 4, 22, 171, 7, 19, 174, 10, 
-       16, 177, 13, 182, 187, 192, 197, 138, 
-       202, 204, 67, 261, 224, 240, 203, 66, 
-       205, 258, 206, 208, 65, 257, 207, 64, 
-       209, 253, 210, 212, 63, 252, 211, 62, 
-       213, 248, 214, 216, 61, 247, 215, 60, 
-       217, 243, 218, 220, 59, 242, 219, 35, 
-       227, 34, 223, 226, 225, 138, 230, 38, 
-       56, 233, 41, 53, 236, 44, 50, 239, 
-       47, 244, 249, 254, 259, 138, 264, 100, 
-       266, 319, 267, 269, 99, 318, 268, 98, 
-       270, 314, 271, 273, 97, 313, 272, 96, 
-       274, 309, 275, 277, 95, 308, 276, 94, 
-       278, 304, 279, 281, 93, 303, 280, 69, 
-       288, 68, 284, 287, 286, 138, 291, 72, 
-       90, 294, 75, 87, 297, 78, 84, 300, 
-       81, 305, 310, 315, 320, 138, 138, 326, 
-       328, 134, 133, 348, 364, 327, 329, 382, 
-       330, 332, 132, 381, 331, 131, 333, 377, 
-       334, 336, 130, 376, 335, 129, 337, 372, 
-       338, 340, 128, 371, 339, 127, 341, 367, 
-       342, 344, 126, 366, 343, 102, 351, 101, 
-       347, 350, 349, 138, 354, 105, 123, 357, 
-       108, 120, 360, 111, 117, 363, 114, 368, 
-       373, 378, 383, 135, 388, 389, 395, 390, 
-       392, 136, 391, 394, 393, 138, 397, 137, 
-       400, 399, 402, 401, 138
+static const unsigned char _indic_syllable_machine_trans_targs[] = {
+       39, 45, 50, 2, 51, 5, 6, 53, 
+       57, 58, 39, 67, 11, 73, 68, 14, 
+       15, 75, 80, 81, 84, 39, 89, 21, 
+       95, 90, 98, 39, 24, 25, 97, 103, 
+       39, 112, 30, 118, 113, 121, 33, 34, 
+       120, 126, 39, 137, 39, 40, 60, 85, 
+       87, 105, 106, 91, 107, 127, 128, 99, 
+       135, 140, 39, 41, 43, 8, 59, 46, 
+       54, 42, 1, 44, 48, 0, 47, 49, 
+       52, 3, 4, 55, 7, 56, 39, 61, 
+       63, 18, 83, 69, 76, 62, 9, 64, 
+       78, 71, 65, 17, 82, 66, 10, 70, 
+       72, 74, 12, 13, 77, 16, 79, 39, 
+       86, 26, 88, 101, 93, 19, 104, 20, 
+       92, 94, 96, 22, 23, 100, 27, 102, 
+       39, 39, 108, 110, 28, 35, 114, 122, 
+       109, 111, 124, 116, 29, 115, 117, 119, 
+       31, 32, 123, 36, 125, 129, 130, 134, 
+       131, 132, 37, 133, 39, 136, 38, 138, 
+       139
 };
 
 static const char _indic_syllable_machine_trans_actions[] = {
        1, 0, 2, 0, 2, 0, 0, 2, 
-       0, 0, 2, 0, 0, 2, 0, 0, 
-       0, 2, 0, 0, 2, 0, 0, 2, 
-       0, 0, 2, 2, 2, 2, 2, 2, 
-       2, 2, 2, 2, 3, 0, 2, 0, 
-       2, 0, 0, 2, 0, 0, 2, 0, 
-       0, 2, 0, 0, 0, 2, 0, 0, 
-       2, 0, 0, 2, 0, 0, 2, 2, 
-       2, 2, 2, 2, 2, 2, 2, 2, 
-       4, 0, 2, 0, 2, 5, 0, 0, 
-       2, 0, 0, 2, 0, 0, 2, 0, 
-       0, 0, 2, 0, 0, 2, 0, 0, 
-       2, 0, 0, 2, 6, 2, 6, 2, 
-       6, 2, 6, 2, 7, 0, 2, 0, 
-       2, 0, 0, 2, 0, 0, 2, 0, 
-       0, 2, 0, 0, 0, 2, 0, 0, 
-       2, 0, 0, 2, 0, 0, 2, 2, 
-       2, 2, 2, 2, 2, 2, 2, 2, 
-       6, 8, 0, 11, 2, 2, 6, 0, 
-       12, 12, 0, 2, 6, 2, 6, 2, 
-       0, 13, 2, 0, 0, 2, 0, 2, 
-       2, 0, 2, 2, 2, 0, 0, 2, 
-       2, 0, 2, 2, 2, 0, 0, 2, 
-       2, 0, 2, 2, 2, 0, 0, 2, 
-       2, 0, 2, 2, 2, 0, 0, 2, 
-       2, 0, 2, 0, 0, 0, 0, 14, 
-       2, 0, 0, 2, 0, 0, 2, 0, 
-       0, 2, 0, 2, 2, 2, 2, 15, 
-       2, 0, 0, 2, 0, 2, 2, 0, 
-       2, 2, 2, 0, 0, 2, 2, 0, 
-       2, 2, 2, 0, 0, 2, 2, 0, 
-       2, 2, 2, 0, 0, 2, 2, 0, 
-       2, 2, 2, 0, 0, 2, 2, 0, 
-       2, 0, 0, 0, 0, 16, 2, 0, 
-       0, 2, 0, 0, 2, 0, 0, 2, 
-       0, 2, 2, 2, 2, 17, 6, 0, 
-       6, 2, 6, 0, 0, 6, 6, 0, 
-       6, 2, 6, 0, 0, 6, 6, 0, 
-       6, 2, 6, 0, 0, 6, 6, 0, 
-       6, 2, 6, 0, 0, 6, 6, 0, 
-       2, 0, 0, 0, 0, 18, 2, 0, 
-       0, 2, 0, 0, 2, 0, 0, 2, 
-       0, 2, 2, 2, 2, 19, 20, 2, 
-       0, 0, 0, 0, 2, 2, 2, 2, 
-       2, 0, 0, 2, 2, 0, 2, 2, 
-       2, 0, 0, 2, 2, 0, 2, 2, 
-       2, 0, 0, 2, 2, 0, 2, 2, 
-       2, 0, 0, 2, 2, 0, 2, 0, 
-       0, 0, 0, 21, 2, 0, 0, 2, 
-       0, 0, 2, 0, 0, 2, 0, 2, 
-       2, 2, 2, 0, 0, 22, 22, 0, 
-       0, 0, 0, 0, 0, 23, 2, 0, 
-       0, 0, 0, 0, 24
+       2, 2, 3, 2, 0, 2, 0, 0, 
+       0, 2, 2, 2, 2, 4, 2, 0, 
+       5, 0, 5, 6, 0, 0, 5, 2, 
+       7, 2, 0, 2, 0, 2, 0, 0, 
+       2, 2, 8, 0, 11, 2, 2, 5, 
+       0, 12, 12, 0, 2, 5, 2, 5, 
+       2, 0, 13, 2, 0, 0, 2, 0, 
+       2, 2, 0, 2, 2, 0, 0, 2, 
+       2, 0, 0, 0, 0, 2, 14, 2, 
+       0, 0, 2, 0, 2, 2, 0, 2, 
+       2, 2, 2, 0, 2, 2, 0, 0, 
+       2, 2, 0, 0, 0, 0, 2, 15, 
+       5, 0, 5, 2, 2, 0, 5, 0, 
+       0, 2, 5, 0, 0, 0, 0, 2, 
+       16, 17, 2, 0, 0, 0, 0, 2, 
+       2, 2, 2, 2, 0, 0, 2, 2, 
+       0, 0, 0, 0, 2, 0, 18, 18, 
+       0, 0, 0, 0, 19, 2, 0, 0, 
+       0
 };
 
 static const char _indic_syllable_machine_to_state_actions[] = {
@@ -823,6 +319,7 @@ static const char _indic_syllable_machine_to_state_actions[] = {
        0, 0, 0, 0, 0, 0, 0, 0, 
        0, 0, 0, 0, 0, 0, 0, 0, 
        0, 0, 0, 0, 0, 0, 0, 0, 
+       0, 0, 0, 0, 0, 0, 0, 9, 
        0, 0, 0, 0, 0, 0, 0, 0, 
        0, 0, 0, 0, 0, 0, 0, 0, 
        0, 0, 0, 0, 0, 0, 0, 0, 
@@ -835,41 +332,7 @@ static const char _indic_syllable_machine_to_state_actions[] = {
        0, 0, 0, 0, 0, 0, 0, 0, 
        0, 0, 0, 0, 0, 0, 0, 0, 
        0, 0, 0, 0, 0, 0, 0, 0, 
-       0, 0, 0, 0, 0, 0, 0, 0, 
-       0, 0, 9, 0, 0, 0, 0, 0, 
-       0, 0, 0, 0, 0, 0, 0, 0, 
-       0, 0, 0, 0, 0, 0, 0, 0, 
-       0, 0, 0, 0, 0, 0, 0, 0, 
-       0, 0, 0, 0, 0, 0, 0, 0, 
-       0, 0, 0, 0, 0, 0, 0, 0, 
-       0, 0, 0, 0, 0, 0, 0, 0, 
-       0, 0, 0, 0, 0, 0, 0, 0, 
-       0, 0, 0, 0, 0, 0, 0, 0, 
-       0, 0, 0, 0, 0, 0, 0, 0, 
-       0, 0, 0, 0, 0, 0, 0, 0, 
-       0, 0, 0, 0, 0, 0, 0, 0, 
-       0, 0, 0, 0, 0, 0, 0, 0, 
-       0, 0, 0, 0, 0, 0, 0, 0, 
-       0, 0, 0, 0, 0, 0, 0, 0, 
-       0, 0, 0, 0, 0, 0, 0, 0, 
-       0, 0, 0, 0, 0, 0, 0, 0, 
-       0, 0, 0, 0, 0, 0, 0, 0, 
-       0, 0, 0, 0, 0, 0, 0, 0, 
-       0, 0, 0, 0, 0, 0, 0, 0, 
-       0, 0, 0, 0, 0, 0, 0, 0, 
-       0, 0, 0, 0, 0, 0, 0, 0, 
-       0, 0, 0, 0, 0, 0, 0, 0, 
-       0, 0, 0, 0, 0, 0, 0, 0, 
-       0, 0, 0, 0, 0, 0, 0, 0, 
-       0, 0, 0, 0, 0, 0, 0, 0, 
-       0, 0, 0, 0, 0, 0, 0, 0, 
-       0, 0, 0, 0, 0, 0, 0, 0, 
-       0, 0, 0, 0, 0, 0, 0, 0, 
-       0, 0, 0, 0, 0, 0, 0, 0, 
-       0, 0, 0, 0, 0, 0, 0, 0, 
-       0, 0, 0, 0, 0, 0, 0, 0, 
-       0, 0, 0, 0, 0, 0, 0, 0, 
-       0, 0, 0, 0
+       0, 0, 0, 0, 0
 };
 
 static const char _indic_syllable_machine_from_state_actions[] = {
@@ -877,6 +340,7 @@ static const char _indic_syllable_machine_from_state_actions[] = {
        0, 0, 0, 0, 0, 0, 0, 0, 
        0, 0, 0, 0, 0, 0, 0, 0, 
        0, 0, 0, 0, 0, 0, 0, 0, 
+       0, 0, 0, 0, 0, 0, 0, 10, 
        0, 0, 0, 0, 0, 0, 0, 0, 
        0, 0, 0, 0, 0, 0, 0, 0, 
        0, 0, 0, 0, 0, 0, 0, 0, 
@@ -889,102 +353,35 @@ static const char _indic_syllable_machine_from_state_actions[] = {
        0, 0, 0, 0, 0, 0, 0, 0, 
        0, 0, 0, 0, 0, 0, 0, 0, 
        0, 0, 0, 0, 0, 0, 0, 0, 
-       0, 0, 0, 0, 0, 0, 0, 0, 
-       0, 0, 10, 0, 0, 0, 0, 0, 
-       0, 0, 0, 0, 0, 0, 0, 0, 
-       0, 0, 0, 0, 0, 0, 0, 0, 
-       0, 0, 0, 0, 0, 0, 0, 0, 
-       0, 0, 0, 0, 0, 0, 0, 0, 
-       0, 0, 0, 0, 0, 0, 0, 0, 
-       0, 0, 0, 0, 0, 0, 0, 0, 
-       0, 0, 0, 0, 0, 0, 0, 0, 
-       0, 0, 0, 0, 0, 0, 0, 0, 
-       0, 0, 0, 0, 0, 0, 0, 0, 
-       0, 0, 0, 0, 0, 0, 0, 0, 
-       0, 0, 0, 0, 0, 0, 0, 0, 
-       0, 0, 0, 0, 0, 0, 0, 0, 
-       0, 0, 0, 0, 0, 0, 0, 0, 
-       0, 0, 0, 0, 0, 0, 0, 0, 
-       0, 0, 0, 0, 0, 0, 0, 0, 
-       0, 0, 0, 0, 0, 0, 0, 0, 
-       0, 0, 0, 0, 0, 0, 0, 0, 
-       0, 0, 0, 0, 0, 0, 0, 0, 
-       0, 0, 0, 0, 0, 0, 0, 0, 
-       0, 0, 0, 0, 0, 0, 0, 0, 
-       0, 0, 0, 0, 0, 0, 0, 0, 
-       0, 0, 0, 0, 0, 0, 0, 0, 
-       0, 0, 0, 0, 0, 0, 0, 0, 
-       0, 0, 0, 0, 0, 0, 0, 0, 
-       0, 0, 0, 0, 0, 0, 0, 0, 
-       0, 0, 0, 0, 0, 0, 0, 0, 
-       0, 0, 0, 0, 0, 0, 0, 0, 
-       0, 0, 0, 0, 0, 0, 0, 0, 
-       0, 0, 0, 0, 0, 0, 0, 0, 
-       0, 0, 0, 0, 0, 0, 0, 0, 
-       0, 0, 0, 0, 0, 0, 0, 0, 
-       0, 0, 0, 0, 0, 0, 0, 0, 
-       0, 0, 0, 0
+       0, 0, 0, 0, 0
 };
 
 static const short _indic_syllable_machine_eof_trans[] = {
        1, 1, 1, 1, 1, 1, 1, 1, 
-       1, 1, 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, 
-       37, 37, 37, 37, 37, 37, 37, 37, 
-       37, 37, 37, 37, 37, 37, 37, 37, 
-       37, 37, 37, 37, 37, 37, 37, 37, 
-       37, 37, 37, 37, 73, 73, 78, 78, 
-       73, 73, 73, 73, 73, 73, 73, 73, 
-       73, 73, 73, 73, 73, 73, 73, 73, 
-       73, 73, 73, 73, 73, 73, 73, 73, 
-       73, 73, 73, 73, 73, 109, 109, 109, 
-       109, 109, 109, 109, 109, 109, 109, 109, 
-       109, 109, 109, 109, 109, 109, 109, 109, 
-       109, 109, 109, 109, 109, 109, 109, 109, 
-       109, 109, 109, 109, 109, 109, 109, 73, 
-       1, 146, 0, 162, 162, 162, 162, 162, 
-       162, 162, 162, 162, 162, 162, 162, 162, 
-       162, 162, 162, 162, 162, 162, 162, 162, 
-       162, 162, 162, 162, 162, 162, 162, 162, 
-       162, 162, 162, 162, 162, 162, 162, 162, 
-       162, 162, 162, 162, 162, 162, 162, 162, 
-       162, 162, 162, 162, 162, 162, 162, 162, 
-       162, 162, 162, 162, 162, 162, 162, 162, 
-       162, 224, 224, 224, 224, 224, 224, 224, 
-       224, 224, 224, 224, 224, 224, 224, 224, 
-       224, 224, 224, 224, 224, 224, 224, 224, 
-       224, 224, 224, 224, 224, 224, 224, 224, 
-       224, 224, 224, 224, 224, 224, 224, 224, 
-       224, 224, 224, 224, 224, 224, 224, 224, 
-       224, 224, 224, 224, 224, 224, 224, 224, 
-       224, 224, 224, 224, 224, 224, 224, 286, 
-       286, 286, 286, 286, 286, 286, 286, 286, 
-       286, 286, 286, 286, 286, 286, 286, 286, 
-       286, 286, 286, 286, 286, 286, 286, 286, 
-       286, 286, 286, 286, 286, 286, 286, 286, 
-       286, 286, 286, 286, 286, 286, 286, 286, 
-       286, 286, 286, 286, 286, 286, 286, 286, 
-       286, 286, 286, 286, 286, 286, 286, 286, 
-       286, 286, 342, 286, 342, 343, 343, 343, 
-       343, 343, 343, 343, 343, 343, 343, 343, 
-       343, 343, 343, 343, 343, 343, 343, 343, 
-       343, 343, 343, 343, 343, 343, 343, 343, 
-       343, 343, 343, 343, 343, 343, 343, 343, 
-       343, 343, 343, 343, 343, 343, 343, 343, 
-       343, 343, 343, 343, 343, 343, 343, 343, 
-       343, 343, 343, 343, 343, 343, 343, 343, 
-       343, 343, 286, 162, 162, 162, 162, 162, 
-       162, 162, 162, 162, 414, 414, 414, 414, 
-       414, 414, 414, 342
+       1, 11, 11, 11, 11, 11, 11, 11, 
+       11, 11, 11, 22, 22, 28, 22, 22, 
+       22, 22, 22, 22, 33, 33, 33, 33, 
+       33, 33, 33, 33, 33, 1, 43, 0, 
+       59, 59, 59, 59, 59, 59, 59, 59, 
+       59, 59, 59, 59, 59, 59, 59, 59, 
+       59, 59, 59, 59, 79, 79, 79, 79, 
+       79, 79, 79, 79, 79, 79, 79, 79, 
+       79, 79, 79, 79, 79, 79, 79, 79, 
+       79, 79, 79, 79, 79, 104, 104, 104, 
+       104, 104, 104, 104, 104, 104, 104, 104, 
+       104, 104, 104, 104, 104, 104, 104, 104, 
+       104, 121, 121, 122, 122, 122, 122, 122, 
+       122, 122, 122, 122, 122, 122, 122, 122, 
+       122, 122, 122, 122, 122, 122, 122, 104, 
+       59, 59, 59, 59, 59, 59, 59, 149, 
+       149, 149, 149, 149, 121
 };
 
-static const int indic_syllable_machine_start = 138;
-static const int indic_syllable_machine_first_final = 138;
+static const int indic_syllable_machine_start = 39;
+static const int indic_syllable_machine_first_final = 39;
 static const int indic_syllable_machine_error = -1;
 
-static const int indic_syllable_machine_en_main = 138;
+static const int indic_syllable_machine_en_main = 39;
 
 
 #line 36 "hb-ot-shape-complex-indic-machine.rl"
@@ -998,19 +395,19 @@ static const int indic_syllable_machine_en_main = 138;
   HB_STMT_START { \
     if (0) fprintf (stderr, "syllable %d..%d %s\n", ts, te, #syllable_type); \
     for (unsigned int i = ts; i < te; i++) \
-      info[i].syllable() = (syllable_serial << 4) | syllable_type; \
+      info[i].syllable() = (syllable_serial << 4) | indic_##syllable_type; \
     syllable_serial++; \
     if (unlikely (syllable_serial == 16)) syllable_serial = 1; \
   } HB_STMT_END
 
 static void
-find_syllables (hb_buffer_t *buffer)
+find_syllables_indic (hb_buffer_t *buffer)
 {
   unsigned int p, pe, eof, ts, te, act;
   int cs;
   hb_glyph_info_t *info = buffer->info;
   
-#line 1014 "hb-ot-shape-complex-indic-machine.hh"
+#line 411 "hb-ot-shape-complex-indic-machine.hh"
        {
        cs = indic_syllable_machine_start;
        ts = 0;
@@ -1026,12 +423,12 @@ find_syllables (hb_buffer_t *buffer)
 
   unsigned int syllable_serial = 1;
   
-#line 1030 "hb-ot-shape-complex-indic-machine.hh"
+#line 427 "hb-ot-shape-complex-indic-machine.hh"
        {
        int _slen;
        int _trans;
        const unsigned char *_keys;
-       const short *_inds;
+       const unsigned char *_inds;
        if ( p == pe )
                goto _test_eof;
 _resume:
@@ -1040,7 +437,7 @@ _resume:
 #line 1 "NONE"
        {ts = p;}
        break;
-#line 1044 "hb-ot-shape-complex-indic-machine.hh"
+#line 441 "hb-ot-shape-complex-indic-machine.hh"
        }
 
        _keys = _indic_syllable_machine_trans_keys + (cs<<1);
@@ -1062,26 +459,6 @@ _eof_trans:
 #line 1 "NONE"
        {te = p+1;}
        break;
-       case 14:
-#line 84 "hb-ot-shape-complex-indic-machine.rl"
-       {te = p+1;{ found_syllable (consonant_syllable); }}
-       break;
-       case 16:
-#line 85 "hb-ot-shape-complex-indic-machine.rl"
-       {te = p+1;{ found_syllable (vowel_syllable); }}
-       break;
-       case 21:
-#line 86 "hb-ot-shape-complex-indic-machine.rl"
-       {te = p+1;{ found_syllable (standalone_cluster); }}
-       break;
-       case 24:
-#line 87 "hb-ot-shape-complex-indic-machine.rl"
-       {te = p+1;{ found_syllable (symbol_cluster); }}
-       break;
-       case 18:
-#line 88 "hb-ot-shape-complex-indic-machine.rl"
-       {te = p+1;{ found_syllable (broken_cluster); }}
-       break;
        case 11:
 #line 89 "hb-ot-shape-complex-indic-machine.rl"
        {te = p+1;{ found_syllable (non_indic_cluster); }}
@@ -1090,23 +467,23 @@ _eof_trans:
 #line 84 "hb-ot-shape-complex-indic-machine.rl"
        {te = p;p--;{ found_syllable (consonant_syllable); }}
        break;
-       case 15:
+       case 14:
 #line 85 "hb-ot-shape-complex-indic-machine.rl"
        {te = p;p--;{ found_syllable (vowel_syllable); }}
        break;
-       case 20:
+       case 17:
 #line 86 "hb-ot-shape-complex-indic-machine.rl"
        {te = p;p--;{ found_syllable (standalone_cluster); }}
        break;
-       case 23:
+       case 19:
 #line 87 "hb-ot-shape-complex-indic-machine.rl"
        {te = p;p--;{ found_syllable (symbol_cluster); }}
        break;
-       case 17:
+       case 15:
 #line 88 "hb-ot-shape-complex-indic-machine.rl"
        {te = p;p--;{ found_syllable (broken_cluster); }}
        break;
-       case 19:
+       case 16:
 #line 89 "hb-ot-shape-complex-indic-machine.rl"
        {te = p;p--;{ found_syllable (non_indic_cluster); }}
        break;
@@ -1130,7 +507,7 @@ _eof_trans:
 #line 88 "hb-ot-shape-complex-indic-machine.rl"
        {{p = ((te))-1;}{ found_syllable (broken_cluster); }}
        break;
-       case 5:
+       case 6:
 #line 1 "NONE"
        {       switch( act ) {
        case 1:
@@ -1145,13 +522,13 @@ _eof_trans:
        }
        }
        break;
-       case 22:
+       case 18:
 #line 1 "NONE"
        {te = p+1;}
 #line 84 "hb-ot-shape-complex-indic-machine.rl"
        {act = 1;}
        break;
-       case 6:
+       case 5:
 #line 1 "NONE"
        {te = p+1;}
 #line 88 "hb-ot-shape-complex-indic-machine.rl"
@@ -1163,7 +540,7 @@ _eof_trans:
 #line 89 "hb-ot-shape-complex-indic-machine.rl"
        {act = 6;}
        break;
-#line 1167 "hb-ot-shape-complex-indic-machine.hh"
+#line 544 "hb-ot-shape-complex-indic-machine.hh"
        }
 
 _again:
@@ -1172,7 +549,7 @@ _again:
 #line 1 "NONE"
        {ts = 0;}
        break;
-#line 1176 "hb-ot-shape-complex-indic-machine.hh"
+#line 553 "hb-ot-shape-complex-indic-machine.hh"
        }
 
        if ( ++p != pe )
@@ -1192,4 +569,6 @@ _again:
 
 }
 
+#undef found_syllable
+
 #endif /* HB_OT_SHAPE_COMPLEX_INDIC_MACHINE_HH */
index f7e022b..5f819bd 100644 (file)
@@ -64,14 +64,14 @@ reph = (Ra H | Repha);              # possible reph
 cn = c.ZWJ?.n?;
 forced_rakar = ZWJ H ZWJ Ra;
 symbol = Symbol.N?;
-matra_group = z{0,3}.M.N?.(H | forced_rakar)?;
-syllable_tail = (z?.SM.SM?.ZWNJ?)? A{0,3}?;
+matra_group = z*.M.N?.(H | forced_rakar)?;
+syllable_tail = (z?.SM.SM?.ZWNJ?)? A*;
 halant_group = (z?.H.(ZWJ.N?)?);
 final_halant_group = halant_group | H.ZWNJ;
 medial_group = CM?;
-halant_or_matra_group = (final_halant_group | matra_group{0,4});
+halant_or_matra_group = (final_halant_group | matra_group*);
 
-complex_syllable_tail = (halant_group.cn){0,4} medial_group halant_or_matra_group syllable_tail;
+complex_syllable_tail = (halant_group.cn)* medial_group halant_or_matra_group syllable_tail;
 
 consonant_syllable =   (Repha|CS)? cn complex_syllable_tail;
 vowel_syllable =       reph? V.n? (ZWJ | complex_syllable_tail);
@@ -96,13 +96,13 @@ main := |*
   HB_STMT_START { \
     if (0) fprintf (stderr, "syllable %d..%d %s\n", ts, te, #syllable_type); \
     for (unsigned int i = ts; i < te; i++) \
-      info[i].syllable() = (syllable_serial << 4) | syllable_type; \
+      info[i].syllable() = (syllable_serial << 4) | indic_##syllable_type; \
     syllable_serial++; \
     if (unlikely (syllable_serial == 16)) syllable_serial = 1; \
   } HB_STMT_END
 
 static void
-find_syllables (hb_buffer_t *buffer)
+find_syllables_indic (hb_buffer_t *buffer)
 {
   unsigned int p, pe, eof, ts, te, act;
   int cs;
@@ -121,4 +121,6 @@ find_syllables (hb_buffer_t *buffer)
   }%%
 }
 
+#undef found_syllable
+
 #endif /* HB_OT_SHAPE_COMPLEX_INDIC_MACHINE_HH */
index d26bbb8..cc91f17 100644 (file)
  * # Date: 2018-07-30, 19:40:00 GMT [KW]
  */
 
+#include "hb.hh"
+
+#ifndef HB_NO_OT_SHAPE
+
 #include "hb-ot-shape-complex-indic.hh"
 
 #pragma GCC diagnostic push
 #pragma GCC diagnostic ignored "-Wunused-macros"
 
-#define ISC_A  INDIC_SYLLABIC_CATEGORY_AVAGRAHA                /*  17 chars; Avagraha */
-#define ISC_Bi INDIC_SYLLABIC_CATEGORY_BINDU                   /*  86 chars; Bindu */
-#define ISC_BJN        INDIC_SYLLABIC_CATEGORY_BRAHMI_JOINING_NUMBER   /*  20 chars; Brahmi_Joining_Number */
-#define ISC_Ca INDIC_SYLLABIC_CATEGORY_CANTILLATION_MARK       /*  59 chars; Cantillation_Mark */
-#define ISC_C  INDIC_SYLLABIC_CATEGORY_CONSONANT               /* 2160 chars; Consonant */
-#define ISC_CD INDIC_SYLLABIC_CATEGORY_CONSONANT_DEAD          /*  12 chars; Consonant_Dead */
-#define ISC_CF INDIC_SYLLABIC_CATEGORY_CONSONANT_FINAL         /*  67 chars; Consonant_Final */
-#define ISC_CHL        INDIC_SYLLABIC_CATEGORY_CONSONANT_HEAD_LETTER   /*   5 chars; Consonant_Head_Letter */
-#define ISC_CIP        INDIC_SYLLABIC_CATEGORY_CONSONANT_INITIAL_POSTFIXED     /*   1 chars; Consonant_Initial_Postfixed */
-#define ISC_CK INDIC_SYLLABIC_CATEGORY_CONSONANT_KILLER        /*   2 chars; Consonant_Killer */
-#define ISC_CM INDIC_SYLLABIC_CATEGORY_CONSONANT_MEDIAL        /*  29 chars; Consonant_Medial */
-#define ISC_CP INDIC_SYLLABIC_CATEGORY_CONSONANT_PLACEHOLDER   /*  22 chars; Consonant_Placeholder */
-#define ISC_CPR        INDIC_SYLLABIC_CATEGORY_CONSONANT_PRECEDING_REPHA       /*   2 chars; Consonant_Preceding_Repha */
-#define ISC_CPrf       INDIC_SYLLABIC_CATEGORY_CONSONANT_PREFIXED      /*   9 chars; Consonant_Prefixed */
-#define ISC_CS INDIC_SYLLABIC_CATEGORY_CONSONANT_SUBJOINED     /*  94 chars; Consonant_Subjoined */
-#define ISC_CSR        INDIC_SYLLABIC_CATEGORY_CONSONANT_SUCCEEDING_REPHA      /*   4 chars; Consonant_Succeeding_Repha */
-#define ISC_CWS        INDIC_SYLLABIC_CATEGORY_CONSONANT_WITH_STACKER  /*   6 chars; Consonant_With_Stacker */
-#define ISC_GM INDIC_SYLLABIC_CATEGORY_GEMINATION_MARK         /*   3 chars; Gemination_Mark */
-#define ISC_IS INDIC_SYLLABIC_CATEGORY_INVISIBLE_STACKER       /*  11 chars; Invisible_Stacker */
-#define ISC_ZWJ        INDIC_SYLLABIC_CATEGORY_JOINER                  /*   1 chars; Joiner */
-#define ISC_ML INDIC_SYLLABIC_CATEGORY_MODIFYING_LETTER        /*   1 chars; Modifying_Letter */
-#define ISC_ZWNJ       INDIC_SYLLABIC_CATEGORY_NON_JOINER              /*   1 chars; Non_Joiner */
-#define ISC_N  INDIC_SYLLABIC_CATEGORY_NUKTA                   /*  30 chars; Nukta */
-#define ISC_Nd INDIC_SYLLABIC_CATEGORY_NUMBER                  /* 481 chars; Number */
-#define ISC_NJ INDIC_SYLLABIC_CATEGORY_NUMBER_JOINER           /*   1 chars; Number_Joiner */
-#define ISC_x  INDIC_SYLLABIC_CATEGORY_OTHER                   /*   1 chars; Other */
-#define ISC_PK INDIC_SYLLABIC_CATEGORY_PURE_KILLER             /*  21 chars; Pure_Killer */
-#define ISC_RS INDIC_SYLLABIC_CATEGORY_REGISTER_SHIFTER        /*   2 chars; Register_Shifter */
-#define ISC_SM INDIC_SYLLABIC_CATEGORY_SYLLABLE_MODIFIER       /*  25 chars; Syllable_Modifier */
-#define ISC_TL INDIC_SYLLABIC_CATEGORY_TONE_LETTER             /*   7 chars; Tone_Letter */
-#define ISC_TM INDIC_SYLLABIC_CATEGORY_TONE_MARK               /*  42 chars; Tone_Mark */
-#define ISC_V  INDIC_SYLLABIC_CATEGORY_VIRAMA                  /*  27 chars; Virama */
-#define ISC_Vs INDIC_SYLLABIC_CATEGORY_VISARGA                 /*  35 chars; Visarga */
-#define ISC_Vo INDIC_SYLLABIC_CATEGORY_VOWEL                   /*  30 chars; Vowel */
-#define ISC_M  INDIC_SYLLABIC_CATEGORY_VOWEL_DEPENDENT         /* 673 chars; Vowel_Dependent */
-#define ISC_VI INDIC_SYLLABIC_CATEGORY_VOWEL_INDEPENDENT       /* 476 chars; Vowel_Independent */
-
-#define IMC_B  INDIC_MATRA_CATEGORY_BOTTOM                     /* 349 chars; Bottom */
-#define IMC_BL INDIC_MATRA_CATEGORY_BOTTOM_AND_LEFT            /*   1 chars; Bottom_And_Left */
-#define IMC_BR INDIC_MATRA_CATEGORY_BOTTOM_AND_RIGHT           /*   2 chars; Bottom_And_Right */
-#define IMC_L  INDIC_MATRA_CATEGORY_LEFT                       /*  61 chars; Left */
-#define IMC_LR INDIC_MATRA_CATEGORY_LEFT_AND_RIGHT             /*  21 chars; Left_And_Right */
-#define IMC_x  INDIC_MATRA_CATEGORY_NOT_APPLICABLE             /*   1 chars; Not_Applicable */
-#define IMC_O  INDIC_MATRA_CATEGORY_OVERSTRUCK                 /*  10 chars; Overstruck */
-#define IMC_R  INDIC_MATRA_CATEGORY_RIGHT                      /* 281 chars; Right */
-#define IMC_T  INDIC_MATRA_CATEGORY_TOP                        /* 398 chars; Top */
-#define IMC_TB INDIC_MATRA_CATEGORY_TOP_AND_BOTTOM             /*  10 chars; Top_And_Bottom */
-#define IMC_TBR        INDIC_MATRA_CATEGORY_TOP_AND_BOTTOM_AND_RIGHT   /*   1 chars; Top_And_Bottom_And_Right */
-#define IMC_TL INDIC_MATRA_CATEGORY_TOP_AND_LEFT               /*   6 chars; Top_And_Left */
-#define IMC_TLR        INDIC_MATRA_CATEGORY_TOP_AND_LEFT_AND_RIGHT     /*   4 chars; Top_And_Left_And_Right */
-#define IMC_TR INDIC_MATRA_CATEGORY_TOP_AND_RIGHT              /*  13 chars; Top_And_Right */
-#define IMC_VOL        INDIC_MATRA_CATEGORY_VISUAL_ORDER_LEFT          /*  19 chars; Visual_Order_Left */
+#define ISC_A    INDIC_SYLLABIC_CATEGORY_AVAGRAHA                    /*   17 chars; Avagraha */
+#define ISC_Bi   INDIC_SYLLABIC_CATEGORY_BINDU                       /*   86 chars; Bindu */
+#define ISC_BJN  INDIC_SYLLABIC_CATEGORY_BRAHMI_JOINING_NUMBER       /*   20 chars; Brahmi_Joining_Number */
+#define ISC_Ca   INDIC_SYLLABIC_CATEGORY_CANTILLATION_MARK           /*   59 chars; Cantillation_Mark */
+#define ISC_C    INDIC_SYLLABIC_CATEGORY_CONSONANT                   /* 2160 chars; Consonant */
+#define ISC_CD   INDIC_SYLLABIC_CATEGORY_CONSONANT_DEAD              /*   12 chars; Consonant_Dead */
+#define ISC_CF   INDIC_SYLLABIC_CATEGORY_CONSONANT_FINAL             /*   67 chars; Consonant_Final */
+#define ISC_CHL  INDIC_SYLLABIC_CATEGORY_CONSONANT_HEAD_LETTER       /*    5 chars; Consonant_Head_Letter */
+#define ISC_CIP  INDIC_SYLLABIC_CATEGORY_CONSONANT_INITIAL_POSTFIXED /*    1 chars; Consonant_Initial_Postfixed */
+#define ISC_CK   INDIC_SYLLABIC_CATEGORY_CONSONANT_KILLER            /*    2 chars; Consonant_Killer */
+#define ISC_CM   INDIC_SYLLABIC_CATEGORY_CONSONANT_MEDIAL            /*   29 chars; Consonant_Medial */
+#define ISC_CP   INDIC_SYLLABIC_CATEGORY_CONSONANT_PLACEHOLDER       /*   22 chars; Consonant_Placeholder */
+#define ISC_CPR  INDIC_SYLLABIC_CATEGORY_CONSONANT_PRECEDING_REPHA   /*    2 chars; Consonant_Preceding_Repha */
+#define ISC_CPrf INDIC_SYLLABIC_CATEGORY_CONSONANT_PREFIXED          /*    9 chars; Consonant_Prefixed */
+#define ISC_CS   INDIC_SYLLABIC_CATEGORY_CONSONANT_SUBJOINED         /*   94 chars; Consonant_Subjoined */
+#define ISC_CSR  INDIC_SYLLABIC_CATEGORY_CONSONANT_SUCCEEDING_REPHA  /*    4 chars; Consonant_Succeeding_Repha */
+#define ISC_CWS  INDIC_SYLLABIC_CATEGORY_CONSONANT_WITH_STACKER      /*    6 chars; Consonant_With_Stacker */
+#define ISC_GM   INDIC_SYLLABIC_CATEGORY_GEMINATION_MARK             /*    3 chars; Gemination_Mark */
+#define ISC_IS   INDIC_SYLLABIC_CATEGORY_INVISIBLE_STACKER           /*   11 chars; Invisible_Stacker */
+#define ISC_ZWJ  INDIC_SYLLABIC_CATEGORY_JOINER                      /*    1 chars; Joiner */
+#define ISC_ML   INDIC_SYLLABIC_CATEGORY_MODIFYING_LETTER            /*    1 chars; Modifying_Letter */
+#define ISC_ZWNJ INDIC_SYLLABIC_CATEGORY_NON_JOINER                  /*    1 chars; Non_Joiner */
+#define ISC_N    INDIC_SYLLABIC_CATEGORY_NUKTA                       /*   30 chars; Nukta */
+#define ISC_Nd   INDIC_SYLLABIC_CATEGORY_NUMBER                      /*  481 chars; Number */
+#define ISC_NJ   INDIC_SYLLABIC_CATEGORY_NUMBER_JOINER               /*    1 chars; Number_Joiner */
+#define ISC_x    INDIC_SYLLABIC_CATEGORY_OTHER                       /*    1 chars; Other */
+#define ISC_PK   INDIC_SYLLABIC_CATEGORY_PURE_KILLER                 /*   21 chars; Pure_Killer */
+#define ISC_RS   INDIC_SYLLABIC_CATEGORY_REGISTER_SHIFTER            /*    2 chars; Register_Shifter */
+#define ISC_SM   INDIC_SYLLABIC_CATEGORY_SYLLABLE_MODIFIER           /*   25 chars; Syllable_Modifier */
+#define ISC_TL   INDIC_SYLLABIC_CATEGORY_TONE_LETTER                 /*    7 chars; Tone_Letter */
+#define ISC_TM   INDIC_SYLLABIC_CATEGORY_TONE_MARK                   /*   42 chars; Tone_Mark */
+#define ISC_V    INDIC_SYLLABIC_CATEGORY_VIRAMA                      /*   27 chars; Virama */
+#define ISC_Vs   INDIC_SYLLABIC_CATEGORY_VISARGA                     /*   35 chars; Visarga */
+#define ISC_Vo   INDIC_SYLLABIC_CATEGORY_VOWEL                       /*   30 chars; Vowel */
+#define ISC_M    INDIC_SYLLABIC_CATEGORY_VOWEL_DEPENDENT             /*  673 chars; Vowel_Dependent */
+#define ISC_VI   INDIC_SYLLABIC_CATEGORY_VOWEL_INDEPENDENT           /*  476 chars; Vowel_Independent */
+
+#define IMC_B    INDIC_MATRA_CATEGORY_BOTTOM                         /*  349 chars; Bottom */
+#define IMC_BL   INDIC_MATRA_CATEGORY_BOTTOM_AND_LEFT                /*    1 chars; Bottom_And_Left */
+#define IMC_BR   INDIC_MATRA_CATEGORY_BOTTOM_AND_RIGHT               /*    2 chars; Bottom_And_Right */
+#define IMC_L    INDIC_MATRA_CATEGORY_LEFT                           /*   61 chars; Left */
+#define IMC_LR   INDIC_MATRA_CATEGORY_LEFT_AND_RIGHT                 /*   21 chars; Left_And_Right */
+#define IMC_x    INDIC_MATRA_CATEGORY_NOT_APPLICABLE                 /*    1 chars; Not_Applicable */
+#define IMC_O    INDIC_MATRA_CATEGORY_OVERSTRUCK                     /*   10 chars; Overstruck */
+#define IMC_R    INDIC_MATRA_CATEGORY_RIGHT                          /*  281 chars; Right */
+#define IMC_T    INDIC_MATRA_CATEGORY_TOP                            /*  398 chars; Top */
+#define IMC_TB   INDIC_MATRA_CATEGORY_TOP_AND_BOTTOM                 /*   10 chars; Top_And_Bottom */
+#define IMC_TBR  INDIC_MATRA_CATEGORY_TOP_AND_BOTTOM_AND_RIGHT       /*    1 chars; Top_And_Bottom_And_Right */
+#define IMC_TL   INDIC_MATRA_CATEGORY_TOP_AND_LEFT                   /*    6 chars; Top_And_Left */
+#define IMC_TLR  INDIC_MATRA_CATEGORY_TOP_AND_LEFT_AND_RIGHT         /*    4 chars; Top_And_Left_And_Right */
+#define IMC_TR   INDIC_MATRA_CATEGORY_TOP_AND_RIGHT                  /*   13 chars; Top_And_Right */
+#define IMC_VOL  INDIC_MATRA_CATEGORY_VISUAL_ORDER_LEFT              /*   19 chars; Visual_Order_Left */
+
 #pragma GCC diagnostic pop
 
 #define _(S,M) INDIC_COMBINE_CATEGORIES (ISC_##S, IMC_##M)
@@ -435,6 +440,7 @@ hb_indic_get_categories (hb_codepoint_t u)
 }
 
 #undef _
+
 #undef ISC_A
 #undef ISC_Bi
 #undef ISC_BJN
@@ -471,6 +477,7 @@ hb_indic_get_categories (hb_codepoint_t u)
 #undef ISC_Vo
 #undef ISC_M
 #undef ISC_VI
+
 #undef IMC_B
 #undef IMC_BL
 #undef IMC_BR
@@ -487,4 +494,6 @@ hb_indic_get_categories (hb_codepoint_t u)
 #undef IMC_TR
 #undef IMC_VOL
 
+#endif
+
 /* == End of generated table == */
index 1fd8fc6..26dc60d 100644 (file)
  * Google Author(s): Behdad Esfahbod
  */
 
+#include "hb.hh"
+
+#ifndef HB_NO_OT_SHAPE
+
 #include "hb-ot-shape-complex-indic.hh"
 #include "hb-ot-shape-complex-vowel-constraints.hh"
 #include "hb-ot-layout.hh"
@@ -127,62 +131,47 @@ indic_features[] =
   {HB_TAG('b','l','w','s'), F_GLOBAL_MANUAL_JOINERS},
   {HB_TAG('p','s','t','s'), F_GLOBAL_MANUAL_JOINERS},
   {HB_TAG('h','a','l','n'), F_GLOBAL_MANUAL_JOINERS},
-  /*
-   * Positioning features.
-   * We don't care about the types.
-   */
-  {HB_TAG('d','i','s','t'), F_GLOBAL},
-  {HB_TAG('a','b','v','m'), F_GLOBAL},
-  {HB_TAG('b','l','w','m'), F_GLOBAL},
 };
 
 /*
  * Must be in the same order as the indic_features array.
  */
 enum {
-  _NUKT,
-  _AKHN,
-  RPHF,
-  _RKRF,
-  PREF,
-  BLWF,
-  ABVF,
-  HALF,
-  PSTF,
-  _VATU,
-  _CJCT,
-
-  INIT,
-  _PRES,
-  _ABVS,
-  _BLWS,
-  _PSTS,
-  _HALN,
-
-  _DIST,
-  _ABVM,
-  _BLWM,
+  _INDIC_NUKT,
+  _INDIC_AKHN,
+  INDIC_RPHF,
+  _INDIC_RKRF,
+  INDIC_PREF,
+  INDIC_BLWF,
+  INDIC_ABVF,
+  INDIC_HALF,
+  INDIC_PSTF,
+  _INDIC_VATU,
+  _INDIC_CJCT,
+
+  INDIC_INIT,
+  _INDIC_PRES,
+  _INDIC_ABVS,
+  _INDIC_BLWS,
+  _INDIC_PSTS,
+  _INDIC_HALN,
 
   INDIC_NUM_FEATURES,
-  INDIC_BASIC_FEATURES = INIT, /* Don't forget to update this! */
+  INDIC_BASIC_FEATURES = INDIC_INIT, /* Don't forget to update this! */
 };
 
 static void
-setup_syllables (const hb_ot_shape_plan_t *plan,
-                hb_font_t *font,
-                hb_buffer_t *buffer);
-static void
-initial_reordering (const hb_ot_shape_plan_t *plan,
-                   hb_font_t *font,
-                   hb_buffer_t *buffer);
+setup_syllables_indic (const hb_ot_shape_plan_t *plan,
+                      hb_font_t *font,
+                      hb_buffer_t *buffer);
 static void
-final_reordering (const hb_ot_shape_plan_t *plan,
-                 hb_font_t *font,
-                 hb_buffer_t *buffer);
+initial_reordering_indic (const hb_ot_shape_plan_t *plan,
+                         hb_font_t *font,
+                         hb_buffer_t *buffer);
 static void
-clear_syllables (const hb_ot_shape_plan_t *plan,
-                hb_font_t *font,
-                hb_buffer_t *buffer);
+final_reordering_indic (const hb_ot_shape_plan_t *plan,
+                       hb_font_t *font,
+                       hb_buffer_t *buffer);
 
 static void
 collect_features_indic (hb_ot_shape_planner_t *plan)
@@ -190,7 +179,7 @@ collect_features_indic (hb_ot_shape_planner_t *plan)
   hb_ot_map_builder_t *map = &plan->map;
 
   /* Do this before any lookups have been applied. */
-  map->add_gsub_pause (setup_syllables);
+  map->add_gsub_pause (setup_syllables_indic);
 
   map->enable_feature (HB_TAG('l','o','c','l'));
   /* The Indic specs do not require ccmp, but we apply it here since if
@@ -199,14 +188,14 @@ collect_features_indic (hb_ot_shape_planner_t *plan)
 
 
   unsigned int i = 0;
-  map->add_gsub_pause (initial_reordering);
+  map->add_gsub_pause (initial_reordering_indic);
 
   for (; i < INDIC_BASIC_FEATURES; i++) {
     map->add_feature (indic_features[i]);
     map->add_gsub_pause (nullptr);
   }
 
-  map->add_gsub_pause (final_reordering);
+  map->add_gsub_pause (final_reordering_indic);
 
   for (; i < INDIC_NUM_FEATURES; i++)
     map->add_feature (indic_features[i]);
@@ -214,7 +203,7 @@ collect_features_indic (hb_ot_shape_planner_t *plan)
   map->enable_feature (HB_TAG('c','a','l','t'));
   map->enable_feature (HB_TAG('c','l','i','g'));
 
-  map->add_gsub_pause (clear_syllables);
+  map->add_gsub_pause (_hb_clear_syllables);
 }
 
 static void
@@ -224,32 +213,6 @@ override_features_indic (hb_ot_shape_planner_t *plan)
 }
 
 
-struct would_substitute_feature_t
-{
-  void init (const hb_ot_map_t *map, hb_tag_t feature_tag, bool zero_context_)
-  {
-    zero_context = zero_context_;
-    map->get_stage_lookups (0/*GSUB*/,
-                           map->get_feature_stage (0/*GSUB*/, feature_tag),
-                           &lookups, &count);
-  }
-
-  bool would_substitute (const hb_codepoint_t *glyphs,
-                        unsigned int          glyphs_count,
-                        hb_face_t            *face) const
-  {
-    for (unsigned int i = 0; i < count; i++)
-      if (hb_ot_layout_lookup_would_substitute (face, lookups[i].index, glyphs, glyphs_count, zero_context))
-       return true;
-    return false;
-  }
-
-  private:
-  const hb_ot_map_t::lookup_map_t *lookups;
-  unsigned int count;
-  bool zero_context;
-};
-
 struct indic_shape_plan_t
 {
   bool load_virama_glyph (hb_font_t *font, hb_codepoint_t *pglyph) const
@@ -274,13 +237,17 @@ struct indic_shape_plan_t
   const indic_config_t *config;
 
   bool is_old_spec;
+#ifndef HB_NO_UNISCRIBE_BUG_COMPATIBLE
   bool uniscribe_bug_compatible;
+#else
+  static constexpr bool uniscribe_bug_compatible = false;
+#endif
   mutable hb_atomic_int_t virama_glyph;
 
-  would_substitute_feature_t rphf;
-  would_substitute_feature_t pref;
-  would_substitute_feature_t blwf;
-  would_substitute_feature_t pstf;
+  hb_indic_would_substitute_feature_t rphf;
+  hb_indic_would_substitute_feature_t pref;
+  hb_indic_would_substitute_feature_t blwf;
+  hb_indic_would_substitute_feature_t pstf;
 
   hb_mask_t mask_array[INDIC_NUM_FEATURES];
 };
@@ -300,7 +267,9 @@ data_create_indic (const hb_ot_shape_plan_t *plan)
     }
 
   indic_plan->is_old_spec = indic_plan->config->has_old_spec && ((plan->map.chosen_script[0] & 0x000000FFu) != '2');
+#ifndef HB_NO_UNISCRIBE_BUG_COMPATIBLE
   indic_plan->uniscribe_bug_compatible = hb_options ().uniscribe_bug_compatible;
+#endif
   indic_plan->virama_glyph.set_relaxed (-1);
 
   /* Use zero-context would_substitute() matching for new-spec of the main
@@ -361,13 +330,13 @@ consonant_position_from_face (const indic_shape_plan_t *indic_plan,
 }
 
 
-enum syllable_type_t {
-  consonant_syllable,
-  vowel_syllable,
-  standalone_cluster,
-  symbol_cluster,
-  broken_cluster,
-  non_indic_cluster,
+enum indic_syllable_type_t {
+  indic_consonant_syllable,
+  indic_vowel_syllable,
+  indic_standalone_cluster,
+  indic_symbol_cluster,
+  indic_broken_cluster,
+  indic_non_indic_cluster,
 };
 
 #include "hb-ot-shape-complex-indic-machine.hh"
@@ -391,11 +360,11 @@ setup_masks_indic (const hb_ot_shape_plan_t *plan HB_UNUSED,
 }
 
 static void
-setup_syllables (const hb_ot_shape_plan_t *plan HB_UNUSED,
-                hb_font_t *font HB_UNUSED,
-                hb_buffer_t *buffer)
+setup_syllables_indic (const hb_ot_shape_plan_t *plan HB_UNUSED,
+                      hb_font_t *font HB_UNUSED,
+                      hb_buffer_t *buffer)
 {
-  find_syllables (buffer);
+  find_syllables_indic (buffer);
   foreach_syllable (buffer, start, end)
     buffer->unsafe_to_break (start, end);
 }
@@ -412,9 +381,9 @@ compare_indic_order (const hb_glyph_info_t *pa, const hb_glyph_info_t *pb)
 
 
 static void
-update_consonant_positions (const hb_ot_shape_plan_t *plan,
-                           hb_font_t         *font,
-                           hb_buffer_t       *buffer)
+update_consonant_positions_indic (const hb_ot_shape_plan_t *plan,
+                                 hb_font_t         *font,
+                                 hb_buffer_t       *buffer)
 {
   const indic_shape_plan_t *indic_plan = (const indic_shape_plan_t *) plan->data;
 
@@ -487,7 +456,7 @@ initial_reordering_consonant_syllable (const hb_ot_shape_plan_t *plan,
      *    and has more than one consonant, Ra is excluded from candidates for
      *    base consonants. */
     unsigned int limit = start;
-    if (indic_plan->mask_array[RPHF] &&
+    if (indic_plan->mask_array[INDIC_RPHF] &&
        start + 3 <= end &&
        (
         (indic_plan->config->reph_mode == REPH_MODE_IMPLICIT && !is_joiner (info[start + 2])) ||
@@ -571,7 +540,7 @@ initial_reordering_consonant_syllable (const hb_ot_shape_plan_t *plan,
 
       case BASE_POS_LAST_SINHALA:
       {
-        /* Sinhala base positioning is slightly different from main Indic, in that:
+       /* Sinhala base positioning is slightly different from main Indic, in that:
         * 1. Its ZWJ behavior is different,
         * 2. We don't need to look into the font for consonant positions.
         */
@@ -645,7 +614,7 @@ initial_reordering_consonant_syllable (const hb_ot_shape_plan_t *plan,
   /* Reorder characters */
 
   for (unsigned int i = start; i < base; i++)
-    info[i].indic_position() = MIN (POS_PRE_C, (indic_position_t) info[i].indic_position());
+    info[i].indic_position() = hb_min (POS_PRE_C, (indic_position_t) info[i].indic_position());
 
   if (base < end)
     info[base].indic_position() = POS_BASE_C;
@@ -700,8 +669,8 @@ initial_reordering_consonant_syllable (const hb_ot_shape_plan_t *plan,
     for (unsigned int i = base + 1; i < end; i++)
       if (info[i].indic_category() == OT_H)
       {
-        unsigned int j;
-        for (j = end - 1; j > i; j--)
+       unsigned int j;
+       for (j = end - 1; j > i; j--)
          if (is_consonant (info[j]) ||
              (disallow_double_halants && info[j].indic_category() == OT_H))
            break;
@@ -711,7 +680,7 @@ initial_reordering_consonant_syllable (const hb_ot_shape_plan_t *plan,
          memmove (&info[i], &info[i + 1], (j - i) * sizeof (info[0]));
          info[j] = t;
        }
-        break;
+       break;
       }
   }
 
@@ -742,7 +711,7 @@ initial_reordering_consonant_syllable (const hb_ot_shape_plan_t *plan,
            }
        }
       } else if (info[i].indic_position() != POS_SMVD) {
-        last_pos = (indic_position_t) info[i].indic_position();
+       last_pos = (indic_position_t) info[i].indic_position();
       }
     }
   }
@@ -758,7 +727,7 @@ initial_reordering_consonant_syllable (const hb_ot_shape_plan_t *plan,
            info[j].indic_position() = info[i].indic_position();
        last = i;
       } else if (info[i].indic_category() == OT_M)
-        last = i;
+       last = i;
   }
 
 
@@ -795,13 +764,13 @@ initial_reordering_consonant_syllable (const hb_ot_shape_plan_t *plan,
     {
       /* Note!  syllable() is a one-byte field. */
       for (unsigned int i = base; i < end; i++)
-        if (info[i].syllable() != 255)
+       if (info[i].syllable() != 255)
        {
          unsigned int max = i;
          unsigned int j = start + info[i].syllable();
          while (j != i)
          {
-           max = MAX (max, j);
+           max = hb_max (max, j);
            unsigned int next = start + info[j].syllable();
            info[j].syllable() = 255; /* So we don't process j later again. */
            j = next;
@@ -823,13 +792,13 @@ initial_reordering_consonant_syllable (const hb_ot_shape_plan_t *plan,
 
     /* Reph */
     for (unsigned int i = start; i < end && info[i].indic_position() == POS_RA_TO_BECOME_REPH; i++)
-      info[i].mask |= indic_plan->mask_array[RPHF];
+      info[i].mask |= indic_plan->mask_array[INDIC_RPHF];
 
     /* Pre-base */
-    mask = indic_plan->mask_array[HALF];
+    mask = indic_plan->mask_array[INDIC_HALF];
     if (!indic_plan->is_old_spec &&
        indic_plan->config->blwf_mode == BLWF_MODE_PRE_AND_POST)
-      mask |= indic_plan->mask_array[BLWF];
+      mask |= indic_plan->mask_array[INDIC_BLWF];
     for (unsigned int i = start; i < base; i++)
       info[i].mask  |= mask;
     /* Base */
@@ -837,7 +806,9 @@ initial_reordering_consonant_syllable (const hb_ot_shape_plan_t *plan,
     if (base < end)
       info[base].mask |= mask;
     /* Post-base */
-    mask = indic_plan->mask_array[BLWF] | indic_plan->mask_array[ABVF] | indic_plan->mask_array[PSTF];
+    mask = indic_plan->mask_array[INDIC_BLWF] |
+          indic_plan->mask_array[INDIC_ABVF] |
+          indic_plan->mask_array[INDIC_PSTF];
     for (unsigned int i = base + 1; i < end; i++)
       info[i].mask  |= mask;
   }
@@ -869,23 +840,23 @@ initial_reordering_consonant_syllable (const hb_ot_shape_plan_t *plan,
          (i + 2 == base ||
           info[i+2].indic_category() != OT_ZWJ))
       {
-       info[i  ].mask |= indic_plan->mask_array[BLWF];
-       info[i+1].mask |= indic_plan->mask_array[BLWF];
+       info[i  ].mask |= indic_plan->mask_array[INDIC_BLWF];
+       info[i+1].mask |= indic_plan->mask_array[INDIC_BLWF];
       }
   }
 
   unsigned int pref_len = 2;
-  if (indic_plan->mask_array[PREF] && base + pref_len < end)
+  if (indic_plan->mask_array[INDIC_PREF] && base + pref_len < end)
   {
     /* Find a Halant,Ra sequence and mark it for pre-base-reordering processing. */
     for (unsigned int i = base + 1; i + pref_len - 1 < end; i++) {
       hb_codepoint_t glyphs[2];
       for (unsigned int j = 0; j < pref_len; j++)
-        glyphs[j] = info[i + j].codepoint;
+       glyphs[j] = info[i + j].codepoint;
       if (indic_plan->pref.would_substitute (glyphs, pref_len, face))
       {
        for (unsigned int j = 0; j < pref_len; j++)
-         info[i++].mask |= indic_plan->mask_array[PREF];
+         info[i++].mask |= indic_plan->mask_array[INDIC_PREF];
        break;
       }
     }
@@ -906,7 +877,7 @@ initial_reordering_consonant_syllable (const hb_ot_shape_plan_t *plan,
 
        /* A ZWNJ disables HALF. */
        if (non_joiner)
-         info[j].mask &= ~indic_plan->mask_array[HALF];
+         info[j].mask &= ~indic_plan->mask_array[INDIC_HALF];
 
       } while (j > start && !is_consonant (info[j]));
     }
@@ -918,11 +889,10 @@ initial_reordering_standalone_cluster (const hb_ot_shape_plan_t *plan,
                                       hb_buffer_t *buffer,
                                       unsigned int start, unsigned int end)
 {
-  const indic_shape_plan_t *indic_plan = (const indic_shape_plan_t *) plan->data;
-
   /* We treat placeholder/dotted-circle as if they are consonants, so we
    * should just chain.  Only if not in compatibility mode that is... */
 
+  const indic_shape_plan_t *indic_plan = (const indic_shape_plan_t *) plan->data;
   if (indic_plan->uniscribe_bug_compatible)
   {
     /* For dotted-circle, this is what Uniscribe does:
@@ -936,34 +906,34 @@ initial_reordering_standalone_cluster (const hb_ot_shape_plan_t *plan,
 }
 
 static void
-initial_reordering_syllable (const hb_ot_shape_plan_t *plan,
-                            hb_face_t *face,
-                            hb_buffer_t *buffer,
-                            unsigned int start, unsigned int end)
+initial_reordering_syllable_indic (const hb_ot_shape_plan_t *plan,
+                                  hb_face_t *face,
+                                  hb_buffer_t *buffer,
+                                  unsigned int start, unsigned int end)
 {
-  syllable_type_t syllable_type = (syllable_type_t) (buffer->info[start].syllable() & 0x0F);
+  indic_syllable_type_t syllable_type = (indic_syllable_type_t) (buffer->info[start].syllable() & 0x0F);
   switch (syllable_type)
   {
-    case vowel_syllable: /* We made the vowels look like consonants.  So let's call the consonant logic! */
-    case consonant_syllable:
+    case indic_vowel_syllable: /* We made the vowels look like consonants.  So let's call the consonant logic! */
+    case indic_consonant_syllable:
      initial_reordering_consonant_syllable (plan, face, buffer, start, end);
      break;
 
-    case broken_cluster: /* We already inserted dotted-circles, so just call the standalone_cluster. */
-    case standalone_cluster:
+    case indic_broken_cluster: /* We already inserted dotted-circles, so just call the standalone_cluster. */
+    case indic_standalone_cluster:
      initial_reordering_standalone_cluster (plan, face, buffer, start, end);
      break;
 
-    case symbol_cluster:
-    case non_indic_cluster:
+    case indic_symbol_cluster:
+    case indic_non_indic_cluster:
       break;
   }
 }
 
 static inline void
-insert_dotted_circles (const hb_ot_shape_plan_t *plan HB_UNUSED,
-                      hb_font_t *font,
-                      hb_buffer_t *buffer)
+insert_dotted_circles_indic (const hb_ot_shape_plan_t *plan HB_UNUSED,
+                            hb_font_t *font,
+                            hb_buffer_t *buffer)
 {
   if (unlikely (buffer->flags & HB_BUFFER_FLAG_DO_NOT_INSERT_DOTTED_CIRCLE))
     return;
@@ -974,7 +944,7 @@ insert_dotted_circles (const hb_ot_shape_plan_t *plan HB_UNUSED,
   unsigned int count = buffer->len;
   hb_glyph_info_t *info = buffer->info;
   for (unsigned int i = 0; i < count; i++)
-    if ((info[i].syllable() & 0x0F) == broken_cluster)
+    if ((info[i].syllable() & 0x0F) == indic_broken_cluster)
     {
       has_broken_syllables = true;
       break;
@@ -999,8 +969,8 @@ insert_dotted_circles (const hb_ot_shape_plan_t *plan HB_UNUSED,
   while (buffer->idx < buffer->len && buffer->successful)
   {
     unsigned int syllable = buffer->cur().syllable();
-    syllable_type_t syllable_type = (syllable_type_t) (syllable & 0x0F);
-    if (unlikely (last_syllable != syllable && syllable_type == broken_cluster))
+    indic_syllable_type_t syllable_type = (indic_syllable_type_t) (syllable & 0x0F);
+    if (unlikely (last_syllable != syllable && syllable_type == indic_broken_cluster))
     {
       last_syllable = syllable;
 
@@ -1008,13 +978,12 @@ insert_dotted_circles (const hb_ot_shape_plan_t *plan HB_UNUSED,
       ginfo.cluster = buffer->cur().cluster;
       ginfo.mask = buffer->cur().mask;
       ginfo.syllable() = buffer->cur().syllable();
-      /* TODO Set glyph_props? */
 
       /* Insert dottedcircle after possible Repha. */
       while (buffer->idx < buffer->len && buffer->successful &&
             last_syllable == buffer->cur().syllable() &&
             buffer->cur().indic_category() == OT_Repha)
-        buffer->next_glyph ();
+       buffer->next_glyph ();
 
       buffer->output_info (ginfo);
     }
@@ -1025,21 +994,21 @@ insert_dotted_circles (const hb_ot_shape_plan_t *plan HB_UNUSED,
 }
 
 static void
-initial_reordering (const hb_ot_shape_plan_t *plan,
-                   hb_font_t *font,
-                   hb_buffer_t *buffer)
+initial_reordering_indic (const hb_ot_shape_plan_t *plan,
+                         hb_font_t *font,
+                         hb_buffer_t *buffer)
 {
-  update_consonant_positions (plan, font, buffer);
-  insert_dotted_circles (plan, font, buffer);
+  update_consonant_positions_indic (plan, font, buffer);
+  insert_dotted_circles_indic (plan, font, buffer);
 
   foreach_syllable (buffer, start, end)
-    initial_reordering_syllable (plan, font->face, buffer, start, end);
+    initial_reordering_syllable_indic (plan, font->face, buffer, start, end);
 }
 
 static void
-final_reordering_syllable (const hb_ot_shape_plan_t *plan,
-                          hb_buffer_t *buffer,
-                          unsigned int start, unsigned int end)
+final_reordering_syllable_indic (const hb_ot_shape_plan_t *plan,
+                                hb_buffer_t *buffer,
+                                unsigned int start, unsigned int end)
 {
   const indic_shape_plan_t *indic_plan = (const indic_shape_plan_t *) plan->data;
   hb_glyph_info_t *info = buffer->info;
@@ -1060,7 +1029,7 @@ final_reordering_syllable (const hb_ot_shape_plan_t *plan,
          _hb_glyph_info_ligated (&info[i]) &&
          _hb_glyph_info_multiplied (&info[i]))
       {
-        /* This will make sure that this glyph passes is_halant() test. */
+       /* This will make sure that this glyph passes is_halant() test. */
        info[i].indic_category() = OT_H;
        _hb_glyph_info_clear_ligated_and_multiplied (&info[i]);
       }
@@ -1075,7 +1044,7 @@ final_reordering_syllable (const hb_ot_shape_plan_t *plan,
    * syllable.
    */
 
-  bool try_pref = !!indic_plan->mask_array[PREF];
+  bool try_pref = !!indic_plan->mask_array[INDIC_PREF];
 
   /* Find base again */
   unsigned int base;
@@ -1085,7 +1054,7 @@ final_reordering_syllable (const hb_ot_shape_plan_t *plan,
       if (try_pref && base + 1 < end)
       {
        for (unsigned int i = base + 1; i < end; i++)
-         if ((info[i].mask & indic_plan->mask_array[PREF]) != 0)
+         if ((info[i].mask & indic_plan->mask_array[INDIC_PREF]) != 0)
          {
            if (!(_hb_glyph_info_substituted (&info[i]) &&
                  _hb_glyph_info_ligated_and_didnt_multiply (&info[i])))
@@ -1123,7 +1092,7 @@ final_reordering_syllable (const hb_ot_shape_plan_t *plan,
       }
 
       if (start < base && info[base].indic_position() > POS_BASE_C)
-        base--;
+       base--;
       break;
     }
   if (base == end && start < base &&
@@ -1213,7 +1182,7 @@ final_reordering_syllable (const hb_ot_shape_plan_t *plan,
        }
       }
       else
-        new_pos = start; /* No move. */
+       new_pos = start; /* No move. */
     }
 
     if (start < new_pos && info[new_pos].indic_position () != POS_PRE_M)
@@ -1232,14 +1201,14 @@ final_reordering_syllable (const hb_ot_shape_plan_t *plan,
 
          /* Note: this merge_clusters() is intentionally *after* the reordering.
           * Indic matra reordering is special and tricky... */
-         buffer->merge_clusters (new_pos, MIN (end, base + 1));
+         buffer->merge_clusters (new_pos, hb_min (end, base + 1));
 
          new_pos--;
        }
     } else {
       for (unsigned int i = start; i < base; i++)
        if (info[i].indic_position () == POS_PRE_M) {
-         buffer->merge_clusters (i, MIN (end, base + 1));
+         buffer->merge_clusters (i, hb_min (end, base + 1));
          break;
        }
     }
@@ -1315,7 +1284,7 @@ final_reordering_syllable (const hb_ot_shape_plan_t *plan,
       while (new_reph_pos + 1 < end && info[new_reph_pos + 1].indic_position() <= POS_AFTER_MAIN)
        new_reph_pos++;
       if (new_reph_pos < end)
-        goto reph_move;
+       goto reph_move;
     }
 
     /*       4. If reph should be positioned before post-base consonant, find
@@ -1331,7 +1300,7 @@ final_reordering_syllable (const hb_ot_shape_plan_t *plan,
             !( FLAG_UNSAFE (info[new_reph_pos + 1].indic_position()) & (FLAG (POS_POST_C) | FLAG (POS_AFTER_POST) | FLAG (POS_SMVD))))
        new_reph_pos++;
       if (new_reph_pos < end)
-        goto reph_move;
+       goto reph_move;
     }
 
     /*       5. If no consonant is found in steps 3 or 4, move reph to a position
@@ -1372,13 +1341,15 @@ final_reordering_syllable (const hb_ot_shape_plan_t *plan,
        * TEST: U+0930,U+094D,U+0915,U+094B,U+094D
        */
       if (!indic_plan->uniscribe_bug_compatible &&
-         unlikely (is_halant (info[new_reph_pos]))) {
+         unlikely (is_halant (info[new_reph_pos])))
+      {
        for (unsigned int i = base + 1; i < new_reph_pos; i++)
          if (info[i].indic_category() == OT_M) {
            /* Ok, got it. */
            new_reph_pos--;
          }
       }
+
       goto reph_move;
     }
 
@@ -1405,13 +1376,13 @@ final_reordering_syllable (const hb_ot_shape_plan_t *plan,
   if (try_pref && base + 1 < end) /* Otherwise there can't be any pre-base-reordering Ra. */
   {
     for (unsigned int i = base + 1; i < end; i++)
-      if ((info[i].mask & indic_plan->mask_array[PREF]) != 0)
+      if ((info[i].mask & indic_plan->mask_array[INDIC_PREF]) != 0)
       {
        /*       1. Only reorder a glyph produced by substitution during application
         *          of the <pref> feature. (Note that a font may shape a Ra consonant with
         *          the feature generally but block it in certain contexts.)
         */
-        /* Note: We just check that something got substituted.  We don't check that
+       /* Note: We just check that something got substituted.  We don't check that
         * the <pref> feature actually did it...
         *
         * Reorder pref only if it ligated. */
@@ -1457,7 +1428,7 @@ final_reordering_syllable (const hb_ot_shape_plan_t *plan,
          }
        }
 
-        break;
+       break;
       }
   }
 
@@ -1468,7 +1439,7 @@ final_reordering_syllable (const hb_ot_shape_plan_t *plan,
     if (!start ||
        !(FLAG_UNSAFE (_hb_glyph_info_get_general_category (&info[start - 1])) &
         FLAG_RANGE (HB_UNICODE_GENERAL_CATEGORY_FORMAT, HB_UNICODE_GENERAL_CATEGORY_NON_SPACING_MARK)))
-      info[start].mask |= indic_plan->mask_array[INIT];
+      info[start].mask |= indic_plan->mask_array[INDIC_INIT];
     else
       buffer->unsafe_to_break (start - 1, start + 1);
   }
@@ -1483,7 +1454,7 @@ final_reordering_syllable (const hb_ot_shape_plan_t *plan,
     {
       case HB_SCRIPT_TAMIL:
       case HB_SCRIPT_SINHALA:
-        break;
+       break;
 
       default:
        /* Uniscribe merges the entire syllable into a single cluster... Except for Tamil & Sinhala.
@@ -1498,15 +1469,15 @@ final_reordering_syllable (const hb_ot_shape_plan_t *plan,
 
 
 static void
-final_reordering (const hb_ot_shape_plan_t *plan,
-                 hb_font_t *font HB_UNUSED,
-                 hb_buffer_t *buffer)
+final_reordering_indic (const hb_ot_shape_plan_t *plan,
+                       hb_font_t *font HB_UNUSED,
+                       hb_buffer_t *buffer)
 {
   unsigned int count = buffer->len;
   if (unlikely (!count)) return;
 
   foreach_syllable (buffer, start, end)
-    final_reordering_syllable (plan, buffer, start, end);
+    final_reordering_syllable_indic (plan, buffer, start, end);
 
   HB_BUFFER_DEALLOCATE_VAR (buffer, indic_category);
   HB_BUFFER_DEALLOCATE_VAR (buffer, indic_position);
@@ -1514,18 +1485,6 @@ final_reordering (const hb_ot_shape_plan_t *plan,
 
 
 static void
-clear_syllables (const hb_ot_shape_plan_t *plan HB_UNUSED,
-                hb_font_t *font HB_UNUSED,
-                hb_buffer_t *buffer)
-{
-  hb_glyph_info_t *info = buffer->info;
-  unsigned int count = buffer->len;
-  for (unsigned int i = 0; i < count; i++)
-    info[i].syllable() = 0;
-}
-
-
-static void
 preprocess_text_indic (const hb_ot_shape_plan_t *plan,
                       hb_buffer_t              *buffer,
                       hb_font_t                *font)
@@ -1591,11 +1550,10 @@ decompose_indic (const hb_ot_shape_normalize_context_t *c,
      *   https://docs.microsoft.com/en-us/typography/script-development/sinhala#shaping
      */
 
-    const indic_shape_plan_t *indic_plan = (const indic_shape_plan_t *) c->plan->data;
 
+    const indic_shape_plan_t *indic_plan = (const indic_shape_plan_t *) c->plan->data;
     hb_codepoint_t glyph;
-
-    if (hb_options ().uniscribe_bug_compatible ||
+    if (indic_plan->uniscribe_bug_compatible ||
        (c->font->get_nominal_glyph (ab, &glyph) &&
         indic_plan->pstf.would_substitute (&glyph, 1, c->font->face)))
     {
@@ -1643,3 +1601,6 @@ const hb_ot_complex_shaper_t _hb_ot_complex_shaper_indic =
   HB_OT_SHAPE_ZERO_WIDTH_MARKS_NONE,
   false, /* fallback_position */
 };
+
+
+#endif
index 13ab516..1eeed68 100644 (file)
@@ -64,7 +64,14 @@ enum indic_category_t {
   OT_Ra = 16,
   OT_CM = 17,  /* Consonant-Medial. */
   OT_Symbol = 18, /* Avagraha, etc that take marks (SM,A,VD). */
-  OT_CS = 19
+  OT_CS = 19,
+
+  /* The following are used by Khmer & Myanmar shapers.  Defined
+   * here for them to share. */
+  OT_VAbv    = 26,
+  OT_VBlw    = 27,
+  OT_VPre    = 28,
+  OT_VPst    = 29,
 };
 
 #define MEDIAL_FLAGS (FLAG (OT_CM))
@@ -278,7 +285,7 @@ matra_position_indic (hb_codepoint_t u, indic_position_t side)
     case POS_POST_C:   return MATRA_POS_RIGHT (u);
     case POS_ABOVE_C:  return MATRA_POS_TOP (u);
     case POS_BELOW_C:  return MATRA_POS_BOTTOM (u);
-  };
+  }
   return side;
 }
 
@@ -359,7 +366,7 @@ set_indic_properties (hb_glyph_info_t &info)
   /* According to ScriptExtensions.txt, these Grantha marks may also be used in Tamil,
    * so the Indic shaper needs to know their categories. */
   else if (unlikely (u == 0x11301u || u == 0x11303u)) cat = OT_SM;
-  else if (unlikely (u == 0x1133cu)) cat = OT_N;
+  else if (unlikely (u == 0x1133Bu || u == 0x1133Cu)) cat = OT_N;
 
   else if (unlikely (u == 0x0AFBu)) cat = OT_N; /* https://github.com/harfbuzz/harfbuzz/issues/552 */
 
@@ -398,5 +405,31 @@ set_indic_properties (hb_glyph_info_t &info)
   info.indic_position() = pos;
 }
 
+struct hb_indic_would_substitute_feature_t
+{
+  void init (const hb_ot_map_t *map, hb_tag_t feature_tag, bool zero_context_)
+  {
+    zero_context = zero_context_;
+    map->get_stage_lookups (0/*GSUB*/,
+                           map->get_feature_stage (0/*GSUB*/, feature_tag),
+                           &lookups, &count);
+  }
+
+  bool would_substitute (const hb_codepoint_t *glyphs,
+                        unsigned int          glyphs_count,
+                        hb_face_t            *face) const
+  {
+    for (unsigned int i = 0; i < count; i++)
+      if (hb_ot_layout_lookup_would_substitute (face, lookups[i].index, glyphs, glyphs_count, zero_context))
+       return true;
+    return false;
+  }
+
+  private:
+  const hb_ot_map_t::lookup_map_t *lookups;
+  unsigned int count;
+  bool zero_context;
+};
+
 
 #endif /* HB_OT_SHAPE_COMPLEX_INDIC_HH */
index 65e0ffc..a040318 100644 (file)
@@ -226,13 +226,13 @@ static const int khmer_syllable_machine_en_main = 20;
   HB_STMT_START { \
     if (0) fprintf (stderr, "syllable %d..%d %s\n", ts, te, #syllable_type); \
     for (unsigned int i = ts; i < te; i++) \
-      info[i].syllable() = (syllable_serial << 4) | syllable_type; \
+      info[i].syllable() = (syllable_serial << 4) | khmer_##syllable_type; \
     syllable_serial++; \
     if (unlikely (syllable_serial == 16)) syllable_serial = 1; \
   } HB_STMT_END
 
 static void
-find_syllables (hb_buffer_t *buffer)
+find_syllables_khmer (hb_buffer_t *buffer)
 {
   unsigned int p, pe, eof, ts, te, act HB_UNUSED;
   int cs;
@@ -367,4 +367,6 @@ _again:
 
 }
 
+#undef found_syllable
+
 #endif /* HB_OT_SHAPE_COMPLEX_KHMER_MACHINE_HH */
index 1076a08..e7f1453 100644 (file)
@@ -83,13 +83,13 @@ main := |*
   HB_STMT_START { \
     if (0) fprintf (stderr, "syllable %d..%d %s\n", ts, te, #syllable_type); \
     for (unsigned int i = ts; i < te; i++) \
-      info[i].syllable() = (syllable_serial << 4) | syllable_type; \
+      info[i].syllable() = (syllable_serial << 4) | khmer_##syllable_type; \
     syllable_serial++; \
     if (unlikely (syllable_serial == 16)) syllable_serial = 1; \
   } HB_STMT_END
 
 static void
-find_syllables (hb_buffer_t *buffer)
+find_syllables_khmer (hb_buffer_t *buffer)
 {
   unsigned int p, pe, eof, ts, te, act HB_UNUSED;
   int cs;
@@ -108,4 +108,6 @@ find_syllables (hb_buffer_t *buffer)
   }%%
 }
 
+#undef found_syllable
+
 #endif /* HB_OT_SHAPE_COMPLEX_KHMER_MACHINE_HH */
index 5746651..fd8a9be 100644 (file)
  * Google Author(s): Behdad Esfahbod
  */
 
+#include "hb.hh"
+
+#ifndef HB_NO_OT_SHAPE
+
 #include "hb-ot-shape-complex-khmer.hh"
 #include "hb-ot-layout.hh"
 
@@ -52,50 +56,35 @@ khmer_features[] =
   {HB_TAG('a','b','v','s'), F_GLOBAL_MANUAL_JOINERS},
   {HB_TAG('b','l','w','s'), F_GLOBAL_MANUAL_JOINERS},
   {HB_TAG('p','s','t','s'), F_GLOBAL_MANUAL_JOINERS},
-  /*
-   * Positioning features.
-   * We don't care about the types.
-   */
-  {HB_TAG('d','i','s','t'), F_GLOBAL},
-  {HB_TAG('a','b','v','m'), F_GLOBAL},
-  {HB_TAG('b','l','w','m'), F_GLOBAL},
 };
 
 /*
  * Must be in the same order as the khmer_features array.
  */
 enum {
-  PREF,
-  BLWF,
-  ABVF,
-  PSTF,
-  CFAR,
+  KHMER_PREF,
+  KHMER_BLWF,
+  KHMER_ABVF,
+  KHMER_PSTF,
+  KHMER_CFAR,
 
-  _PRES,
-  _ABVS,
-  _BLWS,
-  _PSTS,
-
-  _DIST,
-  _ABVM,
-  _BLWM,
+  _KHMER_PRES,
+  _KHMER_ABVS,
+  _KHMER_BLWS,
+  _KHMER_PSTS,
 
   KHMER_NUM_FEATURES,
-  KHMER_BASIC_FEATURES = _PRES, /* Don't forget to update this! */
+  KHMER_BASIC_FEATURES = _KHMER_PRES, /* Don't forget to update this! */
 };
 
 static void
-setup_syllables (const hb_ot_shape_plan_t *plan,
-                hb_font_t *font,
-                hb_buffer_t *buffer);
-static void
-reorder (const hb_ot_shape_plan_t *plan,
-        hb_font_t *font,
-        hb_buffer_t *buffer);
+setup_syllables_khmer (const hb_ot_shape_plan_t *plan,
+                      hb_font_t *font,
+                      hb_buffer_t *buffer);
 static void
-clear_syllables (const hb_ot_shape_plan_t *plan,
-                hb_font_t *font,
-                hb_buffer_t *buffer);
+reorder_khmer (const hb_ot_shape_plan_t *plan,
+              hb_font_t *font,
+              hb_buffer_t *buffer);
 
 static void
 collect_features_khmer (hb_ot_shape_planner_t *plan)
@@ -103,8 +92,8 @@ collect_features_khmer (hb_ot_shape_planner_t *plan)
   hb_ot_map_builder_t *map = &plan->map;
 
   /* Do this before any lookups have been applied. */
-  map->add_gsub_pause (setup_syllables);
-  map->add_gsub_pause (reorder);
+  map->add_gsub_pause (setup_syllables_khmer);
+  map->add_gsub_pause (reorder_khmer);
 
   /* Testing suggests that Uniscribe does NOT pause between basic
    * features.  Test with KhmerUI.ttf and the following three
@@ -123,7 +112,7 @@ collect_features_khmer (hb_ot_shape_planner_t *plan)
   for (; i < KHMER_BASIC_FEATURES; i++)
     map->add_feature (khmer_features[i]);
 
-  map->add_gsub_pause (clear_syllables);
+  map->add_gsub_pause (_hb_clear_syllables);
 
   for (; i < KHMER_NUM_FEATURES; i++)
     map->add_feature (khmer_features[i]);
@@ -149,32 +138,6 @@ override_features_khmer (hb_ot_shape_planner_t *plan)
 }
 
 
-struct would_substitute_feature_t
-{
-  void init (const hb_ot_map_t *map, hb_tag_t feature_tag, bool zero_context_)
-  {
-    zero_context = zero_context_;
-    map->get_stage_lookups (0/*GSUB*/,
-                           map->get_feature_stage (0/*GSUB*/, feature_tag),
-                           &lookups, &count);
-  }
-
-  bool would_substitute (const hb_codepoint_t *glyphs,
-                        unsigned int          glyphs_count,
-                        hb_face_t            *face) const
-  {
-    for (unsigned int i = 0; i < count; i++)
-      if (hb_ot_layout_lookup_would_substitute (face, lookups[i].index, glyphs, glyphs_count, zero_context))
-       return true;
-    return false;
-  }
-
-  private:
-  const hb_ot_map_t::lookup_map_t *lookups;
-  unsigned int count;
-  bool zero_context;
-};
-
 struct khmer_shape_plan_t
 {
   bool get_virama_glyph (hb_font_t *font, hb_codepoint_t *pglyph) const
@@ -198,7 +161,7 @@ struct khmer_shape_plan_t
 
   mutable hb_codepoint_t virama_glyph;
 
-  would_substitute_feature_t pref;
+  hb_indic_would_substitute_feature_t pref;
 
   hb_mask_t mask_array[KHMER_NUM_FEATURES];
 };
@@ -228,10 +191,10 @@ data_destroy_khmer (void *data)
 }
 
 
-enum syllable_type_t {
-  consonant_syllable,
-  broken_cluster,
-  non_khmer_cluster,
+enum khmer_syllable_type_t {
+  khmer_consonant_syllable,
+  khmer_broken_cluster,
+  khmer_non_khmer_cluster,
 };
 
 #include "hb-ot-shape-complex-khmer-machine.hh"
@@ -253,11 +216,11 @@ setup_masks_khmer (const hb_ot_shape_plan_t *plan HB_UNUSED,
 }
 
 static void
-setup_syllables (const hb_ot_shape_plan_t *plan HB_UNUSED,
-                hb_font_t *font HB_UNUSED,
-                hb_buffer_t *buffer)
+setup_syllables_khmer (const hb_ot_shape_plan_t *plan HB_UNUSED,
+                      hb_font_t *font HB_UNUSED,
+                      hb_buffer_t *buffer)
 {
-  find_syllables (buffer);
+  find_syllables_khmer (buffer);
   foreach_syllable (buffer, start, end)
     buffer->unsafe_to_break (start, end);
 }
@@ -278,7 +241,9 @@ reorder_consonant_syllable (const hb_ot_shape_plan_t *plan,
   /* Setup masks. */
   {
     /* Post-base */
-    hb_mask_t mask = khmer_plan->mask_array[BLWF] | khmer_plan->mask_array[ABVF] | khmer_plan->mask_array[PSTF];
+    hb_mask_t mask = khmer_plan->mask_array[KHMER_BLWF] |
+                    khmer_plan->mask_array[KHMER_ABVF] |
+                    khmer_plan->mask_array[KHMER_PSTF];
     for (unsigned int i = start + 1; i < end; i++)
       info[i].mask  |= mask;
   }
@@ -305,7 +270,7 @@ reorder_consonant_syllable (const hb_ot_shape_plan_t *plan,
       if (info[i + 1].khmer_category() == OT_Ra)
       {
        for (unsigned int j = 0; j < 2; j++)
-         info[i + j].mask |= khmer_plan->mask_array[PREF];
+         info[i + j].mask |= khmer_plan->mask_array[KHMER_PREF];
 
        /* Move the Coeng,Ro sequence to the start. */
        buffer->merge_clusters (start, i + 2);
@@ -321,9 +286,9 @@ reorder_consonant_syllable (const hb_ot_shape_plan_t *plan,
         * U+1784,U+17D2,U+179A,U+17D2,U+1782
         * U+1784,U+17D2,U+1782,U+17D2,U+179A
         */
-       if (khmer_plan->mask_array[CFAR])
+       if (khmer_plan->mask_array[KHMER_CFAR])
          for (unsigned int j = i + 2; j < end; j++)
-           info[j].mask |= khmer_plan->mask_array[CFAR];
+           info[j].mask |= khmer_plan->mask_array[KHMER_CFAR];
 
        num_coengs = 2; /* Done. */
       }
@@ -342,38 +307,39 @@ reorder_consonant_syllable (const hb_ot_shape_plan_t *plan,
 }
 
 static void
-initial_reordering_syllable (const hb_ot_shape_plan_t *plan,
-                            hb_face_t *face,
-                            hb_buffer_t *buffer,
-                            unsigned int start, unsigned int end)
+reorder_syllable_khmer (const hb_ot_shape_plan_t *plan,
+                       hb_face_t *face,
+                       hb_buffer_t *buffer,
+                       unsigned int start, unsigned int end)
 {
-  syllable_type_t syllable_type = (syllable_type_t) (buffer->info[start].syllable() & 0x0F);
+  khmer_syllable_type_t syllable_type = (khmer_syllable_type_t) (buffer->info[start].syllable() & 0x0F);
   switch (syllable_type)
   {
-    case broken_cluster: /* We already inserted dotted-circles, so just call the consonant_syllable. */
-    case consonant_syllable:
+    case khmer_broken_cluster: /* We already inserted dotted-circles, so just call the consonant_syllable. */
+    case khmer_consonant_syllable:
      reorder_consonant_syllable (plan, face, buffer, start, end);
      break;
 
-    case non_khmer_cluster:
+    case khmer_non_khmer_cluster:
       break;
   }
 }
 
 static inline void
-insert_dotted_circles (const hb_ot_shape_plan_t *plan HB_UNUSED,
-                      hb_font_t *font,
-                      hb_buffer_t *buffer)
+insert_dotted_circles_khmer (const hb_ot_shape_plan_t *plan HB_UNUSED,
+                            hb_font_t *font,
+                            hb_buffer_t *buffer)
 {
   if (unlikely (buffer->flags & HB_BUFFER_FLAG_DO_NOT_INSERT_DOTTED_CIRCLE))
     return;
 
-  /* Note: This loop is extra overhead, but should not be measurable. */
+  /* Note: This loop is extra overhead, but should not be measurable.
+   * TODO Use a buffer scratch flag to remove the loop. */
   bool has_broken_syllables = false;
   unsigned int count = buffer->len;
   hb_glyph_info_t *info = buffer->info;
   for (unsigned int i = 0; i < count; i++)
-    if ((info[i].syllable() & 0x0F) == broken_cluster)
+    if ((info[i].syllable() & 0x0F) == khmer_broken_cluster)
     {
       has_broken_syllables = true;
       break;
@@ -398,8 +364,8 @@ insert_dotted_circles (const hb_ot_shape_plan_t *plan HB_UNUSED,
   while (buffer->idx < buffer->len && buffer->successful)
   {
     unsigned int syllable = buffer->cur().syllable();
-    syllable_type_t syllable_type = (syllable_type_t) (syllable & 0x0F);
-    if (unlikely (last_syllable != syllable && syllable_type == broken_cluster))
+    khmer_syllable_type_t syllable_type = (khmer_syllable_type_t) (syllable & 0x0F);
+    if (unlikely (last_syllable != syllable && syllable_type == khmer_broken_cluster))
     {
       last_syllable = syllable;
 
@@ -407,13 +373,12 @@ insert_dotted_circles (const hb_ot_shape_plan_t *plan HB_UNUSED,
       ginfo.cluster = buffer->cur().cluster;
       ginfo.mask = buffer->cur().mask;
       ginfo.syllable() = buffer->cur().syllable();
-      /* TODO Set glyph_props? */
 
       /* Insert dottedcircle after possible Repha. */
       while (buffer->idx < buffer->len && buffer->successful &&
             last_syllable == buffer->cur().syllable() &&
             buffer->cur().khmer_category() == OT_Repha)
-        buffer->next_glyph ();
+       buffer->next_glyph ();
 
       buffer->output_info (ginfo);
     }
@@ -424,29 +389,18 @@ insert_dotted_circles (const hb_ot_shape_plan_t *plan HB_UNUSED,
 }
 
 static void
-reorder (const hb_ot_shape_plan_t *plan,
-        hb_font_t *font,
-        hb_buffer_t *buffer)
+reorder_khmer (const hb_ot_shape_plan_t *plan,
+              hb_font_t *font,
+              hb_buffer_t *buffer)
 {
-  insert_dotted_circles (plan, font, buffer);
+  insert_dotted_circles_khmer (plan, font, buffer);
 
   foreach_syllable (buffer, start, end)
-    initial_reordering_syllable (plan, font->face, buffer, start, end);
+    reorder_syllable_khmer (plan, font->face, buffer, start, end);
 
   HB_BUFFER_DEALLOCATE_VAR (buffer, khmer_category);
 }
 
-static void
-clear_syllables (const hb_ot_shape_plan_t *plan HB_UNUSED,
-                hb_font_t *font HB_UNUSED,
-                hb_buffer_t *buffer)
-{
-  hb_glyph_info_t *info = buffer->info;
-  unsigned int count = buffer->len;
-  for (unsigned int i = 0; i < count; i++)
-    info[i].syllable() = 0;
-}
-
 
 static bool
 decompose_khmer (const hb_ot_shape_normalize_context_t *c,
@@ -502,3 +456,6 @@ const hb_ot_complex_shaper_t _hb_ot_complex_shaper_khmer =
   HB_OT_SHAPE_ZERO_WIDTH_MARKS_NONE,
   false, /* fallback_position */
 };
+
+
+#endif
index 6222945..11a77bf 100644 (file)
@@ -43,11 +43,10 @@ enum khmer_category_t
   OT_Robatic = 20,
   OT_Xgroup  = 21,
   OT_Ygroup  = 22,
-
-  OT_VAbv    = 26,
-  OT_VBlw    = 27,
-  OT_VPre    = 28,
-  OT_VPst    = 29,
+  //OT_VAbv = 26,
+  //OT_VBlw = 27,
+  //OT_VPre = 28,
+  //OT_VPst = 29,
 };
 
 static inline void
@@ -100,12 +99,12 @@ set_khmer_properties (hb_glyph_info_t &info)
   if (cat == (khmer_category_t) OT_M)
     switch ((int) pos)
     {
-      case POS_PRE_C:  cat = OT_VPre; break;
-      case POS_BELOW_C:        cat = OT_VBlw; break;
-      case POS_ABOVE_C:        cat = OT_VAbv; break;
-      case POS_POST_C: cat = OT_VPst; break;
+      case POS_PRE_C:  cat = (khmer_category_t) OT_VPre; break;
+      case POS_BELOW_C:        cat = (khmer_category_t) OT_VBlw; break;
+      case POS_ABOVE_C:        cat = (khmer_category_t) OT_VAbv; break;
+      case POS_POST_C: cat = (khmer_category_t) OT_VPst; break;
       default: assert (0);
-    };
+    }
 
   info.khmer_category() = cat;
 }
index 0c19e4f..c2f4c00 100644 (file)
 static const unsigned char _myanmar_syllable_machine_trans_keys[] = {
        1u, 32u, 3u, 30u, 5u, 29u, 5u, 8u, 5u, 29u, 3u, 25u, 5u, 25u, 5u, 25u, 
        3u, 29u, 3u, 29u, 3u, 29u, 3u, 29u, 1u, 16u, 3u, 29u, 3u, 29u, 3u, 29u, 
-       3u, 29u, 3u, 29u, 3u, 30u, 3u, 29u, 3u, 29u, 3u, 29u, 3u, 29u, 5u, 29u, 
-       5u, 8u, 5u, 29u, 3u, 25u, 5u, 25u, 5u, 25u, 3u, 29u, 3u, 29u, 3u, 29u, 
-       3u, 29u, 3u, 30u, 3u, 29u, 1u, 32u, 3u, 29u, 3u, 29u, 3u, 29u, 3u, 29u, 
-       3u, 29u, 3u, 30u, 3u, 29u, 3u, 29u, 3u, 29u, 3u, 29u, 1u, 32u, 8u, 8u, 
-       0
+       3u, 29u, 3u, 29u, 3u, 30u, 3u, 29u, 3u, 29u, 3u, 29u, 3u, 29u, 3u, 29u, 
+       5u, 29u, 5u, 8u, 5u, 29u, 3u, 25u, 5u, 25u, 5u, 25u, 3u, 29u, 3u, 29u, 
+       3u, 29u, 3u, 29u, 1u, 16u, 3u, 30u, 3u, 29u, 3u, 29u, 3u, 29u, 3u, 29u, 
+       3u, 29u, 3u, 30u, 3u, 29u, 3u, 29u, 3u, 29u, 3u, 29u, 3u, 29u, 3u, 30u, 
+       3u, 29u, 1u, 32u, 1u, 32u, 8u, 8u, 0
 };
 
 static const char _myanmar_syllable_machine_key_spans[] = {
        32, 28, 25, 4, 25, 23, 21, 21, 
        27, 27, 27, 27, 16, 27, 27, 27, 
-       27, 27, 28, 27, 27, 27, 27, 25, 
-       4, 25, 23, 21, 21, 27, 27, 27, 
-       27, 28, 27, 32, 27, 27, 27, 27, 
-       27, 28, 27, 27, 27, 27, 32, 1
+       27, 27, 28, 27, 27, 27, 27, 27, 
+       25, 4, 25, 23, 21, 21, 27, 27, 
+       27, 27, 16, 28, 27, 27, 27, 27, 
+       27, 28, 27, 27, 27, 27, 27, 28, 
+       27, 32, 32, 1
 };
 
 static const short _myanmar_syllable_machine_index_offsets[] = {
        0, 33, 62, 88, 93, 119, 143, 165, 
        187, 215, 243, 271, 299, 316, 344, 372, 
        400, 428, 456, 485, 513, 541, 569, 597, 
-       623, 628, 654, 678, 700, 722, 750, 778, 
-       806, 834, 863, 891, 924, 952, 980, 1008, 
-       1036, 1064, 1093, 1121, 1149, 1177, 1205, 1238
+       625, 651, 656, 682, 706, 728, 750, 778, 
+       806, 834, 862, 879, 908, 936, 964, 992, 
+       1020, 1048, 1077, 1105, 1133, 1161, 1189, 1217, 
+       1246, 1274, 1307, 1340
 };
 
 static const char _myanmar_syllable_machine_indicies[] = {
@@ -124,120 +126,134 @@ static const char _myanmar_syllable_machine_indicies[] = {
        21, 21, 21, 21, 21, 21, 32, 33, 
        34, 35, 36, 43, 21, 22, 21, 24, 
        24, 21, 25, 21, 26, 21, 21, 21, 
-       21, 21, 21, 21, 43, 21, 21, 28, 
+       21, 21, 21, 21, 21, 21, 21, 28, 
        21, 30, 21, 32, 33, 34, 35, 36, 
        21, 22, 21, 24, 24, 21, 25, 21, 
        26, 21, 21, 21, 21, 21, 21, 21, 
        43, 21, 21, 28, 21, 21, 21, 32, 
        33, 34, 35, 36, 21, 22, 21, 24, 
        24, 21, 25, 21, 26, 21, 21, 21, 
-       21, 21, 21, 21, 43, 21, 21, 28, 
+       21, 21, 21, 21, 44, 21, 21, 28, 
        29, 30, 21, 32, 33, 34, 35, 36, 
-       21, 22, 23, 24, 24, 21, 25, 21, 
+       21, 22, 21, 24, 24, 21, 25, 21, 
        26, 21, 21, 21, 21, 21, 21, 21, 
-       27, 21, 21, 28, 29, 30, 31, 32, 
-       33, 34, 35, 36, 21, 3, 3, 44, 
-       5, 44, 44, 44, 44, 44, 44, 44, 
-       44, 44, 45, 44, 44, 44, 44, 44, 
-       44, 14, 44, 44, 44, 18, 44, 3, 
-       3, 44, 5, 44, 3, 3, 44, 5, 
-       44, 44, 44, 44, 44, 44, 44, 44, 
-       44, 44, 44, 44, 44, 44, 44, 44, 
-       14, 44, 44, 44, 18, 44, 46, 44, 
-       3, 3, 44, 5, 44, 14, 44, 44, 
-       44, 44, 44, 44, 44, 47, 44, 44, 
-       44, 44, 44, 44, 14, 44, 3, 3, 
-       44, 5, 44, 44, 44, 44, 44, 44, 
-       44, 44, 44, 47, 44, 44, 44, 44, 
-       44, 44, 14, 44, 3, 3, 44, 5, 
-       44, 44, 44, 44, 44, 44, 44, 44, 
-       44, 44, 44, 44, 44, 44, 44, 44, 
-       14, 44, 2, 44, 3, 3, 44, 5, 
-       44, 6, 44, 44, 44, 44, 44, 44, 
-       44, 48, 44, 44, 48, 44, 44, 44, 
-       14, 49, 44, 44, 18, 44, 2, 44, 
-       3, 3, 44, 5, 44, 6, 44, 44, 
-       44, 44, 44, 44, 44, 44, 44, 44, 
-       44, 44, 44, 44, 14, 44, 44, 44, 
-       18, 44, 2, 44, 3, 3, 44, 5, 
-       44, 6, 44, 44, 44, 44, 44, 44, 
-       44, 48, 44, 44, 44, 44, 44, 44, 
-       14, 49, 44, 44, 18, 44, 2, 44, 
-       3, 3, 44, 5, 44, 6, 44, 44, 
-       44, 44, 44, 44, 44, 44, 44, 44, 
-       44, 44, 44, 44, 14, 49, 44, 44, 
-       18, 44, 22, 23, 24, 24, 21, 25, 
-       21, 26, 21, 21, 21, 21, 21, 21, 
-       21, 50, 21, 21, 28, 29, 30, 31, 
-       32, 33, 34, 35, 36, 37, 21, 22, 
-       51, 24, 24, 21, 25, 21, 26, 21, 
-       21, 21, 21, 21, 21, 21, 27, 21, 
-       21, 28, 29, 30, 31, 32, 33, 34, 
-       35, 36, 21, 1, 1, 2, 3, 3, 
-       3, 44, 5, 44, 6, 1, 44, 44, 
-       44, 44, 1, 44, 8, 44, 44, 10, 
+       21, 21, 21, 28, 29, 30, 21, 32, 
+       33, 34, 35, 36, 21, 22, 23, 24, 
+       24, 21, 25, 21, 26, 21, 21, 21, 
+       21, 21, 21, 21, 27, 21, 21, 28, 
+       29, 30, 31, 32, 33, 34, 35, 36, 
+       21, 46, 46, 45, 5, 45, 45, 45, 
+       45, 45, 45, 45, 45, 45, 47, 45, 
+       45, 45, 45, 45, 45, 14, 45, 45, 
+       45, 18, 45, 46, 46, 45, 5, 45, 
+       46, 46, 45, 5, 45, 45, 45, 45, 
+       45, 45, 45, 45, 45, 45, 45, 45, 
+       45, 45, 45, 45, 14, 45, 45, 45, 
+       18, 45, 48, 45, 46, 46, 45, 5, 
+       45, 14, 45, 45, 45, 45, 45, 45, 
+       45, 49, 45, 45, 45, 45, 45, 45, 
+       14, 45, 46, 46, 45, 5, 45, 45, 
+       45, 45, 45, 45, 45, 45, 45, 49, 
+       45, 45, 45, 45, 45, 45, 14, 45, 
+       46, 46, 45, 5, 45, 45, 45, 45, 
+       45, 45, 45, 45, 45, 45, 45, 45, 
+       45, 45, 45, 45, 14, 45, 2, 45, 
+       46, 46, 45, 5, 45, 6, 45, 45, 
+       45, 45, 45, 45, 45, 50, 45, 45, 
+       50, 45, 45, 45, 14, 51, 45, 45, 
+       18, 45, 2, 45, 46, 46, 45, 5, 
+       45, 6, 45, 45, 45, 45, 45, 45, 
+       45, 45, 45, 45, 45, 45, 45, 45, 
+       14, 45, 45, 45, 18, 45, 2, 45, 
+       46, 46, 45, 5, 45, 6, 45, 45, 
+       45, 45, 45, 45, 45, 50, 45, 45, 
+       45, 45, 45, 45, 14, 51, 45, 45, 
+       18, 45, 2, 45, 46, 46, 45, 5, 
+       45, 6, 45, 45, 45, 45, 45, 45, 
+       45, 45, 45, 45, 45, 45, 45, 45, 
+       14, 51, 45, 45, 18, 45, 52, 52, 
+       45, 45, 45, 45, 45, 45, 45, 45, 
+       45, 45, 45, 45, 45, 52, 45, 2, 
+       3, 46, 46, 45, 5, 45, 6, 45, 
+       45, 45, 45, 45, 45, 45, 8, 45, 
+       45, 10, 11, 12, 13, 14, 15, 16, 
+       17, 18, 19, 45, 2, 45, 46, 46, 
+       45, 5, 45, 6, 45, 45, 45, 45, 
+       45, 45, 45, 8, 45, 45, 10, 11, 
+       12, 13, 14, 15, 16, 17, 18, 45, 
+       2, 45, 46, 46, 45, 5, 45, 6, 
+       45, 45, 45, 45, 45, 45, 45, 53, 
+       45, 45, 45, 45, 45, 45, 14, 15, 
+       16, 17, 18, 45, 2, 45, 46, 46, 
+       45, 5, 45, 6, 45, 45, 45, 45, 
+       45, 45, 45, 45, 45, 45, 45, 45, 
+       45, 45, 14, 15, 16, 17, 18, 45, 
+       2, 45, 46, 46, 45, 5, 45, 6, 
+       45, 45, 45, 45, 45, 45, 45, 45, 
+       45, 45, 45, 45, 45, 45, 14, 15, 
+       16, 45, 18, 45, 2, 45, 46, 46, 
+       45, 5, 45, 6, 45, 45, 45, 45, 
+       45, 45, 45, 45, 45, 45, 45, 45, 
+       45, 45, 14, 45, 16, 45, 18, 45, 
+       2, 45, 46, 46, 45, 5, 45, 6, 
+       45, 45, 45, 45, 45, 45, 45, 45, 
+       45, 45, 45, 45, 45, 45, 14, 15, 
+       16, 17, 18, 53, 45, 2, 45, 46, 
+       46, 45, 5, 45, 6, 45, 45, 45, 
+       45, 45, 45, 45, 45, 45, 45, 10, 
+       45, 12, 45, 14, 15, 16, 17, 18, 
+       45, 2, 45, 46, 46, 45, 5, 45, 
+       6, 45, 45, 45, 45, 45, 45, 45, 
+       53, 45, 45, 10, 45, 45, 45, 14, 
+       15, 16, 17, 18, 45, 2, 45, 46, 
+       46, 45, 5, 45, 6, 45, 45, 45, 
+       45, 45, 45, 45, 54, 45, 45, 10, 
+       11, 12, 45, 14, 15, 16, 17, 18, 
+       45, 2, 45, 46, 46, 45, 5, 45, 
+       6, 45, 45, 45, 45, 45, 45, 45, 
+       45, 45, 45, 10, 11, 12, 45, 14, 
+       15, 16, 17, 18, 45, 2, 3, 46, 
+       46, 45, 5, 45, 6, 45, 45, 45, 
+       45, 45, 45, 45, 8, 45, 45, 10, 
        11, 12, 13, 14, 15, 16, 17, 18, 
-       19, 44, 1, 44, 2, 44, 3, 3, 
-       44, 5, 44, 6, 44, 44, 44, 44, 
-       44, 44, 44, 8, 44, 44, 10, 11, 
-       12, 13, 14, 15, 16, 17, 18, 44, 
-       2, 44, 3, 3, 44, 5, 44, 6, 
-       44, 44, 44, 44, 44, 44, 44, 52, 
-       44, 44, 44, 44, 44, 44, 14, 15, 
-       16, 17, 18, 44, 2, 44, 3, 3, 
-       44, 5, 44, 6, 44, 44, 44, 44, 
-       44, 44, 44, 44, 44, 44, 44, 44, 
-       44, 44, 14, 15, 16, 17, 18, 44, 
-       2, 44, 3, 3, 44, 5, 44, 6, 
-       44, 44, 44, 44, 44, 44, 44, 44, 
-       44, 44, 44, 44, 44, 44, 14, 15, 
-       16, 44, 18, 44, 2, 44, 3, 3, 
-       44, 5, 44, 6, 44, 44, 44, 44, 
-       44, 44, 44, 44, 44, 44, 44, 44, 
-       44, 44, 14, 44, 16, 44, 18, 44, 
-       2, 44, 3, 3, 44, 5, 44, 6, 
-       44, 44, 44, 44, 44, 44, 44, 44, 
-       44, 44, 44, 44, 44, 44, 14, 15, 
-       16, 17, 18, 52, 44, 2, 44, 3, 
-       3, 44, 5, 44, 6, 44, 44, 44, 
-       44, 44, 44, 44, 52, 44, 44, 10, 
-       44, 12, 44, 14, 15, 16, 17, 18, 
-       44, 2, 44, 3, 3, 44, 5, 44, 
-       6, 44, 44, 44, 44, 44, 44, 44, 
-       52, 44, 44, 10, 44, 44, 44, 14, 
-       15, 16, 17, 18, 44, 2, 44, 3, 
-       3, 44, 5, 44, 6, 44, 44, 44, 
-       44, 44, 44, 44, 52, 44, 44, 10, 
-       11, 12, 44, 14, 15, 16, 17, 18, 
-       44, 2, 3, 3, 3, 44, 5, 44, 
-       6, 44, 44, 44, 44, 44, 44, 44, 
-       8, 44, 44, 10, 11, 12, 13, 14, 
-       15, 16, 17, 18, 44, 1, 1, 53, 
-       53, 53, 53, 53, 53, 53, 53, 1, 
-       53, 53, 53, 53, 1, 53, 53, 53, 
-       53, 53, 53, 53, 53, 53, 53, 53, 
-       53, 53, 53, 53, 1, 53, 54, 53, 
-       0
+       45, 22, 23, 24, 24, 21, 25, 21, 
+       26, 21, 21, 21, 21, 21, 21, 21, 
+       55, 21, 21, 28, 29, 30, 31, 32, 
+       33, 34, 35, 36, 37, 21, 22, 56, 
+       24, 24, 21, 25, 21, 26, 21, 21, 
+       21, 21, 21, 21, 21, 27, 21, 21, 
+       28, 29, 30, 31, 32, 33, 34, 35, 
+       36, 21, 1, 1, 2, 3, 46, 46, 
+       45, 5, 45, 6, 1, 45, 45, 45, 
+       45, 1, 45, 8, 45, 45, 10, 11, 
+       12, 13, 14, 15, 16, 17, 18, 19, 
+       45, 1, 45, 1, 1, 57, 57, 57, 
+       57, 57, 57, 57, 57, 1, 57, 57, 
+       57, 57, 1, 57, 57, 57, 57, 57, 
+       57, 57, 57, 57, 57, 57, 57, 57, 
+       57, 57, 1, 57, 58, 57, 0
 };
 
 static const char _myanmar_syllable_machine_trans_targs[] = {
-       0, 1, 23, 0, 0, 24, 30, 33
-       36, 46, 37, 42, 43, 44, 26, 39, 
-       40, 41, 29, 45, 47, 0, 2, 12, 
+       0, 1, 24, 34, 0, 25, 31, 47
+       36, 50, 37, 42, 43, 44, 27, 39, 
+       40, 41, 30, 46, 51, 0, 2, 12, 
        0, 3, 9, 13, 14, 19, 20, 21, 
-       5, 16, 17, 18, 8, 22, 4, 6, 
-       7, 10, 11, 15, 0, 25, 27, 28, 
-       31, 32, 34, 35, 38, 0, 0
+       5, 16, 17, 18, 8, 23, 4, 6, 
+       7, 10, 11, 15, 22, 0, 0, 26, 
+       28, 29, 32, 33, 35, 38, 45, 48, 
+       49, 0, 0
 };
 
 static const char _myanmar_syllable_machine_trans_actions[] = {
-       3, 0, 0, 4, 5, 0, 0, 0, 
+       3, 0, 0, 0, 4, 0, 0, 0, 
+       0, 0, 0, 0, 0, 0, 0, 0, 
+       0, 0, 0, 0, 0, 5, 0, 0, 
+       6, 0, 0, 0, 0, 0, 0, 0, 
        0, 0, 0, 0, 0, 0, 0, 0, 
-       0, 0, 0, 0, 0, 6, 0, 0, 
-       7, 0, 0, 0, 0, 0, 0, 0, 
+       0, 0, 0, 0, 0, 7, 8, 0, 
        0, 0, 0, 0, 0, 0, 0, 0, 
-       0, 0, 0, 0, 8, 0, 0, 0, 
-       0, 0, 0, 0, 0, 9, 10
+       0, 9, 10
 };
 
 static const char _myanmar_syllable_machine_to_state_actions[] = {
@@ -246,7 +262,8 @@ static const char _myanmar_syllable_machine_to_state_actions[] = {
        0, 0, 0, 0, 0, 0, 0, 0, 
        0, 0, 0, 0, 0, 0, 0, 0, 
        0, 0, 0, 0, 0, 0, 0, 0, 
-       0, 0, 0, 0, 0, 0, 0, 0
+       0, 0, 0, 0, 0, 0, 0, 0, 
+       0, 0, 0, 0
 };
 
 static const char _myanmar_syllable_machine_from_state_actions[] = {
@@ -255,16 +272,18 @@ static const char _myanmar_syllable_machine_from_state_actions[] = {
        0, 0, 0, 0, 0, 0, 0, 0, 
        0, 0, 0, 0, 0, 0, 0, 0, 
        0, 0, 0, 0, 0, 0, 0, 0, 
-       0, 0, 0, 0, 0, 0, 0, 0
+       0, 0, 0, 0, 0, 0, 0, 0, 
+       0, 0, 0, 0
 };
 
 static const short _myanmar_syllable_machine_eof_trans[] = {
        0, 22, 22, 22, 22, 22, 22, 22, 
        22, 22, 22, 22, 22, 22, 22, 22, 
-       22, 22, 22, 22, 22, 22, 22, 45, 
-       45, 45, 45, 45, 45, 45, 45, 45, 
-       45, 22, 22, 45, 45, 45, 45, 45, 
-       45, 45, 45, 45, 45, 45, 54, 54
+       22, 22, 22, 22, 22, 22, 22, 22, 
+       46, 46, 46, 46, 46, 46, 46, 46, 
+       46, 46, 46, 46, 46, 46, 46, 46, 
+       46, 46, 46, 46, 46, 46, 46, 22, 
+       22, 46, 58, 58
 };
 
 static const int myanmar_syllable_machine_start = 0;
@@ -285,19 +304,19 @@ static const int myanmar_syllable_machine_en_main = 0;
   HB_STMT_START { \
     if (0) fprintf (stderr, "syllable %d..%d %s\n", ts, te, #syllable_type); \
     for (unsigned int i = ts; i < te; i++) \
-      info[i].syllable() = (syllable_serial << 4) | syllable_type; \
+      info[i].syllable() = (syllable_serial << 4) | myanmar_##syllable_type; \
     syllable_serial++; \
     if (unlikely (syllable_serial == 16)) syllable_serial = 1; \
   } HB_STMT_END
 
 static void
-find_syllables (hb_buffer_t *buffer)
+find_syllables_myanmar (hb_buffer_t *buffer)
 {
   unsigned int p, pe, eof, ts, te, act HB_UNUSED;
   int cs;
   hb_glyph_info_t *info = buffer->info;
   
-#line 301 "hb-ot-shape-complex-myanmar-machine.hh"
+#line 320 "hb-ot-shape-complex-myanmar-machine.hh"
        {
        cs = myanmar_syllable_machine_start;
        ts = 0;
@@ -313,7 +332,7 @@ find_syllables (hb_buffer_t *buffer)
 
   unsigned int syllable_serial = 1;
   
-#line 317 "hb-ot-shape-complex-myanmar-machine.hh"
+#line 336 "hb-ot-shape-complex-myanmar-machine.hh"
        {
        int _slen;
        int _trans;
@@ -327,7 +346,7 @@ _resume:
 #line 1 "NONE"
        {ts = p;}
        break;
-#line 331 "hb-ot-shape-complex-myanmar-machine.hh"
+#line 350 "hb-ot-shape-complex-myanmar-machine.hh"
        }
 
        _keys = _myanmar_syllable_machine_trans_keys + (cs<<1);
@@ -345,11 +364,11 @@ _eof_trans:
                goto _again;
 
        switch ( _myanmar_syllable_machine_trans_actions[_trans] ) {
-       case 7:
+       case 6:
 #line 86 "hb-ot-shape-complex-myanmar-machine.rl"
        {te = p+1;{ found_syllable (consonant_syllable); }}
        break;
-       case 5:
+       case 4:
 #line 87 "hb-ot-shape-complex-myanmar-machine.rl"
        {te = p+1;{ found_syllable (non_myanmar_cluster); }}
        break;
@@ -357,7 +376,7 @@ _eof_trans:
 #line 88 "hb-ot-shape-complex-myanmar-machine.rl"
        {te = p+1;{ found_syllable (punctuation_cluster); }}
        break;
-       case 4:
+       case 8:
 #line 89 "hb-ot-shape-complex-myanmar-machine.rl"
        {te = p+1;{ found_syllable (broken_cluster); }}
        break;
@@ -365,11 +384,11 @@ _eof_trans:
 #line 90 "hb-ot-shape-complex-myanmar-machine.rl"
        {te = p+1;{ found_syllable (non_myanmar_cluster); }}
        break;
-       case 6:
+       case 5:
 #line 86 "hb-ot-shape-complex-myanmar-machine.rl"
        {te = p;p--;{ found_syllable (consonant_syllable); }}
        break;
-       case 8:
+       case 7:
 #line 89 "hb-ot-shape-complex-myanmar-machine.rl"
        {te = p;p--;{ found_syllable (broken_cluster); }}
        break;
@@ -377,7 +396,7 @@ _eof_trans:
 #line 90 "hb-ot-shape-complex-myanmar-machine.rl"
        {te = p;p--;{ found_syllable (non_myanmar_cluster); }}
        break;
-#line 381 "hb-ot-shape-complex-myanmar-machine.hh"
+#line 400 "hb-ot-shape-complex-myanmar-machine.hh"
        }
 
 _again:
@@ -386,7 +405,7 @@ _again:
 #line 1 "NONE"
        {ts = 0;}
        break;
-#line 390 "hb-ot-shape-complex-myanmar-machine.hh"
+#line 409 "hb-ot-shape-complex-myanmar-machine.hh"
        }
 
        if ( ++p != pe )
index 7845a86..67133cd 100644 (file)
@@ -69,15 +69,15 @@ k = (Ra As H);                      # Kinzi
 
 c = C|Ra;                      # is_consonant
 
-medial_group = MY? MR? MW? MH? As?;
+medial_group = MY? As? MR? ((MW MH? | MH) As?)?;
 main_vowel_group = (VPre.VS?)* VAbv* VBlw* A* (DB As?)?;
 post_vowel_group = VPst MH? As* VAbv* A* (DB As?)?;
 pwo_tone_group = PT A* DB? As?;
 
 complex_syllable_tail = As* medial_group main_vowel_group post_vowel_group* pwo_tone_group* V* j?;
-syllable_tail = (H | complex_syllable_tail);
+syllable_tail = (H (c|IV).VS?)* (H | complex_syllable_tail);
 
-consonant_syllable =   (k|CS)? (c|IV|D|GB).VS? (H (c|IV).VS?)* syllable_tail;
+consonant_syllable =   (k|CS)? (c|IV|D|GB).VS? syllable_tail;
 punctuation_cluster =  P V;
 broken_cluster =       k? VS? syllable_tail;
 other =                        any;
@@ -97,13 +97,13 @@ main := |*
   HB_STMT_START { \
     if (0) fprintf (stderr, "syllable %d..%d %s\n", ts, te, #syllable_type); \
     for (unsigned int i = ts; i < te; i++) \
-      info[i].syllable() = (syllable_serial << 4) | syllable_type; \
+      info[i].syllable() = (syllable_serial << 4) | myanmar_##syllable_type; \
     syllable_serial++; \
     if (unlikely (syllable_serial == 16)) syllable_serial = 1; \
   } HB_STMT_END
 
 static void
-find_syllables (hb_buffer_t *buffer)
+find_syllables_myanmar (hb_buffer_t *buffer)
 {
   unsigned int p, pe, eof, ts, te, act HB_UNUSED;
   int cs;
index 70ab972..fc3490d 100644 (file)
  * Google Author(s): Behdad Esfahbod
  */
 
+#include "hb.hh"
+
+#ifndef HB_NO_OT_SHAPE
+
 #include "hb-ot-shape-complex-myanmar.hh"
 
 
@@ -32,7 +36,7 @@
  */
 
 static const hb_tag_t
-basic_features[] =
+myanmar_basic_features[] =
 {
   /*
    * Basic features.
@@ -44,7 +48,7 @@ basic_features[] =
   HB_TAG('p','s','t','f'),
 };
 static const hb_tag_t
-other_features[] =
+myanmar_other_features[] =
 {
   /*
    * Other features.
@@ -55,36 +59,13 @@ other_features[] =
   HB_TAG('b','l','w','s'),
   HB_TAG('p','s','t','s'),
 };
-static const hb_tag_t
-positioning_features[] =
-{
-  /*
-   * Positioning features.
-   * We don't care about the types.
-   */
-  HB_TAG('d','i','s','t'),
-  /* Pre-release version of Windows 8 Myanmar font had abvm,blwm
-   * features.  The released Windows 8 version of the font (as well
-   * as the released spec) used 'mark' instead.  The Windows 8
-   * shaper however didn't apply 'mark' but did apply 'mkmk'.
-   * Perhaps it applied abvm/blwm.  This was fixed in a Windows 8
-   * update, so now it applies mark/mkmk.  We are guessing that
-   * it still applies abvm/blwm too.
-   */
-  HB_TAG('a','b','v','m'),
-  HB_TAG('b','l','w','m'),
-};
 
 static void
-setup_syllables (const hb_ot_shape_plan_t *plan,
-                hb_font_t *font,
-                hb_buffer_t *buffer);
-static void
-reorder (const hb_ot_shape_plan_t *plan,
-        hb_font_t *font,
-        hb_buffer_t *buffer);
+setup_syllables_myanmar (const hb_ot_shape_plan_t *plan,
+                        hb_font_t *font,
+                        hb_buffer_t *buffer);
 static void
-clear_syllables (const hb_ot_shape_plan_t *plan,
+reorder_myanmar (const hb_ot_shape_plan_t *plan,
                 hb_font_t *font,
                 hb_buffer_t *buffer);
 
@@ -94,7 +75,7 @@ collect_features_myanmar (hb_ot_shape_planner_t *plan)
   hb_ot_map_builder_t *map = &plan->map;
 
   /* Do this before any lookups have been applied. */
-  map->add_gsub_pause (setup_syllables);
+  map->add_gsub_pause (setup_syllables_myanmar);
 
   map->enable_feature (HB_TAG('l','o','c','l'));
   /* The Indic specs do not require ccmp, but we apply it here since if
@@ -102,21 +83,18 @@ collect_features_myanmar (hb_ot_shape_planner_t *plan)
   map->enable_feature (HB_TAG('c','c','m','p'));
 
 
-  map->add_gsub_pause (reorder);
+  map->add_gsub_pause (reorder_myanmar);
 
-  for (unsigned int i = 0; i < ARRAY_LENGTH (basic_features); i++)
+  for (unsigned int i = 0; i < ARRAY_LENGTH (myanmar_basic_features); i++)
   {
-    map->enable_feature (basic_features[i], F_MANUAL_ZWJ);
+    map->enable_feature (myanmar_basic_features[i], F_MANUAL_ZWJ);
     map->add_gsub_pause (nullptr);
   }
 
-  map->add_gsub_pause (clear_syllables);
-
-  for (unsigned int i = 0; i < ARRAY_LENGTH (other_features); i++)
-    map->enable_feature (other_features[i], F_MANUAL_ZWJ);
+  map->add_gsub_pause (_hb_clear_syllables);
 
-  for (unsigned int i = 0; i < ARRAY_LENGTH (positioning_features); i++)
-    map->enable_feature (positioning_features[i]);
+  for (unsigned int i = 0; i < ARRAY_LENGTH (myanmar_other_features); i++)
+    map->enable_feature (myanmar_other_features[i], F_MANUAL_ZWJ);
 }
 
 static void
@@ -126,11 +104,11 @@ override_features_myanmar (hb_ot_shape_planner_t *plan)
 }
 
 
-enum syllable_type_t {
-  consonant_syllable,
-  punctuation_cluster,
-  broken_cluster,
-  non_myanmar_cluster,
+enum myanmar_syllable_type_t {
+  myanmar_consonant_syllable,
+  myanmar_punctuation_cluster,
+  myanmar_broken_cluster,
+  myanmar_non_myanmar_cluster,
 };
 
 #include "hb-ot-shape-complex-myanmar-machine.hh"
@@ -138,8 +116,8 @@ enum syllable_type_t {
 
 static void
 setup_masks_myanmar (const hb_ot_shape_plan_t *plan HB_UNUSED,
-                  hb_buffer_t              *buffer,
-                  hb_font_t                *font HB_UNUSED)
+                    hb_buffer_t              *buffer,
+                    hb_font_t                *font HB_UNUSED)
 {
   HB_BUFFER_ALLOCATE_VAR (buffer, myanmar_category);
   HB_BUFFER_ALLOCATE_VAR (buffer, myanmar_position);
@@ -154,11 +132,11 @@ setup_masks_myanmar (const hb_ot_shape_plan_t *plan HB_UNUSED,
 }
 
 static void
-setup_syllables (const hb_ot_shape_plan_t *plan HB_UNUSED,
-                hb_font_t *font HB_UNUSED,
-                hb_buffer_t *buffer)
+setup_syllables_myanmar (const hb_ot_shape_plan_t *plan HB_UNUSED,
+                        hb_font_t *font HB_UNUSED,
+                        hb_buffer_t *buffer)
 {
-  find_syllables (buffer);
+  find_syllables_myanmar (buffer);
   foreach_syllable (buffer, start, end)
     buffer->unsafe_to_break (start, end);
 }
@@ -261,7 +239,7 @@ initial_reordering_consonant_syllable (hb_buffer_t *buffer,
       }
       if (pos == POS_BELOW_C && info[i].myanmar_category() != OT_A)
       {
-        pos = POS_AFTER_SUB;
+       pos = POS_AFTER_SUB;
        info[i].myanmar_position() = pos;
        continue;
       }
@@ -274,39 +252,40 @@ initial_reordering_consonant_syllable (hb_buffer_t *buffer,
 }
 
 static void
-initial_reordering_syllable (const hb_ot_shape_plan_t *plan HB_UNUSED,
-                            hb_face_t *face HB_UNUSED,
-                            hb_buffer_t *buffer,
-                            unsigned int start, unsigned int end)
+reorder_syllable_myanmar (const hb_ot_shape_plan_t *plan HB_UNUSED,
+                         hb_face_t *face HB_UNUSED,
+                         hb_buffer_t *buffer,
+                         unsigned int start, unsigned int end)
 {
-  syllable_type_t syllable_type = (syllable_type_t) (buffer->info[start].syllable() & 0x0F);
+  myanmar_syllable_type_t syllable_type = (myanmar_syllable_type_t) (buffer->info[start].syllable() & 0x0F);
   switch (syllable_type) {
 
-    case broken_cluster: /* We already inserted dotted-circles, so just call the consonant_syllable. */
-    case consonant_syllable:
+    case myanmar_broken_cluster: /* We already inserted dotted-circles, so just call the consonant_syllable. */
+    case myanmar_consonant_syllable:
       initial_reordering_consonant_syllable  (buffer, start, end);
       break;
 
-    case punctuation_cluster:
-    case non_myanmar_cluster:
+    case myanmar_punctuation_cluster:
+    case myanmar_non_myanmar_cluster:
       break;
   }
 }
 
 static inline void
-insert_dotted_circles (const hb_ot_shape_plan_t *plan HB_UNUSED,
-                      hb_font_t *font,
-                      hb_buffer_t *buffer)
+insert_dotted_circles_myanmar (const hb_ot_shape_plan_t *plan HB_UNUSED,
+                              hb_font_t *font,
+                              hb_buffer_t *buffer)
 {
   if (unlikely (buffer->flags & HB_BUFFER_FLAG_DO_NOT_INSERT_DOTTED_CIRCLE))
     return;
 
-  /* Note: This loop is extra overhead, but should not be measurable. */
+  /* Note: This loop is extra overhead, but should not be measurable.
+   * TODO Use a buffer scratch flag to remove the loop. */
   bool has_broken_syllables = false;
   unsigned int count = buffer->len;
   hb_glyph_info_t *info = buffer->info;
   for (unsigned int i = 0; i < count; i++)
-    if ((info[i].syllable() & 0x0F) == broken_cluster)
+    if ((info[i].syllable() & 0x0F) == myanmar_broken_cluster)
     {
       has_broken_syllables = true;
       break;
@@ -331,8 +310,8 @@ insert_dotted_circles (const hb_ot_shape_plan_t *plan HB_UNUSED,
   while (buffer->idx < buffer->len && buffer->successful)
   {
     unsigned int syllable = buffer->cur().syllable();
-    syllable_type_t syllable_type = (syllable_type_t) (syllable & 0x0F);
-    if (unlikely (last_syllable != syllable && syllable_type == broken_cluster))
+    myanmar_syllable_type_t syllable_type = (myanmar_syllable_type_t) (syllable & 0x0F);
+    if (unlikely (last_syllable != syllable && syllable_type == myanmar_broken_cluster))
     {
       last_syllable = syllable;
 
@@ -350,30 +329,19 @@ insert_dotted_circles (const hb_ot_shape_plan_t *plan HB_UNUSED,
 }
 
 static void
-reorder (const hb_ot_shape_plan_t *plan,
-        hb_font_t *font,
-        hb_buffer_t *buffer)
+reorder_myanmar (const hb_ot_shape_plan_t *plan,
+                hb_font_t *font,
+                hb_buffer_t *buffer)
 {
-  insert_dotted_circles (plan, font, buffer);
+  insert_dotted_circles_myanmar (plan, font, buffer);
 
   foreach_syllable (buffer, start, end)
-    initial_reordering_syllable (plan, font->face, buffer, start, end);
+    reorder_syllable_myanmar (plan, font->face, buffer, start, end);
 
   HB_BUFFER_DEALLOCATE_VAR (buffer, myanmar_category);
   HB_BUFFER_DEALLOCATE_VAR (buffer, myanmar_position);
 }
 
-static void
-clear_syllables (const hb_ot_shape_plan_t *plan HB_UNUSED,
-                hb_font_t *font HB_UNUSED,
-                hb_buffer_t *buffer)
-{
-  hb_glyph_info_t *info = buffer->info;
-  unsigned int count = buffer->len;
-  for (unsigned int i = 0; i < count; i++)
-    info[i].syllable() = 0;
-}
-
 
 const hb_ot_complex_shaper_t _hb_ot_complex_shaper_myanmar =
 {
@@ -414,3 +382,6 @@ const hb_ot_complex_shaper_t _hb_ot_complex_shaper_myanmar_zawgyi =
   HB_OT_SHAPE_ZERO_WIDTH_MARKS_NONE,
   false, /* fallback_position */
 };
+
+
+#endif
index 3e9537a..7b9821e 100644 (file)
@@ -49,10 +49,10 @@ enum myanmar_category_t {
   OT_MW  = 23, /* Various consonant medial types */
   OT_MY  = 24, /* Various consonant medial types */
   OT_PT  = 25, /* Pwo and other tones */
-  OT_VAbv = 26,
-  OT_VBlw = 27,
-  OT_VPre = 28,
-  OT_VPst = 29,
+  //OT_VAbv = 26,
+  //OT_VBlw = 27,
+  //OT_VPre = 28,
+  //OT_VPst = 29,
   OT_VS   = 30, /* Variation selectors */
   OT_P    = 31, /* Punctuation */
   OT_D    = 32, /* Digits except zero */
@@ -146,7 +146,7 @@ set_myanmar_properties (hb_glyph_info_t &info)
       break;
 
     case 0xAA74u: case 0xAA75u: case 0xAA76u:
-      /* https://github.com/roozbehp/unicode-data/issues/3 */
+      /* https://github.com/harfbuzz/harfbuzz/issues/218 */
       cat = OT_C;
       break;
   }
@@ -155,11 +155,11 @@ set_myanmar_properties (hb_glyph_info_t &info)
   {
     switch ((int) pos)
     {
-      case POS_PRE_C:  cat = OT_VPre;
+      case POS_PRE_C:  cat = (myanmar_category_t) OT_VPre;
                        pos = POS_PRE_M; break;
-      case POS_ABOVE_C:        cat = OT_VAbv;   break;
-      case POS_BELOW_C:        cat = OT_VBlw;   break;
-      case POS_POST_C: cat = OT_VPst;   break;
+      case POS_ABOVE_C:        cat = (myanmar_category_t) OT_VAbv;   break;
+      case POS_BELOW_C:        cat = (myanmar_category_t) OT_VBlw;   break;
+      case POS_POST_C: cat = (myanmar_category_t) OT_VPst;   break;
     }
   }
 
index 650c980..347ea2e 100644 (file)
  * Google Author(s): Behdad Esfahbod
  */
 
+#include "hb.hh"
+
+#ifndef HB_NO_OT_SHAPE
+
 #include "hb-ot-shape-complex.hh"
 
 
@@ -218,6 +222,10 @@ do_thai_pua_shaping (const hb_ot_shape_plan_t *plan HB_UNUSED,
                     hb_buffer_t              *buffer,
                     hb_font_t                *font)
 {
+#ifdef HB_NO_OT_SHAPE_COMPLEX_THAI_FALLBACK
+  return;
+#endif
+
   thai_above_state_t above_state = thai_above_start_state[NOT_CONSONANT];
   thai_below_state_t below_state = thai_below_start_state[NOT_CONSONANT];
   unsigned int base = 0;
@@ -381,3 +389,6 @@ const hb_ot_complex_shaper_t _hb_ot_complex_shaper_thai =
   HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_GDEF_LATE,
   false,/* fallback_position */
 };
+
+
+#endif
index c9410e4..462342c 100644 (file)
 
 #line 38 "hb-ot-shape-complex-use-machine.hh"
 static const unsigned char _use_syllable_machine_trans_keys[] = {
-       12u, 44u, 1u, 15u, 1u, 1u, 12u, 44u, 0u, 44u, 21u, 21u, 8u, 44u, 8u, 44u,
-       1u, 15u, 1u, 1u, 8u, 44u, 8u, 44u, 8u, 39u, 8u, 26u, 8u, 26u, 8u, 26u,
-       8u, 39u, 8u, 39u, 8u, 39u, 8u, 44u, 8u, 44u, 8u, 44u, 8u, 44u, 8u, 44u,
-       8u, 44u, 8u, 44u, 8u, 44u, 1u, 39u, 8u, 44u, 13u, 21u, 4u, 4u, 13u, 13u,
-       8u, 44u, 8u, 44u, 8u, 44u, 8u, 39u, 8u, 26u, 8u, 26u, 8u, 26u, 8u, 39u,
-       8u, 39u, 8u, 39u, 8u, 44u, 8u, 44u, 8u, 44u, 8u, 44u, 8u, 44u, 8u, 44u,
-       8u, 44u, 8u, 44u, 1u, 39u, 1u, 15u, 12u, 44u, 1u, 44u, 8u, 44u, 21u, 42u,
-       41u, 42u, 42u, 42u, 1u, 5u, 0
+       12u, 48u, 1u, 15u, 1u, 1u, 12u, 48u, 1u, 1u, 0u, 48u, 21u, 21u, 11u, 48u, 
+       11u, 48u, 1u, 15u, 1u, 1u, 11u, 48u, 22u, 48u, 23u, 48u, 24u, 47u, 25u, 47u, 
+       26u, 47u, 45u, 46u, 46u, 46u, 24u, 48u, 24u, 48u, 24u, 48u, 1u, 1u, 24u, 48u, 
+       23u, 48u, 23u, 48u, 23u, 48u, 22u, 48u, 22u, 48u, 22u, 48u, 22u, 48u, 11u, 48u, 
+       1u, 48u, 11u, 48u, 13u, 21u, 4u, 4u, 13u, 13u, 11u, 48u, 11u, 48u, 41u, 42u, 
+       42u, 42u, 11u, 48u, 11u, 48u, 22u, 48u, 23u, 48u, 24u, 47u, 25u, 47u, 26u, 47u, 
+       45u, 46u, 46u, 46u, 24u, 48u, 24u, 48u, 24u, 48u, 24u, 48u, 23u, 48u, 23u, 48u, 
+       23u, 48u, 22u, 48u, 22u, 48u, 22u, 48u, 22u, 48u, 11u, 48u, 1u, 48u, 1u, 15u, 
+       4u, 4u, 13u, 21u, 13u, 13u, 12u, 48u, 1u, 48u, 11u, 48u, 41u, 42u, 42u, 42u, 
+       21u, 42u, 1u, 5u, 0
 };
 
 static const char _use_syllable_machine_key_spans[] = {
-       33, 15, 1, 33, 45, 1, 37, 37,
-       15, 1, 37, 37, 32, 19, 19, 19,
-       32, 32, 32, 37, 37, 37, 37, 37,
-       37, 37, 37, 39, 37, 9, 1, 1,
-       37, 37, 37, 32, 19, 19, 19, 32,
-       32, 32, 37, 37, 37, 37, 37, 37,
-       37, 37, 39, 15, 33, 44, 37, 22,
-       2, 1, 5
+       37, 15, 1, 37, 1, 49, 1, 38, 
+       38, 15, 1, 38, 27, 26, 24, 23, 
+       22, 2, 1, 25, 25, 25, 1, 25, 
+       26, 26, 26, 27, 27, 27, 27, 38, 
+       48, 38, 9, 1, 1, 38, 38, 2, 
+       1, 38, 38, 27, 26, 24, 23, 22, 
+       2, 1, 25, 25, 25, 25, 26, 26, 
+       26, 27, 27, 27, 27, 38, 48, 15, 
+       1, 9, 1, 37, 48, 38, 2, 1, 
+       22, 5
 };
 
 static const short _use_syllable_machine_index_offsets[] = {
-       0, 34, 50, 52, 86, 132, 134, 172,
-       210, 226, 228, 266, 304, 337, 357, 377,
-       397, 430, 463, 496, 534, 572, 610, 648,
-       686, 724, 762, 800, 840, 878, 888, 890,
-       892, 930, 968, 1006, 1039, 1059, 1079, 1099,
-       1132, 1165, 1198, 1236, 1274, 1312, 1350, 1388,
-       1426, 1464, 1502, 1542, 1558, 1592, 1637, 1675,
-       1698, 1701, 1703
+       0, 38, 54, 56, 94, 96, 146, 148, 
+       187, 226, 242, 244, 283, 311, 338, 363, 
+       387, 410, 413, 415, 441, 467, 493, 495, 
+       521, 548, 575, 602, 630, 658, 686, 714, 
+       753, 802, 841, 851, 853, 855, 894, 933, 
+       936, 938, 977, 1016, 1044, 1071, 1096, 1120, 
+       1143, 1146, 1148, 1174, 1200, 1226, 1252, 1279, 
+       1306, 1333, 1361, 1389, 1417, 1445, 1484, 1533, 
+       1549, 1551, 1561, 1563, 1601, 1650, 1689, 1692, 
+       1694, 1717
 };
 
 static const char _use_syllable_machine_indicies[] = {
-       1, 0, 0, 0, 0, 0, 0, 0,
-       0, 0, 0, 0, 0, 0, 0, 0,
-       0, 0, 0, 0, 0, 0, 0, 0,
-       0, 0, 0, 0, 0, 0, 0, 0,
-       1, 0, 3, 2, 2, 2, 2, 2, 
+       1, 0, 0, 0, 0, 0, 0, 0, 
+       0, 0, 0, 0, 0, 0, 0, 0, 
+       0, 0, 0, 0, 0, 0, 0, 0, 
+       0, 0, 0, 0, 0, 0, 0, 0, 
+       1, 0, 0, 0, 1, 0, 3, 2, 
        2, 2, 2, 2, 2, 2, 2, 2, 
-       4, 2, 3, 2, 6, 5, 5, 5,
-       5, 5, 5, 5, 5, 5, 5, 5,
-       5, 5, 5, 5, 5, 5, 5, 5,
-       5, 5, 5, 5, 5, 5, 5, 5,
-       5, 5, 5, 5, 6, 5, 7, 8,
-       9, 7, 10, 8, 9, 9, 11, 9, 
-       9, 3, 12, 9, 9, 13, 7, 7, 
-       14, 15, 9, 9, 16, 17, 18, 19, 
-       20, 21, 22, 16, 23, 24, 25, 26, 
-       27, 28, 9, 29, 30, 31, 9, 9, 
-       9, 32, 33, 9, 35, 34, 37, 36,
-       36, 38, 1, 36, 36, 39, 36, 36,
-       36, 36, 36, 40, 41, 42, 43, 44,
-       45, 46, 47, 41, 48, 40, 49, 50,
-       51, 52, 36, 53, 54, 55, 36, 36,
-       36, 36, 56, 36, 37, 36, 36, 38,
-       1, 36, 36, 39, 36, 36, 36, 36,
-       36, 57, 41, 42, 43, 44, 45, 46,
-       47, 41, 48, 49, 49, 50, 51, 52,
-       36, 53, 54, 55, 36, 36, 36, 36,
-       56, 36, 38, 58, 58, 58, 58, 58,
-       58, 58, 58, 58, 58, 58, 58, 58,
-       59, 58, 38, 58, 37, 36, 36, 38,
-       1, 36, 36, 39, 36, 36, 36, 36,
-       36, 36, 41, 42, 43, 44, 45, 46,
-       47, 41, 48, 49, 49, 50, 51, 52,
-       36, 53, 54, 55, 36, 36, 36, 36,
-       56, 36, 37, 36, 36, 36, 36, 36,
-       36, 36, 36, 36, 36, 36, 36, 36,
-       41, 42, 43, 44, 45, 36, 36, 36,
-       36, 36, 36, 50, 51, 52, 36, 53,
-       54, 55, 36, 36, 36, 36, 42, 36,
-       37, 36, 36, 36, 36, 36, 36, 36,
-       36, 36, 36, 36, 36, 36, 36, 42,
-       43, 44, 45, 36, 36, 36, 36, 36,
-       36, 36, 36, 36, 36, 53, 54, 55,
-       36, 37, 36, 36, 36, 36, 36, 36,
-       36, 36, 36, 36, 36, 36, 36, 36,
-       36, 43, 44, 45, 36, 37, 36, 36,
-       36, 36, 36, 36, 36, 36, 36, 36,
-       36, 36, 36, 36, 36, 36, 44, 45,
-       36, 37, 36, 36, 36, 36, 36, 36,
-       36, 36, 36, 36, 36, 36, 36, 36,
-       36, 36, 36, 45, 36, 37, 36, 36,
-       36, 36, 36, 36, 36, 36, 36, 36,
-       36, 36, 36, 36, 36, 43, 44, 45,
-       36, 36, 36, 36, 36, 36, 36, 36,
-       36, 36, 53, 54, 55, 36, 37, 36,
-       36, 36, 36, 36, 36, 36, 36, 36,
-       36, 36, 36, 36, 36, 36, 43, 44,
-       45, 36, 36, 36, 36, 36, 36, 36,
-       36, 36, 36, 36, 54, 55, 36, 37,
-       36, 36, 36, 36, 36, 36, 36, 36,
-       36, 36, 36, 36, 36, 36, 36, 43,
-       44, 45, 36, 36, 36, 36, 36, 36,
-       36, 36, 36, 36, 36, 36, 55, 36,
-       37, 36, 36, 36, 36, 36, 36, 36,
-       36, 36, 36, 36, 36, 36, 36, 42,
-       43, 44, 45, 36, 36, 36, 36, 36,
-       36, 50, 51, 52, 36, 53, 54, 55,
-       36, 36, 36, 36, 42, 36, 37, 36,
-       36, 36, 36, 36, 36, 36, 36, 36,
-       36, 36, 36, 36, 36, 42, 43, 44,
-       45, 36, 36, 36, 36, 36, 36, 36,
-       51, 52, 36, 53, 54, 55, 36, 36,
-       36, 36, 42, 36, 37, 36, 36, 36,
-       36, 36, 36, 36, 36, 36, 36, 36,
-       36, 36, 36, 42, 43, 44, 45, 36,
-       36, 36, 36, 36, 36, 36, 36, 52,
-       36, 53, 54, 55, 36, 36, 36, 36,
-       42, 36, 37, 36, 36, 36, 36, 36,
-       36, 36, 36, 36, 36, 36, 36, 36,
-       41, 42, 43, 44, 45, 36, 47, 41,
-       36, 36, 36, 50, 51, 52, 36, 53,
-       54, 55, 36, 36, 36, 36, 42, 36,
-       37, 36, 36, 36, 36, 36, 36, 36,
-       36, 36, 36, 36, 36, 36, 41, 42,
-       43, 44, 45, 36, 60, 41, 36, 36,
-       36, 50, 51, 52, 36, 53, 54, 55,
-       36, 36, 36, 36, 42, 36, 37, 36,
-       36, 36, 36, 36, 36, 36, 36, 36,
-       36, 36, 36, 36, 41, 42, 43, 44,
-       45, 36, 36, 41, 36, 36, 36, 50,
-       51, 52, 36, 53, 54, 55, 36, 36,
-       36, 36, 42, 36, 37, 36, 36, 36,
-       36, 36, 36, 36, 36, 36, 36, 36,
-       36, 36, 41, 42, 43, 44, 45, 46,
-       47, 41, 36, 36, 36, 50, 51, 52,
-       36, 53, 54, 55, 36, 36, 36, 36,
-       42, 36, 37, 36, 36, 38, 1, 36,
-       36, 39, 36, 36, 36, 36, 36, 36,
-       41, 42, 43, 44, 45, 46, 47, 41,
-       48, 36, 49, 50, 51, 52, 36, 53,
-       54, 55, 36, 36, 36, 36, 56, 36,
-       38, 58, 58, 58, 58, 58, 58, 37,
-       58, 58, 58, 58, 58, 58, 59, 58,
-       58, 58, 58, 58, 58, 58, 42, 43,
-       44, 45, 58, 58, 58, 58, 58, 58,
-       58, 58, 58, 58, 53, 54, 55, 58,
-       37, 36, 36, 38, 1, 36, 36, 39,
-       36, 36, 36, 36, 36, 36, 41, 42,
-       43, 44, 45, 46, 47, 41, 48, 40,
-       49, 50, 51, 52, 36, 53, 54, 55,
-       36, 36, 36, 36, 56, 36, 62, 61,
-       61, 61, 61, 61, 61, 61, 63, 61,
-       10, 64, 62, 61, 11, 65, 65, 3,
-       6, 65, 65, 66, 65, 65, 65, 65,
-       65, 67, 16, 17, 18, 19, 20, 21,
-       22, 16, 23, 25, 25, 26, 27, 28,
-       65, 29, 30, 31, 65, 65, 65, 65,
-       33, 65, 11, 65, 65, 3, 6, 65,
-       65, 66, 65, 65, 65, 65, 65, 65,
-       16, 17, 18, 19, 20, 21, 22, 16, 
-       23, 25, 25, 26, 27, 28, 65, 29,
-       30, 31, 65, 65, 65, 65, 33, 65,
-       11, 65, 65, 65, 65, 65, 65, 65,
-       65, 65, 65, 65, 65, 65, 16, 17,
-       18, 19, 20, 65, 65, 65, 65, 65,
-       65, 26, 27, 28, 65, 29, 30, 31,
-       65, 65, 65, 65, 17, 65, 11, 65,
-       65, 65, 65, 65, 65, 65, 65, 65,
-       65, 65, 65, 65, 65, 17, 18, 19,
-       20, 65, 65, 65, 65, 65, 65, 65,
-       65, 65, 65, 29, 30, 31, 65, 11,
-       65, 65, 65, 65, 65, 65, 65, 65,
-       65, 65, 65, 65, 65, 65, 65, 18,
-       19, 20, 65, 11, 65, 65, 65, 65,
-       65, 65, 65, 65, 65, 65, 65, 65,
-       65, 65, 65, 65, 19, 20, 65, 11,
-       65, 65, 65, 65, 65, 65, 65, 65,
-       65, 65, 65, 65, 65, 65, 65, 65,
-       65, 20, 65, 11, 65, 65, 65, 65,
-       65, 65, 65, 65, 65, 65, 65, 65,
-       65, 65, 65, 18, 19, 20, 65, 65,
-       65, 65, 65, 65, 65, 65, 65, 65,
-       29, 30, 31, 65, 11, 65, 65, 65,
-       65, 65, 65, 65, 65, 65, 65, 65,
-       65, 65, 65, 65, 18, 19, 20, 65,
-       65, 65, 65, 65, 65, 65, 65, 65,
-       65, 65, 30, 31, 65, 11, 65, 65,
-       65, 65, 65, 65, 65, 65, 65, 65,
-       65, 65, 65, 65, 65, 18, 19, 20,
-       65, 65, 65, 65, 65, 65, 65, 65,
-       65, 65, 65, 65, 31, 65, 11, 65,
-       65, 65, 65, 65, 65, 65, 65, 65,
-       65, 65, 65, 65, 65, 17, 18, 19,
-       20, 65, 65, 65, 65, 65, 65, 26,
-       27, 28, 65, 29, 30, 31, 65, 65,
-       65, 65, 17, 65, 11, 65, 65, 65,
-       65, 65, 65, 65, 65, 65, 65, 65,
-       65, 65, 65, 17, 18, 19, 20, 65,
-       65, 65, 65, 65, 65, 65, 27, 28,
-       65, 29, 30, 31, 65, 65, 65, 65,
-       17, 65, 11, 65, 65, 65, 65, 65,
-       65, 65, 65, 65, 65, 65, 65, 65,
-       65, 17, 18, 19, 20, 65, 65, 65,
-       65, 65, 65, 65, 65, 28, 65, 29,
-       30, 31, 65, 65, 65, 65, 17, 65,
-       11, 65, 65, 65, 65, 65, 65, 65,
-       65, 65, 65, 65, 65, 65, 16, 17,
-       18, 19, 20, 65, 22, 16, 65, 65,
-       65, 26, 27, 28, 65, 29, 30, 31,
-       65, 65, 65, 65, 17, 65, 11, 65,
-       65, 65, 65, 65, 65, 65, 65, 65,
-       65, 65, 65, 65, 16, 17, 18, 19,
-       20, 65, 68, 16, 65, 65, 65, 26,
-       27, 28, 65, 29, 30, 31, 65, 65,
-       65, 65, 17, 65, 11, 65, 65, 65,
-       65, 65, 65, 65, 65, 65, 65, 65,
-       65, 65, 16, 17, 18, 19, 20, 65,
-       65, 16, 65, 65, 65, 26, 27, 28,
-       65, 29, 30, 31, 65, 65, 65, 65,
-       17, 65, 11, 65, 65, 65, 65, 65,
-       65, 65, 65, 65, 65, 65, 65, 65,
-       16, 17, 18, 19, 20, 21, 22, 16,
-       65, 65, 65, 26, 27, 28, 65, 29,
-       30, 31, 65, 65, 65, 65, 17, 65,
-       11, 65, 65, 3, 6, 65, 65, 66,
-       65, 65, 65, 65, 65, 65, 16, 17,
-       18, 19, 20, 21, 22, 16, 23, 65,
-       25, 26, 27, 28, 65, 29, 30, 31,
-       65, 65, 65, 65, 33, 65, 3, 65,
-       65, 65, 65, 65, 65, 11, 65, 65,
-       65, 65, 65, 65, 4, 65, 65, 65,
-       65, 65, 65, 65, 17, 18, 19, 20,
-       65, 65, 65, 65, 65, 65, 65, 65,
-       65, 65, 29, 30, 31, 65, 3, 69,
-       69, 69, 69, 69, 69, 69, 69, 69,
-       69, 69, 69, 69, 4, 69, 6, 69,
-       69, 69, 69, 69, 69, 69, 69, 69,
-       69, 69, 69, 69, 69, 69, 69, 69,
-       69, 69, 69, 69, 69, 69, 69, 69,
-       69, 69, 69, 69, 69, 69, 6, 69,
-       8, 65, 65, 65, 8, 65, 65, 11,
-       65, 65, 3, 6, 65, 65, 66, 65,
-       65, 65, 65, 65, 65, 16, 17, 18,
-       19, 20, 21, 22, 16, 23, 24, 25, 
-       26, 27, 28, 65, 29, 30, 31, 65,
-       65, 65, 65, 33, 65, 11, 65, 65,
-       3, 6, 65, 65, 66, 65, 65, 65,
-       65, 65, 65, 16, 17, 18, 19, 20,
-       21, 22, 16, 23, 24, 25, 26, 27,
-       28, 65, 29, 30, 31, 65, 65, 65,
-       65, 33, 65, 71, 70, 70, 70, 70,
-       70, 70, 70, 70, 70, 70, 70, 70,
-       70, 70, 70, 70, 70, 70, 70, 71,
-       72, 70, 71, 72, 70, 72, 70, 8,
-       69, 69, 69, 8, 69, 0
+       2, 2, 2, 2, 4, 2, 3, 2, 
+       6, 5, 5, 5, 5, 5, 5, 5, 
+       5, 5, 5, 5, 5, 5, 5, 5, 
+       5, 5, 5, 5, 5, 5, 5, 5, 
+       5, 5, 5, 5, 5, 5, 5, 5, 
+       6, 5, 5, 5, 6, 5, 7, 5, 
+       8, 9, 10, 8, 11, 12, 10, 10, 
+       10, 10, 10, 3, 13, 14, 10, 15, 
+       8, 8, 16, 17, 10, 10, 18, 19, 
+       20, 21, 22, 23, 24, 18, 25, 26, 
+       27, 28, 29, 30, 10, 31, 32, 33, 
+       10, 34, 35, 36, 37, 38, 39, 40, 
+       13, 10, 42, 41, 44, 1, 43, 43, 
+       45, 43, 43, 43, 43, 43, 46, 47, 
+       48, 49, 50, 51, 52, 53, 47, 54, 
+       46, 55, 56, 57, 58, 43, 59, 60, 
+       61, 43, 43, 43, 43, 62, 63, 64, 
+       65, 1, 43, 44, 1, 43, 43, 45, 
+       43, 43, 43, 43, 43, 66, 47, 48, 
+       49, 50, 51, 52, 53, 47, 54, 55, 
+       55, 56, 57, 58, 43, 59, 60, 61, 
+       43, 43, 43, 43, 62, 63, 64, 65, 
+       1, 43, 44, 67, 67, 67, 67, 67, 
+       67, 67, 67, 67, 67, 67, 67, 67, 
+       68, 67, 44, 67, 44, 1, 43, 43, 
+       45, 43, 43, 43, 43, 43, 43, 47, 
+       48, 49, 50, 51, 52, 53, 47, 54, 
+       55, 55, 56, 57, 58, 43, 59, 60, 
+       61, 43, 43, 43, 43, 62, 63, 64, 
+       65, 1, 43, 47, 48, 49, 50, 51, 
+       43, 43, 43, 43, 43, 43, 56, 57, 
+       58, 43, 59, 60, 61, 43, 43, 43, 
+       43, 48, 63, 64, 65, 69, 43, 48, 
+       49, 50, 51, 43, 43, 43, 43, 43, 
+       43, 43, 43, 43, 43, 59, 60, 61, 
+       43, 43, 43, 43, 43, 63, 64, 65, 
+       69, 43, 49, 50, 51, 43, 43, 43, 
+       43, 43, 43, 43, 43, 43, 43, 43, 
+       43, 43, 43, 43, 43, 43, 43, 63, 
+       64, 65, 43, 50, 51, 43, 43, 43, 
+       43, 43, 43, 43, 43, 43, 43, 43, 
+       43, 43, 43, 43, 43, 43, 43, 63, 
+       64, 65, 43, 51, 43, 43, 43, 43, 
+       43, 43, 43, 43, 43, 43, 43, 43, 
+       43, 43, 43, 43, 43, 43, 63, 64, 
+       65, 43, 63, 64, 43, 64, 43, 49, 
+       50, 51, 43, 43, 43, 43, 43, 43, 
+       43, 43, 43, 43, 59, 60, 61, 43, 
+       43, 43, 43, 43, 63, 64, 65, 69, 
+       43, 49, 50, 51, 43, 43, 43, 43, 
+       43, 43, 43, 43, 43, 43, 43, 60, 
+       61, 43, 43, 43, 43, 43, 63, 64, 
+       65, 69, 43, 49, 50, 51, 43, 43, 
+       43, 43, 43, 43, 43, 43, 43, 43, 
+       43, 43, 61, 43, 43, 43, 43, 43, 
+       63, 64, 65, 69, 43, 71, 70, 49, 
+       50, 51, 43, 43, 43, 43, 43, 43, 
+       43, 43, 43, 43, 43, 43, 43, 43, 
+       43, 43, 43, 43, 63, 64, 65, 69, 
+       43, 48, 49, 50, 51, 43, 43, 43, 
+       43, 43, 43, 56, 57, 58, 43, 59, 
+       60, 61, 43, 43, 43, 43, 48, 63, 
+       64, 65, 69, 43, 48, 49, 50, 51, 
+       43, 43, 43, 43, 43, 43, 43, 57, 
+       58, 43, 59, 60, 61, 43, 43, 43, 
+       43, 48, 63, 64, 65, 69, 43, 48, 
+       49, 50, 51, 43, 43, 43, 43, 43, 
+       43, 43, 43, 58, 43, 59, 60, 61, 
+       43, 43, 43, 43, 48, 63, 64, 65, 
+       69, 43, 47, 48, 49, 50, 51, 43, 
+       53, 47, 43, 43, 43, 56, 57, 58, 
+       43, 59, 60, 61, 43, 43, 43, 43, 
+       48, 63, 64, 65, 69, 43, 47, 48, 
+       49, 50, 51, 43, 72, 47, 43, 43, 
+       43, 56, 57, 58, 43, 59, 60, 61, 
+       43, 43, 43, 43, 48, 63, 64, 65, 
+       69, 43, 47, 48, 49, 50, 51, 43, 
+       43, 47, 43, 43, 43, 56, 57, 58, 
+       43, 59, 60, 61, 43, 43, 43, 43, 
+       48, 63, 64, 65, 69, 43, 47, 48, 
+       49, 50, 51, 52, 53, 47, 43, 43, 
+       43, 56, 57, 58, 43, 59, 60, 61, 
+       43, 43, 43, 43, 48, 63, 64, 65, 
+       69, 43, 44, 1, 43, 43, 45, 43, 
+       43, 43, 43, 43, 43, 47, 48, 49, 
+       50, 51, 52, 53, 47, 54, 43, 55, 
+       56, 57, 58, 43, 59, 60, 61, 43, 
+       43, 43, 43, 62, 63, 64, 65, 1, 
+       43, 44, 67, 67, 67, 67, 67, 67, 
+       67, 67, 67, 67, 67, 67, 67, 68, 
+       67, 67, 67, 67, 67, 67, 67, 48, 
+       49, 50, 51, 67, 67, 67, 67, 67, 
+       67, 67, 67, 67, 67, 59, 60, 61, 
+       67, 67, 67, 67, 67, 63, 64, 65, 
+       69, 67, 44, 1, 43, 43, 45, 43, 
+       43, 43, 43, 43, 43, 47, 48, 49, 
+       50, 51, 52, 53, 47, 54, 46, 55, 
+       56, 57, 58, 43, 59, 60, 61, 43, 
+       43, 43, 43, 62, 63, 64, 65, 1, 
+       43, 74, 73, 73, 73, 73, 73, 73, 
+       73, 75, 73, 11, 76, 74, 73, 44, 
+       1, 43, 43, 45, 43, 43, 43, 43, 
+       43, 77, 47, 48, 49, 50, 51, 52, 
+       53, 47, 54, 46, 55, 56, 57, 58, 
+       43, 59, 60, 61, 43, 78, 79, 43, 
+       62, 63, 64, 65, 1, 43, 44, 1, 
+       43, 43, 45, 43, 43, 43, 43, 43, 
+       43, 47, 48, 49, 50, 51, 52, 53, 
+       47, 54, 46, 55, 56, 57, 58, 43, 
+       59, 60, 61, 43, 78, 79, 43, 62, 
+       63, 64, 65, 1, 43, 78, 79, 80, 
+       79, 80, 3, 6, 81, 81, 82, 81, 
+       81, 81, 81, 81, 83, 18, 19, 20, 
+       21, 22, 23, 24, 18, 25, 27, 27, 
+       28, 29, 30, 81, 31, 32, 33, 81, 
+       81, 81, 81, 37, 38, 39, 40, 6, 
+       81, 3, 6, 81, 81, 82, 81, 81, 
+       81, 81, 81, 81, 18, 19, 20, 21, 
+       22, 23, 24, 18, 25, 27, 27, 28, 
+       29, 30, 81, 31, 32, 33, 81, 81, 
+       81, 81, 37, 38, 39, 40, 6, 81, 
+       18, 19, 20, 21, 22, 81, 81, 81, 
+       81, 81, 81, 28, 29, 30, 81, 31, 
+       32, 33, 81, 81, 81, 81, 19, 38, 
+       39, 40, 84, 81, 19, 20, 21, 22, 
+       81, 81, 81, 81, 81, 81, 81, 81, 
+       81, 81, 31, 32, 33, 81, 81, 81, 
+       81, 81, 38, 39, 40, 84, 81, 20, 
+       21, 22, 81, 81, 81, 81, 81, 81, 
+       81, 81, 81, 81, 81, 81, 81, 81, 
+       81, 81, 81, 81, 38, 39, 40, 81, 
+       21, 22, 81, 81, 81, 81, 81, 81, 
+       81, 81, 81, 81, 81, 81, 81, 81, 
+       81, 81, 81, 81, 38, 39, 40, 81, 
+       22, 81, 81, 81, 81, 81, 81, 81, 
+       81, 81, 81, 81, 81, 81, 81, 81, 
+       81, 81, 81, 38, 39, 40, 81, 38, 
+       39, 81, 39, 81, 20, 21, 22, 81, 
+       81, 81, 81, 81, 81, 81, 81, 81, 
+       81, 31, 32, 33, 81, 81, 81, 81, 
+       81, 38, 39, 40, 84, 81, 20, 21, 
+       22, 81, 81, 81, 81, 81, 81, 81, 
+       81, 81, 81, 81, 32, 33, 81, 81, 
+       81, 81, 81, 38, 39, 40, 84, 81, 
+       20, 21, 22, 81, 81, 81, 81, 81, 
+       81, 81, 81, 81, 81, 81, 81, 33, 
+       81, 81, 81, 81, 81, 38, 39, 40, 
+       84, 81, 20, 21, 22, 81, 81, 81, 
+       81, 81, 81, 81, 81, 81, 81, 81, 
+       81, 81, 81, 81, 81, 81, 81, 38, 
+       39, 40, 84, 81, 19, 20, 21, 22, 
+       81, 81, 81, 81, 81, 81, 28, 29, 
+       30, 81, 31, 32, 33, 81, 81, 81, 
+       81, 19, 38, 39, 40, 84, 81, 19, 
+       20, 21, 22, 81, 81, 81, 81, 81, 
+       81, 81, 29, 30, 81, 31, 32, 33, 
+       81, 81, 81, 81, 19, 38, 39, 40, 
+       84, 81, 19, 20, 21, 22, 81, 81, 
+       81, 81, 81, 81, 81, 81, 30, 81, 
+       31, 32, 33, 81, 81, 81, 81, 19, 
+       38, 39, 40, 84, 81, 18, 19, 20, 
+       21, 22, 81, 24, 18, 81, 81, 81, 
+       28, 29, 30, 81, 31, 32, 33, 81, 
+       81, 81, 81, 19, 38, 39, 40, 84, 
+       81, 18, 19, 20, 21, 22, 81, 85, 
+       18, 81, 81, 81, 28, 29, 30, 81, 
+       31, 32, 33, 81, 81, 81, 81, 19, 
+       38, 39, 40, 84, 81, 18, 19, 20, 
+       21, 22, 81, 81, 18, 81, 81, 81, 
+       28, 29, 30, 81, 31, 32, 33, 81, 
+       81, 81, 81, 19, 38, 39, 40, 84, 
+       81, 18, 19, 20, 21, 22, 23, 24, 
+       18, 81, 81, 81, 28, 29, 30, 81, 
+       31, 32, 33, 81, 81, 81, 81, 19, 
+       38, 39, 40, 84, 81, 3, 6, 81, 
+       81, 82, 81, 81, 81, 81, 81, 81, 
+       18, 19, 20, 21, 22, 23, 24, 18, 
+       25, 81, 27, 28, 29, 30, 81, 31, 
+       32, 33, 81, 81, 81, 81, 37, 38, 
+       39, 40, 6, 81, 3, 81, 81, 81, 
+       81, 81, 81, 81, 81, 81, 81, 81, 
+       81, 81, 4, 81, 81, 81, 81, 81, 
+       81, 81, 19, 20, 21, 22, 81, 81, 
+       81, 81, 81, 81, 81, 81, 81, 81, 
+       31, 32, 33, 81, 81, 81, 81, 81, 
+       38, 39, 40, 84, 81, 3, 86, 86, 
+       86, 86, 86, 86, 86, 86, 86, 86, 
+       86, 86, 86, 4, 86, 87, 81, 14, 
+       81, 81, 81, 81, 81, 81, 81, 88, 
+       81, 14, 81, 6, 86, 86, 86, 86, 
+       86, 86, 86, 86, 86, 86, 86, 86, 
+       86, 86, 86, 86, 86, 86, 86, 86, 
+       86, 86, 86, 86, 86, 86, 86, 86, 
+       86, 86, 86, 6, 86, 86, 86, 6, 
+       86, 9, 81, 81, 81, 9, 81, 81, 
+       81, 81, 81, 3, 6, 14, 81, 82, 
+       81, 81, 81, 81, 81, 81, 18, 19, 
+       20, 21, 22, 23, 24, 18, 25, 26, 
+       27, 28, 29, 30, 81, 31, 32, 33, 
+       81, 34, 35, 81, 37, 38, 39, 40, 
+       6, 81, 3, 6, 81, 81, 82, 81, 
+       81, 81, 81, 81, 81, 18, 19, 20, 
+       21, 22, 23, 24, 18, 25, 26, 27, 
+       28, 29, 30, 81, 31, 32, 33, 81, 
+       81, 81, 81, 37, 38, 39, 40, 6, 
+       81, 34, 35, 81, 35, 81, 78, 80, 
+       80, 80, 80, 80, 80, 80, 80, 80, 
+       80, 80, 80, 80, 80, 80, 80, 80, 
+       80, 80, 78, 79, 80, 9, 86, 86, 
+       86, 9, 86, 0
 };
 
 static const char _use_syllable_machine_trans_targs[] = {
-       4, 8, 4, 32, 2, 4, 1, 5,
-       6, 4, 29, 4, 51, 52, 53, 55,
-       34, 35, 36, 37, 38, 45, 46, 48,
-       54, 49, 42, 43, 44, 39, 40, 41,
-       58, 50, 4, 4, 4, 4, 7, 0,
-       28, 11, 12, 13, 14, 15, 22, 23,
-       25, 26, 19, 20, 21, 16, 17, 18,
-       27, 10, 4, 9, 24, 4, 30, 31,
-       4, 4, 3, 33, 47, 4, 4, 56,
-       57
+       5, 9, 5, 41, 2, 5, 1, 53, 
+       6, 7, 5, 34, 37, 63, 64, 67, 
+       68, 72, 43, 44, 45, 46, 47, 57, 
+       58, 60, 69, 61, 54, 55, 56, 50, 
+       51, 52, 70, 71, 73, 62, 48, 49, 
+       5, 5, 5, 5, 8, 0, 33, 12, 
+       13, 14, 15, 16, 27, 28, 30, 31, 
+       24, 25, 26, 19, 20, 21, 32, 17, 
+       18, 5, 11, 5, 10, 22, 5, 23, 
+       29, 5, 35, 36, 5, 38, 39, 40, 
+       5, 5, 3, 42, 4, 59, 5, 65, 
+       66
 };
 
 static const char _use_syllable_machine_trans_actions[] = {
-       1, 0, 2, 3, 0, 4, 0, 0, 
-       7, 8, 0, 9, 10, 10, 3, 0, 
+       1, 0, 2, 3, 0, 4, 0, 5, 
+       0, 5, 8, 0, 5, 9, 0, 9, 
+       3, 0, 5, 5, 0, 0, 0, 5, 
+       5, 5, 3, 3, 5, 5, 5, 5, 
+       5, 5, 0, 0, 0, 3, 0, 0, 
+       10, 11, 12, 13, 5, 0, 5, 0, 
+       0, 0, 0, 0, 0, 0, 0, 5, 
        0, 0, 0, 0, 0, 0, 0, 0, 
-       3, 3, 0, 0, 0, 0, 0, 0, 
-       0, 3, 11, 12, 13, 14, 7, 0,
-       7, 0, 0, 0, 0, 0, 0, 0,
-       0, 7, 0, 0, 0, 0, 0, 0,
-       0, 7, 15, 0, 0, 16, 0, 0,
-       17, 18, 0, 3, 0, 19, 20, 0,
+       0, 14, 5, 15, 0, 0, 16, 0, 
+       0, 17, 0, 0, 18, 5, 0, 0, 
+       19, 20, 0, 3, 0, 5, 21, 0, 
        0
 };
 
 static const char _use_syllable_machine_to_state_actions[] = {
-       0, 0, 0, 0, 5, 0, 0, 0, 
+       0, 0, 0, 0, 0, 6, 0, 0, 
+       0, 0, 0, 0, 0, 0, 0, 0, 
+       0, 0, 0, 0, 0, 0, 0, 0, 
        0, 0, 0, 0, 0, 0, 0, 0, 
        0, 0, 0, 0, 0, 0, 0, 0, 
        0, 0, 0, 0, 0, 0, 0, 0, 
        0, 0, 0, 0, 0, 0, 0, 0, 
        0, 0, 0, 0, 0, 0, 0, 0, 
        0, 0, 0, 0, 0, 0, 0, 0, 
-       0, 0, 0
+       0, 0
 };
 
 static const char _use_syllable_machine_from_state_actions[] = {
-       0, 0, 0, 0, 6, 0, 0, 0, 
+       0, 0, 0, 0, 0, 7, 0, 0, 
        0, 0, 0, 0, 0, 0, 0, 0, 
        0, 0, 0, 0, 0, 0, 0, 0, 
        0, 0, 0, 0, 0, 0, 0, 0, 
        0, 0, 0, 0, 0, 0, 0, 0, 
        0, 0, 0, 0, 0, 0, 0, 0, 
        0, 0, 0, 0, 0, 0, 0, 0, 
-       0, 0, 0
+       0, 0, 0, 0, 0, 0, 0, 0, 
+       0, 0, 0, 0, 0, 0, 0, 0, 
+       0, 0
 };
 
 static const short _use_syllable_machine_eof_trans[] = {
-       1, 3, 3, 6, 0, 35, 37, 37,
-       59, 59, 37, 37, 37, 37, 37, 37,
-       37, 37, 37, 37, 37, 37, 37, 37,
-       37, 37, 37, 59, 37, 62, 65, 62,
-       66, 66, 66, 66, 66, 66, 66, 66,
-       66, 66, 66, 66, 66, 66, 66, 66,
-       66, 66, 66, 70, 70, 66, 66, 71,
-       71, 71, 70
+       1, 3, 3, 6, 6, 0, 42, 44, 
+       44, 68, 68, 44, 44, 44, 44, 44, 
+       44, 44, 44, 44, 44, 44, 71, 44, 
+       44, 44, 44, 44, 44, 44, 44, 44, 
+       68, 44, 74, 77, 74, 44, 44, 81, 
+       81, 82, 82, 82, 82, 82, 82, 82, 
+       82, 82, 82, 82, 82, 82, 82, 82, 
+       82, 82, 82, 82, 82, 82, 82, 87, 
+       82, 82, 82, 87, 82, 82, 82, 82, 
+       81, 87
 };
 
-static const int use_syllable_machine_start = 4;
-static const int use_syllable_machine_first_final = 4;
+static const int use_syllable_machine_start = 5;
+static const int use_syllable_machine_first_final = 5;
 static const int use_syllable_machine_error = -1;
 
-static const int use_syllable_machine_en_main = 4;
+static const int use_syllable_machine_en_main = 5;
 
 
 #line 38 "hb-ot-shape-complex-use-machine.rl"
 
 
 
-#line 143 "hb-ot-shape-complex-use-machine.rl"
+#line 162 "hb-ot-shape-complex-use-machine.rl"
 
 
 #define found_syllable(syllable_type) \
   HB_STMT_START { \
     if (0) fprintf (stderr, "syllable %d..%d %s\n", ts, te, #syllable_type); \
     for (unsigned int i = ts; i < te; i++) \
-      info[i].syllable() = (syllable_serial << 4) | syllable_type; \
+      info[i].syllable() = (syllable_serial << 4) | use_##syllable_type; \
     syllable_serial++; \
     if (unlikely (syllable_serial == 16)) syllable_serial = 1; \
   } HB_STMT_END
 
 static void
-find_syllables (hb_buffer_t *buffer)
+find_syllables_use (hb_buffer_t *buffer)
 {
   unsigned int p, pe, eof, ts, te, act;
   int cs;
   hb_glyph_info_t *info = buffer->info;
   
-#line 378 "hb-ot-shape-complex-use-machine.hh"
+#line 396 "hb-ot-shape-complex-use-machine.hh"
        {
        cs = use_syllable_machine_start;
        ts = 0;
@@ -382,7 +400,7 @@ find_syllables (hb_buffer_t *buffer)
        act = 0;
        }
 
-#line 163 "hb-ot-shape-complex-use-machine.rl"
+#line 182 "hb-ot-shape-complex-use-machine.rl"
 
 
   p = 0;
@@ -390,7 +408,7 @@ find_syllables (hb_buffer_t *buffer)
 
   unsigned int syllable_serial = 1;
   
-#line 394 "hb-ot-shape-complex-use-machine.hh"
+#line 412 "hb-ot-shape-complex-use-machine.hh"
        {
        int _slen;
        int _trans;
@@ -400,11 +418,11 @@ find_syllables (hb_buffer_t *buffer)
                goto _test_eof;
 _resume:
        switch ( _use_syllable_machine_from_state_actions[cs] ) {
-       case 6:
+       case 7:
 #line 1 "NONE"
        {ts = p;}
        break;
-#line 408 "hb-ot-shape-complex-use-machine.hh"
+#line 426 "hb-ot-shape-complex-use-machine.hh"
        }
 
        _keys = _use_syllable_machine_trans_keys + (cs<<1);
@@ -422,73 +440,77 @@ _eof_trans:
                goto _again;
 
        switch ( _use_syllable_machine_trans_actions[_trans] ) {
-       case 7:
+       case 5:
 #line 1 "NONE"
        {te = p+1;}
        break;
        case 12:
-#line 132 "hb-ot-shape-complex-use-machine.rl"
+#line 150 "hb-ot-shape-complex-use-machine.rl"
        {te = p+1;{ found_syllable (independent_cluster); }}
        break;
        case 14:
-#line 134 "hb-ot-shape-complex-use-machine.rl"
+#line 153 "hb-ot-shape-complex-use-machine.rl"
        {te = p+1;{ found_syllable (standard_cluster); }}
        break;
-       case 9:
-#line 138 "hb-ot-shape-complex-use-machine.rl"
+       case 10:
+#line 157 "hb-ot-shape-complex-use-machine.rl"
        {te = p+1;{ found_syllable (broken_cluster); }}
        break;
        case 8:
-#line 139 "hb-ot-shape-complex-use-machine.rl"
+#line 158 "hb-ot-shape-complex-use-machine.rl"
        {te = p+1;{ found_syllable (non_cluster); }}
        break;
        case 11:
-#line 132 "hb-ot-shape-complex-use-machine.rl"
+#line 150 "hb-ot-shape-complex-use-machine.rl"
        {te = p;p--;{ found_syllable (independent_cluster); }}
        break;
        case 15:
-#line 133 "hb-ot-shape-complex-use-machine.rl"
+#line 151 "hb-ot-shape-complex-use-machine.rl"
        {te = p;p--;{ found_syllable (virama_terminated_cluster); }}
        break;
+       case 16:
+#line 152 "hb-ot-shape-complex-use-machine.rl"
+       {te = p;p--;{ found_syllable (sakot_terminated_cluster); }}
+       break;
        case 13:
-#line 134 "hb-ot-shape-complex-use-machine.rl"
+#line 153 "hb-ot-shape-complex-use-machine.rl"
        {te = p;p--;{ found_syllable (standard_cluster); }}
        break;
-       case 17:
-#line 135 "hb-ot-shape-complex-use-machine.rl"
+       case 18:
+#line 154 "hb-ot-shape-complex-use-machine.rl"
        {te = p;p--;{ found_syllable (number_joiner_terminated_cluster); }}
        break;
-       case 16:
-#line 136 "hb-ot-shape-complex-use-machine.rl"
+       case 17:
+#line 155 "hb-ot-shape-complex-use-machine.rl"
        {te = p;p--;{ found_syllable (numeral_cluster); }}
        break;
-       case 20:
-#line 137 "hb-ot-shape-complex-use-machine.rl"
+       case 19:
+#line 156 "hb-ot-shape-complex-use-machine.rl"
        {te = p;p--;{ found_syllable (symbol_cluster); }}
        break;
-       case 18:
-#line 138 "hb-ot-shape-complex-use-machine.rl"
+       case 20:
+#line 157 "hb-ot-shape-complex-use-machine.rl"
        {te = p;p--;{ found_syllable (broken_cluster); }}
        break;
-       case 19:
-#line 139 "hb-ot-shape-complex-use-machine.rl"
+       case 21:
+#line 158 "hb-ot-shape-complex-use-machine.rl"
        {te = p;p--;{ found_syllable (non_cluster); }}
        break;
        case 1:
-#line 134 "hb-ot-shape-complex-use-machine.rl"
+#line 153 "hb-ot-shape-complex-use-machine.rl"
        {{p = ((te))-1;}{ found_syllable (standard_cluster); }}
        break;
        case 4:
-#line 138 "hb-ot-shape-complex-use-machine.rl"
+#line 157 "hb-ot-shape-complex-use-machine.rl"
        {{p = ((te))-1;}{ found_syllable (broken_cluster); }}
        break;
        case 2:
 #line 1 "NONE"
        {       switch( act ) {
-       case 7:
+       case 8:
        {{p = ((te))-1;} found_syllable (broken_cluster); }
        break;
-       case 8:
+       case 9:
        {{p = ((te))-1;} found_syllable (non_cluster); }
        break;
        }
@@ -497,25 +519,25 @@ _eof_trans:
        case 3:
 #line 1 "NONE"
        {te = p+1;}
-#line 138 "hb-ot-shape-complex-use-machine.rl"
-       {act = 7;}
+#line 157 "hb-ot-shape-complex-use-machine.rl"
+       {act = 8;}
        break;
-       case 10:
+       case 9:
 #line 1 "NONE"
        {te = p+1;}
-#line 139 "hb-ot-shape-complex-use-machine.rl"
-       {act = 8;}
+#line 158 "hb-ot-shape-complex-use-machine.rl"
+       {act = 9;}
        break;
-#line 510 "hb-ot-shape-complex-use-machine.hh"
+#line 532 "hb-ot-shape-complex-use-machine.hh"
        }
 
 _again:
        switch ( _use_syllable_machine_to_state_actions[cs] ) {
-       case 5:
+       case 6:
 #line 1 "NONE"
        {ts = 0;}
        break;
-#line 519 "hb-ot-shape-complex-use-machine.hh"
+#line 541 "hb-ot-shape-complex-use-machine.hh"
        }
 
        if ( ++p != pe )
@@ -531,7 +553,7 @@ _again:
 
        }
 
-#line 171 "hb-ot-shape-complex-use-machine.rl"
+#line 190 "hb-ot-shape-complex-use-machine.rl"
 
 }
 
index 7702cd9..9b75b5c 100644 (file)
@@ -49,7 +49,7 @@ N     = 4; # BASE_NUM
 GB     = 5; # BASE_OTHER
 CGJ    = 6; # CGJ
 #F     = 7; # CONS_FINAL
-FM     = 8; # CONS_FINAL_MOD
+#FM    = 8; # CONS_FINAL_MOD
 #M     = 9; # CONS_MED
 #CM    = 10; # CONS_MOD
 SUB    = 11; # CONS_SUB
@@ -66,6 +66,9 @@ S     = 19; # SYM
 VS     = 21; # VARIATION_SELECTOR
 #V     = 36; # VOWEL
 #VM    = 40; # VOWEL_MOD
+CS     = 43; # CONS_WITH_STACKER
+HVM    = 44; # HALANT_OR_VOWEL_MODIFIER
+Sk     = 48; # SAKOT
 
 FAbv   = 24; # CONS_FINAL_ABOVE
 FBlw   = 25; # CONS_FINAL_BELOW
@@ -86,11 +89,11 @@ VMPst       = 39; # VOWEL_MOD_POST
 VMPre  = 23; # VOWEL_MOD_PRE
 SMAbv  = 41; # SYM_MOD_ABOVE
 SMBlw  = 42; # SYM_MOD_BELOW
-CS     = 43; # CONS_WITH_STACKER
-
-HVM    = 44; # HALANT_OR_VOWEL_MODIFIER
+FMAbv  = 45; # CONS_FINAL_MOD  UIPC = Top
+FMBlw  = 46; # CONS_FINAL_MOD  UIPC = Bottom
+FMPst  = 47; # CONS_FINAL_MOD  UIPC = Not_Applicable
 
-h = H | HVM; # https://github.com/harfbuzz/harfbuzz/issues/1102
+h = H | HVM | Sk;
 
 # Override: Adhoc ZWJ placement. https://github.com/harfbuzz/harfbuzz/issues/542#issuecomment-353169729
 consonant_modifiers = CMAbv* CMBlw* ((ZWJ?.h.ZWJ? B | SUB) VS? CMAbv? CMBlw*)*;
@@ -98,39 +101,55 @@ consonant_modifiers = CMAbv* CMBlw* ((ZWJ?.h.ZWJ? B | SUB) VS? CMAbv? CMBlw*)*;
 medial_consonants = MPre? MAbv? MBlw?.MBlw? MPst?;
 dependent_vowels = VPre* VAbv* VBlw* VPst*;
 vowel_modifiers = HVM? VMPre* VMAbv* VMBlw* VMPst*;
-final_consonants = FAbv* FBlw* FPst* FM?;
+final_consonants = FAbv* FBlw* FPst*;
+final_modifiers = FMAbv* FMBlw* | FMPst?;
 
-complex_syllable_tail =
+complex_syllable_start = (R | CS)? (B | GB) VS?;
+complex_syllable_middle =
        consonant_modifiers
        medial_consonants
        dependent_vowels
        vowel_modifiers
+       (Sk B)*
+;
+complex_syllable_tail =
+       complex_syllable_middle
        final_consonants
+       final_modifiers
 ;
+number_joiner_terminated_cluster_tail = (HN N VS?)* HN;
+numeral_cluster_tail = (HN N VS?)+;
+symbol_cluster_tail = SMAbv+ SMBlw* | SMBlw+;
 
 virama_terminated_cluster =
-       (R|CS)? (B | GB) VS?
+       complex_syllable_start
        consonant_modifiers
        ZWJ?.h.ZWJ?
 ;
+sakot_terminated_cluster =
+       complex_syllable_start
+       complex_syllable_middle
+       Sk
+;
 standard_cluster =
-       (R|CS)? (B | GB) VS?
+       complex_syllable_start
        complex_syllable_tail
 ;
 broken_cluster =
        R?
-       complex_syllable_tail
+       (complex_syllable_tail | number_joiner_terminated_cluster_tail | numeral_cluster_tail | symbol_cluster_tail)
 ;
 
-number_joiner_terminated_cluster = N VS? (HN N VS?)* HN;
-numeral_cluster = N VS? (HN N VS?)*;
-symbol_cluster = S VS? SMAbv* SMBlw*;
+number_joiner_terminated_cluster = N VS? number_joiner_terminated_cluster_tail;
+numeral_cluster = N VS? numeral_cluster_tail?;
+symbol_cluster = (S | GB) VS? symbol_cluster_tail?;
 independent_cluster = (IND | O | Rsv | WJ) VS?;
 other = any;
 
 main := |*
        independent_cluster                     => { found_syllable (independent_cluster); };
        virama_terminated_cluster               => { found_syllable (virama_terminated_cluster); };
+       sakot_terminated_cluster                => { found_syllable (sakot_terminated_cluster); };
        standard_cluster                        => { found_syllable (standard_cluster); };
        number_joiner_terminated_cluster        => { found_syllable (number_joiner_terminated_cluster); };
        numeral_cluster                         => { found_syllable (numeral_cluster); };
@@ -146,13 +165,13 @@ main := |*
   HB_STMT_START { \
     if (0) fprintf (stderr, "syllable %d..%d %s\n", ts, te, #syllable_type); \
     for (unsigned int i = ts; i < te; i++) \
-      info[i].syllable() = (syllable_serial << 4) | syllable_type; \
+      info[i].syllable() = (syllable_serial << 4) | use_##syllable_type; \
     syllable_serial++; \
     if (unlikely (syllable_serial == 16)) syllable_serial = 1; \
   } HB_STMT_END
 
 static void
-find_syllables (hb_buffer_t *buffer)
+find_syllables_use (hb_buffer_t *buffer)
 {
   unsigned int p, pe, eof, ts, te, act;
   int cs;
index cb5c358..e3889b3 100644 (file)
  * UnicodeData.txt does not have a header.
  */
 
+#include "hb.hh"
+
+#ifndef HB_NO_OT_SHAPE
+
 #include "hb-ot-shape-complex-use.hh"
 
 #pragma GCC diagnostic push
@@ -22,7 +26,6 @@
 #define B      USE_B   /* BASE */
 #define CGJ    USE_CGJ /* CGJ */
 #define CS     USE_CS  /* CONS_WITH_STACKER */
-#define FM     USE_FM  /* CONS_FINAL_MOD */
 #define GB     USE_GB  /* BASE_OTHER */
 #define H      USE_H   /* HALANT */
 #define HN     USE_HN  /* HALANT_NUM */
@@ -34,6 +37,7 @@
 #define Rsv    USE_Rsv /* Reserved */
 #define S      USE_S   /* SYM */
 #define SUB    USE_SUB /* CONS_SUB */
+#define Sk     USE_Sk  /* SAKOT */
 #define VS     USE_VS  /* VARIATION_SELECTOR */
 #define WJ     USE_WJ  /* Word_Joiner */
 #define ZWJ    USE_ZWJ /* ZWJ */
@@ -43,6 +47,9 @@
 #define FBlw   USE_FBlw
 #define FPst   USE_FPst
 #define FAbv   USE_FAbv
+#define FMBlw  USE_FMBlw
+#define FMPst  USE_FMPst
+#define FMAbv  USE_FMAbv
 #define MPre   USE_MPre
 #define MBlw   USE_MBlw
 #define MPst   USE_MPst
@@ -75,7 +82,7 @@ static const USE_TABLE_ELEMENT_TYPE use_table[] = {
   /* Latin-1 Supplement */
 
   /* 00A0 */    GB,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,
-  /* 00B0 */     O,     O,    FM,    FM,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,
+  /* 00B0 */     O,     O, FMPst, FMPst,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,
   /* 00C0 */     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,
   /* 00D0 */     O,     O,     O,     O,     O,     O,     O,    GB,
 
@@ -108,7 +115,7 @@ static const USE_TABLE_ELEMENT_TYPE use_table[] = {
   /* 09C0 */  VPst,  VBlw,  VBlw,  VBlw,  VBlw,     O,     O,  VPre,  VPre,     O,     O,  VPst,  VPst,     H,   IND,     O,
   /* 09D0 */     O,     O,     O,     O,     O,     O,     O,  VPst,     O,     O,     O,     O,     B,     B,     O,     B,
   /* 09E0 */     B,     B,  VBlw,  VBlw,     O,     O,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,
-  /* 09F0 */     B,     B,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     B,     O,    FM,     O,
+  /* 09F0 */     B,     B,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     B,     O, FMAbv,     O,
 
   /* Gurmukhi */
 
@@ -204,7 +211,7 @@ static const USE_TABLE_ELEMENT_TYPE use_table[] = {
   /* Tibetan */
                                                                       VBlw,  VBlw,     O,     O,     O,     O,     O,     O,
   /* 0F20 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,
-  /* 0F30 */     B,     B,     B,     B,     O,    FM,     O,    FM,     O, CMAbv,     O,     O,     O,     O,  VPst,  VPre,
+  /* 0F30 */     B,     B,     B,     B,     O, FMBlw,     O, FMBlw,     O, CMAbv,     O,     O,     O,     O,  VPst,  VPre,
   /* 0F40 */     B,     B,     B,     B,     B,     B,     B,     B,     O,     B,     B,     B,     B,     B,     B,     B,
   /* 0F50 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,
   /* 0F60 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     O,     O,     O,
@@ -213,7 +220,7 @@ static const USE_TABLE_ELEMENT_TYPE use_table[] = {
   /* 0F90 */   SUB,   SUB,   SUB,   SUB,   SUB,   SUB,   SUB,   SUB,     O,   SUB,   SUB,   SUB,   SUB,   SUB,   SUB,   SUB,
   /* 0FA0 */   SUB,   SUB,   SUB,   SUB,   SUB,   SUB,   SUB,   SUB,   SUB,   SUB,   SUB,   SUB,   SUB,   SUB,   SUB,   SUB,
   /* 0FB0 */   SUB,   SUB,   SUB,   SUB,   SUB,   SUB,   SUB,   SUB,   SUB,   SUB,   SUB,   SUB,   SUB,     O,     O,     O,
-  /* 0FC0 */     O,     O,     O,     O,     O,     O,    FM,     O,
+  /* 0FC0 */     O,     O,     O,     O,     O,     O, FMBlw,     O,
 
 #define use_offset_0x1000u 1536
 
@@ -260,8 +267,8 @@ static const USE_TABLE_ELEMENT_TYPE use_table[] = {
   /* 1790 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,
   /* 17A0 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,
   /* 17B0 */     B,     B,     B,     B,     O,     O,  VPst,  VAbv,  VAbv,  VAbv,  VAbv,  VBlw,  VBlw,  VBlw,  VPst,  VPst,
-  /* 17C0 */  VPst,  VPre,  VPre,  VPre,  VPst,  VPst, VMAbv, VMPst,  VPst, VMAbv, VMAbv,    FM,  FAbv, CMAbv,    FM,    FM,
-  /* 17D0 */    FM,  VAbv,     H,    FM,     O,     O,     O,     O,     O,     O,     O,     O,     B,    FM,     O,     O,
+  /* 17C0 */  VPst,  VPre,  VPre,  VPre,  VPst,  VPst, VMAbv, VMPst,  VPst, VMAbv, VMAbv, FMAbv,  FAbv, CMAbv, FMAbv, FMAbv,
+  /* 17D0 */ FMAbv,  VAbv,     H, FMAbv,     O,     O,     O,     O,     O,     O,     O,     O,     B, FMAbv,     O,     O,
   /* 17E0 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     O,     O,     O,     O,     O,     O,
 
 #define use_offset_0x1900u 1936
@@ -272,7 +279,7 @@ static const USE_TABLE_ELEMENT_TYPE use_table[] = {
   /* 1900 */    GB,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,
   /* 1910 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     O,
   /* 1920 */  VAbv,  VAbv,  VBlw,  VPst,  VPst,  VAbv,  VAbv,  VAbv,  VAbv,   SUB,   SUB,   SUB,     O,     O,     O,     O,
-  /* 1930 */  FPst,  FPst, VMBlw,  FPst,  FPst,  FPst,  FPst,  FPst,  FPst,  FBlw,  VAbv,    FM,     O,     O,     O,     O,
+  /* 1930 */  FPst,  FPst, VMBlw,  FPst,  FPst,  FPst,  FPst,  FPst,  FPst,  FBlw,  VAbv, FMBlw,     O,     O,     O,     O,
   /* 1940 */     O,     O,     O,     O,     O,     O,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,
 
   /* Tai Le */
@@ -302,9 +309,9 @@ static const USE_TABLE_ELEMENT_TYPE use_table[] = {
   /* 1A20 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,
   /* 1A30 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,
   /* 1A40 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,
-  /* 1A50 */     B,     B,     B,     B,     B,  MPre,  MBlw,   SUB,  FAbv,  FAbv,  FAbv,   SUB,   SUB,   SUB,   SUB,     O,
-  /* 1A60 */     H,  VPst,  VAbv,  VPst,  VPst,  VAbv,  VAbv,  VAbv,  VAbv,  VBlw,  VBlw,  VAbv,  VBlw,  VPst,  VPre,  VPre,
-  /* 1A70 */  VPre,  VPre,  VPre,  VAbv, VMAbv, VMAbv, VMAbv, VMAbv, VMAbv, VMAbv,  VAbv,    FM,    FM,     O,     O,  FBlw,
+  /* 1A50 */     B,     B,     B,     B,     B,  MPre,  MBlw,   SUB,  FAbv,  FAbv,  MAbv,   SUB,   SUB,   SUB,   SUB,     O,
+  /* 1A60 */    Sk,  VPst,  VAbv,  VPst,  VPst,  VAbv,  VAbv,  VAbv,  VAbv,  VBlw,  VBlw,  VAbv,  VBlw,  VPst,  VPre,  VPre,
+  /* 1A70 */  VPre,  VPre,  VPre,  VAbv, VMAbv, VMAbv, VMAbv, VMAbv, VMAbv, VMAbv,  VAbv, FMAbv, FMAbv,     O,     O, FMBlw,
   /* 1A80 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     O,     O,     O,     O,     O,     O,
   /* 1A90 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     O,     O,     O,     O,     O,     O,
 
@@ -318,8 +325,8 @@ static const USE_TABLE_ELEMENT_TYPE use_table[] = {
   /* 1B20 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,
   /* 1B30 */     B,     B,     B,     B, CMAbv,  VPst,  VAbv,  VAbv,  VBlw,  VBlw,  VBlw,  VBlw,  VAbv,  VAbv,  VPre,  VPre,
   /* 1B40 */  VPst,  VPst,  VAbv,  VAbv,     H,     B,     B,     B,     B,     B,     B,     B,     O,     O,     O,     O,
-  /* 1B50 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     O,     O,     O,     O,     O,     O,
-  /* 1B60 */     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O, SMAbv, SMBlw, SMAbv, SMAbv, SMAbv,
+  /* 1B50 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     O,    GB,    GB,     O,     O,    GB,
+  /* 1B60 */     O,     S,    GB,     S,     S,     S,     S,     S,    GB,     S,     S, SMAbv, SMBlw, SMAbv, SMAbv, SMAbv,
   /* 1B70 */ SMAbv, SMAbv, SMAbv, SMAbv,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,
 
   /* Sundanese */
@@ -340,8 +347,8 @@ static const USE_TABLE_ELEMENT_TYPE use_table[] = {
 
   /* 1C00 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,
   /* 1C10 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,
-  /* 1C20 */     B,     B,     B,     B,   SUB,   SUB,  VPst,  VPre,  VPre,  VPst,  VPst,  VPst,  VBlw,  FAbv,  FAbv,  FAbv,
-  /* 1C30 */  FAbv,  FAbv,  FAbv,  FAbv, VMPre, VMPre,    FM, CMBlw,     O,     O,     O,     O,     O,     O,     O,     O,
+  /* 1C20 */     B,     B,     B,     B,   SUB,   SUB,  VPst,  VPre,  VPre,  VPre,  VPst,  VPst,  VBlw,  FAbv,  FAbv,  FAbv,
+  /* 1C30 */  FAbv,  FAbv,  FAbv,  FAbv, VMPre, VMPre, FMAbv, CMBlw,     O,     O,     O,     O,     O,     O,     O,     O,
   /* 1C40 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     O,     O,     O,     B,     B,     B,
 
 #define use_offset_0x1cd0u 2688
@@ -357,7 +364,7 @@ static const USE_TABLE_ELEMENT_TYPE use_table[] = {
 
 
   /* Combining Diacritical Marks Supplement */
-                                                                         O,     O,     O,    FM,     O,     O,     O,     O,
+                                                                         O,     O,     O, FMAbv,     O,     O,     O,     O,
 
 #define use_offset_0x2008u 2744
 
@@ -372,8 +379,8 @@ static const USE_TABLE_ELEMENT_TYPE use_table[] = {
 
   /* Superscripts and Subscripts */
 
-  /* 2070 */     O,     O,     O,     O,    FM,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,
-  /* 2080 */     O,     O,    FM,    FM,    FM,     O,     O,     O,
+  /* 2070 */     O,     O,     O,     O, FMPst,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,
+  /* 2080 */     O,     O, FMPst, FMPst, FMPst,     O,     O,     O,
 
 #define use_offset_0x20f0u 2800
 
@@ -547,7 +554,7 @@ static const USE_TABLE_ELEMENT_TYPE use_table[] = {
   /* 11190 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,
   /* 111A0 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,
   /* 111B0 */     B,     B,     B,  VPst,  VPre,  VPst,  VBlw,  VBlw,  VBlw,  VBlw,  VBlw,  VBlw,  VAbv,  VAbv,  VAbv,  VAbv,
-  /* 111C0 */     H,     B,     R,     R,     O,     O,     O,     O,    GB,  FBlw, CMBlw,  VAbv,  VBlw,     O,     O,     O,
+  /* 111C0 */     H,     B,     R,     R,     O,     O,     O,     O,    GB, FMBlw, CMBlw,  VAbv,  VBlw,     O,     O,     O,
   /* 111D0 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     O,     O,     O,     O,     O,     O,
 
   /* Sinhala Archaic Numbers */
@@ -600,7 +607,7 @@ static const USE_TABLE_ELEMENT_TYPE use_table[] = {
   /* 11420 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,
   /* 11430 */     B,     B,     B,     B,     B,  VPst,  VPre,  VPst,  VBlw,  VBlw,  VBlw,  VBlw,  VBlw,  VBlw,  VAbv,  VAbv,
   /* 11440 */  VPst,  VPst,     H, VMAbv, VMAbv, VMPst, CMBlw,     B,     O,     O,     O,     O,     O,     O,     O,     O,
-  /* 11450 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     O,     O,     O,     O,    FM,     B,
+  /* 11450 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     O,     O,     O,     O, FMAbv,     B,
   /* 11460 */     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,
   /* 11470 */     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,     O,
 
@@ -683,7 +690,7 @@ static const USE_TABLE_ELEMENT_TYPE use_table[] = {
   /* 11A00 */     B,  VAbv,  VBlw,  VBlw,  VAbv,  VAbv,  VAbv,  VAbv,  VAbv,  VAbv,  VBlw,     B,     B,     B,     B,     B,
   /* 11A10 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,
   /* 11A20 */     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,     B,
-  /* 11A30 */     B,     B,     B,    FM,  VBlw, VMAbv, VMAbv, VMAbv, VMAbv, VMPst,     R,  MBlw,  MBlw,  MBlw,  MBlw,    GB,
+  /* 11A30 */     B,     B,     B, FMBlw,  VBlw, VMAbv, VMAbv, VMAbv, VMAbv, VMPst,     R,  MBlw,  MBlw,  MBlw,  MBlw,    GB,
   /* 11A40 */     O,     O,     O,     O,     O,    GB,     O,     H,     O,     O,     O,     O,     O,     O,     O,     O,
 
   /* Soyombo */
@@ -809,7 +816,6 @@ hb_use_get_category (hb_codepoint_t u)
 #undef B
 #undef CGJ
 #undef CS
-#undef FM
 #undef GB
 #undef H
 #undef HN
@@ -821,6 +827,7 @@ hb_use_get_category (hb_codepoint_t u)
 #undef Rsv
 #undef S
 #undef SUB
+#undef Sk
 #undef VS
 #undef WJ
 #undef ZWJ
@@ -830,6 +837,9 @@ hb_use_get_category (hb_codepoint_t u)
 #undef FBlw
 #undef FPst
 #undef FAbv
+#undef FMBlw
+#undef FMPst
+#undef FMAbv
 #undef MPre
 #undef MBlw
 #undef MPst
@@ -845,4 +855,6 @@ hb_use_get_category (hb_codepoint_t u)
 #undef VMPst
 #undef VMAbv
 
+
+#endif
 /* == End of generated table == */
index eecde6e..10f5822 100644 (file)
  * Google Author(s): Behdad Esfahbod
  */
 
+#include "hb.hh"
+
+#ifndef HB_NO_OT_SHAPE
+
 #include "hb-ot-shape-complex-use.hh"
 #include "hb-ot-shape-complex-arabic.hh"
 #include "hb-ot-shape-complex-vowel-constraints.hh"
@@ -40,7 +44,7 @@
  */
 
 static const hb_tag_t
-basic_features[] =
+use_basic_features[] =
 {
   /*
    * Basic features.
@@ -55,28 +59,23 @@ basic_features[] =
   HB_TAG('c','j','c','t'),
 };
 static const hb_tag_t
-arabic_features[] =
+use_topographical_features[] =
 {
   HB_TAG('i','s','o','l'),
   HB_TAG('i','n','i','t'),
   HB_TAG('m','e','d','i'),
   HB_TAG('f','i','n','a'),
-  /* The spec doesn't specify these but we apply anyway, since our Arabic shaper
-   * does.  These are only used in Syriac spec. */
-  HB_TAG('m','e','d','2'),
-  HB_TAG('f','i','n','2'),
-  HB_TAG('f','i','n','3'),
 };
-/* Same order as arabic_features.  Don't need Syriac stuff.*/
+/* Same order as use_topographical_features. */
 enum joining_form_t {
-  ISOL,
-  INIT,
-  MEDI,
-  FINA,
-  _NONE
+  USE_ISOL,
+  USE_INIT,
+  USE_MEDI,
+  USE_FINA,
+  _USE_NONE
 };
 static const hb_tag_t
-other_features[] =
+use_other_features[] =
 {
   /*
    * Other features.
@@ -89,42 +88,23 @@ other_features[] =
   HB_TAG('p','r','e','s'),
   HB_TAG('p','s','t','s'),
 };
-static const hb_tag_t
-positioning_features[] =
-{
-  /*
-   * Positioning features.
-   * We don't care about the types.
-   */
-  HB_TAG('d','i','s','t'),
-  HB_TAG('a','b','v','m'),
-  HB_TAG('b','l','w','m'),
-};
 
 static void
-setup_syllables (const hb_ot_shape_plan_t *plan,
+setup_syllables_use (const hb_ot_shape_plan_t *plan,
+                    hb_font_t *font,
+                    hb_buffer_t *buffer);
+static void
+record_rphf_use (const hb_ot_shape_plan_t *plan,
                 hb_font_t *font,
                 hb_buffer_t *buffer);
 static void
-clear_substitution_flags (const hb_ot_shape_plan_t *plan,
-                         hb_font_t *font,
-                         hb_buffer_t *buffer);
-static void
-record_rphf (const hb_ot_shape_plan_t *plan,
-            hb_font_t *font,
-            hb_buffer_t *buffer);
+record_pref_use (const hb_ot_shape_plan_t *plan,
+                hb_font_t *font,
+                hb_buffer_t *buffer);
 static void
-record_pref (const hb_ot_shape_plan_t *plan,
+reorder_use (const hb_ot_shape_plan_t *plan,
             hb_font_t *font,
             hb_buffer_t *buffer);
-static void
-reorder (const hb_ot_shape_plan_t *plan,
-        hb_font_t *font,
-        hb_buffer_t *buffer);
-static void
-clear_syllables (const hb_ot_shape_plan_t *plan,
-                hb_font_t *font,
-                hb_buffer_t *buffer);
 
 static void
 collect_features_use (hb_ot_shape_planner_t *plan)
@@ -132,7 +112,7 @@ collect_features_use (hb_ot_shape_planner_t *plan)
   hb_ot_map_builder_t *map = &plan->map;
 
   /* Do this before any lookups have been applied. */
-  map->add_gsub_pause (setup_syllables);
+  map->add_gsub_pause (setup_syllables_use);
 
   /* "Default glyph pre-processing group" */
   map->enable_feature (HB_TAG('l','o','c','l'));
@@ -141,32 +121,28 @@ collect_features_use (hb_ot_shape_planner_t *plan)
   map->enable_feature (HB_TAG('a','k','h','n'), F_MANUAL_ZWJ);
 
   /* "Reordering group" */
-  map->add_gsub_pause (clear_substitution_flags);
+  map->add_gsub_pause (_hb_clear_substitution_flags);
   map->add_feature (HB_TAG('r','p','h','f'), F_MANUAL_ZWJ);
-  map->add_gsub_pause (record_rphf);
-  map->add_gsub_pause (clear_substitution_flags);
+  map->add_gsub_pause (record_rphf_use);
+  map->add_gsub_pause (_hb_clear_substitution_flags);
   map->enable_feature (HB_TAG('p','r','e','f'), F_MANUAL_ZWJ);
-  map->add_gsub_pause (record_pref);
+  map->add_gsub_pause (record_pref_use);
 
   /* "Orthographic unit shaping group" */
-  for (unsigned int i = 0; i < ARRAY_LENGTH (basic_features); i++)
-    map->enable_feature (basic_features[i], F_MANUAL_ZWJ);
+  for (unsigned int i = 0; i < ARRAY_LENGTH (use_basic_features); i++)
+    map->enable_feature (use_basic_features[i], F_MANUAL_ZWJ);
 
-  map->add_gsub_pause (reorder);
-  map->add_gsub_pause (clear_syllables);
+  map->add_gsub_pause (reorder_use);
+  map->add_gsub_pause (_hb_clear_syllables);
 
   /* "Topographical features" */
-  for (unsigned int i = 0; i < ARRAY_LENGTH (arabic_features); i++)
-    map->add_feature (arabic_features[i]);
+  for (unsigned int i = 0; i < ARRAY_LENGTH (use_topographical_features); i++)
+    map->add_feature (use_topographical_features[i]);
   map->add_gsub_pause (nullptr);
 
   /* "Standard typographic presentation" */
-  for (unsigned int i = 0; i < ARRAY_LENGTH (other_features); i++)
-    map->enable_feature (other_features[i], F_MANUAL_ZWJ);
-
-  /* "Positional feature application" */
-  for (unsigned int i = 0; i < ARRAY_LENGTH (positioning_features); i++)
-    map->enable_feature (positioning_features[i]);
+  for (unsigned int i = 0; i < ARRAY_LENGTH (use_other_features); i++)
+    map->enable_feature (use_other_features[i], F_MANUAL_ZWJ);
 }
 
 struct use_shape_plan_t
@@ -243,15 +219,16 @@ data_destroy_use (void *data)
   free (data);
 }
 
-enum syllable_type_t {
-  independent_cluster,
-  virama_terminated_cluster,
-  standard_cluster,
-  number_joiner_terminated_cluster,
-  numeral_cluster,
-  symbol_cluster,
-  broken_cluster,
-  non_cluster,
+enum use_syllable_type_t {
+  use_independent_cluster,
+  use_virama_terminated_cluster,
+  use_sakot_terminated_cluster,
+  use_standard_cluster,
+  use_number_joiner_terminated_cluster,
+  use_numeral_cluster,
+  use_symbol_cluster,
+  use_broken_cluster,
+  use_non_cluster,
 };
 
 #include "hb-ot-shape-complex-use-machine.hh"
@@ -294,7 +271,7 @@ setup_rphf_mask (const hb_ot_shape_plan_t *plan,
 
   foreach_syllable (buffer, start, end)
   {
-    unsigned int limit = info[start].use_category() == USE_R ? 1 : MIN (3u, end - start);
+    unsigned int limit = info[start].use_category() == USE_R ? 1 : hb_min (3u, end - start);
     for (unsigned int i = start; i < start + limit; i++)
       info[i].mask |= mask;
   }
@@ -308,11 +285,11 @@ setup_topographical_masks (const hb_ot_shape_plan_t *plan,
   if (use_plan->arabic_plan)
     return;
 
-  static_assert ((INIT < 4 && ISOL < 4 && MEDI < 4 && FINA < 4), "");
+  static_assert ((USE_INIT < 4 && USE_ISOL < 4 && USE_MEDI < 4 && USE_FINA < 4), "");
   hb_mask_t masks[4], all_masks = 0;
   for (unsigned int i = 0; i < 4; i++)
   {
-    masks[i] = plan->map.get_1_mask (arabic_features[i]);
+    masks[i] = plan->map.get_1_mask (use_topographical_features[i]);
     if (masks[i] == plan->map.get_global_mask ())
       masks[i] = 0;
     all_masks |= masks[i];
@@ -322,38 +299,39 @@ setup_topographical_masks (const hb_ot_shape_plan_t *plan,
   hb_mask_t other_masks = ~all_masks;
 
   unsigned int last_start = 0;
-  joining_form_t last_form = _NONE;
+  joining_form_t last_form = _USE_NONE;
   hb_glyph_info_t *info = buffer->info;
   foreach_syllable (buffer, start, end)
   {
-    syllable_type_t syllable_type = (syllable_type_t) (info[start].syllable() & 0x0F);
+    use_syllable_type_t syllable_type = (use_syllable_type_t) (info[start].syllable() & 0x0F);
     switch (syllable_type)
     {
-      case independent_cluster:
-      case symbol_cluster:
-      case non_cluster:
+      case use_independent_cluster:
+      case use_symbol_cluster:
+      case use_non_cluster:
        /* These don't join.  Nothing to do. */
-       last_form = _NONE;
+       last_form = _USE_NONE;
        break;
 
-      case virama_terminated_cluster:
-      case standard_cluster:
-      case number_joiner_terminated_cluster:
-      case numeral_cluster:
-      case broken_cluster:
+      case use_virama_terminated_cluster:
+      case use_sakot_terminated_cluster:
+      case use_standard_cluster:
+      case use_number_joiner_terminated_cluster:
+      case use_numeral_cluster:
+      case use_broken_cluster:
 
-       bool join = last_form == FINA || last_form == ISOL;
+       bool join = last_form == USE_FINA || last_form == USE_ISOL;
 
        if (join)
        {
          /* Fixup previous syllable's form. */
-         last_form = last_form == FINA ? MEDI : INIT;
+         last_form = last_form == USE_FINA ? USE_MEDI : USE_INIT;
          for (unsigned int i = last_start; i < start; i++)
            info[i].mask = (info[i].mask & other_masks) | masks[last_form];
        }
 
        /* Form for this syllable. */
-       last_form = join ? FINA : ISOL;
+       last_form = join ? USE_FINA : USE_ISOL;
        for (unsigned int i = start; i < end; i++)
          info[i].mask = (info[i].mask & other_masks) | masks[last_form];
 
@@ -365,11 +343,11 @@ setup_topographical_masks (const hb_ot_shape_plan_t *plan,
 }
 
 static void
-setup_syllables (const hb_ot_shape_plan_t *plan,
-                hb_font_t *font HB_UNUSED,
-                hb_buffer_t *buffer)
+setup_syllables_use (const hb_ot_shape_plan_t *plan,
+                    hb_font_t *font HB_UNUSED,
+                    hb_buffer_t *buffer)
 {
-  find_syllables (buffer);
+  find_syllables_use (buffer);
   foreach_syllable (buffer, start, end)
     buffer->unsafe_to_break (start, end);
   setup_rphf_mask (plan, buffer);
@@ -377,20 +355,9 @@ setup_syllables (const hb_ot_shape_plan_t *plan,
 }
 
 static void
-clear_substitution_flags (const hb_ot_shape_plan_t *plan HB_UNUSED,
-                         hb_font_t *font HB_UNUSED,
-                         hb_buffer_t *buffer)
-{
-  hb_glyph_info_t *info = buffer->info;
-  unsigned int count = buffer->len;
-  for (unsigned int i = 0; i < count; i++)
-    _hb_glyph_info_clear_substituted (&info[i]);
-}
-
-static void
-record_rphf (const hb_ot_shape_plan_t *plan,
-            hb_font_t *font HB_UNUSED,
-            hb_buffer_t *buffer)
+record_rphf_use (const hb_ot_shape_plan_t *plan,
+                hb_font_t *font HB_UNUSED,
+                hb_buffer_t *buffer)
 {
   const use_shape_plan_t *use_plan = (const use_shape_plan_t *) plan->data;
 
@@ -411,9 +378,9 @@ record_rphf (const hb_ot_shape_plan_t *plan,
 }
 
 static void
-record_pref (const hb_ot_shape_plan_t *plan HB_UNUSED,
-            hb_font_t *font HB_UNUSED,
-            hb_buffer_t *buffer)
+record_pref_use (const hb_ot_shape_plan_t *plan HB_UNUSED,
+                hb_font_t *font HB_UNUSED,
+                hb_buffer_t *buffer)
 {
   hb_glyph_info_t *info = buffer->info;
 
@@ -430,21 +397,22 @@ record_pref (const hb_ot_shape_plan_t *plan HB_UNUSED,
 }
 
 static inline bool
-is_halant (const hb_glyph_info_t &info)
+is_halant_use (const hb_glyph_info_t &info)
 {
   return (info.use_category() == USE_H || info.use_category() == USE_HVM) &&
         !_hb_glyph_info_ligated (&info);
 }
 
 static void
-reorder_syllable (hb_buffer_t *buffer, unsigned int start, unsigned int end)
+reorder_syllable_use (hb_buffer_t *buffer, unsigned int start, unsigned int end)
 {
-  syllable_type_t syllable_type = (syllable_type_t) (buffer->info[start].syllable() & 0x0F);
+  use_syllable_type_t syllable_type = (use_syllable_type_t) (buffer->info[start].syllable() & 0x0F);
   /* Only a few syllable types need reordering. */
   if (unlikely (!(FLAG_UNSAFE (syllable_type) &
-                 (FLAG (virama_terminated_cluster) |
-                  FLAG (standard_cluster) |
-                  FLAG (broken_cluster) |
+                 (FLAG (use_virama_terminated_cluster) |
+                  FLAG (use_sakot_terminated_cluster) |
+                  FLAG (use_standard_cluster) |
+                  FLAG (use_broken_cluster) |
                   0))))
     return;
 
@@ -475,7 +443,7 @@ reorder_syllable (hb_buffer_t *buffer, unsigned int start, unsigned int end)
     for (unsigned int i = start + 1; i < end; i++)
     {
       bool is_post_base_glyph = (FLAG64_UNSAFE (info[i].use_category()) & POST_BASE_FLAGS64) ||
-                               is_halant (info[i]);
+                               is_halant_use (info[i]);
       if (is_post_base_glyph || i == end - 1)
       {
        /* If we hit a post-base glyph, move before it; otherwise move to the
@@ -499,7 +467,7 @@ reorder_syllable (hb_buffer_t *buffer, unsigned int start, unsigned int end)
   for (unsigned int i = start; i < end; i++)
   {
     uint32_t flag = FLAG_UNSAFE (info[i].use_category());
-    if (is_halant (info[i]))
+    if (is_halant_use (info[i]))
     {
       /* If we hit a halant, move after it; otherwise move to the beginning, and
        * shift things in between forward. */
@@ -519,19 +487,20 @@ reorder_syllable (hb_buffer_t *buffer, unsigned int start, unsigned int end)
 }
 
 static inline void
-insert_dotted_circles (const hb_ot_shape_plan_t *plan HB_UNUSED,
-                      hb_font_t *font,
-                      hb_buffer_t *buffer)
+insert_dotted_circles_use (const hb_ot_shape_plan_t *plan HB_UNUSED,
+                          hb_font_t *font,
+                          hb_buffer_t *buffer)
 {
   if (unlikely (buffer->flags & HB_BUFFER_FLAG_DO_NOT_INSERT_DOTTED_CIRCLE))
     return;
 
-  /* Note: This loop is extra overhead, but should not be measurable. */
+  /* Note: This loop is extra overhead, but should not be measurable.
+   * TODO Use a buffer scratch flag to remove the loop. */
   bool has_broken_syllables = false;
   unsigned int count = buffer->len;
   hb_glyph_info_t *info = buffer->info;
   for (unsigned int i = 0; i < count; i++)
-    if ((info[i].syllable() & 0x0F) == broken_cluster)
+    if ((info[i].syllable() & 0x0F) == use_broken_cluster)
     {
       has_broken_syllables = true;
       break;
@@ -551,8 +520,8 @@ insert_dotted_circles (const hb_ot_shape_plan_t *plan HB_UNUSED,
   while (buffer->idx < buffer->len && buffer->successful)
   {
     unsigned int syllable = buffer->cur().syllable();
-    syllable_type_t syllable_type = (syllable_type_t) (syllable & 0x0F);
-    if (unlikely (last_syllable != syllable && syllable_type == broken_cluster))
+    use_syllable_type_t syllable_type = (use_syllable_type_t) (syllable & 0x0F);
+    if (unlikely (last_syllable != syllable && syllable_type == use_broken_cluster))
     {
       last_syllable = syllable;
 
@@ -560,13 +529,12 @@ insert_dotted_circles (const hb_ot_shape_plan_t *plan HB_UNUSED,
       ginfo.cluster = buffer->cur().cluster;
       ginfo.mask = buffer->cur().mask;
       ginfo.syllable() = buffer->cur().syllable();
-      /* TODO Set glyph_props? */
 
       /* Insert dottedcircle after possible Repha. */
       while (buffer->idx < buffer->len && buffer->successful &&
             last_syllable == buffer->cur().syllable() &&
             buffer->cur().use_category() == USE_R)
-        buffer->next_glyph ();
+       buffer->next_glyph ();
 
       buffer->output_info (ginfo);
     }
@@ -577,29 +545,18 @@ insert_dotted_circles (const hb_ot_shape_plan_t *plan HB_UNUSED,
 }
 
 static void
-reorder (const hb_ot_shape_plan_t *plan,
-        hb_font_t *font,
-        hb_buffer_t *buffer)
+reorder_use (const hb_ot_shape_plan_t *plan,
+            hb_font_t *font,
+            hb_buffer_t *buffer)
 {
-  insert_dotted_circles (plan, font, buffer);
+  insert_dotted_circles_use (plan, font, buffer);
 
   foreach_syllable (buffer, start, end)
-    reorder_syllable (buffer, start, end);
+    reorder_syllable_use (buffer, start, end);
 
   HB_BUFFER_DEALLOCATE_VAR (buffer, use_category);
 }
 
-static void
-clear_syllables (const hb_ot_shape_plan_t *plan HB_UNUSED,
-                hb_font_t *font HB_UNUSED,
-                hb_buffer_t *buffer)
-{
-  hb_glyph_info_t *info = buffer->info;
-  unsigned int count = buffer->len;
-  for (unsigned int i = 0; i < count; i++)
-    info[i].syllable() = 0;
-}
-
 
 static void
 preprocess_text_use (const hb_ot_shape_plan_t *plan,
@@ -640,3 +597,6 @@ const hb_ot_complex_shaper_t _hb_ot_complex_shaper_use =
   HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_GDEF_EARLY,
   false, /* fallback_position */
 };
+
+
+#endif
index ab56e1b..ce6645e 100644 (file)
@@ -68,6 +68,12 @@ enum use_category_t {
   USE_VS       = 21,   /* VARIATION_SELECTOR */
 //  USE_V      = 36,   /* VOWEL */
 //  USE_VM     = 40,   /* VOWEL_MOD */
+  USE_CS       = 43,   /* CONS_WITH_STACKER */
+
+  /* https://github.com/harfbuzz/harfbuzz/issues/1102 */
+  USE_HVM      = 44,   /* HALANT_OR_VOWEL_MODIFIER */
+
+  USE_Sk       = 48,   /* SAKOT */
 
   USE_FAbv     = 24,   /* CONS_FINAL_ABOVE */
   USE_FBlw     = 25,   /* CONS_FINAL_BELOW */
@@ -88,10 +94,9 @@ enum use_category_t {
   USE_VMPre    = 23,   /* VOWEL_MOD_PRE */
   USE_SMAbv    = 41,   /* SYM_MOD_ABOVE */
   USE_SMBlw    = 42,   /* SYM_MOD_BELOW */
-  USE_CS       = 43,   /* CONS_WITH_STACKER */
-
-  /* https://github.com/harfbuzz/harfbuzz/issues/1102 */
-  USE_HVM      = 44,   /* HALANT_OR_VOWEL_MODIFIER */
+  USE_FMAbv    = 45,   /* CONS_FINAL_MOD       UIPC = Top */
+  USE_FMBlw    = 46,   /* CONS_FINAL_MOD       UIPC = Bottom */
+  USE_FMPst    = 47,   /* CONS_FINAL_MOD       UIPC = Not_Applicable */
 };
 
 HB_INTERNAL USE_TABLE_ELEMENT_TYPE
index e4cf645..2f80413 100644 (file)
  * # Date: 2019-01-28, 22:16:47 GMT
  */
 
+#include "hb.hh"
+
+#ifndef HB_NO_OT_SHAPE
+
 #include "hb-ot-shape-complex-vowel-constraints.hh"
 
 static void
@@ -34,6 +38,9 @@ _hb_preprocess_text_vowel_constraints (const hb_ot_shape_plan_t *plan HB_UNUSED,
                                       hb_buffer_t              *buffer,
                                       hb_font_t                *font HB_UNUSED)
 {
+#ifdef HB_NO_OT_SHAPE_COMPLEX_VOWEL_CONSTRAINTS
+  return;
+#endif
   if (buffer->flags & HB_BUFFER_FLAG_DO_NOT_INSERT_DOTTED_CIRCLE)
     return;
 
@@ -437,4 +444,6 @@ _hb_preprocess_text_vowel_constraints (const hb_ot_shape_plan_t *plan HB_UNUSED,
   }
 }
 
+
+#endif
 /* == End of generated functions == */
index f9d4a75..024bcfe 100644 (file)
  * Google Author(s): Behdad Esfahbod
  */
 
+#include "hb.hh"
+
+#ifndef HB_NO_OT_SHAPE
+
 #include "hb-ot-shape-fallback.hh"
 #include "hb-kern.hh"
 
@@ -41,30 +45,30 @@ recategorize_combining_class (hb_codepoint_t u,
     {
       switch (u)
       {
-        case 0x0E31u:
-        case 0x0E34u:
-        case 0x0E35u:
-        case 0x0E36u:
-        case 0x0E37u:
-        case 0x0E47u:
-        case 0x0E4Cu:
-        case 0x0E4Du:
-        case 0x0E4Eu:
+       case 0x0E31u:
+       case 0x0E34u:
+       case 0x0E35u:
+       case 0x0E36u:
+       case 0x0E37u:
+       case 0x0E47u:
+       case 0x0E4Cu:
+       case 0x0E4Du:
+       case 0x0E4Eu:
          klass = HB_UNICODE_COMBINING_CLASS_ABOVE_RIGHT;
          break;
 
-        case 0x0EB1u:
-        case 0x0EB4u:
-        case 0x0EB5u:
-        case 0x0EB6u:
-        case 0x0EB7u:
-        case 0x0EBBu:
-        case 0x0ECCu:
-        case 0x0ECDu:
+       case 0x0EB1u:
+       case 0x0EB4u:
+       case 0x0EB5u:
+       case 0x0EB6u:
+       case 0x0EB7u:
+       case 0x0EBBu:
+       case 0x0ECCu:
+       case 0x0ECDu:
          klass = HB_UNICODE_COMBINING_CLASS_ABOVE;
          break;
 
-        case 0x0EBCu:
+       case 0x0EBCu:
          klass = HB_UNICODE_COMBINING_CLASS_BELOW;
          break;
       }
@@ -163,9 +167,13 @@ recategorize_combining_class (hb_codepoint_t u,
 
 void
 _hb_ot_shape_fallback_mark_position_recategorize_marks (const hb_ot_shape_plan_t *plan HB_UNUSED,
-                                                       hb_font_t *font HB_UNUSED,
-                                                       hb_buffer_t  *buffer)
+                                                       hb_font_t *font HB_UNUSED,
+                                                       hb_buffer_t  *buffer)
 {
+#ifdef HB_NO_OT_SHAPE_FALLBACK
+  return;
+#endif
+
   unsigned int count = buffer->len;
   hb_glyph_info_t *info = buffer->info;
   for (unsigned int i = 0; i < count; i++)
@@ -224,10 +232,10 @@ position_mark (const hb_ot_shape_plan_t *plan HB_UNUSED,
     case HB_UNICODE_COMBINING_CLASS_DOUBLE_ABOVE:
       if (buffer->props.direction == HB_DIRECTION_LTR) {
        pos.x_offset += base_extents.x_bearing + base_extents.width - mark_extents.width / 2 - mark_extents.x_bearing;
-        break;
+       break;
       } else if (buffer->props.direction == HB_DIRECTION_RTL) {
        pos.x_offset += base_extents.x_bearing - mark_extents.width / 2 - mark_extents.x_bearing;
-        break;
+       break;
       }
       HB_FALLTHROUGH;
 
@@ -379,7 +387,7 @@ position_around_base (const hb_ot_shape_plan_t *plan,
       if (last_combining_class != this_combining_class)
       {
        last_combining_class = this_combining_class;
-        cluster_extents = component_extents;
+       cluster_extents = component_extents;
       }
 
       position_mark (plan, font, buffer, cluster_extents, i, this_combining_class);
@@ -434,6 +442,10 @@ _hb_ot_shape_fallback_mark_position (const hb_ot_shape_plan_t *plan,
                                     hb_buffer_t  *buffer,
                                     bool adjust_offsets_when_zeroing)
 {
+#ifdef HB_NO_OT_SHAPE_FALLBACK
+  return;
+#endif
+
   _hb_buffer_assert_gsubgpos_vars (buffer);
 
   unsigned int start = 0;
@@ -448,6 +460,7 @@ _hb_ot_shape_fallback_mark_position (const hb_ot_shape_plan_t *plan,
 }
 
 
+#ifndef HB_DISABLE_DEPRECATED
 struct hb_ot_shape_fallback_kern_driver_t
 {
   hb_ot_shape_fallback_kern_driver_t (hb_font_t   *font_,
@@ -466,6 +479,7 @@ struct hb_ot_shape_fallback_kern_driver_t
   hb_font_t *font;
   hb_direction_t direction;
 };
+#endif
 
 /* Performs font-assisted kerning. */
 void
@@ -473,6 +487,11 @@ _hb_ot_shape_fallback_kern (const hb_ot_shape_plan_t *plan,
                            hb_font_t *font,
                            hb_buffer_t *buffer)
 {
+#ifdef HB_NO_OT_SHAPE_FALLBACK
+  return;
+#endif
+
+#ifndef HB_DISABLE_DEPRECATED
   if (HB_DIRECTION_IS_HORIZONTAL (buffer->props.direction) ?
       !font->has_glyph_h_kerning_func () :
       !font->has_glyph_v_kerning_func ())
@@ -489,6 +508,7 @@ _hb_ot_shape_fallback_kern (const hb_ot_shape_plan_t *plan,
 
   if (reverse)
     buffer->reverse ();
+#endif
 }
 
 
@@ -571,3 +591,6 @@ _hb_ot_shape_fallback_spaces (const hb_ot_shape_plan_t *plan HB_UNUSED,
       }
     }
 }
+
+
+#endif
index 82bb24b..553d532 100644 (file)
  * Google Author(s): Behdad Esfahbod
  */
 
+#include "hb.hh"
+
+#ifndef HB_NO_OT_SHAPE
+
 #include "hb-ot-shape-normalize.hh"
 #include "hb-ot-shape-complex.hh"
 #include "hb-ot-shape.hh"
@@ -229,7 +233,7 @@ handle_variation_selector_cluster (const hb_ot_shape_normalize_context_t *c,
       }
       else
       {
-        /* Just pass on the two characters separately, let GSUB do its magic. */
+       /* Just pass on the two characters separately, let GSUB do its magic. */
        set_glyph (buffer->cur(), font);
        buffer->next_glyph ();
        set_glyph (buffer->cur(), font);
@@ -339,7 +343,7 @@ _hb_ot_shape_normalize (const hb_ot_shape_plan_t *plan,
       /* From idx to end are simple clusters. */
       if (might_short_circuit)
       {
-        unsigned int done = font->get_nominal_glyphs (end - buffer->idx,
+       unsigned int done = font->get_nominal_glyphs (end - buffer->idx,
                                                      &buffer->cur().codepoint,
                                                      sizeof (buffer->info[0]),
                                                      &buffer->cur().glyph_index(),
@@ -469,3 +473,6 @@ _hb_ot_shape_normalize (const hb_ot_shape_plan_t *plan,
     buffer->swap_buffers ();
   }
 }
+
+
+#endif
index 7fff305..5d9a70c 100644 (file)
  * Google Author(s): Behdad Esfahbod
  */
 
+#include "hb.hh"
+
+#ifndef HB_NO_OT_SHAPE
+
+#ifdef HB_NO_OT_LAYOUT
+#error "Cannot compile 'ot' shaper with HB_NO_OT_LAYOUT."
+#endif
+
 #include "hb-shaper-impl.hh"
 
 #include "hb-ot-shape.hh"
@@ -55,7 +63,8 @@ hb_ot_shape_collect_features (hb_ot_shape_planner_t          *planner,
                              const hb_feature_t             *user_features,
                              unsigned int                    num_user_features);
 
-static bool
+#ifndef HB_NO_AAT_SHAPE
+static inline bool
 _hb_apply_morx (hb_face_t *face)
 {
   if (hb_options ().aat &&
@@ -69,14 +78,17 @@ _hb_apply_morx (hb_face_t *face)
                                               0, nullptr, nullptr)) &&
         hb_aat_layout_has_substitution (face);
 }
+#endif
 
 hb_ot_shape_planner_t::hb_ot_shape_planner_t (hb_face_t                     *face,
                                              const hb_segment_properties_t *props) :
                                                face (face),
                                                props (*props),
                                                map (face, props),
-                                               aat_map (face, props),
-                                               apply_morx (_hb_apply_morx (face))
+                                               aat_map (face, props)
+#ifndef HB_NO_AAT_SHAPE
+                                               , apply_morx (_hb_apply_morx (face))
+#endif
 {
   shaper = hb_ot_shape_complex_categorize (this);
 
@@ -94,21 +106,30 @@ hb_ot_shape_planner_t::compile (hb_ot_shape_plan_t           &plan,
   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'));
   plan.numr_mask = plan.map.get_1_mask (HB_TAG ('n','u','m','r'));
   plan.dnom_mask = plan.map.get_1_mask (HB_TAG ('d','n','o','m'));
   plan.has_frac = plan.frac_mask || (plan.numr_mask && plan.dnom_mask);
+#endif
+
   plan.rtlm_mask = plan.map.get_1_mask (HB_TAG ('r','t','l','m'));
   hb_tag_t kern_tag = HB_DIRECTION_IS_HORIZONTAL (props.direction) ?
                      HB_TAG ('k','e','r','n') : HB_TAG ('v','k','r','n');
+#ifndef HB_NO_OT_KERN
   plan.kern_mask = plan.map.get_mask (kern_tag);
-  plan.trak_mask = plan.map.get_mask (HB_TAG ('t','r','a','k'));
-
   plan.requested_kerning = !!plan.kern_mask;
+#endif
+#ifndef HB_NO_AAT_SHAPE
+  plan.trak_mask = plan.map.get_mask (HB_TAG ('t','r','a','k'));
   plan.requested_tracking = !!plan.trak_mask;
+#endif
+
   bool has_gpos_kern = plan.map.get_feature_index (1, kern_tag) != HB_OT_LAYOUT_NO_FEATURE_INDEX;
   bool disable_gpos = plan.shaper->gpos_tag &&
                      plan.shaper->gpos_tag != plan.map.chosen_script[1];
@@ -124,42 +145,65 @@ hb_ot_shape_planner_t::compile (hb_ot_shape_plan_t           &plan,
    * Decide who does substitutions. GSUB, morx, or fallback.
    */
 
+#ifndef HB_NO_AAT_SHAPE
   plan.apply_morx = apply_morx;
+#endif
 
   /*
    * Decide who does positioning. GPOS, kerx, kern, or fallback.
    */
 
-  if (hb_options ().aat && hb_aat_layout_has_positioning (face))
+  if (0)
+    ;
+#ifndef HB_NO_AAT_SHAPE
+  else if (hb_options ().aat && hb_aat_layout_has_positioning (face))
     plan.apply_kerx = true;
+#endif
   else if (!apply_morx && !disable_gpos && hb_ot_layout_has_positioning (face))
     plan.apply_gpos = true;
+#ifndef HB_NO_AAT_SHAPE
   else if (hb_aat_layout_has_positioning (face))
     plan.apply_kerx = true;
+#endif
 
   if (!plan.apply_kerx && !has_gpos_kern)
   {
     /* Apparently Apple applies kerx if GPOS kern was not applied. */
+#ifndef HB_NO_AAT_SHAPE
     if (hb_aat_layout_has_positioning (face))
       plan.apply_kerx = true;
-    else if (hb_ot_layout_has_kerning (face))
+    else
+#endif
+#ifndef HB_NO_OT_KERN
+    if (hb_ot_layout_has_kerning (face))
       plan.apply_kern = true;
+#endif
   }
 
   plan.zero_marks = script_zero_marks &&
                    !plan.apply_kerx &&
-                   (!plan.apply_kern || !hb_ot_layout_has_machine_kerning (face));
+                   (!plan.apply_kern
+#ifndef HB_NO_OT_KERN
+                    || !hb_ot_layout_has_machine_kerning (face)
+#endif
+                   );
   plan.has_gpos_mark = !!plan.map.get_1_mask (HB_TAG ('m','a','r','k'));
 
   plan.adjust_mark_positioning_when_zeroing = !plan.apply_gpos &&
                                              !plan.apply_kerx &&
-                                             (!plan.apply_kern || !hb_ot_layout_has_cross_kerning (face));
+                                             (!plan.apply_kern
+#ifndef HB_NO_OT_KERN
+                                              || !hb_ot_layout_has_cross_kerning (face)
+#endif
+                                             );
 
   plan.fallback_mark_positioning = plan.adjust_mark_positioning_when_zeroing &&
                                   script_fallback_mark_positioning;
 
+#ifndef HB_NO_AAT_SHAPE
   /* Currently we always apply trak. */
   plan.apply_trak = plan.requested_tracking && hb_aat_layout_has_tracking (face);
+#endif
 }
 
 bool
@@ -167,7 +211,9 @@ hb_ot_shape_plan_t::init0 (hb_face_t                     *face,
                           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);
@@ -195,16 +241,20 @@ hb_ot_shape_plan_t::fini ()
     shaper->data_destroy (const_cast<void *> (data));
 
   map.fini ();
+#ifndef HB_NO_AAT_SHAPE
   aat_map.fini ();
+#endif
 }
 
 void
 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);
 }
 
@@ -214,21 +264,29 @@ hb_ot_shape_plan_t::position (hb_font_t   *font,
 {
   if (this->apply_gpos)
     map.position (this, font, buffer);
+#ifndef HB_NO_AAT_SHAPE
   else if (this->apply_kerx)
     hb_aat_layout_position (this, font, buffer);
+#endif
+#ifndef HB_NO_OT_KERN
   else if (this->apply_kern)
     hb_ot_layout_kern (this, font, buffer);
+#endif
   else
     _hb_ot_shape_fallback_kern (this, font, buffer);
 
+#ifndef HB_NO_AAT_SHAPE
   if (this->apply_trak)
     hb_aat_layout_track (this, font, buffer);
+#endif
 }
 
 
 static const hb_ot_map_feature_t
 common_features[] =
 {
+  {HB_TAG('a','b','v','m'), F_GLOBAL},
+  {HB_TAG('b','l','w','m'), F_GLOBAL},
   {HB_TAG('c','c','m','p'), F_GLOBAL},
   {HB_TAG('l','o','c','l'), F_GLOBAL},
   {HB_TAG('m','a','r','k'), F_GLOBAL_MANUAL_JOINERS},
@@ -243,6 +301,7 @@ horizontal_features[] =
   {HB_TAG('c','a','l','t'), F_GLOBAL},
   {HB_TAG('c','l','i','g'), F_GLOBAL},
   {HB_TAG('c','u','r','s'), F_GLOBAL},
+  {HB_TAG('d','i','s','t'), F_GLOBAL},
   {HB_TAG('k','e','r','n'), F_GLOBAL_HAS_FALLBACK},
   {HB_TAG('l','i','g','a'), F_GLOBAL},
   {HB_TAG('r','c','l','t'), F_GLOBAL},
@@ -274,18 +333,22 @@ hb_ot_shape_collect_features (hb_ot_shape_planner_t          *planner,
       break;
   }
 
+#ifndef HB_NO_OT_SHAPE_FRACTIONS
   /* Automatic fractions. */
   map->add_feature (HB_TAG ('f','r','a','c'));
   map->add_feature (HB_TAG ('n','u','m','r'));
   map->add_feature (HB_TAG ('d','n','o','m'));
+#endif
 
   /* Random! */
   map->enable_feature (HB_TAG ('r','a','n','d'), F_RANDOM, HB_OT_MAP_MAX_VALUE);
 
+#ifndef HB_NO_AAT_SHAPE
   /* Tracking.  We enable dummy feature here just to allow disabling
    * AAT 'trak' table using features.
    * https://github.com/harfbuzz/harfbuzz/issues/1303 */
   map->enable_feature (HB_TAG ('t','r','a','k'), F_HAS_FALLBACK);
+#endif
 
   map->enable_feature (HB_TAG ('H','A','R','F'));
 
@@ -318,6 +381,7 @@ hb_ot_shape_collect_features (hb_ot_shape_planner_t          *planner,
                      feature->value);
   }
 
+#ifndef HB_NO_AAT_SHAPE
   if (planner->apply_morx)
   {
     hb_aat_map_builder_t *aat_map = &planner->aat_map;
@@ -327,6 +391,7 @@ hb_ot_shape_collect_features (hb_ot_shape_planner_t          *planner,
       aat_map->add_feature (feature->tag, feature->value);
     }
   }
+#endif
 
   if (planner->shaper->override_features)
     planner->shaper->override_features (planner);
@@ -417,17 +482,19 @@ hb_set_unicode_props (hb_buffer_t *buffer)
     {
        _hb_glyph_info_set_continuation (&info[i]);
     }
+#ifndef HB_NO_EMOJI_SEQUENCES
     else if (unlikely (_hb_glyph_info_is_zwj (&info[i])))
     {
       _hb_glyph_info_set_continuation (&info[i]);
       if (i + 1 < count &&
          _hb_unicode_is_emoji_Extended_Pictographic (info[i + 1].codepoint))
       {
-        i++;
+       i++;
        _hb_glyph_info_set_unicode_props (&info[i], buffer);
        _hb_glyph_info_set_continuation (&info[i]);
       }
     }
+#endif
     /* Or part of the Other_Grapheme_Extend that is not marks.
      * As of Unicode 11 that is just:
      *
@@ -551,6 +618,10 @@ hb_ot_mirror_chars (const hb_ot_shape_context_t *c)
 static inline void
 hb_ot_shape_setup_masks_fraction (const hb_ot_shape_context_t *c)
 {
+#ifdef HB_NO_OT_SHAPE_FRACTIONS
+  return;
+#endif
+
   if (!(c->buffer->scratch_flags & HB_BUFFER_SCRATCH_FLAG_HAS_NON_ASCII) ||
       !c->plan->has_frac)
     return;
@@ -579,19 +650,19 @@ hb_ot_shape_setup_masks_fraction (const hb_ot_shape_context_t *c)
       while (start &&
             _hb_glyph_info_get_general_category (&info[start - 1]) ==
             HB_UNICODE_GENERAL_CATEGORY_DECIMAL_NUMBER)
-        start--;
+       start--;
       while (end < count &&
             _hb_glyph_info_get_general_category (&info[end]) ==
             HB_UNICODE_GENERAL_CATEGORY_DECIMAL_NUMBER)
-        end++;
+       end++;
 
       buffer->unsafe_to_break (start, end);
 
       for (unsigned int j = start; j < i; j++)
-        info[j].mask |= pre_mask;
+       info[j].mask |= pre_mask;
       info[i].mask |= c->plan->frac_mask;
       for (unsigned int j = i + 1; j < end; j++)
-        info[j].mask |= post_mask;
+       info[j].mask |= post_mask;
 
       i = end - 1;
     }
@@ -761,8 +832,10 @@ static inline void
 hb_ot_substitute_post (const hb_ot_shape_context_t *c)
 {
   hb_ot_hide_default_ignorables (c->buffer, c->font);
+#ifndef HB_NO_AAT_SHAPE
   if (c->plan->apply_morx)
     hb_aat_layout_remove_deleted_glyphs (c->buffer);
+#endif
 
   if (c->plan->shaper->postprocess_glyphs)
     c->plan->shaper->postprocess_glyphs (c->plan, c->buffer, c->font);
@@ -796,7 +869,7 @@ zero_mark_widths_by_gdef (hb_buffer_t *buffer, bool adjust_offsets)
     if (_hb_glyph_info_is_mark (&info[i]))
     {
       if (adjust_offsets)
-        adjust_mark_offsets (&buffer->pos[i]);
+       adjust_mark_offsets (&buffer->pos[i]);
       zero_mark_width (&buffer->pos[i]);
     }
 }
@@ -812,7 +885,7 @@ hb_ot_position_default (const hb_ot_shape_context_t *c)
   if (HB_DIRECTION_IS_HORIZONTAL (direction))
   {
     c->font->get_glyph_h_advances (count, &info[0].codepoint, sizeof(info[0]),
-                                   &pos[0].x_advance, sizeof(pos[0]));
+                                  &pos[0].x_advance, sizeof(pos[0]));
     /* The nil glyph_h_origin() func returns 0, so no need to apply it. */
     if (c->font->has_glyph_h_origin_func ())
       for (unsigned int i = 0; i < count; i++)
@@ -823,7 +896,7 @@ hb_ot_position_default (const hb_ot_shape_context_t *c)
   else
   {
     c->font->get_glyph_v_advances (count, &info[0].codepoint, sizeof(info[0]),
-                                   &pos[0].y_advance, sizeof(pos[0]));
+                                  &pos[0].y_advance, sizeof(pos[0]));
     for (unsigned int i = 0; i < count; i++)
     {
       c->font->subtract_glyph_v_origin (info[i].codepoint,
@@ -896,8 +969,10 @@ hb_ot_position_complex (const hb_ot_shape_context_t *c)
   /* Finish off.  Has to follow a certain order. */
   hb_ot_layout_position_finish_advances (c->font, c->buffer);
   hb_ot_zero_width_default_ignorables (c->buffer);
+#ifndef HB_NO_AAT_SHAPE
   if (c->plan->apply_morx)
     hb_aat_layout_zero_width_deleted_glyphs (c->buffer);
+#endif
   hb_ot_layout_position_finish_offsets (c->font, c->buffer);
 
   /* The nil glyph_h_origin() func returns 0, so no need to apply it. */
@@ -962,12 +1037,12 @@ hb_ot_shape_internal (hb_ot_shape_context_t *c)
   c->buffer->scratch_flags = HB_BUFFER_SCRATCH_FLAG_DEFAULT;
   if (likely (!hb_unsigned_mul_overflows (c->buffer->len, HB_BUFFER_MAX_LEN_FACTOR)))
   {
-    c->buffer->max_len = MAX (c->buffer->len * HB_BUFFER_MAX_LEN_FACTOR,
+    c->buffer->max_len = hb_max (c->buffer->len * HB_BUFFER_MAX_LEN_FACTOR,
                              (unsigned) HB_BUFFER_MAX_LEN_MIN);
   }
   if (likely (!hb_unsigned_mul_overflows (c->buffer->len, HB_BUFFER_MAX_OPS_FACTOR)))
   {
-    c->buffer->max_ops = MAX (c->buffer->len * HB_BUFFER_MAX_OPS_FACTOR,
+    c->buffer->max_ops = hb_max (c->buffer->len * HB_BUFFER_MAX_OPS_FACTOR,
                              (unsigned) HB_BUFFER_MAX_OPS_MIN);
   }
 
@@ -1084,3 +1159,6 @@ hb_ot_shape_glyphs_closure (hb_font_t          *font,
 
   hb_shape_plan_destroy (shape_plan);
 }
+
+
+#endif
index 73a11e1..2cde73d 100644 (file)
@@ -65,14 +65,40 @@ struct hb_ot_shape_plan_t
   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;
+#else
+  static constexpr hb_mask_t frac_mask = 0;
+  static constexpr hb_mask_t numr_mask = 0;
+  static constexpr hb_mask_t dnom_mask = 0;
+#endif
   hb_mask_t rtlm_mask;
+#ifndef HB_NO_OT_KERN
   hb_mask_t kern_mask;
+#else
+  static constexpr hb_mask_t kern_mask = 0;
+#endif
+#ifndef HB_NO_AAT_SHAPE
   hb_mask_t trak_mask;
+#else
+  static constexpr hb_mask_t trak_mask = 0;
+#endif
 
+#ifndef HB_NO_OT_KERN
   bool requested_kerning : 1;
+#else
+  static constexpr bool requested_kerning = false;
+#endif
+#ifndef HB_NO_AAT_SHAPE
   bool requested_tracking : 1;
+#else
+  static constexpr bool requested_tracking = false;
+#endif
+#ifndef HB_NO_OT_SHAPE_FRACTIONS
   bool has_frac : 1;
+#else
+  static constexpr bool has_frac = false;
+#endif
   bool has_gpos_mark : 1;
   bool zero_marks : 1;
   bool fallback_glyph_classes : 1;
@@ -80,10 +106,20 @@ struct hb_ot_shape_plan_t
   bool adjust_mark_positioning_when_zeroing : 1;
 
   bool apply_gpos : 1;
-  bool apply_kerx : 1;
+#ifndef HB_NO_OT_KERN
   bool apply_kern : 1;
+#else
+  static constexpr bool apply_kern = false;
+#endif
+#ifndef HB_NO_AAT_SHAPE
+  bool apply_kerx : 1;
   bool apply_morx : 1;
   bool apply_trak : 1;
+#else
+  static constexpr bool apply_kerx = false;
+  static constexpr bool apply_morx = false;
+  static constexpr bool apply_trak = false;
+#endif
 
   void collect_lookups (hb_tag_t table_tag, hb_set_t *lookups) const
   {
@@ -113,7 +149,11 @@ struct hb_ot_shape_planner_t
   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
+  static constexpr bool apply_morx = false;
+#endif
   bool script_zero_marks : 1;
   bool script_fallback_mark_positioning : 1;
   const struct hb_ot_complex_shaper_t *shaper;
index 04a2ee9..2cdd3a4 100644 (file)
@@ -59,6 +59,8 @@ enum
 
 struct AxisValueFormat1
 {
+  hb_ot_name_id_t get_value_name_id () const { return valueNameID; }
+
   bool sanitize (hb_sanitize_context_t *c) const
   {
     TRACE_SANITIZE (this);
@@ -75,13 +77,15 @@ struct AxisValueFormat1
   NameID       valueNameID;    /* The name ID for entries in the 'name' table
                                 * that provide a display string for this
                                 * attribute value. */
-  Fixed                value;          /* A numeric value for this attribute value. */
+  HBFixed              value;          /* A numeric value for this attribute value. */
   public:
   DEFINE_SIZE_STATIC (12);
 };
 
 struct AxisValueFormat2
 {
+  hb_ot_name_id_t get_value_name_id () const { return valueNameID; }
+
   bool sanitize (hb_sanitize_context_t *c) const
   {
     TRACE_SANITIZE (this);
@@ -98,10 +102,10 @@ struct AxisValueFormat2
   NameID       valueNameID;    /* The name ID for entries in the 'name' table
                                 * that provide a display string for this
                                 * attribute value. */
-  Fixed                nominalValue;   /* A numeric value for this attribute value. */
-  Fixed                rangeMinValue;  /* The minimum value for a range associated
+  HBFixed              nominalValue;   /* A numeric value for this attribute value. */
+  HBFixed              rangeMinValue;  /* The minimum value for a range associated
                                 * with the specified name ID. */
-  Fixed                rangeMaxValue;  /* The maximum value for a range associated
+  HBFixed              rangeMaxValue;  /* The maximum value for a range associated
                                 * with the specified name ID. */
   public:
   DEFINE_SIZE_STATIC (20);
@@ -109,6 +113,8 @@ struct AxisValueFormat2
 
 struct AxisValueFormat3
 {
+  hb_ot_name_id_t get_value_name_id () const { return valueNameID; }
+
   bool sanitize (hb_sanitize_context_t *c) const
   {
     TRACE_SANITIZE (this);
@@ -125,8 +131,8 @@ struct AxisValueFormat3
   NameID       valueNameID;    /* The name ID for entries in the 'name' table
                                 * that provide a display string for this
                                 * attribute value. */
-  Fixed                value;          /* A numeric value for this attribute value. */
-  Fixed                linkedValue;    /* The numeric value for a style-linked mapping
+  HBFixed              value;          /* A numeric value for this attribute value. */
+  HBFixed              linkedValue;    /* The numeric value for a style-linked mapping
                                 * from this value. */
   public:
   DEFINE_SIZE_STATIC (16);
@@ -144,13 +150,15 @@ struct AxisValueRecord
   HBUINT16     axisIndex;      /* Zero-base index into the axis record array
                                 * identifying the axis to which this value
                                 * applies. Must be less than designAxisCount. */
-  Fixed                value;          /* A numeric value for this attribute value. */
+  HBFixed              value;          /* A numeric value for this attribute value. */
   public:
   DEFINE_SIZE_STATIC (6);
 };
 
 struct AxisValueFormat4
 {
+  hb_ot_name_id_t get_value_name_id () const { return valueNameID; }
+
   bool sanitize (hb_sanitize_context_t *c) const
   {
     TRACE_SANITIZE (this);
@@ -175,19 +183,31 @@ struct AxisValueFormat4
 
 struct AxisValue
 {
+  hb_ot_name_id_t get_value_name_id () const
+  {
+    switch (u.format)
+    {
+    case 1: return u.format1.get_value_name_id ();
+    case 2: return u.format2.get_value_name_id ();
+    case 3: return u.format3.get_value_name_id ();
+    case 4: return u.format4.get_value_name_id ();
+    default:return HB_OT_NAME_ID_INVALID;
+    }
+  }
+
   bool sanitize (hb_sanitize_context_t *c) const
   {
     TRACE_SANITIZE (this);
-    if (unlikely (c->check_struct (this)))
+    if (unlikely (!c->check_struct (this)))
       return_trace (false);
 
     switch (u.format)
     {
-    case 1:  return_trace (likely (u.format1.sanitize (c)));
-    case 2:  return_trace (likely (u.format2.sanitize (c)));
-    case 3:  return_trace (likely (u.format3.sanitize (c)));
-    case 4:  return_trace (likely (u.format4.sanitize (c)));
-    default: return_trace (true);
+    case 1: return_trace (u.format1.sanitize (c));
+    case 2: return_trace (u.format2.sanitize (c));
+    case 3: return_trace (u.format3.sanitize (c));
+    case 4: return_trace (u.format4.sanitize (c));
+    default:return_trace (true);
     }
   }
 
@@ -206,6 +226,8 @@ struct AxisValue
 
 struct StatAxisRecord
 {
+  hb_ot_name_id_t get_name_id () const { return nameID; }
+
   bool sanitize (hb_sanitize_context_t *c) const
   {
     TRACE_SANITIZE (this);
@@ -227,21 +249,63 @@ struct STAT
 {
   static constexpr hb_tag_t tableTag = HB_OT_TAG_STAT;
 
+  bool has_data () const { return version.to_int (); }
+
+  unsigned get_design_axis_count () const { return designAxisCount; }
+
+  hb_ot_name_id_t get_axis_record_name_id (unsigned axis_record_index) const
+  {
+    if (unlikely (axis_record_index >= designAxisCount)) return HB_OT_NAME_ID_INVALID;
+    const StatAxisRecord &axis_record = get_design_axes ()[axis_record_index];
+    return axis_record.get_name_id ();
+  }
+
+  unsigned get_axis_value_count () const { return axisValueCount; }
+
+  hb_ot_name_id_t get_axis_value_name_id (unsigned axis_value_index) const
+  {
+    if (unlikely (axis_value_index >= axisValueCount)) return HB_OT_NAME_ID_INVALID;
+    const AxisValue &axis_value = (this + get_axis_value_offsets ()[axis_value_index]);
+    return axis_value.get_value_name_id ();
+  }
+
+  void collect_name_ids (hb_set_t *nameids_to_retain) const
+  {
+    if (!has_data ()) return;
+
+    + get_design_axes ()
+    | hb_map (&StatAxisRecord::get_name_id)
+    | hb_sink (nameids_to_retain)
+    ;
+
+    + get_axis_value_offsets ()
+    | hb_map (hb_add (&(this + offsetToAxisValueOffsets)))
+    | hb_map (&AxisValue::get_value_name_id)
+    | hb_sink (nameids_to_retain)
+    ;
+  }
+
   bool sanitize (hb_sanitize_context_t *c) const
   {
     TRACE_SANITIZE (this);
     return_trace (likely (c->check_struct (this) &&
-                         majorVersion == 1 &&
-                         minorVersion > 0 &&
+                         version.major == 1 &&
+                         version.minor > 0 &&
                          designAxesOffset.sanitize (c, this, designAxisCount) &&
                          offsetToAxisValueOffsets.sanitize (c, this, axisValueCount, &(this+offsetToAxisValueOffsets))));
   }
 
   protected:
-  HBUINT16     majorVersion;   /* Major version number of the style attributes
-                                * table — set to 1. */
-  HBUINT16     minorVersion;   /* Minor version number of the style attributes
-                                * table — set to 2. */
+  hb_array_t<const StatAxisRecord> const get_design_axes () const
+  { return (this+designAxesOffset).as_array (designAxisCount); }
+
+  hb_array_t<const OffsetTo<AxisValue>> const get_axis_value_offsets () const
+  { return (this+offsetToAxisValueOffsets).as_array (axisValueCount); }
+
+
+  protected:
+  FixedVersion<>version;       /* Version of the stat table
+                                * initially set to 0x00010002u */
   HBUINT16     designAxisSize; /* The size in bytes of each axis record. */
   HBUINT16     designAxisCount;/* The number of design axis records. In a
                                 * font with an 'fvar' table, this value must be
@@ -249,7 +313,7 @@ struct STAT
                                 * in the 'fvar' table. In all fonts, must
                                 * be greater than zero if axisValueCount
                                 * is greater than zero. */
-  LNNOffsetTo<UnsizedArrayOf<StatAxisRecord> >
+  LNNOffsetTo<UnsizedArrayOf<StatAxisRecord>>
                designAxesOffset;
                                /* Offset in bytes from the beginning of
                                 * the STAT table to the start of the design
@@ -257,7 +321,7 @@ struct STAT
                                 * set to zero; if designAxisCount is greater
                                 * than zero, must be greater than zero. */
   HBUINT16     axisValueCount; /* The number of axis value tables. */
-  LNNOffsetTo<UnsizedArrayOf<OffsetTo<AxisValue> > >
+  LNNOffsetTo<UnsizedArrayOf<OffsetTo<AxisValue>>>
                offsetToAxisValueOffsets;
                                /* Offset in bytes from the beginning of
                                 * the STAT table to the start of the design
index 09e1627..d8fcd2f 100644 (file)
  * on files with these headers:
  *
  * <meta name="updated_at" content="2018-11-18 05:25 AM" />
- * File-Date: 2019-02-20
+ * File-Date: 2019-04-03
  */
 
 #ifndef HB_OT_TAG_TABLE_HH
 #define HB_OT_TAG_TABLE_HH
 
 static const LangTag ot_languages[] = {
-  {"aa",       {HB_TAG('A','F','R',' ')}},     /* Afar */
-  {"aae",      {HB_TAG('S','Q','I',' ')}},     /* Arbëreshë Albanian -> Albanian */
-  {"aao",      {HB_TAG('A','R','A',' ')}},     /* Algerian Saharan Arabic -> Arabic */
-  {"aat",      {HB_TAG('S','Q','I',' ')}},     /* Arvanitika Albanian -> Albanian */
-  {"ab",       {HB_TAG('A','B','K',' ')}},     /* Abkhazian */
-  {"abh",      {HB_TAG('A','R','A',' ')}},     /* Tajiki Arabic -> Arabic */
-  {"abq",      {HB_TAG('A','B','A',' ')}},     /* Abaza */
-  {"abv",      {HB_TAG('A','R','A',' ')}},     /* Baharna Arabic -> Arabic */
-  {"acf",      {HB_TAG('F','A','N',' ')}},     /* Saint Lucian Creole French -> French Antillean */
-  {"ach",      {HB_TAG('A','C','H',' ')}},     /* Acoli -> Acholi */
-  {"acm",      {HB_TAG('A','R','A',' ')}},     /* Mesopotamian Arabic -> Arabic */
-  {"acq",      {HB_TAG('A','R','A',' ')}},     /* Ta'izzi-Adeni Arabic -> Arabic */
-  {"acr",      {HB_TAG('A','C','R',' ')}},     /* Achi */
-  {"acw",      {HB_TAG('A','R','A',' ')}},     /* Hijazi Arabic -> Arabic */
-  {"acx",      {HB_TAG('A','R','A',' ')}},     /* Omani Arabic -> Arabic */
-  {"acy",      {HB_TAG('A','R','A',' ')}},     /* Cypriot Arabic -> Arabic */
-  {"ada",      {HB_TAG('D','N','G',' ')}},     /* Adangme -> Dangme */
-  {"adf",      {HB_TAG('A','R','A',' ')}},     /* Dhofari Arabic -> Arabic */
-  {"adp",      {HB_TAG('D','Z','N',' ')}},     /* Adap (retired code) -> Dzongkha */
-  {"ady",      {HB_TAG('A','D','Y',' ')}},     /* Adyghe */
-  {"aeb",      {HB_TAG('A','R','A',' ')}},     /* Tunisian Arabic -> Arabic */
-  {"aec",      {HB_TAG('A','R','A',' ')}},     /* Saidi Arabic -> Arabic */
-  {"af",       {HB_TAG('A','F','K',' ')}},     /* Afrikaans */
-  {"afb",      {HB_TAG('A','R','A',' ')}},     /* Gulf Arabic -> Arabic */
-  {"ahg",      {HB_TAG('A','G','W',' ')}},     /* Qimant -> Agaw */
-  {"aht",      {HB_TAG('A','T','H',' ')}},     /* Ahtena -> Athapaskan */
-  {"aii",      {HB_TAG('S','W','A',' '),       /* Assyrian Neo-Aramaic -> Swadaya Aramaic */
-                HB_TAG('S','Y','R',' ')}},     /* Assyrian Neo-Aramaic -> Syriac */
-  {"aio",      {HB_TAG('A','I','O',' ')}},     /* Aiton */
-  {"aiw",      {HB_TAG('A','R','I',' ')}},     /* Aari */
-  {"ajp",      {HB_TAG('A','R','A',' ')}},     /* South Levantine Arabic -> Arabic */
-  {"ak",       {HB_TAG('A','K','A',' '),       /* Akan [macrolanguage] */
-                HB_TAG('T','W','I',' ')}},     /* Akan [macrolanguage] -> Twi */
-  {"aln",      {HB_TAG('S','Q','I',' ')}},     /* Gheg Albanian -> Albanian */
-  {"als",      {HB_TAG('S','Q','I',' ')}},     /* Tosk Albanian -> Albanian */
-  {"alt",      {HB_TAG('A','L','T',' ')}},     /* Southern Altai -> Altai */
-  {"am",       {HB_TAG('A','M','H',' ')}},     /* Amharic */
-  {"amf",      {HB_TAG('H','B','N',' ')}},     /* Hamer-Banna -> Hammer-Banna */
-  {"amw",      {HB_TAG('S','Y','R',' ')}},     /* Western Neo-Aramaic -> Syriac */
-  {"an",       {HB_TAG('A','R','G',' ')}},     /* Aragonese */
-  {"ang",      {HB_TAG('A','N','G',' ')}},     /* Old English (ca. 450-1100) -> Anglo-Saxon */
-  {"apc",      {HB_TAG('A','R','A',' ')}},     /* North Levantine Arabic -> Arabic */
-  {"apd",      {HB_TAG('A','R','A',' ')}},     /* Sudanese Arabic -> Arabic */
-  {"apj",      {HB_TAG('A','T','H',' ')}},     /* Jicarilla Apache -> Athapaskan */
-  {"apk",      {HB_TAG('A','T','H',' ')}},     /* Kiowa Apache -> Athapaskan */
-  {"apl",      {HB_TAG('A','T','H',' ')}},     /* Lipan Apache -> Athapaskan */
-  {"apm",      {HB_TAG('A','T','H',' ')}},     /* Mescalero-Chiricahua Apache -> Athapaskan */
-  {"apw",      {HB_TAG('A','T','H',' ')}},     /* Western Apache -> Athapaskan */
-  {"ar",       {HB_TAG('A','R','A',' ')}},     /* Arabic [macrolanguage] */
-  {"arb",      {HB_TAG('A','R','A',' ')}},     /* Standard Arabic -> Arabic */
-  {"arn",      {HB_TAG('M','A','P',' ')}},     /* Mapudungun */
-  {"arq",      {HB_TAG('A','R','A',' ')}},     /* Algerian Arabic -> Arabic */
-  {"ars",      {HB_TAG('A','R','A',' ')}},     /* Najdi Arabic -> Arabic */
-  {"ary",      {HB_TAG('M','O','R',' ')}},     /* Moroccan Arabic -> Moroccan */
-  {"arz",      {HB_TAG('A','R','A',' ')}},     /* Egyptian Arabic -> Arabic */
-  {"as",       {HB_TAG('A','S','M',' ')}},     /* Assamese */
-  {"ast",      {HB_TAG('A','S','T',' ')}},     /* Asturian */
-  {"ath",      {HB_TAG('A','T','H',' ')}},     /* Athapascan [family] -> Athapaskan */
-  {"atj",      {HB_TAG('R','C','R',' ')}},     /* Atikamekw -> R-Cree */
-  {"atv",      {HB_TAG('A','L','T',' ')}},     /* Northern Altai -> Altai */
-  {"auz",      {HB_TAG('A','R','A',' ')}},     /* Uzbeki Arabic -> Arabic */
-  {"av",       {HB_TAG('A','V','R',' ')}},     /* Avaric -> Avar */
-  {"avl",      {HB_TAG('A','R','A',' ')}},     /* Eastern Egyptian Bedawi Arabic -> Arabic */
-  {"awa",      {HB_TAG('A','W','A',' ')}},     /* Awadhi */
-  {"ay",       {HB_TAG('A','Y','M',' ')}},     /* Aymara [macrolanguage] */
-  {"ayc",      {HB_TAG('A','Y','M',' ')}},     /* Southern Aymara -> Aymara */
-  {"ayh",      {HB_TAG('A','R','A',' ')}},     /* Hadrami Arabic -> Arabic */
-  {"ayl",      {HB_TAG('A','R','A',' ')}},     /* Libyan Arabic -> Arabic */
-  {"ayn",      {HB_TAG('A','R','A',' ')}},     /* Sanaani Arabic -> Arabic */
-  {"ayp",      {HB_TAG('A','R','A',' ')}},     /* North Mesopotamian Arabic -> Arabic */
-  {"ayr",      {HB_TAG('A','Y','M',' ')}},     /* Central Aymara -> Aymara */
-  {"az",       {HB_TAG('A','Z','E',' ')}},     /* Azerbaijani [macrolanguage] */
-  {"azb",      {HB_TAG('A','Z','B',' ')}},     /* South Azerbaijani -> Torki */
-  {"azj",      {HB_TAG('A','Z','E',' ')}},     /* North Azerbaijani -> Azerbaijani */
-  {"ba",       {HB_TAG('B','S','H',' ')}},     /* Bashkir */
-  {"bad",      {HB_TAG('B','A','D','0')}},     /* Banda [family] */
-  {"bai",      {HB_TAG('B','M','L',' ')}},     /* Bamileke [family] */
-  {"bal",      {HB_TAG('B','L','I',' ')}},     /* Baluchi [macrolanguage] */
-  {"ban",      {HB_TAG('B','A','N',' ')}},     /* Balinese */
-  {"bar",      {HB_TAG('B','A','R',' ')}},     /* Bavarian */
-  {"bbc",      {HB_TAG('B','B','C',' ')}},     /* Batak Toba */
-  {"bbz",      {HB_TAG('A','R','A',' ')}},     /* Babalia Creole Arabic -> Arabic */
-  {"bcc",      {HB_TAG('B','L','I',' ')}},     /* Southern Balochi -> Baluchi */
-  {"bci",      {HB_TAG('B','A','U',' ')}},     /* Baoulé -> Baulé */
-  {"bcl",      {HB_TAG('B','I','K',' ')}},     /* Central Bikol -> Bikol */
-  {"bcq",      {HB_TAG('B','C','H',' ')}},     /* Bench */
-  {"bcr",      {HB_TAG('A','T','H',' ')}},     /* Babine -> Athapaskan */
-  {"bdy",      {HB_TAG('B','D','Y',' ')}},     /* Bandjalang */
-  {"be",       {HB_TAG('B','E','L',' ')}},     /* Belarusian -> Belarussian */
-  {"bea",      {HB_TAG('A','T','H',' ')}},     /* Beaver -> Athapaskan */
-  {"beb",      {HB_TAG('B','T','I',' ')}},     /* Bebele -> Beti */
-  {"bem",      {HB_TAG('B','E','M',' ')}},     /* Bemba (Zambia) */
-  {"ber",      {HB_TAG('B','B','R',' ')}},     /* Berber [family] */
-  {"bfq",      {HB_TAG('B','A','D',' ')}},     /* Badaga */
-  {"bft",      {HB_TAG('B','L','T',' ')}},     /* Balti */
-  {"bfu",      {HB_TAG('L','A','H',' ')}},     /* Gahri -> Lahuli */
-  {"bfy",      {HB_TAG('B','A','G',' ')}},     /* Bagheli -> Baghelkhandi */
-  {"bg",       {HB_TAG('B','G','R',' ')}},     /* Bulgarian */
-  {"bgc",      {HB_TAG('B','G','C',' ')}},     /* Haryanvi */
-  {"bgn",      {HB_TAG('B','L','I',' ')}},     /* Western Balochi -> Baluchi */
-  {"bgp",      {HB_TAG('B','L','I',' ')}},     /* Eastern Balochi -> Baluchi */
-  {"bgq",      {HB_TAG('B','G','Q',' ')}},     /* Bagri */
-  {"bgr",      {HB_TAG('Q','I','N',' ')}},     /* Bawm Chin -> Chin */
-  {"bhb",      {HB_TAG('B','H','I',' ')}},     /* Bhili */
-  {"bhi",      {HB_TAG('B','H','I',' ')}},     /* Bhilali -> Bhili */
-  {"bhk",      {HB_TAG('B','I','K',' ')}},     /* Albay Bicolano (retired code) -> Bikol */
-  {"bho",      {HB_TAG('B','H','O',' ')}},     /* Bhojpuri */
-  {"bhr",      {HB_TAG('M','L','G',' ')}},     /* Bara Malagasy -> Malagasy */
-  {"bi",       {HB_TAG('B','I','S',' ')}},     /* Bislama */
-  {"bik",      {HB_TAG('B','I','K',' ')}},     /* Bikol [macrolanguage] */
-  {"bin",      {HB_TAG('E','D','O',' ')}},     /* Edo */
-  {"bjj",      {HB_TAG('B','J','J',' ')}},     /* Kanauji */
-  {"bjn",      {HB_TAG('M','L','Y',' ')}},     /* Banjar -> Malay */
-  {"bjq",      {HB_TAG('M','L','G',' ')}},     /* Southern Betsimisaraka Malagasy (retired code) -> Malagasy */
-  {"bjt",      {HB_TAG('B','L','N',' ')}},     /* Balanta-Ganja -> Balante */
-  {"bla",      {HB_TAG('B','K','F',' ')}},     /* Siksika -> Blackfoot */
-  {"ble",      {HB_TAG('B','L','N',' ')}},     /* Balanta-Kentohe -> Balante */
-  {"blk",      {HB_TAG('B','L','K',' ')}},     /* Pa’o Karen */
-  {"bln",      {HB_TAG('B','I','K',' ')}},     /* Southern Catanduanes Bikol -> Bikol */
-  {"bm",       {HB_TAG('B','M','B',' ')}},     /* Bambara (Bamanankan) */
-  {"bmm",      {HB_TAG('M','L','G',' ')}},     /* Northern Betsimisaraka Malagasy -> Malagasy */
-  {"bn",       {HB_TAG('B','E','N',' ')}},     /* Bengali */
-  {"bo",       {HB_TAG('T','I','B',' ')}},     /* Tibetan */
-  {"bpy",      {HB_TAG('B','P','Y',' ')}},     /* Bishnupriya -> Bishnupriya Manipuri */
-  {"bqi",      {HB_TAG('L','R','C',' ')}},     /* Bakhtiari -> Luri */
-  {"br",       {HB_TAG('B','R','E',' ')}},     /* Breton */
-  {"bra",      {HB_TAG('B','R','I',' ')}},     /* Braj -> Braj Bhasha */
-  {"brh",      {HB_TAG('B','R','H',' ')}},     /* Brahui */
-  {"brx",      {HB_TAG('B','R','X',' ')}},     /* Bodo (India) */
-  {"bs",       {HB_TAG('B','O','S',' ')}},     /* Bosnian */
-  {"bsk",      {HB_TAG('B','S','K',' ')}},     /* Burushaski */
-  {"btb",      {HB_TAG('B','T','I',' ')}},     /* Beti (Cameroon) (retired code) */
-  {"btj",      {HB_TAG('M','L','Y',' ')}},     /* Bacanese Malay -> Malay */
-  {"bto",      {HB_TAG('B','I','K',' ')}},     /* Rinconada Bikol -> Bikol */
-  {"bts",      {HB_TAG('B','T','S',' ')}},     /* Batak Simalungun */
-  {"bug",      {HB_TAG('B','U','G',' ')}},     /* Buginese -> Bugis */
-  {"bum",      {HB_TAG('B','T','I',' ')}},     /* Bulu (Cameroon) -> Beti */
-  {"bve",      {HB_TAG('M','L','Y',' ')}},     /* Berau Malay -> Malay */
-  {"bvu",      {HB_TAG('M','L','Y',' ')}},     /* Bukit Malay -> Malay */
-  {"bxk",      {HB_TAG('L','U','H',' ')}},     /* Bukusu -> Luyia */
-  {"bxp",      {HB_TAG('B','T','I',' ')}},     /* Bebil -> Beti */
-  {"bxr",      {HB_TAG('R','B','U',' ')}},     /* Russia Buriat -> Russian Buriat */
-  {"byn",      {HB_TAG('B','I','L',' ')}},     /* Bilin -> Bilen */
-  {"byv",      {HB_TAG('B','Y','V',' ')}},     /* Medumba */
-  {"bzc",      {HB_TAG('M','L','G',' ')}},     /* Southern Betsimisaraka Malagasy -> Malagasy */
-  {"ca",       {HB_TAG('C','A','T',' ')}},     /* Catalan */
-  {"caf",      {HB_TAG('C','R','R',' '),       /* Southern Carrier -> Carrier */
-                HB_TAG('A','T','H',' ')}},     /* Southern Carrier -> Athapaskan */
-  {"cak",      {HB_TAG('C','A','K',' ')}},     /* Kaqchikel */
-  {"cbk",      {HB_TAG('C','B','K',' ')}},     /* Chavacano -> Zamboanga Chavacano */
-  {"cbl",      {HB_TAG('Q','I','N',' ')}},     /* Bualkhaw Chin -> Chin */
-  {"cco",      {HB_TAG('C','C','H','N')}},     /* Comaltepec Chinantec -> Chinantec */
-  {"ccq",      {HB_TAG('A','R','K',' ')}},     /* Chaungtha (retired code) -> Rakhine */
-  {"cdo",      {HB_TAG('Z','H','S',' ')}},     /* Min Dong Chinese -> Chinese Simplified */
-  {"ce",       {HB_TAG('C','H','E',' ')}},     /* Chechen */
-  {"ceb",      {HB_TAG('C','E','B',' ')}},     /* Cebuano */
-  {"cfm",      {HB_TAG('H','A','L',' ')}},     /* Halam (Falam Chin) */
-  {"cgg",      {HB_TAG('C','G','G',' ')}},     /* Chiga */
-  {"ch",       {HB_TAG('C','H','A',' ')}},     /* Chamorro */
-  {"chj",      {HB_TAG('C','C','H','N')}},     /* Ojitlán Chinantec -> Chinantec */
-  {"chk",      {HB_TAG('C','H','K','0')}},     /* Chuukese */
-  {"cho",      {HB_TAG('C','H','O',' ')}},     /* Choctaw */
-  {"chp",      {HB_TAG('C','H','P',' '),       /* Chipewyan */
-                HB_TAG('S','A','Y',' '),       /* Chipewyan -> Sayisi */
-                HB_TAG('A','T','H',' ')}},     /* Chipewyan -> Athapaskan */
-  {"chq",      {HB_TAG('C','C','H','N')}},     /* Quiotepec Chinantec -> Chinantec */
-  {"chr",      {HB_TAG('C','H','R',' ')}},     /* Cherokee */
-  {"chy",      {HB_TAG('C','H','Y',' ')}},     /* Cheyenne */
-  {"chz",      {HB_TAG('C','C','H','N')}},     /* Ozumacín Chinantec -> Chinantec */
-  {"ciw",      {HB_TAG('O','J','B',' ')}},     /* Chippewa -> Ojibway */
-  {"cja",      {HB_TAG('C','J','A',' ')}},     /* Western Cham */
-  {"cjm",      {HB_TAG('C','J','M',' ')}},     /* Eastern Cham */
-  {"cjy",      {HB_TAG('Z','H','S',' ')}},     /* Jinyu Chinese -> Chinese Simplified */
-  {"cka",      {HB_TAG('Q','I','N',' ')}},     /* Khumi Awa Chin (retired code) -> Chin */
-  {"ckb",      {HB_TAG('K','U','R',' ')}},     /* Central Kurdish -> Kurdish */
-  {"ckt",      {HB_TAG('C','H','K',' ')}},     /* Chukot -> Chukchi */
-  {"clc",      {HB_TAG('A','T','H',' ')}},     /* Chilcotin -> Athapaskan */
-  {"cld",      {HB_TAG('S','Y','R',' ')}},     /* Chaldean Neo-Aramaic -> Syriac */
-  {"cle",      {HB_TAG('C','C','H','N')}},     /* Lealao Chinantec -> Chinantec */
-  {"cmn",      {HB_TAG('Z','H','S',' ')}},     /* Mandarin Chinese -> Chinese Simplified */
-  {"cmr",      {HB_TAG('Q','I','N',' ')}},     /* Mro-Khimi Chin -> Chin */
-  {"cnb",      {HB_TAG('Q','I','N',' ')}},     /* Chinbon Chin -> Chin */
-  {"cnh",      {HB_TAG('Q','I','N',' ')}},     /* Hakha Chin -> Chin */
-  {"cnk",      {HB_TAG('Q','I','N',' ')}},     /* Khumi Chin -> Chin */
-  {"cnl",      {HB_TAG('C','C','H','N')}},     /* Lalana Chinantec -> Chinantec */
-  {"cnt",      {HB_TAG('C','C','H','N')}},     /* Tepetotutla Chinantec -> Chinantec */
-  {"cnw",      {HB_TAG('Q','I','N',' ')}},     /* Ngawn Chin -> Chin */
-  {"co",       {HB_TAG('C','O','S',' ')}},     /* Corsican */
-  {"coa",      {HB_TAG('M','L','Y',' ')}},     /* Cocos Islands Malay -> Malay */
-  {"cop",      {HB_TAG('C','O','P',' ')}},     /* Coptic */
-  {"coq",      {HB_TAG('A','T','H',' ')}},     /* Coquille -> Athapaskan */
-  {"cpa",      {HB_TAG('C','C','H','N')}},     /* Palantla Chinantec -> Chinantec */
-  {"cpe",      {HB_TAG('C','P','P',' ')}},     /* English-based creoles and pidgins [family] -> Creoles */
-  {"cpf",      {HB_TAG('C','P','P',' ')}},     /* French-based creoles and pidgins [family] -> Creoles */
-  {"cpp",      {HB_TAG('C','P','P',' ')}},     /* Portuguese-based creoles and pidgins [family] -> Creoles */
-  {"cpx",      {HB_TAG('Z','H','S',' ')}},     /* Pu-Xian Chinese -> Chinese Simplified */
-  {"cqd",      {HB_TAG('H','M','N',' ')}},     /* Chuanqiandian Cluster Miao -> Hmong */
-  {"cqu",      {HB_TAG('Q','U','H',' ')}},     /* Chilean Quechua (retired code) -> Quechua (Bolivia) */
-  {"cr",       {HB_TAG('C','R','E',' '),       /* Cree [macrolanguage] */
-                HB_TAG('Y','C','R',' ')}},     /* Cree [macrolanguage] -> Y-Cree */
-  {"crh",      {HB_TAG('C','R','T',' ')}},     /* Crimean Tatar */
-  {"crj",      {HB_TAG('E','C','R',' ')}},     /* Southern East Cree -> Eastern Cree */
-  {"crk",      {HB_TAG('W','C','R',' ')}},     /* Plains Cree -> West-Cree */
-  {"crl",      {HB_TAG('E','C','R',' ')}},     /* Northern East Cree -> Eastern Cree */
-  {"crm",      {HB_TAG('M','C','R',' '),       /* Moose Cree */
-                HB_TAG('L','C','R',' ')}},     /* Moose Cree -> L-Cree */
-  {"crp",      {HB_TAG('C','P','P',' ')}},     /* Creoles and pidgins [family] -> Creoles */
-  {"crx",      {HB_TAG('C','R','R',' '),       /* Carrier */
-                HB_TAG('A','T','H',' ')}},     /* Carrier -> Athapaskan */
-  {"cs",       {HB_TAG('C','S','Y',' ')}},     /* Czech */
-  {"csa",      {HB_TAG('C','C','H','N')}},     /* Chiltepec Chinantec -> Chinantec */
-  {"csb",      {HB_TAG('C','S','B',' ')}},     /* Kashubian */
-  {"csh",      {HB_TAG('Q','I','N',' ')}},     /* Asho Chin -> Chin */
-  {"cso",      {HB_TAG('C','C','H','N')}},     /* Sochiapam Chinantec -> Chinantec */
-  {"csw",      {HB_TAG('N','C','R',' '),       /* Swampy Cree -> N-Cree */
-                HB_TAG('N','H','C',' ')}},     /* Swampy Cree -> Norway House Cree */
-  {"csy",      {HB_TAG('Q','I','N',' ')}},     /* Siyin Chin -> Chin */
-  {"ctc",      {HB_TAG('A','T','H',' ')}},     /* Chetco -> Athapaskan */
-  {"ctd",      {HB_TAG('Q','I','N',' ')}},     /* Tedim Chin -> Chin */
-  {"cte",      {HB_TAG('C','C','H','N')}},     /* Tepinapa Chinantec -> Chinantec */
-  {"ctg",      {HB_TAG('C','T','G',' ')}},     /* Chittagonian */
-  {"ctl",      {HB_TAG('C','C','H','N')}},     /* Tlacoatzintepec Chinantec -> Chinantec */
-  {"cts",      {HB_TAG('B','I','K',' ')}},     /* Northern Catanduanes Bikol -> Bikol */
-  {"cu",       {HB_TAG('C','S','L',' ')}},     /* Church Slavonic */
-  {"cuc",      {HB_TAG('C','C','H','N')}},     /* Usila Chinantec -> Chinantec */
-  {"cuk",      {HB_TAG('C','U','K',' ')}},     /* San Blas Kuna */
-  {"cv",       {HB_TAG('C','H','U',' ')}},     /* Chuvash */
-  {"cvn",      {HB_TAG('C','C','H','N')}},     /* Valle Nacional Chinantec -> Chinantec */
-  {"cwd",      {HB_TAG('D','C','R',' '),       /* Woods Cree */
-                HB_TAG('T','C','R',' ')}},     /* Woods Cree -> TH-Cree */
-  {"cy",       {HB_TAG('W','E','L',' ')}},     /* Welsh */
-  {"czh",      {HB_TAG('Z','H','S',' ')}},     /* Huizhou Chinese -> Chinese Simplified */
-  {"czo",      {HB_TAG('Z','H','S',' ')}},     /* Min Zhong Chinese -> Chinese Simplified */
-  {"czt",      {HB_TAG('Q','I','N',' ')}},     /* Zotung Chin -> Chin */
-  {"da",       {HB_TAG('D','A','N',' ')}},     /* Danish */
-  {"dao",      {HB_TAG('Q','I','N',' ')}},     /* Daai Chin -> Chin */
-  {"dap",      {HB_TAG('N','I','S',' ')}},     /* Nisi (India) (retired code) */
-  {"dar",      {HB_TAG('D','A','R',' ')}},     /* Dargwa */
-  {"dax",      {HB_TAG('D','A','X',' ')}},     /* Dayi */
-  {"de",       {HB_TAG('D','E','U',' ')}},     /* German */
-  {"den",      {HB_TAG('S','L','A',' '),       /* Slave (Athapascan) [macrolanguage] -> Slavey */
-                HB_TAG('A','T','H',' ')}},     /* Slave (Athapascan) [macrolanguage] -> Athapaskan */
-  {"dgo",      {HB_TAG('D','G','O',' ')}},     /* Dogri */
-  {"dgr",      {HB_TAG('A','T','H',' ')}},     /* Dogrib -> Athapaskan */
-  {"dhd",      {HB_TAG('M','A','W',' ')}},     /* Dhundari -> Marwari */
-  {"dhg",      {HB_TAG('D','H','G',' ')}},     /* Dhangu */
-  {"dib",      {HB_TAG('D','N','K',' ')}},     /* South Central Dinka -> Dinka */
-  {"dik",      {HB_TAG('D','N','K',' ')}},     /* Southwestern Dinka -> Dinka */
-  {"din",      {HB_TAG('D','N','K',' ')}},     /* Dinka [macrolanguage] */
-  {"dip",      {HB_TAG('D','N','K',' ')}},     /* Northeastern Dinka -> Dinka */
-  {"diq",      {HB_TAG('D','I','Q',' ')}},     /* Dimli */
-  {"diw",      {HB_TAG('D','N','K',' ')}},     /* Northwestern Dinka -> Dinka */
-  {"dje",      {HB_TAG('D','J','R',' ')}},     /* Zarma */
-  {"djr",      {HB_TAG('D','J','R','0')}},     /* Djambarrpuyngu */
-  {"dks",      {HB_TAG('D','N','K',' ')}},     /* Southeastern Dinka -> Dinka */
-  {"dng",      {HB_TAG('D','U','N',' ')}},     /* Dungan */
-  {"dnj",      {HB_TAG('D','N','J',' ')}},     /* Dan */
-  {"doi",      {HB_TAG('D','G','R',' ')}},     /* Dogri [macrolanguage] */
-  {"drh",      {HB_TAG('M','N','G',' ')}},     /* Darkhat (retired code) -> Mongolian */
-  {"drw",      {HB_TAG('D','R','I',' ')}},     /* Darwazi (retired code) -> Dari */
-  {"dsb",      {HB_TAG('L','S','B',' ')}},     /* Lower Sorbian */
-  {"dty",      {HB_TAG('N','E','P',' ')}},     /* Dotyali -> Nepali */
-  {"duj",      {HB_TAG('D','U','J',' ')}},     /* Dhuwal (retired code) */
-  {"dup",      {HB_TAG('M','L','Y',' ')}},     /* Duano -> Malay */
-  {"dv",       {HB_TAG('D','I','V',' '),       /* Divehi (Dhivehi, Maldivian) */
-                HB_TAG('D','H','V',' ')}},     /* Divehi (Dhivehi, Maldivian) (deprecated) */
-  {"dwu",      {HB_TAG('D','U','J',' ')}},     /* Dhuwal */
-  {"dwy",      {HB_TAG('D','U','J',' ')}},     /* Dhuwaya -> Dhuwal */
-  {"dyu",      {HB_TAG('J','U','L',' ')}},     /* Dyula -> Jula */
-  {"dz",       {HB_TAG('D','Z','N',' ')}},     /* Dzongkha */
-  {"ee",       {HB_TAG('E','W','E',' ')}},     /* Ewe */
-  {"efi",      {HB_TAG('E','F','I',' ')}},     /* Efik */
-  {"ekk",      {HB_TAG('E','T','I',' ')}},     /* Standard Estonian -> Estonian */
-  {"el",       {HB_TAG('E','L','L',' ')}},     /* Modern Greek (1453-) -> Greek */
-  {"emk",      {HB_TAG('E','M','K',' '),       /* Eastern Maninkakan */
-                HB_TAG('M','N','K',' ')}},     /* Eastern Maninkakan -> Maninka */
-  {"en",       {HB_TAG('E','N','G',' ')}},     /* English */
-  {"enb",      {HB_TAG('K','A','L',' ')}},     /* Markweeta -> Kalenjin */
-  {"enf",      {HB_TAG('F','N','E',' ')}},     /* Forest Enets -> Forest Nenets */
-  {"enh",      {HB_TAG('T','N','E',' ')}},     /* Tundra Enets -> Tundra Nenets */
-  {"eo",       {HB_TAG('N','T','O',' ')}},     /* Esperanto */
-  {"es",       {HB_TAG('E','S','P',' ')}},     /* Spanish */
-  {"esg",      {HB_TAG('G','O','N',' ')}},     /* Aheri Gondi -> Gondi */
-  {"esi",      {HB_TAG('I','P','K',' ')}},     /* North Alaskan Inupiatun -> Inupiat */
-  {"esk",      {HB_TAG('I','P','K',' ')}},     /* Northwest Alaska Inupiatun -> Inupiat */
-  {"esu",      {HB_TAG('E','S','U',' ')}},     /* Central Yupik */
-  {"et",       {HB_TAG('E','T','I',' ')}},     /* Estonian [macrolanguage] */
-  {"eto",      {HB_TAG('B','T','I',' ')}},     /* Eton (Cameroon) -> Beti */
-  {"eu",       {HB_TAG('E','U','Q',' ')}},     /* Basque */
-  {"eve",      {HB_TAG('E','V','N',' ')}},     /* Even */
-  {"evn",      {HB_TAG('E','V','K',' ')}},     /* Evenki */
-  {"ewo",      {HB_TAG('B','T','I',' ')}},     /* Ewondo -> Beti */
-  {"eyo",      {HB_TAG('K','A','L',' ')}},     /* Keiyo -> Kalenjin */
-  {"fa",       {HB_TAG('F','A','R',' ')}},     /* Persian [macrolanguage] */
-  {"fan",      {HB_TAG('F','A','N','0')}},     /* Fang (Equatorial Guinea) */
-  {"fat",      {HB_TAG('F','A','T',' ')}},     /* Fanti */
-  {"fbl",      {HB_TAG('B','I','K',' ')}},     /* West Albay Bikol -> Bikol */
-  {"ff",       {HB_TAG('F','U','L',' ')}},     /* Fulah [macrolanguage] */
-  {"ffm",      {HB_TAG('F','U','L',' ')}},     /* Maasina Fulfulde -> Fulah */
-  {"fi",       {HB_TAG('F','I','N',' ')}},     /* Finnish */
-  {"fil",      {HB_TAG('P','I','L',' ')}},     /* Filipino */
-  {"fj",       {HB_TAG('F','J','I',' ')}},     /* Fijian */
-  {"flm",      {HB_TAG('H','A','L',' '),       /* Halam (Falam Chin) (retired code) */
-                HB_TAG('Q','I','N',' ')}},     /* Falam Chin (retired code) -> Chin */
-  {"fmp",      {HB_TAG('F','M','P',' ')}},     /* Fe’fe’ */
-  {"fo",       {HB_TAG('F','O','S',' ')}},     /* Faroese */
-  {"fon",      {HB_TAG('F','O','N',' ')}},     /* Fon */
-  {"fr",       {HB_TAG('F','R','A',' ')}},     /* French */
-  {"frc",      {HB_TAG('F','R','C',' ')}},     /* Cajun French */
-  {"frp",      {HB_TAG('F','R','P',' ')}},     /* Arpitan */
-  {"fub",      {HB_TAG('F','U','L',' ')}},     /* Adamawa Fulfulde -> Fulah */
-  {"fuc",      {HB_TAG('F','U','L',' ')}},     /* Pulaar -> Fulah */
-  {"fue",      {HB_TAG('F','U','L',' ')}},     /* Borgu Fulfulde -> Fulah */
-  {"fuf",      {HB_TAG('F','T','A',' ')}},     /* Pular -> Futa */
-  {"fuh",      {HB_TAG('F','U','L',' ')}},     /* Western Niger Fulfulde -> Fulah */
-  {"fui",      {HB_TAG('F','U','L',' ')}},     /* Bagirmi Fulfulde -> Fulah */
-  {"fuq",      {HB_TAG('F','U','L',' ')}},     /* Central-Eastern Niger Fulfulde -> Fulah */
-  {"fur",      {HB_TAG('F','R','L',' ')}},     /* Friulian */
-  {"fuv",      {HB_TAG('F','U','V',' ')}},     /* Nigerian Fulfulde */
-  {"fy",       {HB_TAG('F','R','I',' ')}},     /* Western Frisian -> Frisian */
-  {"ga",       {HB_TAG('I','R','I',' ')}},     /* Irish */
-  {"gaa",      {HB_TAG('G','A','D',' ')}},     /* Ga */
-  {"gag",      {HB_TAG('G','A','G',' ')}},     /* Gagauz */
-  {"gan",      {HB_TAG('Z','H','S',' ')}},     /* Gan Chinese -> Chinese Simplified */
-  {"gax",      {HB_TAG('O','R','O',' ')}},     /* Borana-Arsi-Guji Oromo -> Oromo */
-  {"gaz",      {HB_TAG('O','R','O',' ')}},     /* West Central Oromo -> Oromo */
-  {"gbm",      {HB_TAG('G','A','W',' ')}},     /* Garhwali */
-  {"gce",      {HB_TAG('A','T','H',' ')}},     /* Galice -> Athapaskan */
-  {"gd",       {HB_TAG('G','A','E',' ')}},     /* Scottish Gaelic (Gaelic) */
-  {"gda",      {HB_TAG('R','A','J',' ')}},     /* Gade Lohar -> Rajasthani */
-  {"gez",      {HB_TAG('G','E','Z',' ')}},     /* Geez */
-  {"ggo",      {HB_TAG('G','O','N',' ')}},     /* Southern Gondi (retired code) -> Gondi */
-  {"gih",      {HB_TAG('G','I','H',' ')}},     /* Githabul */
-  {"gil",      {HB_TAG('G','I','L','0')}},     /* Kiribati (Gilbertese) */
-  {"gju",      {HB_TAG('R','A','J',' ')}},     /* Gujari -> Rajasthani */
-  {"gkp",      {HB_TAG('G','K','P',' ')}},     /* Guinea Kpelle -> Kpelle (Guinea) */
-  {"gl",       {HB_TAG('G','A','L',' ')}},     /* Galician */
-  {"gld",      {HB_TAG('N','A','N',' ')}},     /* Nanai */
-  {"glk",      {HB_TAG('G','L','K',' ')}},     /* Gilaki */
-  {"gn",       {HB_TAG('G','U','A',' ')}},     /* Guarani [macrolanguage] */
-  {"gnn",      {HB_TAG('G','N','N',' ')}},     /* Gumatj */
-  {"gno",      {HB_TAG('G','O','N',' ')}},     /* Northern Gondi -> Gondi */
-  {"gnw",      {HB_TAG('G','U','A',' ')}},     /* Western Bolivian Guaraní -> Guarani */
-  {"gog",      {HB_TAG('G','O','G',' ')}},     /* Gogo */
-  {"gom",      {HB_TAG('K','O','K',' ')}},     /* Goan Konkani -> Konkani */
-  {"gon",      {HB_TAG('G','O','N',' ')}},     /* Gondi [macrolanguage] */
-  {"grt",      {HB_TAG('G','R','O',' ')}},     /* Garo */
-  {"gru",      {HB_TAG('S','O','G',' ')}},     /* Kistane -> Sodo Gurage */
-  {"gsw",      {HB_TAG('A','L','S',' ')}},     /* Alsatian */
-  {"gu",       {HB_TAG('G','U','J',' ')}},     /* Gujarati */
-  {"guc",      {HB_TAG('G','U','C',' ')}},     /* Wayuu */
-  {"guf",      {HB_TAG('G','U','F',' ')}},     /* Gupapuyngu */
-  {"gug",      {HB_TAG('G','U','A',' ')}},     /* Paraguayan Guaraní -> Guarani */
-  {"gui",      {HB_TAG('G','U','A',' ')}},     /* Eastern Bolivian Guaraní -> Guarani */
-  {"guk",      {HB_TAG('G','M','Z',' '),       /* Gumuz */
-                HB_TAG('G','U','K',' ')}},     /* Gumuz (SIL fonts) */
-  {"gun",      {HB_TAG('G','U','A',' ')}},     /* Mbyá Guaraní -> Guarani */
-  {"guz",      {HB_TAG('G','U','Z',' ')}},     /* Gusii */
-  {"gv",       {HB_TAG('M','N','X',' ')}},     /* Manx */
-  {"gwi",      {HB_TAG('A','T','H',' ')}},     /* Gwichʼin -> Athapaskan */
-  {"ha",       {HB_TAG('H','A','U',' ')}},     /* Hausa */
-  {"haa",      {HB_TAG('A','T','H',' ')}},     /* Han -> Athapaskan */
-  {"hae",      {HB_TAG('O','R','O',' ')}},     /* Eastern Oromo -> Oromo */
-  {"hak",      {HB_TAG('Z','H','S',' ')}},     /* Hakka Chinese -> Chinese Simplified */
-  {"har",      {HB_TAG('H','R','I',' ')}},     /* Harari */
-  {"haw",      {HB_TAG('H','A','W',' ')}},     /* Hawaiian */
-  {"hay",      {HB_TAG('H','A','Y',' ')}},     /* Haya */
-  {"haz",      {HB_TAG('H','A','Z',' ')}},     /* Hazaragi */
-  {"he",       {HB_TAG('I','W','R',' ')}},     /* Hebrew */
-  {"hea",      {HB_TAG('H','M','N',' ')}},     /* Northern Qiandong Miao -> Hmong */
-  {"hi",       {HB_TAG('H','I','N',' ')}},     /* Hindi */
-  {"hil",      {HB_TAG('H','I','L',' ')}},     /* Hiligaynon */
-  {"hji",      {HB_TAG('M','L','Y',' ')}},     /* Haji -> Malay */
-  {"hlt",      {HB_TAG('Q','I','N',' ')}},     /* Matu Chin -> Chin */
-  {"hma",      {HB_TAG('H','M','N',' ')}},     /* Southern Mashan Hmong -> Hmong */
-  {"hmc",      {HB_TAG('H','M','N',' ')}},     /* Central Huishui Hmong -> Hmong */
-  {"hmd",      {HB_TAG('H','M','N',' ')}},     /* Large Flowery Miao -> Hmong */
-  {"hme",      {HB_TAG('H','M','N',' ')}},     /* Eastern Huishui Hmong -> Hmong */
-  {"hmg",      {HB_TAG('H','M','N',' ')}},     /* Southwestern Guiyang Hmong -> Hmong */
-  {"hmh",      {HB_TAG('H','M','N',' ')}},     /* Southwestern Huishui Hmong -> Hmong */
-  {"hmi",      {HB_TAG('H','M','N',' ')}},     /* Northern Huishui Hmong -> Hmong */
-  {"hmj",      {HB_TAG('H','M','N',' ')}},     /* Ge -> Hmong */
-  {"hml",      {HB_TAG('H','M','N',' ')}},     /* Luopohe Hmong -> Hmong */
-  {"hmm",      {HB_TAG('H','M','N',' ')}},     /* Central Mashan Hmong -> Hmong */
-  {"hmn",      {HB_TAG('H','M','N',' ')}},     /* Hmong [macrolanguage] */
-  {"hmp",      {HB_TAG('H','M','N',' ')}},     /* Northern Mashan Hmong -> Hmong */
-  {"hmq",      {HB_TAG('H','M','N',' ')}},     /* Eastern Qiandong Miao -> Hmong */
-  {"hms",      {HB_TAG('H','M','N',' ')}},     /* Southern Qiandong Miao -> Hmong */
-  {"hmw",      {HB_TAG('H','M','N',' ')}},     /* Western Mashan Hmong -> Hmong */
-  {"hmy",      {HB_TAG('H','M','N',' ')}},     /* Southern Guiyang Hmong -> Hmong */
-  {"hmz",      {HB_TAG('H','M','N',' ')}},     /* Hmong Shua -> Hmong */
-  {"hnd",      {HB_TAG('H','N','D',' ')}},     /* Southern Hindko -> Hindko */
-  {"hne",      {HB_TAG('C','H','H',' ')}},     /* Chhattisgarhi -> Chattisgarhi */
-  {"hnj",      {HB_TAG('H','M','N',' ')}},     /* Hmong Njua -> Hmong */
-  {"hno",      {HB_TAG('H','N','D',' ')}},     /* Northern Hindko -> Hindko */
-  {"ho",       {HB_TAG('H','M','O',' ')}},     /* Hiri Motu */
-  {"hoc",      {HB_TAG('H','O',' ',' ')}},     /* Ho */
-  {"hoi",      {HB_TAG('A','T','H',' ')}},     /* Holikachuk -> Athapaskan */
-  {"hoj",      {HB_TAG('H','A','R',' ')}},     /* Hadothi -> Harauti */
-  {"hr",       {HB_TAG('H','R','V',' ')}},     /* Croatian */
-  {"hrm",      {HB_TAG('H','M','N',' ')}},     /* Horned Miao -> Hmong */
-  {"hsb",      {HB_TAG('U','S','B',' ')}},     /* Upper Sorbian */
-  {"hsn",      {HB_TAG('Z','H','S',' ')}},     /* Xiang Chinese -> Chinese Simplified */
-  {"ht",       {HB_TAG('H','A','I',' ')}},     /* Haitian (Haitian Creole) */
-  {"hu",       {HB_TAG('H','U','N',' ')}},     /* Hungarian */
-  {"huj",      {HB_TAG('H','M','N',' ')}},     /* Northern Guiyang Hmong -> Hmong */
-  {"hup",      {HB_TAG('A','T','H',' ')}},     /* Hupa -> Athapaskan */
-  {"hy",       {HB_TAG('H','Y','E','0'),       /* Armenian -> Armenian East */
-                HB_TAG('H','Y','E',' ')}},     /* Armenian */
-  {"hyw",      {HB_TAG('H','Y','E',' ')}},     /* Western Armenian -> Armenian */
-  {"hz",       {HB_TAG('H','E','R',' ')}},     /* Herero */
-  {"ia",       {HB_TAG('I','N','A',' ')}},     /* Interlingua (International Auxiliary Language Association) */
-  {"iba",      {HB_TAG('I','B','A',' ')}},     /* Iban */
-  {"ibb",      {HB_TAG('I','B','B',' ')}},     /* Ibibio */
-  {"id",       {HB_TAG('I','N','D',' ')}},     /* Indonesian */
-  {"ida",      {HB_TAG('L','U','H',' ')}},     /* Idakho-Isukha-Tiriki -> Luyia */
-  {"ie",       {HB_TAG('I','L','E',' ')}},     /* Interlingue */
-  {"ig",       {HB_TAG('I','B','O',' ')}},     /* Igbo */
-  {"igb",      {HB_TAG('E','B','I',' ')}},     /* Ebira */
-  {"ii",       {HB_TAG('Y','I','M',' ')}},     /* Sichuan Yi -> Yi Modern */
-  {"ijc",      {HB_TAG('I','J','O',' ')}},     /* Izon -> Ijo */
-  {"ijo",      {HB_TAG('I','J','O',' ')}},     /* Ijo [family] */
-  {"ik",       {HB_TAG('I','P','K',' ')}},     /* Inupiaq [macrolanguage] -> Inupiat */
-  {"ike",      {HB_TAG('I','N','U',' ')}},     /* Eastern Canadian Inuktitut -> Inuktitut */
-  {"ikt",      {HB_TAG('I','N','U',' ')}},     /* Inuinnaqtun -> Inuktitut */
-  {"ilo",      {HB_TAG('I','L','O',' ')}},     /* Iloko -> Ilokano */
-  {"in",       {HB_TAG('I','N','D',' ')}},     /* Indonesian (retired code) */
-  {"ing",      {HB_TAG('A','T','H',' ')}},     /* Degexit'an -> Athapaskan */
-  {"inh",      {HB_TAG('I','N','G',' ')}},     /* Ingush */
-  {"io",       {HB_TAG('I','D','O',' ')}},     /* Ido */
-  {"is",       {HB_TAG('I','S','L',' ')}},     /* Icelandic */
-  {"it",       {HB_TAG('I','T','A',' ')}},     /* Italian */
-  {"iu",       {HB_TAG('I','N','U',' ')}},     /* Inuktitut [macrolanguage] */
-  {"iw",       {HB_TAG('I','W','R',' ')}},     /* Hebrew (retired code) */
-  {"ja",       {HB_TAG('J','A','N',' ')}},     /* Japanese */
-  {"jak",      {HB_TAG('M','L','Y',' ')}},     /* Jakun -> Malay */
-  {"jam",      {HB_TAG('J','A','M',' ')}},     /* Jamaican Creole English -> Jamaican Creole */
-  {"jax",      {HB_TAG('M','L','Y',' ')}},     /* Jambi Malay -> Malay */
-  {"jbo",      {HB_TAG('J','B','O',' ')}},     /* Lojban */
-  {"jct",      {HB_TAG('J','C','T',' ')}},     /* Krymchak */
-  {"ji",       {HB_TAG('J','I','I',' ')}},     /* Yiddish (retired code) */
-  {"jv",       {HB_TAG('J','A','V',' ')}},     /* Javanese */
-  {"jw",       {HB_TAG('J','A','V',' ')}},     /* Javanese (retired code) */
-  {"ka",       {HB_TAG('K','A','T',' ')}},     /* Georgian */
-  {"kaa",      {HB_TAG('K','R','K',' ')}},     /* Kara-Kalpak -> Karakalpak */
-  {"kab",      {HB_TAG('K','A','B','0')}},     /* Kabyle */
-  {"kam",      {HB_TAG('K','M','B',' ')}},     /* Kamba (Kenya) */
-  {"kar",      {HB_TAG('K','R','N',' ')}},     /* Karen [family] */
-  {"kbd",      {HB_TAG('K','A','B',' ')}},     /* Kabardian */
-  {"kby",      {HB_TAG('K','N','R',' ')}},     /* Manga Kanuri -> Kanuri */
-  {"kca",      {HB_TAG('K','H','K',' '),       /* Khanty -> Khanty-Kazim */
-                HB_TAG('K','H','S',' '),       /* Khanty -> Khanty-Shurishkar */
-                HB_TAG('K','H','V',' ')}},     /* Khanty -> Khanty-Vakhi */
-  {"kde",      {HB_TAG('K','D','E',' ')}},     /* Makonde */
-  {"kdr",      {HB_TAG('K','R','M',' ')}},     /* Karaim */
-  {"kdt",      {HB_TAG('K','U','Y',' ')}},     /* Kuy */
-  {"kea",      {HB_TAG('K','E','A',' ')}},     /* Kabuverdianu (Crioulo) */
-  {"kek",      {HB_TAG('K','E','K',' ')}},     /* Kekchi */
-  {"kex",      {HB_TAG('K','K','N',' ')}},     /* Kukna -> Kokni */
-  {"kfa",      {HB_TAG('K','O','D',' ')}},     /* Kodava -> Kodagu */
-  {"kfr",      {HB_TAG('K','A','C',' ')}},     /* Kachhi -> Kachchi */
-  {"kfx",      {HB_TAG('K','U','L',' ')}},     /* Kullu Pahari -> Kulvi */
-  {"kfy",      {HB_TAG('K','M','N',' ')}},     /* Kumaoni */
-  {"kg",       {HB_TAG('K','O','N','0')}},     /* Kongo [macrolanguage] */
-  {"kha",      {HB_TAG('K','S','I',' ')}},     /* Khasi */
-  {"khb",      {HB_TAG('X','B','D',' ')}},     /* Lü */
-  {"khk",      {HB_TAG('M','N','G',' ')}},     /* Halh Mongolian -> Mongolian */
-  {"kht",      {HB_TAG('K','H','N',' '),       /* Khamti -> Khamti Shan (Microsoft fonts) */
-                HB_TAG('K','H','T',' ')}},     /* Khamti -> Khamti Shan (OpenType spec and SIL fonts) */
-  {"khw",      {HB_TAG('K','H','W',' ')}},     /* Khowar */
-  {"ki",       {HB_TAG('K','I','K',' ')}},     /* Kikuyu (Gikuyu) */
-  {"kiu",      {HB_TAG('K','I','U',' ')}},     /* Kirmanjki */
-  {"kj",       {HB_TAG('K','U','A',' ')}},     /* Kuanyama */
-  {"kjd",      {HB_TAG('K','J','D',' ')}},     /* Southern Kiwai */
-  {"kjh",      {HB_TAG('K','H','A',' ')}},     /* Khakas -> Khakass */
-  {"kjp",      {HB_TAG('K','J','P',' ')}},     /* Pwo Eastern Karen -> Eastern Pwo Karen */
-  {"kjz",      {HB_TAG('K','J','Z',' ')}},     /* Bumthangkha */
-  {"kk",       {HB_TAG('K','A','Z',' ')}},     /* Kazakh */
-  {"kkz",      {HB_TAG('A','T','H',' ')}},     /* Kaska -> Athapaskan */
-  {"kl",       {HB_TAG('G','R','N',' ')}},     /* Greenlandic */
-  {"kln",      {HB_TAG('K','A','L',' ')}},     /* Kalenjin [macrolanguage] */
-  {"km",       {HB_TAG('K','H','M',' ')}},     /* Khmer */
-  {"kmb",      {HB_TAG('M','B','N',' ')}},     /* Kimbundu -> Mbundu */
-  {"kmr",      {HB_TAG('K','U','R',' ')}},     /* Northern Kurdish -> Kurdish */
-  {"kmw",      {HB_TAG('K','M','O',' ')}},     /* Komo (Democratic Republic of Congo) */
-  {"kmz",      {HB_TAG('K','M','Z',' ')}},     /* Khorasani Turkish -> Khorasani Turkic */
-  {"kn",       {HB_TAG('K','A','N',' ')}},     /* Kannada */
-  {"knc",      {HB_TAG('K','N','R',' ')}},     /* Central Kanuri -> Kanuri */
-  {"kng",      {HB_TAG('K','O','N','0')}},     /* Koongo -> Kongo */
-  {"knn",      {HB_TAG('K','O','K',' ')}},     /* Konkani */
-  {"ko",       {HB_TAG('K','O','R',' ')}},     /* Korean */
-  {"koi",      {HB_TAG('K','O','P',' ')}},     /* Komi-Permyak */
-  {"kok",      {HB_TAG('K','O','K',' ')}},     /* Konkani [macrolanguage] */
-  {"kos",      {HB_TAG('K','O','S',' ')}},     /* Kosraean */
-  {"koy",      {HB_TAG('A','T','H',' ')}},     /* Koyukon -> Athapaskan */
-  {"kpe",      {HB_TAG('K','P','L',' ')}},     /* Kpelle [macrolanguage] */
-  {"kpv",      {HB_TAG('K','O','Z',' ')}},     /* Komi-Zyrian */
-  {"kpy",      {HB_TAG('K','Y','K',' ')}},     /* Koryak */
-  {"kqs",      {HB_TAG('K','I','S',' ')}},     /* Northern Kissi -> Kisii */
-  {"kqy",      {HB_TAG('K','R','T',' ')}},     /* Koorete */
-  {"kr",       {HB_TAG('K','N','R',' ')}},     /* Kanuri [macrolanguage] */
-  {"krc",      {HB_TAG('K','A','R',' '),       /* Karachay-Balkar -> Karachay */
-                HB_TAG('B','A','L',' ')}},     /* Karachay-Balkar -> Balkar */
-  {"kri",      {HB_TAG('K','R','I',' ')}},     /* Krio */
-  {"krl",      {HB_TAG('K','R','L',' ')}},     /* Karelian */
-  {"krt",      {HB_TAG('K','N','R',' ')}},     /* Tumari Kanuri -> Kanuri */
-  {"kru",      {HB_TAG('K','U','U',' ')}},     /* Kurukh */
-  {"ks",       {HB_TAG('K','S','H',' ')}},     /* Kashmiri */
-  {"ksh",      {HB_TAG('K','S','H','0')}},     /* Kölsch -> Ripuarian */
-  {"kss",      {HB_TAG('K','I','S',' ')}},     /* Southern Kisi -> Kisii */
-  {"ksw",      {HB_TAG('K','S','W',' ')}},     /* S’gaw Karen */
-  {"ktb",      {HB_TAG('K','E','B',' ')}},     /* Kambaata -> Kebena */
-  {"ktu",      {HB_TAG('K','O','N',' ')}},     /* Kituba (Democratic Republic of Congo) -> Kikongo */
-  {"ktw",      {HB_TAG('A','T','H',' ')}},     /* Kato -> Athapaskan */
-  {"ku",       {HB_TAG('K','U','R',' ')}},     /* Kurdish [macrolanguage] */
-  {"kum",      {HB_TAG('K','U','M',' ')}},     /* Kumyk */
-  {"kuu",      {HB_TAG('A','T','H',' ')}},     /* Upper Kuskokwim -> Athapaskan */
-  {"kv",       {HB_TAG('K','O','M',' ')}},     /* Komi [macrolanguage] */
-  {"kvb",      {HB_TAG('M','L','Y',' ')}},     /* Kubu -> Malay */
-  {"kvr",      {HB_TAG('M','L','Y',' ')}},     /* Kerinci -> Malay */
-  {"kw",       {HB_TAG('C','O','R',' ')}},     /* Cornish */
-  {"kwy",      {HB_TAG('K','O','N','0')}},     /* San Salvador Kongo -> Kongo */
-  {"kxc",      {HB_TAG('K','M','S',' ')}},     /* Konso -> Komso */
-  {"kxd",      {HB_TAG('M','L','Y',' ')}},     /* Brunei -> Malay */
-  {"kxu",      {HB_TAG('K','U','I',' ')}},     /* Kui (India) */
-  {"ky",       {HB_TAG('K','I','R',' ')}},     /* Kirghiz (Kyrgyz) */
-  {"kyu",      {HB_TAG('K','Y','U',' ')}},     /* Western Kayah */
-  {"la",       {HB_TAG('L','A','T',' ')}},     /* Latin */
-  {"lad",      {HB_TAG('J','U','D',' ')}},     /* Ladino */
-  {"lb",       {HB_TAG('L','T','Z',' ')}},     /* Luxembourgish */
-  {"lbe",      {HB_TAG('L','A','K',' ')}},     /* Lak */
-  {"lbj",      {HB_TAG('L','D','K',' ')}},     /* Ladakhi */
-  {"lbl",      {HB_TAG('B','I','K',' ')}},     /* Libon Bikol -> Bikol */
-  {"lce",      {HB_TAG('M','L','Y',' ')}},     /* Loncong -> Malay */
-  {"lcf",      {HB_TAG('M','L','Y',' ')}},     /* Lubu -> Malay */
-  {"ldi",      {HB_TAG('K','O','N','0')}},     /* Laari -> Kongo */
-  {"lez",      {HB_TAG('L','E','Z',' ')}},     /* Lezghian -> Lezgi */
-  {"lg",       {HB_TAG('L','U','G',' ')}},     /* Ganda */
-  {"li",       {HB_TAG('L','I','M',' ')}},     /* Limburgish */
-  {"lif",      {HB_TAG('L','M','B',' ')}},     /* Limbu */
-  {"lij",      {HB_TAG('L','I','J',' ')}},     /* Ligurian */
-  {"lis",      {HB_TAG('L','I','S',' ')}},     /* Lisu */
-  {"liw",      {HB_TAG('M','L','Y',' ')}},     /* Col -> Malay */
-  {"ljp",      {HB_TAG('L','J','P',' ')}},     /* Lampung Api -> Lampung */
-  {"lkb",      {HB_TAG('L','U','H',' ')}},     /* Kabras -> Luyia */
-  {"lki",      {HB_TAG('L','K','I',' ')}},     /* Laki */
-  {"lko",      {HB_TAG('L','U','H',' ')}},     /* Khayo -> Luyia */
-  {"lks",      {HB_TAG('L','U','H',' ')}},     /* Kisa -> Luyia */
-  {"lld",      {HB_TAG('L','A','D',' ')}},     /* Ladin */
-  {"lmn",      {HB_TAG('L','A','M',' ')}},     /* Lambadi -> Lambani */
-  {"lmo",      {HB_TAG('L','M','O',' ')}},     /* Lombard */
-  {"ln",       {HB_TAG('L','I','N',' ')}},     /* Lingala */
-  {"lo",       {HB_TAG('L','A','O',' ')}},     /* Lao */
-  {"lom",      {HB_TAG('L','O','M',' ')}},     /* Loma (Liberia) */
-  {"lrc",      {HB_TAG('L','R','C',' ')}},     /* Northern Luri -> Luri */
-  {"lri",      {HB_TAG('L','U','H',' ')}},     /* Marachi -> Luyia */
-  {"lrm",      {HB_TAG('L','U','H',' ')}},     /* Marama -> Luyia */
-  {"lsm",      {HB_TAG('L','U','H',' ')}},     /* Saamia -> Luyia */
-  {"lt",       {HB_TAG('L','T','H',' ')}},     /* Lithuanian */
-  {"ltg",      {HB_TAG('L','V','I',' ')}},     /* Latgalian -> Latvian */
-  {"lto",      {HB_TAG('L','U','H',' ')}},     /* Tsotso -> Luyia */
-  {"lts",      {HB_TAG('L','U','H',' ')}},     /* Tachoni -> Luyia */
-  {"lu",       {HB_TAG('L','U','B',' ')}},     /* Luba-Katanga */
-  {"lua",      {HB_TAG('L','U','A',' ')}},     /* Luba-Lulua */
-  {"luo",      {HB_TAG('L','U','O',' ')}},     /* Luo (Kenya and Tanzania) */
-  {"lus",      {HB_TAG('M','I','Z',' ')}},     /* Lushai -> Mizo */
-  {"luy",      {HB_TAG('L','U','H',' ')}},     /* Luyia [macrolanguage] */
-  {"luz",      {HB_TAG('L','R','C',' ')}},     /* Southern Luri -> Luri */
-  {"lv",       {HB_TAG('L','V','I',' ')}},     /* Latvian [macrolanguage] */
-  {"lvs",      {HB_TAG('L','V','I',' ')}},     /* Standard Latvian -> Latvian */
-  {"lwg",      {HB_TAG('L','U','H',' ')}},     /* Wanga -> Luyia */
-  {"lzh",      {HB_TAG('Z','H','T',' ')}},     /* Literary Chinese -> Chinese Traditional */
-  {"lzz",      {HB_TAG('L','A','Z',' ')}},     /* Laz */
-  {"mad",      {HB_TAG('M','A','D',' ')}},     /* Madurese -> Madura */
-  {"mag",      {HB_TAG('M','A','G',' ')}},     /* Magahi */
-  {"mai",      {HB_TAG('M','T','H',' ')}},     /* Maithili */
-  {"mak",      {HB_TAG('M','K','R',' ')}},     /* Makasar */
-  {"mam",      {HB_TAG('M','A','M',' ')}},     /* Mam */
-  {"man",      {HB_TAG('M','N','K',' ')}},     /* Mandingo [macrolanguage] -> Maninka */
-  {"max",      {HB_TAG('M','L','Y',' ')}},     /* North Moluccan Malay -> Malay */
-  {"mbo",      {HB_TAG('M','B','O',' ')}},     /* Mbo (Cameroon) */
-  {"mct",      {HB_TAG('B','T','I',' ')}},     /* Mengisa -> Beti */
-  {"mdf",      {HB_TAG('M','O','K',' ')}},     /* Moksha */
-  {"mdr",      {HB_TAG('M','D','R',' ')}},     /* Mandar */
-  {"mdy",      {HB_TAG('M','L','E',' ')}},     /* Male (Ethiopia) */
-  {"men",      {HB_TAG('M','D','E',' ')}},     /* Mende (Sierra Leone) */
-  {"meo",      {HB_TAG('M','L','Y',' ')}},     /* Kedah Malay -> Malay */
-  {"mer",      {HB_TAG('M','E','R',' ')}},     /* Meru */
-  {"mfa",      {HB_TAG('M','F','A',' ')}},     /* Pattani Malay */
-  {"mfb",      {HB_TAG('M','L','Y',' ')}},     /* Bangka -> Malay */
-  {"mfe",      {HB_TAG('M','F','E',' ')}},     /* Morisyen */
-  {"mg",       {HB_TAG('M','L','G',' ')}},     /* Malagasy [macrolanguage] */
-  {"mh",       {HB_TAG('M','A','H',' ')}},     /* Marshallese */
-  {"mhr",      {HB_TAG('L','M','A',' ')}},     /* Eastern Mari -> Low Mari */
-  {"mhv",      {HB_TAG('A','R','K',' ')}},     /* Arakanese (retired code) -> Rakhine */
-  {"mi",       {HB_TAG('M','R','I',' ')}},     /* Maori */
-  {"min",      {HB_TAG('M','I','N',' ')}},     /* Minangkabau */
-  {"mk",       {HB_TAG('M','K','D',' ')}},     /* Macedonian */
-  {"mku",      {HB_TAG('M','N','K',' ')}},     /* Konyanka Maninka -> Maninka */
-  {"mkw",      {HB_TAG('M','K','W',' ')}},     /* Kituba (Congo) */
-  {"ml",       {HB_TAG('M','A','L',' '),       /* Malayalam -> Malayalam Traditional */
-                HB_TAG('M','L','R',' ')}},     /* Malayalam -> Malayalam Reformed */
-  {"mlq",      {HB_TAG('M','L','N',' '),       /* Western Maninkakan -> Malinke */
-                HB_TAG('M','N','K',' ')}},     /* Western Maninkakan -> Maninka */
-  {"mmr",      {HB_TAG('H','M','N',' ')}},     /* Western Xiangxi Miao -> Hmong */
-  {"mn",       {HB_TAG('M','N','G',' ')}},     /* Mongolian [macrolanguage] */
-  {"mnc",      {HB_TAG('M','C','H',' ')}},     /* Manchu */
-  {"mni",      {HB_TAG('M','N','I',' ')}},     /* Manipuri */
-  {"mnk",      {HB_TAG('M','N','D',' '),       /* Mandinka */
-                HB_TAG('M','N','K',' ')}},     /* Mandinka -> Maninka */
-  {"mnp",      {HB_TAG('Z','H','S',' ')}},     /* Min Bei Chinese -> Chinese Simplified */
-  {"mns",      {HB_TAG('M','A','N',' ')}},     /* Mansi */
-  {"mnw",      {HB_TAG('M','O','N',' ')}},     /* Mon */
-  {"mo",       {HB_TAG('M','O','L',' ')}},     /* Moldavian (retired code) */
-  {"moh",      {HB_TAG('M','O','H',' ')}},     /* Mohawk */
-  {"mos",      {HB_TAG('M','O','S',' ')}},     /* Mossi */
-  {"mpe",      {HB_TAG('M','A','J',' ')}},     /* Majang */
-  {"mqg",      {HB_TAG('M','L','Y',' ')}},     /* Kota Bangun Kutai Malay -> Malay */
-  {"mr",       {HB_TAG('M','A','R',' ')}},     /* Marathi */
-  {"mrh",      {HB_TAG('Q','I','N',' ')}},     /* Mara Chin -> Chin */
-  {"mrj",      {HB_TAG('H','M','A',' ')}},     /* Western Mari -> High Mari */
-  {"ms",       {HB_TAG('M','L','Y',' ')}},     /* Malay [macrolanguage] */
-  {"msc",      {HB_TAG('M','N','K',' ')}},     /* Sankaran Maninka -> Maninka */
-  {"msh",      {HB_TAG('M','L','G',' ')}},     /* Masikoro Malagasy -> Malagasy */
-  {"msi",      {HB_TAG('M','L','Y',' ')}},     /* Sabah Malay -> Malay */
-  {"mt",       {HB_TAG('M','T','S',' ')}},     /* Maltese */
-  {"mtr",      {HB_TAG('M','A','W',' ')}},     /* Mewari -> Marwari */
-  {"mui",      {HB_TAG('M','L','Y',' ')}},     /* Musi -> Malay */
-  {"mup",      {HB_TAG('R','A','J',' ')}},     /* Malvi -> Rajasthani */
-  {"muq",      {HB_TAG('H','M','N',' ')}},     /* Eastern Xiangxi Miao -> Hmong */
-  {"mus",      {HB_TAG('M','U','S',' ')}},     /* Creek -> Muscogee */
-  {"mvb",      {HB_TAG('A','T','H',' ')}},     /* Mattole -> Athapaskan */
-  {"mve",      {HB_TAG('M','A','W',' ')}},     /* Marwari (Pakistan) */
-  {"mvf",      {HB_TAG('M','N','G',' ')}},     /* Peripheral Mongolian -> Mongolian */
-  {"mwk",      {HB_TAG('M','N','K',' ')}},     /* Kita Maninkakan -> Maninka */
-  {"mwl",      {HB_TAG('M','W','L',' ')}},     /* Mirandese */
-  {"mwr",      {HB_TAG('M','A','W',' ')}},     /* Marwari [macrolanguage] */
-  {"mww",      {HB_TAG('M','W','W',' ')}},     /* Hmong Daw */
-  {"my",       {HB_TAG('B','R','M',' ')}},     /* Burmese */
-  {"mym",      {HB_TAG('M','E','N',' ')}},     /* Me’en */
-  {"myn",      {HB_TAG('M','Y','N',' ')}},     /* Mayan [family] */
-  {"myq",      {HB_TAG('M','N','K',' ')}},     /* Forest Maninka (retired code) -> Maninka */
-  {"myv",      {HB_TAG('E','R','Z',' ')}},     /* Erzya */
-  {"mzn",      {HB_TAG('M','Z','N',' ')}},     /* Mazanderani */
-  {"na",       {HB_TAG('N','A','U',' ')}},     /* Nauru -> Nauruan */
-  {"nag",      {HB_TAG('N','A','G',' ')}},     /* Naga Pidgin -> Naga-Assamese */
-  {"nah",      {HB_TAG('N','A','H',' ')}},     /* Nahuatl [family] */
-  {"nan",      {HB_TAG('Z','H','S',' ')}},     /* Min Nan Chinese -> Chinese Simplified */
-  {"nap",      {HB_TAG('N','A','P',' ')}},     /* Neapolitan */
-  {"nb",       {HB_TAG('N','O','R',' ')}},     /* Norwegian Bokmål -> Norwegian */
-  {"nd",       {HB_TAG('N','D','B',' ')}},     /* North Ndebele -> Ndebele */
-  {"ndc",      {HB_TAG('N','D','C',' ')}},     /* Ndau */
-  {"nds",      {HB_TAG('N','D','S',' ')}},     /* Low Saxon */
-  {"ne",       {HB_TAG('N','E','P',' ')}},     /* Nepali [macrolanguage] */
-  {"new",      {HB_TAG('N','E','W',' ')}},     /* Newari */
-  {"ng",       {HB_TAG('N','D','G',' ')}},     /* Ndonga */
-  {"nga",      {HB_TAG('N','G','A',' ')}},     /* Ngbaka */
-  {"ngl",      {HB_TAG('L','M','W',' ')}},     /* Lomwe */
-  {"ngo",      {HB_TAG('S','X','T',' ')}},     /* Ngoni -> Sutu */
-  {"nhd",      {HB_TAG('G','U','A',' ')}},     /* Chiripá -> Guarani */
-  {"niq",      {HB_TAG('K','A','L',' ')}},     /* Nandi -> Kalenjin */
-  {"niu",      {HB_TAG('N','I','U',' ')}},     /* Niuean */
-  {"niv",      {HB_TAG('G','I','L',' ')}},     /* Gilyak */
-  {"njz",      {HB_TAG('N','I','S',' ')}},     /* Nyishi -> Nisi */
-  {"nl",       {HB_TAG('N','L','D',' ')}},     /* Dutch */
-  {"nle",      {HB_TAG('L','U','H',' ')}},     /* East Nyala -> Luyia */
-  {"nn",       {HB_TAG('N','Y','N',' ')}},     /* Norwegian Nynorsk (Nynorsk, Norwegian) */
-  {"no",       {HB_TAG('N','O','R',' ')}},     /* Norwegian [macrolanguage] */
-  {"nod",      {HB_TAG('N','T','A',' ')}},     /* Northern Thai -> Northern Tai */
-  {"noe",      {HB_TAG('N','O','E',' ')}},     /* Nimadi */
-  {"nog",      {HB_TAG('N','O','G',' ')}},     /* Nogai */
-  {"nov",      {HB_TAG('N','O','V',' ')}},     /* Novial */
-  {"npi",      {HB_TAG('N','E','P',' ')}},     /* Nepali */
-  {"nqo",      {HB_TAG('N','K','O',' ')}},     /* N’Ko */
-  {"nr",       {HB_TAG('N','D','B',' ')}},     /* South Ndebele -> Ndebele */
-  {"nsk",      {HB_TAG('N','A','S',' ')}},     /* Naskapi */
-  {"nso",      {HB_TAG('N','S','O',' ')}},     /* Pedi -> Sotho, Northern */
-  {"nv",       {HB_TAG('N','A','V',' '),       /* Navajo */
-                HB_TAG('A','T','H',' ')}},     /* Navajo -> Athapaskan */
-  {"ny",       {HB_TAG('C','H','I',' ')}},     /* Chichewa (Chewa, Nyanja) */
-  {"nyd",      {HB_TAG('L','U','H',' ')}},     /* Nyore -> Luyia */
-  {"nym",      {HB_TAG('N','Y','M',' ')}},     /* Nyamwezi */
-  {"nyn",      {HB_TAG('N','K','L',' ')}},     /* Nyankole */
-  {"nza",      {HB_TAG('N','Z','A',' ')}},     /* Tigon Mbembe -> Mbembe Tigon */
-  {"oc",       {HB_TAG('O','C','I',' ')}},     /* Occitan (post 1500) */
-  {"oj",       {HB_TAG('O','J','B',' ')}},     /* Ojibwa [macrolanguage] -> Ojibway */
-  {"ojb",      {HB_TAG('O','J','B',' ')}},     /* Northwestern Ojibwa -> Ojibway */
-  {"ojc",      {HB_TAG('O','J','B',' ')}},     /* Central Ojibwa -> Ojibway */
-  {"ojg",      {HB_TAG('O','J','B',' ')}},     /* Eastern Ojibwa -> Ojibway */
-  {"ojs",      {HB_TAG('O','C','R',' ')}},     /* Severn Ojibwa -> Oji-Cree */
-  {"ojw",      {HB_TAG('O','J','B',' ')}},     /* Western Ojibwa -> Ojibway */
-  {"oki",      {HB_TAG('K','A','L',' ')}},     /* Okiek -> Kalenjin */
-  {"okm",      {HB_TAG('K','O','H',' ')}},     /* Middle Korean (10th-16th cent.) -> Korean Old Hangul */
-  {"om",       {HB_TAG('O','R','O',' ')}},     /* Oromo [macrolanguage] */
-  {"or",       {HB_TAG('O','R','I',' ')}},     /* Odia (formerly Oriya) [macrolanguage] */
-  {"orc",      {HB_TAG('O','R','O',' ')}},     /* Orma -> Oromo */
-  {"orn",      {HB_TAG('M','L','Y',' ')}},     /* Orang Kanaq -> Malay */
-  {"ors",      {HB_TAG('M','L','Y',' ')}},     /* Orang Seletar -> Malay */
-  {"ory",      {HB_TAG('O','R','I',' ')}},     /* Odia (formerly Oriya) */
-  {"os",       {HB_TAG('O','S','S',' ')}},     /* Ossetian */
-  {"otw",      {HB_TAG('O','J','B',' ')}},     /* Ottawa -> Ojibway */
-  {"pa",       {HB_TAG('P','A','N',' ')}},     /* Punjabi */
-  {"pag",      {HB_TAG('P','A','G',' ')}},     /* Pangasinan */
-  {"pam",      {HB_TAG('P','A','M',' ')}},     /* Pampanga -> Pampangan */
-  {"pap",      {HB_TAG('P','A','P','0')}},     /* Papiamento -> Papiamentu */
-  {"pau",      {HB_TAG('P','A','U',' ')}},     /* Palauan */
-  {"pbt",      {HB_TAG('P','A','S',' ')}},     /* Southern Pashto -> Pashto */
-  {"pbu",      {HB_TAG('P','A','S',' ')}},     /* Northern Pashto -> Pashto */
-  {"pcc",      {HB_TAG('P','C','C',' ')}},     /* Bouyei */
-  {"pcd",      {HB_TAG('P','C','D',' ')}},     /* Picard */
-  {"pce",      {HB_TAG('P','L','G',' ')}},     /* Ruching Palaung -> Palaung */
-  {"pck",      {HB_TAG('Q','I','N',' ')}},     /* Paite Chin -> Chin */
-  {"pdc",      {HB_TAG('P','D','C',' ')}},     /* Pennsylvania German */
-  {"pel",      {HB_TAG('M','L','Y',' ')}},     /* Pekal -> Malay */
-  {"pes",      {HB_TAG('F','A','R',' ')}},     /* Iranian Persian -> Persian */
-  {"pga",      {HB_TAG('A','R','A',' ')}},     /* Sudanese Creole Arabic -> Arabic */
-  {"phk",      {HB_TAG('P','H','K',' ')}},     /* Phake */
-  {"pi",       {HB_TAG('P','A','L',' ')}},     /* Pali */
-  {"pih",      {HB_TAG('P','I','H',' ')}},     /* Pitcairn-Norfolk -> Norfolk */
-  {"pko",      {HB_TAG('K','A','L',' ')}},     /* Pökoot -> Kalenjin */
-  {"pl",       {HB_TAG('P','L','K',' ')}},     /* Polish */
-  {"pll",      {HB_TAG('P','L','G',' ')}},     /* Shwe Palaung -> Palaung */
-  {"plp",      {HB_TAG('P','A','P',' ')}},     /* Palpa */
-  {"plt",      {HB_TAG('M','L','G',' ')}},     /* Plateau Malagasy -> Malagasy */
-  {"pms",      {HB_TAG('P','M','S',' ')}},     /* Piemontese */
-  {"pnb",      {HB_TAG('P','N','B',' ')}},     /* Western Panjabi */
-  {"poh",      {HB_TAG('P','O','H',' ')}},     /* Poqomchi' -> Pocomchi */
-  {"pon",      {HB_TAG('P','O','N',' ')}},     /* Pohnpeian */
-  {"ppa",      {HB_TAG('B','A','G',' ')}},     /* Pao (retired code) -> Baghelkhandi */
-  {"pro",      {HB_TAG('P','R','O',' ')}},     /* Old Provençal (to 1500) -> Provençal / Old Provençal */
-  {"prs",      {HB_TAG('D','R','I',' ')}},     /* Dari */
-  {"ps",       {HB_TAG('P','A','S',' ')}},     /* Pashto [macrolanguage] */
-  {"pse",      {HB_TAG('M','L','Y',' ')}},     /* Central Malay -> Malay */
-  {"pst",      {HB_TAG('P','A','S',' ')}},     /* Central Pashto -> Pashto */
-  {"pt",       {HB_TAG('P','T','G',' ')}},     /* Portuguese */
-  {"pwo",      {HB_TAG('P','W','O',' ')}},     /* Pwo Western Karen -> Western Pwo Karen */
-  {"qu",       {HB_TAG('Q','U','Z',' ')}},     /* Quechua [macrolanguage] */
-  {"qub",      {HB_TAG('Q','W','H',' ')}},     /* Huallaga Huánuco Quechua -> Quechua (Peru) */
-  {"quc",      {HB_TAG('Q','U','C',' ')}},     /* K’iche’ */
-  {"qud",      {HB_TAG('Q','V','I',' ')}},     /* Calderón Highland Quichua -> Quechua (Ecuador) */
-  {"quf",      {HB_TAG('Q','U','Z',' ')}},     /* Lambayeque Quechua -> Quechua */
-  {"qug",      {HB_TAG('Q','V','I',' ')}},     /* Chimborazo Highland Quichua -> Quechua (Ecuador) */
-  {"quh",      {HB_TAG('Q','U','H',' ')}},     /* South Bolivian Quechua -> Quechua (Bolivia) */
-  {"quk",      {HB_TAG('Q','U','Z',' ')}},     /* Chachapoyas Quechua -> Quechua */
-  {"qul",      {HB_TAG('Q','U','Z',' ')}},     /* North Bolivian Quechua -> Quechua */
-  {"qup",      {HB_TAG('Q','V','I',' ')}},     /* Southern Pastaza Quechua -> Quechua (Ecuador) */
-  {"qur",      {HB_TAG('Q','W','H',' ')}},     /* Yanahuanca Pasco Quechua -> Quechua (Peru) */
-  {"qus",      {HB_TAG('Q','U','H',' ')}},     /* Santiago del Estero Quichua -> Quechua (Bolivia) */
-  {"quw",      {HB_TAG('Q','V','I',' ')}},     /* Tena Lowland Quichua -> Quechua (Ecuador) */
-  {"qux",      {HB_TAG('Q','W','H',' ')}},     /* Yauyos Quechua -> Quechua (Peru) */
-  {"quy",      {HB_TAG('Q','U','Z',' ')}},     /* Ayacucho Quechua -> Quechua */
-  {"quz",      {HB_TAG('Q','U','Z',' ')}},     /* Cusco Quechua -> Quechua */
-  {"qva",      {HB_TAG('Q','W','H',' ')}},     /* Ambo-Pasco Quechua -> Quechua (Peru) */
-  {"qvc",      {HB_TAG('Q','U','Z',' ')}},     /* Cajamarca Quechua -> Quechua */
-  {"qve",      {HB_TAG('Q','U','Z',' ')}},     /* Eastern Apurímac Quechua -> Quechua */
-  {"qvh",      {HB_TAG('Q','W','H',' ')}},     /* Huamalíes-Dos de Mayo Huánuco Quechua -> Quechua (Peru) */
-  {"qvi",      {HB_TAG('Q','V','I',' ')}},     /* Imbabura Highland Quichua -> Quechua (Ecuador) */
-  {"qvj",      {HB_TAG('Q','V','I',' ')}},     /* Loja Highland Quichua -> Quechua (Ecuador) */
-  {"qvl",      {HB_TAG('Q','W','H',' ')}},     /* Cajatambo North Lima Quechua -> Quechua (Peru) */
-  {"qvm",      {HB_TAG('Q','W','H',' ')}},     /* Margos-Yarowilca-Lauricocha Quechua -> Quechua (Peru) */
-  {"qvn",      {HB_TAG('Q','W','H',' ')}},     /* North Junín Quechua -> Quechua (Peru) */
-  {"qvo",      {HB_TAG('Q','V','I',' ')}},     /* Napo Lowland Quechua -> Quechua (Ecuador) */
-  {"qvp",      {HB_TAG('Q','W','H',' ')}},     /* Pacaraos Quechua -> Quechua (Peru) */
-  {"qvs",      {HB_TAG('Q','U','Z',' ')}},     /* San Martín Quechua -> Quechua */
-  {"qvw",      {HB_TAG('Q','W','H',' ')}},     /* Huaylla Wanca Quechua -> Quechua (Peru) */
-  {"qvz",      {HB_TAG('Q','V','I',' ')}},     /* Northern Pastaza Quichua -> Quechua (Ecuador) */
-  {"qwa",      {HB_TAG('Q','W','H',' ')}},     /* Corongo Ancash Quechua -> Quechua (Peru) */
-  {"qwc",      {HB_TAG('Q','U','Z',' ')}},     /* Classical Quechua -> Quechua */
-  {"qwh",      {HB_TAG('Q','W','H',' ')}},     /* Huaylas Ancash Quechua -> Quechua (Peru) */
-  {"qws",      {HB_TAG('Q','W','H',' ')}},     /* Sihuas Ancash Quechua -> Quechua (Peru) */
-  {"qxa",      {HB_TAG('Q','W','H',' ')}},     /* Chiquián Ancash Quechua -> Quechua (Peru) */
-  {"qxc",      {HB_TAG('Q','W','H',' ')}},     /* Chincha Quechua -> Quechua (Peru) */
-  {"qxh",      {HB_TAG('Q','W','H',' ')}},     /* Panao Huánuco Quechua -> Quechua (Peru) */
-  {"qxl",      {HB_TAG('Q','V','I',' ')}},     /* Salasaca Highland Quichua -> Quechua (Ecuador) */
-  {"qxn",      {HB_TAG('Q','W','H',' ')}},     /* Northern Conchucos Ancash Quechua -> Quechua (Peru) */
-  {"qxo",      {HB_TAG('Q','W','H',' ')}},     /* Southern Conchucos Ancash Quechua -> Quechua (Peru) */
-  {"qxp",      {HB_TAG('Q','U','Z',' ')}},     /* Puno Quechua -> Quechua */
-  {"qxr",      {HB_TAG('Q','V','I',' ')}},     /* Cañar Highland Quichua -> Quechua (Ecuador) */
-  {"qxt",      {HB_TAG('Q','W','H',' ')}},     /* Santa Ana de Tusi Pasco Quechua -> Quechua (Peru) */
-  {"qxu",      {HB_TAG('Q','U','Z',' ')}},     /* Arequipa-La Unión Quechua -> Quechua */
-  {"qxw",      {HB_TAG('Q','W','H',' ')}},     /* Jauja Wanca Quechua -> Quechua (Peru) */
-  {"rag",      {HB_TAG('L','U','H',' ')}},     /* Logooli -> Luyia */
-  {"raj",      {HB_TAG('R','A','J',' ')}},     /* Rajasthani [macrolanguage] */
-  {"rar",      {HB_TAG('R','A','R',' ')}},     /* Rarotongan */
-  {"rbb",      {HB_TAG('P','L','G',' ')}},     /* Rumai Palaung -> Palaung */
-  {"rbl",      {HB_TAG('B','I','K',' ')}},     /* Miraya Bikol -> Bikol */
-  {"rej",      {HB_TAG('R','E','J',' ')}},     /* Rejang */
-  {"ria",      {HB_TAG('R','I','A',' ')}},     /* Riang (India) */
-  {"rif",      {HB_TAG('R','I','F',' ')}},     /* Tarifit */
-  {"rit",      {HB_TAG('R','I','T',' ')}},     /* Ritarungo */
-  {"rki",      {HB_TAG('A','R','K',' ')}},     /* Rakhine */
-  {"rkw",      {HB_TAG('R','K','W',' ')}},     /* Arakwal */
-  {"rm",       {HB_TAG('R','M','S',' ')}},     /* Romansh */
-  {"rmc",      {HB_TAG('R','O','Y',' ')}},     /* Carpathian Romani -> Romany */
-  {"rmf",      {HB_TAG('R','O','Y',' ')}},     /* Kalo Finnish Romani -> Romany */
-  {"rml",      {HB_TAG('R','O','Y',' ')}},     /* Baltic Romani -> Romany */
-  {"rmn",      {HB_TAG('R','O','Y',' ')}},     /* Balkan Romani -> Romany */
-  {"rmo",      {HB_TAG('R','O','Y',' ')}},     /* Sinte Romani -> Romany */
-  {"rmw",      {HB_TAG('R','O','Y',' ')}},     /* Welsh Romani -> Romany */
-  {"rmy",      {HB_TAG('R','M','Y',' ')}},     /* Vlax Romani */
-  {"rmz",      {HB_TAG('A','R','K',' ')}},     /* Marma -> Rakhine */
-  {"rn",       {HB_TAG('R','U','N',' ')}},     /* Rundi */
-  {"rnl",      {HB_TAG('H','A','L',' ')}},     /* Ranglong -> Halam (Falam Chin) */
-  {"ro",       {HB_TAG('R','O','M',' ')}},     /* Romanian */
-  {"rom",      {HB_TAG('R','O','Y',' ')}},     /* Romany [macrolanguage] */
-  {"rtm",      {HB_TAG('R','T','M',' ')}},     /* Rotuman */
-  {"ru",       {HB_TAG('R','U','S',' ')}},     /* Russian */
-  {"rue",      {HB_TAG('R','S','Y',' ')}},     /* Rusyn */
-  {"rup",      {HB_TAG('R','U','P',' ')}},     /* Aromanian */
-  {"rw",       {HB_TAG('R','U','A',' ')}},     /* Kinyarwanda */
-  {"rwr",      {HB_TAG('M','A','W',' ')}},     /* Marwari (India) */
-  {"sa",       {HB_TAG('S','A','N',' ')}},     /* Sanskrit */
-  {"sah",      {HB_TAG('Y','A','K',' ')}},     /* Yakut -> Sakha */
-  {"sam",      {HB_TAG('P','A','A',' ')}},     /* Samaritan Aramaic -> Palestinian Aramaic */
-  {"sas",      {HB_TAG('S','A','S',' ')}},     /* Sasak */
-  {"sat",      {HB_TAG('S','A','T',' ')}},     /* Santali */
-  {"sc",       {HB_TAG('S','R','D',' ')}},     /* Sardinian [macrolanguage] */
-  {"sck",      {HB_TAG('S','A','D',' ')}},     /* Sadri */
-  {"scn",      {HB_TAG('S','C','N',' ')}},     /* Sicilian */
-  {"sco",      {HB_TAG('S','C','O',' ')}},     /* Scots */
-  {"scs",      {HB_TAG('S','C','S',' '),       /* North Slavey */
-                HB_TAG('S','L','A',' '),       /* North Slavey -> Slavey */
-                HB_TAG('A','T','H',' ')}},     /* North Slavey -> Athapaskan */
-  {"sd",       {HB_TAG('S','N','D',' ')}},     /* Sindhi */
-  {"sdc",      {HB_TAG('S','R','D',' ')}},     /* Sassarese Sardinian -> Sardinian */
-  {"sdh",      {HB_TAG('K','U','R',' ')}},     /* Southern Kurdish -> Kurdish */
-  {"sdn",      {HB_TAG('S','R','D',' ')}},     /* Gallurese Sardinian -> Sardinian */
-  {"se",       {HB_TAG('N','S','M',' ')}},     /* Northern Sami */
-  {"seh",      {HB_TAG('S','N','A',' ')}},     /* Sena */
-  {"sek",      {HB_TAG('A','T','H',' ')}},     /* Sekani -> Athapaskan */
-  {"sel",      {HB_TAG('S','E','L',' ')}},     /* Selkup */
-  {"sez",      {HB_TAG('Q','I','N',' ')}},     /* Senthang Chin -> Chin */
-  {"sfm",      {HB_TAG('H','M','N',' ')}},     /* Small Flowery Miao -> Hmong */
-  {"sg",       {HB_TAG('S','G','O',' ')}},     /* Sango */
-  {"sga",      {HB_TAG('S','G','A',' ')}},     /* Old Irish (to 900) */
-  {"sgc",      {HB_TAG('K','A','L',' ')}},     /* Kipsigis -> Kalenjin */
-  {"sgs",      {HB_TAG('S','G','S',' ')}},     /* Samogitian */
-  {"sgw",      {HB_TAG('C','H','G',' '),       /* Sebat Bet Gurage -> Chaha Gurage */
-                HB_TAG('S','G','W',' ')}},     /* Sebat Bet Gurage -> Chaha Gurage (SIL fonts) */
-  {"shi",      {HB_TAG('S','H','I',' ')}},     /* Tachelhit */
-  {"shn",      {HB_TAG('S','H','N',' ')}},     /* Shan */
-  {"shu",      {HB_TAG('A','R','A',' ')}},     /* Chadian Arabic -> Arabic */
-  {"si",       {HB_TAG('S','N','H',' ')}},     /* Sinhala (Sinhalese) */
-  {"sid",      {HB_TAG('S','I','D',' ')}},     /* Sidamo */
-  {"sjd",      {HB_TAG('K','S','M',' ')}},     /* Kildin Sami */
-  {"sjo",      {HB_TAG('S','I','B',' ')}},     /* Xibe -> Sibe */
-  {"sk",       {HB_TAG('S','K','Y',' ')}},     /* Slovak */
-  {"skg",      {HB_TAG('M','L','G',' ')}},     /* Sakalava Malagasy -> Malagasy */
-  {"skr",      {HB_TAG('S','R','K',' ')}},     /* Saraiki */
-  {"sl",       {HB_TAG('S','L','V',' ')}},     /* Slovenian */
-  {"sm",       {HB_TAG('S','M','O',' ')}},     /* Samoan */
-  {"sma",      {HB_TAG('S','S','M',' ')}},     /* Southern Sami */
-  {"smj",      {HB_TAG('L','S','M',' ')}},     /* Lule Sami */
-  {"smn",      {HB_TAG('I','S','M',' ')}},     /* Inari Sami */
-  {"sms",      {HB_TAG('S','K','S',' ')}},     /* Skolt Sami */
-  {"sn",       {HB_TAG('S','N','A','0')}},     /* Shona */
-  {"snk",      {HB_TAG('S','N','K',' ')}},     /* Soninke */
-  {"so",       {HB_TAG('S','M','L',' ')}},     /* Somali */
-  {"sop",      {HB_TAG('S','O','P',' ')}},     /* Songe */
-  {"spv",      {HB_TAG('O','R','I',' ')}},     /* Sambalpuri -> Odia (formerly Oriya) */
-  {"spy",      {HB_TAG('K','A','L',' ')}},     /* Sabaot -> Kalenjin */
-  {"sq",       {HB_TAG('S','Q','I',' ')}},     /* Albanian [macrolanguage] */
-  {"sr",       {HB_TAG('S','R','B',' ')}},     /* Serbian */
-  {"src",      {HB_TAG('S','R','D',' ')}},     /* Logudorese Sardinian -> Sardinian */
-  {"sro",      {HB_TAG('S','R','D',' ')}},     /* Campidanese Sardinian -> Sardinian */
-  {"srr",      {HB_TAG('S','R','R',' ')}},     /* Serer */
-  {"srs",      {HB_TAG('A','T','H',' ')}},     /* Sarsi -> Athapaskan */
-  {"ss",       {HB_TAG('S','W','Z',' ')}},     /* Swati */
-  {"ssh",      {HB_TAG('A','R','A',' ')}},     /* Shihhi Arabic -> Arabic */
-  {"st",       {HB_TAG('S','O','T',' ')}},     /* Southern Sotho -> Sotho, Southern */
-  {"stq",      {HB_TAG('S','T','Q',' ')}},     /* Saterfriesisch -> Saterland Frisian */
-  {"stv",      {HB_TAG('S','I','G',' ')}},     /* Silt'e -> Silte Gurage */
-  {"su",       {HB_TAG('S','U','N',' ')}},     /* Sundanese */
-  {"suk",      {HB_TAG('S','U','K',' ')}},     /* Sukuma */
-  {"suq",      {HB_TAG('S','U','R',' ')}},     /* Suri */
-  {"sv",       {HB_TAG('S','V','E',' ')}},     /* Swedish */
-  {"sva",      {HB_TAG('S','V','A',' ')}},     /* Svan */
-  {"sw",       {HB_TAG('S','W','K',' ')}},     /* Swahili [macrolanguage] */
-  {"swb",      {HB_TAG('C','M','R',' ')}},     /* Maore Comorian -> Comorian */
-  {"swc",      {HB_TAG('S','W','K',' ')}},     /* Congo Swahili -> Swahili */
-  {"swh",      {HB_TAG('S','W','K',' ')}},     /* Swahili */
-  {"swv",      {HB_TAG('M','A','W',' ')}},     /* Shekhawati -> Marwari */
-  {"sxu",      {HB_TAG('S','X','U',' ')}},     /* Upper Saxon */
-  {"syc",      {HB_TAG('S','Y','R',' ')}},     /* Classical Syriac -> Syriac */
-  {"syl",      {HB_TAG('S','Y','L',' ')}},     /* Sylheti */
-  {"syr",      {HB_TAG('S','Y','R',' ')}},     /* Syriac [macrolanguage] */
-  {"szl",      {HB_TAG('S','Z','L',' ')}},     /* Silesian */
-  {"ta",       {HB_TAG('T','A','M',' ')}},     /* Tamil */
-  {"taa",      {HB_TAG('A','T','H',' ')}},     /* Lower Tanana -> Athapaskan */
-  {"tab",      {HB_TAG('T','A','B',' ')}},     /* Tabassaran -> Tabasaran */
-  {"taq",      {HB_TAG('T','M','H',' ')}},     /* Tamasheq -> Tamashek */
-  {"tau",      {HB_TAG('A','T','H',' ')}},     /* Upper Tanana -> Athapaskan */
-  {"tcb",      {HB_TAG('A','T','H',' ')}},     /* Tanacross -> Athapaskan */
-  {"tce",      {HB_TAG('A','T','H',' ')}},     /* Southern Tutchone -> Athapaskan */
-  {"tcp",      {HB_TAG('Q','I','N',' ')}},     /* Tawr Chin -> Chin */
-  {"tcy",      {HB_TAG('T','U','L',' ')}},     /* Tulu -> Tumbuka */
-  {"tcz",      {HB_TAG('Q','I','N',' ')}},     /* Thado Chin -> Chin */
-  {"tdd",      {HB_TAG('T','D','D',' ')}},     /* Tai Nüa -> Dehong Dai */
-  {"tdx",      {HB_TAG('M','L','G',' ')}},     /* Tandroy-Mahafaly Malagasy -> Malagasy */
-  {"te",       {HB_TAG('T','E','L',' ')}},     /* Telugu */
-  {"tec",      {HB_TAG('K','A','L',' ')}},     /* Terik -> Kalenjin */
-  {"tem",      {HB_TAG('T','M','N',' ')}},     /* Timne -> Temne */
-  {"tet",      {HB_TAG('T','E','T',' ')}},     /* Tetum */
-  {"tfn",      {HB_TAG('A','T','H',' ')}},     /* Tanaina -> Athapaskan */
-  {"tg",       {HB_TAG('T','A','J',' ')}},     /* Tajik -> Tajiki */
-  {"tgj",      {HB_TAG('N','I','S',' ')}},     /* Tagin -> Nisi */
-  {"tgx",      {HB_TAG('A','T','H',' ')}},     /* Tagish -> Athapaskan */
-  {"th",       {HB_TAG('T','H','A',' ')}},     /* Thai */
-  {"tht",      {HB_TAG('A','T','H',' ')}},     /* Tahltan -> Athapaskan */
-  {"thv",      {HB_TAG('T','M','H',' ')}},     /* Tahaggart Tamahaq -> Tamashek */
-  {"thz",      {HB_TAG('T','M','H',' ')}},     /* Tayart Tamajeq -> Tamashek */
-  {"ti",       {HB_TAG('T','G','Y',' ')}},     /* Tigrinya */
-  {"tig",      {HB_TAG('T','G','R',' ')}},     /* Tigre */
-  {"tiv",      {HB_TAG('T','I','V',' ')}},     /* Tiv */
-  {"tk",       {HB_TAG('T','K','M',' ')}},     /* Turkmen */
-  {"tkg",      {HB_TAG('M','L','G',' ')}},     /* Tesaka Malagasy -> Malagasy */
-  {"tl",       {HB_TAG('T','G','L',' ')}},     /* Tagalog */
-  {"tmh",      {HB_TAG('T','M','H',' ')}},     /* Tamashek [macrolanguage] */
-  {"tmw",      {HB_TAG('M','L','Y',' ')}},     /* Temuan -> Malay */
-  {"tn",       {HB_TAG('T','N','A',' ')}},     /* Tswana */
-  {"tnf",      {HB_TAG('D','R','I',' ')}},     /* Tangshewi (retired code) -> Dari */
-  {"to",       {HB_TAG('T','G','N',' ')}},     /* Tonga (Tonga Islands) -> Tongan */
-  {"tod",      {HB_TAG('T','O','D','0')}},     /* Toma */
-  {"toi",      {HB_TAG('T','N','G',' ')}},     /* Tonga (Zambia) */
-  {"tol",      {HB_TAG('A','T','H',' ')}},     /* Tolowa -> Athapaskan */
-  {"tpi",      {HB_TAG('T','P','I',' ')}},     /* Tok Pisin */
-  {"tr",       {HB_TAG('T','R','K',' ')}},     /* Turkish */
-  {"tru",      {HB_TAG('T','U','A',' '),       /* Turoyo -> Turoyo Aramaic */
-                HB_TAG('S','Y','R',' ')}},     /* Turoyo -> Syriac */
-  {"ts",       {HB_TAG('T','S','G',' ')}},     /* Tsonga */
-  {"tsj",      {HB_TAG('T','S','J',' ')}},     /* Tshangla */
-  {"tt",       {HB_TAG('T','A','T',' ')}},     /* Tatar */
-  {"ttm",      {HB_TAG('A','T','H',' ')}},     /* Northern Tutchone -> Athapaskan */
-  {"ttq",      {HB_TAG('T','M','H',' ')}},     /* Tawallammat Tamajaq -> Tamashek */
-  {"tum",      {HB_TAG('T','U','M',' ')}},     /* Tumbuka -> Tulu */
-  {"tuu",      {HB_TAG('A','T','H',' ')}},     /* Tututni -> Athapaskan */
-  {"tuy",      {HB_TAG('K','A','L',' ')}},     /* Tugen -> Kalenjin */
-  {"tvl",      {HB_TAG('T','V','L',' ')}},     /* Tuvalu */
-  {"tw",       {HB_TAG('T','W','I',' '),       /* Twi */
-                HB_TAG('A','K','A',' ')}},     /* Twi -> Akan */
-  {"txc",      {HB_TAG('A','T','H',' ')}},     /* Tsetsaut -> Athapaskan */
-  {"txy",      {HB_TAG('M','L','G',' ')}},     /* Tanosy Malagasy -> Malagasy */
-  {"ty",       {HB_TAG('T','H','T',' ')}},     /* Tahitian */
-  {"tyv",      {HB_TAG('T','U','V',' ')}},     /* Tuvinian -> Tuvin */
-  {"tyz",      {HB_TAG('T','Y','Z',' ')}},     /* Tày */
-  {"tzm",      {HB_TAG('T','Z','M',' ')}},     /* Central Atlas Tamazight -> Tamazight */
-  {"tzo",      {HB_TAG('T','Z','O',' ')}},     /* Tzotzil */
-  {"ubl",      {HB_TAG('B','I','K',' ')}},     /* Buhi'non Bikol -> Bikol */
-  {"udm",      {HB_TAG('U','D','M',' ')}},     /* Udmurt */
-  {"ug",       {HB_TAG('U','Y','G',' ')}},     /* Uyghur */
-  {"uk",       {HB_TAG('U','K','R',' ')}},     /* Ukrainian */
-  {"umb",      {HB_TAG('U','M','B',' ')}},     /* Umbundu */
-  {"unr",      {HB_TAG('M','U','N',' ')}},     /* Mundari */
-  {"ur",       {HB_TAG('U','R','D',' ')}},     /* Urdu */
-  {"urk",      {HB_TAG('M','L','Y',' ')}},     /* Urak Lawoi' -> Malay */
-  {"uz",       {HB_TAG('U','Z','B',' ')}},     /* Uzbek [macrolanguage] */
-  {"uzn",      {HB_TAG('U','Z','B',' ')}},     /* Northern Uzbek -> Uzbek */
-  {"uzs",      {HB_TAG('U','Z','B',' ')}},     /* Southern Uzbek -> Uzbek */
-  {"ve",       {HB_TAG('V','E','N',' ')}},     /* Venda */
-  {"vec",      {HB_TAG('V','E','C',' ')}},     /* Venetian */
-  {"vi",       {HB_TAG('V','I','T',' ')}},     /* Vietnamese */
-  {"vkk",      {HB_TAG('M','L','Y',' ')}},     /* Kaur -> Malay */
-  {"vkt",      {HB_TAG('M','L','Y',' ')}},     /* Tenggarong Kutai Malay -> Malay */
-  {"vls",      {HB_TAG('F','L','E',' ')}},     /* Vlaams -> Dutch (Flemish) */
-  {"vmw",      {HB_TAG('M','A','K',' ')}},     /* Makhuwa */
-  {"vo",       {HB_TAG('V','O','L',' ')}},     /* Volapük */
-  {"vro",      {HB_TAG('V','R','O',' ')}},     /* Võro */
-  {"wa",       {HB_TAG('W','L','N',' ')}},     /* Walloon */
-  {"war",      {HB_TAG('W','A','R',' ')}},     /* Waray (Philippines) -> Waray-Waray */
-  {"wbm",      {HB_TAG('W','A',' ',' ')}},     /* Wa */
-  {"wbr",      {HB_TAG('W','A','G',' ')}},     /* Wagdi */
-  {"wlc",      {HB_TAG('C','M','R',' ')}},     /* Mwali Comorian -> Comorian */
-  {"wle",      {HB_TAG('S','I','G',' ')}},     /* Wolane -> Silte Gurage */
-  {"wlk",      {HB_TAG('A','T','H',' ')}},     /* Wailaki -> Athapaskan */
-  {"wni",      {HB_TAG('C','M','R',' ')}},     /* Ndzwani Comorian -> Comorian */
-  {"wo",       {HB_TAG('W','L','F',' ')}},     /* Wolof */
-  {"wry",      {HB_TAG('M','A','W',' ')}},     /* Merwari -> Marwari */
-  {"wsg",      {HB_TAG('G','O','N',' ')}},     /* Adilabad Gondi -> Gondi */
-  {"wtm",      {HB_TAG('W','T','M',' ')}},     /* Mewati */
-  {"wuu",      {HB_TAG('Z','H','S',' ')}},     /* Wu Chinese -> Chinese Simplified */
-  {"xal",      {HB_TAG('K','L','M',' '),       /* Kalmyk */
-                HB_TAG('T','O','D',' ')}},     /* Kalmyk -> Todo */
-  {"xan",      {HB_TAG('S','E','K',' ')}},     /* Xamtanga -> Sekota */
-  {"xh",       {HB_TAG('X','H','S',' ')}},     /* Xhosa */
-  {"xjb",      {HB_TAG('X','J','B',' ')}},     /* Minjungbal -> Minjangbal */
-  {"xkf",      {HB_TAG('X','K','F',' ')}},     /* Khengkha */
-  {"xmm",      {HB_TAG('M','L','Y',' ')}},     /* Manado Malay -> Malay */
-  {"xmv",      {HB_TAG('M','L','G',' ')}},     /* Antankarana Malagasy -> Malagasy */
-  {"xmw",      {HB_TAG('M','L','G',' ')}},     /* Tsimihety Malagasy -> Malagasy */
-  {"xnr",      {HB_TAG('D','G','R',' ')}},     /* Kangri -> Dogri */
-  {"xog",      {HB_TAG('X','O','G',' ')}},     /* Soga */
-  {"xpe",      {HB_TAG('X','P','E',' ')}},     /* Liberia Kpelle -> Kpelle (Liberia) */
-  {"xsl",      {HB_TAG('S','S','L',' '),       /* South Slavey */
-                HB_TAG('S','L','A',' '),       /* South Slavey -> Slavey */
-                HB_TAG('A','T','H',' ')}},     /* South Slavey -> Athapaskan */
-  {"xst",      {HB_TAG('S','I','G',' ')}},     /* Silt'e (retired code) -> Silte Gurage */
-  {"xwo",      {HB_TAG('T','O','D',' ')}},     /* Written Oirat -> Todo */
-  {"yao",      {HB_TAG('Y','A','O',' ')}},     /* Yao */
-  {"yap",      {HB_TAG('Y','A','P',' ')}},     /* Yapese */
-  {"ybd",      {HB_TAG('A','R','K',' ')}},     /* Yangbye (retired code) -> Rakhine */
-  {"ydd",      {HB_TAG('J','I','I',' ')}},     /* Eastern Yiddish -> Yiddish */
-  {"yi",       {HB_TAG('J','I','I',' ')}},     /* Yiddish [macrolanguage] */
-  {"yih",      {HB_TAG('J','I','I',' ')}},     /* Western Yiddish -> Yiddish */
-  {"yo",       {HB_TAG('Y','B','A',' ')}},     /* Yoruba */
-  {"yos",      {HB_TAG('Q','I','N',' ')}},     /* Yos (retired code) -> Chin */
-  {"yrk",      {HB_TAG('T','N','E',' '),       /* Nenets -> Tundra Nenets */
-                HB_TAG('F','N','E',' ')}},     /* Nenets -> Forest Nenets */
-  {"yue",      {HB_TAG('Z','H','H',' ')}},     /* Yue Chinese -> Chinese, Hong Kong SAR */
-  {"za",       {HB_TAG('Z','H','A',' ')}},     /* Zhuang [macrolanguage] */
-  {"zch",      {HB_TAG('Z','H','A',' ')}},     /* Central Hongshuihe Zhuang -> Zhuang */
-  {"zdj",      {HB_TAG('C','M','R',' ')}},     /* Ngazidja Comorian -> Comorian */
-  {"zea",      {HB_TAG('Z','E','A',' ')}},     /* Zeeuws -> Zealandic */
-  {"zeh",      {HB_TAG('Z','H','A',' ')}},     /* Eastern Hongshuihe Zhuang -> Zhuang */
-  {"zgb",      {HB_TAG('Z','H','A',' ')}},     /* Guibei Zhuang -> Zhuang */
-  {"zgh",      {HB_TAG('Z','G','H',' ')}},     /* Standard Moroccan Tamazight */
-  {"zgm",      {HB_TAG('Z','H','A',' ')}},     /* Minz Zhuang -> Zhuang */
-  {"zgn",      {HB_TAG('Z','H','A',' ')}},     /* Guibian Zhuang -> Zhuang */
-  {"zh",       {HB_TAG('Z','H','S',' ')}},     /* Chinese [macrolanguage] -> Chinese Simplified */
-  {"zhd",      {HB_TAG('Z','H','A',' ')}},     /* Dai Zhuang -> Zhuang */
-  {"zhn",      {HB_TAG('Z','H','A',' ')}},     /* Nong Zhuang -> Zhuang */
-  {"zlj",      {HB_TAG('Z','H','A',' ')}},     /* Liujiang Zhuang -> Zhuang */
-  {"zlm",      {HB_TAG('M','L','Y',' ')}},     /* Malay */
-  {"zln",      {HB_TAG('Z','H','A',' ')}},     /* Lianshan Zhuang -> Zhuang */
-  {"zlq",      {HB_TAG('Z','H','A',' ')}},     /* Liuqian Zhuang -> Zhuang */
-  {"zmi",      {HB_TAG('M','L','Y',' ')}},     /* Negeri Sembilan Malay -> Malay */
-  {"zne",      {HB_TAG('Z','N','D',' ')}},     /* Zande */
-  {"zom",      {HB_TAG('Q','I','N',' ')}},     /* Zou -> Chin */
-  {"zqe",      {HB_TAG('Z','H','A',' ')}},     /* Qiubei Zhuang -> Zhuang */
-  {"zsm",      {HB_TAG('M','L','Y',' ')}},     /* Standard Malay -> Malay */
-  {"zu",       {HB_TAG('Z','U','L',' ')}},     /* Zulu */
-  {"zum",      {HB_TAG('L','R','C',' ')}},     /* Kumzari -> Luri */
-  {"zyb",      {HB_TAG('Z','H','A',' ')}},     /* Yongbei Zhuang -> Zhuang */
-  {"zyg",      {HB_TAG('Z','H','A',' ')}},     /* Yang Zhuang -> Zhuang */
-  {"zyj",      {HB_TAG('Z','H','A',' ')}},     /* Youjiang Zhuang -> Zhuang */
-  {"zyn",      {HB_TAG('Z','H','A',' ')}},     /* Yongnan Zhuang -> Zhuang */
-  {"zza",      {HB_TAG('Z','Z','A',' ')}},     /* Zazaki [macrolanguage] */
-  {"zzj",      {HB_TAG('Z','H','A',' ')}},     /* Zuojiang Zhuang -> Zhuang */
+  {"aa",       HB_TAG('A','F','R',' ')},       /* Afar */
+  {"aae",      HB_TAG('S','Q','I',' ')},       /* Arbëreshë Albanian -> Albanian */
+  {"aao",      HB_TAG('A','R','A',' ')},       /* Algerian Saharan Arabic -> Arabic */
+  {"aat",      HB_TAG('S','Q','I',' ')},       /* Arvanitika Albanian -> Albanian */
+  {"ab",       HB_TAG('A','B','K',' ')},       /* Abkhazian */
+  {"abh",      HB_TAG('A','R','A',' ')},       /* Tajiki Arabic -> Arabic */
+  {"abq",      HB_TAG('A','B','A',' ')},       /* Abaza */
+  {"abv",      HB_TAG('A','R','A',' ')},       /* Baharna Arabic -> Arabic */
+  {"acf",      HB_TAG('F','A','N',' ')},       /* Saint Lucian Creole French -> French Antillean */
+/*{"ach",      HB_TAG('A','C','H',' ')},*/     /* Acoli -> Acholi */
+  {"acm",      HB_TAG('A','R','A',' ')},       /* Mesopotamian Arabic -> Arabic */
+  {"acq",      HB_TAG('A','R','A',' ')},       /* Ta'izzi-Adeni Arabic -> Arabic */
+/*{"acr",      HB_TAG('A','C','R',' ')},*/     /* Achi */
+  {"acw",      HB_TAG('A','R','A',' ')},       /* Hijazi Arabic -> Arabic */
+  {"acx",      HB_TAG('A','R','A',' ')},       /* Omani Arabic -> Arabic */
+  {"acy",      HB_TAG('A','R','A',' ')},       /* Cypriot Arabic -> Arabic */
+  {"ada",      HB_TAG('D','N','G',' ')},       /* Adangme -> Dangme */
+  {"adf",      HB_TAG('A','R','A',' ')},       /* Dhofari Arabic -> Arabic */
+  {"adp",      HB_TAG('D','Z','N',' ')},       /* Adap (retired code) -> Dzongkha */
+/*{"ady",      HB_TAG('A','D','Y',' ')},*/     /* Adyghe */
+  {"aeb",      HB_TAG('A','R','A',' ')},       /* Tunisian Arabic -> Arabic */
+  {"aec",      HB_TAG('A','R','A',' ')},       /* Saidi Arabic -> Arabic */
+  {"af",       HB_TAG('A','F','K',' ')},       /* Afrikaans */
+  {"afb",      HB_TAG('A','R','A',' ')},       /* Gulf Arabic -> Arabic */
+  {"ahg",      HB_TAG('A','G','W',' ')},       /* Qimant -> Agaw */
+  {"aht",      HB_TAG('A','T','H',' ')},       /* Ahtena -> Athapaskan */
+  {"aii",      HB_TAG('S','W','A',' ')},       /* Assyrian Neo-Aramaic -> Swadaya Aramaic */
+  {"aii",      HB_TAG('S','Y','R',' ')},       /* Assyrian Neo-Aramaic -> Syriac */
+/*{"aio",      HB_TAG('A','I','O',' ')},*/     /* Aiton */
+  {"aiw",      HB_TAG('A','R','I',' ')},       /* Aari */
+  {"ajp",      HB_TAG('A','R','A',' ')},       /* South Levantine Arabic -> Arabic */
+  {"ak",       HB_TAG('A','K','A',' ')},       /* Akan [macrolanguage] */
+  {"ak",       HB_TAG('T','W','I',' ')},       /* Akan [macrolanguage] -> Twi */
+  {"aln",      HB_TAG('S','Q','I',' ')},       /* Gheg Albanian -> Albanian */
+  {"als",      HB_TAG('S','Q','I',' ')},       /* Tosk Albanian -> Albanian */
+/*{"alt",      HB_TAG('A','L','T',' ')},*/     /* Southern Altai -> Altai */
+  {"am",       HB_TAG('A','M','H',' ')},       /* Amharic */
+  {"amf",      HB_TAG('H','B','N',' ')},       /* Hamer-Banna -> Hammer-Banna */
+  {"amw",      HB_TAG('S','Y','R',' ')},       /* Western Neo-Aramaic -> Syriac */
+  {"an",       HB_TAG('A','R','G',' ')},       /* Aragonese */
+/*{"ang",      HB_TAG('A','N','G',' ')},*/     /* Old English (ca. 450-1100) -> Anglo-Saxon */
+  {"apc",      HB_TAG('A','R','A',' ')},       /* North Levantine Arabic -> Arabic */
+  {"apd",      HB_TAG('A','R','A',' ')},       /* Sudanese Arabic -> Arabic */
+  {"apj",      HB_TAG('A','T','H',' ')},       /* Jicarilla Apache -> Athapaskan */
+  {"apk",      HB_TAG('A','T','H',' ')},       /* Kiowa Apache -> Athapaskan */
+  {"apl",      HB_TAG('A','T','H',' ')},       /* Lipan Apache -> Athapaskan */
+  {"apm",      HB_TAG('A','T','H',' ')},       /* Mescalero-Chiricahua Apache -> Athapaskan */
+  {"apw",      HB_TAG('A','T','H',' ')},       /* Western Apache -> Athapaskan */
+  {"ar",       HB_TAG('A','R','A',' ')},       /* Arabic [macrolanguage] */
+  {"arb",      HB_TAG('A','R','A',' ')},       /* Standard Arabic -> Arabic */
+  {"arn",      HB_TAG('M','A','P',' ')},       /* Mapudungun */
+  {"arq",      HB_TAG('A','R','A',' ')},       /* Algerian Arabic -> Arabic */
+  {"ars",      HB_TAG('A','R','A',' ')},       /* Najdi Arabic -> Arabic */
+  {"ary",      HB_TAG('M','O','R',' ')},       /* Moroccan Arabic -> Moroccan */
+  {"arz",      HB_TAG('A','R','A',' ')},       /* Egyptian Arabic -> Arabic */
+  {"as",       HB_TAG('A','S','M',' ')},       /* Assamese */
+/*{"ast",      HB_TAG('A','S','T',' ')},*/     /* Asturian */
+/*{"ath",      HB_TAG('A','T','H',' ')},*/     /* Athapascan [family] -> Athapaskan */
+  {"atj",      HB_TAG('R','C','R',' ')},       /* Atikamekw -> R-Cree */
+  {"atv",      HB_TAG('A','L','T',' ')},       /* Northern Altai -> Altai */
+  {"auz",      HB_TAG('A','R','A',' ')},       /* Uzbeki Arabic -> Arabic */
+  {"av",       HB_TAG('A','V','R',' ')},       /* Avaric -> Avar */
+  {"avl",      HB_TAG('A','R','A',' ')},       /* Eastern Egyptian Bedawi Arabic -> Arabic */
+/*{"awa",      HB_TAG('A','W','A',' ')},*/     /* Awadhi */
+  {"ay",       HB_TAG('A','Y','M',' ')},       /* Aymara [macrolanguage] */
+  {"ayc",      HB_TAG('A','Y','M',' ')},       /* Southern Aymara -> Aymara */
+  {"ayh",      HB_TAG('A','R','A',' ')},       /* Hadrami Arabic -> Arabic */
+  {"ayl",      HB_TAG('A','R','A',' ')},       /* Libyan Arabic -> Arabic */
+  {"ayn",      HB_TAG('A','R','A',' ')},       /* Sanaani Arabic -> Arabic */
+  {"ayp",      HB_TAG('A','R','A',' ')},       /* North Mesopotamian Arabic -> Arabic */
+  {"ayr",      HB_TAG('A','Y','M',' ')},       /* Central Aymara -> Aymara */
+  {"az",       HB_TAG('A','Z','E',' ')},       /* Azerbaijani [macrolanguage] */
+/*{"azb",      HB_TAG('A','Z','B',' ')},*/     /* South Azerbaijani -> Torki */
+  {"azj",      HB_TAG('A','Z','E',' ')},       /* North Azerbaijani -> Azerbaijani */
+  {"ba",       HB_TAG('B','S','H',' ')},       /* Bashkir */
+  {"bad",      HB_TAG('B','A','D','0')},       /* Banda [family] */
+  {"bai",      HB_TAG('B','M','L',' ')},       /* Bamileke [family] */
+  {"bal",      HB_TAG('B','L','I',' ')},       /* Baluchi [macrolanguage] */
+/*{"ban",      HB_TAG('B','A','N',' ')},*/     /* Balinese */
+/*{"bar",      HB_TAG('B','A','R',' ')},*/     /* Bavarian */
+/*{"bbc",      HB_TAG('B','B','C',' ')},*/     /* Batak Toba */
+  {"bbz",      HB_TAG('A','R','A',' ')},       /* Babalia Creole Arabic -> Arabic */
+  {"bcc",      HB_TAG('B','L','I',' ')},       /* Southern Balochi -> Baluchi */
+  {"bci",      HB_TAG('B','A','U',' ')},       /* Baoulé -> Baulé */
+  {"bcl",      HB_TAG('B','I','K',' ')},       /* Central Bikol -> Bikol */
+  {"bcq",      HB_TAG('B','C','H',' ')},       /* Bench */
+  {"bcr",      HB_TAG('A','T','H',' ')},       /* Babine -> Athapaskan */
+/*{"bdy",      HB_TAG('B','D','Y',' ')},*/     /* Bandjalang */
+  {"be",       HB_TAG('B','E','L',' ')},       /* Belarusian -> Belarussian */
+  {"bea",      HB_TAG('A','T','H',' ')},       /* Beaver -> Athapaskan */
+  {"beb",      HB_TAG('B','T','I',' ')},       /* Bebele -> Beti */
+/*{"bem",      HB_TAG('B','E','M',' ')},*/     /* Bemba (Zambia) */
+  {"ber",      HB_TAG('B','B','R',' ')},       /* Berber [family] */
+  {"bfq",      HB_TAG('B','A','D',' ')},       /* Badaga */
+  {"bft",      HB_TAG('B','L','T',' ')},       /* Balti */
+  {"bfu",      HB_TAG('L','A','H',' ')},       /* Gahri -> Lahuli */
+  {"bfy",      HB_TAG('B','A','G',' ')},       /* Bagheli -> Baghelkhandi */
+  {"bg",       HB_TAG('B','G','R',' ')},       /* Bulgarian */
+/*{"bgc",      HB_TAG('B','G','C',' ')},*/     /* Haryanvi */
+  {"bgn",      HB_TAG('B','L','I',' ')},       /* Western Balochi -> Baluchi */
+  {"bgp",      HB_TAG('B','L','I',' ')},       /* Eastern Balochi -> Baluchi */
+/*{"bgq",      HB_TAG('B','G','Q',' ')},*/     /* Bagri */
+  {"bgr",      HB_TAG('Q','I','N',' ')},       /* Bawm Chin -> Chin */
+  {"bhb",      HB_TAG('B','H','I',' ')},       /* Bhili */
+/*{"bhi",      HB_TAG('B','H','I',' ')},*/     /* Bhilali -> Bhili */
+  {"bhk",      HB_TAG('B','I','K',' ')},       /* Albay Bicolano (retired code) -> Bikol */
+/*{"bho",      HB_TAG('B','H','O',' ')},*/     /* Bhojpuri */
+  {"bhr",      HB_TAG('M','L','G',' ')},       /* Bara Malagasy -> Malagasy */
+  {"bi",       HB_TAG('B','I','S',' ')},       /* Bislama */
+/*{"bik",      HB_TAG('B','I','K',' ')},*/     /* Bikol [macrolanguage] */
+  {"bin",      HB_TAG('E','D','O',' ')},       /* Edo */
+/*{"bjj",      HB_TAG('B','J','J',' ')},*/     /* Kanauji */
+  {"bjn",      HB_TAG('M','L','Y',' ')},       /* Banjar -> Malay */
+  {"bjq",      HB_TAG('M','L','G',' ')},       /* Southern Betsimisaraka Malagasy (retired code) -> Malagasy */
+  {"bjt",      HB_TAG('B','L','N',' ')},       /* Balanta-Ganja -> Balante */
+  {"bla",      HB_TAG('B','K','F',' ')},       /* Siksika -> Blackfoot */
+  {"ble",      HB_TAG('B','L','N',' ')},       /* Balanta-Kentohe -> Balante */
+/*{"blk",      HB_TAG('B','L','K',' ')},*/     /* Pa’o Karen */
+  {"bln",      HB_TAG('B','I','K',' ')},       /* Southern Catanduanes Bikol -> Bikol */
+  {"bm",       HB_TAG('B','M','B',' ')},       /* Bambara (Bamanankan) */
+  {"bmm",      HB_TAG('M','L','G',' ')},       /* Northern Betsimisaraka Malagasy -> Malagasy */
+  {"bn",       HB_TAG('B','E','N',' ')},       /* Bengali */
+  {"bo",       HB_TAG('T','I','B',' ')},       /* Tibetan */
+/*{"bpy",      HB_TAG('B','P','Y',' ')},*/     /* Bishnupriya -> Bishnupriya Manipuri */
+  {"bqi",      HB_TAG('L','R','C',' ')},       /* Bakhtiari -> Luri */
+  {"br",       HB_TAG('B','R','E',' ')},       /* Breton */
+  {"bra",      HB_TAG('B','R','I',' ')},       /* Braj -> Braj Bhasha */
+/*{"brh",      HB_TAG('B','R','H',' ')},*/     /* Brahui */
+/*{"brx",      HB_TAG('B','R','X',' ')},*/     /* Bodo (India) */
+  {"bs",       HB_TAG('B','O','S',' ')},       /* Bosnian */
+/*{"bsk",      HB_TAG('B','S','K',' ')},*/     /* Burushaski */
+  {"btb",      HB_TAG('B','T','I',' ')},       /* Beti (Cameroon) (retired code) */
+  {"btj",      HB_TAG('M','L','Y',' ')},       /* Bacanese Malay -> Malay */
+  {"bto",      HB_TAG('B','I','K',' ')},       /* Rinconada Bikol -> Bikol */
+/*{"bts",      HB_TAG('B','T','S',' ')},*/     /* Batak Simalungun */
+/*{"bug",      HB_TAG('B','U','G',' ')},*/     /* Buginese -> Bugis */
+  {"bum",      HB_TAG('B','T','I',' ')},       /* Bulu (Cameroon) -> Beti */
+  {"bve",      HB_TAG('M','L','Y',' ')},       /* Berau Malay -> Malay */
+  {"bvu",      HB_TAG('M','L','Y',' ')},       /* Bukit Malay -> Malay */
+  {"bxk",      HB_TAG('L','U','H',' ')},       /* Bukusu -> Luyia */
+  {"bxp",      HB_TAG('B','T','I',' ')},       /* Bebil -> Beti */
+  {"bxr",      HB_TAG('R','B','U',' ')},       /* Russia Buriat -> Russian Buriat */
+  {"byn",      HB_TAG('B','I','L',' ')},       /* Bilin -> Bilen */
+/*{"byv",      HB_TAG('B','Y','V',' ')},*/     /* Medumba */
+  {"bzc",      HB_TAG('M','L','G',' ')},       /* Southern Betsimisaraka Malagasy -> Malagasy */
+  {"ca",       HB_TAG('C','A','T',' ')},       /* Catalan */
+  {"caf",      HB_TAG('C','R','R',' ')},       /* Southern Carrier -> Carrier */
+  {"caf",      HB_TAG('A','T','H',' ')},       /* Southern Carrier -> Athapaskan */
+/*{"cak",      HB_TAG('C','A','K',' ')},*/     /* Kaqchikel */
+/*{"cbk",      HB_TAG('C','B','K',' ')},*/     /* Chavacano -> Zamboanga Chavacano */
+  {"cbl",      HB_TAG('Q','I','N',' ')},       /* Bualkhaw Chin -> Chin */
+  {"cco",      HB_TAG('C','C','H','N')},       /* Comaltepec Chinantec -> Chinantec */
+  {"ccq",      HB_TAG('A','R','K',' ')},       /* Chaungtha (retired code) -> Rakhine */
+  {"cdo",      HB_TAG('Z','H','S',' ')},       /* Min Dong Chinese -> Chinese Simplified */
+  {"ce",       HB_TAG('C','H','E',' ')},       /* Chechen */
+/*{"ceb",      HB_TAG('C','E','B',' ')},*/     /* Cebuano */
+  {"cfm",      HB_TAG('H','A','L',' ')},       /* Halam (Falam Chin) */
+/*{"cgg",      HB_TAG('C','G','G',' ')},*/     /* Chiga */
+  {"ch",       HB_TAG('C','H','A',' ')},       /* Chamorro */
+  {"chj",      HB_TAG('C','C','H','N')},       /* Ojitlán Chinantec -> Chinantec */
+  {"chk",      HB_TAG('C','H','K','0')},       /* Chuukese */
+/*{"cho",      HB_TAG('C','H','O',' ')},*/     /* Choctaw */
+  {"chp",      HB_TAG('C','H','P',' ')},       /* Chipewyan */
+  {"chp",      HB_TAG('S','A','Y',' ')},       /* Chipewyan -> Sayisi */
+  {"chp",      HB_TAG('A','T','H',' ')},       /* Chipewyan -> Athapaskan */
+  {"chq",      HB_TAG('C','C','H','N')},       /* Quiotepec Chinantec -> Chinantec */
+/*{"chr",      HB_TAG('C','H','R',' ')},*/     /* Cherokee */
+/*{"chy",      HB_TAG('C','H','Y',' ')},*/     /* Cheyenne */
+  {"chz",      HB_TAG('C','C','H','N')},       /* Ozumacín Chinantec -> Chinantec */
+  {"ciw",      HB_TAG('O','J','B',' ')},       /* Chippewa -> Ojibway */
+/*{"cja",      HB_TAG('C','J','A',' ')},*/     /* Western Cham */
+/*{"cjm",      HB_TAG('C','J','M',' ')},*/     /* Eastern Cham */
+  {"cjy",      HB_TAG('Z','H','S',' ')},       /* Jinyu Chinese -> Chinese Simplified */
+  {"cka",      HB_TAG('Q','I','N',' ')},       /* Khumi Awa Chin (retired code) -> Chin */
+  {"ckb",      HB_TAG('K','U','R',' ')},       /* Central Kurdish -> Kurdish */
+  {"ckt",      HB_TAG('C','H','K',' ')},       /* Chukot -> Chukchi */
+  {"clc",      HB_TAG('A','T','H',' ')},       /* Chilcotin -> Athapaskan */
+  {"cld",      HB_TAG('S','Y','R',' ')},       /* Chaldean Neo-Aramaic -> Syriac */
+  {"cle",      HB_TAG('C','C','H','N')},       /* Lealao Chinantec -> Chinantec */
+  {"cmn",      HB_TAG('Z','H','S',' ')},       /* Mandarin Chinese -> Chinese Simplified */
+  {"cmr",      HB_TAG('Q','I','N',' ')},       /* Mro-Khimi Chin -> Chin */
+  {"cnb",      HB_TAG('Q','I','N',' ')},       /* Chinbon Chin -> Chin */
+  {"cnh",      HB_TAG('Q','I','N',' ')},       /* Hakha Chin -> Chin */
+  {"cnk",      HB_TAG('Q','I','N',' ')},       /* Khumi Chin -> Chin */
+  {"cnl",      HB_TAG('C','C','H','N')},       /* Lalana Chinantec -> Chinantec */
+  {"cnt",      HB_TAG('C','C','H','N')},       /* Tepetotutla Chinantec -> Chinantec */
+  {"cnw",      HB_TAG('Q','I','N',' ')},       /* Ngawn Chin -> Chin */
+  {"co",       HB_TAG('C','O','S',' ')},       /* Corsican */
+  {"coa",      HB_TAG('M','L','Y',' ')},       /* Cocos Islands Malay -> Malay */
+/*{"cop",      HB_TAG('C','O','P',' ')},*/     /* Coptic */
+  {"coq",      HB_TAG('A','T','H',' ')},       /* Coquille -> Athapaskan */
+  {"cpa",      HB_TAG('C','C','H','N')},       /* Palantla Chinantec -> Chinantec */
+  {"cpe",      HB_TAG('C','P','P',' ')},       /* English-based creoles and pidgins [family] -> Creoles */
+  {"cpf",      HB_TAG('C','P','P',' ')},       /* French-based creoles and pidgins [family] -> Creoles */
+/*{"cpp",      HB_TAG('C','P','P',' ')},*/     /* Portuguese-based creoles and pidgins [family] -> Creoles */
+  {"cpx",      HB_TAG('Z','H','S',' ')},       /* Pu-Xian Chinese -> Chinese Simplified */
+  {"cqd",      HB_TAG('H','M','N',' ')},       /* Chuanqiandian Cluster Miao -> Hmong */
+  {"cqu",      HB_TAG('Q','U','H',' ')},       /* Chilean Quechua (retired code) -> Quechua (Bolivia) */
+  {"cr",       HB_TAG('C','R','E',' ')},       /* Cree [macrolanguage] */
+  {"cr",       HB_TAG('Y','C','R',' ')},       /* Cree [macrolanguage] -> Y-Cree */
+  {"crh",      HB_TAG('C','R','T',' ')},       /* Crimean Tatar */
+  {"crj",      HB_TAG('E','C','R',' ')},       /* Southern East Cree -> Eastern Cree */
+  {"crk",      HB_TAG('W','C','R',' ')},       /* Plains Cree -> West-Cree */
+  {"crl",      HB_TAG('E','C','R',' ')},       /* Northern East Cree -> Eastern Cree */
+  {"crm",      HB_TAG('M','C','R',' ')},       /* Moose Cree */
+  {"crm",      HB_TAG('L','C','R',' ')},       /* Moose Cree -> L-Cree */
+  {"crp",      HB_TAG('C','P','P',' ')},       /* Creoles and pidgins [family] -> Creoles */
+  {"crx",      HB_TAG('C','R','R',' ')},       /* Carrier */
+  {"crx",      HB_TAG('A','T','H',' ')},       /* Carrier -> Athapaskan */
+  {"cs",       HB_TAG('C','S','Y',' ')},       /* Czech */
+  {"csa",      HB_TAG('C','C','H','N')},       /* Chiltepec Chinantec -> Chinantec */
+/*{"csb",      HB_TAG('C','S','B',' ')},*/     /* Kashubian */
+  {"csh",      HB_TAG('Q','I','N',' ')},       /* Asho Chin -> Chin */
+  {"cso",      HB_TAG('C','C','H','N')},       /* Sochiapam Chinantec -> Chinantec */
+  {"csw",      HB_TAG('N','C','R',' ')},       /* Swampy Cree -> N-Cree */
+  {"csw",      HB_TAG('N','H','C',' ')},       /* Swampy Cree -> Norway House Cree */
+  {"csy",      HB_TAG('Q','I','N',' ')},       /* Siyin Chin -> Chin */
+  {"ctc",      HB_TAG('A','T','H',' ')},       /* Chetco -> Athapaskan */
+  {"ctd",      HB_TAG('Q','I','N',' ')},       /* Tedim Chin -> Chin */
+  {"cte",      HB_TAG('C','C','H','N')},       /* Tepinapa Chinantec -> Chinantec */
+/*{"ctg",      HB_TAG('C','T','G',' ')},*/     /* Chittagonian */
+  {"ctl",      HB_TAG('C','C','H','N')},       /* Tlacoatzintepec Chinantec -> Chinantec */
+  {"cts",      HB_TAG('B','I','K',' ')},       /* Northern Catanduanes Bikol -> Bikol */
+  {"cu",       HB_TAG('C','S','L',' ')},       /* Church Slavonic */
+  {"cuc",      HB_TAG('C','C','H','N')},       /* Usila Chinantec -> Chinantec */
+/*{"cuk",      HB_TAG('C','U','K',' ')},*/     /* San Blas Kuna */
+  {"cv",       HB_TAG('C','H','U',' ')},       /* Chuvash */
+  {"cvn",      HB_TAG('C','C','H','N')},       /* Valle Nacional Chinantec -> Chinantec */
+  {"cwd",      HB_TAG('D','C','R',' ')},       /* Woods Cree */
+  {"cwd",      HB_TAG('T','C','R',' ')},       /* Woods Cree -> TH-Cree */
+  {"cy",       HB_TAG('W','E','L',' ')},       /* Welsh */
+  {"czh",      HB_TAG('Z','H','S',' ')},       /* Huizhou Chinese -> Chinese Simplified */
+  {"czo",      HB_TAG('Z','H','S',' ')},       /* Min Zhong Chinese -> Chinese Simplified */
+  {"czt",      HB_TAG('Q','I','N',' ')},       /* Zotung Chin -> Chin */
+  {"da",       HB_TAG('D','A','N',' ')},       /* Danish */
+  {"dao",      HB_TAG('Q','I','N',' ')},       /* Daai Chin -> Chin */
+  {"dap",      HB_TAG('N','I','S',' ')},       /* Nisi (India) (retired code) */
+/*{"dar",      HB_TAG('D','A','R',' ')},*/     /* Dargwa */
+/*{"dax",      HB_TAG('D','A','X',' ')},*/     /* Dayi */
+  {"de",       HB_TAG('D','E','U',' ')},       /* German */
+  {"den",      HB_TAG('S','L','A',' ')},       /* Slave (Athapascan) [macrolanguage] -> Slavey */
+  {"den",      HB_TAG('A','T','H',' ')},       /* Slave (Athapascan) [macrolanguage] -> Athapaskan */
+/*{"dgo",      HB_TAG('D','G','O',' ')},*/     /* Dogri */
+  {"dgr",      HB_TAG('A','T','H',' ')},       /* Dogrib -> Athapaskan */
+  {"dhd",      HB_TAG('M','A','W',' ')},       /* Dhundari -> Marwari */
+/*{"dhg",      HB_TAG('D','H','G',' ')},*/     /* Dhangu */
+  {"dib",      HB_TAG('D','N','K',' ')},       /* South Central Dinka -> Dinka */
+  {"dik",      HB_TAG('D','N','K',' ')},       /* Southwestern Dinka -> Dinka */
+  {"din",      HB_TAG('D','N','K',' ')},       /* Dinka [macrolanguage] */
+  {"dip",      HB_TAG('D','N','K',' ')},       /* Northeastern Dinka -> Dinka */
+/*{"diq",      HB_TAG('D','I','Q',' ')},*/     /* Dimli */
+  {"diw",      HB_TAG('D','N','K',' ')},       /* Northwestern Dinka -> Dinka */
+  {"dje",      HB_TAG('D','J','R',' ')},       /* Zarma */
+  {"djr",      HB_TAG('D','J','R','0')},       /* Djambarrpuyngu */
+  {"dks",      HB_TAG('D','N','K',' ')},       /* Southeastern Dinka -> Dinka */
+  {"dng",      HB_TAG('D','U','N',' ')},       /* Dungan */
+/*{"dnj",      HB_TAG('D','N','J',' ')},*/     /* Dan */
+  {"doi",      HB_TAG('D','G','R',' ')},       /* Dogri [macrolanguage] */
+  {"drh",      HB_TAG('M','N','G',' ')},       /* Darkhat (retired code) -> Mongolian */
+  {"drw",      HB_TAG('D','R','I',' ')},       /* Darwazi (retired code) -> Dari */
+  {"dsb",      HB_TAG('L','S','B',' ')},       /* Lower Sorbian */
+  {"dty",      HB_TAG('N','E','P',' ')},       /* Dotyali -> Nepali */
+/*{"duj",      HB_TAG('D','U','J',' ')},*/     /* Dhuwal (retired code) */
+  {"dup",      HB_TAG('M','L','Y',' ')},       /* Duano -> Malay */
+  {"dv",       HB_TAG('D','I','V',' ')},       /* Divehi (Dhivehi, Maldivian) */
+  {"dv",       HB_TAG('D','H','V',' ')},       /* Divehi (Dhivehi, Maldivian) (deprecated) */
+  {"dwu",      HB_TAG('D','U','J',' ')},       /* Dhuwal */
+  {"dwy",      HB_TAG('D','U','J',' ')},       /* Dhuwaya -> Dhuwal */
+  {"dyu",      HB_TAG('J','U','L',' ')},       /* Dyula -> Jula */
+  {"dz",       HB_TAG('D','Z','N',' ')},       /* Dzongkha */
+  {"ee",       HB_TAG('E','W','E',' ')},       /* Ewe */
+/*{"efi",      HB_TAG('E','F','I',' ')},*/     /* Efik */
+  {"ekk",      HB_TAG('E','T','I',' ')},       /* Standard Estonian -> Estonian */
+  {"el",       HB_TAG('E','L','L',' ')},       /* Modern Greek (1453-) -> Greek */
+  {"emk",      HB_TAG('E','M','K',' ')},       /* Eastern Maninkakan */
+  {"emk",      HB_TAG('M','N','K',' ')},       /* Eastern Maninkakan -> Maninka */
+  {"en",       HB_TAG('E','N','G',' ')},       /* English */
+  {"enb",      HB_TAG('K','A','L',' ')},       /* Markweeta -> Kalenjin */
+  {"enf",      HB_TAG('F','N','E',' ')},       /* Forest Enets -> Forest Nenets */
+  {"enh",      HB_TAG('T','N','E',' ')},       /* Tundra Enets -> Tundra Nenets */
+  {"eo",       HB_TAG('N','T','O',' ')},       /* Esperanto */
+  {"es",       HB_TAG('E','S','P',' ')},       /* Spanish */
+  {"esg",      HB_TAG('G','O','N',' ')},       /* Aheri Gondi -> Gondi */
+  {"esi",      HB_TAG('I','P','K',' ')},       /* North Alaskan Inupiatun -> Inupiat */
+  {"esk",      HB_TAG('I','P','K',' ')},       /* Northwest Alaska Inupiatun -> Inupiat */
+/*{"esu",      HB_TAG('E','S','U',' ')},*/     /* Central Yupik */
+  {"et",       HB_TAG('E','T','I',' ')},       /* Estonian [macrolanguage] */
+  {"eto",      HB_TAG('B','T','I',' ')},       /* Eton (Cameroon) -> Beti */
+  {"eu",       HB_TAG('E','U','Q',' ')},       /* Basque */
+  {"eve",      HB_TAG('E','V','N',' ')},       /* Even */
+  {"evn",      HB_TAG('E','V','K',' ')},       /* Evenki */
+  {"ewo",      HB_TAG('B','T','I',' ')},       /* Ewondo -> Beti */
+  {"eyo",      HB_TAG('K','A','L',' ')},       /* Keiyo -> Kalenjin */
+  {"fa",       HB_TAG('F','A','R',' ')},       /* Persian [macrolanguage] */
+  {"fan",      HB_TAG('F','A','N','0')},       /* Fang (Equatorial Guinea) */
+/*{"fat",      HB_TAG('F','A','T',' ')},*/     /* Fanti */
+  {"fbl",      HB_TAG('B','I','K',' ')},       /* West Albay Bikol -> Bikol */
+  {"ff",       HB_TAG('F','U','L',' ')},       /* Fulah [macrolanguage] */
+  {"ffm",      HB_TAG('F','U','L',' ')},       /* Maasina Fulfulde -> Fulah */
+  {"fi",       HB_TAG('F','I','N',' ')},       /* Finnish */
+  {"fil",      HB_TAG('P','I','L',' ')},       /* Filipino */
+  {"fj",       HB_TAG('F','J','I',' ')},       /* Fijian */
+  {"flm",      HB_TAG('H','A','L',' ')},       /* Halam (Falam Chin) (retired code) */
+  {"flm",      HB_TAG('Q','I','N',' ')},       /* Falam Chin (retired code) -> Chin */
+/*{"fmp",      HB_TAG('F','M','P',' ')},*/     /* Fe’fe’ */
+  {"fo",       HB_TAG('F','O','S',' ')},       /* Faroese */
+/*{"fon",      HB_TAG('F','O','N',' ')},*/     /* Fon */
+  {"fr",       HB_TAG('F','R','A',' ')},       /* French */
+/*{"frc",      HB_TAG('F','R','C',' ')},*/     /* Cajun French */
+/*{"frp",      HB_TAG('F','R','P',' ')},*/     /* Arpitan */
+  {"fub",      HB_TAG('F','U','L',' ')},       /* Adamawa Fulfulde -> Fulah */
+  {"fuc",      HB_TAG('F','U','L',' ')},       /* Pulaar -> Fulah */
+  {"fue",      HB_TAG('F','U','L',' ')},       /* Borgu Fulfulde -> Fulah */
+  {"fuf",      HB_TAG('F','T','A',' ')},       /* Pular -> Futa */
+  {"fuh",      HB_TAG('F','U','L',' ')},       /* Western Niger Fulfulde -> Fulah */
+  {"fui",      HB_TAG('F','U','L',' ')},       /* Bagirmi Fulfulde -> Fulah */
+  {"fuq",      HB_TAG('F','U','L',' ')},       /* Central-Eastern Niger Fulfulde -> Fulah */
+  {"fur",      HB_TAG('F','R','L',' ')},       /* Friulian */
+/*{"fuv",      HB_TAG('F','U','V',' ')},*/     /* Nigerian Fulfulde */
+  {"fy",       HB_TAG('F','R','I',' ')},       /* Western Frisian -> Frisian */
+  {"ga",       HB_TAG('I','R','I',' ')},       /* Irish */
+  {"gaa",      HB_TAG('G','A','D',' ')},       /* Ga */
+/*{"gag",      HB_TAG('G','A','G',' ')},*/     /* Gagauz */
+  {"gan",      HB_TAG('Z','H','S',' ')},       /* Gan Chinese -> Chinese Simplified */
+  {"gax",      HB_TAG('O','R','O',' ')},       /* Borana-Arsi-Guji Oromo -> Oromo */
+  {"gaz",      HB_TAG('O','R','O',' ')},       /* West Central Oromo -> Oromo */
+  {"gbm",      HB_TAG('G','A','W',' ')},       /* Garhwali */
+  {"gce",      HB_TAG('A','T','H',' ')},       /* Galice -> Athapaskan */
+  {"gd",       HB_TAG('G','A','E',' ')},       /* Scottish Gaelic (Gaelic) */
+  {"gda",      HB_TAG('R','A','J',' ')},       /* Gade Lohar -> Rajasthani */
+/*{"gez",      HB_TAG('G','E','Z',' ')},*/     /* Geez */
+  {"ggo",      HB_TAG('G','O','N',' ')},       /* Southern Gondi (retired code) -> Gondi */
+/*{"gih",      HB_TAG('G','I','H',' ')},*/     /* Githabul */
+  {"gil",      HB_TAG('G','I','L','0')},       /* Kiribati (Gilbertese) */
+  {"gju",      HB_TAG('R','A','J',' ')},       /* Gujari -> Rajasthani */
+/*{"gkp",      HB_TAG('G','K','P',' ')},*/     /* Guinea Kpelle -> Kpelle (Guinea) */
+  {"gl",       HB_TAG('G','A','L',' ')},       /* Galician */
+  {"gld",      HB_TAG('N','A','N',' ')},       /* Nanai */
+/*{"glk",      HB_TAG('G','L','K',' ')},*/     /* Gilaki */
+  {"gn",       HB_TAG('G','U','A',' ')},       /* Guarani [macrolanguage] */
+/*{"gnn",      HB_TAG('G','N','N',' ')},*/     /* Gumatj */
+  {"gno",      HB_TAG('G','O','N',' ')},       /* Northern Gondi -> Gondi */
+  {"gnw",      HB_TAG('G','U','A',' ')},       /* Western Bolivian Guaraní -> Guarani */
+/*{"gog",      HB_TAG('G','O','G',' ')},*/     /* Gogo */
+  {"gom",      HB_TAG('K','O','K',' ')},       /* Goan Konkani -> Konkani */
+/*{"gon",      HB_TAG('G','O','N',' ')},*/     /* Gondi [macrolanguage] */
+  {"grt",      HB_TAG('G','R','O',' ')},       /* Garo */
+  {"gru",      HB_TAG('S','O','G',' ')},       /* Kistane -> Sodo Gurage */
+  {"gsw",      HB_TAG('A','L','S',' ')},       /* Alsatian */
+  {"gu",       HB_TAG('G','U','J',' ')},       /* Gujarati */
+/*{"guc",      HB_TAG('G','U','C',' ')},*/     /* Wayuu */
+/*{"guf",      HB_TAG('G','U','F',' ')},*/     /* Gupapuyngu */
+  {"gug",      HB_TAG('G','U','A',' ')},       /* Paraguayan Guaraní -> Guarani */
+  {"gui",      HB_TAG('G','U','A',' ')},       /* Eastern Bolivian Guaraní -> Guarani */
+  {"guk",      HB_TAG('G','M','Z',' ')},       /* Gumuz */
+  {"guk",      HB_TAG('G','U','K',' ')},       /* Gumuz (SIL fonts) */
+  {"gun",      HB_TAG('G','U','A',' ')},       /* Mbyá Guaraní -> Guarani */
+/*{"guz",      HB_TAG('G','U','Z',' ')},*/     /* Gusii */
+  {"gv",       HB_TAG('M','N','X',' ')},       /* Manx */
+  {"gwi",      HB_TAG('A','T','H',' ')},       /* Gwichʼin -> Athapaskan */
+  {"ha",       HB_TAG('H','A','U',' ')},       /* Hausa */
+  {"haa",      HB_TAG('A','T','H',' ')},       /* Han -> Athapaskan */
+  {"hae",      HB_TAG('O','R','O',' ')},       /* Eastern Oromo -> Oromo */
+  {"hak",      HB_TAG('Z','H','S',' ')},       /* Hakka Chinese -> Chinese Simplified */
+  {"har",      HB_TAG('H','R','I',' ')},       /* Harari */
+/*{"haw",      HB_TAG('H','A','W',' ')},*/     /* Hawaiian */
+/*{"hay",      HB_TAG('H','A','Y',' ')},*/     /* Haya */
+/*{"haz",      HB_TAG('H','A','Z',' ')},*/     /* Hazaragi */
+  {"he",       HB_TAG('I','W','R',' ')},       /* Hebrew */
+  {"hea",      HB_TAG('H','M','N',' ')},       /* Northern Qiandong Miao -> Hmong */
+  {"hi",       HB_TAG('H','I','N',' ')},       /* Hindi */
+/*{"hil",      HB_TAG('H','I','L',' ')},*/     /* Hiligaynon */
+  {"hji",      HB_TAG('M','L','Y',' ')},       /* Haji -> Malay */
+  {"hlt",      HB_TAG('Q','I','N',' ')},       /* Matu Chin -> Chin */
+  {"hma",      HB_TAG('H','M','N',' ')},       /* Southern Mashan Hmong -> Hmong */
+  {"hmc",      HB_TAG('H','M','N',' ')},       /* Central Huishui Hmong -> Hmong */
+  {"hmd",      HB_TAG('H','M','N',' ')},       /* Large Flowery Miao -> Hmong */
+  {"hme",      HB_TAG('H','M','N',' ')},       /* Eastern Huishui Hmong -> Hmong */
+  {"hmg",      HB_TAG('H','M','N',' ')},       /* Southwestern Guiyang Hmong -> Hmong */
+  {"hmh",      HB_TAG('H','M','N',' ')},       /* Southwestern Huishui Hmong -> Hmong */
+  {"hmi",      HB_TAG('H','M','N',' ')},       /* Northern Huishui Hmong -> Hmong */
+  {"hmj",      HB_TAG('H','M','N',' ')},       /* Ge -> Hmong */
+  {"hml",      HB_TAG('H','M','N',' ')},       /* Luopohe Hmong -> Hmong */
+  {"hmm",      HB_TAG('H','M','N',' ')},       /* Central Mashan Hmong -> Hmong */
+/*{"hmn",      HB_TAG('H','M','N',' ')},*/     /* Hmong [macrolanguage] */
+  {"hmp",      HB_TAG('H','M','N',' ')},       /* Northern Mashan Hmong -> Hmong */
+  {"hmq",      HB_TAG('H','M','N',' ')},       /* Eastern Qiandong Miao -> Hmong */
+  {"hms",      HB_TAG('H','M','N',' ')},       /* Southern Qiandong Miao -> Hmong */
+  {"hmw",      HB_TAG('H','M','N',' ')},       /* Western Mashan Hmong -> Hmong */
+  {"hmy",      HB_TAG('H','M','N',' ')},       /* Southern Guiyang Hmong -> Hmong */
+  {"hmz",      HB_TAG('H','M','N',' ')},       /* Hmong Shua -> Hmong */
+/*{"hnd",      HB_TAG('H','N','D',' ')},*/     /* Southern Hindko -> Hindko */
+  {"hne",      HB_TAG('C','H','H',' ')},       /* Chhattisgarhi -> Chattisgarhi */
+  {"hnj",      HB_TAG('H','M','N',' ')},       /* Hmong Njua -> Hmong */
+  {"hno",      HB_TAG('H','N','D',' ')},       /* Northern Hindko -> Hindko */
+  {"ho",       HB_TAG('H','M','O',' ')},       /* Hiri Motu */
+  {"hoc",      HB_TAG('H','O',' ',' ')},       /* Ho */
+  {"hoi",      HB_TAG('A','T','H',' ')},       /* Holikachuk -> Athapaskan */
+  {"hoj",      HB_TAG('H','A','R',' ')},       /* Hadothi -> Harauti */
+  {"hr",       HB_TAG('H','R','V',' ')},       /* Croatian */
+  {"hrm",      HB_TAG('H','M','N',' ')},       /* Horned Miao -> Hmong */
+  {"hsb",      HB_TAG('U','S','B',' ')},       /* Upper Sorbian */
+  {"hsn",      HB_TAG('Z','H','S',' ')},       /* Xiang Chinese -> Chinese Simplified */
+  {"ht",       HB_TAG('H','A','I',' ')},       /* Haitian (Haitian Creole) */
+  {"hu",       HB_TAG('H','U','N',' ')},       /* Hungarian */
+  {"huj",      HB_TAG('H','M','N',' ')},       /* Northern Guiyang Hmong -> Hmong */
+  {"hup",      HB_TAG('A','T','H',' ')},       /* Hupa -> Athapaskan */
+  {"hy",       HB_TAG('H','Y','E','0')},       /* Armenian -> Armenian East */
+  {"hy",       HB_TAG('H','Y','E',' ')},       /* Armenian */
+  {"hyw",      HB_TAG('H','Y','E',' ')},       /* Western Armenian -> Armenian */
+  {"hz",       HB_TAG('H','E','R',' ')},       /* Herero */
+  {"ia",       HB_TAG('I','N','A',' ')},       /* Interlingua (International Auxiliary Language Association) */
+/*{"iba",      HB_TAG('I','B','A',' ')},*/     /* Iban */
+/*{"ibb",      HB_TAG('I','B','B',' ')},*/     /* Ibibio */
+  {"id",       HB_TAG('I','N','D',' ')},       /* Indonesian */
+  {"ida",      HB_TAG('L','U','H',' ')},       /* Idakho-Isukha-Tiriki -> Luyia */
+  {"ie",       HB_TAG('I','L','E',' ')},       /* Interlingue */
+  {"ig",       HB_TAG('I','B','O',' ')},       /* Igbo */
+  {"igb",      HB_TAG('E','B','I',' ')},       /* Ebira */
+  {"ii",       HB_TAG('Y','I','M',' ')},       /* Sichuan Yi -> Yi Modern */
+  {"ijc",      HB_TAG('I','J','O',' ')},       /* Izon -> Ijo */
+/*{"ijo",      HB_TAG('I','J','O',' ')},*/     /* Ijo [family] */
+  {"ik",       HB_TAG('I','P','K',' ')},       /* Inupiaq [macrolanguage] -> Inupiat */
+  {"ike",      HB_TAG('I','N','U',' ')},       /* Eastern Canadian Inuktitut -> Inuktitut */
+  {"ikt",      HB_TAG('I','N','U',' ')},       /* Inuinnaqtun -> Inuktitut */
+/*{"ilo",      HB_TAG('I','L','O',' ')},*/     /* Iloko -> Ilokano */
+  {"in",       HB_TAG('I','N','D',' ')},       /* Indonesian (retired code) */
+  {"ing",      HB_TAG('A','T','H',' ')},       /* Degexit'an -> Athapaskan */
+  {"inh",      HB_TAG('I','N','G',' ')},       /* Ingush */
+  {"io",       HB_TAG('I','D','O',' ')},       /* Ido */
+  {"is",       HB_TAG('I','S','L',' ')},       /* Icelandic */
+  {"it",       HB_TAG('I','T','A',' ')},       /* Italian */
+  {"iu",       HB_TAG('I','N','U',' ')},       /* Inuktitut [macrolanguage] */
+  {"iw",       HB_TAG('I','W','R',' ')},       /* Hebrew (retired code) */
+  {"ja",       HB_TAG('J','A','N',' ')},       /* Japanese */
+  {"jak",      HB_TAG('M','L','Y',' ')},       /* Jakun -> Malay */
+/*{"jam",      HB_TAG('J','A','M',' ')},*/     /* Jamaican Creole English -> Jamaican Creole */
+  {"jax",      HB_TAG('M','L','Y',' ')},       /* Jambi Malay -> Malay */
+/*{"jbo",      HB_TAG('J','B','O',' ')},*/     /* Lojban */
+/*{"jct",      HB_TAG('J','C','T',' ')},*/     /* Krymchak */
+  {"ji",       HB_TAG('J','I','I',' ')},       /* Yiddish (retired code) */
+  {"jv",       HB_TAG('J','A','V',' ')},       /* Javanese */
+  {"jw",       HB_TAG('J','A','V',' ')},       /* Javanese (retired code) */
+  {"ka",       HB_TAG('K','A','T',' ')},       /* Georgian */
+  {"kaa",      HB_TAG('K','R','K',' ')},       /* Kara-Kalpak -> Karakalpak */
+  {"kab",      HB_TAG('K','A','B','0')},       /* Kabyle */
+  {"kam",      HB_TAG('K','M','B',' ')},       /* Kamba (Kenya) */
+  {"kar",      HB_TAG('K','R','N',' ')},       /* Karen [family] */
+  {"kbd",      HB_TAG('K','A','B',' ')},       /* Kabardian */
+  {"kby",      HB_TAG('K','N','R',' ')},       /* Manga Kanuri -> Kanuri */
+  {"kca",      HB_TAG('K','H','K',' ')},       /* Khanty -> Khanty-Kazim */
+  {"kca",      HB_TAG('K','H','S',' ')},       /* Khanty -> Khanty-Shurishkar */
+  {"kca",      HB_TAG('K','H','V',' ')},       /* Khanty -> Khanty-Vakhi */
+/*{"kde",      HB_TAG('K','D','E',' ')},*/     /* Makonde */
+  {"kdr",      HB_TAG('K','R','M',' ')},       /* Karaim */
+  {"kdt",      HB_TAG('K','U','Y',' ')},       /* Kuy */
+/*{"kea",      HB_TAG('K','E','A',' ')},*/     /* Kabuverdianu (Crioulo) */
+/*{"kek",      HB_TAG('K','E','K',' ')},*/     /* Kekchi */
+  {"kex",      HB_TAG('K','K','N',' ')},       /* Kukna -> Kokni */
+  {"kfa",      HB_TAG('K','O','D',' ')},       /* Kodava -> Kodagu */
+  {"kfr",      HB_TAG('K','A','C',' ')},       /* Kachhi -> Kachchi */
+  {"kfx",      HB_TAG('K','U','L',' ')},       /* Kullu Pahari -> Kulvi */
+  {"kfy",      HB_TAG('K','M','N',' ')},       /* Kumaoni */
+  {"kg",       HB_TAG('K','O','N','0')},       /* Kongo [macrolanguage] */
+  {"kha",      HB_TAG('K','S','I',' ')},       /* Khasi */
+  {"khb",      HB_TAG('X','B','D',' ')},       /* Lü */
+  {"khk",      HB_TAG('M','N','G',' ')},       /* Halh Mongolian -> Mongolian */
+  {"kht",      HB_TAG('K','H','N',' ')},       /* Khamti -> Khamti Shan (Microsoft fonts) */
+  {"kht",      HB_TAG('K','H','T',' ')},       /* Khamti -> Khamti Shan (OpenType spec and SIL fonts) */
+/*{"khw",      HB_TAG('K','H','W',' ')},*/     /* Khowar */
+  {"ki",       HB_TAG('K','I','K',' ')},       /* Kikuyu (Gikuyu) */
+/*{"kiu",      HB_TAG('K','I','U',' ')},*/     /* Kirmanjki */
+  {"kj",       HB_TAG('K','U','A',' ')},       /* Kuanyama */
+/*{"kjd",      HB_TAG('K','J','D',' ')},*/     /* Southern Kiwai */
+  {"kjh",      HB_TAG('K','H','A',' ')},       /* Khakas -> Khakass */
+/*{"kjp",      HB_TAG('K','J','P',' ')},*/     /* Pwo Eastern Karen -> Eastern Pwo Karen */
+/*{"kjz",      HB_TAG('K','J','Z',' ')},*/     /* Bumthangkha */
+  {"kk",       HB_TAG('K','A','Z',' ')},       /* Kazakh */
+  {"kkz",      HB_TAG('A','T','H',' ')},       /* Kaska -> Athapaskan */
+  {"kl",       HB_TAG('G','R','N',' ')},       /* Greenlandic */
+  {"kln",      HB_TAG('K','A','L',' ')},       /* Kalenjin [macrolanguage] */
+  {"km",       HB_TAG('K','H','M',' ')},       /* Khmer */
+  {"kmb",      HB_TAG('M','B','N',' ')},       /* Kimbundu -> Mbundu */
+  {"kmr",      HB_TAG('K','U','R',' ')},       /* Northern Kurdish -> Kurdish */
+  {"kmw",      HB_TAG('K','M','O',' ')},       /* Komo (Democratic Republic of Congo) */
+/*{"kmz",      HB_TAG('K','M','Z',' ')},*/     /* Khorasani Turkish -> Khorasani Turkic */
+  {"kn",       HB_TAG('K','A','N',' ')},       /* Kannada */
+  {"knc",      HB_TAG('K','N','R',' ')},       /* Central Kanuri -> Kanuri */
+  {"kng",      HB_TAG('K','O','N','0')},       /* Koongo -> Kongo */
+  {"knn",      HB_TAG('K','O','K',' ')},       /* Konkani */
+  {"ko",       HB_TAG('K','O','R',' ')},       /* Korean */
+  {"koi",      HB_TAG('K','O','P',' ')},       /* Komi-Permyak */
+/*{"kok",      HB_TAG('K','O','K',' ')},*/     /* Konkani [macrolanguage] */
+/*{"kos",      HB_TAG('K','O','S',' ')},*/     /* Kosraean */
+  {"koy",      HB_TAG('A','T','H',' ')},       /* Koyukon -> Athapaskan */
+  {"kpe",      HB_TAG('K','P','L',' ')},       /* Kpelle [macrolanguage] */
+  {"kpv",      HB_TAG('K','O','Z',' ')},       /* Komi-Zyrian */
+  {"kpy",      HB_TAG('K','Y','K',' ')},       /* Koryak */
+  {"kqs",      HB_TAG('K','I','S',' ')},       /* Northern Kissi -> Kisii */
+  {"kqy",      HB_TAG('K','R','T',' ')},       /* Koorete */
+  {"kr",       HB_TAG('K','N','R',' ')},       /* Kanuri [macrolanguage] */
+  {"krc",      HB_TAG('K','A','R',' ')},       /* Karachay-Balkar -> Karachay */
+  {"krc",      HB_TAG('B','A','L',' ')},       /* Karachay-Balkar -> Balkar */
+/*{"kri",      HB_TAG('K','R','I',' ')},*/     /* Krio */
+/*{"krl",      HB_TAG('K','R','L',' ')},*/     /* Karelian */
+  {"krt",      HB_TAG('K','N','R',' ')},       /* Tumari Kanuri -> Kanuri */
+  {"kru",      HB_TAG('K','U','U',' ')},       /* Kurukh */
+  {"ks",       HB_TAG('K','S','H',' ')},       /* Kashmiri */
+  {"ksh",      HB_TAG('K','S','H','0')},       /* Kölsch -> Ripuarian */
+  {"kss",      HB_TAG('K','I','S',' ')},       /* Southern Kisi -> Kisii */
+/*{"ksw",      HB_TAG('K','S','W',' ')},*/     /* S’gaw Karen */
+  {"ktb",      HB_TAG('K','E','B',' ')},       /* Kambaata -> Kebena */
+  {"ktu",      HB_TAG('K','O','N',' ')},       /* Kituba (Democratic Republic of Congo) -> Kikongo */
+  {"ktw",      HB_TAG('A','T','H',' ')},       /* Kato -> Athapaskan */
+  {"ku",       HB_TAG('K','U','R',' ')},       /* Kurdish [macrolanguage] */
+/*{"kum",      HB_TAG('K','U','M',' ')},*/     /* Kumyk */
+  {"kuu",      HB_TAG('A','T','H',' ')},       /* Upper Kuskokwim -> Athapaskan */
+  {"kv",       HB_TAG('K','O','M',' ')},       /* Komi [macrolanguage] */
+  {"kvb",      HB_TAG('M','L','Y',' ')},       /* Kubu -> Malay */
+  {"kvr",      HB_TAG('M','L','Y',' ')},       /* Kerinci -> Malay */
+  {"kw",       HB_TAG('C','O','R',' ')},       /* Cornish */
+  {"kwy",      HB_TAG('K','O','N','0')},       /* San Salvador Kongo -> Kongo */
+  {"kxc",      HB_TAG('K','M','S',' ')},       /* Konso -> Komso */
+  {"kxd",      HB_TAG('M','L','Y',' ')},       /* Brunei -> Malay */
+  {"kxu",      HB_TAG('K','U','I',' ')},       /* Kui (India) */
+  {"ky",       HB_TAG('K','I','R',' ')},       /* Kirghiz (Kyrgyz) */
+/*{"kyu",      HB_TAG('K','Y','U',' ')},*/     /* Western Kayah */
+  {"la",       HB_TAG('L','A','T',' ')},       /* Latin */
+  {"lad",      HB_TAG('J','U','D',' ')},       /* Ladino */
+  {"lb",       HB_TAG('L','T','Z',' ')},       /* Luxembourgish */
+  {"lbe",      HB_TAG('L','A','K',' ')},       /* Lak */
+  {"lbj",      HB_TAG('L','D','K',' ')},       /* Ladakhi */
+  {"lbl",      HB_TAG('B','I','K',' ')},       /* Libon Bikol -> Bikol */
+  {"lce",      HB_TAG('M','L','Y',' ')},       /* Loncong -> Malay */
+  {"lcf",      HB_TAG('M','L','Y',' ')},       /* Lubu -> Malay */
+  {"ldi",      HB_TAG('K','O','N','0')},       /* Laari -> Kongo */
+/*{"lez",      HB_TAG('L','E','Z',' ')},*/     /* Lezghian -> Lezgi */
+  {"lg",       HB_TAG('L','U','G',' ')},       /* Ganda */
+  {"li",       HB_TAG('L','I','M',' ')},       /* Limburgish */
+  {"lif",      HB_TAG('L','M','B',' ')},       /* Limbu */
+/*{"lij",      HB_TAG('L','I','J',' ')},*/     /* Ligurian */
+/*{"lis",      HB_TAG('L','I','S',' ')},*/     /* Lisu */
+  {"liw",      HB_TAG('M','L','Y',' ')},       /* Col -> Malay */
+/*{"ljp",      HB_TAG('L','J','P',' ')},*/     /* Lampung Api -> Lampung */
+  {"lkb",      HB_TAG('L','U','H',' ')},       /* Kabras -> Luyia */
+/*{"lki",      HB_TAG('L','K','I',' ')},*/     /* Laki */
+  {"lko",      HB_TAG('L','U','H',' ')},       /* Khayo -> Luyia */
+  {"lks",      HB_TAG('L','U','H',' ')},       /* Kisa -> Luyia */
+  {"lld",      HB_TAG('L','A','D',' ')},       /* Ladin */
+  {"lmn",      HB_TAG('L','A','M',' ')},       /* Lambadi -> Lambani */
+/*{"lmo",      HB_TAG('L','M','O',' ')},*/     /* Lombard */
+  {"ln",       HB_TAG('L','I','N',' ')},       /* Lingala */
+  {"lo",       HB_TAG('L','A','O',' ')},       /* Lao */
+/*{"lom",      HB_TAG('L','O','M',' ')},*/     /* Loma (Liberia) */
+/*{"lrc",      HB_TAG('L','R','C',' ')},*/     /* Northern Luri -> Luri */
+  {"lri",      HB_TAG('L','U','H',' ')},       /* Marachi -> Luyia */
+  {"lrm",      HB_TAG('L','U','H',' ')},       /* Marama -> Luyia */
+  {"lsm",      HB_TAG('L','U','H',' ')},       /* Saamia -> Luyia */
+  {"lt",       HB_TAG('L','T','H',' ')},       /* Lithuanian */
+  {"ltg",      HB_TAG('L','V','I',' ')},       /* Latgalian -> Latvian */
+  {"lto",      HB_TAG('L','U','H',' ')},       /* Tsotso -> Luyia */
+  {"lts",      HB_TAG('L','U','H',' ')},       /* Tachoni -> Luyia */
+  {"lu",       HB_TAG('L','U','B',' ')},       /* Luba-Katanga */
+/*{"lua",      HB_TAG('L','U','A',' ')},*/     /* Luba-Lulua */
+/*{"luo",      HB_TAG('L','U','O',' ')},*/     /* Luo (Kenya and Tanzania) */
+  {"lus",      HB_TAG('M','I','Z',' ')},       /* Lushai -> Mizo */
+  {"luy",      HB_TAG('L','U','H',' ')},       /* Luyia [macrolanguage] */
+  {"luz",      HB_TAG('L','R','C',' ')},       /* Southern Luri -> Luri */
+  {"lv",       HB_TAG('L','V','I',' ')},       /* Latvian [macrolanguage] */
+  {"lvs",      HB_TAG('L','V','I',' ')},       /* Standard Latvian -> Latvian */
+  {"lwg",      HB_TAG('L','U','H',' ')},       /* Wanga -> Luyia */
+  {"lzh",      HB_TAG('Z','H','T',' ')},       /* Literary Chinese -> Chinese Traditional */
+  {"lzz",      HB_TAG('L','A','Z',' ')},       /* Laz */
+/*{"mad",      HB_TAG('M','A','D',' ')},*/     /* Madurese -> Madura */
+/*{"mag",      HB_TAG('M','A','G',' ')},*/     /* Magahi */
+  {"mai",      HB_TAG('M','T','H',' ')},       /* Maithili */
+  {"mak",      HB_TAG('M','K','R',' ')},       /* Makasar */
+/*{"mam",      HB_TAG('M','A','M',' ')},*/     /* Mam */
+  {"man",      HB_TAG('M','N','K',' ')},       /* Mandingo [macrolanguage] -> Maninka */
+  {"max",      HB_TAG('M','L','Y',' ')},       /* North Moluccan Malay -> Malay */
+/*{"mbo",      HB_TAG('M','B','O',' ')},*/     /* Mbo (Cameroon) */
+  {"mct",      HB_TAG('B','T','I',' ')},       /* Mengisa -> Beti */
+  {"mdf",      HB_TAG('M','O','K',' ')},       /* Moksha */
+/*{"mdr",      HB_TAG('M','D','R',' ')},*/     /* Mandar */
+  {"mdy",      HB_TAG('M','L','E',' ')},       /* Male (Ethiopia) */
+  {"men",      HB_TAG('M','D','E',' ')},       /* Mende (Sierra Leone) */
+  {"meo",      HB_TAG('M','L','Y',' ')},       /* Kedah Malay -> Malay */
+/*{"mer",      HB_TAG('M','E','R',' ')},*/     /* Meru */
+/*{"mfa",      HB_TAG('M','F','A',' ')},*/     /* Pattani Malay */
+  {"mfb",      HB_TAG('M','L','Y',' ')},       /* Bangka -> Malay */
+/*{"mfe",      HB_TAG('M','F','E',' ')},*/     /* Morisyen */
+  {"mg",       HB_TAG('M','L','G',' ')},       /* Malagasy [macrolanguage] */
+  {"mh",       HB_TAG('M','A','H',' ')},       /* Marshallese */
+  {"mhr",      HB_TAG('L','M','A',' ')},       /* Eastern Mari -> Low Mari */
+  {"mhv",      HB_TAG('A','R','K',' ')},       /* Arakanese (retired code) -> Rakhine */
+  {"mi",       HB_TAG('M','R','I',' ')},       /* Maori */
+/*{"min",      HB_TAG('M','I','N',' ')},*/     /* Minangkabau */
+  {"mk",       HB_TAG('M','K','D',' ')},       /* Macedonian */
+  {"mku",      HB_TAG('M','N','K',' ')},       /* Konyanka Maninka -> Maninka */
+/*{"mkw",      HB_TAG('M','K','W',' ')},*/     /* Kituba (Congo) */
+  {"ml",       HB_TAG('M','A','L',' ')},       /* Malayalam -> Malayalam Traditional */
+  {"ml",       HB_TAG('M','L','R',' ')},       /* Malayalam -> Malayalam Reformed */
+  {"mlq",      HB_TAG('M','L','N',' ')},       /* Western Maninkakan -> Malinke */
+  {"mlq",      HB_TAG('M','N','K',' ')},       /* Western Maninkakan -> Maninka */
+  {"mmr",      HB_TAG('H','M','N',' ')},       /* Western Xiangxi Miao -> Hmong */
+  {"mn",       HB_TAG('M','N','G',' ')},       /* Mongolian [macrolanguage] */
+  {"mnc",      HB_TAG('M','C','H',' ')},       /* Manchu */
+/*{"mni",      HB_TAG('M','N','I',' ')},*/     /* Manipuri */
+  {"mnk",      HB_TAG('M','N','D',' ')},       /* Mandinka */
+  {"mnk",      HB_TAG('M','N','K',' ')},       /* Mandinka -> Maninka */
+  {"mnp",      HB_TAG('Z','H','S',' ')},       /* Min Bei Chinese -> Chinese Simplified */
+  {"mns",      HB_TAG('M','A','N',' ')},       /* Mansi */
+  {"mnw",      HB_TAG('M','O','N',' ')},       /* Mon */
+  {"mo",       HB_TAG('M','O','L',' ')},       /* Moldavian (retired code) */
+/*{"moh",      HB_TAG('M','O','H',' ')},*/     /* Mohawk */
+/*{"mos",      HB_TAG('M','O','S',' ')},*/     /* Mossi */
+  {"mpe",      HB_TAG('M','A','J',' ')},       /* Majang */
+  {"mqg",      HB_TAG('M','L','Y',' ')},       /* Kota Bangun Kutai Malay -> Malay */
+  {"mr",       HB_TAG('M','A','R',' ')},       /* Marathi */
+  {"mrh",      HB_TAG('Q','I','N',' ')},       /* Mara Chin -> Chin */
+  {"mrj",      HB_TAG('H','M','A',' ')},       /* Western Mari -> High Mari */
+  {"ms",       HB_TAG('M','L','Y',' ')},       /* Malay [macrolanguage] */
+  {"msc",      HB_TAG('M','N','K',' ')},       /* Sankaran Maninka -> Maninka */
+  {"msh",      HB_TAG('M','L','G',' ')},       /* Masikoro Malagasy -> Malagasy */
+  {"msi",      HB_TAG('M','L','Y',' ')},       /* Sabah Malay -> Malay */
+  {"mt",       HB_TAG('M','T','S',' ')},       /* Maltese */
+  {"mtr",      HB_TAG('M','A','W',' ')},       /* Mewari -> Marwari */
+  {"mui",      HB_TAG('M','L','Y',' ')},       /* Musi -> Malay */
+  {"mup",      HB_TAG('R','A','J',' ')},       /* Malvi -> Rajasthani */
+  {"muq",      HB_TAG('H','M','N',' ')},       /* Eastern Xiangxi Miao -> Hmong */
+/*{"mus",      HB_TAG('M','U','S',' ')},*/     /* Creek -> Muscogee */
+  {"mvb",      HB_TAG('A','T','H',' ')},       /* Mattole -> Athapaskan */
+  {"mve",      HB_TAG('M','A','W',' ')},       /* Marwari (Pakistan) */
+  {"mvf",      HB_TAG('M','N','G',' ')},       /* Peripheral Mongolian -> Mongolian */
+  {"mwk",      HB_TAG('M','N','K',' ')},       /* Kita Maninkakan -> Maninka */
+/*{"mwl",      HB_TAG('M','W','L',' ')},*/     /* Mirandese */
+  {"mwr",      HB_TAG('M','A','W',' ')},       /* Marwari [macrolanguage] */
+/*{"mww",      HB_TAG('M','W','W',' ')},*/     /* Hmong Daw */
+  {"my",       HB_TAG('B','R','M',' ')},       /* Burmese */
+  {"mym",      HB_TAG('M','E','N',' ')},       /* Me’en */
+/*{"myn",      HB_TAG('M','Y','N',' ')},*/     /* Mayan [family] */
+  {"myq",      HB_TAG('M','N','K',' ')},       /* Forest Maninka (retired code) -> Maninka */
+  {"myv",      HB_TAG('E','R','Z',' ')},       /* Erzya */
+/*{"mzn",      HB_TAG('M','Z','N',' ')},*/     /* Mazanderani */
+  {"na",       HB_TAG('N','A','U',' ')},       /* Nauru -> Nauruan */
+/*{"nag",      HB_TAG('N','A','G',' ')},*/     /* Naga Pidgin -> Naga-Assamese */
+/*{"nah",      HB_TAG('N','A','H',' ')},*/     /* Nahuatl [family] */
+  {"nan",      HB_TAG('Z','H','S',' ')},       /* Min Nan Chinese -> Chinese Simplified */
+/*{"nap",      HB_TAG('N','A','P',' ')},*/     /* Neapolitan */
+  {"nb",       HB_TAG('N','O','R',' ')},       /* Norwegian Bokmål -> Norwegian */
+  {"nd",       HB_TAG('N','D','B',' ')},       /* North Ndebele -> Ndebele */
+/*{"ndc",      HB_TAG('N','D','C',' ')},*/     /* Ndau */
+/*{"nds",      HB_TAG('N','D','S',' ')},*/     /* Low Saxon */
+  {"ne",       HB_TAG('N','E','P',' ')},       /* Nepali [macrolanguage] */
+/*{"new",      HB_TAG('N','E','W',' ')},*/     /* Newari */
+  {"ng",       HB_TAG('N','D','G',' ')},       /* Ndonga */
+/*{"nga",      HB_TAG('N','G','A',' ')},*/     /* Ngbaka */
+  {"ngl",      HB_TAG('L','M','W',' ')},       /* Lomwe */
+  {"ngo",      HB_TAG('S','X','T',' ')},       /* Ngoni -> Sutu */
+  {"nhd",      HB_TAG('G','U','A',' ')},       /* Chiripá -> Guarani */
+  {"niq",      HB_TAG('K','A','L',' ')},       /* Nandi -> Kalenjin */
+/*{"niu",      HB_TAG('N','I','U',' ')},*/     /* Niuean */
+  {"niv",      HB_TAG('G','I','L',' ')},       /* Gilyak */
+  {"njz",      HB_TAG('N','I','S',' ')},       /* Nyishi -> Nisi */
+  {"nl",       HB_TAG('N','L','D',' ')},       /* Dutch */
+  {"nle",      HB_TAG('L','U','H',' ')},       /* East Nyala -> Luyia */
+  {"nn",       HB_TAG('N','Y','N',' ')},       /* Norwegian Nynorsk (Nynorsk, Norwegian) */
+  {"no",       HB_TAG('N','O','R',' ')},       /* Norwegian [macrolanguage] */
+  {"nod",      HB_TAG('N','T','A',' ')},       /* Northern Thai -> Northern Tai */
+/*{"noe",      HB_TAG('N','O','E',' ')},*/     /* Nimadi */
+/*{"nog",      HB_TAG('N','O','G',' ')},*/     /* Nogai */
+/*{"nov",      HB_TAG('N','O','V',' ')},*/     /* Novial */
+  {"npi",      HB_TAG('N','E','P',' ')},       /* Nepali */
+  {"nqo",      HB_TAG('N','K','O',' ')},       /* N’Ko */
+  {"nr",       HB_TAG('N','D','B',' ')},       /* South Ndebele -> Ndebele */
+  {"nsk",      HB_TAG('N','A','S',' ')},       /* Naskapi */
+/*{"nso",      HB_TAG('N','S','O',' ')},*/     /* Pedi -> Sotho, Northern */
+  {"nv",       HB_TAG('N','A','V',' ')},       /* Navajo */
+  {"nv",       HB_TAG('A','T','H',' ')},       /* Navajo -> Athapaskan */
+  {"ny",       HB_TAG('C','H','I',' ')},       /* Chichewa (Chewa, Nyanja) */
+  {"nyd",      HB_TAG('L','U','H',' ')},       /* Nyore -> Luyia */
+/*{"nym",      HB_TAG('N','Y','M',' ')},*/     /* Nyamwezi */
+  {"nyn",      HB_TAG('N','K','L',' ')},       /* Nyankole */
+/*{"nza",      HB_TAG('N','Z','A',' ')},*/     /* Tigon Mbembe -> Mbembe Tigon */
+  {"oc",       HB_TAG('O','C','I',' ')},       /* Occitan (post 1500) */
+  {"oj",       HB_TAG('O','J','B',' ')},       /* Ojibwa [macrolanguage] -> Ojibway */
+/*{"ojb",      HB_TAG('O','J','B',' ')},*/     /* Northwestern Ojibwa -> Ojibway */
+  {"ojc",      HB_TAG('O','J','B',' ')},       /* Central Ojibwa -> Ojibway */
+  {"ojg",      HB_TAG('O','J','B',' ')},       /* Eastern Ojibwa -> Ojibway */
+  {"ojs",      HB_TAG('O','C','R',' ')},       /* Severn Ojibwa -> Oji-Cree */
+  {"ojw",      HB_TAG('O','J','B',' ')},       /* Western Ojibwa -> Ojibway */
+  {"oki",      HB_TAG('K','A','L',' ')},       /* Okiek -> Kalenjin */
+  {"okm",      HB_TAG('K','O','H',' ')},       /* Middle Korean (10th-16th cent.) -> Korean Old Hangul */
+  {"om",       HB_TAG('O','R','O',' ')},       /* Oromo [macrolanguage] */
+  {"or",       HB_TAG('O','R','I',' ')},       /* Odia (formerly Oriya) [macrolanguage] */
+  {"orc",      HB_TAG('O','R','O',' ')},       /* Orma -> Oromo */
+  {"orn",      HB_TAG('M','L','Y',' ')},       /* Orang Kanaq -> Malay */
+  {"ors",      HB_TAG('M','L','Y',' ')},       /* Orang Seletar -> Malay */
+  {"ory",      HB_TAG('O','R','I',' ')},       /* Odia (formerly Oriya) */
+  {"os",       HB_TAG('O','S','S',' ')},       /* Ossetian */
+  {"otw",      HB_TAG('O','J','B',' ')},       /* Ottawa -> Ojibway */
+  {"pa",       HB_TAG('P','A','N',' ')},       /* Punjabi */
+/*{"pag",      HB_TAG('P','A','G',' ')},*/     /* Pangasinan */
+/*{"pam",      HB_TAG('P','A','M',' ')},*/     /* Pampanga -> Pampangan */
+  {"pap",      HB_TAG('P','A','P','0')},       /* Papiamento -> Papiamentu */
+/*{"pau",      HB_TAG('P','A','U',' ')},*/     /* Palauan */
+  {"pbt",      HB_TAG('P','A','S',' ')},       /* Southern Pashto -> Pashto */
+  {"pbu",      HB_TAG('P','A','S',' ')},       /* Northern Pashto -> Pashto */
+/*{"pcc",      HB_TAG('P','C','C',' ')},*/     /* Bouyei */
+/*{"pcd",      HB_TAG('P','C','D',' ')},*/     /* Picard */
+  {"pce",      HB_TAG('P','L','G',' ')},       /* Ruching Palaung -> Palaung */
+  {"pck",      HB_TAG('Q','I','N',' ')},       /* Paite Chin -> Chin */
+/*{"pdc",      HB_TAG('P','D','C',' ')},*/     /* Pennsylvania German */
+  {"pel",      HB_TAG('M','L','Y',' ')},       /* Pekal -> Malay */
+  {"pes",      HB_TAG('F','A','R',' ')},       /* Iranian Persian -> Persian */
+  {"pga",      HB_TAG('A','R','A',' ')},       /* Sudanese Creole Arabic -> Arabic */
+/*{"phk",      HB_TAG('P','H','K',' ')},*/     /* Phake */
+  {"pi",       HB_TAG('P','A','L',' ')},       /* Pali */
+/*{"pih",      HB_TAG('P','I','H',' ')},*/     /* Pitcairn-Norfolk -> Norfolk */
+  {"pko",      HB_TAG('K','A','L',' ')},       /* Pökoot -> Kalenjin */
+  {"pl",       HB_TAG('P','L','K',' ')},       /* Polish */
+  {"pll",      HB_TAG('P','L','G',' ')},       /* Shwe Palaung -> Palaung */
+  {"plp",      HB_TAG('P','A','P',' ')},       /* Palpa */
+  {"plt",      HB_TAG('M','L','G',' ')},       /* Plateau Malagasy -> Malagasy */
+/*{"pms",      HB_TAG('P','M','S',' ')},*/     /* Piemontese */
+/*{"pnb",      HB_TAG('P','N','B',' ')},*/     /* Western Panjabi */
+/*{"poh",      HB_TAG('P','O','H',' ')},*/     /* Poqomchi' -> Pocomchi */
+/*{"pon",      HB_TAG('P','O','N',' ')},*/     /* Pohnpeian */
+  {"ppa",      HB_TAG('B','A','G',' ')},       /* Pao (retired code) -> Baghelkhandi */
+/*{"pro",      HB_TAG('P','R','O',' ')},*/     /* Old Provençal (to 1500) -> Provençal / Old Provençal */
+  {"prs",      HB_TAG('D','R','I',' ')},       /* Dari */
+  {"ps",       HB_TAG('P','A','S',' ')},       /* Pashto [macrolanguage] */
+  {"pse",      HB_TAG('M','L','Y',' ')},       /* Central Malay -> Malay */
+  {"pst",      HB_TAG('P','A','S',' ')},       /* Central Pashto -> Pashto */
+  {"pt",       HB_TAG('P','T','G',' ')},       /* Portuguese */
+/*{"pwo",      HB_TAG('P','W','O',' ')},*/     /* Pwo Western Karen -> Western Pwo Karen */
+  {"qu",       HB_TAG('Q','U','Z',' ')},       /* Quechua [macrolanguage] */
+  {"qub",      HB_TAG('Q','W','H',' ')},       /* Huallaga Huánuco Quechua -> Quechua (Peru) */
+/*{"quc",      HB_TAG('Q','U','C',' ')},*/     /* K’iche’ */
+  {"qud",      HB_TAG('Q','V','I',' ')},       /* Calderón Highland Quichua -> Quechua (Ecuador) */
+  {"quf",      HB_TAG('Q','U','Z',' ')},       /* Lambayeque Quechua -> Quechua */
+  {"qug",      HB_TAG('Q','V','I',' ')},       /* Chimborazo Highland Quichua -> Quechua (Ecuador) */
+/*{"quh",      HB_TAG('Q','U','H',' ')},*/     /* South Bolivian Quechua -> Quechua (Bolivia) */
+  {"quk",      HB_TAG('Q','U','Z',' ')},       /* Chachapoyas Quechua -> Quechua */
+  {"qul",      HB_TAG('Q','U','Z',' ')},       /* North Bolivian Quechua -> Quechua */
+  {"qup",      HB_TAG('Q','V','I',' ')},       /* Southern Pastaza Quechua -> Quechua (Ecuador) */
+  {"qur",      HB_TAG('Q','W','H',' ')},       /* Yanahuanca Pasco Quechua -> Quechua (Peru) */
+  {"qus",      HB_TAG('Q','U','H',' ')},       /* Santiago del Estero Quichua -> Quechua (Bolivia) */
+  {"quw",      HB_TAG('Q','V','I',' ')},       /* Tena Lowland Quichua -> Quechua (Ecuador) */
+  {"qux",      HB_TAG('Q','W','H',' ')},       /* Yauyos Quechua -> Quechua (Peru) */
+  {"quy",      HB_TAG('Q','U','Z',' ')},       /* Ayacucho Quechua -> Quechua */
+/*{"quz",      HB_TAG('Q','U','Z',' ')},*/     /* Cusco Quechua -> Quechua */
+  {"qva",      HB_TAG('Q','W','H',' ')},       /* Ambo-Pasco Quechua -> Quechua (Peru) */
+  {"qvc",      HB_TAG('Q','U','Z',' ')},       /* Cajamarca Quechua -> Quechua */
+  {"qve",      HB_TAG('Q','U','Z',' ')},       /* Eastern Apurímac Quechua -> Quechua */
+  {"qvh",      HB_TAG('Q','W','H',' ')},       /* Huamalíes-Dos de Mayo Huánuco Quechua -> Quechua (Peru) */
+/*{"qvi",      HB_TAG('Q','V','I',' ')},*/     /* Imbabura Highland Quichua -> Quechua (Ecuador) */
+  {"qvj",      HB_TAG('Q','V','I',' ')},       /* Loja Highland Quichua -> Quechua (Ecuador) */
+  {"qvl",      HB_TAG('Q','W','H',' ')},       /* Cajatambo North Lima Quechua -> Quechua (Peru) */
+  {"qvm",      HB_TAG('Q','W','H',' ')},       /* Margos-Yarowilca-Lauricocha Quechua -> Quechua (Peru) */
+  {"qvn",      HB_TAG('Q','W','H',' ')},       /* North Junín Quechua -> Quechua (Peru) */
+  {"qvo",      HB_TAG('Q','V','I',' ')},       /* Napo Lowland Quechua -> Quechua (Ecuador) */
+  {"qvp",      HB_TAG('Q','W','H',' ')},       /* Pacaraos Quechua -> Quechua (Peru) */
+  {"qvs",      HB_TAG('Q','U','Z',' ')},       /* San Martín Quechua -> Quechua */
+  {"qvw",      HB_TAG('Q','W','H',' ')},       /* Huaylla Wanca Quechua -> Quechua (Peru) */
+  {"qvz",      HB_TAG('Q','V','I',' ')},       /* Northern Pastaza Quichua -> Quechua (Ecuador) */
+  {"qwa",      HB_TAG('Q','W','H',' ')},       /* Corongo Ancash Quechua -> Quechua (Peru) */
+  {"qwc",      HB_TAG('Q','U','Z',' ')},       /* Classical Quechua -> Quechua */
+/*{"qwh",      HB_TAG('Q','W','H',' ')},*/     /* Huaylas Ancash Quechua -> Quechua (Peru) */
+  {"qws",      HB_TAG('Q','W','H',' ')},       /* Sihuas Ancash Quechua -> Quechua (Peru) */
+  {"qxa",      HB_TAG('Q','W','H',' ')},       /* Chiquián Ancash Quechua -> Quechua (Peru) */
+  {"qxc",      HB_TAG('Q','W','H',' ')},       /* Chincha Quechua -> Quechua (Peru) */
+  {"qxh",      HB_TAG('Q','W','H',' ')},       /* Panao Huánuco Quechua -> Quechua (Peru) */
+  {"qxl",      HB_TAG('Q','V','I',' ')},       /* Salasaca Highland Quichua -> Quechua (Ecuador) */
+  {"qxn",      HB_TAG('Q','W','H',' ')},       /* Northern Conchucos Ancash Quechua -> Quechua (Peru) */
+  {"qxo",      HB_TAG('Q','W','H',' ')},       /* Southern Conchucos Ancash Quechua -> Quechua (Peru) */
+  {"qxp",      HB_TAG('Q','U','Z',' ')},       /* Puno Quechua -> Quechua */
+  {"qxr",      HB_TAG('Q','V','I',' ')},       /* Cañar Highland Quichua -> Quechua (Ecuador) */
+  {"qxt",      HB_TAG('Q','W','H',' ')},       /* Santa Ana de Tusi Pasco Quechua -> Quechua (Peru) */
+  {"qxu",      HB_TAG('Q','U','Z',' ')},       /* Arequipa-La Unión Quechua -> Quechua */
+  {"qxw",      HB_TAG('Q','W','H',' ')},       /* Jauja Wanca Quechua -> Quechua (Peru) */
+  {"rag",      HB_TAG('L','U','H',' ')},       /* Logooli -> Luyia */
+/*{"raj",      HB_TAG('R','A','J',' ')},*/     /* Rajasthani [macrolanguage] */
+/*{"rar",      HB_TAG('R','A','R',' ')},*/     /* Rarotongan */
+  {"rbb",      HB_TAG('P','L','G',' ')},       /* Rumai Palaung -> Palaung */
+  {"rbl",      HB_TAG('B','I','K',' ')},       /* Miraya Bikol -> Bikol */
+/*{"rej",      HB_TAG('R','E','J',' ')},*/     /* Rejang */
+/*{"ria",      HB_TAG('R','I','A',' ')},*/     /* Riang (India) */
+/*{"rif",      HB_TAG('R','I','F',' ')},*/     /* Tarifit */
+/*{"rit",      HB_TAG('R','I','T',' ')},*/     /* Ritarungo */
+  {"rki",      HB_TAG('A','R','K',' ')},       /* Rakhine */
+/*{"rkw",      HB_TAG('R','K','W',' ')},*/     /* Arakwal */
+  {"rm",       HB_TAG('R','M','S',' ')},       /* Romansh */
+  {"rmc",      HB_TAG('R','O','Y',' ')},       /* Carpathian Romani -> Romany */
+  {"rmf",      HB_TAG('R','O','Y',' ')},       /* Kalo Finnish Romani -> Romany */
+  {"rml",      HB_TAG('R','O','Y',' ')},       /* Baltic Romani -> Romany */
+  {"rmn",      HB_TAG('R','O','Y',' ')},       /* Balkan Romani -> Romany */
+  {"rmo",      HB_TAG('R','O','Y',' ')},       /* Sinte Romani -> Romany */
+  {"rmw",      HB_TAG('R','O','Y',' ')},       /* Welsh Romani -> Romany */
+/*{"rmy",      HB_TAG('R','M','Y',' ')},*/     /* Vlax Romani */
+  {"rmz",      HB_TAG('A','R','K',' ')},       /* Marma -> Rakhine */
+  {"rn",       HB_TAG('R','U','N',' ')},       /* Rundi */
+  {"rnl",      HB_TAG('H','A','L',' ')},       /* Ranglong -> Halam (Falam Chin) */
+  {"ro",       HB_TAG('R','O','M',' ')},       /* Romanian */
+  {"rom",      HB_TAG('R','O','Y',' ')},       /* Romany [macrolanguage] */
+/*{"rtm",      HB_TAG('R','T','M',' ')},*/     /* Rotuman */
+  {"ru",       HB_TAG('R','U','S',' ')},       /* Russian */
+  {"rue",      HB_TAG('R','S','Y',' ')},       /* Rusyn */
+/*{"rup",      HB_TAG('R','U','P',' ')},*/     /* Aromanian */
+  {"rw",       HB_TAG('R','U','A',' ')},       /* Kinyarwanda */
+  {"rwr",      HB_TAG('M','A','W',' ')},       /* Marwari (India) */
+  {"sa",       HB_TAG('S','A','N',' ')},       /* Sanskrit */
+  {"sah",      HB_TAG('Y','A','K',' ')},       /* Yakut -> Sakha */
+  {"sam",      HB_TAG('P','A','A',' ')},       /* Samaritan Aramaic -> Palestinian Aramaic */
+/*{"sas",      HB_TAG('S','A','S',' ')},*/     /* Sasak */
+/*{"sat",      HB_TAG('S','A','T',' ')},*/     /* Santali */
+  {"sc",       HB_TAG('S','R','D',' ')},       /* Sardinian [macrolanguage] */
+  {"sck",      HB_TAG('S','A','D',' ')},       /* Sadri */
+/*{"scn",      HB_TAG('S','C','N',' ')},*/     /* Sicilian */
+/*{"sco",      HB_TAG('S','C','O',' ')},*/     /* Scots */
+  {"scs",      HB_TAG('S','C','S',' ')},       /* North Slavey */
+  {"scs",      HB_TAG('S','L','A',' ')},       /* North Slavey -> Slavey */
+  {"scs",      HB_TAG('A','T','H',' ')},       /* North Slavey -> Athapaskan */
+  {"sd",       HB_TAG('S','N','D',' ')},       /* Sindhi */
+  {"sdc",      HB_TAG('S','R','D',' ')},       /* Sassarese Sardinian -> Sardinian */
+  {"sdh",      HB_TAG('K','U','R',' ')},       /* Southern Kurdish -> Kurdish */
+  {"sdn",      HB_TAG('S','R','D',' ')},       /* Gallurese Sardinian -> Sardinian */
+  {"se",       HB_TAG('N','S','M',' ')},       /* Northern Sami */
+  {"seh",      HB_TAG('S','N','A',' ')},       /* Sena */
+  {"sek",      HB_TAG('A','T','H',' ')},       /* Sekani -> Athapaskan */
+/*{"sel",      HB_TAG('S','E','L',' ')},*/     /* Selkup */
+  {"sez",      HB_TAG('Q','I','N',' ')},       /* Senthang Chin -> Chin */
+  {"sfm",      HB_TAG('H','M','N',' ')},       /* Small Flowery Miao -> Hmong */
+  {"sg",       HB_TAG('S','G','O',' ')},       /* Sango */
+/*{"sga",      HB_TAG('S','G','A',' ')},*/     /* Old Irish (to 900) */
+  {"sgc",      HB_TAG('K','A','L',' ')},       /* Kipsigis -> Kalenjin */
+/*{"sgs",      HB_TAG('S','G','S',' ')},*/     /* Samogitian */
+  {"sgw",      HB_TAG('C','H','G',' ')},       /* Sebat Bet Gurage -> Chaha Gurage */
+  {"sgw",      HB_TAG('S','G','W',' ')},       /* Sebat Bet Gurage -> Chaha Gurage (SIL fonts) */
+/*{"shi",      HB_TAG('S','H','I',' ')},*/     /* Tachelhit */
+/*{"shn",      HB_TAG('S','H','N',' ')},*/     /* Shan */
+  {"shu",      HB_TAG('A','R','A',' ')},       /* Chadian Arabic -> Arabic */
+  {"si",       HB_TAG('S','N','H',' ')},       /* Sinhala (Sinhalese) */
+/*{"sid",      HB_TAG('S','I','D',' ')},*/     /* Sidamo */
+  {"sjd",      HB_TAG('K','S','M',' ')},       /* Kildin Sami */
+  {"sjo",      HB_TAG('S','I','B',' ')},       /* Xibe -> Sibe */
+  {"sk",       HB_TAG('S','K','Y',' ')},       /* Slovak */
+  {"skg",      HB_TAG('M','L','G',' ')},       /* Sakalava Malagasy -> Malagasy */
+  {"skr",      HB_TAG('S','R','K',' ')},       /* Saraiki */
+  {"sl",       HB_TAG('S','L','V',' ')},       /* Slovenian */
+  {"sm",       HB_TAG('S','M','O',' ')},       /* Samoan */
+  {"sma",      HB_TAG('S','S','M',' ')},       /* Southern Sami */
+  {"smj",      HB_TAG('L','S','M',' ')},       /* Lule Sami */
+  {"smn",      HB_TAG('I','S','M',' ')},       /* Inari Sami */
+  {"sms",      HB_TAG('S','K','S',' ')},       /* Skolt Sami */
+  {"sn",       HB_TAG('S','N','A','0')},       /* Shona */
+/*{"snk",      HB_TAG('S','N','K',' ')},*/     /* Soninke */
+  {"so",       HB_TAG('S','M','L',' ')},       /* Somali */
+/*{"sop",      HB_TAG('S','O','P',' ')},*/     /* Songe */
+  {"spv",      HB_TAG('O','R','I',' ')},       /* Sambalpuri -> Odia (formerly Oriya) */
+  {"spy",      HB_TAG('K','A','L',' ')},       /* Sabaot -> Kalenjin */
+  {"sq",       HB_TAG('S','Q','I',' ')},       /* Albanian [macrolanguage] */
+  {"sr",       HB_TAG('S','R','B',' ')},       /* Serbian */
+  {"src",      HB_TAG('S','R','D',' ')},       /* Logudorese Sardinian -> Sardinian */
+  {"sro",      HB_TAG('S','R','D',' ')},       /* Campidanese Sardinian -> Sardinian */
+/*{"srr",      HB_TAG('S','R','R',' ')},*/     /* Serer */
+  {"srs",      HB_TAG('A','T','H',' ')},       /* Sarsi -> Athapaskan */
+  {"ss",       HB_TAG('S','W','Z',' ')},       /* Swati */
+  {"ssh",      HB_TAG('A','R','A',' ')},       /* Shihhi Arabic -> Arabic */
+  {"st",       HB_TAG('S','O','T',' ')},       /* Southern Sotho -> Sotho, Southern */
+/*{"stq",      HB_TAG('S','T','Q',' ')},*/     /* Saterfriesisch -> Saterland Frisian */
+  {"stv",      HB_TAG('S','I','G',' ')},       /* Silt'e -> Silte Gurage */
+  {"su",       HB_TAG('S','U','N',' ')},       /* Sundanese */
+/*{"suk",      HB_TAG('S','U','K',' ')},*/     /* Sukuma */
+  {"suq",      HB_TAG('S','U','R',' ')},       /* Suri */
+  {"sv",       HB_TAG('S','V','E',' ')},       /* Swedish */
+/*{"sva",      HB_TAG('S','V','A',' ')},*/     /* Svan */
+  {"sw",       HB_TAG('S','W','K',' ')},       /* Swahili [macrolanguage] */
+  {"swb",      HB_TAG('C','M','R',' ')},       /* Maore Comorian -> Comorian */
+  {"swc",      HB_TAG('S','W','K',' ')},       /* Congo Swahili -> Swahili */
+  {"swh",      HB_TAG('S','W','K',' ')},       /* Swahili */
+  {"swv",      HB_TAG('M','A','W',' ')},       /* Shekhawati -> Marwari */
+/*{"sxu",      HB_TAG('S','X','U',' ')},*/     /* Upper Saxon */
+  {"syc",      HB_TAG('S','Y','R',' ')},       /* Classical Syriac -> Syriac */
+/*{"syl",      HB_TAG('S','Y','L',' ')},*/     /* Sylheti */
+/*{"syr",      HB_TAG('S','Y','R',' ')},*/     /* Syriac [macrolanguage] */
+/*{"szl",      HB_TAG('S','Z','L',' ')},*/     /* Silesian */
+  {"ta",       HB_TAG('T','A','M',' ')},       /* Tamil */
+  {"taa",      HB_TAG('A','T','H',' ')},       /* Lower Tanana -> Athapaskan */
+/*{"tab",      HB_TAG('T','A','B',' ')},*/     /* Tabassaran -> Tabasaran */
+  {"taq",      HB_TAG('T','M','H',' ')},       /* Tamasheq -> Tamashek */
+  {"tau",      HB_TAG('A','T','H',' ')},       /* Upper Tanana -> Athapaskan */
+  {"tcb",      HB_TAG('A','T','H',' ')},       /* Tanacross -> Athapaskan */
+  {"tce",      HB_TAG('A','T','H',' ')},       /* Southern Tutchone -> Athapaskan */
+  {"tcp",      HB_TAG('Q','I','N',' ')},       /* Tawr Chin -> Chin */
+  {"tcy",      HB_TAG('T','U','L',' ')},       /* Tulu -> Tumbuka */
+  {"tcz",      HB_TAG('Q','I','N',' ')},       /* Thado Chin -> Chin */
+/*{"tdd",      HB_TAG('T','D','D',' ')},*/     /* Tai Nüa -> Dehong Dai */
+  {"tdx",      HB_TAG('M','L','G',' ')},       /* Tandroy-Mahafaly Malagasy -> Malagasy */
+  {"te",       HB_TAG('T','E','L',' ')},       /* Telugu */
+  {"tec",      HB_TAG('K','A','L',' ')},       /* Terik -> Kalenjin */
+  {"tem",      HB_TAG('T','M','N',' ')},       /* Timne -> Temne */
+/*{"tet",      HB_TAG('T','E','T',' ')},*/     /* Tetum */
+  {"tfn",      HB_TAG('A','T','H',' ')},       /* Tanaina -> Athapaskan */
+  {"tg",       HB_TAG('T','A','J',' ')},       /* Tajik -> Tajiki */
+  {"tgj",      HB_TAG('N','I','S',' ')},       /* Tagin -> Nisi */
+  {"tgx",      HB_TAG('A','T','H',' ')},       /* Tagish -> Athapaskan */
+  {"th",       HB_TAG('T','H','A',' ')},       /* Thai */
+  {"tht",      HB_TAG('A','T','H',' ')},       /* Tahltan -> Athapaskan */
+  {"thv",      HB_TAG('T','M','H',' ')},       /* Tahaggart Tamahaq -> Tamashek */
+  {"thz",      HB_TAG('T','M','H',' ')},       /* Tayart Tamajeq -> Tamashek */
+  {"ti",       HB_TAG('T','G','Y',' ')},       /* Tigrinya */
+  {"tig",      HB_TAG('T','G','R',' ')},       /* Tigre */
+/*{"tiv",      HB_TAG('T','I','V',' ')},*/     /* Tiv */
+  {"tk",       HB_TAG('T','K','M',' ')},       /* Turkmen */
+  {"tkg",      HB_TAG('M','L','G',' ')},       /* Tesaka Malagasy -> Malagasy */
+  {"tl",       HB_TAG('T','G','L',' ')},       /* Tagalog */
+/*{"tmh",      HB_TAG('T','M','H',' ')},*/     /* Tamashek [macrolanguage] */
+  {"tmw",      HB_TAG('M','L','Y',' ')},       /* Temuan -> Malay */
+  {"tn",       HB_TAG('T','N','A',' ')},       /* Tswana */
+  {"tnf",      HB_TAG('D','R','I',' ')},       /* Tangshewi (retired code) -> Dari */
+  {"to",       HB_TAG('T','G','N',' ')},       /* Tonga (Tonga Islands) -> Tongan */
+  {"tod",      HB_TAG('T','O','D','0')},       /* Toma */
+  {"toi",      HB_TAG('T','N','G',' ')},       /* Tonga (Zambia) */
+  {"tol",      HB_TAG('A','T','H',' ')},       /* Tolowa -> Athapaskan */
+/*{"tpi",      HB_TAG('T','P','I',' ')},*/     /* Tok Pisin */
+  {"tr",       HB_TAG('T','R','K',' ')},       /* Turkish */
+  {"tru",      HB_TAG('T','U','A',' ')},       /* Turoyo -> Turoyo Aramaic */
+  {"tru",      HB_TAG('S','Y','R',' ')},       /* Turoyo -> Syriac */
+  {"ts",       HB_TAG('T','S','G',' ')},       /* Tsonga */
+/*{"tsj",      HB_TAG('T','S','J',' ')},*/     /* Tshangla */
+  {"tt",       HB_TAG('T','A','T',' ')},       /* Tatar */
+  {"ttm",      HB_TAG('A','T','H',' ')},       /* Northern Tutchone -> Athapaskan */
+  {"ttq",      HB_TAG('T','M','H',' ')},       /* Tawallammat Tamajaq -> Tamashek */
+/*{"tum",      HB_TAG('T','U','M',' ')},*/     /* Tumbuka -> Tulu */
+  {"tuu",      HB_TAG('A','T','H',' ')},       /* Tututni -> Athapaskan */
+  {"tuy",      HB_TAG('K','A','L',' ')},       /* Tugen -> Kalenjin */
+/*{"tvl",      HB_TAG('T','V','L',' ')},*/     /* Tuvalu */
+  {"tw",       HB_TAG('T','W','I',' ')},       /* Twi */
+  {"tw",       HB_TAG('A','K','A',' ')},       /* Twi -> Akan */
+  {"txc",      HB_TAG('A','T','H',' ')},       /* Tsetsaut -> Athapaskan */
+  {"txy",      HB_TAG('M','L','G',' ')},       /* Tanosy Malagasy -> Malagasy */
+  {"ty",       HB_TAG('T','H','T',' ')},       /* Tahitian */
+  {"tyv",      HB_TAG('T','U','V',' ')},       /* Tuvinian -> Tuvin */
+/*{"tyz",      HB_TAG('T','Y','Z',' ')},*/     /* Tày */
+/*{"tzm",      HB_TAG('T','Z','M',' ')},*/     /* Central Atlas Tamazight -> Tamazight */
+/*{"tzo",      HB_TAG('T','Z','O',' ')},*/     /* Tzotzil */
+  {"ubl",      HB_TAG('B','I','K',' ')},       /* Buhi'non Bikol -> Bikol */
+/*{"udm",      HB_TAG('U','D','M',' ')},*/     /* Udmurt */
+  {"ug",       HB_TAG('U','Y','G',' ')},       /* Uyghur */
+  {"uk",       HB_TAG('U','K','R',' ')},       /* Ukrainian */
+/*{"umb",      HB_TAG('U','M','B',' ')},*/     /* Umbundu */
+  {"unr",      HB_TAG('M','U','N',' ')},       /* Mundari */
+  {"ur",       HB_TAG('U','R','D',' ')},       /* Urdu */
+  {"urk",      HB_TAG('M','L','Y',' ')},       /* Urak Lawoi' -> Malay */
+  {"uz",       HB_TAG('U','Z','B',' ')},       /* Uzbek [macrolanguage] */
+  {"uzn",      HB_TAG('U','Z','B',' ')},       /* Northern Uzbek -> Uzbek */
+  {"uzs",      HB_TAG('U','Z','B',' ')},       /* Southern Uzbek -> Uzbek */
+  {"ve",       HB_TAG('V','E','N',' ')},       /* Venda */
+/*{"vec",      HB_TAG('V','E','C',' ')},*/     /* Venetian */
+  {"vi",       HB_TAG('V','I','T',' ')},       /* Vietnamese */
+  {"vkk",      HB_TAG('M','L','Y',' ')},       /* Kaur -> Malay */
+  {"vkt",      HB_TAG('M','L','Y',' ')},       /* Tenggarong Kutai Malay -> Malay */
+  {"vls",      HB_TAG('F','L','E',' ')},       /* Vlaams -> Dutch (Flemish) */
+  {"vmw",      HB_TAG('M','A','K',' ')},       /* Makhuwa */
+  {"vo",       HB_TAG('V','O','L',' ')},       /* Volapük */
+/*{"vro",      HB_TAG('V','R','O',' ')},*/     /* Võro */
+  {"wa",       HB_TAG('W','L','N',' ')},       /* Walloon */
+/*{"war",      HB_TAG('W','A','R',' ')},*/     /* Waray (Philippines) -> Waray-Waray */
+  {"wbm",      HB_TAG('W','A',' ',' ')},       /* Wa */
+  {"wbr",      HB_TAG('W','A','G',' ')},       /* Wagdi */
+  {"wlc",      HB_TAG('C','M','R',' ')},       /* Mwali Comorian -> Comorian */
+  {"wle",      HB_TAG('S','I','G',' ')},       /* Wolane -> Silte Gurage */
+  {"wlk",      HB_TAG('A','T','H',' ')},       /* Wailaki -> Athapaskan */
+  {"wni",      HB_TAG('C','M','R',' ')},       /* Ndzwani Comorian -> Comorian */
+  {"wo",       HB_TAG('W','L','F',' ')},       /* Wolof */
+  {"wry",      HB_TAG('M','A','W',' ')},       /* Merwari -> Marwari */
+  {"wsg",      HB_TAG('G','O','N',' ')},       /* Adilabad Gondi -> Gondi */
+/*{"wtm",      HB_TAG('W','T','M',' ')},*/     /* Mewati */
+  {"wuu",      HB_TAG('Z','H','S',' ')},       /* Wu Chinese -> Chinese Simplified */
+  {"xal",      HB_TAG('K','L','M',' ')},       /* Kalmyk */
+  {"xal",      HB_TAG('T','O','D',' ')},       /* Kalmyk -> Todo */
+  {"xan",      HB_TAG('S','E','K',' ')},       /* Xamtanga -> Sekota */
+  {"xh",       HB_TAG('X','H','S',' ')},       /* Xhosa */
+/*{"xjb",      HB_TAG('X','J','B',' ')},*/     /* Minjungbal -> Minjangbal */
+/*{"xkf",      HB_TAG('X','K','F',' ')},*/     /* Khengkha */
+  {"xmm",      HB_TAG('M','L','Y',' ')},       /* Manado Malay -> Malay */
+  {"xmv",      HB_TAG('M','L','G',' ')},       /* Antankarana Malagasy -> Malagasy */
+  {"xmw",      HB_TAG('M','L','G',' ')},       /* Tsimihety Malagasy -> Malagasy */
+  {"xnr",      HB_TAG('D','G','R',' ')},       /* Kangri -> Dogri */
+/*{"xog",      HB_TAG('X','O','G',' ')},*/     /* Soga */
+/*{"xpe",      HB_TAG('X','P','E',' ')},*/     /* Liberia Kpelle -> Kpelle (Liberia) */
+  {"xsl",      HB_TAG('S','S','L',' ')},       /* South Slavey */
+  {"xsl",      HB_TAG('S','L','A',' ')},       /* South Slavey -> Slavey */
+  {"xsl",      HB_TAG('A','T','H',' ')},       /* South Slavey -> Athapaskan */
+  {"xst",      HB_TAG('S','I','G',' ')},       /* Silt'e (retired code) -> Silte Gurage */
+  {"xwo",      HB_TAG('T','O','D',' ')},       /* Written Oirat -> Todo */
+/*{"yao",      HB_TAG('Y','A','O',' ')},*/     /* Yao */
+/*{"yap",      HB_TAG('Y','A','P',' ')},*/     /* Yapese */
+  {"ybd",      HB_TAG('A','R','K',' ')},       /* Yangbye (retired code) -> Rakhine */
+  {"ydd",      HB_TAG('J','I','I',' ')},       /* Eastern Yiddish -> Yiddish */
+  {"yi",       HB_TAG('J','I','I',' ')},       /* Yiddish [macrolanguage] */
+  {"yih",      HB_TAG('J','I','I',' ')},       /* Western Yiddish -> Yiddish */
+  {"yo",       HB_TAG('Y','B','A',' ')},       /* Yoruba */
+  {"yos",      HB_TAG('Q','I','N',' ')},       /* Yos (retired code) -> Chin */
+  {"yrk",      HB_TAG('T','N','E',' ')},       /* Nenets -> Tundra Nenets */
+  {"yrk",      HB_TAG('F','N','E',' ')},       /* Nenets -> Forest Nenets */
+  {"yue",      HB_TAG('Z','H','H',' ')},       /* Yue Chinese -> Chinese, Hong Kong SAR */
+  {"za",       HB_TAG('Z','H','A',' ')},       /* Zhuang [macrolanguage] */
+  {"zch",      HB_TAG('Z','H','A',' ')},       /* Central Hongshuihe Zhuang -> Zhuang */
+  {"zdj",      HB_TAG('C','M','R',' ')},       /* Ngazidja Comorian -> Comorian */
+/*{"zea",      HB_TAG('Z','E','A',' ')},*/     /* Zeeuws -> Zealandic */
+  {"zeh",      HB_TAG('Z','H','A',' ')},       /* Eastern Hongshuihe Zhuang -> Zhuang */
+  {"zgb",      HB_TAG('Z','H','A',' ')},       /* Guibei Zhuang -> Zhuang */
+/*{"zgh",      HB_TAG('Z','G','H',' ')},*/     /* Standard Moroccan Tamazight */
+  {"zgm",      HB_TAG('Z','H','A',' ')},       /* Minz Zhuang -> Zhuang */
+  {"zgn",      HB_TAG('Z','H','A',' ')},       /* Guibian Zhuang -> Zhuang */
+  {"zh",       HB_TAG('Z','H','S',' ')},       /* Chinese [macrolanguage] -> Chinese Simplified */
+  {"zhd",      HB_TAG('Z','H','A',' ')},       /* Dai Zhuang -> Zhuang */
+  {"zhn",      HB_TAG('Z','H','A',' ')},       /* Nong Zhuang -> Zhuang */
+  {"zlj",      HB_TAG('Z','H','A',' ')},       /* Liujiang Zhuang -> Zhuang */
+  {"zlm",      HB_TAG('M','L','Y',' ')},       /* Malay */
+  {"zln",      HB_TAG('Z','H','A',' ')},       /* Lianshan Zhuang -> Zhuang */
+  {"zlq",      HB_TAG('Z','H','A',' ')},       /* Liuqian Zhuang -> Zhuang */
+  {"zmi",      HB_TAG('M','L','Y',' ')},       /* Negeri Sembilan Malay -> Malay */
+  {"zne",      HB_TAG('Z','N','D',' ')},       /* Zande */
+  {"zom",      HB_TAG('Q','I','N',' ')},       /* Zou -> Chin */
+  {"zqe",      HB_TAG('Z','H','A',' ')},       /* Qiubei Zhuang -> Zhuang */
+  {"zsm",      HB_TAG('M','L','Y',' ')},       /* Standard Malay -> Malay */
+  {"zu",       HB_TAG('Z','U','L',' ')},       /* Zulu */
+  {"zum",      HB_TAG('L','R','C',' ')},       /* Kumzari -> Luri */
+  {"zyb",      HB_TAG('Z','H','A',' ')},       /* Yongbei Zhuang -> Zhuang */
+  {"zyg",      HB_TAG('Z','H','A',' ')},       /* Yang Zhuang -> Zhuang */
+  {"zyj",      HB_TAG('Z','H','A',' ')},       /* Youjiang Zhuang -> Zhuang */
+  {"zyn",      HB_TAG('Z','H','A',' ')},       /* Yongnan Zhuang -> Zhuang */
+/*{"zza",      HB_TAG('Z','Z','A',' ')},*/     /* Zazaki [macrolanguage] */
+  {"zzj",      HB_TAG('Z','H','A',' ')},       /* Zuojiang Zhuang -> Zhuang */
 };
 
-static_assert (HB_OT_MAX_TAGS_PER_LANGUAGE == 3u, "");
-
 /**
  * hb_ot_tags_from_complex_language:
  * @lang_str: a BCP 47 language tag to convert.
@@ -1934,7 +1932,8 @@ hb_ot_tags_from_complex_language (const char   *lang_str,
  *
  * Converts @tag to a BCP 47 language tag if it is ambiguous (it corresponds to
  * many language tags) and the best tag is not the alphabetically first, or if
- * the best tag consists of multiple subtags.
+ * the best tag consists of multiple subtags, or if the best tag does not appear
+ * in #ot_languages.
  *
  * Return value: The #hb_language_t corresponding to the BCP 47 language tag,
  * or #HB_LANGUAGE_INVALID if @tag is not ambiguous.
@@ -1944,6 +1943,8 @@ hb_ot_ambiguous_tag_to_language (hb_tag_t tag)
 {
   switch (tag)
   {
+  case HB_TAG('A','L','T',' '):  /* Altai */
+    return hb_language_from_string ("alt", -1);  /* Southern Altai */
   case HB_TAG('A','P','P','H'):  /* Phonetic transcription—Americanist conventions */
     return hb_language_from_string ("und-fonnapa", -1);  /* Undetermined; North American Phonetic Alphabet */
   case HB_TAG('A','R','A',' '):  /* Arabic */
@@ -1962,8 +1963,6 @@ hb_ot_ambiguous_tag_to_language (hb_tag_t tag)
     return hb_language_from_string ("din", -1);  /* Dinka */
   case HB_TAG('D','R','I',' '):  /* Dari */
     return hb_language_from_string ("prs", -1);  /* Dari */
-  case HB_TAG('D','U','J',' '):  /* Dhuwal */
-    return hb_language_from_string ("dwu", -1);  /* Dhuwal */
   case HB_TAG('D','Z','N',' '):  /* Dzongkha */
     return hb_language_from_string ("dz", -1);  /* Dzongkha */
   case HB_TAG('E','T','I',' '):  /* Estonian */
@@ -1972,6 +1971,8 @@ hb_ot_ambiguous_tag_to_language (hb_tag_t tag)
     return hb_language_from_string ("gon", -1);  /* Gondi */
   case HB_TAG('H','M','N',' '):  /* Hmong */
     return hb_language_from_string ("hmn", -1);  /* Hmong */
+  case HB_TAG('H','N','D',' '):  /* Hindko */
+    return hb_language_from_string ("hnd", -1);  /* Southern Hindko */
   case HB_TAG('I','J','O',' '):  /* Ijo */
     return hb_language_from_string ("ijo", -1);  /* Ijo */
   case HB_TAG('I','N','U',' '):  /* Inuktitut */
index 751ccab..8ad917a 100644 (file)
@@ -28,6 +28,8 @@
 
 #include "hb.hh"
 
+#ifndef HB_NO_OT_TAG
+
 
 /* hb_script_t */
 
@@ -113,6 +115,7 @@ hb_ot_new_tag_to_script (hb_tag_t tag)
   return HB_SCRIPT_UNKNOWN;
 }
 
+#ifndef HB_DISABLE_DEPRECATED
 void
 hb_ot_tags_from_script (hb_script_t  script,
                        hb_tag_t    *script_tag_1,
@@ -124,6 +127,7 @@ hb_ot_tags_from_script (hb_script_t  script,
   *script_tag_1 = count > 0 ? tags[0] : HB_OT_TAG_DEFAULT_SCRIPT;
   *script_tag_2 = count > 1 ? tags[1] : HB_OT_TAG_DEFAULT_SCRIPT;
 }
+#endif
 
 /*
  * Complete list at:
@@ -143,7 +147,9 @@ hb_ot_all_tags_from_script (hb_script_t   script,
   hb_tag_t new_tag = hb_ot_new_tag_from_script (script);
   if (unlikely (new_tag != HB_OT_TAG_DEFAULT_SCRIPT))
   {
-    tags[i++] = new_tag | '3';
+    /* HB_SCRIPT_MYANMAR maps to 'mym2', but there is no 'mym3'. */
+    if (new_tag != HB_TAG('m','y','m','2'))
+      tags[i++] = new_tag | '3';
     if (*count > i)
       tags[i++] = new_tag;
   }
@@ -198,7 +204,7 @@ lang_matches (const char *lang_str, const char *spec)
 struct LangTag
 {
   char language[4];
-  hb_tag_t tags[HB_OT_MAX_TAGS_PER_LANGUAGE];
+  hb_tag_t tag;
 
   int cmp (const char *a) const
   {
@@ -212,7 +218,7 @@ struct LangTag
     p = strchr (b, '-');
     db = p ? (unsigned int) (p - b) : strlen (b);
 
-    return strncmp (a, b, MAX (da, db));
+    return strncmp (a, b, hb_max (da, db));
   }
   int cmp (const LangTag *that) const
   { return cmp (that->language); }
@@ -230,6 +236,7 @@ struct LangTag
 /*{"??",       {HB_TAG('Y','I','C',' ')}},*/   /* Yi Classic */
 /*{"zh?",      {HB_TAG('Z','H','P',' ')}},*/   /* Chinese Phonetic */
 
+#ifndef HB_DISABLE_DEPRECATED
 hb_tag_t
 hb_ot_tag_from_language (hb_language_t language)
 {
@@ -238,6 +245,7 @@ hb_ot_tag_from_language (hb_language_t language)
   hb_ot_tags_from_script_and_language (HB_SCRIPT_UNKNOWN, language, nullptr, nullptr, &count, tags);
   return count > 0 ? tags[0] : HB_OT_TAG_DEFAULT_LANGUAGE;
 }
+#endif
 
 static void
 hb_ot_tags_from_language (const char   *lang_str,
@@ -246,6 +254,7 @@ hb_ot_tags_from_language (const char   *lang_str,
                          hb_tag_t     *tags)
 {
   const char *s;
+  unsigned int tag_idx;
 
   /* Check for matches of multiple subtags. */
   if (hb_ot_tags_from_complex_language (lang_str, limit, count, tags))
@@ -254,7 +263,6 @@ hb_ot_tags_from_language (const char   *lang_str,
   /* Find a language matching in the first component. */
   s = strchr (lang_str, '-');
   {
-    const LangTag *lang_tag;
     if (s && limit - lang_str >= 6)
     {
       const char *extlang_end = strchr (s + 1, '-');
@@ -263,12 +271,18 @@ hb_ot_tags_from_language (const char   *lang_str,
          ISALPHA (s[1]))
        lang_str = s + 1;
     }
-    lang_tag = hb_sorted_array (ot_languages).bsearch (lang_str);
-    if (lang_tag)
+    if (hb_sorted_array (ot_languages).bfind (lang_str, &tag_idx))
     {
       unsigned int i;
-      for (i = 0; i < *count && lang_tag->tags[i] != HB_TAG_NONE; i++)
-       tags[i] = lang_tag->tags[i];
+      while (tag_idx != 0 &&
+            0 == strcmp (ot_languages[tag_idx].language, ot_languages[tag_idx - 1].language))
+       tag_idx--;
+      for (i = 0;
+          i < *count &&
+          tag_idx + i < ARRAY_LENGTH (ot_languages) &&
+          0 == strcmp (ot_languages[tag_idx + i].language, ot_languages[tag_idx].language);
+          i++)
+       tags[i] = ot_languages[tag_idx + i].tag;
       *count = i;
       return;
     }
@@ -293,28 +307,28 @@ parse_private_use_subtag (const char     *private_use_subtag,
                          const char     *prefix,
                          unsigned char (*normalize) (unsigned char))
 {
-  if (private_use_subtag && count && tags && *count)
-  {
-    const char *s = strstr (private_use_subtag, prefix);
-    if (s)
-    {
-      char tag[4];
-      int i;
-      s += strlen (prefix);
-      for (i = 0; i < 4 && ISALNUM (s[i]); i++)
-       tag[i] = normalize (s[i]);
-      if (i)
-      {
-       for (; i < 4; i++)
-         tag[i] = ' ';
-       tags[0] = HB_TAG (tag[0], tag[1], tag[2], tag[3]);
-       if ((tags[0] & 0xDFDFDFDF) == HB_OT_TAG_DEFAULT_SCRIPT)
-         tags[0] ^= ~0xDFDFDFDF;
-       *count = 1;
-       return false;
-      }
-    }
-  }
+#ifdef HB_NO_LANGUAGE_PRIVATE_SUBTAG
+  return false;
+#endif
+
+  if (!(private_use_subtag && count && tags && *count)) return false;
+
+  const char *s = strstr (private_use_subtag, prefix);
+  if (!s) return false;
+
+  char tag[4];
+  int i;
+  s += strlen (prefix);
+  for (i = 0; i < 4 && ISALNUM (s[i]); i++)
+    tag[i] = normalize (s[i]);
+  if (!i) return false;
+
+  for (; i < 4; i++)
+    tag[i] = ' ';
+  tags[0] = HB_TAG (tag[0], tag[1], tag[2], tag[3]);
+  if ((tags[0] & 0xDFDFDFDF) == HB_OT_TAG_DEFAULT_SCRIPT)
+    tags[0] ^= ~0xDFDFDFDF;
+  *count = 1;
   return true;
 }
 
@@ -382,8 +396,8 @@ hb_ot_tags_from_script_and_language (hb_script_t   script,
        limit = s;
     }
 
-    needs_script = parse_private_use_subtag (private_use_subtag, script_count, script_tags, "-hbsc", TOLOWER);
-    needs_language = parse_private_use_subtag (private_use_subtag, language_count, language_tags, "-hbot", TOUPPER);
+    needs_script = !parse_private_use_subtag (private_use_subtag, script_count, script_tags, "-hbsc", TOLOWER);
+    needs_language = !parse_private_use_subtag (private_use_subtag, language_count, language_tags, "-hbot", TOUPPER);
 
     if (needs_language && language_count && language_tags && *language_count)
       hb_ot_tags_from_language (lang_str, limit, language_count, language_tags);
@@ -417,20 +431,33 @@ hb_ot_tag_to_language (hb_tag_t tag)
   }
 
   for (i = 0; i < ARRAY_LENGTH (ot_languages); i++)
-    if (ot_languages[i].tags[0] == tag)
+    if (ot_languages[i].tag == tag)
       return hb_language_from_string (ot_languages[i].language, -1);
 
-  /* Else return a custom language in the form of "x-hbotABCD" */
+  /* If it's three letters long, assume it's ISO 639-3 and lower-case and use it
+   * (if it's not a registered tag, calling hb_ot_tag_from_language on the
+   * result might not return the same tag as the original tag).
+   * Else return a custom language in the form of "x-hbotABCD". */
   {
-    unsigned char buf[11] = "x-hbot";
+    char buf[11] = "x-hbot";
+    char *str = buf;
     buf[6] = tag >> 24;
     buf[7] = (tag >> 16) & 0xFF;
     buf[8] = (tag >> 8) & 0xFF;
     buf[9] = tag & 0xFF;
     if (buf[9] == 0x20)
+    {
       buf[9] = '\0';
+      if (ISALPHA (buf[6]) && ISALPHA (buf[7]) && ISALPHA (buf[8]))
+      {
+       buf[6] = TOLOWER (buf[6]);
+       buf[7] = TOLOWER (buf[7]);
+       buf[8] = TOLOWER (buf[8]);
+       str += 6;
+      }
+    }
     buf[10] = '\0';
-    return hb_language_from_string ((char *) buf, -1);
+    return hb_language_from_string (str, -1);
   }
 }
 
@@ -506,7 +533,7 @@ test_langs_sorted ()
   for (unsigned int i = 1; i < ARRAY_LENGTH (ot_languages); i++)
   {
     int c = ot_languages[i].cmp (&ot_languages[i - 1]);
-    if (c >= 0)
+    if (c > 0)
     {
       fprintf (stderr, "ot_languages not sorted at index %d: %s %d %s\n",
               i, ot_languages[i-1].language, c, ot_languages[i].language);
@@ -523,3 +550,6 @@ main ()
 }
 
 #endif
+
+
+#endif
index c4a192d..ef8ba3f 100644 (file)
@@ -49,9 +49,10 @@ struct AxisValueMap
   }
 
   public:
-  F2DOT14      fromCoord;      /* A normalized coordinate value obtained using
-                                * default normalization. */
-  F2DOT14      toCoord;        /* The modified, normalized coordinate value. */
+  F2DOT14      coords[2];
+//   F2DOT14   fromCoord;      /* A normalized coordinate value obtained using
+//                              * default normalization. */
+//   F2DOT14   toCoord;        /* The modified, normalized coordinate value. */
 
   public:
   DEFINE_SIZE_STATIC (4);
@@ -59,12 +60,13 @@ struct AxisValueMap
 
 struct SegmentMaps : ArrayOf<AxisValueMap>
 {
-  int map (int value) const
+  int map (int value, unsigned int from_offset = 0, unsigned int to_offset = 1) const
   {
+#define fromCoord coords[from_offset]
+#define toCoord coords[to_offset]
     /* The following special-cases are not part of OpenType, which requires
      * that at least -1, 0, and +1 must be mapped. But we include these as
      * part of a better error recovery scheme. */
-
     if (len < 2)
     {
       if (!len)
@@ -91,8 +93,12 @@ struct SegmentMaps : ArrayOf<AxisValueMap>
     return arrayZ[i-1].toCoord +
           ((arrayZ[i].toCoord - arrayZ[i-1].toCoord) *
            (value - arrayZ[i-1].fromCoord) + denom/2) / denom;
+#undef toCoord
+#undef fromCoord
   }
 
+  int unmap (int value) const { return map (value, 1, 0); }
+
   public:
   DEFINE_SIZE_ARRAY (2, *this);
 };
@@ -114,7 +120,7 @@ struct avar
     for (unsigned int i = 0; i < count; i++)
     {
       if (unlikely (!map->sanitize (c)))
-        return_trace (false);
+       return_trace (false);
       map = &StructAfter<SegmentMaps> (*map);
     }
 
@@ -123,7 +129,7 @@ struct avar
 
   void map_coords (int *coords, unsigned int coords_length) const
   {
-    unsigned int count = MIN<unsigned int> (coords_length, axisCount);
+    unsigned int count = hb_min (coords_length, axisCount);
 
     const SegmentMaps *map = &firstAxisSegmentMaps;
     for (unsigned int i = 0; i < count; i++)
@@ -133,6 +139,18 @@ struct avar
     }
   }
 
+  void unmap_coords (int *coords, unsigned int coords_length) const
+  {
+    unsigned int count = hb_min (coords_length, axisCount);
+
+    const SegmentMaps *map = &firstAxisSegmentMaps;
+    for (unsigned int i = 0; i < count; i++)
+    {
+      coords[i] = map->unmap (coords[i]);
+      map = &StructAfter<SegmentMaps> (*map);
+    }
+  }
+
   protected:
   FixedVersion<>version;       /* Version of the avar table
                                 * initially set to 0x00010000u */
@@ -140,7 +158,7 @@ struct avar
   HBUINT16     axisCount;      /* The number of variation axes in the font. This
                                 * must be the same number as axisCount in the
                                 * 'fvar' table. */
-  SegmentMaps   firstAxisSegmentMaps;
+  SegmentMaps  firstAxisSegmentMaps;
 
   public:
   DEFINE_SIZE_MIN (8);
index 78cb3c8..7ce3123 100644 (file)
@@ -44,7 +44,7 @@ struct InstanceRecord
 {
   friend struct fvar;
 
-  hb_array_t<const Fixed> get_coordinates (unsigned int axis_count) const
+  hb_array_t<const HBFixed> get_coordinates (unsigned int axis_count) const
   { return coordinatesZ.as_array (axis_count); }
 
   bool sanitize (hb_sanitize_context_t *c, unsigned int axis_count) const
@@ -58,7 +58,7 @@ struct InstanceRecord
   NameID       subfamilyNameID;/* The name ID for entries in the 'name' table
                                 * that provide subfamily names for this instance. */
   HBUINT16     flags;          /* Reserved for future use — set to 0. */
-  UnsizedArrayOf<Fixed>
+  UnsizedArrayOf<HBFixed>
                coordinatesZ;   /* The coordinates array for this instance. */
   //NameID     postScriptNameIDX;/*Optional. The name ID for entries in the 'name'
   //                             * table that provide PostScript names for this
@@ -83,9 +83,9 @@ struct AxisRecord
 
   public:
   Tag          axisTag;        /* Tag identifying the design variation for the axis. */
-  Fixed                minValue;       /* The minimum coordinate value for the axis. */
-  Fixed                defaultValue;   /* The default coordinate value for the axis. */
-  Fixed                maxValue;       /* The maximum coordinate value for the axis. */
+  HBFixed              minValue;       /* The minimum coordinate value for the axis. */
+  HBFixed              defaultValue;   /* The default coordinate value for the axis. */
+  HBFixed              maxValue;       /* The maximum coordinate value for the axis. */
   HBUINT16     flags;          /* Axis flags. */
   NameID       axisNameID;     /* The name ID for entries in the 'name' table that
                                 * provide a display name for this axis. */
@@ -114,17 +114,19 @@ struct fvar
 
   unsigned int get_axis_count () const { return axisCount; }
 
+#ifndef HB_DISABLE_DEPRECATED
   void get_axis_deprecated (unsigned int axis_index,
                                   hb_ot_var_axis_t *info) const
   {
     const AxisRecord &axis = get_axes ()[axis_index];
     info->tag = axis.axisTag;
     info->name_id =  axis.axisNameID;
-    info->default_value = axis.defaultValue / 65536.;
+    info->default_value = axis.defaultValue / 65536.f;
     /* Ensure order, to simplify client math. */
-    info->min_value = MIN<float> (info->default_value, axis.minValue / 65536.);
-    info->max_value = MAX<float> (info->default_value, axis.maxValue / 65536.);
+    info->min_value = hb_min (info->default_value, axis.minValue / 65536.f);
+    info->max_value = hb_max (info->default_value, axis.maxValue / 65536.f);
   }
+#endif
 
   void get_axis_info (unsigned int axis_index,
                      hb_ot_var_axis_info_t *info) const
@@ -134,13 +136,14 @@ struct fvar
     info->tag = axis.axisTag;
     info->name_id =  axis.axisNameID;
     info->flags = (hb_ot_var_axis_flags_t) (unsigned int) axis.flags;
-    info->default_value = axis.defaultValue / 65536.;
+    info->default_value = axis.defaultValue / 65536.f;
     /* Ensure order, to simplify client math. */
-    info->min_value = MIN<float> (info->default_value, axis.minValue / 65536.);
-    info->max_value = MAX<float> (info->default_value, axis.maxValue / 65536.);
+    info->min_value = hb_min (info->default_value, axis.minValue / 65536.f);
+    info->max_value = hb_max (info->default_value, axis.maxValue / 65536.f);
     info->reserved = 0;
   }
 
+#ifndef HB_DISABLE_DEPRECATED
   unsigned int get_axes_deprecated (unsigned int      start_offset,
                                    unsigned int     *axes_count /* IN/OUT */,
                                    hb_ot_var_axis_t *axes_array /* OUT */) const
@@ -149,12 +152,12 @@ struct fvar
     {
       /* TODO Rewrite as hb_array_t<>::sub-array() */
       unsigned int count = axisCount;
-      start_offset = MIN (start_offset, count);
+      start_offset = hb_min (start_offset, count);
 
       count -= start_offset;
       axes_array += start_offset;
 
-      count = MIN (count, *axes_count);
+      count = hb_min (count, *axes_count);
       *axes_count = count;
 
       for (unsigned int i = 0; i < count; i++)
@@ -162,6 +165,7 @@ struct fvar
     }
     return axisCount;
   }
+#endif
 
   unsigned int get_axis_infos (unsigned int           start_offset,
                               unsigned int          *axes_count /* IN/OUT */,
@@ -171,12 +175,12 @@ struct fvar
     {
       /* TODO Rewrite as hb_array_t<>::sub-array() */
       unsigned int count = axisCount;
-      start_offset = MIN (start_offset, count);
+      start_offset = hb_min (start_offset, count);
 
       count -= start_offset;
       axes_array += start_offset;
 
-      count = MIN (count, *axes_count);
+      count = hb_min (count, *axes_count);
       *axes_count = count;
 
       for (unsigned int i = 0; i < count; i++)
@@ -185,6 +189,7 @@ struct fvar
     return axisCount;
   }
 
+#ifndef HB_DISABLE_DEPRECATED
   bool find_axis_deprecated (hb_tag_t tag,
                             unsigned int *axis_index,
                             hb_ot_var_axis_t *info) const
@@ -194,7 +199,7 @@ struct fvar
     for (unsigned int i = 0; i < count; i++)
       if (axes[i].axisTag == tag)
       {
-        if (axis_index)
+       if (axis_index)
          *axis_index = i;
        get_axis_deprecated (i, info);
        return true;
@@ -203,6 +208,7 @@ struct fvar
       *axis_index = HB_OT_VAR_NO_AXIS_INDEX;
     return false;
   }
+#endif
 
   bool find_axis_info (hb_tag_t tag,
                       hb_ot_var_axis_info_t *info) const
@@ -223,7 +229,7 @@ struct fvar
     hb_ot_var_axis_info_t axis;
     get_axis_info (axis_index, &axis);
 
-    v = MAX (MIN (v, axis.max_value), axis.min_value); /* Clamp. */
+    v = hb_max (hb_min (v, axis.max_value), axis.min_value); /* Clamp. */
 
     if (v == axis.default_value)
       return 0;
@@ -231,7 +237,21 @@ struct fvar
       v = (v - axis.default_value) / (axis.default_value - axis.min_value);
     else
       v = (v - axis.default_value) / (axis.max_value - axis.default_value);
-    return (int) (v * 16384.f + (v >= 0.f ? .5f : -.5f));
+    return roundf (v * 16384.f);
+  }
+
+  float unnormalize_axis_value (unsigned int axis_index, float v) const
+  {
+    hb_ot_var_axis_info_t axis;
+    get_axis_info (axis_index, &axis);
+
+    if (v == 0)
+      return axis.default_value;
+    else if (v < 0)
+      v = v * (axis.default_value - axis.min_value) / 16384.f + axis.default_value;
+    else
+      v = v * (axis.max_value - axis.default_value) / 16384.f + axis.default_value;
+    return v;
   }
 
   unsigned int get_instance_count () const { return instanceCount; }
@@ -253,27 +273,48 @@ struct fvar
   }
 
   unsigned int get_instance_coords (unsigned int  instance_index,
-                                          unsigned int *coords_length, /* IN/OUT */
-                                          float        *coords         /* OUT */) const
+                                   unsigned int *coords_length, /* IN/OUT */
+                                   float        *coords         /* OUT */) const
   {
     const InstanceRecord *instance = get_instance (instance_index);
     if (unlikely (!instance))
     {
       if (coords_length)
-        *coords_length = 0;
+       *coords_length = 0;
       return 0;
     }
 
     if (coords_length && *coords_length)
     {
-      hb_array_t<const Fixed> instanceCoords = instance->get_coordinates (axisCount)
+      hb_array_t<const HBFixed> instanceCoords = instance->get_coordinates (axisCount)
                                                         .sub_array (0, *coords_length);
       for (unsigned int i = 0; i < instanceCoords.length; i++)
-        coords[i] = instanceCoords.arrayZ[i].to_float ();
+       coords[i] = instanceCoords.arrayZ[i].to_float ();
     }
     return axisCount;
   }
 
+  void collect_name_ids (hb_set_t *nameids) const
+  {
+    if (!has_data ()) return;
+
+    + get_axes ()
+    | hb_map (&AxisRecord::axisNameID)
+    | hb_sink (nameids)
+    ;
+
+    + hb_range ((unsigned) instanceCount)
+    | hb_map ([this] (const unsigned _) { return get_instance_subfamily_name_id (_); })
+    | hb_sink (nameids)
+    ;
+
+    + hb_range ((unsigned) instanceCount)
+    | hb_map ([this] (const unsigned _) { return get_instance_postscript_name_id (_); })
+    | hb_sink (nameids)
+    ;
+  }
+
+
   protected:
   hb_array_t<const AxisRecord> get_axes () const
   { return hb_array (&(this+firstAxis), axisCount); }
@@ -299,8 +340,8 @@ struct fvar
   HBUINT16     instanceCount;  /* The number of named instances defined in the font
                                 * (the number of records in the instances array). */
   HBUINT16     instanceSize;   /* The size in bytes of each InstanceRecord — set
-                                * to either axisCount * sizeof(Fixed) + 4, or to
-                                * axisCount * sizeof(Fixed) + 6. */
+                                * to either axisCount * sizeof(HBFixed) + 4, or to
+                                * axisCount * sizeof(HBFixed) + 6. */
 
   public:
   DEFINE_SIZE_STATIC (16);
diff --git a/src/hb-ot-var-gvar-table.hh b/src/hb-ot-var-gvar-table.hh
new file mode 100644 (file)
index 0000000..a76121d
--- /dev/null
@@ -0,0 +1,717 @@
+/*
+ * Copyright © 2019  Adobe Inc.
+ * Copyright © 2019  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.
+ *
+ * Adobe Author(s): Michiharu Ariza
+ */
+
+#ifndef HB_OT_VAR_GVAR_TABLE_HH
+#define HB_OT_VAR_GVAR_TABLE_HH
+
+#include "hb-open-type.hh"
+#include "hb-ot-glyf-table.hh"
+#include "hb-ot-var-fvar-table.hh"
+
+/*
+ * gvar -- Glyph Variation Table
+ * https://docs.microsoft.com/en-us/typography/opentype/spec/gvar
+ */
+#define HB_OT_TAG_gvar HB_TAG('g','v','a','r')
+
+namespace OT {
+
+struct contour_point_t
+{
+  void init (float x_=0.f, float y_=0.f) { flag = 0; x = x_; y = y_; }
+
+  void translate (const contour_point_t &p) { x += p.x; y += p.y; }
+
+  uint8_t flag;
+  float x, y;
+};
+
+struct contour_point_vector_t : hb_vector_t<contour_point_t>
+{
+  void extend (const hb_array_t<contour_point_t> &a)
+  {
+    unsigned int old_len = length;
+    resize (old_len + a.length);
+    for (unsigned int i = 0; i < a.length; i++)
+      (*this)[old_len + i] = a[i];
+  }
+
+  void transform (const float (&matrix)[4])
+  {
+    for (unsigned int i = 0; i < length; i++)
+    {
+      contour_point_t &p = (*this)[i];
+      float x_ = p.x * matrix[0] + p.y * matrix[2];
+          p.y = p.x * matrix[1] + p.y * matrix[3];
+      p.x = x_;
+    }
+  }
+
+  void translate (const contour_point_t& delta)
+  {
+    for (unsigned int i = 0; i < length; i++)
+      (*this)[i].translate (delta);
+  }
+};
+
+struct Tuple : UnsizedArrayOf<F2DOT14> {};
+
+struct TuppleIndex : HBUINT16
+{
+  enum Flags {
+    EmbeddedPeakTuple   = 0x8000u,
+    IntermediateRegion  = 0x4000u,
+    PrivatePointNumbers = 0x2000u,
+    TupleIndexMask      = 0x0FFFu
+  };
+
+  DEFINE_SIZE_STATIC (2);
+};
+
+struct TupleVarHeader
+{
+  unsigned int get_size (unsigned int axis_count) const
+  {
+    return min_size +
+          (has_peak () ? get_peak_tuple ().get_size (axis_count) : 0) +
+          (has_intermediate () ? (get_start_tuple (axis_count).get_size (axis_count) +
+                                  get_end_tuple (axis_count).get_size (axis_count)) : 0);
+  }
+
+  const TupleVarHeader &get_next (unsigned int axis_count) const
+  { return StructAtOffset<TupleVarHeader> (this, get_size (axis_count)); }
+
+  float calculate_scalar (const int *coords, unsigned int coord_count,
+                         const hb_array_t<const F2DOT14> shared_tuples) const
+  {
+    const F2DOT14 *peak_tuple;
+
+    if (has_peak ())
+      peak_tuple = &(get_peak_tuple ()[0]);
+    else
+    {
+      unsigned int index = get_index ();
+      if (unlikely (index * coord_count >= shared_tuples.length))
+       return 0.f;
+      peak_tuple = &shared_tuples[coord_count * index];
+    }
+
+    const F2DOT14 *start_tuple = nullptr;
+    const F2DOT14 *end_tuple = nullptr;
+    if (has_intermediate ())
+    {
+      start_tuple = get_start_tuple (coord_count);
+      end_tuple = get_end_tuple (coord_count);
+    }
+
+    float scalar = 1.f;
+    for (unsigned int i = 0; i < coord_count; i++)
+    {
+      int v = coords[i];
+      int peak = peak_tuple[i];
+      if (!peak || v == peak) continue;
+
+      if (has_intermediate ())
+      {
+       int start = start_tuple[i];
+       int end = end_tuple[i];
+       if (unlikely (start > peak || peak > end ||
+                     (start < 0 && end > 0 && peak))) continue;
+       if (v < start || v > end) return 0.f;
+       if (v < peak)
+       { if (peak != start) scalar *= (float) (v - start) / (peak - start); }
+       else
+       { if (peak != end) scalar *= (float) (end - v) / (end - peak); }
+      }
+      else if (!v || v < hb_min (0, peak) || v > hb_max (0, peak)) return 0.f;
+      else
+       scalar *= (float) v / peak;
+    }
+    return scalar;
+  }
+
+  unsigned int get_data_size () const { return varDataSize; }
+
+  bool           has_peak () const { return (tupleIndex & TuppleIndex::EmbeddedPeakTuple); }
+  bool   has_intermediate () const { return (tupleIndex & TuppleIndex::IntermediateRegion); }
+  bool has_private_points () const { return (tupleIndex & TuppleIndex::PrivatePointNumbers); }
+  unsigned int  get_index () const { return (tupleIndex & TuppleIndex::TupleIndexMask); }
+
+  protected:
+  const Tuple &get_peak_tuple () const
+  { return StructAfter<Tuple> (tupleIndex); }
+  const Tuple &get_start_tuple (unsigned int axis_count) const
+  { return *(const Tuple *) &get_peak_tuple ()[has_peak () ? axis_count : 0]; }
+  const Tuple &get_end_tuple (unsigned int axis_count) const
+  { return *(const Tuple *) &get_peak_tuple ()[has_peak () ? (axis_count * 2) : axis_count]; }
+
+  HBUINT16             varDataSize;
+  TuppleIndex          tupleIndex;
+  /* UnsizedArrayOf<F2DOT14> peakTuple - optional */
+  /* UnsizedArrayOf<F2DOT14> intermediateStartTuple - optional */
+  /* UnsizedArrayOf<F2DOT14> intermediateEndTuple - optional */
+
+  public:
+  DEFINE_SIZE_MIN (4);
+};
+
+struct TupleVarCount : HBUINT16
+{
+  bool has_shared_point_numbers () const { return ((*this) & SharedPointNumbers); }
+  unsigned int get_count () const { return (*this) & CountMask; }
+
+  protected:
+  enum Flags
+  {
+    SharedPointNumbers = 0x8000u,
+    CountMask          = 0x0FFFu
+  };
+
+  public:
+  DEFINE_SIZE_STATIC (2);
+};
+
+struct GlyphVarData
+{
+  const TupleVarHeader &get_tuple_var_header (void) const
+  { return StructAfter<TupleVarHeader> (data); }
+
+  struct tuple_iterator_t
+  {
+    void init (const GlyphVarData *var_data_, unsigned int length_, unsigned int axis_count_)
+    {
+      var_data = var_data_;
+      length = length_;
+      index = 0;
+      axis_count = axis_count_;
+      current_tuple = &var_data->get_tuple_var_header ();
+      data_offset = 0;
+    }
+
+    bool get_shared_indices (hb_vector_t<unsigned int> &shared_indices /* OUT */)
+    {
+      if (var_data->has_shared_point_numbers ())
+      {
+       hb_bytes_t bytes ((const char *) var_data, length);
+       const HBUINT8 *base = &(var_data+var_data->data);
+       const HBUINT8 *p = base;
+       if (!unpack_points (p, shared_indices, bytes)) return false;
+       data_offset = p - base;
+      }
+      return true;
+    }
+
+    bool is_valid () const
+    {
+      return (index < var_data->tupleVarCount.get_count ()) &&
+            in_range (current_tuple) &&
+            current_tuple->get_size (axis_count);
+    }
+
+    bool move_to_next ()
+    {
+      data_offset += current_tuple->get_data_size ();
+      current_tuple = &current_tuple->get_next (axis_count);
+      index++;
+      return is_valid ();
+    }
+
+    bool in_range (const void *p, unsigned int l) const
+    { return (const char*) p >= (const char*) var_data && (const char*) p+l <= (const char*) var_data + length; }
+
+    template <typename T> bool in_range (const T *p) const { return in_range (p, sizeof (*p)); }
+
+    const HBUINT8 *get_serialized_data () const
+    { return &(var_data+var_data->data) + data_offset; }
+
+    private:
+    const GlyphVarData *var_data;
+    unsigned int length;
+    unsigned int index;
+    unsigned int axis_count;
+    unsigned int data_offset;
+
+    public:
+    const TupleVarHeader *current_tuple;
+  };
+
+  static bool get_tuple_iterator (const GlyphVarData *var_data,
+                                 unsigned int length,
+                                 unsigned int axis_count,
+                                 hb_vector_t<unsigned int> &shared_indices /* OUT */,
+                                 tuple_iterator_t *iterator /* OUT */)
+  {
+    iterator->init (var_data, length, axis_count);
+    if (!iterator->get_shared_indices (shared_indices))
+      return false;
+    return iterator->is_valid ();
+  }
+
+  bool has_shared_point_numbers () const { return tupleVarCount.has_shared_point_numbers (); }
+
+  static bool unpack_points (const HBUINT8 *&p /* IN/OUT */,
+                            hb_vector_t<unsigned int> &points /* OUT */,
+                            const hb_bytes_t &bytes)
+  {
+    enum packed_point_flag_t
+    {
+      POINTS_ARE_WORDS     = 0x80,
+      POINT_RUN_COUNT_MASK = 0x7F
+    };
+
+    if (unlikely (!bytes.in_range (p))) return false;
+
+    uint16_t count = *p++;
+    if (count & POINTS_ARE_WORDS)
+    {
+      if (unlikely (!bytes.in_range (p))) return false;
+      count = ((count & POINT_RUN_COUNT_MASK) << 8) | *p++;
+    }
+    points.resize (count);
+
+    unsigned int n = 0;
+    uint16_t i = 0;
+    while (i < count)
+    {
+      if (unlikely (!bytes.in_range (p))) return false;
+      uint16_t j;
+      uint8_t control = *p++;
+      uint16_t run_count = (control & POINT_RUN_COUNT_MASK) + 1;
+      if (control & POINTS_ARE_WORDS)
+      {
+       for (j = 0; j < run_count && i < count; j++, i++)
+       {
+         if (unlikely (!bytes.in_range ((const HBUINT16 *) p)))
+           return false;
+         n += *(const HBUINT16 *)p;
+         points[i] = n;
+         p += HBUINT16::static_size;
+       }
+      }
+      else
+      {
+       for (j = 0; j < run_count && i < count; j++, i++)
+       {
+         if (unlikely (!bytes.in_range (p))) return false;
+         n += *p++;
+         points[i] = n;
+       }
+      }
+      if (j < run_count) return false;
+    }
+    return true;
+  }
+
+  static bool unpack_deltas (const HBUINT8 *&p /* IN/OUT */,
+                            hb_vector_t<int> &deltas /* IN/OUT */,
+                            const hb_bytes_t &bytes)
+  {
+    enum packed_delta_flag_t
+    {
+      DELTAS_ARE_ZERO      = 0x80,
+      DELTAS_ARE_WORDS     = 0x40,
+      DELTA_RUN_COUNT_MASK = 0x3F
+    };
+
+    unsigned int i = 0;
+    unsigned int count = deltas.length;
+    while (i < count)
+    {
+      if (unlikely (!bytes.in_range (p))) return false;
+      uint8_t control = *p++;
+      unsigned int run_count = (control & DELTA_RUN_COUNT_MASK) + 1;
+      unsigned int j;
+      if (control & DELTAS_ARE_ZERO)
+       for (j = 0; j < run_count && i < count; j++, i++)
+         deltas[i] = 0;
+      else if (control & DELTAS_ARE_WORDS)
+       for (j = 0; j < run_count && i < count; j++, i++)
+       {
+         if (unlikely (!bytes.in_range ((const HBUINT16 *) p)))
+           return false;
+         deltas[i] = *(const HBINT16 *) p;
+         p += HBUINT16::static_size;
+       }
+      else
+       for (j = 0; j < run_count && i < count; j++, i++)
+       {
+         if (unlikely (!bytes.in_range (p)))
+           return false;
+         deltas[i] = *(const HBINT8 *) p++;
+       }
+      if (j < run_count)
+       return false;
+    }
+    return true;
+  }
+
+  protected:
+  TupleVarCount                tupleVarCount;
+  OffsetTo<HBUINT8>    data;
+  /* TupleVarHeader tupleVarHeaders[] */
+  public:
+  DEFINE_SIZE_MIN (4);
+};
+
+struct gvar
+{
+  static constexpr hb_tag_t tableTag = HB_OT_TAG_gvar;
+
+  bool sanitize_shallow (hb_sanitize_context_t *c) const
+  {
+    TRACE_SANITIZE (this);
+    return_trace (c->check_struct (this) && (version.major == 1) &&
+                 (glyphCount == c->get_num_glyphs ()) &&
+                 c->check_array (&(this+sharedTuples), axisCount * sharedTupleCount) &&
+                 (is_long_offset () ?
+                    c->check_array (get_long_offset_array (), glyphCount+1) :
+                    c->check_array (get_short_offset_array (), glyphCount+1)) &&
+                 c->check_array (((const HBUINT8*)&(this+dataZ)) + get_offset (0),
+                                 get_offset (glyphCount) - get_offset (0)));
+  }
+
+  /* GlyphVarData not sanitized here; must be checked while accessing each glyph varation data */
+  bool sanitize (hb_sanitize_context_t *c) const
+  { return sanitize_shallow (c); }
+
+  bool subset (hb_subset_context_t *c) const
+  {
+    TRACE_SUBSET (this);
+
+    gvar *out = c->serializer->allocate_min<gvar> ();
+    if (unlikely (!out)) return_trace (false);
+
+    out->version.major = 1;
+    out->version.minor = 0;
+    out->axisCount = axisCount;
+    out->sharedTupleCount = sharedTupleCount;
+
+    unsigned int num_glyphs = c->plan->num_output_glyphs ();
+    out->glyphCount = num_glyphs;
+
+    unsigned int subset_data_size = 0;
+    for (hb_codepoint_t gid = 0; gid < num_glyphs; gid++)
+    {
+      hb_codepoint_t old_gid;
+      if (!c->plan->old_gid_for_new_gid (gid, &old_gid)) continue;
+      subset_data_size += get_glyph_var_data_length (old_gid);
+    }
+
+    bool long_offset = subset_data_size & ~0xFFFFu;
+    out->flags = long_offset ? 1 : 0;
+
+    HBUINT8 *subset_offsets = c->serializer->allocate_size<HBUINT8> ((long_offset ? 4 : 2) * (num_glyphs + 1));
+    if (!subset_offsets) return_trace (false);
+
+    /* shared tuples */
+    if (!sharedTupleCount || !sharedTuples)
+      out->sharedTuples = 0;
+    else
+    {
+      unsigned int shared_tuple_size = F2DOT14::static_size * axisCount * sharedTupleCount;
+      F2DOT14 *tuples = c->serializer->allocate_size<F2DOT14> (shared_tuple_size);
+      if (!tuples) return_trace (false);
+      out->sharedTuples = (char *) tuples - (char *) out;
+      memcpy (tuples, &(this+sharedTuples), shared_tuple_size);
+    }
+
+    char *subset_data = c->serializer->allocate_size<char> (subset_data_size);
+    if (!subset_data) return_trace (false);
+    out->dataZ = subset_data - (char *)out;
+
+    unsigned int glyph_offset = 0;
+    for (hb_codepoint_t gid = 0; gid < num_glyphs; gid++)
+    {
+      hb_codepoint_t old_gid;
+      unsigned int length = c->plan->old_gid_for_new_gid (gid, &old_gid) ? get_glyph_var_data_length (old_gid) : 0;
+
+      if (long_offset)
+       ((HBUINT32 *) subset_offsets)[gid] = glyph_offset;
+      else
+       ((HBUINT16 *) subset_offsets)[gid] = glyph_offset / 2;
+
+      if (length > 0) memcpy (subset_data, get_glyph_var_data (old_gid), length);
+      subset_data += length;
+      glyph_offset += length;
+    }
+    if (long_offset)
+      ((HBUINT32 *) subset_offsets)[num_glyphs] = glyph_offset;
+    else
+      ((HBUINT16 *) subset_offsets)[num_glyphs] = glyph_offset / 2;
+
+    return_trace (true);
+  }
+
+  protected:
+  const GlyphVarData *get_glyph_var_data (hb_codepoint_t glyph) const
+  {
+    unsigned int start_offset = get_offset (glyph);
+    unsigned int end_offset = get_offset (glyph+1);
+
+    if ((start_offset == end_offset) ||
+       unlikely ((start_offset > get_offset (glyphCount)) ||
+                 (start_offset + GlyphVarData::min_size > end_offset)))
+      return &Null (GlyphVarData);
+    return &(((unsigned char *) this + start_offset) + dataZ);
+  }
+
+  bool is_long_offset () const { return (flags & 1) != 0; }
+
+  unsigned int get_offset (unsigned int i) const
+  {
+    if (is_long_offset ())
+      return get_long_offset_array ()[i];
+    else
+      return get_short_offset_array ()[i] * 2;
+  }
+
+  unsigned int get_glyph_var_data_length (unsigned int glyph) const
+  {
+    unsigned int end_offset = get_offset (glyph + 1);
+    unsigned int start_offset = get_offset (glyph);
+    if (unlikely (start_offset > end_offset || end_offset > get_offset (glyphCount)))
+      return 0;
+    return end_offset - start_offset;
+  }
+
+  const HBUINT32 * get_long_offset_array () const { return (const HBUINT32 *) &offsetZ; }
+  const HBUINT16 *get_short_offset_array () const { return (const HBUINT16 *) &offsetZ; }
+
+  public:
+  struct accelerator_t
+  {
+    void init (hb_face_t *face)
+    {
+      gvar_table = hb_sanitize_context_t ().reference_table<gvar> (face);
+      hb_blob_ptr_t<fvar> fvar_table = hb_sanitize_context_t ().reference_table<fvar> (face);
+      unsigned int axis_count = fvar_table->get_axis_count ();
+      fvar_table.destroy ();
+
+      if (unlikely ((gvar_table->glyphCount != face->get_num_glyphs ()) ||
+                   (gvar_table->axisCount != axis_count)))
+       fini ();
+
+      unsigned int num_shared_coord = gvar_table->sharedTupleCount * gvar_table->axisCount;
+      shared_tuples.resize (num_shared_coord);
+      for (unsigned int i = 0; i < num_shared_coord; i++)
+       shared_tuples[i] = (&(gvar_table + gvar_table->sharedTuples))[i];
+    }
+
+    void fini ()
+    {
+      gvar_table.destroy ();
+      shared_tuples.fini ();
+    }
+
+    private:
+    struct x_getter { static float get (const contour_point_t &p) { return p.x; } };
+    struct y_getter { static float get (const contour_point_t &p) { return p.y; } };
+
+    template <typename T>
+    static float infer_delta (const hb_array_t<contour_point_t> points,
+                             const hb_array_t<contour_point_t> deltas,
+                             unsigned int target, unsigned int prev, unsigned int next)
+    {
+      float target_val = T::get (points[target]);
+      float prev_val = T::get (points[prev]);
+      float next_val = T::get (points[next]);
+      float prev_delta = T::get (deltas[prev]);
+      float next_delta = T::get (deltas[next]);
+
+      if (prev_val == next_val)
+       return (prev_delta == next_delta) ? prev_delta : 0.f;
+      else if (target_val <= hb_min (prev_val, next_val))
+       return (prev_val < next_val) ? prev_delta : next_delta;
+      else if (target_val >= hb_max (prev_val, next_val))
+       return (prev_val > next_val) ? prev_delta : next_delta;
+
+      /* linear interpolation */
+      float r = (target_val - prev_val) / (next_val - prev_val);
+      return (1.f - r) * prev_delta + r * next_delta;
+    }
+
+    static unsigned int next_index (unsigned int i, unsigned int start, unsigned int end)
+    { return (i >= end) ? start : (i + 1); }
+
+    public:
+    bool apply_deltas_to_points (hb_codepoint_t glyph,
+                                const int *coords, unsigned int coord_count,
+                                const hb_array_t<contour_point_t> points,
+                                const hb_array_t<unsigned int> end_points) const
+    {
+      if (unlikely (coord_count != gvar_table->axisCount)) return false;
+
+      const GlyphVarData *var_data = gvar_table->get_glyph_var_data (glyph);
+      if (var_data == &Null (GlyphVarData)) return true;
+      hb_vector_t<unsigned int> shared_indices;
+      GlyphVarData::tuple_iterator_t iterator;
+      if (!GlyphVarData::get_tuple_iterator (var_data,
+                                            gvar_table->get_glyph_var_data_length (glyph),
+                                            gvar_table->axisCount,
+                                            shared_indices,
+                                            &iterator))
+       return false;
+
+      /* Save original points for inferred delta calculation */
+      contour_point_vector_t orig_points;
+      orig_points.resize (points.length);
+      for (unsigned int i = 0; i < orig_points.length; i++)
+       orig_points[i] = points[i];
+
+      contour_point_vector_t deltas; /* flag is used to indicate referenced point */
+      deltas.resize (points.length);
+
+      do
+      {
+       float scalar = iterator.current_tuple->calculate_scalar (coords, coord_count, shared_tuples.as_array ());
+       if (scalar == 0.f) continue;
+       const HBUINT8 *p = iterator.get_serialized_data ();
+       unsigned int length = iterator.current_tuple->get_data_size ();
+       if (unlikely (!iterator.in_range (p, length)))
+         return false;
+
+       hb_bytes_t bytes ((const char *) p, length);
+       hb_vector_t<unsigned int> private_indices;
+       if (iterator.current_tuple->has_private_points () &&
+           !GlyphVarData::unpack_points (p, private_indices, bytes))
+         return false;
+       const hb_array_t<unsigned int> &indices = private_indices.length ? private_indices : shared_indices;
+
+       bool apply_to_all = (indices.length == 0);
+       unsigned int num_deltas = apply_to_all ? points.length : indices.length;
+       hb_vector_t<int> x_deltas;
+       x_deltas.resize (num_deltas);
+       if (!GlyphVarData::unpack_deltas (p, x_deltas, bytes))
+         return false;
+       hb_vector_t<int> y_deltas;
+       y_deltas.resize (num_deltas);
+       if (!GlyphVarData::unpack_deltas (p, y_deltas, bytes))
+         return false;
+
+       for (unsigned int i = 0; i < deltas.length; i++)
+         deltas[i].init ();
+       for (unsigned int i = 0; i < num_deltas; i++)
+       {
+         unsigned int pt_index = apply_to_all ? i : indices[i];
+         deltas[pt_index].flag = 1;    /* this point is referenced, i.e., explicit deltas specified */
+         deltas[pt_index].x += x_deltas[i] * scalar;
+         deltas[pt_index].y += y_deltas[i] * scalar;
+       }
+
+       /* infer deltas for unreferenced points */
+       unsigned int start_point = 0;
+       for (unsigned int c = 0; c < end_points.length; c++)
+       {
+         unsigned int end_point = end_points[c];
+         unsigned int i, j;
+
+         /* Check the number of unreferenced points in a contour. If no unref points or no ref points, nothing to do. */
+         unsigned int unref_count = 0;
+         for (i = start_point; i <= end_point; i++)
+           if (!deltas[i].flag) unref_count++;
+         if (unref_count == 0 || unref_count > end_point - start_point)
+           goto no_more_gaps;
+
+         j = start_point;
+         for (;;)
+         {
+           /* Locate the next gap of unreferenced points between two referenced points prev and next.
+            * Note that a gap may wrap around at left (start_point) and/or at right (end_point).
+            */
+           unsigned int prev, next;
+           for (;;)
+           {
+             i = j;
+             j = next_index (i, start_point, end_point);
+             if (deltas[i].flag && !deltas[j].flag) break;
+           }
+           prev = j = i;
+           for (;;)
+           {
+             i = j;
+             j = next_index (i, start_point, end_point);
+             if (!deltas[i].flag && deltas[j].flag) break;
+           }
+           next = j;
+           /* Infer deltas for all unref points in the gap between prev and next */
+           i = prev;
+           for (;;)
+           {
+             i = next_index (i, start_point, end_point);
+             if (i == next) break;
+             deltas[i].x = infer_delta<x_getter> (orig_points.as_array (), deltas.as_array (), i, prev, next);
+             deltas[i].y = infer_delta<y_getter> (orig_points.as_array (), deltas.as_array (), i, prev, next);
+             if (--unref_count == 0) goto no_more_gaps;
+           }
+         }
+no_more_gaps:
+         start_point = end_point + 1;
+       }
+
+       /* apply specified / inferred deltas to points */
+       for (unsigned int i = 0; i < points.length; i++)
+       {
+         points[i].x += (float) roundf (deltas[i].x);
+         points[i].y += (float) roundf (deltas[i].y);
+       }
+      } while (iterator.move_to_next ());
+
+      return true;
+    }
+
+    unsigned int get_axis_count () const { return gvar_table->axisCount; }
+
+    protected:
+    const GlyphVarData *get_glyph_var_data (hb_codepoint_t glyph) const
+    { return gvar_table->get_glyph_var_data (glyph); }
+
+    private:
+    hb_blob_ptr_t<gvar> gvar_table;
+    hb_vector_t<F2DOT14> shared_tuples;
+  };
+
+  protected:
+  FixedVersion<>version;       /* Version of gvar table. Set to 0x00010000u. */
+  HBUINT16     axisCount;
+  HBUINT16     sharedTupleCount;
+  LOffsetTo<F2DOT14>
+               sharedTuples;   /* LOffsetTo<UnsizedArrayOf<Tupple>> */
+  HBUINT16     glyphCount;
+  HBUINT16     flags;
+  LOffsetTo<GlyphVarData>
+               dataZ;          /* Array of GlyphVarData */
+  UnsizedArrayOf<HBUINT8>
+               offsetZ;        /* Array of 16-bit or 32-bit (glyphCount+1) offsets */
+  public:
+  DEFINE_SIZE_MIN (20);
+};
+
+struct gvar_accelerator_t : gvar::accelerator_t {};
+
+} /* namespace OT */
+
+#endif /* HB_OT_VAR_GVAR_TABLE_HH */
index a8d9fe3..223430f 100644 (file)
@@ -114,14 +114,21 @@ struct HVARVVAR
                  rsbMap.sanitize (c, this));
   }
 
-  float get_advance_var (hb_codepoint_t glyph,
-                        const int *coords, unsigned int coord_count) const
+  float get_advance_var (hb_font_t *font, hb_codepoint_t glyph) const
   {
     unsigned int varidx = (this+advMap).map (glyph);
+    return (this+varStore).get_delta (varidx, font->coords, font->num_coords);
+  }
+
+  float get_side_bearing_var (hb_codepoint_t glyph,
+                             const int *coords, unsigned int coord_count) const
+  {
+    if (!has_side_bearing_deltas ()) return 0.f;
+    unsigned int varidx = (this+lsbMap).map (glyph);
     return (this+varStore).get_delta (varidx, coords, coord_count);
   }
 
-  bool has_sidebearing_deltas () const { return lsbMap && rsbMap; }
+  bool has_side_bearing_deltas () const { return lsbMap && rsbMap; }
 
   protected:
   FixedVersion<>version;       /* Version of the metrics variation table
index 0dd63e5..5a9d2af 100644 (file)
@@ -77,9 +77,9 @@ struct MVAR
                 const int *coords, unsigned int coord_count) const
   {
     const VariationValueRecord *record;
-    record = (VariationValueRecord *) bsearch (&tag, valuesZ.arrayZ,
-                                              valueRecordCount, valueRecordSize,
-                                              tag_compare);
+    record = (VariationValueRecord *) hb_bsearch (&tag, valuesZ.arrayZ,
+                                                 valueRecordCount, valueRecordSize,
+                                                 tag_compare);
     if (!record)
       return 0.;
 
index e327fb7..6b8b09b 100644 (file)
  * Google Author(s): Behdad Esfahbod
  */
 
-#include "hb-open-type.hh"
+#include "hb.hh"
+
+#ifndef HB_NO_VAR
+
+#include "hb-ot-var.h"
 
-#include "hb-ot-face.hh"
 #include "hb-ot-var-avar-table.hh"
 #include "hb-ot-var-fvar-table.hh"
 #include "hb-ot-var-mvar-table.hh"
-#include "hb-ot-var.h"
 
 
 /**
@@ -75,6 +77,7 @@ hb_ot_var_get_axis_count (hb_face_t *face)
   return face->table.fvar->get_axis_count ();
 }
 
+#ifndef HB_DISABLE_DEPRECATED
 /**
  * hb_ot_var_get_axes:
  *
@@ -104,6 +107,7 @@ hb_ot_var_find_axis (hb_face_t        *face,
 {
   return face->table.fvar->find_axis_deprecated (axis_tag, axis_index, axis_info);
 }
+#endif
 
 /**
  * hb_ot_var_get_axis_infos:
@@ -211,3 +215,6 @@ hb_ot_var_normalize_coords (hb_face_t    *face,
 
   face->table.avar->map_coords (normalized_coords, coords_length);
 }
+
+
+#endif
index cf6f0c9..df89bc5 100644 (file)
@@ -68,7 +68,7 @@ hb_ot_var_get_axis_count (hb_face_t *face);
 typedef enum { /*< flags >*/
   HB_OT_VAR_AXIS_FLAG_HIDDEN   = 0x00000001u,
 
-  _HB_OT_VAR_AXIS_FLAG_MAX_VALUE= 0x7FFFFFFFu /*< skip >*/
+  _HB_OT_VAR_AXIS_FLAG_MAX_VALUE= HB_TAG_MAX_SIGNED /*< skip >*/
 } hb_ot_var_axis_flags_t;
 
 /**
index 39073db..a4d6b06 100644 (file)
@@ -48,7 +48,7 @@ struct VertOriginMetric
   }
 
   public:
-  GlyphID      glyph;
+  HBGlyphID    glyph;
   FWORD                vertOriginY;
 
   public:
@@ -69,110 +69,56 @@ struct VORG
     return vertYOrigins[i].vertOriginY;
   }
 
-  bool _subset (const hb_subset_plan_t *plan HB_UNUSED,
-               const VORG *vorg_table,
-               const hb_vector_t<VertOriginMetric> &subset_metrics,
-               unsigned int dest_sz,
-               void *dest) const
+  template <typename Iterator,
+           hb_requires (hb_is_iterator (Iterator))>
+  void serialize (hb_serialize_context_t *c,
+                 Iterator it,
+                 FWORD defaultVertOriginY)
   {
-    hb_serialize_context_t c (dest, dest_sz);
-
-    VORG *subset_table = c.start_serialize<VORG> ();
-    if (unlikely (!c.extend_min (*subset_table)))
-      return false;
-
-    subset_table->version.major.set (1);
-    subset_table->version.minor.set (0);
-
-    subset_table->defaultVertOriginY.set (vorg_table->defaultVertOriginY);
-    subset_table->vertYOrigins.len.set (subset_metrics.length);
-
-    bool success = true;
-    if (subset_metrics.length > 0)
-    {
-      unsigned int  size = VertOriginMetric::static_size * subset_metrics.length;
-      VertOriginMetric  *metrics = c.allocate_size<VertOriginMetric> (size);
-      if (likely (metrics != nullptr))
-        memcpy (metrics, &subset_metrics[0], size);
-      else
-        success = false;
-    }
-    c.end_serialize ();
-
-    return success;
+
+    if (unlikely (!c->extend_min ((*this))))  return;
+
+    this->version.major = 1;
+    this->version.minor = 0;
+
+    this->defaultVertOriginY = defaultVertOriginY;
+    this->vertYOrigins.len = it.len ();
+
+    for (const auto _ : it) c->copy (_);
   }
 
-  bool subset (hb_subset_plan_t *plan) const
+  bool subset (hb_subset_context_t *c) const
   {
-    hb_blob_t *vorg_blob = hb_sanitize_context_t().reference_table<VORG> (plan->source);
-    const VORG *vorg_table = vorg_blob->as<VORG> ();
-
-    /* count the number of glyphs to be included in the subset table */
-    hb_vector_t<VertOriginMetric> subset_metrics;
-    subset_metrics.init ();
-
-
-    hb_codepoint_t old_glyph = HB_SET_VALUE_INVALID;
-    unsigned int i = 0;
-    while (i < vertYOrigins.len
-           && plan->glyphset ()->next (&old_glyph))
-    {
-      while (old_glyph > vertYOrigins[i].glyph)
-      {
-        i++;
-        if (i >= vertYOrigins.len)
-          break;
-      }
-
-      if (old_glyph == vertYOrigins[i].glyph)
-      {
-        hb_codepoint_t new_glyph;
-        if (plan->new_gid_for_old_gid (old_glyph, &new_glyph))
-        {
-          VertOriginMetric *metrics = subset_metrics.push ();
-          metrics->glyph.set (new_glyph);
-          metrics->vertOriginY.set (vertYOrigins[i].vertOriginY);
-        }
-      }
-    }
-
-    /* alloc the new table */
-    unsigned int dest_sz = VORG::min_size + VertOriginMetric::static_size * subset_metrics.length;
-    void *dest = (void *) malloc (dest_sz);
-    if (unlikely (!dest))
-    {
-      subset_metrics.fini ();
-      hb_blob_destroy (vorg_blob);
-      return false;
-    }
+    TRACE_SUBSET (this);
+    VORG *vorg_prime = c->serializer->start_embed<VORG> ();
+    if (unlikely (!c->serializer->check_success (vorg_prime))) return_trace (false);
+
+    auto it =
+    + vertYOrigins.as_array ()
+    | hb_filter (c->plan->glyphset (), &VertOriginMetric::glyph)
+    | hb_map ([&] (const VertOriginMetric& _)
+             {
+               hb_codepoint_t new_glyph = HB_SET_VALUE_INVALID;
+               c->plan->new_gid_for_old_gid (_.glyph, &new_glyph);
+
+               VertOriginMetric metric;
+               metric.glyph = new_glyph;
+               metric.vertOriginY = _.vertOriginY;
+               return metric;
+             })
+    ;
 
     /* serialize the new table */
-    if (!_subset (plan, vorg_table, subset_metrics, dest_sz, dest))
-    {
-      subset_metrics.fini ();
-      free (dest);
-      hb_blob_destroy (vorg_blob);
-      return false;
-    }
-
-    hb_blob_t *result = hb_blob_create ((const char *)dest,
-                                        dest_sz,
-                                        HB_MEMORY_MODE_READONLY,
-                                        dest,
-                                        free);
-    bool success = plan->add_table (HB_OT_TAG_VORG, result);
-    hb_blob_destroy (result);
-    subset_metrics.fini ();
-    hb_blob_destroy (vorg_blob);
-    return success;
+    vorg_prime->serialize (c->serializer, it, defaultVertOriginY);
+    return_trace (true);
   }
 
   bool sanitize (hb_sanitize_context_t *c) const
   {
     TRACE_SANITIZE (this);
     return_trace (c->check_struct (this) &&
-                  version.major == 1 &&
-                  vertYOrigins.sanitize (c));
+                 version.major == 1 &&
+                 vertYOrigins.sanitize (c));
   }
 
   protected:
index db78469..f2dbaa1 100644 (file)
@@ -35,6 +35,8 @@
 #include "hb-ot-font.h"
 #include "hb-ot-layout.h"
 #include "hb-ot-math.h"
+#include "hb-ot-meta.h"
+#include "hb-ot-metrics.h"
 #include "hb-ot-name.h"
 #include "hb-ot-shape.h"
 #include "hb-ot-var.h"
diff --git a/src/hb-pool.hh b/src/hb-pool.hh
new file mode 100644 (file)
index 0000000..83875db
--- /dev/null
@@ -0,0 +1,102 @@
+/*
+ * Copyright © 2019  Facebook, 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.
+ *
+ * Facebook Author(s): Behdad Esfahbod
+ */
+
+#ifndef HB_POOL_HH
+#define HB_POOL_HH
+
+#include "hb.hh"
+
+/* Memory pool for persistent allocation of small objects. */
+
+template <typename T, unsigned ChunkLen = 16>
+struct hb_pool_t
+{
+  hb_pool_t () : next (nullptr) {}
+  ~hb_pool_t () { fini (); }
+
+  void fini ()
+  {
+    next = nullptr;
+
+    + hb_iter (chunks)
+    | hb_apply ([] (chunk_t *_) { ::free (_); })
+    ;
+
+    chunks.fini ();
+  }
+
+  T* alloc ()
+  {
+    if (unlikely (!next))
+    {
+      if (unlikely (!chunks.alloc (chunks.length + 1))) return nullptr;
+      chunk_t *chunk = (chunk_t *) calloc (1, sizeof (chunk_t));
+      if (unlikely (!chunk)) return nullptr;
+      chunks.push (chunk);
+      next = chunk->thread ();
+    }
+
+    T* obj = next;
+    next = * ((T**) next);
+
+    memset (obj, 0, sizeof (T));
+
+    return obj;
+  }
+
+  void free (T* obj)
+  {
+    * (T**) obj = next;
+    next = obj;
+  }
+
+  private:
+
+  static_assert (ChunkLen > 1, "");
+  static_assert (sizeof (T) >= sizeof (void *), "");
+  static_assert (alignof (T) % alignof (void *) == 0, "");
+
+  struct chunk_t
+  {
+    T* thread ()
+    {
+      for (unsigned i = 0; i < ARRAY_LENGTH (arrayZ) - 1; i++)
+       * (T**) &arrayZ[i] = &arrayZ[i + 1];
+
+      * (T**) &arrayZ[ARRAY_LENGTH (arrayZ) - 1] = nullptr;
+
+      return arrayZ;
+    }
+
+    T arrayZ[ChunkLen];
+  };
+
+  T* next;
+  hb_vector_t<chunk_t *> chunks;
+};
+
+
+#endif /* HB_POOL_HH */
diff --git a/src/hb-sanitize.hh b/src/hb-sanitize.hh
new file mode 100644 (file)
index 0000000..7859c6a
--- /dev/null
@@ -0,0 +1,401 @@
+/*
+ * Copyright © 2007,2008,2009,2010  Red Hat, Inc.
+ * Copyright © 2012,2018  Google, Inc.
+ *
+ *  This is part of HarfBuzz, a text shaping library.
+ *
+ * Permission is hereby granted, without written agreement and without
+ * license or royalty fees, to use, copy, modify, and distribute this
+ * software and its documentation for any purpose, provided that the
+ * above copyright notice and the following two paragraphs appear in
+ * all copies of this software.
+ *
+ * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
+ * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
+ * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
+ * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+ * DAMAGE.
+ *
+ * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
+ * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS
+ * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
+ * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
+ *
+ * Red Hat Author(s): Behdad Esfahbod
+ * Google Author(s): Behdad Esfahbod
+ */
+
+#ifndef HB_SANITIZE_HH
+#define HB_SANITIZE_HH
+
+#include "hb.hh"
+#include "hb-blob.hh"
+#include "hb-dispatch.hh"
+
+
+/*
+ * Sanitize
+ *
+ *
+ * === Introduction ===
+ *
+ * The sanitize machinery is at the core of our zero-cost font loading.  We
+ * mmap() font file into memory and create a blob out of it.  Font subtables
+ * are returned as a readonly sub-blob of the main font blob.  These table
+ * blobs are then sanitized before use, to ensure invalid memory access does
+ * not happen.  The toplevel sanitize API use is like, eg. to load the 'head'
+ * table:
+ *
+ *   hb_blob_t *head_blob = hb_sanitize_context_t ().reference_table<OT::head> (face);
+ *
+ * The blob then can be converted to a head table struct with:
+ *
+ *   const head *head_table = head_blob->as<head> ();
+ *
+ * What the reference_table does is, to call hb_face_reference_table() to load
+ * the table blob, sanitize it and return either the sanitized blob, or empty
+ * blob if sanitization failed.  The blob->as() function returns the null
+ * object of its template type argument if the blob is empty.  Otherwise, it
+ * just casts the blob contents to the desired type.
+ *
+ * Sanitizing a blob of data with a type T works as follows (with minor
+ * simplification):
+ *
+ *   - Cast blob content to T*, call sanitize() method of it,
+ *   - If sanitize succeeded, return blob.
+ *   - Otherwise, if blob is not writable, try making it writable,
+ *     or copy if cannot be made writable in-place,
+ *   - Call sanitize() again.  Return blob if sanitize succeeded.
+ *   - Return empty blob otherwise.
+ *
+ *
+ * === The sanitize() contract ===
+ *
+ * The sanitize() method of each object type shall return true if it's safe to
+ * call other methods of the object, and false otherwise.
+ *
+ * Note that what sanitize() checks for might align with what the specification
+ * describes as valid table data, but does not have to be.  In particular, we
+ * do NOT want to be pedantic and concern ourselves with validity checks that
+ * are irrelevant to our use of the table.  On the contrary, we want to be
+ * lenient with error handling and accept invalid data to the extent that it
+ * does not impose extra burden on us.
+ *
+ * Based on the sanitize contract, one can see that what we check for depends
+ * on how we use the data in other table methods.  Ie. if other table methods
+ * assume that offsets do NOT point out of the table data block, then that's
+ * something sanitize() must check for (GSUB/GPOS/GDEF/etc work this way).  On
+ * the other hand, if other methods do such checks themselves, then sanitize()
+ * does not have to bother with them (glyf/local work this way).  The choice
+ * depends on the table structure and sanitize() performance.  For example, to
+ * check glyf/loca offsets in sanitize() would cost O(num-glyphs).  We try hard
+ * to avoid such costs during font loading.  By postponing such checks to the
+ * actual glyph loading, we reduce the sanitize cost to O(1) and total runtime
+ * cost to O(used-glyphs).  As such, this is preferred.
+ *
+ * The same argument can be made re GSUB/GPOS/GDEF, but there, the table
+ * structure is so complicated that by checking all offsets at sanitize() time,
+ * we make the code much simpler in other methods, as offsets and referenced
+ * objects do not need to be validated at each use site.
+ */
+
+/* This limits sanitizing time on really broken fonts. */
+#ifndef HB_SANITIZE_MAX_EDITS
+#define HB_SANITIZE_MAX_EDITS 32
+#endif
+#ifndef HB_SANITIZE_MAX_OPS_FACTOR
+#define HB_SANITIZE_MAX_OPS_FACTOR 8
+#endif
+#ifndef HB_SANITIZE_MAX_OPS_MIN
+#define HB_SANITIZE_MAX_OPS_MIN 16384
+#endif
+#ifndef HB_SANITIZE_MAX_OPS_MAX
+#define HB_SANITIZE_MAX_OPS_MAX 0x3FFFFFFF
+#endif
+
+struct hb_sanitize_context_t :
+       hb_dispatch_context_t<hb_sanitize_context_t, bool, HB_DEBUG_SANITIZE>
+{
+  hb_sanitize_context_t () :
+       debug_depth (0),
+       start (nullptr), end (nullptr),
+       max_ops (0),
+       writable (false), edit_count (0),
+       blob (nullptr),
+       num_glyphs (65536),
+       num_glyphs_set (false) {}
+
+  const char *get_name () { return "SANITIZE"; }
+  template <typename T, typename F>
+  bool may_dispatch (const T *obj HB_UNUSED, const F *format)
+  { return format->sanitize (this); }
+  static return_t default_return_value () { return true; }
+  static return_t no_dispatch_return_value () { return false; }
+  bool stop_sublookup_iteration (const return_t r) const { return !r; }
+
+  private:
+  template <typename T, typename ...Ts> auto
+  _dispatch (const T &obj, hb_priority<1>, Ts&&... ds) HB_AUTO_RETURN
+  ( obj.sanitize (this, hb_forward<Ts> (ds)...) )
+  template <typename T, typename ...Ts> auto
+  _dispatch (const T &obj, hb_priority<0>, Ts&&... ds) HB_AUTO_RETURN
+  ( obj.dispatch (this, hb_forward<Ts> (ds)...) )
+  public:
+  template <typename T, typename ...Ts> auto
+  dispatch (const T &obj, Ts&&... ds) HB_AUTO_RETURN
+  ( _dispatch (obj, hb_prioritize, hb_forward<Ts> (ds)...) )
+
+
+  void init (hb_blob_t *b)
+  {
+    this->blob = hb_blob_reference (b);
+    this->writable = false;
+  }
+
+  void set_num_glyphs (unsigned int num_glyphs_)
+  {
+    num_glyphs = num_glyphs_;
+    num_glyphs_set = true;
+  }
+  unsigned int get_num_glyphs () { return num_glyphs; }
+
+  void set_max_ops (int max_ops_) { max_ops = max_ops_; }
+
+  template <typename T>
+  void set_object (const T *obj)
+  {
+    reset_object ();
+
+    if (!obj) return;
+
+    const char *obj_start = (const char *) obj;
+    if (unlikely (obj_start < this->start || this->end <= obj_start))
+      this->start = this->end = nullptr;
+    else
+    {
+      this->start = obj_start;
+      this->end   = obj_start + hb_min (size_t (this->end - obj_start), obj->get_size ());
+    }
+  }
+
+  void reset_object ()
+  {
+    this->start = this->blob->data;
+    this->end = this->start + this->blob->length;
+    assert (this->start <= this->end); /* Must not overflow. */
+  }
+
+  void start_processing ()
+  {
+    reset_object ();
+    this->max_ops = hb_max ((unsigned int) (this->end - this->start) * HB_SANITIZE_MAX_OPS_FACTOR,
+                        (unsigned) HB_SANITIZE_MAX_OPS_MIN);
+    this->edit_count = 0;
+    this->debug_depth = 0;
+
+    DEBUG_MSG_LEVEL (SANITIZE, start, 0, +1,
+                    "start [%p..%p] (%lu bytes)",
+                    this->start, this->end,
+                    (unsigned long) (this->end - this->start));
+  }
+
+  void end_processing ()
+  {
+    DEBUG_MSG_LEVEL (SANITIZE, this->start, 0, -1,
+                    "end [%p..%p] %u edit requests",
+                    this->start, this->end, this->edit_count);
+
+    hb_blob_destroy (this->blob);
+    this->blob = nullptr;
+    this->start = this->end = nullptr;
+  }
+
+  unsigned get_edit_count () { return edit_count; }
+
+  bool check_range (const void *base,
+                   unsigned int len) const
+  {
+    const char *p = (const char *) base;
+    bool ok = !len ||
+             (this->start <= p &&
+              p <= this->end &&
+              (unsigned int) (this->end - p) >= len &&
+              this->max_ops-- > 0);
+
+    DEBUG_MSG_LEVEL (SANITIZE, p, this->debug_depth+1, 0,
+                    "check_range [%p..%p]"
+                    " (%d bytes) in [%p..%p] -> %s",
+                    p, p + len, len,
+                    this->start, this->end,
+                    ok ? "OK" : "OUT-OF-RANGE");
+
+    return likely (ok);
+  }
+
+  template <typename T>
+  bool check_range (const T *base,
+                   unsigned int a,
+                   unsigned int b) const
+  {
+    return !hb_unsigned_mul_overflows (a, b) &&
+          this->check_range (base, a * b);
+  }
+
+  template <typename T>
+  bool check_range (const T *base,
+                   unsigned int a,
+                   unsigned int b,
+                   unsigned int c) const
+  {
+    return !hb_unsigned_mul_overflows (a, b) &&
+          this->check_range (base, a * b, c);
+  }
+
+  template <typename T>
+  bool check_array (const T *base, unsigned int len) const
+  {
+    return this->check_range (base, len, hb_static_size (T));
+  }
+
+  template <typename T>
+  bool check_array (const T *base,
+                   unsigned int a,
+                   unsigned int b) const
+  {
+    return this->check_range (base, a, b, hb_static_size (T));
+  }
+
+  template <typename Type>
+  bool check_struct (const Type *obj) const
+  { return likely (this->check_range (obj, obj->min_size)); }
+
+  bool may_edit (const void *base, unsigned int len)
+  {
+    if (this->edit_count >= HB_SANITIZE_MAX_EDITS)
+      return false;
+
+    const char *p = (const char *) base;
+    this->edit_count++;
+
+    DEBUG_MSG_LEVEL (SANITIZE, p, this->debug_depth+1, 0,
+       "may_edit(%u) [%p..%p] (%d bytes) in [%p..%p] -> %s",
+       this->edit_count,
+       p, p + len, len,
+       this->start, this->end,
+       this->writable ? "GRANTED" : "DENIED");
+
+    return this->writable;
+  }
+
+  template <typename Type, typename ValueType>
+  bool try_set (const Type *obj, const ValueType &v)
+  {
+    if (this->may_edit (obj, hb_static_size (Type)))
+    {
+      * const_cast<Type *> (obj) = v;
+      return true;
+    }
+    return false;
+  }
+
+  template <typename Type>
+  hb_blob_t *sanitize_blob (hb_blob_t *blob)
+  {
+    bool sane;
+
+    init (blob);
+
+  retry:
+    DEBUG_MSG_FUNC (SANITIZE, start, "start");
+
+    start_processing ();
+
+    if (unlikely (!start))
+    {
+      end_processing ();
+      return blob;
+    }
+
+    Type *t = reinterpret_cast<Type *> (const_cast<char *> (start));
+
+    sane = t->sanitize (this);
+    if (sane)
+    {
+      if (edit_count)
+      {
+       DEBUG_MSG_FUNC (SANITIZE, start, "passed first round with %d edits; going for second round", edit_count);
+
+       /* sanitize again to ensure no toe-stepping */
+       edit_count = 0;
+       sane = t->sanitize (this);
+       if (edit_count) {
+         DEBUG_MSG_FUNC (SANITIZE, start, "requested %d edits in second round; FAILLING", edit_count);
+         sane = false;
+       }
+      }
+    }
+    else
+    {
+      if (edit_count && !writable) {
+       start = hb_blob_get_data_writable (blob, nullptr);
+       end = start + blob->length;
+
+       if (start)
+       {
+         writable = true;
+         /* ok, we made it writable by relocating.  try again */
+         DEBUG_MSG_FUNC (SANITIZE, start, "retry");
+         goto retry;
+       }
+      }
+    }
+
+    end_processing ();
+
+    DEBUG_MSG_FUNC (SANITIZE, start, sane ? "PASSED" : "FAILED");
+    if (sane)
+    {
+      hb_blob_make_immutable (blob);
+      return blob;
+    }
+    else
+    {
+      hb_blob_destroy (blob);
+      return hb_blob_get_empty ();
+    }
+  }
+
+  template <typename Type>
+  hb_blob_t *reference_table (const hb_face_t *face, hb_tag_t tableTag = Type::tableTag)
+  {
+    if (!num_glyphs_set)
+      set_num_glyphs (hb_face_get_glyph_count (face));
+    return sanitize_blob<Type> (hb_face_reference_table (face, tableTag));
+  }
+
+  mutable unsigned int debug_depth;
+  const char *start, *end;
+  mutable int max_ops;
+  private:
+  bool writable;
+  unsigned int edit_count;
+  hb_blob_t *blob;
+  unsigned int num_glyphs;
+  bool  num_glyphs_set;
+};
+
+struct hb_sanitize_with_object_t
+{
+  template <typename T>
+  hb_sanitize_with_object_t (hb_sanitize_context_t *c, const T& obj) : c (c)
+  { c->set_object (obj); }
+  ~hb_sanitize_with_object_t ()
+  { c->reset_object (); }
+
+  private:
+  hb_sanitize_context_t *c;
+};
+
+
+#endif /* HB_SANITIZE_HH */
diff --git a/src/hb-serialize.hh b/src/hb-serialize.hh
new file mode 100644 (file)
index 0000000..4c674b1
--- /dev/null
@@ -0,0 +1,466 @@
+/*
+ * Copyright © 2007,2008,2009,2010  Red Hat, Inc.
+ * Copyright © 2012,2018  Google, Inc.
+ * Copyright © 2019  Facebook, 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
+ * Facebook Author(s): Behdad Esfahbod
+ */
+
+#ifndef HB_SERIALIZE_HH
+#define HB_SERIALIZE_HH
+
+#include "hb.hh"
+#include "hb-blob.hh"
+#include "hb-map.hh"
+#include "hb-pool.hh"
+
+
+/*
+ * Serialize
+ */
+
+struct hb_serialize_context_t
+{
+  typedef unsigned objidx_t;
+
+  struct range_t
+  {
+    char *head, *tail;
+  };
+
+  struct object_t : range_t
+  {
+    void fini () { links.fini (); }
+
+    bool operator == (const object_t &o) const
+    {
+      return (tail - head == o.tail - o.head)
+         && (links.length == o.links.length)
+         && 0 == hb_memcmp (head, o.head, tail - head)
+         && links.as_bytes () == o.links.as_bytes ();
+    }
+    uint32_t hash () const
+    {
+      return hb_bytes_t (head, tail - head).hash () ^
+            links.as_bytes ().hash ();
+    }
+
+    struct link_t
+    {
+      bool is_wide: 1;
+      unsigned position : 31;
+      unsigned bias;
+      objidx_t objidx;
+    };
+
+    hb_vector_t<link_t> links;
+    object_t *next;
+  };
+
+  range_t snapshot () { range_t s = {head, tail} ; return s; }
+
+
+  hb_serialize_context_t (void *start_, unsigned int size) :
+    start ((char *) start_),
+    end (start + size),
+    current (nullptr)
+  { reset (); }
+  ~hb_serialize_context_t () { fini (); }
+
+  void fini ()
+  {
+    for (object_t *_ : ++hb_iter (packed)) _->fini ();
+    packed.fini ();
+    this->packed_map.fini ();
+
+    while (current)
+    {
+      auto *_ = current;
+      current = current->next;
+      _->fini ();
+    }
+    object_pool.fini ();
+  }
+
+  bool in_error () const { return !this->successful; }
+
+  void reset ()
+  {
+    this->successful = true;
+    this->ran_out_of_room = false;
+    this->head = this->start;
+    this->tail = this->end;
+    this->debug_depth = 0;
+
+    fini ();
+    this->packed.push (nullptr);
+  }
+
+  bool check_success (bool success)
+  { return this->successful && (success || (err_other_error (), false)); }
+
+  template <typename T1, typename T2>
+  bool check_equal (T1 &&v1, T2 &&v2)
+  { return check_success (v1 == v2); }
+
+  template <typename T1, typename T2>
+  bool check_assign (T1 &v1, T2 &&v2)
+  { return check_equal (v1 = v2, v2); }
+
+  template <typename T> bool propagate_error (T &&obj)
+  { return check_success (!hb_deref (obj).in_error ()); }
+
+  template <typename T1, typename... Ts> bool propagate_error (T1 &&o1, Ts&&... os)
+  { return propagate_error (hb_forward<T1> (o1)) &&
+          propagate_error (hb_forward<Ts> (os)...); }
+
+  /* To be called around main operation. */
+  template <typename Type>
+  Type *start_serialize ()
+  {
+    DEBUG_MSG_LEVEL (SERIALIZE, this->start, 0, +1,
+                    "start [%p..%p] (%lu bytes)",
+                    this->start, this->end,
+                    (unsigned long) (this->end - this->start));
+
+    assert (!current);
+    return push<Type> ();
+  }
+  void end_serialize ()
+  {
+    DEBUG_MSG_LEVEL (SERIALIZE, this->start, 0, -1,
+                    "end [%p..%p] serialized %u bytes; %s",
+                    this->start, this->end,
+                    (unsigned) (this->head - this->start),
+                    this->successful ? "successful" : "UNSUCCESSFUL");
+
+    propagate_error (packed, packed_map);
+
+    if (unlikely (!current)) return;
+    assert (!current->next);
+
+    /* Only "pack" if there exist other objects... Otherwise, don't bother.
+     * Saves a move. */
+    if (packed.length <= 1)
+      return;
+
+    pop_pack ();
+
+    resolve_links ();
+  }
+
+  template <typename Type = void>
+  Type *push ()
+  {
+    object_t *obj = object_pool.alloc ();
+    if (unlikely (!obj))
+      check_success (false);
+    else
+    {
+      obj->head = head;
+      obj->tail = tail;
+      obj->next = current;
+      current = obj;
+    }
+    return start_embed<Type> ();
+  }
+  void pop_discard ()
+  {
+    object_t *obj = current;
+    if (unlikely (!obj)) return;
+    current = current->next;
+    revert (*obj);
+    obj->fini ();
+    object_pool.free (obj);
+  }
+  objidx_t pop_pack ()
+  {
+    object_t *obj = current;
+    if (unlikely (!obj)) return 0;
+    current = current->next;
+    obj->tail = head;
+    obj->next = nullptr;
+    unsigned len = obj->tail - obj->head;
+    head = obj->head; /* Rewind head. */
+
+    if (!len)
+    {
+      assert (!obj->links.length);
+      return 0;
+    }
+
+    objidx_t objidx = packed_map.get (obj);
+    if (objidx)
+    {
+      obj->fini ();
+      return objidx;
+    }
+
+    tail -= len;
+    memmove (tail, obj->head, len);
+
+    obj->head = tail;
+    obj->tail = tail + len;
+
+    packed.push (obj);
+
+    if (unlikely (packed.in_error ()))
+      return 0;
+
+    objidx = packed.length - 1;
+
+    packed_map.set (obj, objidx);
+
+    return objidx;
+  }
+
+  void revert (range_t snap)
+  {
+    assert (snap.head <= head);
+    assert (tail <= snap.tail);
+    head = snap.head;
+    tail = snap.tail;
+    discard_stale_objects ();
+  }
+
+  void discard_stale_objects ()
+  {
+    while (packed.length > 1 &&
+          packed.tail ()->head < tail)
+    {
+      packed_map.del (packed.tail ());
+      assert (!packed.tail ()->next);
+      packed.tail ()->fini ();
+      packed.pop ();
+    }
+    if (packed.length > 1)
+      assert (packed.tail ()->head == tail);
+  }
+
+  template <typename T>
+  void add_link (T &ofs, objidx_t objidx, const void *base = nullptr)
+  {
+    static_assert (sizeof (T) == 2 || sizeof (T) == 4, "");
+
+    if (!objidx)
+      return;
+
+    assert (current);
+    assert (current->head <= (const char *) &ofs);
+
+    if (!base)
+      base = current->head;
+    else
+      assert (current->head <= (const char *) base);
+
+    auto& link = *current->links.push ();
+    link.is_wide = sizeof (T) == 4;
+    link.position = (const char *) &ofs - current->head;
+    link.bias = (const char *) base - current->head;
+    link.objidx = objidx;
+  }
+
+  void resolve_links ()
+  {
+    if (unlikely (in_error ())) return;
+
+    assert (!current);
+    assert (packed.length > 1);
+
+    for (const object_t* parent : ++hb_iter (packed))
+      for (const object_t::link_t &link : parent->links)
+      {
+       const object_t* child = packed[link.objidx];
+       assert (link.bias <= (size_t) (parent->tail - parent->head));
+       unsigned offset = (child->head - parent->head) - link.bias;
+
+       if (link.is_wide)
+       {
+         auto &off = * ((BEInt<uint32_t, 4> *) (parent->head + link.position));
+         assert (0 == off);
+         check_assign (off, offset);
+       }
+       else
+       {
+         auto &off = * ((BEInt<uint16_t, 2> *) (parent->head + link.position));
+         assert (0 == off);
+         check_assign (off, offset);
+       }
+      }
+  }
+
+  unsigned int length () const { return this->head - current->head; }
+
+  void align (unsigned int alignment)
+  {
+    unsigned int l = length () % alignment;
+    if (l)
+      allocate_size<void> (alignment - l);
+  }
+
+  template <typename Type = void>
+  Type *start_embed (const Type *obj HB_UNUSED = nullptr) const
+  { return reinterpret_cast<Type *> (this->head); }
+  template <typename Type>
+  Type *start_embed (const Type &obj) const
+  { return start_embed (hb_addressof (obj)); }
+
+  /* Following two functions exist to allow setting breakpoint on. */
+  void err_ran_out_of_room () { this->ran_out_of_room = true; }
+  void err_other_error () { this->successful = false; }
+
+  template <typename Type>
+  Type *allocate_size (unsigned int size)
+  {
+    if (unlikely (!this->successful)) return nullptr;
+
+    if (this->tail - this->head < ptrdiff_t (size))
+    {
+      err_ran_out_of_room ();
+      this->successful = false;
+      return nullptr;
+    }
+    memset (this->head, 0, size);
+    char *ret = this->head;
+    this->head += size;
+    return reinterpret_cast<Type *> (ret);
+  }
+
+  template <typename Type>
+  Type *allocate_min ()
+  { return this->allocate_size<Type> (Type::min_size); }
+
+  template <typename Type>
+  Type *embed (const Type *obj)
+  {
+    unsigned int size = obj->get_size ();
+    Type *ret = this->allocate_size<Type> (size);
+    if (unlikely (!ret)) return nullptr;
+    memcpy (ret, obj, size);
+    return ret;
+  }
+  template <typename Type>
+  Type *embed (const Type &obj)
+  { return embed (hb_addressof (obj)); }
+
+  template <typename Type, typename ...Ts> auto
+  _copy (const Type &src, hb_priority<1>, Ts&&... ds) HB_RETURN
+  (Type *, src.copy (this, hb_forward<Ts> (ds)...))
+
+  template <typename Type> auto
+  _copy (const Type &src, hb_priority<0>) -> decltype (&(hb_declval<Type> () = src))
+  {
+    Type *ret = this->allocate_size<Type> (sizeof (Type));
+    if (unlikely (!ret)) return nullptr;
+    *ret = src;
+    return ret;
+  }
+
+  /* Like embed, but active: calls obj.operator=() or obj.copy() to transfer data
+   * instead of memcpy(). */
+  template <typename Type, typename ...Ts>
+  Type *copy (const Type &src, Ts&&... ds)
+  { return _copy (src, hb_prioritize, hb_forward<Ts> (ds)...); }
+  template <typename Type, typename ...Ts>
+  Type *copy (const Type *src, Ts&&... ds)
+  { return copy (*src, hb_forward<Ts> (ds)...); }
+
+  template <typename Type>
+  hb_serialize_context_t& operator << (const Type &obj) & { embed (obj); return *this; }
+
+  template <typename Type>
+  Type *extend_size (Type *obj, unsigned int size)
+  {
+    assert (this->start <= (char *) obj);
+    assert ((char *) obj <= this->head);
+    assert ((char *) obj + size >= this->head);
+    if (unlikely (!this->allocate_size<Type> (((char *) obj) + size - this->head))) return nullptr;
+    return reinterpret_cast<Type *> (obj);
+  }
+  template <typename Type>
+  Type *extend_size (Type &obj, unsigned int size)
+  { return extend_size (hb_addressof (obj), size); }
+
+  template <typename Type>
+  Type *extend_min (Type *obj) { return extend_size (obj, obj->min_size); }
+  template <typename Type>
+  Type *extend_min (Type &obj) { return extend_min (hb_addressof (obj)); }
+
+  template <typename Type, typename ...Ts>
+  Type *extend (Type *obj, Ts&&... ds)
+  { return extend_size (obj, obj->get_size (hb_forward<Ts> (ds)...)); }
+  template <typename Type, typename ...Ts>
+  Type *extend (Type &obj, Ts&&... ds)
+  { return extend (hb_addressof (obj), hb_forward<Ts> (ds)...); }
+
+  /* Output routines. */
+  hb_bytes_t copy_bytes () const
+  {
+    assert (this->successful);
+    /* Copy both items from head side and tail side... */
+    unsigned int len = (this->head - this->start)
+                    + (this->end  - this->tail);
+
+    char *p = (char *) malloc (len);
+    if (unlikely (!p)) return hb_bytes_t ();
+
+    memcpy (p, this->start, this->head - this->start);
+    memcpy (p + (this->head - this->start), this->tail, this->end - this->tail);
+    return hb_bytes_t (p, len);
+  }
+  template <typename Type>
+  Type *copy () const
+  { return reinterpret_cast<Type *> ((char *) copy_bytes ().arrayZ); }
+  hb_blob_t *copy_blob () const
+  {
+    hb_bytes_t b = copy_bytes ();
+    return hb_blob_create (b.arrayZ, b.length,
+                          HB_MEMORY_MODE_WRITABLE,
+                          (char *) b.arrayZ, free);
+  }
+
+  public: /* TODO Make private. */
+  char *start, *head, *tail, *end;
+  unsigned int debug_depth;
+  bool successful;
+  bool ran_out_of_room;
+
+  private:
+
+  /* Object memory pool. */
+  hb_pool_t<object_t> object_pool;
+
+  /* Stack of currently under construction objects. */
+  object_t *current;
+
+  /* Stack of packed objects.  Object 0 is always nil object. */
+  hb_vector_t<object_t *> packed;
+
+  /* Map view of packed objects. */
+  hb_hashmap_t<const object_t *, objidx_t, nullptr, 0> packed_map;
+};
+
+
+#endif /* HB_SERIALIZE_HH */
index 0682362..10638a7 100644 (file)
@@ -389,6 +389,7 @@ hb_set_symmetric_difference (hb_set_t       *set,
   set->symmetric_difference (other);
 }
 
+#ifndef HB_DISABLE_DEPRECATED
 /**
  * hb_set_invert:
  * @set: a set.
@@ -403,6 +404,7 @@ void
 hb_set_invert (hb_set_t *set HB_UNUSED)
 {
 }
+#endif
 
 /**
  * hb_set_get_population:
@@ -477,7 +479,7 @@ hb_set_next (const hb_set_t *set,
  * @set: a set.
  * @codepoint: (inout):
  *
- * Gets the previous number in @set that is slower than current value of @codepoint.
+ * Gets the previous number in @set that is lower than current value of @codepoint.
  *
  * Set @codepoint to %HB_SET_VALUE_INVALID to get started.
  *
@@ -522,7 +524,7 @@ hb_set_next_range (const hb_set_t *set,
  * @last: (out): output last codepoint in the range.
  *
  * Gets the previous consecutive range of numbers in @set that
- * are greater than current value of @last.
+ * are less than current value of @first.
  *
  * Set @first to %HB_SET_VALUE_INVALID to get started.
  *
index 64a1363..36d11c0 100644 (file)
@@ -28,6 +28,7 @@
 #define HB_SET_HH
 
 #include "hb.hh"
+#include "hb-machinery.hh"
 
 
 /*
@@ -39,7 +40,7 @@
 
 struct hb_set_t
 {
-  HB_NO_COPY_ASSIGN (hb_set_t);
+  HB_DELETE_COPY_ASSIGN (hb_set_t);
   hb_set_t ()  { init (); }
   ~hb_set_t () { fini (); }
 
@@ -62,21 +63,21 @@ struct hb_set_t
     bool is_empty () const
     {
       for (unsigned int i = 0; i < len (); i++)
-        if (v[i])
+       if (v[i])
          return false;
       return true;
     }
 
     void add (hb_codepoint_t g) { elt (g) |= mask (g); }
     void del (hb_codepoint_t g) { elt (g) &= ~mask (g); }
-    bool has (hb_codepoint_t g) const { return !!(elt (g) & mask (g)); }
+    bool get (hb_codepoint_t g) const { return elt (g) & mask (g); }
 
     void add_range (hb_codepoint_t a, hb_codepoint_t b)
     {
       elt_t *la = &elt (a);
       elt_t *lb = &elt (b);
       if (la == lb)
-        *la |= (mask (b) << 1) - mask(a);
+       *la |= (mask (b) << 1) - mask(a);
       else
       {
        *la |= ~(mask (a) - 1);
@@ -97,7 +98,7 @@ struct hb_set_t
     {
       unsigned int pop = 0;
       for (unsigned int i = 0; i < len (); i++)
-        pop += hb_popcount (v[i]);
+       pop += hb_popcount (v[i]);
       return pop;
     }
 
@@ -135,12 +136,17 @@ struct hb_set_t
       unsigned int j = m & ELT_MASK;
 
       const elt_t vv = v[i] & ((elt_t (1) << (j + 1)) - 1);
-      for (const elt_t *p = &vv; (int) i >= 0; p = &v[--i])
+      const elt_t *p = &vv;
+      while (true)
+      {
        if (*p)
        {
          *codepoint = i * ELT_BITS + elt_get_max (*p);
          return true;
        }
+       if ((int) i <= 0) break;
+       p = &v[--i];
+      }
 
       *codepoint = INVALID;
       return false;
@@ -148,14 +154,14 @@ struct hb_set_t
     hb_codepoint_t get_min () const
     {
       for (unsigned int i = 0; i < len (); i++)
-        if (v[i])
+       if (v[i])
          return i * ELT_BITS + elt_get_min (v[i]);
       return INVALID;
     }
     hb_codepoint_t get_max () const
     {
       for (int i = len () - 1; i >= 0; i--)
-        if (v[i])
+       if (v[i])
          return i * ELT_BITS + elt_get_max (v[i]);
       return 0;
     }
@@ -186,7 +192,7 @@ struct hb_set_t
   hb_object_header_t header;
   bool successful; /* Allocations successful */
   mutable unsigned int population;
-  hb_vector_t<page_map_t> page_map;
+  hb_sorted_vector_t<page_map_t> page_map;
   hb_vector_t<page_t> pages;
 
   void init_shallow ()
@@ -227,11 +233,18 @@ struct hb_set_t
     return true;
   }
 
-  void clear ()
+  void reset ()
   {
     if (unlikely (hb_object_is_immutable (this)))
       return;
+    clear ();
     successful = true;
+  }
+
+  void clear ()
+  {
+    if (unlikely (hb_object_is_immutable (this)))
+      return;
     population = 0;
     page_map.resize (0);
     pages.resize (0);
@@ -241,7 +254,7 @@ struct hb_set_t
     unsigned int count = pages.length;
     for (unsigned int i = 0; i < count; i++)
       if (!pages[i].is_empty ())
-        return false;
+       return false;
     return true;
   }
 
@@ -301,7 +314,7 @@ struct hb_set_t
       {
        page->add (g);
 
-       array = (const T *) ((const char *) array + stride);
+       array = &StructAtOffsetUnaligned<T> (array, stride);
        count--;
       }
       while (count && (g = *array, start <= g && g < end));
@@ -325,9 +338,9 @@ struct hb_set_t
       unsigned int end = major_start (m + 1);
       do
       {
-        /* If we try harder we can change the following comparison to <=;
+       /* If we try harder we can change the following comparison to <=;
         * Not sure if it's worth it. */
-        if (g < last_g) return false;
+       if (g < last_g) return false;
        last_g = g;
        page->add (g);
 
@@ -357,15 +370,26 @@ struct hb_set_t
     for (unsigned int i = a; i < b + 1; i++)
       del (i);
   }
-  bool has (hb_codepoint_t g) const
+  bool get (hb_codepoint_t g) const
   {
     const page_t *page = page_for (g);
     if (!page)
       return false;
-    return page->has (g);
+    return page->get (g);
   }
-  bool intersects (hb_codepoint_t first,
-                         hb_codepoint_t last) const
+
+  /* Has interface. */
+  static constexpr bool SENTINEL = false;
+  typedef bool value_t;
+  value_t operator [] (hb_codepoint_t k) const { return get (k); }
+  bool has (hb_codepoint_t k) const { return (*this)[k] != SENTINEL; }
+  /* Predicate. */
+  bool operator () (hb_codepoint_t k) const { return has (k); }
+
+  /* Sink interface. */
+  hb_set_t& operator << (hb_codepoint_t v) { add (v); return *this; }
+
+  bool intersects (hb_codepoint_t first, hb_codepoint_t last) const
   {
     hb_codepoint_t c = first - 1;
     return next (&c) && c <= last;
@@ -396,7 +420,7 @@ struct hb_set_t
       if (other->page_at (b).is_empty ()) { b++; continue; }
       if (page_map[a].major != other->page_map[b].major ||
          !page_at (a).is_equal (&other->page_at (b)))
-        return false;
+       return false;
       a++;
       b++;
     }
@@ -417,13 +441,13 @@ struct hb_set_t
     hb_codepoint_t c = INVALID;
     while (next (&c))
       if (!larger_set->has (c))
-        return false;
+       return false;
 
     return true;
   }
 
-  template <class Op>
-  void process (const hb_set_t *other)
+  template <typename Op>
+  void process (const Op& op, const hb_set_t *other)
   {
     if (unlikely (!successful)) return;
 
@@ -439,21 +463,21 @@ struct hb_set_t
     {
       if (page_map[a].major == other->page_map[b].major)
       {
-        count++;
+       count++;
        a++;
        b++;
       }
       else if (page_map[a].major < other->page_map[b].major)
       {
-        if (Op::passthru_left)
+       if (Op::passthru_left)
          count++;
-        a++;
+       a++;
       }
       else
       {
-        if (Op::passthru_right)
+       if (Op::passthru_right)
          count++;
-        b++;
+       b++;
       }
     }
     if (Op::passthru_left)
@@ -463,7 +487,7 @@ struct hb_set_t
 
     if (count > pages.length)
       if (!resize (count))
-        return;
+       return;
     newCount = count;
 
     /* Process in-place backward. */
@@ -477,7 +501,7 @@ struct hb_set_t
        b--;
        count--;
        page_map[count] = page_map[a];
-       Op::process (page_at (count).v, page_at (a).v, other->page_at (b).v);
+       page_at (count).v = op (page_at (a).v, other->page_at (b).v);
       }
       else if (page_map[a - 1].major > other->page_map[b - 1].major)
       {
@@ -523,19 +547,19 @@ struct hb_set_t
 
   void union_ (const hb_set_t *other)
   {
-    process<HbOpOr> (other);
+    process (hb_bitwise_or, other);
   }
   void intersect (const hb_set_t *other)
   {
-    process<HbOpAnd> (other);
+    process (hb_bitwise_and, other);
   }
   void subtract (const hb_set_t *other)
   {
-    process<HbOpMinus> (other);
+    process (hb_bitwise_sub, other);
   }
   void symmetric_difference (const hb_set_t *other)
   {
-    process<HbOpXor> (other);
+    process (hb_bitwise_xor, other);
   }
   bool next (hb_codepoint_t *codepoint) const
   {
@@ -654,7 +678,7 @@ struct hb_set_t
     unsigned int count = pages.length;
     for (unsigned int i = 0; i < count; i++)
       if (!page_at (i).is_empty ())
-        return page_map[i].major * page_t::PAGE_BITS + page_at (i).get_min ();
+       return page_map[i].major * page_t::PAGE_BITS + page_at (i).get_min ();
     return INVALID;
   }
   hb_codepoint_t get_max () const
@@ -662,7 +686,7 @@ struct hb_set_t
     unsigned int count = pages.length;
     for (int i = count - 1; i >= 0; i++)
       if (!page_at (i).is_empty ())
-        return page_map[(unsigned) i].major * page_t::PAGE_BITS + page_at (i).get_max ();
+       return page_map[(unsigned) i].major * page_t::PAGE_BITS + page_at (i).get_max ();
     return INVALID;
   }
 
@@ -671,27 +695,29 @@ struct hb_set_t
   /*
    * Iterator implementation.
    */
-  struct const_iter_t : hb_sorted_iter_t<const_iter_t, const hb_codepoint_t>
+  struct iter_t : hb_iter_with_fallback_t<iter_t, hb_codepoint_t>
   {
-    const_iter_t (const hb_set_t &s_) :
-      s (s_), v (INVALID), l (s.get_population () + 1) { __next__ (); }
+    static constexpr bool is_sorted_iterator = true;
+    iter_t (const hb_set_t &s_ = Null(hb_set_t)) :
+      s (&s_), v (INVALID), l (s->get_population () + 1) { __next__ (); }
 
-    typedef hb_codepoint_t __item_type__;
+    typedef hb_codepoint_t __item_t__;
     hb_codepoint_t __item__ () const { return v; }
     bool __more__ () const { return v != INVALID; }
-    void __next__ () { s.next (&v); if (l) l--; }
-    void __prev__ () { s.previous (&v); }
-    unsigned __len__ () { return l; }
+    void __next__ () { s->next (&v); if (l) l--; }
+    void __prev__ () { s->previous (&v); }
+    unsigned __len__ () const { return l; }
+    iter_t end () const { return iter_t (*s); }
+    bool operator != (const iter_t& o) const
+    { return s != o.s || v != o.v; }
 
     protected:
-    const hb_set_t &s;
+    const hb_set_t *s;
     hb_codepoint_t v;
     unsigned l;
   };
-  const_iter_t const_iter () const { return const_iter_t (*this); }
-  operator const_iter_t () const { return const_iter (); }
-  typedef const_iter_t iter_t;
-  iter_t iter () const { return const_iter (); }
+  iter_t iter () const { return iter_t (*this); }
+  operator iter_t () const { return iter (); }
 
   protected:
 
index 61ea8d0..ffd723d 100644 (file)
@@ -79,7 +79,9 @@ hb_shape_plan_key_t::init (bool                           copy,
   }
   this->shaper_func = nullptr;
   this->shaper_name = nullptr;
+#ifndef HB_NO_OT_SHAPE
   this->ot.init (face, coords, num_coords);
+#endif
 
   /*
    * Choose shaper.
@@ -148,7 +150,9 @@ hb_shape_plan_key_t::equal (const hb_shape_plan_key_t *other)
 {
   return hb_segment_properties_equal (&this->props, &other->props) &&
         this->user_features_match (other) &&
+#ifndef HB_NO_OT_SHAPE
         this->ot.equal (&other->ot) &&
+#endif
         this->shaper_func == other->shaper_func;
 }
 
@@ -160,13 +164,13 @@ hb_shape_plan_key_t::equal (const hb_shape_plan_key_t *other)
 
 /**
  * hb_shape_plan_create: (Xconstructor)
- * @face: 
- * @props: 
+ * @face:
+ * @props:
  * @user_features: (array length=num_user_features):
- * @num_user_features: 
+ * @num_user_features:
  * @shaper_list: (array zero-terminated=1):
  *
- * 
+ *
  *
  * Return value: (transfer full):
  *
@@ -224,12 +228,16 @@ hb_shape_plan_create2 (hb_face_t                     *face,
                                       num_coords,
                                       shaper_list)))
     goto bail2;
+#ifndef HB_NO_OT_SHAPE
   if (unlikely (!shape_plan->ot.init0 (face, &shape_plan->key)))
     goto bail3;
+#endif
 
   return shape_plan;
 
+#ifndef HB_NO_OT_SHAPE
 bail3:
+#endif
   shape_plan->key.free ();
 bail2:
   free (shape_plan);
@@ -240,7 +248,7 @@ bail:
 /**
  * hb_shape_plan_get_empty:
  *
- * 
+ *
  *
  * Return value: (transfer full):
  *
@@ -256,7 +264,7 @@ hb_shape_plan_get_empty ()
  * hb_shape_plan_reference: (skip)
  * @shape_plan: a shape plan.
  *
- * 
+ *
  *
  * Return value: (transfer full):
  *
@@ -272,7 +280,7 @@ hb_shape_plan_reference (hb_shape_plan_t *shape_plan)
  * hb_shape_plan_destroy: (skip)
  * @shape_plan: a shape plan.
  *
- * 
+ *
  *
  * Since: 0.9.7
  **/
@@ -281,7 +289,9 @@ hb_shape_plan_destroy (hb_shape_plan_t *shape_plan)
 {
   if (!hb_object_destroy (shape_plan)) return;
 
+#ifndef HB_NO_OT_SHAPE
   shape_plan->ot.fini ();
+#endif
   shape_plan->key.free ();
   free (shape_plan);
 }
@@ -289,14 +299,14 @@ hb_shape_plan_destroy (hb_shape_plan_t *shape_plan)
 /**
  * hb_shape_plan_set_user_data: (skip)
  * @shape_plan: a shape plan.
- * @key: 
- * @data: 
- * @destroy: 
- * @replace: 
+ * @key:
+ * @data:
+ * @destroy:
+ * @replace:
+ *
  *
- * 
  *
- * Return value: 
+ * Return value:
  *
  * Since: 0.9.7
  **/
@@ -313,9 +323,9 @@ hb_shape_plan_set_user_data (hb_shape_plan_t    *shape_plan,
 /**
  * hb_shape_plan_get_user_data: (skip)
  * @shape_plan: a shape plan.
- * @key: 
+ * @key:
+ *
  *
- * 
  *
  * Return value: (transfer none):
  *
@@ -332,7 +342,7 @@ hb_shape_plan_get_user_data (hb_shape_plan_t    *shape_plan,
  * hb_shape_plan_get_shaper:
  * @shape_plan: a shape plan.
  *
- * 
+ *
  *
  * Return value: (transfer none):
  *
@@ -351,11 +361,11 @@ hb_shape_plan_get_shaper (hb_shape_plan_t *shape_plan)
  * @font: a font.
  * @buffer: a buffer.
  * @features: (array length=num_features):
- * @num_features: 
+ * @num_features:
  *
- * 
  *
- * Return value: 
+ *
+ * Return value:
  *
  * Since: 0.9.7
  **/
@@ -410,13 +420,13 @@ hb_shape_plan_execute (hb_shape_plan_t    *shape_plan,
 
 /**
  * hb_shape_plan_create_cached:
- * @face: 
- * @props: 
+ * @face:
+ * @props:
  * @user_features: (array length=num_user_features):
- * @num_user_features: 
+ * @num_user_features:
  * @shaper_list: (array zero-terminated=1):
  *
- * 
+ *
  *
  * Return value: (transfer full):
  *
@@ -471,8 +481,8 @@ retry:
     for (hb_face_t::plan_node_t *node = cached_plan_nodes; node; node = node->next)
       if (node->shape_plan->key.equal (&key))
       {
-        DEBUG_MSG_FUNC (SHAPE_PLAN, node->shape_plan, "fulfilled from cache");
-        return hb_shape_plan_reference (node->shape_plan);
+       DEBUG_MSG_FUNC (SHAPE_PLAN, node->shape_plan, "fulfilled from cache");
+       return hb_shape_plan_reference (node->shape_plan);
       }
   }
 
index 3a057fd..6da7edb 100644 (file)
@@ -39,21 +39,23 @@ struct hb_shape_plan_key_t
   const hb_feature_t      *user_features;
   unsigned int             num_user_features;
 
+#ifndef HB_NO_OT_SHAPE
   hb_ot_shape_plan_key_t   ot;
+#endif
 
   hb_shape_func_t         *shaper_func;
   const char              *shaper_name;
 
-  HB_INTERNAL inline bool init (bool                           copy,
-                               hb_face_t                     *face,
-                               const hb_segment_properties_t *props,
-                               const hb_feature_t            *user_features,
-                               unsigned int                   num_user_features,
-                               const int                     *coords,
-                               unsigned int                   num_coords,
-                               const char * const            *shaper_list);
+  HB_INTERNAL bool init (bool                           copy,
+                        hb_face_t                     *face,
+                        const hb_segment_properties_t *props,
+                        const hb_feature_t            *user_features,
+                        unsigned int                   num_user_features,
+                        const int                     *coords,
+                        unsigned int                   num_coords,
+                        const char * const            *shaper_list);
 
-  HB_INTERNAL inline void free () { ::free ((void *) user_features); }
+  HB_INTERNAL void free () { ::free ((void *) user_features); }
 
   HB_INTERNAL bool user_features_match (const hb_shape_plan_key_t *other);
 
@@ -65,7 +67,9 @@ struct hb_shape_plan_t
   hb_object_header_t header;
   hb_face_t *face_unsafe; /* We don't carry a reference to face. */
   hb_shape_plan_key_t key;
+#ifndef HB_NO_OT_SHAPE
   hb_ot_shape_plan_t ot;
+#endif
 };
 
 
index deff77b..cf4e152 100644 (file)
@@ -154,7 +154,9 @@ hb_shape_full (hb_font_t          *font,
  *
  * Shapes @buffer using @font turning its Unicode characters content to
  * positioned glyphs. If @features is not %NULL, it will be used to control the
- * features applied during shaping.
+ * features applied during shaping. If two @features have the same tag but
+ * overlapping ranges the value of the feature with the higher index takes
+ * precedence.
  *
  * Since: 0.9.2
  **/
index 36d8fc7..0d63933 100644 (file)
@@ -28,6 +28,9 @@
 #define HB_SHAPER_LIST_HH
 #endif /* HB_SHAPER_LIST_HH */ /* Dummy header guards */
 
+#ifndef HB_NO_SHAPER
+
+
 /* v--- Add new shapers in the right place here. */
 
 #ifdef HAVE_GRAPHITE2
@@ -35,7 +38,9 @@
 HB_SHAPER_IMPLEMENT (graphite2)
 #endif
 
+#ifndef HB_NO_OT_SHAPE
 HB_SHAPER_IMPLEMENT (ot) /* <--- This is our main OpenType shaper. */
+#endif
 
 #ifdef HAVE_UNISCRIBE
 HB_SHAPER_IMPLEMENT (uniscribe)
@@ -45,12 +50,11 @@ HB_SHAPER_IMPLEMENT (directwrite)
 #endif
 #ifdef HAVE_CORETEXT
 HB_SHAPER_IMPLEMENT (coretext)
-
-/* Only picks up fonts that have a "mort" or "morx" table.
-   Probably going to be removed https://github.com/harfbuzz/harfbuzz/issues/1478 */
-HB_SHAPER_IMPLEMENT (coretext_aat)
 #endif
 
-#ifdef HAVE_FALLBACK
+#ifndef HB_NO_FALLBACK_SHAPE
 HB_SHAPER_IMPLEMENT (fallback) /* <--- This should be last. */
 #endif
+
+
+#endif
index 575ab1f..0ea68ad 100644 (file)
@@ -34,6 +34,9 @@ static const hb_shaper_entry_t all_shapers[] = {
 #include "hb-shaper-list.hh"
 #undef HB_SHAPER_IMPLEMENT
 };
+#ifndef HB_NO_SHAPER
+static_assert (0 != ARRAY_LENGTH_CONST (all_shapers), "No shaper enabled.");
+#endif
 
 #if HB_USE_ATEXIT
 static void free_static_shapers ();
index 4c51588..08a2f21 100644 (file)
 #include "hb-ot-maxp-table.hh"
 
 #ifndef HB_NO_VISIBILITY
+#include "hb-ot-name-language-static.hh"
 
-hb_vector_size_impl_t const _hb_NullPool[(HB_NULL_POOL_SIZE + sizeof (hb_vector_size_impl_t) - 1) / sizeof (hb_vector_size_impl_t)] = {};
-/*thread_local*/ hb_vector_size_impl_t _hb_CrapPool[(HB_NULL_POOL_SIZE + sizeof (hb_vector_size_impl_t) - 1) / sizeof (hb_vector_size_impl_t)] = {};
+uint64_t const _hb_NullPool[(HB_NULL_POOL_SIZE + sizeof (uint64_t) - 1) / sizeof (uint64_t)] = {};
+/*thread_local*/ uint64_t _hb_CrapPool[(HB_NULL_POOL_SIZE + sizeof (uint64_t) - 1) / sizeof (uint64_t)] = {};
 
 DEFINE_NULL_NAMESPACE_BYTES (OT, Index) =  {0xFF,0xFF};
 DEFINE_NULL_NAMESPACE_BYTES (OT, LangSys) = {0x00,0x00, 0xFF,0xFF, 0x00,0x00};
index c4cf666..1c67ab4 100644 (file)
@@ -48,7 +48,7 @@ static const union HB_STRING_ARRAY_TYPE_NAME {
 #include HB_STRING_ARRAY_LIST
 #undef _S
   } st;
-  char str[VAR];
+  char str[HB_VAR_ARRAY];
 }
 HB_STRING_ARRAY_POOL_NAME =
 {
index f29937a..c9a880a 100644 (file)
  * Adobe Author(s): Michiharu Ariza
  */
 
+#include "hb.hh"
+
+#ifndef HB_NO_SUBSET_CFF
+
 #include "hb-ot-cff-common.hh"
 #include "hb-ot-cff2-table.hh"
 #include "hb-subset-cff-common.hh"
@@ -44,18 +48,18 @@ using namespace CFF;
 
 bool
 hb_plan_subset_cff_fdselect (const hb_subset_plan_t *plan,
-                           unsigned int fdCount,
-                           const FDSelect &src, /* IN */
-                           unsigned int &subset_fd_count /* OUT */,
-                           unsigned int &subset_fdselect_size /* OUT */,
-                           unsigned int &subset_fdselect_format /* OUT */,
-                           hb_vector_t<code_pair_t> &fdselect_ranges /* OUT */,
-                           remap_t &fdmap /* OUT */)
+                            unsigned int fdCount,
+                            const FDSelect &src, /* IN */
+                            unsigned int &subset_fd_count /* OUT */,
+                            unsigned int &subset_fdselect_size /* OUT */,
+                            unsigned int &subset_fdselect_format /* OUT */,
+                            hb_vector_t<code_pair_t> &fdselect_ranges /* OUT */,
+                            hb_inc_bimap_t &fdmap /* OUT */)
 {
   subset_fd_count = 0;
   subset_fdselect_size = 0;
   subset_fdselect_format = 0;
-  unsigned int  num_ranges = 0;
+  unsigned int num_ranges = 0;
 
   unsigned int subset_num_glyphs = plan->num_output_glyphs ();
   if (subset_num_glyphs == 0)
@@ -63,14 +67,13 @@ hb_plan_subset_cff_fdselect (const hb_subset_plan_t *plan,
 
   {
     /* use hb_set to determine the subset of font dicts */
-    hb_set_t  *set = hb_set_create ();
-    if (set == &Null (hb_set_t))
-      return false;
-    hb_codepoint_t  prev_fd = CFF_UNDEF_CODE;
+    hb_set_t *set = hb_set_create ();
+    if (unlikely (set == &Null (hb_set_t))) return false;
+    hb_codepoint_t prev_fd = CFF_UNDEF_CODE;
     for (hb_codepoint_t i = 0; i < subset_num_glyphs; i++)
     {
-      hb_codepoint_t   glyph;
-      hb_codepoint_t   fd;
+      hb_codepoint_t glyph;
+      hb_codepoint_t fd;
       if (!plan->old_gid_for_new_gid (i, &glyph))
       {
        /* fonttools retains FDSelect & font dicts for missing glyphs. do the same */
@@ -98,17 +101,13 @@ hb_plan_subset_cff_fdselect (const hb_subset_plan_t *plan,
     else
     {
       /* create a fdmap */
-      if (!fdmap.reset (fdCount))
-      {
-       hb_set_destroy (set);
-       return false;
-      }
+      fdmap.reset ();
 
-      hb_codepoint_t  fd = CFF_UNDEF_CODE;
+      hb_codepoint_t fd = CFF_UNDEF_CODE;
       while (set->next (&fd))
        fdmap.add (fd);
       hb_set_destroy (set);
-      if (unlikely (fdmap.get_count () != subset_fd_count))
+      if (unlikely (fdmap.get_population () != subset_fd_count))
        return false;
     }
 
@@ -152,21 +151,21 @@ hb_plan_subset_cff_fdselect (const hb_subset_plan_t *plan,
 template <typename FDSELECT3_4>
 static inline bool
 serialize_fdselect_3_4 (hb_serialize_context_t *c,
-                         const unsigned int num_glyphs,
-                         const FDSelect &src,
-                         unsigned int size,
-                         const hb_vector_t<code_pair_t> &fdselect_ranges)
+                       const unsigned int num_glyphs,
+                       const FDSelect &src,
+                       unsigned int size,
+                       const hb_vector_t<code_pair_t> &fdselect_ranges)
 {
   TRACE_SERIALIZE (this);
   FDSELECT3_4 *p = c->allocate_size<FDSELECT3_4> (size);
   if (unlikely (p == nullptr)) return_trace (false);
-  p->nRanges ().set (fdselect_ranges.length);
+  p->nRanges () = fdselect_ranges.length;
   for (unsigned int i = 0; i < fdselect_ranges.length; i++)
   {
-    p->ranges[i].first.set (fdselect_ranges[i].glyph);
-    p->ranges[i].fd.set (fdselect_ranges[i].code);
+    p->ranges[i].first = fdselect_ranges[i].glyph;
+    p->ranges[i].fd = fdselect_ranges[i].code;
   }
-  p->sentinel().set (num_glyphs);
+  p->sentinel () = num_glyphs;
   return_trace (true);
 }
 
@@ -176,58 +175,53 @@ serialize_fdselect_3_4 (hb_serialize_context_t *c,
  **/
 bool
 hb_serialize_cff_fdselect (hb_serialize_context_t *c,
-                         const unsigned int num_glyphs,
-                         const FDSelect &src,
-                         unsigned int fd_count,
-                         unsigned int fdselect_format,
-                         unsigned int size,
-                         const hb_vector_t<code_pair_t> &fdselect_ranges)
+                          const unsigned int num_glyphs,
+                          const FDSelect &src,
+                          unsigned int fd_count,
+                          unsigned int fdselect_format,
+                          unsigned int size,
+                          const hb_vector_t<code_pair_t> &fdselect_ranges)
 {
   TRACE_SERIALIZE (this);
-  FDSelect  *p = c->allocate_min<FDSelect> ();
+  FDSelect *p = c->allocate_min<FDSelect> ();
   if (unlikely (p == nullptr)) return_trace (false);
-  p->format.set (fdselect_format);
+  p->format = fdselect_format;
   size -= FDSelect::min_size;
 
   switch (fdselect_format)
   {
 #if CFF_SERIALIZE_FDSELECT_0
-    case 0:
+  case 0:
+  {
+    FDSelect0 *p = c->allocate_size<FDSelect0> (size);
+    if (unlikely (p == nullptr)) return_trace (false);
+    unsigned int range_index = 0;
+    unsigned int fd = fdselect_ranges[range_index++].code;
+    for (unsigned int i = 0; i < num_glyphs; i++)
     {
-      FDSelect0 *p = c->allocate_size<FDSelect0> (size);
-      if (unlikely (p == nullptr)) return_trace (false);
-      unsigned int range_index = 0;
-      unsigned int  fd = fdselect_ranges[range_index++].code;
-      for (unsigned int i = 0; i < num_glyphs; i++)
+      if ((range_index < fdselect_ranges.len) &&
+         (i >= fdselect_ranges[range_index].glyph))
       {
-       if ((range_index < fdselect_ranges.len) &&
-           (i >= fdselect_ranges[range_index].glyph))
-       {
-         fd = fdselect_ranges[range_index++].code;
-       }
-       p->fds[i].set (fd);
+       fd = fdselect_ranges[range_index++].code;
       }
-      break;
+      p->fds[i] = fd;
     }
+    return_trace (true);
+  }
 #endif /* CFF_SERIALIZE_FDSELECT_0 */
 
-    case 3:
-      return serialize_fdselect_3_4<FDSelect3> (c,
-                                               num_glyphs,
-                                               src,
-                                               size,
-                                               fdselect_ranges);
-
-    case 4:
-      return serialize_fdselect_3_4<FDSelect4> (c,
-                                               num_glyphs,
-                                               src,
-                                               size,
-                                               fdselect_ranges);
-
-    default:
-      assert(false);
-  }
+  case 3:
+    return serialize_fdselect_3_4<FDSelect3> (c, num_glyphs, src,
+                                             size, fdselect_ranges);
 
-  return_trace (true);
+  case 4:
+    return serialize_fdselect_3_4<FDSelect4> (c, num_glyphs, src,
+                                             size, fdselect_ranges);
+
+  default:
+    return_trace (false);
+  }
 }
+
+
+#endif
index 81368ee..3c66119 100644 (file)
@@ -209,7 +209,7 @@ struct cff_font_dict_op_serializer_t : op_serializer_t
       /* serialize the opcode */
       HBUINT8 *p = c->allocate_size<HBUINT8> (1);
       if (unlikely (p == nullptr)) return_trace (false);
-      p->set (OpCode_Private);
+      *p = OpCode_Private;
 
       return_trace (true);
     }
@@ -541,39 +541,29 @@ struct subr_subset_param_t
   bool   drop_hints;
 };
 
-struct subr_remap_t : remap_t
+struct subr_remap_t : hb_inc_bimap_t
 {
   void create (hb_set_t *closure)
   {
     /* create a remapping of subroutine numbers from old to new.
      * no optimization based on usage counts. fonttools doesn't appear doing that either.
      */
-    reset (closure->get_max () + 1);
-    for (hb_codepoint_t old_num = 0; old_num < length; old_num++)
-    {
-      if (hb_set_has (closure, old_num))
-       add (old_num);
-    }
 
-    if (get_count () < 1240)
+    hb_codepoint_t old_num = HB_SET_VALUE_INVALID;
+    while (hb_set_next (closure, &old_num))
+      add (old_num);
+
+    if (get_population () < 1240)
       bias = 107;
-    else if (get_count () < 33900)
+    else if (get_population () < 33900)
       bias = 1131;
     else
       bias = 32768;
   }
 
-  hb_codepoint_t operator[] (unsigned int old_num) const
-  {
-    if (old_num >= length)
-      return CFF_UNDEF_CODE;
-    else
-      return remap_t::operator[] (old_num);
-  }
-
   int biased_num (unsigned int old_num) const
   {
-    hb_codepoint_t new_num = (*this)[old_num];
+    hb_codepoint_t new_num = get (old_num);
     return (int)new_num - bias;
   }
 
@@ -581,15 +571,15 @@ struct subr_remap_t : remap_t
   int bias;
 };
 
-struct subr_remap_ts
+struct subr_remaps_t
 {
-  subr_remap_ts ()
+  subr_remaps_t ()
   {
     global_remap.init ();
     local_remaps.init ();
   }
 
-  ~subr_remap_ts () { fini (); }
+  ~subr_remaps_t () { fini (); }
 
   void init (unsigned int fdCount)
   {
@@ -765,7 +755,7 @@ struct subr_subsetter_t
 
   bool encode_subrs (const parsed_cs_str_vec_t &subrs, const subr_remap_t& remap, unsigned int fd, str_buff_vec_t &buffArray) const
   {
-    unsigned int  count = remap.get_count ();
+    unsigned int  count = remap.get_population ();
 
     if (unlikely (!buffArray.resize (count)))
       return false;
@@ -926,7 +916,7 @@ struct subr_subsetter_t
                                  hb_set_t *closure,
                                  const subr_subset_param_t &param)
   {
-    hb_set_add (closure, subr_num);
+    closure->add (subr_num);
     collect_subr_refs_in_str (subrs[subr_num], param);
   }
 
@@ -1005,7 +995,7 @@ struct subr_subsetter_t
   parsed_cs_str_vec_t          parsed_global_subrs;
   hb_vector_t<parsed_cs_str_vec_t>  parsed_local_subrs;
 
-  subr_remap_ts                        remaps;
+  subr_remaps_t                        remaps;
 
   private:
   typedef typename SUBRS::count_type subr_count_type;
@@ -1021,7 +1011,7 @@ hb_plan_subset_cff_fdselect (const hb_subset_plan_t *plan,
                            unsigned int &subset_fdselect_size /* OUT */,
                            unsigned int &subset_fdselect_format /* OUT */,
                            hb_vector_t<CFF::code_pair_t> &fdselect_ranges /* OUT */,
-                           CFF::remap_t &fdmap /* OUT */);
+                           hb_inc_bimap_t &fdmap /* OUT */);
 
 HB_INTERNAL bool
 hb_serialize_cff_fdselect (hb_serialize_context_t *c,
index 49ac0bf..e9e0757 100644 (file)
  * Adobe Author(s): Michiharu Ariza
  */
 
+#include "hb.hh"
+
+#ifndef HB_NO_SUBSET_CFF
+
 #include "hb-open-type.hh"
 #include "hb-ot-cff1-table.hh"
 #include "hb-set.h"
+#include "hb-bimap.hh"
 #include "hb-subset-cff1.hh"
 #include "hb-subset-plan.hh"
 #include "hb-subset-cff-common.hh"
 
 using namespace CFF;
 
-struct remap_sid_t : remap_t
+struct remap_sid_t : hb_inc_bimap_t
 {
   unsigned int add (unsigned int sid)
   {
     if ((sid != CFF_UNDEF_SID) && !is_std_std (sid))
-      return offset_sid (remap_t::add (unoffset_sid (sid)));
+      return offset_sid (hb_inc_bimap_t::add (unoffset_sid (sid)));
     else
       return sid;
   }
@@ -49,7 +54,7 @@ struct remap_sid_t : remap_t
     if (is_std_std (sid) || (sid == CFF_UNDEF_SID))
       return sid;
     else
-      return offset_sid (remap_t::operator [] (unoffset_sid (sid)));
+      return offset_sid (get (unoffset_sid (sid)));
   }
 
   static const unsigned int num_std_strings = 391;
@@ -147,7 +152,7 @@ struct cff1_top_dict_op_serializer_t : cff_top_dict_op_serializer_t<cff1_top_dic
            return_trace (false);
          HBUINT8 *p = c->allocate_size<HBUINT8> (1);
          if (unlikely (p == nullptr)) return_trace (false);
-         p->set (OpCode_Private);
+         *p = OpCode_Private;
        }
        break;
 
@@ -351,7 +356,7 @@ struct cff1_cs_opset_subr_subset_t : cff1_cs_opset_t<cff1_cs_opset_subr_subset_t
       case OpCode_return:
        param.current_parsed_str->add_op (op, env.str_ref);
        param.current_parsed_str->set_parsed ();
-       env.returnFromSubr ();
+       env.return_from_subr ();
        param.set_current_str (env, false);
        break;
 
@@ -382,9 +387,9 @@ struct cff1_cs_opset_subr_subset_t : cff1_cs_opset_t<cff1_cs_opset_subr_subset_t
                                 cff1_biased_subrs_t& subrs, hb_set_t *closure)
   {
     byte_str_ref_t    str_ref = env.str_ref;
-    env.callSubr (subrs, type);
+    env.call_subr (subrs, type);
     param.current_parsed_str->add_call_op (op, str_ref, env.context.subr_num);
-    hb_set_add (closure, env.context.subr_num);
+    closure->add (env.context.subr_num);
     param.set_current_str (env, true);
   }
 
@@ -394,8 +399,8 @@ struct cff1_cs_opset_subr_subset_t : cff1_cs_opset_t<cff1_cs_opset_subr_subset_t
 
 struct cff1_subr_subsetter_t : subr_subsetter_t<cff1_subr_subsetter_t, CFF1Subrs, const OT::cff1::accelerator_subset_t, cff1_cs_interp_env_t, cff1_cs_opset_subr_subset_t, OpCode_endchar>
 {
-  cff1_subr_subsetter_t (const OT::cff1::accelerator_subset_t &acc, const hb_subset_plan_t *plan)
-    : subr_subsetter_t (acc, plan) {}
+  cff1_subr_subsetter_t (const OT::cff1::accelerator_subset_t &acc_, const hb_subset_plan_t *plan_)
+    : subr_subsetter_t (acc_, plan_) {}
 
   static void finalize_parsed_str (cff1_cs_interp_env_t &env, subr_subset_param_t& param, parsed_cs_str_t &charstring)
   {
@@ -577,8 +582,7 @@ struct cff_subset_plan {
 
   bool collect_sids_in_dicts (const OT::cff1::accelerator_subset_t &acc)
   {
-    if (unlikely (!sidmap.reset (acc.stringIndex->count)))
-      return false;
+    sidmap.reset ();
 
     for (unsigned int i = 0; i < name_dict_values_t::ValCount; i++)
     {
@@ -592,7 +596,7 @@ struct cff_subset_plan {
 
     if (acc.fdArray != &Null(CFF1FDArray))
       for (unsigned int i = 0; i < orig_fdcount; i++)
-       if (fdmap.includes (i))
+       if (fdmap.has (i))
          (void)sidmap.add (acc.fontDicts[i].fontName);
 
     return true;
@@ -678,7 +682,7 @@ struct cff_subset_plan {
       /* SIDs for name strings in dicts are added before glyph names so they fit in 16-bit int range */
       if (unlikely (!collect_sids_in_dicts (acc)))
        return false;
-      if (unlikely (sidmap.get_count () > 0x8000))     /* assumption: a dict won't reference that many strings */
+      if (unlikely (sidmap.get_population () > 0x8000))        /* assumption: a dict won't reference that many strings */
        return false;
       if (subset_charset)
        offsets.charsetInfo.size = plan_subset_charset (acc, plan);
@@ -735,7 +739,7 @@ struct cff_subset_plan {
       {
        subset_localsubrs[fd].init ();
        offsets.localSubrsInfos[fd].init ();
-       if (fdmap.includes (fd))
+       if (fdmap.has (fd))
        {
          if (!subr_subsetter.encode_localsubrs (fd, subset_localsubrs[fd]))
            return false;
@@ -786,7 +790,7 @@ struct cff_subset_plan {
       cff1_font_dict_op_serializer_t fontSzr;
       unsigned int dictsSize = 0;
       for (unsigned int i = 0; i < acc.fontDicts.length; i++)
-       if (fdmap.includes (i))
+       if (fdmap.has (i))
          dictsSize += FontDict::calculate_serialized_size (acc.fontDicts[i], fontSzr);
 
       offsets.FDArrayInfo.offSize = calcOffSize (dictsSize);
@@ -809,7 +813,7 @@ struct cff_subset_plan {
     offsets.privateDictInfo.offset = final_size;
     for (unsigned int i = 0; i < orig_fdcount; i++)
     {
-      if (fdmap.includes (i))
+      if (fdmap.has (i))
       {
        bool  has_localsubrs = offsets.localSubrsInfos[i].size > 0;
        cff_private_dict_op_serializer_t privSzr (desubroutinize, plan->drop_hints);
@@ -853,7 +857,7 @@ struct cff_subset_plan {
 
   /* font dict index remap table from fullset FDArray to subset FDArray.
    * set to CFF_UNDEF_CODE if excluded from subset */
-  remap_t   fdmap;
+  hb_inc_bimap_t   fdmap;
 
   str_buff_vec_t               subset_charstrings;
   str_buff_vec_t               subset_globalsubrs;
@@ -892,10 +896,10 @@ static inline bool _write_cff1 (const cff_subset_plan &plan,
     return false;
 
   /* header */
-  cff->version.major.set (0x01);
-  cff->version.minor.set (0x00);
-  cff->nameIndex.set (cff->min_size);
-  cff->offSize.set (4); /* unused? */
+  cff->version.major = 0x01;
+  cff->version.minor = 0x00;
+  cff->nameIndex = cff->min_size;
+  cff->offSize = 4; /* unused? */
 
   /* name INDEX */
   {
@@ -912,7 +916,7 @@ static inline bool _write_cff1 (const cff_subset_plan &plan,
   /* top dict INDEX */
   {
     assert (plan.offsets.topDictInfo.offset == (unsigned) (c.head - c.start));
-    CFF1IndexOf<TopDict> *dest = c.start_embed< CFF1IndexOf<TopDict> > ();
+    CFF1IndexOf<TopDict> *dest = c.start_embed< CFF1IndexOf<TopDict>> ();
     if (dest == nullptr) return false;
     cff1_top_dict_op_serializer_t topSzr;
     top_dict_modifiers_t  modifier (plan.offsets, plan.topDictModSIDs);
@@ -1030,7 +1034,7 @@ static inline bool _write_cff1 (const cff_subset_plan &plan,
   assert (plan.offsets.privateDictInfo.offset == (unsigned) (c.head - c.start));
   for (unsigned int i = 0; i < acc.privateDicts.length; i++)
   {
-    if (plan.fdmap.includes (i))
+    if (plan.fdmap.has (i))
     {
       PrivateDict  *pd = c.start_embed<PrivateDict> ();
       if (unlikely (pd == nullptr)) return false;
@@ -1038,7 +1042,7 @@ static inline bool _write_cff1 (const cff_subset_plan &plan,
       bool result;
       cff_private_dict_op_serializer_t privSzr (plan.desubroutinize, plan.drop_hints);
       /* N.B. local subrs immediately follows its corresponding private dict. i.e., subr offset == private dict size */
-      unsigned int  subroffset = (plan.offsets.localSubrsInfos[i].size > 0)? priv_size: 0;
+      unsigned int subroffset = (plan.offsets.localSubrsInfos[i].size > 0) ? priv_size : 0;
       result = pd->serialize (&c, acc.privateDicts[i], privSzr, subroffset);
       if (unlikely (!result))
       {
@@ -1064,7 +1068,7 @@ static inline bool _write_cff1 (const cff_subset_plan &plan,
   return true;
 }
 
-static bool
+static inline bool
 _hb_subset_cff1 (const OT::cff1::accelerator_subset_t  &acc,
                const char              *data,
                hb_subset_plan_t        *plan,
@@ -1118,3 +1122,6 @@ hb_subset_cff1 (hb_subset_plan_t *plan,
 
   return result;
 }
+
+
+#endif
index bf76a3e..7edc3f5 100644 (file)
  * Adobe Author(s): Michiharu Ariza
  */
 
+#include "hb.hh"
+
+#ifndef HB_NO_SUBSET_CFF
+
 #include "hb-open-type.hh"
 #include "hb-ot-cff2-table.hh"
 #include "hb-set.h"
@@ -183,7 +187,7 @@ struct cff2_cs_opset_subr_subset_t : cff2_cs_opset_t<cff2_cs_opset_subr_subset_t
 
       case OpCode_return:
        param.current_parsed_str->set_parsed ();
-       env.returnFromSubr ();
+       env.return_from_subr ();
        param.set_current_str (env, false);
        break;
 
@@ -213,9 +217,9 @@ struct cff2_cs_opset_subr_subset_t : cff2_cs_opset_t<cff2_cs_opset_subr_subset_t
                                 cff2_biased_subrs_t& subrs, hb_set_t *closure)
   {
     byte_str_ref_t    str_ref = env.str_ref;
-    env.callSubr (subrs, type);
+    env.call_subr (subrs, type);
     param.current_parsed_str->add_call_op (op, str_ref, env.context.subr_num);
-    hb_set_add (closure, env.context.subr_num);
+    closure->add (env.context.subr_num);
     param.set_current_str (env, true);
   }
 
@@ -225,8 +229,8 @@ struct cff2_cs_opset_subr_subset_t : cff2_cs_opset_t<cff2_cs_opset_subr_subset_t
 
 struct cff2_subr_subsetter_t : subr_subsetter_t<cff2_subr_subsetter_t, CFF2Subrs, const OT::cff2::accelerator_subset_t, cff2_cs_interp_env_t, cff2_cs_opset_subr_subset_t>
 {
-  cff2_subr_subsetter_t (const OT::cff2::accelerator_subset_t &acc, const hb_subset_plan_t *plan)
-    : subr_subsetter_t (acc, plan) {}
+  cff2_subr_subsetter_t (const OT::cff2::accelerator_subset_t &acc_, const hb_subset_plan_t *plan_)
+    : subr_subsetter_t (acc_, plan_) {}
 
   static void finalize_parsed_str (cff2_cs_interp_env_t &env, subr_subset_param_t& param, parsed_cs_str_t &charstring)
   {
@@ -326,18 +330,15 @@ struct cff2_subset_plan {
       {
        subset_localsubrs[fd].init ();
        offsets.localSubrsInfos[fd].init ();
-       if (fdmap.includes (fd))
+       if (!subr_subsetter.encode_localsubrs (fd, subset_localsubrs[fd]))
+         return false;
+
+       unsigned int dataSize = subset_localsubrs[fd].total_size ();
+       if (dataSize > 0)
        {
-         if (!subr_subsetter.encode_localsubrs (fd, subset_localsubrs[fd]))
-           return false;
-
-         unsigned int dataSize = subset_localsubrs[fd].total_size ();
-         if (dataSize > 0)
-         {
-           offsets.localSubrsInfos[fd].offset = final_size;
-           offsets.localSubrsInfos[fd].offSize = calcOffSize (dataSize);
-           offsets.localSubrsInfos[fd].size = CFF2Subrs::calculate_serialized_size (offsets.localSubrsInfos[fd].offSize, subset_localsubrs[fd].length, dataSize);
-         }
+         offsets.localSubrsInfos[fd].offset = final_size;
+         offsets.localSubrsInfos[fd].offSize = calcOffSize (dataSize);
+         offsets.localSubrsInfos[fd].size = CFF2Subrs::calculate_serialized_size (offsets.localSubrsInfos[fd].offSize, subset_localsubrs[fd].length, dataSize);
        }
       }
     }
@@ -378,7 +379,7 @@ struct cff2_subset_plan {
       cff_font_dict_op_serializer_t fontSzr;
       unsigned int dictsSize = 0;
       for (unsigned int i = 0; i < acc.fontDicts.length; i++)
-       if (fdmap.includes (i))
+       if (fdmap.has (i))
          dictsSize += FontDict::calculate_serialized_size (acc.fontDicts[i], fontSzr);
 
       offsets.FDArrayInfo.offSize = calcOffSize (dictsSize);
@@ -397,7 +398,7 @@ struct cff2_subset_plan {
     offsets.privateDictsOffset = final_size;
     for (unsigned int i = 0; i < orig_fdcount; i++)
     {
-      if (fdmap.includes (i))
+      if (fdmap.has (i))
       {
        bool  has_localsubrs = offsets.localSubrsInfos[i].size > 0;
        cff_private_dict_op_serializer_t privSzr (desubroutinize, drop_hints);
@@ -427,7 +428,7 @@ struct cff2_subset_plan {
   unsigned int    subset_fdselect_format;
   hb_vector_t<code_pair_t>   subset_fdselect_ranges;
 
-  remap_t   fdmap;
+  hb_inc_bimap_t   fdmap;
 
   str_buff_vec_t           subset_charstrings;
   str_buff_vec_t           subset_globalsubrs;
@@ -451,14 +452,14 @@ static inline bool _write_cff2 (const cff2_subset_plan &plan,
     return false;
 
   /* header */
-  cff2->version.major.set (0x02);
-  cff2->version.minor.set (0x00);
-  cff2->topDict.set (OT::cff2::static_size);
+  cff2->version.major = 0x02;
+  cff2->version.minor = 0x00;
+  cff2->topDict = OT::cff2::static_size;
 
   /* top dict */
   {
     assert (cff2->topDict == (unsigned) (c.head - c.start));
-    cff2->topDictSize.set (plan.offsets.topDictInfo.size);
+    cff2->topDictSize = plan.offsets.topDictInfo.size;
     TopDict &dict = cff2 + cff2->topDict;
     cff2_top_dict_op_serializer_t topSzr;
     if (unlikely (!dict.serialize (&c, acc.topDict, topSzr, plan.offsets)))
@@ -537,7 +538,7 @@ static inline bool _write_cff2 (const cff2_subset_plan &plan,
   assert (plan.offsets.privateDictsOffset == (unsigned) (c.head - c.start));
   for (unsigned int i = 0; i < acc.privateDicts.length; i++)
   {
-    if (plan.fdmap.includes (i))
+    if (plan.fdmap.has (i))
     {
       PrivateDict  *pd = c.start_embed<PrivateDict> ();
       if (unlikely (pd == nullptr)) return false;
@@ -545,7 +546,7 @@ static inline bool _write_cff2 (const cff2_subset_plan &plan,
       bool result;
       cff_private_dict_op_serializer_t privSzr (plan.desubroutinize, plan.drop_hints);
       /* N.B. local subrs immediately follows its corresponding private dict. i.e., subr offset == private dict size */
-      unsigned int  subroffset = (plan.offsets.localSubrsInfos[i].size > 0)? priv_size: 0;
+      unsigned int subroffset = (plan.offsets.localSubrsInfos[i].size > 0) ? priv_size : 0;
       result = pd->serialize (&c, acc.privateDicts[i], privSzr, subroffset);
       if (unlikely (!result))
       {
@@ -571,7 +572,7 @@ static inline bool _write_cff2 (const cff2_subset_plan &plan,
   return true;
 }
 
-static bool
+static inline bool
 _hb_subset_cff2 (const OT::cff2::accelerator_subset_t  &acc,
                const char                    *data,
                hb_subset_plan_t                *plan,
@@ -626,3 +627,6 @@ hb_subset_cff2 (hb_subset_plan_t *plan,
 
   return result;
 }
+
+
+#endif
diff --git a/src/hb-subset-glyf.cc b/src/hb-subset-glyf.cc
deleted file mode 100644 (file)
index ee004ee..0000000
+++ /dev/null
@@ -1,346 +0,0 @@
-/*
- * Copyright © 2018  Google, Inc.
- *
- *  This is part of HarfBuzz, a text shaping library.
- *
- * Permission is hereby granted, without written agreement and without
- * license or royalty fees, to use, copy, modify, and distribute this
- * software and its documentation for any purpose, provided that the
- * above copyright notice and the following two paragraphs appear in
- * all copies of this software.
- *
- * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
- * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
- * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
- * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
- * DAMAGE.
- *
- * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
- * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
- * FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS
- * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
- * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
- *
- * Google Author(s): Garret Rieger, Roderick Sheeter
- */
-
-#include "hb-open-type.hh"
-#include "hb-ot-glyf-table.hh"
-#include "hb-set.h"
-#include "hb-subset-glyf.hh"
-
-struct loca_data_t
-{
-  bool          is_short;
-  void         *data;
-  unsigned int  size;
-
-  inline bool
-  _write_loca_entry (unsigned int  id,
-                     unsigned int  offset)
-  {
-    unsigned int entry_size = is_short ? sizeof (OT::HBUINT16) : sizeof (OT::HBUINT32);
-    if ((id + 1) * entry_size <= size)
-    {
-      if (is_short) {
-        ((OT::HBUINT16*) data) [id].set (offset / 2);
-      } else {
-        ((OT::HBUINT32*) data) [id].set (offset);
-      }
-      return true;
-    }
-
-    // Offset was not written because the write is out of bounds.
-    DEBUG_MSG(SUBSET,
-              nullptr,
-              "WARNING: Attempted to write an out of bounds loca entry at index %d. Loca size is %d.",
-              id,
-              size);
-    return false;
-  }
-};
-
-/**
- * If hints are being dropped find the range which in glyf at which
- * the hinting instructions are located. Add them to the instruction_ranges
- * vector.
- */
-static bool
-_add_instructions_range (const OT::glyf::accelerator_t &glyf,
-                         hb_codepoint_t                 glyph_id,
-                         unsigned int                   glyph_start_offset,
-                         unsigned int                   glyph_end_offset,
-                         bool                           drop_hints,
-                         hb_vector_t<unsigned int>     *instruction_ranges /* OUT */)
-{
-  if (!instruction_ranges->resize (instruction_ranges->length + 2))
-  {
-    DEBUG_MSG(SUBSET, nullptr, "Failed to resize instruction_ranges.");
-    return false;
-  }
-  unsigned int *instruction_start = &(*instruction_ranges)[instruction_ranges->length - 2];
-  *instruction_start = 0;
-  unsigned int *instruction_end = &(*instruction_ranges)[instruction_ranges->length - 1];
-  *instruction_end = 0;
-
-  if (drop_hints)
-  {
-    if (unlikely (!glyf.get_instruction_offsets (glyph_start_offset, glyph_end_offset,
-                                                 instruction_start, instruction_end)))
-    {
-      DEBUG_MSG(SUBSET, nullptr, "Unable to get instruction offsets for %d", glyph_id);
-      return false;
-    }
-  }
-
-  return true;
-}
-
-static bool
-_calculate_glyf_and_loca_prime_size (const OT::glyf::accelerator_t &glyf,
-                                     const hb_subset_plan_t        *plan,
-                                     loca_data_t                   *loca_data, /* OUT */
-                                    unsigned int                  *glyf_size /* OUT */,
-                                    hb_vector_t<unsigned int>     *instruction_ranges /* OUT */)
-{
-  unsigned int total = 0;
-
-  hb_codepoint_t next_glyph = HB_SET_VALUE_INVALID;
-  while (plan->glyphset ()->next (&next_glyph))
-  {
-    unsigned int start_offset, end_offset;
-    if (unlikely (!(glyf.get_offsets (next_glyph, &start_offset, &end_offset) &&
-                   glyf.remove_padding (start_offset, &end_offset))))
-    {
-      DEBUG_MSG(SUBSET, nullptr, "Invalid gid %d", next_glyph);
-      start_offset = end_offset = 0;
-    }
-
-    bool is_zero_length = end_offset - start_offset < OT::glyf::GlyphHeader::static_size;
-    if (!_add_instructions_range (glyf,
-                                  next_glyph,
-                                  start_offset,
-                                  end_offset,
-                                  plan->drop_hints && !is_zero_length,
-                                  instruction_ranges))
-      return false;
-
-    if (is_zero_length)
-      continue; /* 0-length glyph */
-
-    total += end_offset - start_offset
-             - ((*instruction_ranges)[instruction_ranges->length - 1]
-                - (*instruction_ranges)[instruction_ranges->length - 2]);
-    /* round2 so short loca will work */
-    total += total % 2;
-  }
-
-  *glyf_size = total;
-  loca_data->is_short = (total <= 131070);
-  loca_data->size = (plan->num_output_glyphs () + 1)
-      * (loca_data->is_short ? sizeof (OT::HBUINT16) : sizeof (OT::HBUINT32));
-
-  DEBUG_MSG(SUBSET, nullptr, "preparing to subset glyf: final size %d, loca size %d, using %s loca",
-           total,
-           loca_data->size,
-           loca_data->is_short ? "short" : "long");
-  return true;
-}
-
-static void
-_update_components (const hb_subset_plan_t *plan,
-                   char                   *glyph_start,
-                   unsigned int            length)
-{
-  OT::glyf::CompositeGlyphHeader::Iterator iterator;
-  if (OT::glyf::CompositeGlyphHeader::get_iterator (glyph_start,
-                                                   length,
-                                                   &iterator))
-  {
-    do
-    {
-      hb_codepoint_t new_gid;
-      if (!plan->new_gid_for_old_gid (iterator.current->glyphIndex,
-                                     &new_gid))
-       continue;
-
-      ((OT::glyf::CompositeGlyphHeader *) iterator.current)->glyphIndex.set (new_gid);
-    } while (iterator.move_to_next ());
-  }
-}
-
-static bool _remove_composite_instruction_flag (char *glyf_prime, unsigned int length)
-{
-  /* remove WE_HAVE_INSTRUCTIONS from flags in dest */
-  OT::glyf::CompositeGlyphHeader::Iterator composite_it;
-  if (unlikely (!OT::glyf::CompositeGlyphHeader::get_iterator (glyf_prime, length, &composite_it))) return false;
-  const OT::glyf::CompositeGlyphHeader *glyph;
-  do {
-    glyph = composite_it.current;
-    OT::HBUINT16 *flags = const_cast<OT::HBUINT16 *> (&glyph->flags);
-    flags->set ( (uint16_t) *flags & ~OT::glyf::CompositeGlyphHeader::WE_HAVE_INSTRUCTIONS);
-  } while (composite_it.move_to_next ());
-  return true;
-}
-
-static bool
-_write_glyf_and_loca_prime (const hb_subset_plan_t        *plan,
-                           const OT::glyf::accelerator_t &glyf,
-                           const char                    *glyf_data,
-                           hb_vector_t<unsigned int>     &instruction_ranges,
-                           unsigned int                   glyf_prime_size,
-                           char                          *glyf_prime_data /* OUT */,
-                           loca_data_t                   *loca_prime /* OUT */)
-{
-  char *glyf_prime_data_next = glyf_prime_data;
-
-  bool success = true;
-
-
-  unsigned int i = 0;
-  hb_codepoint_t new_gid;
-  for (new_gid = 0; new_gid < plan->num_output_glyphs (); new_gid++)
-  {
-    hb_codepoint_t old_gid;
-    if (!plan->old_gid_for_new_gid (new_gid, &old_gid))
-    {
-      // Empty glyph, add a loca entry and carry on.
-      loca_prime->_write_loca_entry (new_gid,
-                                     glyf_prime_data_next - glyf_prime_data);
-      continue;
-    }
-
-
-    unsigned int start_offset, end_offset;
-    if (unlikely (!(glyf.get_offsets (old_gid, &start_offset, &end_offset) &&
-                   glyf.remove_padding (start_offset, &end_offset))))
-      end_offset = start_offset = 0;
-
-    unsigned int instruction_start = instruction_ranges[i * 2];
-    unsigned int instruction_end = instruction_ranges[i * 2 + 1];
-
-    int length = end_offset - start_offset - (instruction_end - instruction_start);
-
-    if (glyf_prime_data_next + length > glyf_prime_data + glyf_prime_size)
-    {
-      DEBUG_MSG(SUBSET,
-                nullptr,
-                "WARNING: Attempted to write an out of bounds glyph entry for gid %d (length %d)",
-                i, length);
-      return false;
-    }
-
-    if (instruction_start == instruction_end)
-      memcpy (glyf_prime_data_next, glyf_data + start_offset, length);
-    else
-    {
-      memcpy (glyf_prime_data_next, glyf_data + start_offset, instruction_start - start_offset);
-      memcpy (glyf_prime_data_next + instruction_start - start_offset, glyf_data + instruction_end, end_offset - instruction_end);
-      /* if the instructions end at the end this was a composite glyph, else simple */
-      if (instruction_end == end_offset)
-      {
-       if (unlikely (!_remove_composite_instruction_flag (glyf_prime_data_next, length))) return false;
-      }
-      else
-       /* zero instruction length, which is just before instruction_start */
-       memset (glyf_prime_data_next + instruction_start - start_offset - 2, 0, 2);
-    }
-
-    success = success && loca_prime->_write_loca_entry (new_gid,
-                                                        glyf_prime_data_next - glyf_prime_data);
-    _update_components (plan, glyf_prime_data_next, length);
-
-    // TODO: don't align to two bytes if using long loca.
-    glyf_prime_data_next += length + (length % 2); // Align to 2 bytes for short loca.
-
-    i++;
-  }
-
-  // loca table has n+1 entries where the last entry signifies the end location of the last
-  // glyph.
-  success = success && loca_prime->_write_loca_entry (new_gid,
-                                                      glyf_prime_data_next - glyf_prime_data);
-  return success;
-}
-
-static bool
-_hb_subset_glyf_and_loca (const OT::glyf::accelerator_t  &glyf,
-                         const char                     *glyf_data,
-                         hb_subset_plan_t               *plan,
-                         bool                           *use_short_loca,
-                         hb_blob_t                     **glyf_prime_blob /* OUT */,
-                         hb_blob_t                     **loca_prime_blob /* OUT */)
-{
-  // TODO(grieger): Sanity check allocation size for the new table.
-  loca_data_t loca_prime;
-  unsigned int glyf_prime_size;
-  hb_vector_t<unsigned int> instruction_ranges;
-  instruction_ranges.init ();
-
-  if (unlikely (!_calculate_glyf_and_loca_prime_size (glyf,
-                                                      plan,
-                                                      &loca_prime,
-                                                     &glyf_prime_size,
-                                                     &instruction_ranges))) {
-    instruction_ranges.fini ();
-    return false;
-  }
-  *use_short_loca = loca_prime.is_short;
-
-  char *glyf_prime_data = (char *) calloc (1, glyf_prime_size);
-  loca_prime.data = (void *) calloc (1, loca_prime.size);
-  if (unlikely (!_write_glyf_and_loca_prime (plan, glyf, glyf_data,
-                                            instruction_ranges,
-                                            glyf_prime_size, glyf_prime_data,
-                                            &loca_prime))) {
-    free (glyf_prime_data);
-    free (loca_prime.data);
-    instruction_ranges.fini ();
-    return false;
-  }
-  instruction_ranges.fini ();
-
-  *glyf_prime_blob = hb_blob_create (glyf_prime_data,
-                                     glyf_prime_size,
-                                     HB_MEMORY_MODE_READONLY,
-                                     glyf_prime_data,
-                                     free);
-  *loca_prime_blob = hb_blob_create ((char *) loca_prime.data,
-                                     loca_prime.size,
-                                     HB_MEMORY_MODE_READONLY,
-                                     loca_prime.data,
-                                     free);
-  return true;
-}
-
-/**
- * hb_subset_glyf:
- * Subsets the glyph table according to a provided plan.
- *
- * Return value: subsetted glyf table.
- *
- * Since: 1.7.5
- **/
-bool
-hb_subset_glyf_and_loca (hb_subset_plan_t *plan,
-                        bool             *use_short_loca, /* OUT */
-                        hb_blob_t       **glyf_prime, /* OUT */
-                        hb_blob_t       **loca_prime /* OUT */)
-{
-  hb_blob_t *glyf_blob = hb_sanitize_context_t ().reference_table<OT::glyf> (plan->source);
-  const char *glyf_data = hb_blob_get_data (glyf_blob, nullptr);
-
-  OT::glyf::accelerator_t glyf;
-  glyf.init (plan->source);
-  bool result = _hb_subset_glyf_and_loca (glyf,
-                                         glyf_data,
-                                         plan,
-                                         use_short_loca,
-                                         glyf_prime,
-                                         loca_prime);
-
-  hb_blob_destroy (glyf_blob);
-  glyf.fini ();
-
-  return result;
-}
index 693c9c2..d92f33f 100644 (file)
@@ -44,11 +44,45 @@ hb_subset_input_create_or_fail ()
 
   input->unicodes = hb_set_create ();
   input->glyphs = hb_set_create ();
+  input->name_ids = hb_set_create ();
+  hb_set_add_range (input->name_ids, 0, 6);
+  input->drop_tables = hb_set_create ();
   input->drop_hints = false;
-  input->drop_layout = true;
   input->desubroutinize = false;
   input->retain_gids = false;
 
+  hb_tag_t default_drop_tables[] = {
+    // Layout disabled by default
+    HB_TAG ('G', 'S', 'U', 'B'),
+    HB_TAG ('G', 'P', 'O', 'S'),
+    HB_TAG ('G', 'D', 'E', 'F'),
+    HB_TAG ('m', 'o', 'r', 'x'),
+    HB_TAG ('m', 'o', 'r', 't'),
+    HB_TAG ('k', 'e', 'r', 'x'),
+    HB_TAG ('k', 'e', 'r', 'n'),
+
+    // Copied from fontTools:
+    HB_TAG ('B', 'A', 'S', 'E'),
+    HB_TAG ('J', 'S', 'T', 'F'),
+    HB_TAG ('D', 'S', 'I', 'G'),
+    HB_TAG ('E', 'B', 'D', 'T'),
+    HB_TAG ('E', 'B', 'L', 'C'),
+    HB_TAG ('E', 'B', 'S', 'C'),
+    HB_TAG ('S', 'V', 'G', ' '),
+    HB_TAG ('P', 'C', 'L', 'T'),
+    HB_TAG ('L', 'T', 'S', 'H'),
+    // Graphite tables
+    HB_TAG ('F', 'e', 'a', 't'),
+    HB_TAG ('G', 'l', 'a', 't'),
+    HB_TAG ('G', 'l', 'o', 'c'),
+    HB_TAG ('S', 'i', 'l', 'f'),
+    HB_TAG ('S', 'i', 'l', 'l'),
+    // Colour
+    HB_TAG ('s', 'b', 'i', 'x')
+  };
+
+  input->drop_tables->add_array (default_drop_tables, ARRAY_LENGTH (default_drop_tables));
+
   return input;
 }
 
@@ -81,6 +115,8 @@ hb_subset_input_destroy (hb_subset_input_t *subset_input)
 
   hb_set_destroy (subset_input->unicodes);
   hb_set_destroy (subset_input->glyphs);
+  hb_set_destroy (subset_input->name_ids);
+  hb_set_destroy (subset_input->drop_tables);
 
   free (subset_input);
 }
@@ -109,35 +145,34 @@ hb_subset_input_glyph_set (hb_subset_input_t *subset_input)
   return subset_input->glyphs;
 }
 
-HB_EXTERN void
-hb_subset_input_set_drop_hints (hb_subset_input_t *subset_input,
-                               hb_bool_t drop_hints)
+HB_EXTERN hb_set_t *
+hb_subset_input_nameid_set (hb_subset_input_t *subset_input)
 {
-  subset_input->drop_hints = drop_hints;
+  return subset_input->name_ids;
 }
 
-HB_EXTERN hb_bool_t
-hb_subset_input_get_drop_hints (hb_subset_input_t *subset_input)
+HB_EXTERN hb_set_t *
+hb_subset_input_drop_tables_set (hb_subset_input_t *subset_input)
 {
-  return subset_input->drop_hints;
+  return subset_input->drop_tables;
 }
 
 HB_EXTERN void
-hb_subset_input_set_drop_layout (hb_subset_input_t *subset_input,
-                                hb_bool_t drop_layout)
+hb_subset_input_set_drop_hints (hb_subset_input_t *subset_input,
+                               hb_bool_t drop_hints)
 {
-  subset_input->drop_layout = drop_layout;
+  subset_input->drop_hints = drop_hints;
 }
 
 HB_EXTERN hb_bool_t
-hb_subset_input_get_drop_layout (hb_subset_input_t *subset_input)
+hb_subset_input_get_drop_hints (hb_subset_input_t *subset_input)
 {
-  return subset_input->drop_layout;
+  return subset_input->drop_hints;
 }
 
 HB_EXTERN void
 hb_subset_input_set_desubroutinize (hb_subset_input_t *subset_input,
-        hb_bool_t desubroutinize)
+                                   hb_bool_t desubroutinize)
 {
   subset_input->desubroutinize = desubroutinize;
 }
@@ -152,7 +187,7 @@ hb_subset_input_get_desubroutinize (hb_subset_input_t *subset_input)
  * hb_subset_input_set_retain_gids:
  * @subset_input: a subset_input.
  * @retain_gids: If true the subsetter will not renumber glyph ids.
- * Since: REPLACEME
+ * Since: 2.4.0
  **/
 HB_EXTERN void
 hb_subset_input_set_retain_gids (hb_subset_input_t *subset_input,
@@ -164,7 +199,7 @@ hb_subset_input_set_retain_gids (hb_subset_input_t *subset_input,
 /**
  * hb_subset_input_get_retain_gids:
  * Returns: value of retain_gids.
- * Since: REPLACEME
+ * Since: 2.4.0
  **/
 HB_EXTERN hb_bool_t
 hb_subset_input_get_retain_gids (hb_subset_input_t *subset_input)
index 04d6e12..f6dd4ac 100644 (file)
@@ -40,16 +40,17 @@ struct hb_subset_input_t
 
   hb_set_t *unicodes;
   hb_set_t *glyphs;
+  hb_set_t *name_ids;
+  hb_set_t *drop_tables;
 
-  bool drop_hints : 1;
-  bool drop_layout : 1;
-  bool desubroutinize : 1;
-  bool retain_gids : 1;
+  bool drop_hints;
+  bool desubroutinize;
+  bool retain_gids;
   /* TODO
    *
    * features
    * lookups
-   * nameIDs
+   * name_ids
    * ...
    */
 };
index 8b72314..f4912f8 100644 (file)
 #include "hb-ot-cmap-table.hh"
 #include "hb-ot-glyf-table.hh"
 #include "hb-ot-cff1-table.hh"
+#include "hb-ot-var-fvar-table.hh"
+#include "hb-ot-stat-table.hh"
 
-static void
-_add_gid_and_children (const OT::glyf::accelerator_t &glyf,
-                      hb_codepoint_t gid,
-                      hb_set_t *gids_to_retain)
-{
-  if (hb_set_has (gids_to_retain, gid))
-    // Already visited this gid, ignore.
-    return;
-
-  hb_set_add (gids_to_retain, gid);
-
-  OT::glyf::CompositeGlyphHeader::Iterator composite;
-  if (glyf.get_composite (gid, &composite))
-  {
-    do
-    {
-      _add_gid_and_children (glyf, (hb_codepoint_t) composite.current->glyphIndex, gids_to_retain);
-    } while (composite.move_to_next());
-  }
-}
-
-static void
+#ifndef HB_NO_SUBSET_CFF
+static inline void
 _add_cff_seac_components (const OT::cff1::accelerator_t &cff,
-           hb_codepoint_t gid,
-           hb_set_t *gids_to_retain)
+                         hb_codepoint_t gid,
+                         hb_set_t *gids_to_retain)
 {
   hb_codepoint_t base_gid, accent_gid;
   if (cff.get_seac_components (gid, &base_gid, &accent_gid))
   {
-    hb_set_add (gids_to_retain, base_gid);
-    hb_set_add (gids_to_retain, accent_gid);
+    gids_to_retain->add (base_gid);
+    gids_to_retain->add (accent_gid);
   }
 }
+#endif
 
-static void
+#ifndef HB_NO_SUBSET_LAYOUT
+static inline void
 _gsub_closure (hb_face_t *face, hb_set_t *gids_to_retain)
 {
   hb_set_t lookup_indices;
@@ -80,8 +64,20 @@ _gsub_closure (hb_face_t *face, hb_set_t *gids_to_retain)
                                           &lookup_indices,
                                           gids_to_retain);
 }
+#endif
 
-static void
+static inline void
+_cmap_closure (hb_face_t           *face,
+              const hb_set_t      *unicodes,
+              hb_set_t            *glyphset)
+{
+  OT::cmap::accelerator_t cmap;
+  cmap.init (face);
+  cmap.table->closure_glyphs (unicodes, glyphset);
+  cmap.fini ();
+}
+
+static inline void
 _remove_invalid_gids (hb_set_t *glyphs,
                      unsigned int num_glyphs)
 {
@@ -93,24 +89,21 @@ _remove_invalid_gids (hb_set_t *glyphs,
   }
 }
 
-static hb_set_t *
-_populate_gids_to_retain (hb_face_t *face,
+static void
+_populate_gids_to_retain (hb_subset_plan_t* plan,
                          const hb_set_t *unicodes,
-                          const hb_set_t *input_glyphs_to_retain,
-                         bool close_over_gsub,
-                         hb_set_t *unicodes_to_retain,
-                         hb_map_t *codepoint_to_glyph)
+                         const hb_set_t *input_glyphs_to_retain,
+                         bool close_over_gsub)
 {
   OT::cmap::accelerator_t cmap;
   OT::glyf::accelerator_t glyf;
   OT::cff1::accelerator_t cff;
-  cmap.init (face);
-  glyf.init (face);
-  cff.init (face);
+  cmap.init (plan->source);
+  glyf.init (plan->source);
+  cff.init (plan->source);
 
-  hb_set_t *initial_gids_to_retain = hb_set_create ();
-  initial_gids_to_retain->add (0); // Not-def
-  hb_set_union (initial_gids_to_retain, input_glyphs_to_retain);
+  plan->_glyphset_gsub->add (0); // Not-def
+  hb_set_union (plan->_glyphset_gsub, input_glyphs_to_retain);
 
   hb_codepoint_t cp = HB_SET_VALUE_INVALID;
   while (unicodes->next (&cp))
@@ -121,68 +114,84 @@ _populate_gids_to_retain (hb_face_t *face,
       DEBUG_MSG(SUBSET, nullptr, "Drop U+%04X; no gid", cp);
       continue;
     }
-    unicodes_to_retain->add (cp);
-    codepoint_to_glyph->set (cp, gid);
-    initial_gids_to_retain->add (gid);
+    plan->unicodes->add (cp);
+    plan->codepoint_to_glyph->set (cp, gid);
+    plan->_glyphset_gsub->add (gid);
   }
 
+  _cmap_closure (plan->source, plan->unicodes, plan->_glyphset_gsub);
+
+#ifndef HB_NO_SUBSET_LAYOUT
   if (close_over_gsub)
     // Add all glyphs needed for GSUB substitutions.
-    _gsub_closure (face, initial_gids_to_retain);
+    _gsub_closure (plan->source, plan->_glyphset_gsub);
+#endif
+  _remove_invalid_gids (plan->_glyphset_gsub, plan->source->get_num_glyphs ());
 
   // Populate a full set of glyphs to retain by adding all referenced
   // composite glyphs.
   hb_codepoint_t gid = HB_SET_VALUE_INVALID;
-  hb_set_t *all_gids_to_retain = hb_set_create ();
-  while (initial_gids_to_retain->next (&gid))
+  while (plan->_glyphset_gsub->next (&gid))
   {
-    _add_gid_and_children (glyf, gid, all_gids_to_retain);
+    glyf.add_gid_and_children (gid, plan->_glyphset);
+#ifndef HB_NO_SUBSET_CFF
     if (cff.is_valid ())
-      _add_cff_seac_components (cff, gid, all_gids_to_retain);
+      _add_cff_seac_components (cff, gid, plan->_glyphset);
+#endif
   }
-  hb_set_destroy (initial_gids_to_retain);
-
-  _remove_invalid_gids (all_gids_to_retain, face->get_num_glyphs ());
 
+  _remove_invalid_gids (plan->_glyphset, plan->source->get_num_glyphs ());
 
   cff.fini ();
   glyf.fini ();
   cmap.fini ();
-
-  return all_gids_to_retain;
 }
 
 static void
-_create_old_gid_to_new_gid_map (const hb_face_t                   *face,
-                                bool                               retain_gids,
-                               hb_set_t                          *all_gids_to_retain,
-                                hb_map_t                          *glyph_map, /* OUT */
-                                hb_map_t                          *reverse_glyph_map, /* OUT */
-                                unsigned int                      *num_glyphs /* OUT */)
+_create_old_gid_to_new_gid_map (const hb_face_t *face,
+                               bool             retain_gids,
+                               const hb_set_t  *all_gids_to_retain,
+                               hb_map_t        *glyph_map, /* OUT */
+                               hb_map_t        *reverse_glyph_map, /* OUT */
+                               unsigned int    *num_glyphs /* OUT */)
 {
-  hb_codepoint_t gid = HB_SET_VALUE_INVALID;
-  unsigned int length = 0;
-  for (unsigned int i = 0; all_gids_to_retain->next (&gid); i++) {
-    if (!retain_gids)
-    {
-      glyph_map->set (gid, i);
-      reverse_glyph_map->set (i, gid);
-    }
-    else
-    {
-      glyph_map->set (gid, gid);
-      reverse_glyph_map->set (gid, gid);
-    }
-    ++length;
-  }
-  if (!retain_gids || length == 0)
+  if (!retain_gids)
   {
-    *num_glyphs = length;
-  }
-  else
-  {
-    *num_glyphs = face->get_num_glyphs ();
+    + hb_enumerate (hb_iter (all_gids_to_retain), (hb_codepoint_t) 0)
+    | hb_sink (reverse_glyph_map)
+    ;
+    *num_glyphs = reverse_glyph_map->get_population ();
+  } else {
+    + hb_iter (all_gids_to_retain)
+    | hb_map ([] (hb_codepoint_t _) {
+               return hb_pair_t<hb_codepoint_t, hb_codepoint_t> (_, _);
+             })
+    | hb_sink (reverse_glyph_map)
+    ;
+
+    unsigned max_glyph =
+    + hb_iter (all_gids_to_retain)
+    | hb_reduce (hb_max, 0u)
+    ;
+    *num_glyphs = max_glyph + 1;
   }
+
+  + reverse_glyph_map->iter ()
+  | hb_map (&hb_pair_t<hb_codepoint_t, hb_codepoint_t>::reverse)
+  | hb_sink (glyph_map)
+  ;
+}
+
+static void
+_nameid_closure (hb_face_t *face,
+                hb_set_t  *nameids)
+{
+#ifndef HB_NO_STAT
+  face->table.STAT->collect_name_ids (nameids);
+#endif
+#ifndef HB_NO_VAR
+  face->table.fvar->collect_name_ids (nameids);
+#endif
 }
 
 /**
@@ -196,33 +205,38 @@ _create_old_gid_to_new_gid_map (const hb_face_t                   *face,
  * Since: 1.7.5
  **/
 hb_subset_plan_t *
-hb_subset_plan_create (hb_face_t           *face,
-                      hb_subset_input_t   *input)
+hb_subset_plan_create (hb_face_t         *face,
+                      hb_subset_input_t *input)
 {
   hb_subset_plan_t *plan = hb_object_create<hb_subset_plan_t> ();
 
   plan->drop_hints = input->drop_hints;
-  plan->drop_layout = input->drop_layout;
   plan->desubroutinize = input->desubroutinize;
-  plan->unicodes = hb_set_create();
+  plan->retain_gids = input->retain_gids;
+  plan->unicodes = hb_set_create ();
+  plan->name_ids = hb_set_reference (input->name_ids);
+  _nameid_closure (face, plan->name_ids);
+  plan->drop_tables = hb_set_reference (input->drop_tables);
   plan->source = hb_face_reference (face);
   plan->dest = hb_face_builder_create ();
-  plan->codepoint_to_glyph = hb_map_create();
-  plan->glyph_map = hb_map_create();
-  plan->reverse_glyph_map = hb_map_create();
-  plan->_glyphset = _populate_gids_to_retain (face,
-                                              input->unicodes,
-                                              input->glyphs,
-                                              !plan->drop_layout,
-                                              plan->unicodes,
-                                              plan->codepoint_to_glyph);
+
+  plan->_glyphset = hb_set_create ();
+  plan->_glyphset_gsub = hb_set_create ();
+  plan->codepoint_to_glyph = hb_map_create ();
+  plan->glyph_map = hb_map_create ();
+  plan->reverse_glyph_map = hb_map_create ();
+
+  _populate_gids_to_retain (plan,
+                           input->unicodes,
+                           input->glyphs,
+                           !input->drop_tables->has (HB_OT_TAG_GSUB));
 
   _create_old_gid_to_new_gid_map (face,
-                                  input->retain_gids,
+                                 input->retain_gids,
                                  plan->_glyphset,
                                  plan->glyph_map,
-                                  plan->reverse_glyph_map,
-                                  &plan->_num_output_glyphs);
+                                 plan->reverse_glyph_map,
+                                 &plan->_num_output_glyphs);
 
   return plan;
 }
@@ -238,12 +252,15 @@ hb_subset_plan_destroy (hb_subset_plan_t *plan)
   if (!hb_object_destroy (plan)) return;
 
   hb_set_destroy (plan->unicodes);
+  hb_set_destroy (plan->name_ids);
+  hb_set_destroy (plan->drop_tables);
   hb_face_destroy (plan->source);
   hb_face_destroy (plan->dest);
   hb_map_destroy (plan->codepoint_to_glyph);
   hb_map_destroy (plan->glyph_map);
   hb_map_destroy (plan->reverse_glyph_map);
   hb_set_destroy (plan->_glyphset);
+  hb_set_destroy (plan->_glyphset_gsub);
 
   free (plan);
 }
index 56726d4..af2337e 100644 (file)
@@ -40,12 +40,18 @@ struct hb_subset_plan_t
   hb_object_header_t header;
 
   bool drop_hints : 1;
-  bool drop_layout : 1;
   bool desubroutinize : 1;
+  bool retain_gids : 1;
 
   // For each cp that we'd like to retain maps to the corresponding gid.
   hb_set_t *unicodes;
 
+  // name_ids we would like to retain
+  hb_set_t *name_ids;
+
+  // Tables which should be dropped.
+  hb_set_t *drop_tables;
+
   // The glyph subset
   hb_map_t *codepoint_to_glyph;
 
@@ -59,11 +65,14 @@ struct hb_subset_plan_t
 
   unsigned int _num_output_glyphs;
   hb_set_t *_glyphset;
+  hb_set_t *_glyphset_gsub;
 
  public:
 
   /*
    * The set of input glyph ids which will be retained in the subset.
+   * Does NOT include ids kept due to retain_gids. You probably want to use
+   * glyph_map/reverse_glyph_map.
    */
   inline const hb_set_t *
   glyphset () const
@@ -72,6 +81,15 @@ struct hb_subset_plan_t
   }
 
   /*
+   * The set of input glyph ids which will be retained in the subset.
+   */
+  inline const hb_set_t *
+  glyphset_gsub () const
+  {
+    return _glyphset_gsub;
+  }
+
+  /*
    * The total number of output glyphs in the final subset.
    */
   inline unsigned int
@@ -90,7 +108,7 @@ struct hb_subset_plan_t
   }
 
   inline bool new_gid_for_codepoint (hb_codepoint_t codepoint,
-                                     hb_codepoint_t *new_gid) const
+                                    hb_codepoint_t *new_gid) const
   {
     hb_codepoint_t old_gid = codepoint_to_glyph->get (codepoint);
     if (old_gid == HB_MAP_VALUE_INVALID)
@@ -100,7 +118,7 @@ struct hb_subset_plan_t
   }
 
   inline bool new_gid_for_old_gid (hb_codepoint_t old_gid,
-                                   hb_codepoint_t *new_gid) const
+                                  hb_codepoint_t *new_gid) const
   {
     hb_codepoint_t gid = glyph_map->get (old_gid);
     if (gid == HB_MAP_VALUE_INVALID)
@@ -111,7 +129,7 @@ struct hb_subset_plan_t
   }
 
   inline bool old_gid_for_new_gid (hb_codepoint_t  new_gid,
-                                   hb_codepoint_t *old_gid) const
+                                  hb_codepoint_t *old_gid) const
   {
     hb_codepoint_t gid = reverse_glyph_map->get (new_gid);
     if (gid == HB_MAP_VALUE_INVALID)
@@ -139,7 +157,7 @@ typedef struct hb_subset_plan_t hb_subset_plan_t;
 
 HB_INTERNAL hb_subset_plan_t *
 hb_subset_plan_create (hb_face_t           *face,
-                       hb_subset_input_t   *input);
+                      hb_subset_input_t   *input);
 
 HB_INTERNAL void
 hb_subset_plan_destroy (hb_subset_plan_t *plan);
index 135265f..ec2f889 100644 (file)
@@ -28,7 +28,6 @@
 #include "hb-open-type.hh"
 
 #include "hb-subset.hh"
-#include "hb-subset-glyf.hh"
 
 #include "hb-open-file.hh"
 #include "hb-ot-cmap-table.hh"
 #include "hb-ot-cff1-table.hh"
 #include "hb-ot-cff2-table.hh"
 #include "hb-ot-vorg-table.hh"
+#include "hb-ot-name-table.hh"
 #include "hb-ot-layout-gsub-table.hh"
 #include "hb-ot-layout-gpos-table.hh"
 
 
-static unsigned int
+HB_UNUSED static inline unsigned int
+_plan_estimate_subset_table_size (hb_subset_plan_t *plan,
+                                 unsigned int table_len);
+static inline unsigned int
 _plan_estimate_subset_table_size (hb_subset_plan_t *plan,
                                  unsigned int table_len)
 {
@@ -64,47 +67,58 @@ template<typename TableType>
 static bool
 _subset2 (hb_subset_plan_t *plan)
 {
+  bool result = false;
   hb_blob_t *source_blob = hb_sanitize_context_t ().reference_table<TableType> (plan->source);
   const TableType *table = source_blob->as<TableType> ();
 
   hb_tag_t tag = TableType::tableTag;
-  hb_bool_t result = false;
   if (source_blob->data)
   {
     hb_vector_t<char> buf;
+    /* TODO Not all tables are glyph-related.  'name' table size for example should not be
+     * affected by number of glyphs.  Accommodate that. */
     unsigned int buf_size = _plan_estimate_subset_table_size (plan, source_blob->length);
     DEBUG_MSG(SUBSET, nullptr, "OT::%c%c%c%c initial estimated table size: %u bytes.", HB_UNTAG (tag), buf_size);
     if (unlikely (!buf.alloc (buf_size)))
     {
       DEBUG_MSG(SUBSET, nullptr, "OT::%c%c%c%c failed to allocate %u bytes.", HB_UNTAG (tag), buf_size);
+      hb_blob_destroy (source_blob);
       return false;
     }
   retry:
     hb_serialize_context_t serializer ((void *) buf, buf_size);
+    serializer.start_serialize<TableType> ();
     hb_subset_context_t c (plan, &serializer);
-    result = table->subset (&c);
-    if (serializer.in_error ())
+    bool needed = table->subset (&c);
+    if (serializer.ran_out_of_room)
     {
       buf_size += (buf_size >> 1) + 32;
       DEBUG_MSG(SUBSET, nullptr, "OT::%c%c%c%c ran out of room; reallocating to %u bytes.", HB_UNTAG (tag), buf_size);
       if (unlikely (!buf.alloc (buf_size)))
       {
        DEBUG_MSG(SUBSET, nullptr, "OT::%c%c%c%c failed to reallocate %u bytes.", HB_UNTAG (tag), buf_size);
+       hb_blob_destroy (source_blob);
        return false;
       }
       goto retry;
     }
+    serializer.end_serialize ();
+
+    result = !serializer.in_error ();
+
     if (result)
     {
-      hb_blob_t *dest_blob = serializer.copy_blob ();
-      DEBUG_MSG(SUBSET, nullptr, "OT::%c%c%c%c final subset table size: %u bytes.", HB_UNTAG (tag), dest_blob->length);
-      result = c.plan->add_table (tag, dest_blob);
-      hb_blob_destroy (dest_blob);
-    }
-    else
-    {
-      DEBUG_MSG(SUBSET, nullptr, "OT::%c%c%c%c::subset table subsetted to empty.", HB_UNTAG (tag));
-      result = true;
+      if (needed)
+      {
+       hb_blob_t *dest_blob = serializer.copy_blob ();
+       DEBUG_MSG(SUBSET, nullptr, "OT::%c%c%c%c final subset table size: %u bytes.", HB_UNTAG (tag), dest_blob->length);
+       result = c.plan->add_table (tag, dest_blob);
+       hb_blob_destroy (dest_blob);
+      }
+      else
+      {
+       DEBUG_MSG(SUBSET, nullptr, "OT::%c%c%c%c::subset table subsetted to empty.", HB_UNTAG (tag));
+      }
     }
   }
   else
@@ -143,10 +157,13 @@ _subset_table (hb_subset_plan_t *plan,
   bool result = true;
   switch (tag) {
     case HB_OT_TAG_glyf:
-      result = _subset<const OT::glyf> (plan);
+      result = _subset2<const OT::glyf> (plan);
       break;
     case HB_OT_TAG_hdmx:
-      result = _subset<const OT::hdmx> (plan);
+      result = _subset2<const OT::hdmx> (plan);
+      break;
+    case HB_OT_TAG_name:
+      result = _subset2<const OT::name> (plan);
       break;
     case HB_OT_TAG_head:
       // TODO that won't work well if there is no glyf
@@ -157,29 +174,31 @@ _subset_table (hb_subset_plan_t *plan,
       DEBUG_MSG(SUBSET, nullptr, "skip hhea handled by hmtx");
       return true;
     case HB_OT_TAG_hmtx:
-      result = _subset<const OT::hmtx> (plan);
+      result = _subset2<const OT::hmtx> (plan);
       break;
     case HB_OT_TAG_vhea:
       DEBUG_MSG(SUBSET, nullptr, "skip vhea handled by vmtx");
       return true;
     case HB_OT_TAG_vmtx:
-      result = _subset<const OT::vmtx> (plan);
+      result = _subset2<const OT::vmtx> (plan);
       break;
     case HB_OT_TAG_maxp:
-      result = _subset<const OT::maxp> (plan);
+      result = _subset2<const OT::maxp> (plan);
       break;
     case HB_OT_TAG_loca:
       DEBUG_MSG(SUBSET, nullptr, "skip loca handled by glyf");
       return true;
     case HB_OT_TAG_cmap:
-      result = _subset<const OT::cmap> (plan);
+      result = _subset2<const OT::cmap> (plan);
       break;
     case HB_OT_TAG_OS2:
-      result = _subset<const OT::OS2> (plan);
+      result = _subset2<const OT::OS2> (plan);
       break;
     case HB_OT_TAG_post:
-      result = _subset<const OT::post> (plan);
+      result = _subset2<const OT::post> (plan);
       break;
+
+#ifndef HB_NO_SUBSET_CFF
     case HB_OT_TAG_cff1:
       result = _subset<const OT::cff1> (plan);
       break;
@@ -187,8 +206,11 @@ _subset_table (hb_subset_plan_t *plan,
       result = _subset<const OT::cff2> (plan);
       break;
     case HB_OT_TAG_VORG:
-      result = _subset<const OT::VORG> (plan);
+      result = _subset2<const OT::VORG> (plan);
       break;
+#endif
+
+#ifndef HB_NO_SUBSET_LAYOUT
     case HB_OT_TAG_GDEF:
       result = _subset2<const OT::GDEF> (plan);
       break;
@@ -198,6 +220,7 @@ _subset_table (hb_subset_plan_t *plan,
     case HB_OT_TAG_GPOS:
       result = _subset2<const OT::GPOS> (plan);
       break;
+#endif
 
     default:
       hb_blob_t *source_table = hb_face_reference_table (plan->source, tag);
@@ -215,6 +238,9 @@ _subset_table (hb_subset_plan_t *plan,
 static bool
 _should_drop_table (hb_subset_plan_t *plan, hb_tag_t tag)
 {
+  if (plan->drop_tables->has (tag))
+    return true;
+
   switch (tag) {
     case HB_TAG ('c', 'v', 'a', 'r'): /* hint table, fallthrough */
     case HB_TAG ('c', 'v', 't', ' '): /* hint table, fallthrough */
@@ -223,31 +249,19 @@ _should_drop_table (hb_subset_plan_t *plan, hb_tag_t tag)
     case HB_TAG ('h', 'd', 'm', 'x'): /* hint table, fallthrough */
     case HB_TAG ('V', 'D', 'M', 'X'): /* hint table, fallthrough */
       return plan->drop_hints;
+
+#ifdef HB_NO_SUBSET_LAYOUT
     // Drop Layout Tables if requested.
     case HB_OT_TAG_GDEF:
     case HB_OT_TAG_GPOS:
     case HB_OT_TAG_GSUB:
-      return plan->drop_layout;
-    // Drop these tables below by default, list pulled
-    // from fontTools:
-    case HB_TAG ('B', 'A', 'S', 'E'):
-    case HB_TAG ('J', 'S', 'T', 'F'):
-    case HB_TAG ('D', 'S', 'I', 'G'):
-    case HB_TAG ('E', 'B', 'D', 'T'):
-    case HB_TAG ('E', 'B', 'L', 'C'):
-    case HB_TAG ('E', 'B', 'S', 'C'):
-    case HB_TAG ('S', 'V', 'G', ' '):
-    case HB_TAG ('P', 'C', 'L', 'T'):
-    case HB_TAG ('L', 'T', 'S', 'H'):
-    // Graphite tables:
-    case HB_TAG ('F', 'e', 'a', 't'):
-    case HB_TAG ('G', 'l', 'a', 't'):
-    case HB_TAG ('G', 'l', 'o', 'c'):
-    case HB_TAG ('S', 'i', 'l', 'f'):
-    case HB_TAG ('S', 'i', 'l', 'l'):
-    // Colour
-    case HB_TAG ('s', 'b', 'i', 'x'):
+    case HB_TAG ('m', 'o', 'r', 'x'):
+    case HB_TAG ('m', 'o', 'r', 't'):
+    case HB_TAG ('k', 'e', 'r', 'x'):
+    case HB_TAG ('k', 'e', 'r', 'n'):
       return true;
+#endif
+
     default:
       return false;
   }
@@ -271,17 +285,19 @@ hb_subset (hb_face_t *source,
   hb_tag_t table_tags[32];
   unsigned int offset = 0, count;
   bool success = true;
+  hb_set_t tags_set;
   do {
     count = ARRAY_LENGTH (table_tags);
     hb_face_get_table_tags (source, offset, &count, table_tags);
     for (unsigned int i = 0; i < count; i++)
     {
       hb_tag_t tag = table_tags[i];
-      if (_should_drop_table (plan, tag))
+      if (_should_drop_table (plan, tag) && !tags_set.has (tag))
       {
        DEBUG_MSG(SUBSET, nullptr, "drop %c%c%c%c", HB_UNTAG (tag));
        continue;
       }
+      tags_set.add (tag);
       success = success && _subset_table (plan, tag);
     }
     offset += count;
index 657709e..960afef 100644 (file)
@@ -54,6 +54,12 @@ hb_subset_input_unicode_set (hb_subset_input_t *subset_input);
 HB_EXTERN hb_set_t *
 hb_subset_input_glyph_set (hb_subset_input_t *subset_input);
 
+HB_EXTERN hb_set_t *
+hb_subset_input_nameid_set (hb_subset_input_t *subset_input);
+
+HB_EXTERN hb_set_t *
+hb_subset_input_drop_tables_set (hb_subset_input_t *subset_input);
+
 HB_EXTERN void
 hb_subset_input_set_drop_hints (hb_subset_input_t *subset_input,
                                hb_bool_t drop_hints);
@@ -61,14 +67,8 @@ HB_EXTERN hb_bool_t
 hb_subset_input_get_drop_hints (hb_subset_input_t *subset_input);
 
 HB_EXTERN void
-hb_subset_input_set_drop_layout (hb_subset_input_t *subset_input,
-                                hb_bool_t drop_layout);
-HB_EXTERN hb_bool_t
-hb_subset_input_get_drop_layout (hb_subset_input_t *subset_input);
-
-HB_EXTERN void
 hb_subset_input_set_desubroutinize (hb_subset_input_t *subset_input,
-        hb_bool_t desubroutinize);
+                                   hb_bool_t desubroutinize);
 HB_EXTERN hb_bool_t
 hb_subset_input_get_desubroutinize (hb_subset_input_t *subset_input);
 
index 45cb763..b8dd07a 100644 (file)
@@ -40,9 +40,19 @@ struct hb_subset_context_t :
        hb_dispatch_context_t<hb_subset_context_t, bool, HB_DEBUG_SUBSET>
 {
   const char *get_name () { return "SUBSET"; }
-  template <typename T>
-  bool dispatch (const T &obj) { return obj.subset (this); }
-  static bool default_return_value () { return true; }
+  static return_t default_return_value () { return true; }
+
+  private:
+  template <typename T, typename ...Ts> auto
+  _dispatch (const T &obj, hb_priority<1>, Ts&&... ds) HB_AUTO_RETURN
+  ( obj.subset (this, hb_forward<Ts> (ds)...) )
+  template <typename T, typename ...Ts> auto
+  _dispatch (const T &obj, hb_priority<0>, Ts&&... ds) HB_AUTO_RETURN
+  ( obj.dispatch (this, hb_forward<Ts> (ds)...) )
+  public:
+  template <typename T, typename ...Ts> auto
+  dispatch (const T &obj, Ts&&... ds) HB_AUTO_RETURN
+  ( _dispatch (obj, hb_prioritize, hb_forward<Ts> (ds)...) )
 
   hb_subset_plan_t *plan;
   hb_serialize_context_t *serializer;
diff --git a/src/hb-ucd-table.hh b/src/hb-ucd-table.hh
new file mode 100644 (file)
index 0000000..8b7d648
--- /dev/null
@@ -0,0 +1,6696 @@
+/* == Start of generated table == */
+/*
+ * The following table is generated by running:
+ *
+ *   ./gen-ucd-table.py ucd.nounihan.grouped.xml
+ *
+ * on file with this description: Unicode 12.1.0
+ */
+
+#ifndef HB_UCD_TABLE_HH
+#define HB_UCD_TABLE_HH
+
+#include "hb.hh"
+
+static const hb_script_t
+_hb_ucd_sc_map[153] =
+{
+                   HB_SCRIPT_COMMON,              HB_SCRIPT_INHERITED,
+                  HB_SCRIPT_UNKNOWN,                 HB_SCRIPT_ARABIC,
+                 HB_SCRIPT_ARMENIAN,                HB_SCRIPT_BENGALI,
+                 HB_SCRIPT_CYRILLIC,             HB_SCRIPT_DEVANAGARI,
+                 HB_SCRIPT_GEORGIAN,                  HB_SCRIPT_GREEK,
+                 HB_SCRIPT_GUJARATI,               HB_SCRIPT_GURMUKHI,
+                   HB_SCRIPT_HANGUL,                    HB_SCRIPT_HAN,
+                   HB_SCRIPT_HEBREW,               HB_SCRIPT_HIRAGANA,
+                  HB_SCRIPT_KANNADA,               HB_SCRIPT_KATAKANA,
+                      HB_SCRIPT_LAO,                  HB_SCRIPT_LATIN,
+                HB_SCRIPT_MALAYALAM,                  HB_SCRIPT_ORIYA,
+                    HB_SCRIPT_TAMIL,                 HB_SCRIPT_TELUGU,
+                     HB_SCRIPT_THAI,                HB_SCRIPT_TIBETAN,
+                 HB_SCRIPT_BOPOMOFO,                HB_SCRIPT_BRAILLE,
+       HB_SCRIPT_CANADIAN_SYLLABICS,               HB_SCRIPT_CHEROKEE,
+                 HB_SCRIPT_ETHIOPIC,                  HB_SCRIPT_KHMER,
+                HB_SCRIPT_MONGOLIAN,                HB_SCRIPT_MYANMAR,
+                    HB_SCRIPT_OGHAM,                  HB_SCRIPT_RUNIC,
+                  HB_SCRIPT_SINHALA,                 HB_SCRIPT_SYRIAC,
+                   HB_SCRIPT_THAANA,                     HB_SCRIPT_YI,
+                  HB_SCRIPT_DESERET,                 HB_SCRIPT_GOTHIC,
+               HB_SCRIPT_OLD_ITALIC,                  HB_SCRIPT_BUHID,
+                  HB_SCRIPT_HANUNOO,                HB_SCRIPT_TAGALOG,
+                 HB_SCRIPT_TAGBANWA,                HB_SCRIPT_CYPRIOT,
+                    HB_SCRIPT_LIMBU,               HB_SCRIPT_LINEAR_B,
+                  HB_SCRIPT_OSMANYA,                HB_SCRIPT_SHAVIAN,
+                   HB_SCRIPT_TAI_LE,               HB_SCRIPT_UGARITIC,
+                 HB_SCRIPT_BUGINESE,                 HB_SCRIPT_COPTIC,
+               HB_SCRIPT_GLAGOLITIC,             HB_SCRIPT_KHAROSHTHI,
+              HB_SCRIPT_NEW_TAI_LUE,            HB_SCRIPT_OLD_PERSIAN,
+             HB_SCRIPT_SYLOTI_NAGRI,               HB_SCRIPT_TIFINAGH,
+                 HB_SCRIPT_BALINESE,              HB_SCRIPT_CUNEIFORM,
+                      HB_SCRIPT_NKO,               HB_SCRIPT_PHAGS_PA,
+               HB_SCRIPT_PHOENICIAN,                 HB_SCRIPT_CARIAN,
+                     HB_SCRIPT_CHAM,               HB_SCRIPT_KAYAH_LI,
+                   HB_SCRIPT_LEPCHA,                 HB_SCRIPT_LYCIAN,
+                   HB_SCRIPT_LYDIAN,               HB_SCRIPT_OL_CHIKI,
+                   HB_SCRIPT_REJANG,             HB_SCRIPT_SAURASHTRA,
+                HB_SCRIPT_SUNDANESE,                    HB_SCRIPT_VAI,
+                  HB_SCRIPT_AVESTAN,                  HB_SCRIPT_BAMUM,
+     HB_SCRIPT_EGYPTIAN_HIEROGLYPHS,       HB_SCRIPT_IMPERIAL_ARAMAIC,
+    HB_SCRIPT_INSCRIPTIONAL_PAHLAVI, HB_SCRIPT_INSCRIPTIONAL_PARTHIAN,
+                 HB_SCRIPT_JAVANESE,                 HB_SCRIPT_KAITHI,
+                     HB_SCRIPT_LISU,           HB_SCRIPT_MEETEI_MAYEK,
+        HB_SCRIPT_OLD_SOUTH_ARABIAN,             HB_SCRIPT_OLD_TURKIC,
+                HB_SCRIPT_SAMARITAN,               HB_SCRIPT_TAI_THAM,
+                 HB_SCRIPT_TAI_VIET,                  HB_SCRIPT_BATAK,
+                   HB_SCRIPT_BRAHMI,                HB_SCRIPT_MANDAIC,
+                   HB_SCRIPT_CHAKMA,       HB_SCRIPT_MEROITIC_CURSIVE,
+     HB_SCRIPT_MEROITIC_HIEROGLYPHS,                   HB_SCRIPT_MIAO,
+                  HB_SCRIPT_SHARADA,           HB_SCRIPT_SORA_SOMPENG,
+                    HB_SCRIPT_TAKRI,              HB_SCRIPT_BASSA_VAH,
+       HB_SCRIPT_CAUCASIAN_ALBANIAN,               HB_SCRIPT_DUPLOYAN,
+                  HB_SCRIPT_ELBASAN,                HB_SCRIPT_GRANTHA,
+                   HB_SCRIPT_KHOJKI,              HB_SCRIPT_KHUDAWADI,
+                 HB_SCRIPT_LINEAR_A,               HB_SCRIPT_MAHAJANI,
+               HB_SCRIPT_MANICHAEAN,          HB_SCRIPT_MENDE_KIKAKUI,
+                     HB_SCRIPT_MODI,                    HB_SCRIPT_MRO,
+                HB_SCRIPT_NABATAEAN,      HB_SCRIPT_OLD_NORTH_ARABIAN,
+               HB_SCRIPT_OLD_PERMIC,           HB_SCRIPT_PAHAWH_HMONG,
+                HB_SCRIPT_PALMYRENE,            HB_SCRIPT_PAU_CIN_HAU,
+          HB_SCRIPT_PSALTER_PAHLAVI,                HB_SCRIPT_SIDDHAM,
+                  HB_SCRIPT_TIRHUTA,            HB_SCRIPT_WARANG_CITI,
+                     HB_SCRIPT_AHOM,  HB_SCRIPT_ANATOLIAN_HIEROGLYPHS,
+                   HB_SCRIPT_HATRAN,                HB_SCRIPT_MULTANI,
+            HB_SCRIPT_OLD_HUNGARIAN,            HB_SCRIPT_SIGNWRITING,
+                    HB_SCRIPT_ADLAM,              HB_SCRIPT_BHAIKSUKI,
+                  HB_SCRIPT_MARCHEN,                  HB_SCRIPT_OSAGE,
+                   HB_SCRIPT_TANGUT,                   HB_SCRIPT_NEWA,
+            HB_SCRIPT_MASARAM_GONDI,                  HB_SCRIPT_NUSHU,
+                  HB_SCRIPT_SOYOMBO,       HB_SCRIPT_ZANABAZAR_SQUARE,
+                    HB_SCRIPT_DOGRA,          HB_SCRIPT_GUNJALA_GONDI,
+          HB_SCRIPT_HANIFI_ROHINGYA,                HB_SCRIPT_MAKASAR,
+              HB_SCRIPT_MEDEFAIDRIN,            HB_SCRIPT_OLD_SOGDIAN,
+                  HB_SCRIPT_SOGDIAN,                HB_SCRIPT_ELYMAIC,
+              HB_SCRIPT_NANDINAGARI, HB_SCRIPT_NYIAKENG_PUACHUE_HMONG,
+                   HB_SCRIPT_WANCHO,
+};
+static const uint16_t
+_hb_ucd_dm1_p0_map[825] =
+{
+   0x003Bu, 0x004Bu, 0x0060u, 0x00B4u, 0x00B7u, 0x00C5u, 0x02B9u, 0x0300u,
+   0x0301u, 0x0313u, 0x0385u, 0x0386u, 0x0388u, 0x0389u, 0x038Au, 0x038Cu,
+   0x038Eu, 0x038Fu, 0x0390u, 0x03A9u, 0x03ACu, 0x03ADu, 0x03AEu, 0x03AFu,
+   0x03B0u, 0x03B9u, 0x03CCu, 0x03CDu, 0x03CEu, 0x2002u, 0x2003u, 0x3008u,
+   0x3009u, 0x349Eu, 0x34B9u, 0x34BBu, 0x34DFu, 0x3515u, 0x36EEu, 0x36FCu,
+   0x3781u, 0x382Fu, 0x3862u, 0x387Cu, 0x38C7u, 0x38E3u, 0x391Cu, 0x393Au,
+   0x3A2Eu, 0x3A6Cu, 0x3AE4u, 0x3B08u, 0x3B19u, 0x3B49u, 0x3B9Du, 0x3C18u,
+   0x3C4Eu, 0x3D33u, 0x3D96u, 0x3EACu, 0x3EB8u, 0x3F1Bu, 0x3FFCu, 0x4008u,
+   0x4018u, 0x4039u, 0x4046u, 0x4096u, 0x40E3u, 0x412Fu, 0x4202u, 0x4227u,
+   0x42A0u, 0x4301u, 0x4334u, 0x4359u, 0x43D5u, 0x43D9u, 0x440Bu, 0x446Bu,
+   0x452Bu, 0x455Du, 0x4561u, 0x456Bu, 0x45D7u, 0x45F9u, 0x4635u, 0x46BEu,
+   0x46C7u, 0x4995u, 0x49E6u, 0x4A6Eu, 0x4A76u, 0x4AB2u, 0x4B33u, 0x4BCEu,
+   0x4CCEu, 0x4CEDu, 0x4CF8u, 0x4D56u, 0x4E0Du, 0x4E26u, 0x4E32u, 0x4E38u,
+   0x4E39u, 0x4E3Du, 0x4E41u, 0x4E82u, 0x4E86u, 0x4EAEu, 0x4EC0u, 0x4ECCu,
+   0x4EE4u, 0x4F60u, 0x4F80u, 0x4F86u, 0x4F8Bu, 0x4FAEu, 0x4FBBu, 0x4FBFu,
+   0x5002u, 0x502Bu, 0x507Au, 0x5099u, 0x50CFu, 0x50DAu, 0x50E7u, 0x5140u,
+   0x5145u, 0x514Du, 0x5154u, 0x5164u, 0x5167u, 0x5168u, 0x5169u, 0x516Du,
+   0x5177u, 0x5180u, 0x518Du, 0x5192u, 0x5195u, 0x5197u, 0x51A4u, 0x51ACu,
+   0x51B5u, 0x51B7u, 0x51C9u, 0x51CCu, 0x51DCu, 0x51DEu, 0x51F5u, 0x5203u,
+   0x5207u, 0x5217u, 0x5229u, 0x523Au, 0x523Bu, 0x5246u, 0x5272u, 0x5277u,
+   0x5289u, 0x529Bu, 0x52A3u, 0x52B3u, 0x52C7u, 0x52C9u, 0x52D2u, 0x52DEu,
+   0x52E4u, 0x52F5u, 0x52FAu, 0x5305u, 0x5306u, 0x5317u, 0x533Fu, 0x5349u,
+   0x5351u, 0x535Au, 0x5373u, 0x5375u, 0x537Du, 0x537Fu, 0x53C3u, 0x53CAu,
+   0x53DFu, 0x53E5u, 0x53EBu, 0x53F1u, 0x5406u, 0x540Fu, 0x541Du, 0x5438u,
+   0x5442u, 0x5448u, 0x5468u, 0x549Eu, 0x54A2u, 0x54BDu, 0x54F6u, 0x5510u,
+   0x5553u, 0x5555u, 0x5563u, 0x5584u, 0x5587u, 0x5599u, 0x559Du, 0x55ABu,
+   0x55B3u, 0x55C0u, 0x55C2u, 0x55E2u, 0x5606u, 0x5651u, 0x5668u, 0x5674u,
+   0x56F9u, 0x5716u, 0x5717u, 0x578Bu, 0x57CEu, 0x57F4u, 0x580Du, 0x5831u,
+   0x5832u, 0x5840u, 0x585Au, 0x585Eu, 0x58A8u, 0x58ACu, 0x58B3u, 0x58D8u,
+   0x58DFu, 0x58EEu, 0x58F2u, 0x58F7u, 0x5906u, 0x591Au, 0x5922u, 0x5944u,
+   0x5948u, 0x5951u, 0x5954u, 0x5962u, 0x5973u, 0x59D8u, 0x59ECu, 0x5A1Bu,
+   0x5A27u, 0x5A62u, 0x5A66u, 0x5AB5u, 0x5B08u, 0x5B28u, 0x5B3Eu, 0x5B85u,
+   0x5BC3u, 0x5BD8u, 0x5BE7u, 0x5BEEu, 0x5BF3u, 0x5BFFu, 0x5C06u, 0x5C22u,
+   0x5C3Fu, 0x5C60u, 0x5C62u, 0x5C64u, 0x5C65u, 0x5C6Eu, 0x5C8Du, 0x5CC0u,
+   0x5D19u, 0x5D43u, 0x5D50u, 0x5D6Bu, 0x5D6Eu, 0x5D7Cu, 0x5DB2u, 0x5DBAu,
+   0x5DE1u, 0x5DE2u, 0x5DFDu, 0x5E28u, 0x5E3Du, 0x5E69u, 0x5E74u, 0x5EA6u,
+   0x5EB0u, 0x5EB3u, 0x5EB6u, 0x5EC9u, 0x5ECAu, 0x5ED2u, 0x5ED3u, 0x5ED9u,
+   0x5EECu, 0x5EFEu, 0x5F04u, 0x5F22u, 0x5F53u, 0x5F62u, 0x5F69u, 0x5F6Bu,
+   0x5F8Bu, 0x5F9Au, 0x5FA9u, 0x5FADu, 0x5FCDu, 0x5FD7u, 0x5FF5u, 0x5FF9u,
+   0x6012u, 0x601Cu, 0x6075u, 0x6081u, 0x6094u, 0x60C7u, 0x60D8u, 0x60E1u,
+   0x6108u, 0x6144u, 0x6148u, 0x614Cu, 0x614Eu, 0x6160u, 0x6168u, 0x617Au,
+   0x618Eu, 0x6190u, 0x61A4u, 0x61AFu, 0x61B2u, 0x61DEu, 0x61F2u, 0x61F6u,
+   0x6200u, 0x6210u, 0x621Bu, 0x622Eu, 0x6234u, 0x625Du, 0x62B1u, 0x62C9u,
+   0x62CFu, 0x62D3u, 0x62D4u, 0x62FCu, 0x62FEu, 0x633Du, 0x6350u, 0x6368u,
+   0x637Bu, 0x6383u, 0x63A0u, 0x63A9u, 0x63C4u, 0x63C5u, 0x63E4u, 0x641Cu,
+   0x6422u, 0x6452u, 0x6469u, 0x6477u, 0x647Eu, 0x649Au, 0x649Du, 0x64C4u,
+   0x654Fu, 0x6556u, 0x656Cu, 0x6578u, 0x6599u, 0x65C5u, 0x65E2u, 0x65E3u,
+   0x6613u, 0x6649u, 0x6674u, 0x6688u, 0x6691u, 0x669Cu, 0x66B4u, 0x66C6u,
+   0x66F4u, 0x66F8u, 0x6700u, 0x6717u, 0x671Bu, 0x6721u, 0x674Eu, 0x6753u,
+   0x6756u, 0x675Eu, 0x677Bu, 0x6785u, 0x6797u, 0x67F3u, 0x67FAu, 0x6817u,
+   0x681Fu, 0x6852u, 0x6881u, 0x6885u, 0x688Eu, 0x68A8u, 0x6914u, 0x6942u,
+   0x69A3u, 0x69EAu, 0x6A02u, 0x6A13u, 0x6AA8u, 0x6AD3u, 0x6ADBu, 0x6B04u,
+   0x6B21u, 0x6B54u, 0x6B72u, 0x6B77u, 0x6B79u, 0x6B9Fu, 0x6BAEu, 0x6BBAu,
+   0x6BBBu, 0x6C4Eu, 0x6C67u, 0x6C88u, 0x6CBFu, 0x6CCCu, 0x6CCDu, 0x6CE5u,
+   0x6D16u, 0x6D1Bu, 0x6D1Eu, 0x6D34u, 0x6D3Eu, 0x6D41u, 0x6D69u, 0x6D6Au,
+   0x6D77u, 0x6D78u, 0x6D85u, 0x6DCBu, 0x6DDAu, 0x6DEAu, 0x6DF9u, 0x6E1Au,
+   0x6E2Fu, 0x6E6Eu, 0x6E9Cu, 0x6EBAu, 0x6EC7u, 0x6ECBu, 0x6ED1u, 0x6EDBu,
+   0x6F0Fu, 0x6F22u, 0x6F23u, 0x6F6Eu, 0x6FC6u, 0x6FEBu, 0x6FFEu, 0x701Bu,
+   0x701Eu, 0x7039u, 0x704Au, 0x7070u, 0x7077u, 0x707Du, 0x7099u, 0x70ADu,
+   0x70C8u, 0x70D9u, 0x7145u, 0x7149u, 0x716Eu, 0x719Cu, 0x71CEu, 0x71D0u,
+   0x7210u, 0x721Bu, 0x7228u, 0x722Bu, 0x7235u, 0x7250u, 0x7262u, 0x7280u,
+   0x7295u, 0x72AFu, 0x72C0u, 0x72FCu, 0x732Au, 0x7375u, 0x737Au, 0x7387u,
+   0x738Bu, 0x73A5u, 0x73B2u, 0x73DEu, 0x7406u, 0x7409u, 0x7422u, 0x7447u,
+   0x745Cu, 0x7469u, 0x7471u, 0x7485u, 0x7489u, 0x7498u, 0x74CAu, 0x7506u,
+   0x7524u, 0x753Bu, 0x753Eu, 0x7559u, 0x7565u, 0x7570u, 0x75E2u, 0x7610u,
+   0x761Du, 0x761Fu, 0x7642u, 0x7669u, 0x76CAu, 0x76DBu, 0x76E7u, 0x76F4u,
+   0x7701u, 0x771Eu, 0x771Fu, 0x7740u, 0x774Au, 0x778Bu, 0x77A7u, 0x784Eu,
+   0x786Bu, 0x788Cu, 0x7891u, 0x78CAu, 0x78CCu, 0x78FBu, 0x792Au, 0x793Cu,
+   0x793Eu, 0x7948u, 0x7949u, 0x7950u, 0x7956u, 0x795Du, 0x795Eu, 0x7965u,
+   0x797Fu, 0x798Du, 0x798Eu, 0x798Fu, 0x79AEu, 0x79CAu, 0x79EBu, 0x7A1Cu,
+   0x7A40u, 0x7A4Au, 0x7A4Fu, 0x7A81u, 0x7AB1u, 0x7ACBu, 0x7AEEu, 0x7B20u,
+   0x7BC0u, 0x7BC6u, 0x7BC9u, 0x7C3Eu, 0x7C60u, 0x7C7Bu, 0x7C92u, 0x7CBEu,
+   0x7CD2u, 0x7CD6u, 0x7CE3u, 0x7CE7u, 0x7CE8u, 0x7D00u, 0x7D10u, 0x7D22u,
+   0x7D2Fu, 0x7D5Bu, 0x7D63u, 0x7DA0u, 0x7DBEu, 0x7DC7u, 0x7DF4u, 0x7E02u,
+   0x7E09u, 0x7E37u, 0x7E41u, 0x7E45u, 0x7F3Eu, 0x7F72u, 0x7F79u, 0x7F7Au,
+   0x7F85u, 0x7F95u, 0x7F9Au, 0x7FBDu, 0x7FFAu, 0x8001u, 0x8005u, 0x8046u,
+   0x8060u, 0x806Fu, 0x8070u, 0x807Eu, 0x808Bu, 0x80ADu, 0x80B2u, 0x8103u,
+   0x813Eu, 0x81D8u, 0x81E8u, 0x81EDu, 0x8201u, 0x8204u, 0x8218u, 0x826Fu,
+   0x8279u, 0x828Bu, 0x8291u, 0x829Du, 0x82B1u, 0x82B3u, 0x82BDu, 0x82E5u,
+   0x82E6u, 0x831Du, 0x8323u, 0x8336u, 0x8352u, 0x8353u, 0x8363u, 0x83ADu,
+   0x83BDu, 0x83C9u, 0x83CAu, 0x83CCu, 0x83DCu, 0x83E7u, 0x83EFu, 0x83F1u,
+   0x843Du, 0x8449u, 0x8457u, 0x84EEu, 0x84F1u, 0x84F3u, 0x84FCu, 0x8516u,
+   0x8564u, 0x85CDu, 0x85FAu, 0x8606u, 0x8612u, 0x862Du, 0x863Fu, 0x8650u,
+   0x865Cu, 0x8667u, 0x8669u, 0x8688u, 0x86A9u, 0x86E2u, 0x870Eu, 0x8728u,
+   0x876Bu, 0x8779u, 0x8786u, 0x87BAu, 0x87E1u, 0x8801u, 0x881Fu, 0x884Cu,
+   0x8860u, 0x8863u, 0x88C2u, 0x88CFu, 0x88D7u, 0x88DEu, 0x88E1u, 0x88F8u,
+   0x88FAu, 0x8910u, 0x8941u, 0x8964u, 0x8986u, 0x898Bu, 0x8996u, 0x8AA0u,
+   0x8AAAu, 0x8ABFu, 0x8ACBu, 0x8AD2u, 0x8AD6u, 0x8AEDu, 0x8AF8u, 0x8AFEu,
+   0x8B01u, 0x8B39u, 0x8B58u, 0x8B80u, 0x8B8Au, 0x8C48u, 0x8C55u, 0x8CABu,
+   0x8CC1u, 0x8CC2u, 0x8CC8u, 0x8CD3u, 0x8D08u, 0x8D1Bu, 0x8D77u, 0x8DBCu,
+   0x8DCBu, 0x8DEFu, 0x8DF0u, 0x8ECAu, 0x8ED4u, 0x8F26u, 0x8F2Au, 0x8F38u,
+   0x8F3Bu, 0x8F62u, 0x8F9Eu, 0x8FB0u, 0x8FB6u, 0x9023u, 0x9038u, 0x9072u,
+   0x907Cu, 0x908Fu, 0x9094u, 0x90CEu, 0x90DEu, 0x90F1u, 0x90FDu, 0x9111u,
+   0x911Bu, 0x916Au, 0x9199u, 0x91B4u, 0x91CCu, 0x91CFu, 0x91D1u, 0x9234u,
+   0x9238u, 0x9276u, 0x927Cu, 0x92D7u, 0x92D8u, 0x9304u, 0x934Au, 0x93F9u,
+   0x9415u, 0x958Bu, 0x95ADu, 0x95B7u, 0x962Eu, 0x964Bu, 0x964Du, 0x9675u,
+   0x9678u, 0x967Cu, 0x9686u, 0x96A3u, 0x96B7u, 0x96B8u, 0x96C3u, 0x96E2u,
+   0x96E3u, 0x96F6u, 0x96F7u, 0x9723u, 0x9732u, 0x9748u, 0x9756u, 0x97DBu,
+   0x97E0u, 0x97FFu, 0x980Bu, 0x9818u, 0x9829u, 0x983Bu, 0x985Eu, 0x98E2u,
+   0x98EFu, 0x98FCu, 0x9928u, 0x9929u, 0x99A7u, 0x99C2u, 0x99F1u, 0x99FEu,
+   0x9A6Au, 0x9B12u, 0x9B6Fu, 0x9C40u, 0x9C57u, 0x9CFDu, 0x9D67u, 0x9DB4u,
+   0x9DFAu, 0x9E1Eu, 0x9E7Fu, 0x9E97u, 0x9E9Fu, 0x9EBBu, 0x9ECEu, 0x9EF9u,
+   0x9EFEu, 0x9F05u, 0x9F0Fu, 0x9F16u, 0x9F3Bu, 0x9F43u, 0x9F8Du, 0x9F8Eu,
+   0x9F9Cu,
+};
+static const uint16_t
+_hb_ucd_dm1_p2_map[110] =
+{
+   0x0122u, 0x051Cu, 0x0525u, 0x054Bu, 0x063Au, 0x0804u, 0x08DEu, 0x0A2Cu,
+   0x0B63u, 0x14E4u, 0x16A8u, 0x16EAu, 0x19C8u, 0x1B18u, 0x1D0Bu, 0x1DE4u,
+   0x1DE6u, 0x2183u, 0x219Fu, 0x2331u, 0x26D4u, 0x2844u, 0x284Au, 0x2B0Cu,
+   0x2BF1u, 0x300Au, 0x32B8u, 0x335Fu, 0x3393u, 0x339Cu, 0x33C3u, 0x33D5u,
+   0x346Du, 0x36A3u, 0x38A7u, 0x3A8Du, 0x3AFAu, 0x3CBCu, 0x3D1Eu, 0x3ED1u,
+   0x3F5Eu, 0x3F8Eu, 0x4263u, 0x42EEu, 0x43ABu, 0x4608u, 0x4735u, 0x4814u,
+   0x4C36u, 0x4C92u, 0x4FA1u, 0x4FB8u, 0x5044u, 0x50F2u, 0x50F3u, 0x5119u,
+   0x5133u, 0x5249u, 0x541Du, 0x5626u, 0x569Au, 0x56C5u, 0x597Cu, 0x5AA7u,
+   0x5BABu, 0x5C80u, 0x5CD0u, 0x5F86u, 0x61DAu, 0x6228u, 0x6247u, 0x62D9u,
+   0x633Eu, 0x64DAu, 0x6523u, 0x65A8u, 0x67A7u, 0x67B5u, 0x6B3Cu, 0x6C36u,
+   0x6CD5u, 0x6D6Bu, 0x6F2Cu, 0x6FB1u, 0x70D2u, 0x73CAu, 0x7667u, 0x78AEu,
+   0x7966u, 0x7CA8u, 0x7ED3u, 0x7F2Fu, 0x85D2u, 0x85EDu, 0x872Eu, 0x8BFAu,
+   0x8D77u, 0x9145u, 0x91DFu, 0x921Au, 0x940Au, 0x9496u, 0x95B6u, 0x9B30u,
+   0xA0CEu, 0xA105u, 0xA20Eu, 0xA291u, 0xA392u, 0xA600u,
+};
+static const uint32_t
+_hb_ucd_dm2_u32_map[638] =
+{
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x003Cu, 0x0338u, 0x226Eu),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x003Du, 0x0338u, 0x2260u),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x003Eu, 0x0338u, 0x226Fu),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x0041u, 0x0300u, 0x00C0u),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x0041u, 0x0301u, 0x00C1u),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x0041u, 0x0302u, 0x00C2u),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x0041u, 0x0303u, 0x00C3u),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x0041u, 0x0304u, 0x0100u),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x0041u, 0x0306u, 0x0102u),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x0041u, 0x0307u, 0x0226u),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x0041u, 0x0308u, 0x00C4u),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x0041u, 0x0309u, 0x1EA2u),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x0041u, 0x030Au, 0x00C5u),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x0041u, 0x030Cu, 0x01CDu),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x0041u, 0x030Fu, 0x0200u),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x0041u, 0x0311u, 0x0202u),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x0041u, 0x0323u, 0x1EA0u),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x0041u, 0x0325u, 0x1E00u),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x0041u, 0x0328u, 0x0104u),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x0042u, 0x0307u, 0x1E02u),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x0042u, 0x0323u, 0x1E04u),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x0042u, 0x0331u, 0x1E06u),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x0043u, 0x0301u, 0x0106u),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x0043u, 0x0302u, 0x0108u),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x0043u, 0x0307u, 0x010Au),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x0043u, 0x030Cu, 0x010Cu),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x0043u, 0x0327u, 0x00C7u),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x0044u, 0x0307u, 0x1E0Au),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x0044u, 0x030Cu, 0x010Eu),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x0044u, 0x0323u, 0x1E0Cu),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x0044u, 0x0327u, 0x1E10u),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x0044u, 0x032Du, 0x1E12u),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x0044u, 0x0331u, 0x1E0Eu),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x0045u, 0x0300u, 0x00C8u),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x0045u, 0x0301u, 0x00C9u),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x0045u, 0x0302u, 0x00CAu),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x0045u, 0x0303u, 0x1EBCu),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x0045u, 0x0304u, 0x0112u),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x0045u, 0x0306u, 0x0114u),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x0045u, 0x0307u, 0x0116u),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x0045u, 0x0308u, 0x00CBu),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x0045u, 0x0309u, 0x1EBAu),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x0045u, 0x030Cu, 0x011Au),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x0045u, 0x030Fu, 0x0204u),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x0045u, 0x0311u, 0x0206u),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x0045u, 0x0323u, 0x1EB8u),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x0045u, 0x0327u, 0x0228u),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x0045u, 0x0328u, 0x0118u),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x0045u, 0x032Du, 0x1E18u),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x0045u, 0x0330u, 0x1E1Au),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x0046u, 0x0307u, 0x1E1Eu),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x0047u, 0x0301u, 0x01F4u),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x0047u, 0x0302u, 0x011Cu),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x0047u, 0x0304u, 0x1E20u),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x0047u, 0x0306u, 0x011Eu),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x0047u, 0x0307u, 0x0120u),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x0047u, 0x030Cu, 0x01E6u),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x0047u, 0x0327u, 0x0122u),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x0048u, 0x0302u, 0x0124u),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x0048u, 0x0307u, 0x1E22u),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x0048u, 0x0308u, 0x1E26u),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x0048u, 0x030Cu, 0x021Eu),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x0048u, 0x0323u, 0x1E24u),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x0048u, 0x0327u, 0x1E28u),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x0048u, 0x032Eu, 0x1E2Au),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x0049u, 0x0300u, 0x00CCu),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x0049u, 0x0301u, 0x00CDu),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x0049u, 0x0302u, 0x00CEu),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x0049u, 0x0303u, 0x0128u),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x0049u, 0x0304u, 0x012Au),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x0049u, 0x0306u, 0x012Cu),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x0049u, 0x0307u, 0x0130u),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x0049u, 0x0308u, 0x00CFu),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x0049u, 0x0309u, 0x1EC8u),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x0049u, 0x030Cu, 0x01CFu),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x0049u, 0x030Fu, 0x0208u),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x0049u, 0x0311u, 0x020Au),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x0049u, 0x0323u, 0x1ECAu),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x0049u, 0x0328u, 0x012Eu),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x0049u, 0x0330u, 0x1E2Cu),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x004Au, 0x0302u, 0x0134u),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x004Bu, 0x0301u, 0x1E30u),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x004Bu, 0x030Cu, 0x01E8u),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x004Bu, 0x0323u, 0x1E32u),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x004Bu, 0x0327u, 0x0136u),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x004Bu, 0x0331u, 0x1E34u),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x004Cu, 0x0301u, 0x0139u),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x004Cu, 0x030Cu, 0x013Du),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x004Cu, 0x0323u, 0x1E36u),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x004Cu, 0x0327u, 0x013Bu),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x004Cu, 0x032Du, 0x1E3Cu),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x004Cu, 0x0331u, 0x1E3Au),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x004Du, 0x0301u, 0x1E3Eu),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x004Du, 0x0307u, 0x1E40u),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x004Du, 0x0323u, 0x1E42u),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x004Eu, 0x0300u, 0x01F8u),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x004Eu, 0x0301u, 0x0143u),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x004Eu, 0x0303u, 0x00D1u),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x004Eu, 0x0307u, 0x1E44u),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x004Eu, 0x030Cu, 0x0147u),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x004Eu, 0x0323u, 0x1E46u),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x004Eu, 0x0327u, 0x0145u),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x004Eu, 0x032Du, 0x1E4Au),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x004Eu, 0x0331u, 0x1E48u),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x004Fu, 0x0300u, 0x00D2u),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x004Fu, 0x0301u, 0x00D3u),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x004Fu, 0x0302u, 0x00D4u),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x004Fu, 0x0303u, 0x00D5u),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x004Fu, 0x0304u, 0x014Cu),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x004Fu, 0x0306u, 0x014Eu),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x004Fu, 0x0307u, 0x022Eu),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x004Fu, 0x0308u, 0x00D6u),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x004Fu, 0x0309u, 0x1ECEu),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x004Fu, 0x030Bu, 0x0150u),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x004Fu, 0x030Cu, 0x01D1u),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x004Fu, 0x030Fu, 0x020Cu),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x004Fu, 0x0311u, 0x020Eu),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x004Fu, 0x031Bu, 0x01A0u),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x004Fu, 0x0323u, 0x1ECCu),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x004Fu, 0x0328u, 0x01EAu),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x0050u, 0x0301u, 0x1E54u),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x0050u, 0x0307u, 0x1E56u),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x0052u, 0x0301u, 0x0154u),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x0052u, 0x0307u, 0x1E58u),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x0052u, 0x030Cu, 0x0158u),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x0052u, 0x030Fu, 0x0210u),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x0052u, 0x0311u, 0x0212u),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x0052u, 0x0323u, 0x1E5Au),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x0052u, 0x0327u, 0x0156u),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x0052u, 0x0331u, 0x1E5Eu),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x0053u, 0x0301u, 0x015Au),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x0053u, 0x0302u, 0x015Cu),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x0053u, 0x0307u, 0x1E60u),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x0053u, 0x030Cu, 0x0160u),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x0053u, 0x0323u, 0x1E62u),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x0053u, 0x0326u, 0x0218u),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x0053u, 0x0327u, 0x015Eu),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x0054u, 0x0307u, 0x1E6Au),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x0054u, 0x030Cu, 0x0164u),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x0054u, 0x0323u, 0x1E6Cu),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x0054u, 0x0326u, 0x021Au),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x0054u, 0x0327u, 0x0162u),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x0054u, 0x032Du, 0x1E70u),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x0054u, 0x0331u, 0x1E6Eu),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x0055u, 0x0300u, 0x00D9u),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x0055u, 0x0301u, 0x00DAu),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x0055u, 0x0302u, 0x00DBu),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x0055u, 0x0303u, 0x0168u),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x0055u, 0x0304u, 0x016Au),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x0055u, 0x0306u, 0x016Cu),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x0055u, 0x0308u, 0x00DCu),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x0055u, 0x0309u, 0x1EE6u),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x0055u, 0x030Au, 0x016Eu),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x0055u, 0x030Bu, 0x0170u),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x0055u, 0x030Cu, 0x01D3u),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x0055u, 0x030Fu, 0x0214u),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x0055u, 0x0311u, 0x0216u),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x0055u, 0x031Bu, 0x01AFu),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x0055u, 0x0323u, 0x1EE4u),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x0055u, 0x0324u, 0x1E72u),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x0055u, 0x0328u, 0x0172u),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x0055u, 0x032Du, 0x1E76u),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x0055u, 0x0330u, 0x1E74u),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x0056u, 0x0303u, 0x1E7Cu),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x0056u, 0x0323u, 0x1E7Eu),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x0057u, 0x0300u, 0x1E80u),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x0057u, 0x0301u, 0x1E82u),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x0057u, 0x0302u, 0x0174u),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x0057u, 0x0307u, 0x1E86u),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x0057u, 0x0308u, 0x1E84u),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x0057u, 0x0323u, 0x1E88u),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x0058u, 0x0307u, 0x1E8Au),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x0058u, 0x0308u, 0x1E8Cu),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x0059u, 0x0300u, 0x1EF2u),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x0059u, 0x0301u, 0x00DDu),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x0059u, 0x0302u, 0x0176u),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x0059u, 0x0303u, 0x1EF8u),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x0059u, 0x0304u, 0x0232u),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x0059u, 0x0307u, 0x1E8Eu),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x0059u, 0x0308u, 0x0178u),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x0059u, 0x0309u, 0x1EF6u),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x0059u, 0x0323u, 0x1EF4u),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x005Au, 0x0301u, 0x0179u),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x005Au, 0x0302u, 0x1E90u),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x005Au, 0x0307u, 0x017Bu),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x005Au, 0x030Cu, 0x017Du),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x005Au, 0x0323u, 0x1E92u),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x005Au, 0x0331u, 0x1E94u),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x0061u, 0x0300u, 0x00E0u),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x0061u, 0x0301u, 0x00E1u),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x0061u, 0x0302u, 0x00E2u),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x0061u, 0x0303u, 0x00E3u),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x0061u, 0x0304u, 0x0101u),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x0061u, 0x0306u, 0x0103u),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x0061u, 0x0307u, 0x0227u),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x0061u, 0x0308u, 0x00E4u),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x0061u, 0x0309u, 0x1EA3u),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x0061u, 0x030Au, 0x00E5u),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x0061u, 0x030Cu, 0x01CEu),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x0061u, 0x030Fu, 0x0201u),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x0061u, 0x0311u, 0x0203u),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x0061u, 0x0323u, 0x1EA1u),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x0061u, 0x0325u, 0x1E01u),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x0061u, 0x0328u, 0x0105u),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x0062u, 0x0307u, 0x1E03u),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x0062u, 0x0323u, 0x1E05u),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x0062u, 0x0331u, 0x1E07u),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x0063u, 0x0301u, 0x0107u),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x0063u, 0x0302u, 0x0109u),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x0063u, 0x0307u, 0x010Bu),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x0063u, 0x030Cu, 0x010Du),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x0063u, 0x0327u, 0x00E7u),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x0064u, 0x0307u, 0x1E0Bu),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x0064u, 0x030Cu, 0x010Fu),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x0064u, 0x0323u, 0x1E0Du),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x0064u, 0x0327u, 0x1E11u),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x0064u, 0x032Du, 0x1E13u),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x0064u, 0x0331u, 0x1E0Fu),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x0065u, 0x0300u, 0x00E8u),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x0065u, 0x0301u, 0x00E9u),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x0065u, 0x0302u, 0x00EAu),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x0065u, 0x0303u, 0x1EBDu),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x0065u, 0x0304u, 0x0113u),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x0065u, 0x0306u, 0x0115u),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x0065u, 0x0307u, 0x0117u),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x0065u, 0x0308u, 0x00EBu),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x0065u, 0x0309u, 0x1EBBu),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x0065u, 0x030Cu, 0x011Bu),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x0065u, 0x030Fu, 0x0205u),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x0065u, 0x0311u, 0x0207u),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x0065u, 0x0323u, 0x1EB9u),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x0065u, 0x0327u, 0x0229u),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x0065u, 0x0328u, 0x0119u),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x0065u, 0x032Du, 0x1E19u),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x0065u, 0x0330u, 0x1E1Bu),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x0066u, 0x0307u, 0x1E1Fu),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x0067u, 0x0301u, 0x01F5u),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x0067u, 0x0302u, 0x011Du),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x0067u, 0x0304u, 0x1E21u),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x0067u, 0x0306u, 0x011Fu),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x0067u, 0x0307u, 0x0121u),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x0067u, 0x030Cu, 0x01E7u),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x0067u, 0x0327u, 0x0123u),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x0068u, 0x0302u, 0x0125u),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x0068u, 0x0307u, 0x1E23u),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x0068u, 0x0308u, 0x1E27u),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x0068u, 0x030Cu, 0x021Fu),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x0068u, 0x0323u, 0x1E25u),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x0068u, 0x0327u, 0x1E29u),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x0068u, 0x032Eu, 0x1E2Bu),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x0068u, 0x0331u, 0x1E96u),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x0069u, 0x0300u, 0x00ECu),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x0069u, 0x0301u, 0x00EDu),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x0069u, 0x0302u, 0x00EEu),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x0069u, 0x0303u, 0x0129u),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x0069u, 0x0304u, 0x012Bu),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x0069u, 0x0306u, 0x012Du),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x0069u, 0x0308u, 0x00EFu),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x0069u, 0x0309u, 0x1EC9u),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x0069u, 0x030Cu, 0x01D0u),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x0069u, 0x030Fu, 0x0209u),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x0069u, 0x0311u, 0x020Bu),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x0069u, 0x0323u, 0x1ECBu),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x0069u, 0x0328u, 0x012Fu),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x0069u, 0x0330u, 0x1E2Du),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x006Au, 0x0302u, 0x0135u),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x006Au, 0x030Cu, 0x01F0u),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x006Bu, 0x0301u, 0x1E31u),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x006Bu, 0x030Cu, 0x01E9u),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x006Bu, 0x0323u, 0x1E33u),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x006Bu, 0x0327u, 0x0137u),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x006Bu, 0x0331u, 0x1E35u),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x006Cu, 0x0301u, 0x013Au),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x006Cu, 0x030Cu, 0x013Eu),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x006Cu, 0x0323u, 0x1E37u),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x006Cu, 0x0327u, 0x013Cu),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x006Cu, 0x032Du, 0x1E3Du),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x006Cu, 0x0331u, 0x1E3Bu),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x006Du, 0x0301u, 0x1E3Fu),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x006Du, 0x0307u, 0x1E41u),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x006Du, 0x0323u, 0x1E43u),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x006Eu, 0x0300u, 0x01F9u),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x006Eu, 0x0301u, 0x0144u),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x006Eu, 0x0303u, 0x00F1u),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x006Eu, 0x0307u, 0x1E45u),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x006Eu, 0x030Cu, 0x0148u),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x006Eu, 0x0323u, 0x1E47u),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x006Eu, 0x0327u, 0x0146u),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x006Eu, 0x032Du, 0x1E4Bu),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x006Eu, 0x0331u, 0x1E49u),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x006Fu, 0x0300u, 0x00F2u),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x006Fu, 0x0301u, 0x00F3u),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x006Fu, 0x0302u, 0x00F4u),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x006Fu, 0x0303u, 0x00F5u),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x006Fu, 0x0304u, 0x014Du),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x006Fu, 0x0306u, 0x014Fu),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x006Fu, 0x0307u, 0x022Fu),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x006Fu, 0x0308u, 0x00F6u),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x006Fu, 0x0309u, 0x1ECFu),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x006Fu, 0x030Bu, 0x0151u),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x006Fu, 0x030Cu, 0x01D2u),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x006Fu, 0x030Fu, 0x020Du),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x006Fu, 0x0311u, 0x020Fu),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x006Fu, 0x031Bu, 0x01A1u),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x006Fu, 0x0323u, 0x1ECDu),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x006Fu, 0x0328u, 0x01EBu),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x0070u, 0x0301u, 0x1E55u),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x0070u, 0x0307u, 0x1E57u),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x0072u, 0x0301u, 0x0155u),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x0072u, 0x0307u, 0x1E59u),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x0072u, 0x030Cu, 0x0159u),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x0072u, 0x030Fu, 0x0211u),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x0072u, 0x0311u, 0x0213u),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x0072u, 0x0323u, 0x1E5Bu),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x0072u, 0x0327u, 0x0157u),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x0072u, 0x0331u, 0x1E5Fu),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x0073u, 0x0301u, 0x015Bu),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x0073u, 0x0302u, 0x015Du),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x0073u, 0x0307u, 0x1E61u),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x0073u, 0x030Cu, 0x0161u),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x0073u, 0x0323u, 0x1E63u),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x0073u, 0x0326u, 0x0219u),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x0073u, 0x0327u, 0x015Fu),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x0074u, 0x0307u, 0x1E6Bu),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x0074u, 0x0308u, 0x1E97u),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x0074u, 0x030Cu, 0x0165u),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x0074u, 0x0323u, 0x1E6Du),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x0074u, 0x0326u, 0x021Bu),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x0074u, 0x0327u, 0x0163u),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x0074u, 0x032Du, 0x1E71u),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x0074u, 0x0331u, 0x1E6Fu),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x0075u, 0x0300u, 0x00F9u),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x0075u, 0x0301u, 0x00FAu),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x0075u, 0x0302u, 0x00FBu),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x0075u, 0x0303u, 0x0169u),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x0075u, 0x0304u, 0x016Bu),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x0075u, 0x0306u, 0x016Du),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x0075u, 0x0308u, 0x00FCu),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x0075u, 0x0309u, 0x1EE7u),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x0075u, 0x030Au, 0x016Fu),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x0075u, 0x030Bu, 0x0171u),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x0075u, 0x030Cu, 0x01D4u),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x0075u, 0x030Fu, 0x0215u),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x0075u, 0x0311u, 0x0217u),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x0075u, 0x031Bu, 0x01B0u),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x0075u, 0x0323u, 0x1EE5u),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x0075u, 0x0324u, 0x1E73u),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x0075u, 0x0328u, 0x0173u),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x0075u, 0x032Du, 0x1E77u),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x0075u, 0x0330u, 0x1E75u),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x0076u, 0x0303u, 0x1E7Du),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x0076u, 0x0323u, 0x1E7Fu),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x0077u, 0x0300u, 0x1E81u),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x0077u, 0x0301u, 0x1E83u),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x0077u, 0x0302u, 0x0175u),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x0077u, 0x0307u, 0x1E87u),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x0077u, 0x0308u, 0x1E85u),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x0077u, 0x030Au, 0x1E98u),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x0077u, 0x0323u, 0x1E89u),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x0078u, 0x0307u, 0x1E8Bu),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x0078u, 0x0308u, 0x1E8Du),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x0079u, 0x0300u, 0x1EF3u),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x0079u, 0x0301u, 0x00FDu),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x0079u, 0x0302u, 0x0177u),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x0079u, 0x0303u, 0x1EF9u),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x0079u, 0x0304u, 0x0233u),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x0079u, 0x0307u, 0x1E8Fu),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x0079u, 0x0308u, 0x00FFu),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x0079u, 0x0309u, 0x1EF7u),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x0079u, 0x030Au, 0x1E99u),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x0079u, 0x0323u, 0x1EF5u),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x007Au, 0x0301u, 0x017Au),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x007Au, 0x0302u, 0x1E91u),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x007Au, 0x0307u, 0x017Cu),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x007Au, 0x030Cu, 0x017Eu),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x007Au, 0x0323u, 0x1E93u),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x007Au, 0x0331u, 0x1E95u),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x00A8u, 0x0300u, 0x1FEDu),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x00A8u, 0x0301u, 0x0385u),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x00A8u, 0x0342u, 0x1FC1u),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x00C2u, 0x0300u, 0x1EA6u),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x00C2u, 0x0301u, 0x1EA4u),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x00C2u, 0x0303u, 0x1EAAu),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x00C2u, 0x0309u, 0x1EA8u),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x00C4u, 0x0304u, 0x01DEu),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x00C5u, 0x0301u, 0x01FAu),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x00C6u, 0x0301u, 0x01FCu),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x00C6u, 0x0304u, 0x01E2u),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x00C7u, 0x0301u, 0x1E08u),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x00CAu, 0x0300u, 0x1EC0u),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x00CAu, 0x0301u, 0x1EBEu),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x00CAu, 0x0303u, 0x1EC4u),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x00CAu, 0x0309u, 0x1EC2u),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x00CFu, 0x0301u, 0x1E2Eu),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x00D4u, 0x0300u, 0x1ED2u),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x00D4u, 0x0301u, 0x1ED0u),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x00D4u, 0x0303u, 0x1ED6u),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x00D4u, 0x0309u, 0x1ED4u),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x00D5u, 0x0301u, 0x1E4Cu),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x00D5u, 0x0304u, 0x022Cu),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x00D5u, 0x0308u, 0x1E4Eu),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x00D6u, 0x0304u, 0x022Au),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x00D8u, 0x0301u, 0x01FEu),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x00DCu, 0x0300u, 0x01DBu),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x00DCu, 0x0301u, 0x01D7u),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x00DCu, 0x0304u, 0x01D5u),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x00DCu, 0x030Cu, 0x01D9u),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x00E2u, 0x0300u, 0x1EA7u),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x00E2u, 0x0301u, 0x1EA5u),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x00E2u, 0x0303u, 0x1EABu),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x00E2u, 0x0309u, 0x1EA9u),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x00E4u, 0x0304u, 0x01DFu),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x00E5u, 0x0301u, 0x01FBu),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x00E6u, 0x0301u, 0x01FDu),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x00E6u, 0x0304u, 0x01E3u),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x00E7u, 0x0301u, 0x1E09u),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x00EAu, 0x0300u, 0x1EC1u),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x00EAu, 0x0301u, 0x1EBFu),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x00EAu, 0x0303u, 0x1EC5u),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x00EAu, 0x0309u, 0x1EC3u),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x00EFu, 0x0301u, 0x1E2Fu),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x00F4u, 0x0300u, 0x1ED3u),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x00F4u, 0x0301u, 0x1ED1u),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x00F4u, 0x0303u, 0x1ED7u),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x00F4u, 0x0309u, 0x1ED5u),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x00F5u, 0x0301u, 0x1E4Du),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x00F5u, 0x0304u, 0x022Du),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x00F5u, 0x0308u, 0x1E4Fu),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x00F6u, 0x0304u, 0x022Bu),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x00F8u, 0x0301u, 0x01FFu),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x00FCu, 0x0300u, 0x01DCu),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x00FCu, 0x0301u, 0x01D8u),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x00FCu, 0x0304u, 0x01D6u),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x00FCu, 0x030Cu, 0x01DAu),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x0102u, 0x0300u, 0x1EB0u),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x0102u, 0x0301u, 0x1EAEu),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x0102u, 0x0303u, 0x1EB4u),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x0102u, 0x0309u, 0x1EB2u),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x0103u, 0x0300u, 0x1EB1u),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x0103u, 0x0301u, 0x1EAFu),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x0103u, 0x0303u, 0x1EB5u),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x0103u, 0x0309u, 0x1EB3u),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x0112u, 0x0300u, 0x1E14u),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x0112u, 0x0301u, 0x1E16u),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x0113u, 0x0300u, 0x1E15u),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x0113u, 0x0301u, 0x1E17u),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x014Cu, 0x0300u, 0x1E50u),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x014Cu, 0x0301u, 0x1E52u),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x014Du, 0x0300u, 0x1E51u),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x014Du, 0x0301u, 0x1E53u),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x015Au, 0x0307u, 0x1E64u),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x015Bu, 0x0307u, 0x1E65u),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x0160u, 0x0307u, 0x1E66u),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x0161u, 0x0307u, 0x1E67u),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x0168u, 0x0301u, 0x1E78u),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x0169u, 0x0301u, 0x1E79u),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x016Au, 0x0308u, 0x1E7Au),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x016Bu, 0x0308u, 0x1E7Bu),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x017Fu, 0x0307u, 0x1E9Bu),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x01A0u, 0x0300u, 0x1EDCu),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x01A0u, 0x0301u, 0x1EDAu),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x01A0u, 0x0303u, 0x1EE0u),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x01A0u, 0x0309u, 0x1EDEu),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x01A0u, 0x0323u, 0x1EE2u),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x01A1u, 0x0300u, 0x1EDDu),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x01A1u, 0x0301u, 0x1EDBu),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x01A1u, 0x0303u, 0x1EE1u),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x01A1u, 0x0309u, 0x1EDFu),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x01A1u, 0x0323u, 0x1EE3u),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x01AFu, 0x0300u, 0x1EEAu),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x01AFu, 0x0301u, 0x1EE8u),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x01AFu, 0x0303u, 0x1EEEu),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x01AFu, 0x0309u, 0x1EECu),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x01AFu, 0x0323u, 0x1EF0u),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x01B0u, 0x0300u, 0x1EEBu),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x01B0u, 0x0301u, 0x1EE9u),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x01B0u, 0x0303u, 0x1EEFu),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x01B0u, 0x0309u, 0x1EEDu),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x01B0u, 0x0323u, 0x1EF1u),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x01B7u, 0x030Cu, 0x01EEu),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x01EAu, 0x0304u, 0x01ECu),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x01EBu, 0x0304u, 0x01EDu),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x0226u, 0x0304u, 0x01E0u),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x0227u, 0x0304u, 0x01E1u),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x0228u, 0x0306u, 0x1E1Cu),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x0229u, 0x0306u, 0x1E1Du),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x022Eu, 0x0304u, 0x0230u),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x022Fu, 0x0304u, 0x0231u),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x0292u, 0x030Cu, 0x01EFu),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x0308u, 0x0301u, 0x0000u),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x0391u, 0x0300u, 0x1FBAu),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x0391u, 0x0301u, 0x0386u),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x0391u, 0x0304u, 0x1FB9u),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x0391u, 0x0306u, 0x1FB8u),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x0391u, 0x0313u, 0x1F08u),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x0391u, 0x0314u, 0x1F09u),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x0391u, 0x0345u, 0x1FBCu),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x0395u, 0x0300u, 0x1FC8u),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x0395u, 0x0301u, 0x0388u),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x0395u, 0x0313u, 0x1F18u),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x0395u, 0x0314u, 0x1F19u),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x0397u, 0x0300u, 0x1FCAu),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x0397u, 0x0301u, 0x0389u),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x0397u, 0x0313u, 0x1F28u),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x0397u, 0x0314u, 0x1F29u),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x0397u, 0x0345u, 0x1FCCu),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x0399u, 0x0300u, 0x1FDAu),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x0399u, 0x0301u, 0x038Au),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x0399u, 0x0304u, 0x1FD9u),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x0399u, 0x0306u, 0x1FD8u),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x0399u, 0x0308u, 0x03AAu),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x0399u, 0x0313u, 0x1F38u),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x0399u, 0x0314u, 0x1F39u),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x039Fu, 0x0300u, 0x1FF8u),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x039Fu, 0x0301u, 0x038Cu),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x039Fu, 0x0313u, 0x1F48u),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x039Fu, 0x0314u, 0x1F49u),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x03A1u, 0x0314u, 0x1FECu),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x03A5u, 0x0300u, 0x1FEAu),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x03A5u, 0x0301u, 0x038Eu),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x03A5u, 0x0304u, 0x1FE9u),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x03A5u, 0x0306u, 0x1FE8u),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x03A5u, 0x0308u, 0x03ABu),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x03A5u, 0x0314u, 0x1F59u),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x03A9u, 0x0300u, 0x1FFAu),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x03A9u, 0x0301u, 0x038Fu),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x03A9u, 0x0313u, 0x1F68u),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x03A9u, 0x0314u, 0x1F69u),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x03A9u, 0x0345u, 0x1FFCu),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x03ACu, 0x0345u, 0x1FB4u),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x03AEu, 0x0345u, 0x1FC4u),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x03B1u, 0x0300u, 0x1F70u),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x03B1u, 0x0301u, 0x03ACu),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x03B1u, 0x0304u, 0x1FB1u),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x03B1u, 0x0306u, 0x1FB0u),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x03B1u, 0x0313u, 0x1F00u),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x03B1u, 0x0314u, 0x1F01u),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x03B1u, 0x0342u, 0x1FB6u),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x03B1u, 0x0345u, 0x1FB3u),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x03B5u, 0x0300u, 0x1F72u),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x03B5u, 0x0301u, 0x03ADu),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x03B5u, 0x0313u, 0x1F10u),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x03B5u, 0x0314u, 0x1F11u),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x03B7u, 0x0300u, 0x1F74u),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x03B7u, 0x0301u, 0x03AEu),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x03B7u, 0x0313u, 0x1F20u),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x03B7u, 0x0314u, 0x1F21u),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x03B7u, 0x0342u, 0x1FC6u),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x03B7u, 0x0345u, 0x1FC3u),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x03B9u, 0x0300u, 0x1F76u),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x03B9u, 0x0301u, 0x03AFu),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x03B9u, 0x0304u, 0x1FD1u),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x03B9u, 0x0306u, 0x1FD0u),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x03B9u, 0x0308u, 0x03CAu),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x03B9u, 0x0313u, 0x1F30u),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x03B9u, 0x0314u, 0x1F31u),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x03B9u, 0x0342u, 0x1FD6u),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x03BFu, 0x0300u, 0x1F78u),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x03BFu, 0x0301u, 0x03CCu),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x03BFu, 0x0313u, 0x1F40u),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x03BFu, 0x0314u, 0x1F41u),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x03C1u, 0x0313u, 0x1FE4u),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x03C1u, 0x0314u, 0x1FE5u),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x03C5u, 0x0300u, 0x1F7Au),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x03C5u, 0x0301u, 0x03CDu),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x03C5u, 0x0304u, 0x1FE1u),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x03C5u, 0x0306u, 0x1FE0u),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x03C5u, 0x0308u, 0x03CBu),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x03C5u, 0x0313u, 0x1F50u),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x03C5u, 0x0314u, 0x1F51u),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x03C5u, 0x0342u, 0x1FE6u),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x03C9u, 0x0300u, 0x1F7Cu),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x03C9u, 0x0301u, 0x03CEu),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x03C9u, 0x0313u, 0x1F60u),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x03C9u, 0x0314u, 0x1F61u),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x03C9u, 0x0342u, 0x1FF6u),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x03C9u, 0x0345u, 0x1FF3u),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x03CAu, 0x0300u, 0x1FD2u),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x03CAu, 0x0301u, 0x0390u),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x03CAu, 0x0342u, 0x1FD7u),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x03CBu, 0x0300u, 0x1FE2u),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x03CBu, 0x0301u, 0x03B0u),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x03CBu, 0x0342u, 0x1FE7u),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x03CEu, 0x0345u, 0x1FF4u),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x03D2u, 0x0301u, 0x03D3u),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x03D2u, 0x0308u, 0x03D4u),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x0406u, 0x0308u, 0x0407u),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x0410u, 0x0306u, 0x04D0u),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x0410u, 0x0308u, 0x04D2u),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x0413u, 0x0301u, 0x0403u),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x0415u, 0x0300u, 0x0400u),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x0415u, 0x0306u, 0x04D6u),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x0415u, 0x0308u, 0x0401u),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x0416u, 0x0306u, 0x04C1u),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x0416u, 0x0308u, 0x04DCu),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x0417u, 0x0308u, 0x04DEu),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x0418u, 0x0300u, 0x040Du),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x0418u, 0x0304u, 0x04E2u),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x0418u, 0x0306u, 0x0419u),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x0418u, 0x0308u, 0x04E4u),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x041Au, 0x0301u, 0x040Cu),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x041Eu, 0x0308u, 0x04E6u),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x0423u, 0x0304u, 0x04EEu),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x0423u, 0x0306u, 0x040Eu),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x0423u, 0x0308u, 0x04F0u),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x0423u, 0x030Bu, 0x04F2u),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x0427u, 0x0308u, 0x04F4u),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x042Bu, 0x0308u, 0x04F8u),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x042Du, 0x0308u, 0x04ECu),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x0430u, 0x0306u, 0x04D1u),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x0430u, 0x0308u, 0x04D3u),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x0433u, 0x0301u, 0x0453u),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x0435u, 0x0300u, 0x0450u),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x0435u, 0x0306u, 0x04D7u),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x0435u, 0x0308u, 0x0451u),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x0436u, 0x0306u, 0x04C2u),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x0436u, 0x0308u, 0x04DDu),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x0437u, 0x0308u, 0x04DFu),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x0438u, 0x0300u, 0x045Du),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x0438u, 0x0304u, 0x04E3u),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x0438u, 0x0306u, 0x0439u),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x0438u, 0x0308u, 0x04E5u),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x043Au, 0x0301u, 0x045Cu),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x043Eu, 0x0308u, 0x04E7u),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x0443u, 0x0304u, 0x04EFu),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x0443u, 0x0306u, 0x045Eu),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x0443u, 0x0308u, 0x04F1u),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x0443u, 0x030Bu, 0x04F3u),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x0447u, 0x0308u, 0x04F5u),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x044Bu, 0x0308u, 0x04F9u),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x044Du, 0x0308u, 0x04EDu),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x0456u, 0x0308u, 0x0457u),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x0474u, 0x030Fu, 0x0476u),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x0475u, 0x030Fu, 0x0477u),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x04D8u, 0x0308u, 0x04DAu),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x04D9u, 0x0308u, 0x04DBu),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x04E8u, 0x0308u, 0x04EAu),
+   HB_CODEPOINT_ENCODE3_11_7_14 (0x04E9u, 0x0308u, 0x04EBu),
+};
+static const uint64_t
+_hb_ucd_dm2_u64_map[387] =
+{
+     HB_CODEPOINT_ENCODE3 (0x05D0u, 0x05B7u, 0x0000u),   HB_CODEPOINT_ENCODE3 (0x05D0u, 0x05B8u, 0x0000u),
+     HB_CODEPOINT_ENCODE3 (0x05D0u, 0x05BCu, 0x0000u),   HB_CODEPOINT_ENCODE3 (0x05D1u, 0x05BCu, 0x0000u),
+     HB_CODEPOINT_ENCODE3 (0x05D1u, 0x05BFu, 0x0000u),   HB_CODEPOINT_ENCODE3 (0x05D2u, 0x05BCu, 0x0000u),
+     HB_CODEPOINT_ENCODE3 (0x05D3u, 0x05BCu, 0x0000u),   HB_CODEPOINT_ENCODE3 (0x05D4u, 0x05BCu, 0x0000u),
+     HB_CODEPOINT_ENCODE3 (0x05D5u, 0x05B9u, 0x0000u),   HB_CODEPOINT_ENCODE3 (0x05D5u, 0x05BCu, 0x0000u),
+     HB_CODEPOINT_ENCODE3 (0x05D6u, 0x05BCu, 0x0000u),   HB_CODEPOINT_ENCODE3 (0x05D8u, 0x05BCu, 0x0000u),
+     HB_CODEPOINT_ENCODE3 (0x05D9u, 0x05B4u, 0x0000u),   HB_CODEPOINT_ENCODE3 (0x05D9u, 0x05BCu, 0x0000u),
+     HB_CODEPOINT_ENCODE3 (0x05DAu, 0x05BCu, 0x0000u),   HB_CODEPOINT_ENCODE3 (0x05DBu, 0x05BCu, 0x0000u),
+     HB_CODEPOINT_ENCODE3 (0x05DBu, 0x05BFu, 0x0000u),   HB_CODEPOINT_ENCODE3 (0x05DCu, 0x05BCu, 0x0000u),
+     HB_CODEPOINT_ENCODE3 (0x05DEu, 0x05BCu, 0x0000u),   HB_CODEPOINT_ENCODE3 (0x05E0u, 0x05BCu, 0x0000u),
+     HB_CODEPOINT_ENCODE3 (0x05E1u, 0x05BCu, 0x0000u),   HB_CODEPOINT_ENCODE3 (0x05E3u, 0x05BCu, 0x0000u),
+     HB_CODEPOINT_ENCODE3 (0x05E4u, 0x05BCu, 0x0000u),   HB_CODEPOINT_ENCODE3 (0x05E4u, 0x05BFu, 0x0000u),
+     HB_CODEPOINT_ENCODE3 (0x05E6u, 0x05BCu, 0x0000u),   HB_CODEPOINT_ENCODE3 (0x05E7u, 0x05BCu, 0x0000u),
+     HB_CODEPOINT_ENCODE3 (0x05E8u, 0x05BCu, 0x0000u),   HB_CODEPOINT_ENCODE3 (0x05E9u, 0x05BCu, 0x0000u),
+     HB_CODEPOINT_ENCODE3 (0x05E9u, 0x05C1u, 0x0000u),   HB_CODEPOINT_ENCODE3 (0x05E9u, 0x05C2u, 0x0000u),
+     HB_CODEPOINT_ENCODE3 (0x05EAu, 0x05BCu, 0x0000u),   HB_CODEPOINT_ENCODE3 (0x05F2u, 0x05B7u, 0x0000u),
+     HB_CODEPOINT_ENCODE3 (0x0627u, 0x0653u, 0x0622u),   HB_CODEPOINT_ENCODE3 (0x0627u, 0x0654u, 0x0623u),
+     HB_CODEPOINT_ENCODE3 (0x0627u, 0x0655u, 0x0625u),   HB_CODEPOINT_ENCODE3 (0x0648u, 0x0654u, 0x0624u),
+     HB_CODEPOINT_ENCODE3 (0x064Au, 0x0654u, 0x0626u),   HB_CODEPOINT_ENCODE3 (0x06C1u, 0x0654u, 0x06C2u),
+     HB_CODEPOINT_ENCODE3 (0x06D2u, 0x0654u, 0x06D3u),   HB_CODEPOINT_ENCODE3 (0x06D5u, 0x0654u, 0x06C0u),
+     HB_CODEPOINT_ENCODE3 (0x0915u, 0x093Cu, 0x0000u),   HB_CODEPOINT_ENCODE3 (0x0916u, 0x093Cu, 0x0000u),
+     HB_CODEPOINT_ENCODE3 (0x0917u, 0x093Cu, 0x0000u),   HB_CODEPOINT_ENCODE3 (0x091Cu, 0x093Cu, 0x0000u),
+     HB_CODEPOINT_ENCODE3 (0x0921u, 0x093Cu, 0x0000u),   HB_CODEPOINT_ENCODE3 (0x0922u, 0x093Cu, 0x0000u),
+     HB_CODEPOINT_ENCODE3 (0x0928u, 0x093Cu, 0x0929u),   HB_CODEPOINT_ENCODE3 (0x092Bu, 0x093Cu, 0x0000u),
+     HB_CODEPOINT_ENCODE3 (0x092Fu, 0x093Cu, 0x0000u),   HB_CODEPOINT_ENCODE3 (0x0930u, 0x093Cu, 0x0931u),
+     HB_CODEPOINT_ENCODE3 (0x0933u, 0x093Cu, 0x0934u),   HB_CODEPOINT_ENCODE3 (0x09A1u, 0x09BCu, 0x0000u),
+     HB_CODEPOINT_ENCODE3 (0x09A2u, 0x09BCu, 0x0000u),   HB_CODEPOINT_ENCODE3 (0x09AFu, 0x09BCu, 0x0000u),
+     HB_CODEPOINT_ENCODE3 (0x09C7u, 0x09BEu, 0x09CBu),   HB_CODEPOINT_ENCODE3 (0x09C7u, 0x09D7u, 0x09CCu),
+     HB_CODEPOINT_ENCODE3 (0x0A16u, 0x0A3Cu, 0x0000u),   HB_CODEPOINT_ENCODE3 (0x0A17u, 0x0A3Cu, 0x0000u),
+     HB_CODEPOINT_ENCODE3 (0x0A1Cu, 0x0A3Cu, 0x0000u),   HB_CODEPOINT_ENCODE3 (0x0A2Bu, 0x0A3Cu, 0x0000u),
+     HB_CODEPOINT_ENCODE3 (0x0A32u, 0x0A3Cu, 0x0000u),   HB_CODEPOINT_ENCODE3 (0x0A38u, 0x0A3Cu, 0x0000u),
+     HB_CODEPOINT_ENCODE3 (0x0B21u, 0x0B3Cu, 0x0000u),   HB_CODEPOINT_ENCODE3 (0x0B22u, 0x0B3Cu, 0x0000u),
+     HB_CODEPOINT_ENCODE3 (0x0B47u, 0x0B3Eu, 0x0B4Bu),   HB_CODEPOINT_ENCODE3 (0x0B47u, 0x0B56u, 0x0B48u),
+     HB_CODEPOINT_ENCODE3 (0x0B47u, 0x0B57u, 0x0B4Cu),   HB_CODEPOINT_ENCODE3 (0x0B92u, 0x0BD7u, 0x0B94u),
+     HB_CODEPOINT_ENCODE3 (0x0BC6u, 0x0BBEu, 0x0BCAu),   HB_CODEPOINT_ENCODE3 (0x0BC6u, 0x0BD7u, 0x0BCCu),
+     HB_CODEPOINT_ENCODE3 (0x0BC7u, 0x0BBEu, 0x0BCBu),   HB_CODEPOINT_ENCODE3 (0x0C46u, 0x0C56u, 0x0C48u),
+     HB_CODEPOINT_ENCODE3 (0x0CBFu, 0x0CD5u, 0x0CC0u),   HB_CODEPOINT_ENCODE3 (0x0CC6u, 0x0CC2u, 0x0CCAu),
+     HB_CODEPOINT_ENCODE3 (0x0CC6u, 0x0CD5u, 0x0CC7u),   HB_CODEPOINT_ENCODE3 (0x0CC6u, 0x0CD6u, 0x0CC8u),
+     HB_CODEPOINT_ENCODE3 (0x0CCAu, 0x0CD5u, 0x0CCBu),   HB_CODEPOINT_ENCODE3 (0x0D46u, 0x0D3Eu, 0x0D4Au),
+     HB_CODEPOINT_ENCODE3 (0x0D46u, 0x0D57u, 0x0D4Cu),   HB_CODEPOINT_ENCODE3 (0x0D47u, 0x0D3Eu, 0x0D4Bu),
+     HB_CODEPOINT_ENCODE3 (0x0DD9u, 0x0DCAu, 0x0DDAu),   HB_CODEPOINT_ENCODE3 (0x0DD9u, 0x0DCFu, 0x0DDCu),
+     HB_CODEPOINT_ENCODE3 (0x0DD9u, 0x0DDFu, 0x0DDEu),   HB_CODEPOINT_ENCODE3 (0x0DDCu, 0x0DCAu, 0x0DDDu),
+     HB_CODEPOINT_ENCODE3 (0x0F40u, 0x0FB5u, 0x0000u),   HB_CODEPOINT_ENCODE3 (0x0F42u, 0x0FB7u, 0x0000u),
+     HB_CODEPOINT_ENCODE3 (0x0F4Cu, 0x0FB7u, 0x0000u),   HB_CODEPOINT_ENCODE3 (0x0F51u, 0x0FB7u, 0x0000u),
+     HB_CODEPOINT_ENCODE3 (0x0F56u, 0x0FB7u, 0x0000u),   HB_CODEPOINT_ENCODE3 (0x0F5Bu, 0x0FB7u, 0x0000u),
+     HB_CODEPOINT_ENCODE3 (0x0F71u, 0x0F72u, 0x0000u),   HB_CODEPOINT_ENCODE3 (0x0F71u, 0x0F74u, 0x0000u),
+     HB_CODEPOINT_ENCODE3 (0x0F71u, 0x0F80u, 0x0000u),   HB_CODEPOINT_ENCODE3 (0x0F90u, 0x0FB5u, 0x0000u),
+     HB_CODEPOINT_ENCODE3 (0x0F92u, 0x0FB7u, 0x0000u),   HB_CODEPOINT_ENCODE3 (0x0F9Cu, 0x0FB7u, 0x0000u),
+     HB_CODEPOINT_ENCODE3 (0x0FA1u, 0x0FB7u, 0x0000u),   HB_CODEPOINT_ENCODE3 (0x0FA6u, 0x0FB7u, 0x0000u),
+     HB_CODEPOINT_ENCODE3 (0x0FABu, 0x0FB7u, 0x0000u),   HB_CODEPOINT_ENCODE3 (0x0FB2u, 0x0F80u, 0x0000u),
+     HB_CODEPOINT_ENCODE3 (0x0FB3u, 0x0F80u, 0x0000u),   HB_CODEPOINT_ENCODE3 (0x1025u, 0x102Eu, 0x1026u),
+     HB_CODEPOINT_ENCODE3 (0x1B05u, 0x1B35u, 0x1B06u),   HB_CODEPOINT_ENCODE3 (0x1B07u, 0x1B35u, 0x1B08u),
+     HB_CODEPOINT_ENCODE3 (0x1B09u, 0x1B35u, 0x1B0Au),   HB_CODEPOINT_ENCODE3 (0x1B0Bu, 0x1B35u, 0x1B0Cu),
+     HB_CODEPOINT_ENCODE3 (0x1B0Du, 0x1B35u, 0x1B0Eu),   HB_CODEPOINT_ENCODE3 (0x1B11u, 0x1B35u, 0x1B12u),
+     HB_CODEPOINT_ENCODE3 (0x1B3Au, 0x1B35u, 0x1B3Bu),   HB_CODEPOINT_ENCODE3 (0x1B3Cu, 0x1B35u, 0x1B3Du),
+     HB_CODEPOINT_ENCODE3 (0x1B3Eu, 0x1B35u, 0x1B40u),   HB_CODEPOINT_ENCODE3 (0x1B3Fu, 0x1B35u, 0x1B41u),
+     HB_CODEPOINT_ENCODE3 (0x1B42u, 0x1B35u, 0x1B43u),   HB_CODEPOINT_ENCODE3 (0x1E36u, 0x0304u, 0x1E38u),
+     HB_CODEPOINT_ENCODE3 (0x1E37u, 0x0304u, 0x1E39u),   HB_CODEPOINT_ENCODE3 (0x1E5Au, 0x0304u, 0x1E5Cu),
+     HB_CODEPOINT_ENCODE3 (0x1E5Bu, 0x0304u, 0x1E5Du),   HB_CODEPOINT_ENCODE3 (0x1E62u, 0x0307u, 0x1E68u),
+     HB_CODEPOINT_ENCODE3 (0x1E63u, 0x0307u, 0x1E69u),   HB_CODEPOINT_ENCODE3 (0x1EA0u, 0x0302u, 0x1EACu),
+     HB_CODEPOINT_ENCODE3 (0x1EA0u, 0x0306u, 0x1EB6u),   HB_CODEPOINT_ENCODE3 (0x1EA1u, 0x0302u, 0x1EADu),
+     HB_CODEPOINT_ENCODE3 (0x1EA1u, 0x0306u, 0x1EB7u),   HB_CODEPOINT_ENCODE3 (0x1EB8u, 0x0302u, 0x1EC6u),
+     HB_CODEPOINT_ENCODE3 (0x1EB9u, 0x0302u, 0x1EC7u),   HB_CODEPOINT_ENCODE3 (0x1ECCu, 0x0302u, 0x1ED8u),
+     HB_CODEPOINT_ENCODE3 (0x1ECDu, 0x0302u, 0x1ED9u),   HB_CODEPOINT_ENCODE3 (0x1F00u, 0x0300u, 0x1F02u),
+     HB_CODEPOINT_ENCODE3 (0x1F00u, 0x0301u, 0x1F04u),   HB_CODEPOINT_ENCODE3 (0x1F00u, 0x0342u, 0x1F06u),
+     HB_CODEPOINT_ENCODE3 (0x1F00u, 0x0345u, 0x1F80u),   HB_CODEPOINT_ENCODE3 (0x1F01u, 0x0300u, 0x1F03u),
+     HB_CODEPOINT_ENCODE3 (0x1F01u, 0x0301u, 0x1F05u),   HB_CODEPOINT_ENCODE3 (0x1F01u, 0x0342u, 0x1F07u),
+     HB_CODEPOINT_ENCODE3 (0x1F01u, 0x0345u, 0x1F81u),   HB_CODEPOINT_ENCODE3 (0x1F02u, 0x0345u, 0x1F82u),
+     HB_CODEPOINT_ENCODE3 (0x1F03u, 0x0345u, 0x1F83u),   HB_CODEPOINT_ENCODE3 (0x1F04u, 0x0345u, 0x1F84u),
+     HB_CODEPOINT_ENCODE3 (0x1F05u, 0x0345u, 0x1F85u),   HB_CODEPOINT_ENCODE3 (0x1F06u, 0x0345u, 0x1F86u),
+     HB_CODEPOINT_ENCODE3 (0x1F07u, 0x0345u, 0x1F87u),   HB_CODEPOINT_ENCODE3 (0x1F08u, 0x0300u, 0x1F0Au),
+     HB_CODEPOINT_ENCODE3 (0x1F08u, 0x0301u, 0x1F0Cu),   HB_CODEPOINT_ENCODE3 (0x1F08u, 0x0342u, 0x1F0Eu),
+     HB_CODEPOINT_ENCODE3 (0x1F08u, 0x0345u, 0x1F88u),   HB_CODEPOINT_ENCODE3 (0x1F09u, 0x0300u, 0x1F0Bu),
+     HB_CODEPOINT_ENCODE3 (0x1F09u, 0x0301u, 0x1F0Du),   HB_CODEPOINT_ENCODE3 (0x1F09u, 0x0342u, 0x1F0Fu),
+     HB_CODEPOINT_ENCODE3 (0x1F09u, 0x0345u, 0x1F89u),   HB_CODEPOINT_ENCODE3 (0x1F0Au, 0x0345u, 0x1F8Au),
+     HB_CODEPOINT_ENCODE3 (0x1F0Bu, 0x0345u, 0x1F8Bu),   HB_CODEPOINT_ENCODE3 (0x1F0Cu, 0x0345u, 0x1F8Cu),
+     HB_CODEPOINT_ENCODE3 (0x1F0Du, 0x0345u, 0x1F8Du),   HB_CODEPOINT_ENCODE3 (0x1F0Eu, 0x0345u, 0x1F8Eu),
+     HB_CODEPOINT_ENCODE3 (0x1F0Fu, 0x0345u, 0x1F8Fu),   HB_CODEPOINT_ENCODE3 (0x1F10u, 0x0300u, 0x1F12u),
+     HB_CODEPOINT_ENCODE3 (0x1F10u, 0x0301u, 0x1F14u),   HB_CODEPOINT_ENCODE3 (0x1F11u, 0x0300u, 0x1F13u),
+     HB_CODEPOINT_ENCODE3 (0x1F11u, 0x0301u, 0x1F15u),   HB_CODEPOINT_ENCODE3 (0x1F18u, 0x0300u, 0x1F1Au),
+     HB_CODEPOINT_ENCODE3 (0x1F18u, 0x0301u, 0x1F1Cu),   HB_CODEPOINT_ENCODE3 (0x1F19u, 0x0300u, 0x1F1Bu),
+     HB_CODEPOINT_ENCODE3 (0x1F19u, 0x0301u, 0x1F1Du),   HB_CODEPOINT_ENCODE3 (0x1F20u, 0x0300u, 0x1F22u),
+     HB_CODEPOINT_ENCODE3 (0x1F20u, 0x0301u, 0x1F24u),   HB_CODEPOINT_ENCODE3 (0x1F20u, 0x0342u, 0x1F26u),
+     HB_CODEPOINT_ENCODE3 (0x1F20u, 0x0345u, 0x1F90u),   HB_CODEPOINT_ENCODE3 (0x1F21u, 0x0300u, 0x1F23u),
+     HB_CODEPOINT_ENCODE3 (0x1F21u, 0x0301u, 0x1F25u),   HB_CODEPOINT_ENCODE3 (0x1F21u, 0x0342u, 0x1F27u),
+     HB_CODEPOINT_ENCODE3 (0x1F21u, 0x0345u, 0x1F91u),   HB_CODEPOINT_ENCODE3 (0x1F22u, 0x0345u, 0x1F92u),
+     HB_CODEPOINT_ENCODE3 (0x1F23u, 0x0345u, 0x1F93u),   HB_CODEPOINT_ENCODE3 (0x1F24u, 0x0345u, 0x1F94u),
+     HB_CODEPOINT_ENCODE3 (0x1F25u, 0x0345u, 0x1F95u),   HB_CODEPOINT_ENCODE3 (0x1F26u, 0x0345u, 0x1F96u),
+     HB_CODEPOINT_ENCODE3 (0x1F27u, 0x0345u, 0x1F97u),   HB_CODEPOINT_ENCODE3 (0x1F28u, 0x0300u, 0x1F2Au),
+     HB_CODEPOINT_ENCODE3 (0x1F28u, 0x0301u, 0x1F2Cu),   HB_CODEPOINT_ENCODE3 (0x1F28u, 0x0342u, 0x1F2Eu),
+     HB_CODEPOINT_ENCODE3 (0x1F28u, 0x0345u, 0x1F98u),   HB_CODEPOINT_ENCODE3 (0x1F29u, 0x0300u, 0x1F2Bu),
+     HB_CODEPOINT_ENCODE3 (0x1F29u, 0x0301u, 0x1F2Du),   HB_CODEPOINT_ENCODE3 (0x1F29u, 0x0342u, 0x1F2Fu),
+     HB_CODEPOINT_ENCODE3 (0x1F29u, 0x0345u, 0x1F99u),   HB_CODEPOINT_ENCODE3 (0x1F2Au, 0x0345u, 0x1F9Au),
+     HB_CODEPOINT_ENCODE3 (0x1F2Bu, 0x0345u, 0x1F9Bu),   HB_CODEPOINT_ENCODE3 (0x1F2Cu, 0x0345u, 0x1F9Cu),
+     HB_CODEPOINT_ENCODE3 (0x1F2Du, 0x0345u, 0x1F9Du),   HB_CODEPOINT_ENCODE3 (0x1F2Eu, 0x0345u, 0x1F9Eu),
+     HB_CODEPOINT_ENCODE3 (0x1F2Fu, 0x0345u, 0x1F9Fu),   HB_CODEPOINT_ENCODE3 (0x1F30u, 0x0300u, 0x1F32u),
+     HB_CODEPOINT_ENCODE3 (0x1F30u, 0x0301u, 0x1F34u),   HB_CODEPOINT_ENCODE3 (0x1F30u, 0x0342u, 0x1F36u),
+     HB_CODEPOINT_ENCODE3 (0x1F31u, 0x0300u, 0x1F33u),   HB_CODEPOINT_ENCODE3 (0x1F31u, 0x0301u, 0x1F35u),
+     HB_CODEPOINT_ENCODE3 (0x1F31u, 0x0342u, 0x1F37u),   HB_CODEPOINT_ENCODE3 (0x1F38u, 0x0300u, 0x1F3Au),
+     HB_CODEPOINT_ENCODE3 (0x1F38u, 0x0301u, 0x1F3Cu),   HB_CODEPOINT_ENCODE3 (0x1F38u, 0x0342u, 0x1F3Eu),
+     HB_CODEPOINT_ENCODE3 (0x1F39u, 0x0300u, 0x1F3Bu),   HB_CODEPOINT_ENCODE3 (0x1F39u, 0x0301u, 0x1F3Du),
+     HB_CODEPOINT_ENCODE3 (0x1F39u, 0x0342u, 0x1F3Fu),   HB_CODEPOINT_ENCODE3 (0x1F40u, 0x0300u, 0x1F42u),
+     HB_CODEPOINT_ENCODE3 (0x1F40u, 0x0301u, 0x1F44u),   HB_CODEPOINT_ENCODE3 (0x1F41u, 0x0300u, 0x1F43u),
+     HB_CODEPOINT_ENCODE3 (0x1F41u, 0x0301u, 0x1F45u),   HB_CODEPOINT_ENCODE3 (0x1F48u, 0x0300u, 0x1F4Au),
+     HB_CODEPOINT_ENCODE3 (0x1F48u, 0x0301u, 0x1F4Cu),   HB_CODEPOINT_ENCODE3 (0x1F49u, 0x0300u, 0x1F4Bu),
+     HB_CODEPOINT_ENCODE3 (0x1F49u, 0x0301u, 0x1F4Du),   HB_CODEPOINT_ENCODE3 (0x1F50u, 0x0300u, 0x1F52u),
+     HB_CODEPOINT_ENCODE3 (0x1F50u, 0x0301u, 0x1F54u),   HB_CODEPOINT_ENCODE3 (0x1F50u, 0x0342u, 0x1F56u),
+     HB_CODEPOINT_ENCODE3 (0x1F51u, 0x0300u, 0x1F53u),   HB_CODEPOINT_ENCODE3 (0x1F51u, 0x0301u, 0x1F55u),
+     HB_CODEPOINT_ENCODE3 (0x1F51u, 0x0342u, 0x1F57u),   HB_CODEPOINT_ENCODE3 (0x1F59u, 0x0300u, 0x1F5Bu),
+     HB_CODEPOINT_ENCODE3 (0x1F59u, 0x0301u, 0x1F5Du),   HB_CODEPOINT_ENCODE3 (0x1F59u, 0x0342u, 0x1F5Fu),
+     HB_CODEPOINT_ENCODE3 (0x1F60u, 0x0300u, 0x1F62u),   HB_CODEPOINT_ENCODE3 (0x1F60u, 0x0301u, 0x1F64u),
+     HB_CODEPOINT_ENCODE3 (0x1F60u, 0x0342u, 0x1F66u),   HB_CODEPOINT_ENCODE3 (0x1F60u, 0x0345u, 0x1FA0u),
+     HB_CODEPOINT_ENCODE3 (0x1F61u, 0x0300u, 0x1F63u),   HB_CODEPOINT_ENCODE3 (0x1F61u, 0x0301u, 0x1F65u),
+     HB_CODEPOINT_ENCODE3 (0x1F61u, 0x0342u, 0x1F67u),   HB_CODEPOINT_ENCODE3 (0x1F61u, 0x0345u, 0x1FA1u),
+     HB_CODEPOINT_ENCODE3 (0x1F62u, 0x0345u, 0x1FA2u),   HB_CODEPOINT_ENCODE3 (0x1F63u, 0x0345u, 0x1FA3u),
+     HB_CODEPOINT_ENCODE3 (0x1F64u, 0x0345u, 0x1FA4u),   HB_CODEPOINT_ENCODE3 (0x1F65u, 0x0345u, 0x1FA5u),
+     HB_CODEPOINT_ENCODE3 (0x1F66u, 0x0345u, 0x1FA6u),   HB_CODEPOINT_ENCODE3 (0x1F67u, 0x0345u, 0x1FA7u),
+     HB_CODEPOINT_ENCODE3 (0x1F68u, 0x0300u, 0x1F6Au),   HB_CODEPOINT_ENCODE3 (0x1F68u, 0x0301u, 0x1F6Cu),
+     HB_CODEPOINT_ENCODE3 (0x1F68u, 0x0342u, 0x1F6Eu),   HB_CODEPOINT_ENCODE3 (0x1F68u, 0x0345u, 0x1FA8u),
+     HB_CODEPOINT_ENCODE3 (0x1F69u, 0x0300u, 0x1F6Bu),   HB_CODEPOINT_ENCODE3 (0x1F69u, 0x0301u, 0x1F6Du),
+     HB_CODEPOINT_ENCODE3 (0x1F69u, 0x0342u, 0x1F6Fu),   HB_CODEPOINT_ENCODE3 (0x1F69u, 0x0345u, 0x1FA9u),
+     HB_CODEPOINT_ENCODE3 (0x1F6Au, 0x0345u, 0x1FAAu),   HB_CODEPOINT_ENCODE3 (0x1F6Bu, 0x0345u, 0x1FABu),
+     HB_CODEPOINT_ENCODE3 (0x1F6Cu, 0x0345u, 0x1FACu),   HB_CODEPOINT_ENCODE3 (0x1F6Du, 0x0345u, 0x1FADu),
+     HB_CODEPOINT_ENCODE3 (0x1F6Eu, 0x0345u, 0x1FAEu),   HB_CODEPOINT_ENCODE3 (0x1F6Fu, 0x0345u, 0x1FAFu),
+     HB_CODEPOINT_ENCODE3 (0x1F70u, 0x0345u, 0x1FB2u),   HB_CODEPOINT_ENCODE3 (0x1F74u, 0x0345u, 0x1FC2u),
+     HB_CODEPOINT_ENCODE3 (0x1F7Cu, 0x0345u, 0x1FF2u),   HB_CODEPOINT_ENCODE3 (0x1FB6u, 0x0345u, 0x1FB7u),
+     HB_CODEPOINT_ENCODE3 (0x1FBFu, 0x0300u, 0x1FCDu),   HB_CODEPOINT_ENCODE3 (0x1FBFu, 0x0301u, 0x1FCEu),
+     HB_CODEPOINT_ENCODE3 (0x1FBFu, 0x0342u, 0x1FCFu),   HB_CODEPOINT_ENCODE3 (0x1FC6u, 0x0345u, 0x1FC7u),
+     HB_CODEPOINT_ENCODE3 (0x1FF6u, 0x0345u, 0x1FF7u),   HB_CODEPOINT_ENCODE3 (0x1FFEu, 0x0300u, 0x1FDDu),
+     HB_CODEPOINT_ENCODE3 (0x1FFEu, 0x0301u, 0x1FDEu),   HB_CODEPOINT_ENCODE3 (0x1FFEu, 0x0342u, 0x1FDFu),
+     HB_CODEPOINT_ENCODE3 (0x2190u, 0x0338u, 0x219Au),   HB_CODEPOINT_ENCODE3 (0x2192u, 0x0338u, 0x219Bu),
+     HB_CODEPOINT_ENCODE3 (0x2194u, 0x0338u, 0x21AEu),   HB_CODEPOINT_ENCODE3 (0x21D0u, 0x0338u, 0x21CDu),
+     HB_CODEPOINT_ENCODE3 (0x21D2u, 0x0338u, 0x21CFu),   HB_CODEPOINT_ENCODE3 (0x21D4u, 0x0338u, 0x21CEu),
+     HB_CODEPOINT_ENCODE3 (0x2203u, 0x0338u, 0x2204u),   HB_CODEPOINT_ENCODE3 (0x2208u, 0x0338u, 0x2209u),
+     HB_CODEPOINT_ENCODE3 (0x220Bu, 0x0338u, 0x220Cu),   HB_CODEPOINT_ENCODE3 (0x2223u, 0x0338u, 0x2224u),
+     HB_CODEPOINT_ENCODE3 (0x2225u, 0x0338u, 0x2226u),   HB_CODEPOINT_ENCODE3 (0x223Cu, 0x0338u, 0x2241u),
+     HB_CODEPOINT_ENCODE3 (0x2243u, 0x0338u, 0x2244u),   HB_CODEPOINT_ENCODE3 (0x2245u, 0x0338u, 0x2247u),
+     HB_CODEPOINT_ENCODE3 (0x2248u, 0x0338u, 0x2249u),   HB_CODEPOINT_ENCODE3 (0x224Du, 0x0338u, 0x226Du),
+     HB_CODEPOINT_ENCODE3 (0x2261u, 0x0338u, 0x2262u),   HB_CODEPOINT_ENCODE3 (0x2264u, 0x0338u, 0x2270u),
+     HB_CODEPOINT_ENCODE3 (0x2265u, 0x0338u, 0x2271u),   HB_CODEPOINT_ENCODE3 (0x2272u, 0x0338u, 0x2274u),
+     HB_CODEPOINT_ENCODE3 (0x2273u, 0x0338u, 0x2275u),   HB_CODEPOINT_ENCODE3 (0x2276u, 0x0338u, 0x2278u),
+     HB_CODEPOINT_ENCODE3 (0x2277u, 0x0338u, 0x2279u),   HB_CODEPOINT_ENCODE3 (0x227Au, 0x0338u, 0x2280u),
+     HB_CODEPOINT_ENCODE3 (0x227Bu, 0x0338u, 0x2281u),   HB_CODEPOINT_ENCODE3 (0x227Cu, 0x0338u, 0x22E0u),
+     HB_CODEPOINT_ENCODE3 (0x227Du, 0x0338u, 0x22E1u),   HB_CODEPOINT_ENCODE3 (0x2282u, 0x0338u, 0x2284u),
+     HB_CODEPOINT_ENCODE3 (0x2283u, 0x0338u, 0x2285u),   HB_CODEPOINT_ENCODE3 (0x2286u, 0x0338u, 0x2288u),
+     HB_CODEPOINT_ENCODE3 (0x2287u, 0x0338u, 0x2289u),   HB_CODEPOINT_ENCODE3 (0x2291u, 0x0338u, 0x22E2u),
+     HB_CODEPOINT_ENCODE3 (0x2292u, 0x0338u, 0x22E3u),   HB_CODEPOINT_ENCODE3 (0x22A2u, 0x0338u, 0x22ACu),
+     HB_CODEPOINT_ENCODE3 (0x22A8u, 0x0338u, 0x22ADu),   HB_CODEPOINT_ENCODE3 (0x22A9u, 0x0338u, 0x22AEu),
+     HB_CODEPOINT_ENCODE3 (0x22ABu, 0x0338u, 0x22AFu),   HB_CODEPOINT_ENCODE3 (0x22B2u, 0x0338u, 0x22EAu),
+     HB_CODEPOINT_ENCODE3 (0x22B3u, 0x0338u, 0x22EBu),   HB_CODEPOINT_ENCODE3 (0x22B4u, 0x0338u, 0x22ECu),
+     HB_CODEPOINT_ENCODE3 (0x22B5u, 0x0338u, 0x22EDu),   HB_CODEPOINT_ENCODE3 (0x2ADDu, 0x0338u, 0x0000u),
+     HB_CODEPOINT_ENCODE3 (0x3046u, 0x3099u, 0x3094u),   HB_CODEPOINT_ENCODE3 (0x304Bu, 0x3099u, 0x304Cu),
+     HB_CODEPOINT_ENCODE3 (0x304Du, 0x3099u, 0x304Eu),   HB_CODEPOINT_ENCODE3 (0x304Fu, 0x3099u, 0x3050u),
+     HB_CODEPOINT_ENCODE3 (0x3051u, 0x3099u, 0x3052u),   HB_CODEPOINT_ENCODE3 (0x3053u, 0x3099u, 0x3054u),
+     HB_CODEPOINT_ENCODE3 (0x3055u, 0x3099u, 0x3056u),   HB_CODEPOINT_ENCODE3 (0x3057u, 0x3099u, 0x3058u),
+     HB_CODEPOINT_ENCODE3 (0x3059u, 0x3099u, 0x305Au),   HB_CODEPOINT_ENCODE3 (0x305Bu, 0x3099u, 0x305Cu),
+     HB_CODEPOINT_ENCODE3 (0x305Du, 0x3099u, 0x305Eu),   HB_CODEPOINT_ENCODE3 (0x305Fu, 0x3099u, 0x3060u),
+     HB_CODEPOINT_ENCODE3 (0x3061u, 0x3099u, 0x3062u),   HB_CODEPOINT_ENCODE3 (0x3064u, 0x3099u, 0x3065u),
+     HB_CODEPOINT_ENCODE3 (0x3066u, 0x3099u, 0x3067u),   HB_CODEPOINT_ENCODE3 (0x3068u, 0x3099u, 0x3069u),
+     HB_CODEPOINT_ENCODE3 (0x306Fu, 0x3099u, 0x3070u),   HB_CODEPOINT_ENCODE3 (0x306Fu, 0x309Au, 0x3071u),
+     HB_CODEPOINT_ENCODE3 (0x3072u, 0x3099u, 0x3073u),   HB_CODEPOINT_ENCODE3 (0x3072u, 0x309Au, 0x3074u),
+     HB_CODEPOINT_ENCODE3 (0x3075u, 0x3099u, 0x3076u),   HB_CODEPOINT_ENCODE3 (0x3075u, 0x309Au, 0x3077u),
+     HB_CODEPOINT_ENCODE3 (0x3078u, 0x3099u, 0x3079u),   HB_CODEPOINT_ENCODE3 (0x3078u, 0x309Au, 0x307Au),
+     HB_CODEPOINT_ENCODE3 (0x307Bu, 0x3099u, 0x307Cu),   HB_CODEPOINT_ENCODE3 (0x307Bu, 0x309Au, 0x307Du),
+     HB_CODEPOINT_ENCODE3 (0x309Du, 0x3099u, 0x309Eu),   HB_CODEPOINT_ENCODE3 (0x30A6u, 0x3099u, 0x30F4u),
+     HB_CODEPOINT_ENCODE3 (0x30ABu, 0x3099u, 0x30ACu),   HB_CODEPOINT_ENCODE3 (0x30ADu, 0x3099u, 0x30AEu),
+     HB_CODEPOINT_ENCODE3 (0x30AFu, 0x3099u, 0x30B0u),   HB_CODEPOINT_ENCODE3 (0x30B1u, 0x3099u, 0x30B2u),
+     HB_CODEPOINT_ENCODE3 (0x30B3u, 0x3099u, 0x30B4u),   HB_CODEPOINT_ENCODE3 (0x30B5u, 0x3099u, 0x30B6u),
+     HB_CODEPOINT_ENCODE3 (0x30B7u, 0x3099u, 0x30B8u),   HB_CODEPOINT_ENCODE3 (0x30B9u, 0x3099u, 0x30BAu),
+     HB_CODEPOINT_ENCODE3 (0x30BBu, 0x3099u, 0x30BCu),   HB_CODEPOINT_ENCODE3 (0x30BDu, 0x3099u, 0x30BEu),
+     HB_CODEPOINT_ENCODE3 (0x30BFu, 0x3099u, 0x30C0u),   HB_CODEPOINT_ENCODE3 (0x30C1u, 0x3099u, 0x30C2u),
+     HB_CODEPOINT_ENCODE3 (0x30C4u, 0x3099u, 0x30C5u),   HB_CODEPOINT_ENCODE3 (0x30C6u, 0x3099u, 0x30C7u),
+     HB_CODEPOINT_ENCODE3 (0x30C8u, 0x3099u, 0x30C9u),   HB_CODEPOINT_ENCODE3 (0x30CFu, 0x3099u, 0x30D0u),
+     HB_CODEPOINT_ENCODE3 (0x30CFu, 0x309Au, 0x30D1u),   HB_CODEPOINT_ENCODE3 (0x30D2u, 0x3099u, 0x30D3u),
+     HB_CODEPOINT_ENCODE3 (0x30D2u, 0x309Au, 0x30D4u),   HB_CODEPOINT_ENCODE3 (0x30D5u, 0x3099u, 0x30D6u),
+     HB_CODEPOINT_ENCODE3 (0x30D5u, 0x309Au, 0x30D7u),   HB_CODEPOINT_ENCODE3 (0x30D8u, 0x3099u, 0x30D9u),
+     HB_CODEPOINT_ENCODE3 (0x30D8u, 0x309Au, 0x30DAu),   HB_CODEPOINT_ENCODE3 (0x30DBu, 0x3099u, 0x30DCu),
+     HB_CODEPOINT_ENCODE3 (0x30DBu, 0x309Au, 0x30DDu),   HB_CODEPOINT_ENCODE3 (0x30EFu, 0x3099u, 0x30F7u),
+     HB_CODEPOINT_ENCODE3 (0x30F0u, 0x3099u, 0x30F8u),   HB_CODEPOINT_ENCODE3 (0x30F1u, 0x3099u, 0x30F9u),
+     HB_CODEPOINT_ENCODE3 (0x30F2u, 0x3099u, 0x30FAu),   HB_CODEPOINT_ENCODE3 (0x30FDu, 0x3099u, 0x30FEu),
+     HB_CODEPOINT_ENCODE3 (0xFB49u, 0x05C1u, 0x0000u),   HB_CODEPOINT_ENCODE3 (0xFB49u, 0x05C2u, 0x0000u),
+  HB_CODEPOINT_ENCODE3 (0x11099u, 0x110BAu, 0x1109Au),HB_CODEPOINT_ENCODE3 (0x1109Bu, 0x110BAu, 0x1109Cu),
+  HB_CODEPOINT_ENCODE3 (0x110A5u, 0x110BAu, 0x110ABu),HB_CODEPOINT_ENCODE3 (0x11131u, 0x11127u, 0x1112Eu),
+  HB_CODEPOINT_ENCODE3 (0x11132u, 0x11127u, 0x1112Fu),HB_CODEPOINT_ENCODE3 (0x11347u, 0x1133Eu, 0x1134Bu),
+  HB_CODEPOINT_ENCODE3 (0x11347u, 0x11357u, 0x1134Cu),HB_CODEPOINT_ENCODE3 (0x114B9u, 0x114B0u, 0x114BCu),
+  HB_CODEPOINT_ENCODE3 (0x114B9u, 0x114BAu, 0x114BBu),HB_CODEPOINT_ENCODE3 (0x114B9u, 0x114BDu, 0x114BEu),
+  HB_CODEPOINT_ENCODE3 (0x115B8u, 0x115AFu, 0x115BAu),HB_CODEPOINT_ENCODE3 (0x115B9u, 0x115AFu, 0x115BBu),
+   HB_CODEPOINT_ENCODE3 (0x1D157u, 0x1D165u, 0x0000u), HB_CODEPOINT_ENCODE3 (0x1D158u, 0x1D165u, 0x0000u),
+   HB_CODEPOINT_ENCODE3 (0x1D15Fu, 0x1D16Eu, 0x0000u), HB_CODEPOINT_ENCODE3 (0x1D15Fu, 0x1D16Fu, 0x0000u),
+   HB_CODEPOINT_ENCODE3 (0x1D15Fu, 0x1D170u, 0x0000u), HB_CODEPOINT_ENCODE3 (0x1D15Fu, 0x1D171u, 0x0000u),
+   HB_CODEPOINT_ENCODE3 (0x1D15Fu, 0x1D172u, 0x0000u), HB_CODEPOINT_ENCODE3 (0x1D1B9u, 0x1D165u, 0x0000u),
+   HB_CODEPOINT_ENCODE3 (0x1D1BAu, 0x1D165u, 0x0000u), HB_CODEPOINT_ENCODE3 (0x1D1BBu, 0x1D16Eu, 0x0000u),
+   HB_CODEPOINT_ENCODE3 (0x1D1BBu, 0x1D16Fu, 0x0000u), HB_CODEPOINT_ENCODE3 (0x1D1BCu, 0x1D16Eu, 0x0000u),
+   HB_CODEPOINT_ENCODE3 (0x1D1BCu, 0x1D16Fu, 0x0000u),
+};
+
+#ifndef HB_OPTIMIZE_SIZE
+
+static const uint8_t
+_hb_ucd_u8[32102] =
+{
+    0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15,
+   16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 26, 26, 26, 26, 26,
+   26, 26, 26, 26, 26, 26, 27, 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, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 28,
+   29, 26, 30, 31, 32, 33, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26,
+   26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 34, 35, 35, 35, 35,
+   36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 37, 38, 39, 40,
+   41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56,
+   26, 57, 58, 59, 59, 59, 59, 59, 26, 26, 60, 59, 59, 59, 59, 59,
+   59, 59, 26, 61, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59,
+   59, 59, 59, 59, 26, 62, 59, 63, 26, 26, 26, 26, 26, 26, 26, 26,
+   26, 26, 26, 64, 26, 65, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59,
+   59, 59, 59, 59, 59, 59, 59, 59, 66, 67, 59, 59, 59, 59, 68, 59,
+   59, 59, 59, 59, 59, 59, 59, 59, 69, 70, 71, 72, 73, 74, 59, 59,
+   75, 76, 59, 59, 77, 59, 78, 79, 80, 81, 73, 82, 83, 84, 59, 59,
+   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, 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, 26, 26, 26, 26,
+   26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26,
+   26, 26, 26, 85, 26, 26, 26, 26, 26, 26, 26, 86, 87, 26, 26, 26,
+   26, 26, 26, 26, 26, 26, 26, 88, 26, 26, 26, 26, 26, 26, 26, 26,
+   26, 26, 26, 26, 26, 89, 59, 59, 59, 59, 59, 59, 26, 90, 59, 59,
+   59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59,
+   59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59,
+   59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59,
+   59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59,
+   59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59,
+   59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59,
+   59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59,
+   59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59,
+   59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59,
+   59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59,
+   59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59,
+   59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59,
+   59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59,
+   59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59,
+   59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59,
+   59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59,
+   59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59,
+   59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59,
+   59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59,
+   59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59,
+   59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59,
+   59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59,
+   59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59,
+   59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59,
+   59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59,
+   59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59,
+   59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59,
+   59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59,
+   59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59,
+   59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59,
+   59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59,
+   59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59,
+   59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59,
+   59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59,
+   59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59,
+   59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59,
+   59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59,
+   59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59,
+   59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59,
+   59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59,
+   59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59,
+   59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59,
+   59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59,
+   59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59,
+   59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59,
+   59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59,
+   59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59,
+   59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59,
+   59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59,
+   59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59,
+   59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59,
+   59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59,
+   59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59,
+   59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59,
+   59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59,
+   59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59,
+   59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59,
+   59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59,
+   59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59,
+   59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59,
+   59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59,
+   59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59,
+   59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59,
+   59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59,
+   59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59,
+   59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59,
+   59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59,
+   59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59,
+   59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59,
+   59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59,
+   59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59,
+   59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59,
+   59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59,
+   59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59,
+   59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59,
+   59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59,
+   59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59,
+   59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59,
+   59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59,
+   59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59,
+   59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59,
+   59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59,
+   59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59,
+   59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59,
+   59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59,
+   59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59,
+   59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59,
+   59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59,
+   91, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59,
+   59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59,
+   59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59,
+   59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59,
+   59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59,
+   59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59,
+   59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59,
+   59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59,
+   36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36,
+   36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36,
+   36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36,
+   36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36,
+   36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36,
+   36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36,
+   36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36,
+   36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 92,
+   36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36,
+   36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36,
+   36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36,
+   36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36,
+   36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36,
+   36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36,
+   36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36,
+   36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 93,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+   29, 21, 21, 21, 23, 21, 21, 21, 22, 18, 21, 25, 21, 17, 21, 21,
+   13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 21, 21, 25, 25, 25, 21,
+   21,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,
+    9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9, 22, 21, 18, 24, 16,
+   24,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,
+    5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5, 22, 25, 18, 25,  0,
+   29, 21, 23, 23, 23, 23, 26, 21, 24, 26,  7, 20, 25,  1, 26, 24,
+   26, 25, 15, 15, 24,  5, 21, 21, 24, 15,  7, 19, 15, 15, 15, 21,
+    9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,
+    9,  9,  9,  9,  9,  9,  9, 25,  9,  9,  9,  9,  9,  9,  9,  5,
+    5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,
+    5,  5,  5,  5,  5,  5,  5, 25,  5,  5,  5,  5,  5,  5,  5,  5,
+    9,  5,  9,  5,  9,  5,  9,  5,  9,  5,  9,  5,  9,  5,  9,  5,
+    9,  5,  9,  5,  9,  5,  9,  5,  5,  9,  5,  9,  5,  9,  5,  9,
+    5,  9,  5,  9,  5,  9,  5,  9,  5,  5,  9,  5,  9,  5,  9,  5,
+    9,  5,  9,  5,  9,  5,  9,  5,  9,  9,  5,  9,  5,  9,  5,  5,
+    5,  9,  9,  5,  9,  5,  9,  9,  5,  9,  9,  9,  5,  5,  9,  9,
+    9,  9,  5,  9,  9,  5,  9,  9,  9,  5,  5,  5,  9,  9,  5,  9,
+    9,  5,  9,  5,  9,  5,  9,  9,  5,  9,  5,  5,  9,  5,  9,  9,
+    5,  9,  9,  9,  5,  9,  5,  9,  9,  5,  5,  7,  9,  5,  5,  5,
+    7,  7,  7,  7,  9,  8,  5,  9,  8,  5,  9,  8,  5,  9,  5,  9,
+    5,  9,  5,  9,  5,  9,  5,  9,  5,  9,  5,  9,  5,  5,  9,  5,
+    5,  9,  8,  5,  9,  5,  9,  9,  9,  5,  9,  5,  9,  5,  9,  5,
+    9,  5,  9,  5,  5,  5,  5,  5,  5,  5,  9,  9,  5,  9,  9,  5,
+    5,  9,  5,  9,  9,  9,  9,  5,  9,  5,  9,  5,  9,  5,  9,  5,
+    5,  5,  5,  5,  7,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,
+    6,  6,  6,  6,  6,  6,  6,  6,  6,  6,  6,  6,  6,  6,  6,  6,
+    6,  6, 24, 24, 24, 24,  6,  6,  6,  6,  6,  6,  6,  6,  6,  6,
+    6,  6, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
+    6,  6,  6,  6,  6, 24, 24, 24, 24, 24, 24, 24,  6, 24,  6, 24,
+   24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
+   12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
+    9,  5,  9,  5,  6, 24,  9,  5,  2,  2,  6,  5,  5,  5, 21,  9,
+    2,  2,  2,  2, 24, 24,  9, 21,  9,  9,  9,  2,  9,  2,  9,  9,
+    5,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,
+    9,  9,  2,  9,  9,  9,  9,  9,  9,  9,  9,  9,  5,  5,  5,  5,
+    5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  9,
+    5,  5,  9,  9,  9,  5,  5,  5,  9,  5,  9,  5,  9,  5,  9,  5,
+    5,  5,  5,  5,  9,  5, 25,  9,  5,  9,  9,  5,  5,  9,  9,  9,
+    9,  5, 26, 12, 12, 12, 12, 12, 11, 11,  9,  5,  9,  5,  9,  5,
+    9,  9,  5,  9,  5,  9,  5,  9,  5,  9,  5,  9,  5,  9,  5,  5,
+    2,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,
+    9,  9,  9,  9,  9,  9,  9,  2,  2,  6, 21, 21, 21, 21, 21, 21,
+    5,  5,  5,  5,  5,  5,  5,  5,  5, 21, 17,  2,  2, 26, 26, 23,
+    2, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
+   12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 17, 12,
+   21, 12, 12, 21, 12, 12, 21, 12,  2,  2,  2,  2,  2,  2,  2,  2,
+    7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,
+    7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  2,  2,  2,  2,  7,
+    7,  7,  7, 21, 21,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,
+    1,  1,  1,  1,  1,  1, 25, 25, 25, 21, 21, 23, 21, 21, 26, 26,
+   12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 21,  1,  2, 21, 21,
+    6,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7, 12, 12, 12, 12, 12,
+   13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 21, 21, 21, 21,  7,  7,
+   12,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,
+    7,  7,  7,  7, 21,  7, 12, 12, 12, 12, 12, 12, 12,  1, 26, 12,
+   12, 12, 12, 12, 12,  6,  6, 12, 12, 26, 12, 12, 12, 12,  7,  7,
+   13, 13, 13, 13, 13, 13, 13, 13, 13, 13,  7,  7,  7, 26, 26,  7,
+   21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,  2,  1,
+    7, 12,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,
+   12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,  2,  2,  7,  7,  7,
+    7,  7,  7,  7,  7,  7, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
+   12,  7,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,
+   13, 13, 13, 13, 13, 13, 13, 13, 13, 13,  7,  7,  7,  7,  7,  7,
+    7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7, 12, 12, 12, 12, 12,
+   12, 12, 12, 12,  6,  6, 26, 21, 21, 21,  6,  2,  2, 12, 23, 23,
+    7,  7,  7,  7,  7,  7, 12, 12, 12, 12,  6, 12, 12, 12, 12, 12,
+   12, 12, 12, 12,  6, 12, 12, 12,  6, 12, 12, 12, 12, 12,  2,  2,
+   21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,  2,
+    7,  7,  7,  7,  7,  7,  7,  7,  7, 12, 12, 12,  2,  2, 21,  2,
+    7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  2,  2,  2,  2,  2,
+    2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,
+    7,  7,  7,  7,  7,  2,  7,  7,  7,  7,  7,  7,  7,  7,  2,  2,
+    2,  2,  2, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
+   12, 12,  1, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
+   12, 12, 12, 10,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,
+    7,  7,  7,  7,  7,  7,  7,  7,  7,  7, 12, 10, 12,  7, 10, 10,
+   10, 12, 12, 12, 12, 12, 12, 12, 12, 10, 10, 10, 10, 12, 10, 10,
+    7, 12, 12, 12, 12, 12, 12, 12,  7,  7,  7,  7,  7,  7,  7,  7,
+    7,  7, 12, 12, 21, 21, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+   21,  6,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,
+    7, 12, 10, 10,  2,  7,  7,  7,  7,  7,  7,  7,  7,  2,  2,  7,
+    7,  2,  2,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,
+    7,  7,  7,  7,  7,  7,  7,  7,  7,  2,  7,  7,  7,  7,  7,  7,
+    7,  2,  7,  2,  2,  2,  7,  7,  7,  7,  2,  2, 12,  7, 10, 10,
+   10, 12, 12, 12, 12,  2,  2, 10, 10,  2,  2, 10, 10, 12,  7,  2,
+    2,  2,  2,  2,  2,  2,  2, 10,  2,  2,  2,  2,  7,  7,  2,  7,
+    7,  7, 12, 12,  2,  2, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+    7,  7, 23, 23, 15, 15, 15, 15, 15, 15, 26, 23,  7, 21, 12,  2,
+    2, 12, 12, 10,  2,  7,  7,  7,  7,  7,  7,  2,  2,  2,  2,  7,
+    7,  2,  7,  7,  2,  7,  7,  2,  7,  7,  2,  2, 12,  2, 10, 10,
+   10, 12, 12,  2,  2,  2,  2, 12, 12,  2,  2, 12, 12, 12,  2,  2,
+    2, 12,  2,  2,  2,  2,  2,  2,  2,  7,  7,  7,  7,  2,  7,  2,
+    2,  2,  2,  2,  2,  2, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+   12, 12,  7,  7,  7, 12, 21,  2,  2,  2,  2,  2,  2,  2,  2,  2,
+    2, 12, 12, 10,  2,  7,  7,  7,  7,  7,  7,  7,  7,  7,  2,  7,
+    7,  7,  2,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,
+    7,  2,  7,  7,  2,  7,  7,  7,  7,  7,  2,  2, 12,  7, 10, 10,
+   10, 12, 12, 12, 12, 12,  2, 12, 12, 10,  2, 10, 10, 12,  2,  2,
+    7,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,
+   21, 23,  2,  2,  2,  2,  2,  2,  2,  7, 12, 12, 12, 12, 12, 12,
+    2, 12, 10, 10,  2,  7,  7,  7,  7,  7,  7,  7,  7,  2,  2,  7,
+    7,  2,  7,  7,  2,  7,  7,  7,  7,  7,  2,  2, 12,  7, 10, 12,
+   10, 12, 12, 12, 12,  2,  2, 10, 10,  2,  2, 10, 10, 12,  2,  2,
+    2,  2,  2,  2,  2,  2, 12, 10,  2,  2,  2,  2,  7,  7,  2,  7,
+   26,  7, 15, 15, 15, 15, 15, 15,  2,  2,  2,  2,  2,  2,  2,  2,
+    2,  2, 12,  7,  2,  7,  7,  7,  7,  7,  7,  2,  2,  2,  7,  7,
+    7,  2,  7,  7,  7,  7,  2,  2,  2,  7,  7,  2,  7,  2,  7,  7,
+    2,  2,  2,  7,  7,  2,  2,  2,  7,  7,  7,  2,  2,  2,  7,  7,
+    7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  2,  2,  2,  2, 10, 10,
+   12, 10, 10,  2,  2,  2, 10, 10, 10,  2, 10, 10, 10, 12,  2,  2,
+    7,  2,  2,  2,  2,  2,  2, 10,  2,  2,  2,  2,  2,  2,  2,  2,
+   15, 15, 15, 26, 26, 26, 26, 26, 26, 23, 26,  2,  2,  2,  2,  2,
+   12, 10, 10, 10, 12,  7,  7,  7,  7,  7,  7,  7,  7,  2,  7,  7,
+    7,  2,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,
+    7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  2,  2,  2,  7, 12, 12,
+   12, 10, 10, 10, 10,  2, 12, 12, 12,  2, 12, 12, 12, 12,  2,  2,
+    2,  2,  2,  2,  2, 12, 12,  2,  7,  7,  7,  2,  2,  2,  2,  2,
+    2,  2,  2,  2,  2,  2,  2, 21, 15, 15, 15, 15, 15, 15, 15, 26,
+    7, 12, 10, 10, 21,  7,  7,  7,  7,  7,  7,  7,  7,  2,  7,  7,
+    7,  7,  7,  7,  2,  7,  7,  7,  7,  7,  2,  2, 12,  7, 10, 12,
+   10, 10, 10, 10, 10,  2, 12, 10, 10,  2, 10, 10, 12, 12,  2,  2,
+    2,  2,  2,  2,  2, 10, 10,  2,  2,  2,  2,  2,  2,  2,  7,  2,
+    2,  7,  7,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,
+   12, 12, 10, 10,  2,  7,  7,  7,  7,  7,  7,  7,  7,  2,  7,  7,
+    7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7, 12, 12,  7, 10, 10,
+   10, 12, 12, 12, 12,  2, 10, 10, 10,  2, 10, 10, 10, 12,  7, 26,
+    2,  2,  2,  2,  7,  7,  7, 10, 15, 15, 15, 15, 15, 15, 15,  7,
+   15, 15, 15, 15, 15, 15, 15, 15, 15, 26,  7,  7,  7,  7,  7,  7,
+    2,  2, 10, 10,  2,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,
+    7,  7,  7,  7,  7,  7,  7,  2,  2,  2,  7,  7,  7,  7,  7,  7,
+    7,  7,  2,  7,  7,  7,  7,  7,  7,  7,  7,  7,  2,  7,  2,  2,
+    7,  7,  7,  7,  7,  7,  7,  2,  2,  2, 12,  2,  2,  2,  2, 10,
+   10, 10, 12, 12, 12,  2, 12,  2, 10, 10, 10, 10, 10, 10, 10, 10,
+    2,  2, 10, 10, 21,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,
+    2,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,
+    7, 12,  7,  7, 12, 12, 12, 12, 12, 12, 12,  2,  2,  2,  2, 23,
+    7,  7,  7,  7,  7,  7,  6, 12, 12, 12, 12, 12, 12, 12, 12, 21,
+   13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 21, 21,  2,  2,  2,  2,
+    2,  7,  7,  2,  7,  2,  7,  7,  7,  7,  7,  2,  7,  7,  7,  7,
+    7,  7,  7,  7,  2,  7,  2,  7,  7,  7,  7,  7,  7,  7,  7,  7,
+    7, 12,  7,  7, 12, 12, 12, 12, 12, 12, 12, 12, 12,  7,  2,  2,
+    7,  7,  7,  7,  7,  2,  6,  2, 12, 12, 12, 12, 12, 12,  2,  2,
+   13, 13, 13, 13, 13, 13, 13, 13, 13, 13,  2,  2,  7,  7,  7,  7,
+    7, 26, 26, 26, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
+   21, 21, 21, 26, 21, 26, 26, 26, 12, 12, 26, 26, 26, 26, 26, 26,
+   13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 15, 15, 15, 15, 15, 15,
+   15, 15, 15, 15, 26, 12, 26, 12, 26, 12, 22, 18, 22, 18, 10, 10,
+    7,  7,  7,  7,  7,  7,  7,  7,  2,  7,  7,  7,  7,  7,  7,  7,
+    7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  2,  2,  2,
+    2, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 10,
+   12, 12, 12, 12, 12, 21, 12, 12,  7,  7,  7,  7,  7, 12, 12, 12,
+   12, 12, 12, 12, 12, 12, 12, 12,  2, 12, 12, 12, 12, 12, 12, 12,
+   12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,  2, 26, 26,
+   26, 26, 26, 26, 26, 26, 12, 26, 26, 26, 26, 26, 26,  2, 26, 26,
+   21, 21, 21, 21, 21, 26, 26, 26, 26, 21, 21,  2,  2,  2,  2,  2,
+    7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7, 10, 10, 12, 12, 12,
+   12, 10, 12, 12, 12, 12, 12, 12, 10, 12, 12, 10, 10, 12, 12,  7,
+   13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 21, 21, 21, 21, 21, 21,
+    7,  7,  7,  7,  7,  7, 10, 10, 12, 12,  7,  7,  7,  7, 12, 12,
+   12,  7, 10, 10, 10,  7,  7, 10, 10, 10, 10, 10, 10, 10,  7,  7,
+    7, 12, 12, 12, 12,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,
+    7,  7, 12, 10, 10, 12, 12, 10, 10, 10, 10, 10, 10, 12,  7, 10,
+   13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 10, 10, 10, 12, 26, 26,
+    9,  9,  9,  9,  9,  9,  2,  9,  2,  2,  2,  2,  2,  9,  2,  2,
+    5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5, 21,  6,  5,  5,  5,
+    7,  7,  7,  7,  7,  7,  7,  7,  7,  2,  7,  7,  7,  7,  2,  2,
+    7,  7,  7,  7,  7,  7,  7,  2,  7,  2,  7,  7,  7,  7,  2,  2,
+    7,  2,  7,  7,  7,  7,  2,  2,  7,  7,  7,  7,  7,  7,  7,  2,
+    7,  2,  7,  7,  7,  7,  2,  2,  7,  7,  7,  7,  7,  7,  7,  7,
+    7,  7,  7,  7,  7,  7,  7,  2,  7,  7,  7,  7,  7,  7,  7,  7,
+    7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  2,  2, 12, 12, 12,
+   21, 21, 21, 21, 21, 21, 21, 21, 21, 15, 15, 15, 15, 15, 15, 15,
+   15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,  2,  2,  2,
+   26, 26, 26, 26, 26, 26, 26, 26, 26, 26,  2,  2,  2,  2,  2,  2,
+    9,  9,  9,  9,  9,  9,  2,  2,  5,  5,  5,  5,  5,  5,  2,  2,
+   17,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,
+    7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7, 26, 21,  7,
+   29,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,
+    7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7, 22, 18,  2,  2,  2,
+    7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7, 21, 21, 21, 14, 14,
+   14,  7,  7,  7,  7,  7,  7,  7,  7,  2,  2,  2,  2,  2,  2,  2,
+    7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  2,  7,  7,
+    7,  7, 12, 12, 12,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,
+    7,  7, 12, 12, 12, 21, 21,  2,  2,  2,  2,  2,  2,  2,  2,  2,
+    7,  7, 12, 12,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,
+    7,  2, 12, 12,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,
+    7,  7,  7,  7, 12, 12, 10, 12, 12, 12, 12, 12, 12, 12, 10, 10,
+   10, 10, 10, 10, 10, 10, 12, 10, 10, 12, 12, 12, 12, 12, 12, 12,
+   12, 12, 12, 12, 21, 21, 21,  6, 21, 21, 21, 23,  7, 12,  2,  2,
+   13, 13, 13, 13, 13, 13, 13, 13, 13, 13,  2,  2,  2,  2,  2,  2,
+   15, 15, 15, 15, 15, 15, 15, 15, 15, 15,  2,  2,  2,  2,  2,  2,
+   21, 21, 21, 21, 21, 21, 17, 21, 21, 21, 21, 12, 12, 12,  1,  2,
+    7,  7,  7,  6,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,
+    7,  7,  7,  7,  7,  7,  7,  7,  7,  2,  2,  2,  2,  2,  2,  2,
+    7,  7,  7,  7,  7, 12, 12,  7,  7,  7,  7,  7,  7,  7,  7,  7,
+    7,  7,  7,  7,  7,  7,  7,  7,  7, 12,  7,  2,  2,  2,  2,  2,
+    7,  7,  7,  7,  7,  7,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,
+    7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  2,
+   12, 12, 12, 10, 10, 10, 10, 12, 12, 10, 10, 10,  2,  2,  2,  2,
+   10, 10, 12, 10, 10, 10, 10, 10, 10, 12, 12, 12,  2,  2,  2,  2,
+   26,  2,  2,  2, 21, 21, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+    7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  2,  2,
+    7,  7,  7,  7,  7,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,
+    7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  2,  2,  2,  2,
+    7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  2,  2,  2,  2,  2,  2,
+   13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 15,  2,  2,  2, 26, 26,
+   26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26,
+    7,  7,  7,  7,  7,  7,  7, 12, 12, 10, 10, 12,  2,  2, 21, 21,
+    7,  7,  7,  7,  7, 10, 12, 10, 12, 12, 12, 12, 12, 12, 12,  2,
+   12, 10, 12, 10, 10, 12, 12, 12, 12, 12, 12, 12, 12, 10, 10, 10,
+   10, 10, 10, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,  2,  2, 12,
+   21, 21, 21, 21, 21, 21, 21,  6, 21, 21, 21, 21, 21, 21,  2,  2,
+   12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 11,  2,
+   12, 12, 12, 12, 10,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,
+    7,  7,  7,  7, 12, 10, 12, 12, 12, 12, 12, 10, 12, 10, 10, 10,
+   10, 10, 12, 10, 10,  7,  7,  7,  7,  7,  7,  7,  2,  2,  2,  2,
+   21, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 12, 12, 12, 12, 12,
+   12, 12, 12, 12, 26, 26, 26, 26, 26, 26, 26, 26, 26,  2,  2,  2,
+   12, 12, 10,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,
+    7, 10, 12, 12, 12, 12, 10, 10, 12, 12, 10, 12, 12, 12,  7,  7,
+    7,  7,  7,  7,  7,  7, 12, 10, 12, 12, 10, 10, 10, 12, 10, 12,
+   12, 12, 10, 10,  2,  2,  2,  2,  2,  2,  2,  2, 21, 21, 21, 21,
+    7,  7,  7,  7, 10, 10, 10, 10, 10, 10, 10, 10, 12, 12, 12, 12,
+   12, 12, 12, 12, 10, 10, 12, 12,  2,  2,  2, 21, 21, 21, 21, 21,
+   13, 13, 13, 13, 13, 13, 13, 13, 13, 13,  2,  2,  2,  7,  7,  7,
+    7,  7,  7,  7,  7,  7,  7,  7,  6,  6,  6,  6,  6,  6, 21, 21,
+    5,  5,  5,  5,  5,  5,  5,  5,  5,  2,  2,  2,  2,  2,  2,  2,
+    9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  2,  2,  9,  9,  9,
+   21, 21, 21, 21, 21, 21, 21, 21,  2,  2,  2,  2,  2,  2,  2,  2,
+   12, 12, 12, 21, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
+   12, 10, 12, 12, 12, 12, 12, 12, 12,  7,  7,  7,  7, 12,  7,  7,
+    7,  7,  7,  7, 12,  7,  7, 10, 12, 12,  7,  2,  2,  2,  2,  2,
+    5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  6,  6,  6,  6,
+    6,  6,  6,  6,  6,  6,  6,  6,  6,  6,  6,  5,  5,  5,  5,  5,
+    5,  5,  5,  5,  5,  5,  5,  5,  6,  5,  5,  5,  5,  5,  5,  5,
+    5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  6,  6,  6,  6,  6,
+   12, 12, 12, 12, 12, 12, 12, 12, 12, 12,  2, 12, 12, 12, 12, 12,
+    9,  5,  9,  5,  9,  5,  5,  5,  5,  5,  5,  5,  5,  5,  9,  5,
+    5,  5,  5,  5,  5,  5,  5,  5,  9,  9,  9,  9,  9,  9,  9,  9,
+    5,  5,  5,  5,  5,  5,  2,  2,  9,  9,  9,  9,  9,  9,  2,  2,
+    5,  5,  5,  5,  5,  5,  5,  5,  2,  9,  2,  9,  2,  9,  2,  9,
+    5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  2,  2,
+    5,  5,  5,  5,  5,  5,  5,  5,  8,  8,  8,  8,  8,  8,  8,  8,
+    5,  5,  5,  5,  5,  2,  5,  5,  9,  9,  9,  9,  8, 24,  5, 24,
+   24, 24,  5,  5,  5,  2,  5,  5,  9,  9,  9,  9,  8, 24, 24, 24,
+    5,  5,  5,  5,  2,  2,  5,  5,  9,  9,  9,  9,  2, 24, 24, 24,
+    5,  5,  5,  5,  5,  5,  5,  5,  9,  9,  9,  9,  9, 24, 24, 24,
+    2,  2,  5,  5,  5,  2,  5,  5,  9,  9,  9,  9,  8, 24, 24,  2,
+   29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29,  1,  1,  1,  1,  1,
+   17, 17, 17, 17, 17, 17, 21, 21, 20, 19, 22, 20, 20, 19, 22, 20,
+   21, 21, 21, 21, 21, 21, 21, 21, 27, 28,  1,  1,  1,  1,  1, 29,
+   21, 21, 21, 21, 21, 21, 21, 21, 21, 20, 19, 21, 21, 21, 21, 16,
+   16, 21, 21, 21, 25, 22, 18, 21, 21, 21, 21, 21, 21, 21, 21, 21,
+   21, 21, 25, 21, 16, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 29,
+    1,  1,  1,  1,  1,  2,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,
+   15,  6,  2,  2, 15, 15, 15, 15, 15, 15, 25, 25, 25, 22, 18,  6,
+   15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 25, 25, 25, 22, 18,  2,
+    6,  6,  6,  6,  6,  6,  6,  6,  6,  6,  6,  6,  6,  2,  2,  2,
+   23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23,
+   12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 11, 11, 11,
+   11, 12, 11, 11, 11, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
+   12,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,
+   26, 26,  9, 26, 26, 26, 26,  9, 26, 26,  5,  9,  9,  9,  5,  5,
+    9,  9,  9,  5, 26,  9, 26, 26, 25,  9,  9,  9,  9,  9, 26, 26,
+   26, 26, 26, 26,  9, 26,  9, 26,  9, 26,  9,  9,  9,  9, 26,  5,
+    9,  9,  9,  9,  5,  7,  7,  7,  7,  5, 26, 26,  5,  5,  9,  9,
+   25, 25, 25, 25, 25,  9,  5,  5,  5,  5, 26, 25, 26, 26,  5, 26,
+   15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+   14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+   14, 14, 14,  9,  5, 14, 14, 14, 14, 15, 26, 26,  2,  2,  2,  2,
+   25, 25, 25, 25, 25, 26, 26, 26, 26, 26, 25, 25, 26, 26, 26, 26,
+   25, 26, 26, 25, 26, 26, 25, 26, 26, 26, 26, 26, 26, 26, 25, 26,
+   26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 25, 25,
+   26, 26, 25, 26, 25, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26,
+   26, 26, 26, 26, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
+   25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
+   26, 26, 26, 26, 26, 26, 26, 26, 22, 18, 22, 18, 26, 26, 26, 26,
+   25, 25, 26, 26, 26, 26, 26, 26, 26, 22, 18, 26, 26, 26, 26, 26,
+   26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 25, 26, 26, 26,
+   26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 25, 25, 25, 25, 25,
+   25, 25, 25, 25, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26,
+   26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 25, 25, 25, 25,
+   25, 25, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26,
+   26, 26, 26, 26, 26, 26, 26,  2,  2,  2,  2,  2,  2,  2,  2,  2,
+   26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26,  2,  2,  2,  2,  2,
+   15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 26, 26, 26, 26,
+   26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 15, 15, 15, 15, 15, 15,
+   26, 26, 26, 26, 26, 26, 26, 25, 26, 26, 26, 26, 26, 26, 26, 26,
+   26, 25, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26,
+   26, 26, 26, 26, 26, 26, 26, 26, 25, 25, 25, 25, 25, 25, 25, 25,
+   26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 25,
+   26, 26, 26, 26, 26, 26, 26, 26, 22, 18, 22, 18, 22, 18, 22, 18,
+   22, 18, 22, 18, 22, 18, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+   15, 15, 15, 15, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26,
+   25, 25, 25, 25, 25, 22, 18, 25, 25, 25, 25, 25, 25, 25, 25, 25,
+   25, 25, 25, 25, 25, 25, 22, 18, 22, 18, 22, 18, 22, 18, 22, 18,
+   25, 25, 25, 22, 18, 22, 18, 22, 18, 22, 18, 22, 18, 22, 18, 22,
+   18, 22, 18, 22, 18, 22, 18, 22, 18, 25, 25, 25, 25, 25, 25, 25,
+   25, 25, 25, 25, 25, 25, 25, 25, 22, 18, 22, 18, 25, 25, 25, 25,
+   25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 22, 18, 25, 25,
+   25, 25, 25, 25, 25, 26, 26, 25, 25, 25, 25, 25, 25, 26, 26, 26,
+   26, 26, 26, 26,  2,  2, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26,
+   26, 26, 26, 26, 26, 26,  2,  2, 26, 26, 26, 26, 26, 26, 26, 26,
+    9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  2,
+    5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  2,
+    9,  5,  9,  9,  9,  5,  5,  9,  5,  9,  5,  9,  5,  9,  9,  9,
+    9,  5,  9,  5,  5,  9,  5,  5,  5,  5,  5,  5,  6,  6,  9,  9,
+    9,  5,  9,  5,  5, 26, 26, 26, 26, 26, 26,  9,  5,  9,  5, 12,
+   12, 12,  9,  5,  2,  2,  2,  2,  2, 21, 21, 21, 21, 15, 21, 21,
+    5,  5,  5,  5,  5,  5,  2,  5,  2,  2,  2,  2,  2,  5,  2,  2,
+    7,  7,  7,  7,  7,  7,  7,  7,  2,  2,  2,  2,  2,  2,  2,  6,
+   21,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2, 12,
+    7,  7,  7,  7,  7,  7,  7,  2,  2,  2,  2,  2,  2,  2,  2,  2,
+    7,  7,  7,  7,  7,  7,  7,  2,  7,  7,  7,  7,  7,  7,  7,  2,
+   21, 21, 20, 19, 20, 19, 21, 21, 21, 20, 19, 21, 20, 19, 21, 21,
+   21, 21, 21, 21, 21, 21, 21, 17, 21, 21, 17, 21, 20, 19, 21, 21,
+   20, 19, 22, 18, 22, 18, 22, 18, 22, 18, 21, 21, 21, 21, 21,  6,
+   21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 17, 17, 21, 21, 21, 21,
+   17, 21, 22, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
+   26, 26, 26, 26, 26, 26, 26, 26, 26, 26,  2, 26, 26, 26, 26, 26,
+   26, 26, 26, 26,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,
+   26, 26, 26, 26, 26, 26,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,
+   26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26,  2,  2,  2,  2,
+   29, 21, 21, 21, 26,  6,  7, 14, 22, 18, 22, 18, 22, 18, 22, 18,
+   22, 18, 26, 26, 22, 18, 22, 18, 22, 18, 22, 18, 17, 22, 18, 18,
+   26, 14, 14, 14, 14, 14, 14, 14, 14, 14, 12, 12, 12, 12, 10, 10,
+   17,  6,  6,  6,  6,  6, 26, 26, 14, 14, 14,  6,  7, 21, 26, 26,
+    7,  7,  7,  7,  7,  7,  7,  2,  2, 12, 12, 24, 24,  6,  6,  7,
+    7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7, 21,  6,  6,  6,  7,
+    2,  2,  2,  2,  2,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,
+   26, 26, 15, 15, 15, 15, 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,  2,
+   15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 26, 26, 26, 26, 26, 26,
+   26, 26, 26, 26, 26, 26, 26, 26, 15, 15, 15, 15, 15, 15, 15, 15,
+   26, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+    7,  7,  7,  7,  7,  6,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,
+    7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  6, 21, 21, 21,
+   13, 13, 13, 13, 13, 13, 13, 13, 13, 13,  7,  7,  2,  2,  2,  2,
+    9,  5,  9,  5,  9,  5,  9,  5,  9,  5,  9,  5,  9,  5,  7, 12,
+   11, 11, 11, 21, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 21,  6,
+    9,  5,  9,  5,  9,  5,  9,  5,  9,  5,  9,  5,  6,  6, 12, 12,
+    7,  7,  7,  7,  7,  7, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+   12, 12, 21, 21, 21, 21, 21, 21,  2,  2,  2,  2,  2,  2,  2,  2,
+   24, 24, 24, 24, 24, 24, 24,  6,  6,  6,  6,  6,  6,  6,  6,  6,
+   24, 24,  9,  5,  9,  5,  9,  5,  9,  5,  9,  5,  9,  5,  9,  5,
+    5,  5,  9,  5,  9,  5,  9,  5,  9,  5,  9,  5,  9,  5,  9,  5,
+    6,  5,  5,  5,  5,  5,  5,  5,  5,  9,  5,  9,  5,  9,  9,  5,
+    9,  5,  9,  5,  9,  5,  9,  5,  6, 24, 24,  9,  5,  9,  5,  7,
+    9,  5,  9,  5,  5,  5,  9,  5,  9,  5,  9,  5,  9,  5,  9,  5,
+    9,  5,  9,  5,  9,  5,  9,  5,  9,  5,  9,  9,  9,  9,  9,  5,
+    9,  9,  9,  9,  9,  5,  9,  5,  9,  5,  9,  5,  9,  5,  9,  5,
+    2,  2,  9,  5,  9,  9,  9,  2,  2,  2,  2,  2,  2,  2,  2,  2,
+    2,  2,  2,  2,  2,  2,  2,  7,  6,  6,  5,  7,  7,  7,  7,  7,
+    7,  7, 12,  7,  7,  7, 12,  7,  7,  7,  7, 12,  7,  7,  7,  7,
+    7,  7,  7, 10, 10, 12, 12, 10, 26, 26, 26, 26,  2,  2,  2,  2,
+   15, 15, 15, 15, 15, 15, 26, 26, 23, 26,  2,  2,  2,  2,  2,  2,
+    7,  7,  7,  7, 21, 21, 21, 21,  2,  2,  2,  2,  2,  2,  2,  2,
+   10, 10,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,
+    7,  7,  7,  7, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10,
+   10, 10, 10, 10, 12, 12,  2,  2,  2,  2,  2,  2,  2,  2, 21, 21,
+   12, 12,  7,  7,  7,  7,  7,  7, 21, 21, 21,  7, 21,  7,  7, 12,
+    7,  7,  7,  7,  7,  7, 12, 12, 12, 12, 12, 12, 12, 12, 21, 21,
+    7,  7,  7,  7,  7,  7,  7, 12, 12, 12, 12, 12, 12, 12, 12, 12,
+   12, 12, 10, 10,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2, 21,
+    7,  7,  7, 12, 10, 10, 12, 12, 12, 12, 10, 10, 12, 12, 10, 10,
+   10, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,  2,  6,
+   13, 13, 13, 13, 13, 13, 13, 13, 13, 13,  2,  2,  2,  2, 21, 21,
+    7,  7,  7,  7,  7, 12,  6,  7,  7,  7,  7,  7,  7,  7,  7,  7,
+   13, 13, 13, 13, 13, 13, 13, 13, 13, 13,  7,  7,  7,  7,  7,  2,
+    7,  7,  7,  7,  7,  7,  7,  7,  7, 12, 12, 12, 12, 12, 12, 10,
+   10, 12, 12, 10, 10, 12, 12,  2,  2,  2,  2,  2,  2,  2,  2,  2,
+    7,  7,  7, 12,  7,  7,  7,  7,  7,  7,  7,  7, 12, 10,  2,  2,
+   13, 13, 13, 13, 13, 13, 13, 13, 13, 13,  2,  2, 21, 21, 21, 21,
+    6,  7,  7,  7,  7,  7,  7, 26, 26, 26,  7, 10, 12, 10,  7,  7,
+   12,  7, 12, 12, 12,  7,  7, 12, 12,  7,  7,  7,  7,  7, 12, 12,
+    7, 12,  7,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,
+    2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  7,  7,  6, 21, 21,
+    7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7, 10, 12, 12, 10, 10,
+   21, 21,  7,  6,  6, 10, 12,  2,  2,  2,  2,  2,  2,  2,  2,  2,
+    2,  7,  7,  7,  7,  7,  7,  2,  2,  7,  7,  7,  7,  7,  7,  2,
+    2,  7,  7,  7,  7,  7,  7,  2,  2,  2,  2,  2,  2,  2,  2,  2,
+    5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5, 24,  6,  6,  6,  6,
+    5,  5,  5,  5,  5,  5,  5,  5,  2,  2,  2,  2,  2,  2,  2,  2,
+    7,  7,  7, 10, 10, 12, 10, 10, 12, 10, 10, 21, 10, 12,  2,  2,
+    7,  7,  7,  7,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,
+    7,  7,  7,  7,  7,  7,  7,  2,  2,  2,  2,  7,  7,  7,  7,  7,
+    4,  4,  4,  4,  4,  4,  4,  4,  4,  4,  4,  4,  4,  4,  4,  4,
+    3,  3,  3,  3,  3,  3,  3,  3,  3,  3,  3,  3,  3,  3,  3,  3,
+    5,  5,  5,  5,  5,  5,  5,  2,  2,  2,  2,  2,  2,  2,  2,  2,
+    2,  2,  2,  5,  5,  5,  5,  5,  2,  2,  2,  2,  2,  7, 12,  7,
+    7,  7,  7,  7,  7,  7,  7,  7,  7, 25,  7,  7,  7,  7,  7,  7,
+    7,  7,  7,  7,  7,  7,  7,  2,  7,  7,  7,  7,  7,  2,  7,  2,
+    7,  7,  2,  7,  7,  2,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,
+    7,  7, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
+   24, 24,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,
+    2,  2,  2,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,
+    7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7, 18, 22,
+    2,  2,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,
+    7,  7,  7,  7,  7,  7,  7,  7,  2,  2,  2,  2,  2,  2,  2,  2,
+    7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7, 23, 26,  2,  2,
+   21, 21, 21, 21, 21, 21, 21, 22, 18, 21,  2,  2,  2,  2,  2,  2,
+   21, 17, 17, 16, 16, 22, 18, 22, 18, 22, 18, 22, 18, 22, 18, 22,
+   18, 22, 18, 22, 18, 21, 21, 22, 18, 21, 21, 21, 21, 16, 16, 16,
+   21, 21, 21,  2, 21, 21, 21, 21, 17, 22, 18, 22, 18, 22, 18, 21,
+   21, 21, 25, 17, 25, 25, 25,  2, 21, 23, 21, 21,  2,  2,  2,  2,
+    7,  7,  7,  7,  7,  2,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,
+    7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  2,  2,  1,
+    2, 21, 21, 21, 23, 21, 21, 21, 22, 18, 21, 25, 21, 17, 21, 21,
+    5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5, 22, 25, 18, 25, 22,
+   18, 21, 22, 18, 21, 21,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,
+    6,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,
+    7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  6,  6,
+    2,  2,  7,  7,  7,  7,  7,  7,  2,  2,  7,  7,  7,  7,  7,  7,
+    2,  2,  7,  7,  7,  7,  7,  7,  2,  2,  7,  7,  7,  2,  2,  2,
+   23, 23, 25, 24, 26, 23, 23,  2, 26, 25, 25, 25, 25, 26, 26,  2,
+    2,  2,  2,  2,  2,  2,  2,  2,  2,  1,  1,  1, 26, 26,  2,  2,
+    7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  2,  7,  7,  7,
+    7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  2,  7,  7,  2,  7,
+   21, 21, 21,  2,  2,  2,  2, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+   15, 15, 15, 15,  2,  2,  2, 26, 26, 26, 26, 26, 26, 26, 26, 26,
+   14, 14, 14, 14, 14, 15, 15, 15, 15, 26, 26, 26, 26, 26, 26, 26,
+   26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 15, 15, 26, 26, 26,  2,
+   26,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,
+   26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 12,  2,  2,
+   12, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+   15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,  2,  2,  2,  2,
+   15, 15, 15, 15,  2,  2,  2,  2,  2,  2,  2,  2,  2,  7,  7,  7,
+    7, 14,  7,  7,  7,  7,  7,  7,  7,  7, 14,  2,  2,  2,  2,  2,
+    7,  7,  7,  7,  7,  7, 12, 12, 12, 12, 12,  2,  2,  2,  2,  2,
+    7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  2, 21,
+    7,  7,  7,  7,  2,  2,  2,  2,  7,  7,  7,  7,  7,  7,  7,  7,
+   21, 14, 14, 14, 14, 14,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,
+    9,  9,  9,  9,  9,  9,  9,  9,  5,  5,  5,  5,  5,  5,  5,  5,
+    9,  9,  9,  9,  2,  2,  2,  2,  5,  5,  5,  5,  5,  5,  5,  5,
+    5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  2,  2,  2,  2,
+    7,  7,  7,  7,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2, 21,
+    7,  7,  7,  7,  7,  7,  2,  2,  7,  2,  7,  7,  7,  7,  7,  7,
+    7,  7,  7,  7,  7,  7,  2,  7,  7,  2,  2,  2,  7,  2,  2,  7,
+    7,  7,  7,  7,  7,  7,  2, 21, 15, 15, 15, 15, 15, 15, 15, 15,
+    7,  7,  7,  7,  7,  7,  7, 26, 26, 15, 15, 15, 15, 15, 15, 15,
+    2,  2,  2,  2,  2,  2,  2, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+    7,  7,  7,  2,  7,  7,  2,  2,  2,  2,  2, 15, 15, 15, 15, 15,
+    7,  7,  7,  7,  7,  7, 15, 15, 15, 15, 15, 15,  2,  2,  2, 21,
+    7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  2,  2,  2,  2,  2, 21,
+    7,  7,  7,  7,  7,  7,  7,  7,  2,  2,  2,  2, 15, 15,  7,  7,
+    2,  2, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+    7, 12, 12, 12,  2, 12, 12,  2,  2,  2,  2,  2, 12, 12, 12, 12,
+    7,  7,  7,  7,  2,  7,  7,  7,  2,  7,  7,  7,  7,  7,  7,  7,
+    7,  7,  7,  7,  7,  7,  2,  2, 12, 12, 12,  2,  2,  2,  2, 12,
+   15, 15, 15, 15, 15, 15, 15, 15, 15,  2,  2,  2,  2,  2,  2,  2,
+   21, 21, 21, 21, 21, 21, 21, 21, 21,  2,  2,  2,  2,  2,  2,  2,
+    7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7, 15, 15, 21,
+    7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7, 15, 15, 15,
+    7,  7,  7,  7,  7,  7,  7,  7, 26,  7,  7,  7,  7,  7,  7,  7,
+    7,  7,  7,  7,  7, 12, 12,  2,  2,  2,  2, 15, 15, 15, 15, 15,
+   21, 21, 21, 21, 21, 21, 21,  2,  2,  2,  2,  2,  2,  2,  2,  2,
+    7,  7,  7,  7,  7,  7,  2,  2,  2, 21, 21, 21, 21, 21, 21, 21,
+    7,  7,  7,  7,  7,  7,  2,  2, 15, 15, 15, 15, 15, 15, 15, 15,
+    7,  7,  7,  2,  2,  2,  2,  2, 15, 15, 15, 15, 15, 15, 15, 15,
+    7,  7,  2,  2,  2,  2,  2,  2,  2, 21, 21, 21, 21,  2,  2,  2,
+    2,  2,  2,  2,  2,  2,  2,  2,  2, 15, 15, 15, 15, 15, 15, 15,
+    9,  9,  9,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,
+    5,  5,  5,  2,  2,  2,  2,  2,  2,  2, 15, 15, 15, 15, 15, 15,
+    7,  7,  7,  7, 12, 12, 12, 12,  2,  2,  2,  2,  2,  2,  2,  2,
+   15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,  2,
+   15, 15, 15, 15, 15, 15, 15,  7,  2,  2,  2,  2,  2,  2,  2,  2,
+   12, 15, 15, 15, 15, 21, 21, 21, 21, 21,  2,  2,  2,  2,  2,  2,
+   10, 12, 10,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,
+    7,  7,  7,  7,  7,  7,  7,  7, 12, 12, 12, 12, 12, 12, 12, 12,
+   12, 12, 12, 12, 12, 12, 12, 21, 21, 21, 21, 21, 21, 21,  2,  2,
+   15, 15, 15, 15, 15, 15, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+    2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2, 12,
+   10, 10, 10, 12, 12, 12, 12, 10, 10, 12, 12, 21, 21,  1, 21, 21,
+   21, 21,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  1,  2,  2,
+   12, 12, 12,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,
+    7,  7,  7,  7,  7,  7,  7, 12, 12, 12, 12, 12, 10, 12, 12, 12,
+   12, 12, 12, 12, 12,  2, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+   21, 21, 21, 21,  7, 10, 10,  2,  2,  2,  2,  2,  2,  2,  2,  2,
+    7,  7,  7, 12, 21, 21,  7,  2,  2,  2,  2,  2,  2,  2,  2,  2,
+    7,  7,  7, 10, 10, 10, 12, 12, 12, 12, 12, 12, 12, 12, 12, 10,
+   10,  7,  7,  7,  7, 21, 21, 21, 21, 12, 12, 12, 12, 21,  2,  2,
+   13, 13, 13, 13, 13, 13, 13, 13, 13, 13,  7, 21,  7, 21, 21, 21,
+    2, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+   15, 15, 15, 15, 15,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,
+    7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7, 10, 10, 10, 12,
+   12, 12, 10, 10, 12, 10, 12, 12, 21, 21, 21, 21, 21, 21, 12,  2,
+    7,  7,  7,  7,  7,  7,  7,  2,  7,  2,  7,  7,  7,  7,  2,  7,
+    7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  2,  7,
+    7,  7,  7,  7,  7,  7,  7,  7,  7, 21,  2,  2,  2,  2,  2,  2,
+    7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7, 12,
+   10, 10, 10, 12, 12, 12, 12, 12, 12, 12, 12,  2,  2,  2,  2,  2,
+   12, 12, 10, 10,  2,  7,  7,  7,  7,  7,  7,  7,  7,  2,  2,  7,
+    7,  2,  7,  7,  2,  7,  7,  7,  7,  7,  2, 12, 12,  7, 10, 10,
+   12, 10, 10, 10, 10,  2,  2, 10, 10,  2,  2, 10, 10, 10,  2,  2,
+    7,  2,  2,  2,  2,  2,  2, 10,  2,  2,  2,  2,  2,  7,  7,  7,
+    7,  7, 10, 10,  2,  2, 12, 12, 12, 12, 12, 12, 12,  2,  2,  2,
+   12, 12, 12, 12, 12,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,
+    7,  7,  7,  7,  7, 10, 10, 10, 12, 12, 12, 12, 12, 12, 12, 12,
+   10, 10, 12, 12, 12, 10, 12,  7,  7,  7,  7, 21, 21, 21, 21, 21,
+   13, 13, 13, 13, 13, 13, 13, 13, 13, 13,  2, 21,  2, 21, 12,  7,
+   10, 10, 10, 12, 12, 12, 12, 12, 12, 10, 12, 10, 10, 10, 10, 12,
+   12, 10, 12, 12,  7,  7, 21,  7,  2,  2,  2,  2,  2,  2,  2,  2,
+    7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7, 10,
+   10, 10, 12, 12, 12, 12,  2,  2, 10, 10, 10, 10, 12, 12, 10, 12,
+   12, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
+   21, 21, 21, 21, 21, 21, 21, 21,  7,  7,  7,  7, 12, 12,  2,  2,
+   10, 10, 10, 12, 12, 12, 12, 12, 12, 12, 12, 10, 10, 12, 10, 12,
+   12, 21, 21, 21,  7,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,
+   21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,  2,  2,  2,
+    7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7, 12, 10, 12, 10, 10,
+   12, 12, 12, 12, 12, 12, 10, 12,  7,  2,  2,  2,  2,  2,  2,  2,
+   10, 10, 12, 12, 12, 12, 10, 12, 12, 12, 12, 12,  2,  2,  2,  2,
+   13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 15, 15, 21, 21, 21, 26,
+   12, 12, 12, 12, 12, 12, 12, 12, 10, 12, 12, 21,  2,  2,  2,  2,
+   15, 15, 15,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  7,
+    7,  7,  7,  7,  7,  7,  7,  7,  2,  2,  7,  7,  7,  7,  7,  7,
+    7, 10, 10, 10, 12, 12, 12, 12,  2,  2, 12, 12, 10, 10, 10, 10,
+   12,  7, 21,  7, 10,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,
+    7, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,  7,  7,  7,  7,  7,
+    7,  7,  7, 12, 12, 12, 12, 12, 12, 10,  7, 12, 12, 12, 12, 21,
+   21, 21, 21, 21, 21, 21, 21, 12,  2,  2,  2,  2,  2,  2,  2,  2,
+    7, 12, 12, 12, 12, 12, 12, 10, 10, 12, 12, 12,  7,  7,  7,  7,
+    7,  7,  7,  7,  7,  7,  7,  7,  7,  7, 12, 12, 12, 12, 12, 12,
+   12, 12, 12, 12, 12, 12, 12, 10, 12, 12, 21, 21, 21,  7, 21, 21,
+   21, 21, 21,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,
+   12, 12, 12, 12, 12, 12, 12,  2, 12, 12, 12, 12, 12, 12, 10, 12,
+    7, 21, 21, 21, 21, 21,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,
+   21, 21,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,
+    2,  2, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
+   12, 12, 12, 12, 12, 12, 12, 12,  2, 10, 12, 12, 12, 12, 12, 12,
+   12, 10, 12, 12, 10, 12, 12,  2,  2,  2,  2,  2,  2,  2,  2,  2,
+    7,  7,  7,  7,  7,  7,  7,  2,  7,  7,  2,  7,  7,  7,  7,  7,
+    7, 12, 12, 12, 12, 12, 12,  2,  2,  2, 12,  2, 12, 12,  2, 12,
+   12, 12, 12, 12, 12, 12,  7, 12,  2,  2,  2,  2,  2,  2,  2,  2,
+    7,  7,  7,  7,  7,  7,  2,  7,  7,  2,  7,  7,  7,  7,  7,  7,
+    7,  7,  7,  7,  7,  7,  7,  7,  7,  7, 10, 10, 10, 10, 10,  2,
+   12, 12,  2, 10, 10, 12, 10, 12,  7,  2,  2,  2,  2,  2,  2,  2,
+    7,  7,  7, 12, 12, 10, 10, 21, 21,  2,  2,  2,  2,  2,  2,  2,
+   15, 15, 15, 15, 15, 26, 26, 26, 26, 26, 26, 26, 26, 23, 23, 23,
+   23, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26,
+   26, 26,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2, 21,
+   14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,  2,
+   21, 21, 21, 21, 21,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,
+    1,  1,  1,  1,  1,  1,  1,  1,  1,  2,  2,  2,  2,  2,  2,  2,
+   12, 12, 12, 12, 12, 21,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,
+   12, 12, 12, 12, 12, 12, 12, 21, 21, 21, 21, 21, 26, 26, 26, 26,
+    6,  6,  6,  6, 21, 26,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,
+   13, 13, 13, 13, 13, 13, 13, 13, 13, 13,  2, 15, 15, 15, 15, 15,
+   15, 15,  2,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,
+    7,  7,  7,  7,  7,  7,  7,  7,  2,  2,  2,  2,  2,  7,  7,  7,
+   15, 15, 15, 15, 15, 15, 15, 21, 21, 21, 21,  2,  2,  2,  2,  2,
+    7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  2,  2,  2,  2, 12,
+    7, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10,
+   10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10,
+   10, 10, 10, 10, 10, 10, 10, 10,  2,  2,  2,  2,  2,  2,  2, 12,
+   12, 12, 12,  6,  6,  6,  6,  6,  6,  6,  6,  6,  6,  6,  6,  6,
+    6,  6, 21,  6,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,
+    7,  7,  7,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,
+    2,  2,  2,  2,  7,  7,  7,  7,  2,  2,  2,  2,  2,  2,  2,  2,
+    7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  2,  2, 26, 12, 12, 21,
+    1,  1,  1,  1,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,
+   26, 26, 26, 26, 26, 26, 26,  2,  2, 26, 26, 26, 26, 26, 26, 26,
+   26, 26, 26, 26, 26, 10, 10, 12, 12, 12, 26, 26, 26, 10, 10, 10,
+   10, 10, 10,  1,  1,  1,  1,  1,  1,  1,  1, 12, 12, 12, 12, 12,
+   12, 12, 12, 26, 26, 12, 12, 12, 12, 12, 12, 12, 26, 26, 26, 26,
+   26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 12, 12, 12, 12, 26, 26,
+   26, 26, 26, 26, 26, 26, 26, 26, 26,  2,  2,  2,  2,  2,  2,  2,
+   26, 26, 12, 12, 12, 26,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,
+   15, 15, 15, 15,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,
+    9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  5,  5,  5,  5,  5,  5,
+    5,  5,  5,  5,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,
+    9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  5,  5,
+    5,  5,  5,  5,  5,  2,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,
+    9,  9,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,
+    5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  9,  2,  9,  9,
+    2,  2,  9,  2,  2,  9,  9,  2,  2,  9,  9,  9,  9,  2,  9,  9,
+    9,  9,  9,  9,  9,  9,  5,  5,  5,  5,  2,  5,  2,  5,  5,  5,
+    5,  5,  5,  5,  2,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,
+    5,  5,  5,  5,  9,  9,  2,  9,  9,  9,  9,  2,  2,  9,  9,  9,
+    9,  9,  9,  9,  9,  2,  9,  9,  9,  9,  9,  9,  9,  2,  5,  5,
+    5,  5,  5,  5,  5,  5,  5,  5,  9,  9,  2,  9,  9,  9,  9,  2,
+    9,  9,  9,  9,  9,  2,  9,  2,  2,  2,  9,  9,  9,  9,  9,  9,
+    9,  2,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,
+    5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  9,  9,  9,  9,
+    9,  9,  9,  9,  9,  9,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,
+    5,  5,  5,  5,  5,  5,  2,  2,  9,  9,  9,  9,  9,  9,  9,  9,
+    9, 25,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,
+    5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5, 25,  5,  5,  5,  5,
+    5,  5,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,
+    9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9, 25,  5,  5,  5,  5,
+    5,  5,  5,  5,  5, 25,  5,  5,  5,  5,  5,  5,  9,  9,  9,  9,
+    9,  9,  9,  9,  9, 25,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,
+    5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5, 25,
+    5,  5,  5,  5,  5,  5,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,
+    9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9, 25,
+    5,  5,  5,  5,  5,  5,  5,  5,  5, 25,  5,  5,  5,  5,  5,  5,
+    9,  9,  9,  9,  9,  9,  9,  9,  9, 25,  5,  5,  5,  5,  5,  5,
+    5,  5,  5, 25,  5,  5,  5,  5,  5,  5,  9,  5,  2,  2, 13, 13,
+   13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+   12, 12, 12, 12, 12, 12, 12, 26, 26, 26, 26, 12, 12, 12, 12, 12,
+   12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 26, 26, 26,
+   26, 26, 26, 26, 26, 12, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26,
+   26, 26, 26, 26, 12, 26, 26, 21, 21, 21, 21, 21,  2,  2,  2,  2,
+    2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2, 12, 12, 12, 12, 12,
+   12, 12, 12, 12, 12, 12, 12,  2, 12, 12, 12, 12, 12, 12, 12, 12,
+   12, 12, 12, 12, 12, 12, 12, 12, 12,  2,  2, 12, 12, 12, 12, 12,
+   12, 12,  2, 12, 12,  2, 12, 12, 12, 12, 12,  2,  2,  2,  2,  2,
+   12, 12, 12, 12, 12, 12, 12,  6,  6,  6,  6,  6,  6,  6,  2,  2,
+   13, 13, 13, 13, 13, 13, 13, 13, 13, 13,  2,  2,  2,  2,  7, 26,
+    7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7, 12, 12, 12, 12,
+   13, 13, 13, 13, 13, 13, 13, 13, 13, 13,  2,  2,  2,  2,  2, 23,
+    7,  7,  7,  7,  7,  2,  2, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+   12, 12, 12, 12, 12, 12, 12,  2,  2,  2,  2,  2,  2,  2,  2,  2,
+    5,  5,  5,  5, 12, 12, 12, 12, 12, 12, 12,  6,  2,  2,  2,  2,
+   15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 26, 15, 15, 15,
+   23, 15, 15, 15, 15,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,
+   15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 26, 15,
+   15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,  2,  2,
+    7,  7,  7,  7,  2,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,
+    2,  7,  7,  2,  7,  2,  2,  7,  2,  7,  7,  7,  7,  7,  7,  7,
+    7,  7,  7,  2,  7,  7,  7,  7,  2,  7,  2,  7,  2,  2,  2,  2,
+    2,  2,  7,  2,  2,  2,  2,  7,  2,  7,  2,  7,  2,  7,  7,  7,
+    2,  7,  7,  2,  7,  2,  2,  7,  2,  7,  2,  7,  2,  7,  2,  7,
+    2,  7,  7,  2,  7,  2,  2,  7,  7,  7,  7,  2,  7,  7,  7,  7,
+    7,  7,  7,  2,  7,  7,  7,  7,  2,  7,  7,  7,  7,  2,  7,  2,
+    7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  2,  7,  7,  7,  7,  7,
+    2,  7,  7,  7,  2,  7,  7,  7,  7,  7,  2,  7,  7,  7,  7,  7,
+   25, 25,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,
+    2, 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,  2,  2,  2,
+    2,  2,  2,  2,  2,  2, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26,
+   26, 26, 26,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,
+   26, 26,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,
+   26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 24, 24, 24, 24, 24,
+   26, 26, 26, 26, 26, 26, 26, 26,  2,  2,  2,  2,  2,  2,  2,  2,
+   26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26,  2,  2,
+   26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26,  2, 26, 26, 26,
+   26, 26,  2, 26, 26, 26, 26,  2,  2,  2, 26, 26, 26, 26, 26, 26,
+   26, 26, 26,  2,  2, 26, 26, 26, 26, 26, 26,  2,  2,  2, 26, 26,
+   26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26,  2,  2, 26, 26, 26,
+   26, 26, 26, 26,  2,  2,  2,  2, 26, 26, 26,  2,  2,  2,  2,  2,
+    7,  7,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,
+    2,  1,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,
+    1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,
+    3,  3,  3,  3,  3,  3,  3,  3,  3,  3,  3,  3,  3,  3,  2,  2,
+    3,  3,  3,  3,  3,  3,  3,  3,  3,  3,  3,  3,  3,  3,  0,  0,
+    0,  0,  0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13,
+   14,  0,  0, 15,  0,  0,  0, 16, 17, 18, 19, 20, 21, 22,  0,  0,
+   23,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 24, 25,  0,  0,
+   26,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0, 27,  0, 28, 29, 30, 31,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 32,  0,  0, 33,  0,
+    0, 34, 35, 36,  0,  0,  0,  0,  0,  0, 37,  0,  0, 38,  0, 39,
+   40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50,  0, 51, 52,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 53, 54,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 55,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0, 56, 57,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+   58, 54, 59,  0,  0,  0,  0,  0, 60, 61,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  2,  3,  4,  5,  6,
+    7,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  8,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  9, 10, 11, 12,  0,  0,  0,  0, 13,  0,  0, 14, 15,
+    0, 16,  0,  0,  0,  0,  0, 17, 18,  0,  0, 19,  0, 20, 21,  0,
+    0,  0,  0,  0,  0,  0,  0,  0, 22, 23,  0, 24, 25,  0,  0, 26,
+    0,  0,  0,  0,  0,  0,  0, 27, 28, 29,  0,  0,  0, 30, 31, 32,
+    0,  0,  0,  0,  0, 30, 31,  0,  0, 33,  0,  0,  0, 30, 31,  0,
+    0,  0,  0,  0,  0, 30, 31,  0,  0,  0,  0,  0,  0, 30, 31,  0,
+    0,  0,  0,  0,  0,  0, 31,  0,  0,  0,  0,  0,  0,  0, 31, 34,
+    0,  0,  0,  0,  0, 30, 31,  0,  0,  0,  0,  0,  0, 35, 31,  0,
+    0,  0,  0,  0,  0,  0, 36,  0,  0,  0,  0,  0,  0, 37, 38,  0,
+    0,  0,  0,  0,  0, 39, 40,  0,  0,  0,  0, 41,  0, 42,  0,  0,
+    0, 43, 44,  0,  0,  0, 45,  0,  0,  0,  0,  0,  0, 46,  0,  0,
+    0,  0, 47,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 48,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 49,  0, 49,  0,  0,
+    0,  0,  0,  0,  0,  0,  0, 50,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0, 51,  0,  0,  0,  0,  0,  0,  0,  0, 52,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 53,  0,  0,  0,  0,
+   54, 55,  0,  0,  0, 56,  0,  0,  0,  0,  0,  0,  0, 57, 49,  0,
+   58, 59,  0,  0, 60,  0,  0,  0, 61, 62,  0,  0,  0, 63,  0,  0,
+    0,  0,  0,  0,  0,  0,  0, 64, 65, 66,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0, 67, 68,  1, 69,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0, 70, 71, 72,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0, 73, 74,  0,  0,  0,  0,  0,  0,
+    0, 75,  0,  0,  0,  0,  0,  0,  1,  1,  0,  0, 76,  0,  0,  0,
+    0,  0,  0, 77,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+   73, 78,  0, 79,  0,  0,  0,  0,  0, 74, 80,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0, 49,  0,  1, 74,  0,  0, 81,  0,  0, 82,
+    0,  0,  0,  0,  0, 83, 54,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0, 84, 85,  0,  0, 80,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0, 31,  0,  0, 86,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 87,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0, 47,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0, 88,  0,  0,  0,  0,  0,  0,  0,
+    0, 89,  0,  0,  0,  0,  0,  0,  0,  0, 90,  0,  0, 91,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0, 92,  0,  0,  0, 93,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 94, 88,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 80,  0,
+    0, 75,  0,  0,  0, 95,  0,  0,  0,  0, 96,  0,  0, 97,  0,  0,
+    0, 83,  0,  0,  0,  0, 98,  0,  0,  0,  0,  0,  0, 99,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,100,  0,  0,  0,  0,101, 31,  0,
+  102,103,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,104, 33,
+    0,  0,  0,  0,  0,  0,105,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0, 75,106,  0,  0,  0,  0,  0,  0, 75,  0,  0,
+    0,  0,  0,  0,  0,107,  0,  0,  0,  0,  0,  0,108,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 95,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0, 54,  0,  0,  0,  0, 49,109,  0,
+    0,  0,  0,110,  0,  0,  0,  0,  0,  0,  0,  0,  0, 75,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,111,  0,
+    0,  0,  0,109,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,112,  0,  0,  0,113,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,114,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+  115,116,117,  0,118,  0,  0,  0,  0,  0,  0,  0,  0,  0,119,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,120,121,122,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,123,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,124,  0,  0,  0,  0,  0,  0,125,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,230,230,230,230,230,230,
+  230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,232,
+  220,220,220,220,232,216,220,220,220,220,220,202,202,220,220,220,
+  220,202,202,220,220,220,220,220,220,220,220,220,220,220,  1,  1,
+    1,  1,  1,220,220,220,220,230,230,230,230,230,230,230,230,240,
+  230,220,220,220,230,230,230,220,220,  0,230,230,230,220,220,220,
+  220,230,232,220,220,230,233,234,234,233,234,234,233,230,230,230,
+  230,230,230,230,230,230,230,230,230,230,  0,  0,  0,230,230,230,
+  230,230,  0,  0,  0,  0,  0,  0,  0,  0,  0,220,230,230,230,230,
+  220,230,230,230,222,220,230,230,230,230,230,230,220,220,220,220,
+  220,220,230,230,220,230,230,222,228,230, 10, 11, 12, 13, 14, 15,
+   16, 17, 18, 19, 19, 20, 21, 22,  0, 23,  0, 24, 25,  0,230,220,
+    0, 18,  0,  0,  0,  0,  0,  0,  0,  0,230,230,230,230,230,230,
+  230,230, 30, 31, 32,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0, 27, 28, 29, 30, 31, 32, 33, 34,230,230,220,
+  220,230,230,230,230,230,220,230,230,220, 35,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+  230,230,230,230,230,230,230,  0,  0,230,230,230,230,220,230,  0,
+    0,230,230,  0,220,230,230,220,  0,  0,  0, 36,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,230,220,230,230,220,230,
+  230,220,220,220,230,220,220,230,220,230,230,230,220,230,220,230,
+  220,230,220,230,230,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,230,230,230,230,230,230,230,220,230,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,220,  0,  0,  0,  0,  0,  0,  0,  0,
+  230,230,230,230,  0,230,230,230,230,230,230,230,230,230,  0,230,
+  230,230,  0,230,230,230,230,230,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,220,220,220,  0,  0,  0,  0,  0,  0,  0,220,230,230,
+  230,230,230,230,230,230,230,230,230,230,230,230,  0,220,230,230,
+  220,230,230,220,230,230,230,220,220,220, 27, 28, 29,230,230,230,
+  220,230,230,220,220,230,230,230,230,230,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  7,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  9,  0,  0,  0,230,220,230,230,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,230,  0,  0,  0,  0,  0,  0, 84,
+   91,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  9,  9,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  9,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,103,103,  9,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,107,107,107,107,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,118,118,  9,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,122,122,122,122,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,220,220,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,220,
+    0,220,  0,216,  0,  0,  0,  0,  0,  0,  0,129,130,  0,132,  0,
+    0,  0,  0,  0,130,130,130,130,  0,  0,130,  0,230,230,  9,  0,
+  230,230,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+  220,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  7,  0,  9,  9,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,220,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,230,230,230,  0,  0,  0,  0,  9,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  9,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,230,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,228,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,222,230,220,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,230,220,  0,  0,  0,  0,  0,  0,  0,  9,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,230,
+  230,230,230,230,230,230,230,  0,  0,220,230,230,230,230,230,220,
+  220,220,220,220,220,230,230,220,  0,  0,  0,  0,  0,  0,  7,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,230,220,230,230,230,230,230,230,230,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  9,  9,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    7,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  9,  9,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  7,  0,  0,  0,  0,  0,  0,  0,  0,230,230,230,  0,  1,220,
+  220,220,220,220,230,230,220,220,220,220,230,  0,  1,  1,  1,  1,
+    1,  1,  1,  0,  0,  0,  0,220,  0,  0,  0,  0,  0,  0,230,  0,
+    0,  0,230,230,  0,  0,  0,  0,  0,  0,230,230,220,230,230,230,
+  230,230,230,230,220,230,230,234,214,220,202,230,230,230,230,230,
+  230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,
+  232,228,228,220,  0,230,233,220,230,220,230,230,  1,  1,230,230,
+  230,230,  1,  1,  1,230,230,  0,  0,  0,  0,230,  0,  0,  0,  1,
+    1,230,220,230,  1,  1,220,220,220,220,230,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,230,230,230,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  9,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,218,228,232,222,224,224,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  8,  8,  0,  0,  0,  0,  0,  0,  0,  0,  0,230,230,
+  230,230,230,230,230,230,230,230,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,230,230,  0,  0,  0,  0,  0,  0,
+    9,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,220,220,220,  0,  0,  0,  0,  0,  9,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  7,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,230,  0,230,230,220,  0,
+    0,230,230,  0,  0,  0,  0,  0,230,230,  0,230,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0, 26,  0,230,230,230,230,230,230,
+  230,220,220,220,220,220,220,220,230,230,220,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+  230,230,230,230,230,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,220,  0,230,  0,  0,  0,  0,  0,  0,
+    0,  0,230,  1,220,  0,  0,  0,  0,  9,  0,  0,  0,  0,  0,230,
+  220,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,230,230,
+  230,230,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+  220,220,230,230,230,220,230,220,220,220,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  9,  7,  0,  0,  0,  0,  0,230,230,230,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  9,  9,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  9,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  7,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  9,
+    7,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  7,  9,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  7,  7,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+  230,230,230,230,230,230,230,  0,  0,  0,230,230,230,230,230,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  9,  0,  0,  0,
+    7,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  9,  7,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  7,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    9,  7,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  9,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  9,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  9,  0,  0,  0,  0,  0,  0,  0,  0,  7,  0,  9,  9,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  1,  1,  1,  1,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,230,230,230,230,230,230,
+  230,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  1,  0,  0,  0,  0,  0,  0,216,
+  216,  1,  1,  1,  0,  0,  0,226,216,216,216,216,216,  0,  0,  0,
+    0,  0,  0,  0,  0,220,220,220,220,220,220,220,220,  0,  0,230,
+  230,230,230,230,220,220,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,230,230,230,230,  0,  0,  0,  0,230,230,230,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,230,230,230,230,230,230,
+  230,  0,230,230,230,230,230,230,230,230,230,230,230,230,230,230,
+  230,230,230,  0,  0,230,230,230,230,230,230,230,  0,230,230,  0,
+  230,230,230,230,230,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,230,230,230,230,220,220,220,220,220,220,
+  220,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,230,230,
+  230,230,230,230,  7,  0,  0,  0,  0,  0, 16, 17, 17, 17, 17, 17,
+   17, 33, 17, 17, 17, 19, 17, 17, 17, 17, 20,101, 17,113,129,169,
+   17, 27, 28, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+   17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+   17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+   17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+   17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+   17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+   17, 17, 17, 17, 17, 17, 17, 17, 17,237,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  1,  0,  0,  0,  0,  2,  0,  0,  0,  0,  0,  0,
+    3,  4,  0,  0,  0,  0,  0,  0,  3,  4,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  5,  0,  0,  0,  6,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  7,  1,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    8,  9,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0, 10,  0,  0, 10,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0, 10,  0,  0,  0, 10,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 11, 12,  0, 13,
+    0, 14, 15, 16,  0,  0,  0,  0,  0,  1, 17, 18,  0, 19,  7,  1,
+    0,  0,  0, 20, 20,  7, 20, 20, 20, 20, 20, 20, 20,  8, 21,  0,
+   22,  0,  7, 23, 24,  0, 20, 20, 25,  0,  0,  0, 26, 27,  1,  7,
+   20, 20, 20, 20, 20,  1, 28, 29, 30, 31,  0,  0, 20,  0,  0,  0,
+    0,  0,  0,  0, 10,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0, 20, 20, 20,  1,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  8, 21, 32,  4,  0, 10,
+    0, 33,  7, 20, 20, 20,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  8, 34, 34, 35, 36, 34,
+   37,  0, 38,  1, 20, 20,  0,  0, 39,  0,  1,  1,  0,  8, 21,  1,
+   20,  0,  0,  0,  1,  0,  0, 40,  1,  1,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  8, 21,  0,  1,  0,  1,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  1,  0,  0,  0,  0, 26, 34, 34, 34, 34, 34, 34, 34,
+   34, 34, 21,  7, 20, 41, 34, 34, 34, 34, 34, 34, 34, 34, 34, 21,
+    0, 42, 43, 44,  0, 45,  0,  8, 21,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0, 46,  7,  1, 10,  1,  0,  0,
+    0,  1, 20, 20,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 20, 20,  1, 20,
+   20,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+   26, 21,  0,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  0,  0,  0,
+    0,  2,  0,  0,  0,  0,  0,  0,  3,  4,  0,  0,  0,  0,  0,  0,
+    3, 47, 48,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  1,  0,  0,  0,  0,  2,  0,  0,  0,  0,  0,  0,
+    3,  4,  0,  0,  0,  0,  0,  0,  3,  4,  0,  1,  2,  3,  4,  5,
+    6,  7,  8,  9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 17, 19, 20,
+   21, 22, 23, 24, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
+   26, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
+   25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
+   25, 25, 25, 25, 25, 25, 25, 25, 25, 27, 28, 28, 29, 30, 31, 32,
+   33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33,
+   33, 33, 33, 33, 33, 34, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35,
+   35, 35, 35, 35, 35, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45,
+   46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 35, 35, 35,
+   35, 35, 59, 59, 60, 35, 35, 35, 35, 35, 35, 35, 61, 62, 35, 35,
+   35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 63, 64,
+   35, 65, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 67, 66, 68,
+   35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35,
+   35, 35, 69, 70, 35, 35, 35, 35, 71, 35, 35, 35, 35, 35, 35, 35,
+   35, 35, 72, 73, 74, 75, 76, 77, 35, 35, 78, 79, 35, 35, 80, 35,
+   81, 82, 83, 84, 17, 85, 86, 87, 35, 35, 25, 25, 25, 25, 25, 25,
+   25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
+   25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
+   25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
+   25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
+   25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 88, 25, 25,
+   25, 25, 25, 25, 25, 89, 90, 25, 25, 25, 25, 25, 25, 25, 25, 25,
+   25, 91, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 92,
+   35, 35, 35, 35, 35, 35, 25, 93, 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, 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, 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, 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,
+   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, 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, 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, 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, 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, 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, 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, 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,
+   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, 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, 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, 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, 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, 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, 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, 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,
+   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, 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, 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, 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, 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, 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, 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, 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,
+   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, 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, 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, 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, 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, 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, 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, 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,
+   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, 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, 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, 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, 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, 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, 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, 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,
+   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, 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, 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, 94,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 19, 19, 19,
+   19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
+   19, 19, 19, 19, 19, 19, 19,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0, 19,  0,  0,  0,  0,  0, 19, 19, 19, 19,
+   19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
+   19, 19, 19,  0, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
+   19, 19, 19, 19, 19,  0,  0,  0,  0,  0,  0,  0, 19, 19, 19, 19,
+   19,  0,  0,  0,  0,  0, 26, 26,  0,  0,  0,  0,  1,  1,  1,  1,
+    1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  9,  9,  9,  9,
+    0,  9,  9,  9,  2,  2,  9,  9,  9,  9,  0,  9,  2,  2,  2,  2,
+    9,  0,  9,  0,  9,  9,  9,  2,  9,  2,  9,  9,  9,  9,  9,  9,
+    9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  2,  9,
+    9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9, 55, 55,
+   55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55,  6,  6,  6,  6,
+    6,  6,  6,  6,  6,  6,  6,  6,  6,  6,  6,  6,  6,  6,  6,  6,
+    6,  1,  1,  6,  6,  6,  6,  6,  6,  6,  6,  6,  2,  4,  4,  4,
+    4,  4,  4,  4,  4,  4,  4,  4,  4,  4,  4,  4,  4,  4,  4,  4,
+    4,  4,  4,  4,  4,  4,  4,  4,  4,  4,  4,  4,  4,  4,  4,  4,
+    4,  4,  4,  2,  2,  4,  4,  4,  4,  4,  4,  4,  4,  4,  4,  4,
+    4,  4,  4,  4,  4,  0,  4,  2,  2,  4,  4,  4,  2, 14, 14, 14,
+   14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+   14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+   14, 14, 14, 14,  2,  2,  2,  2,  2,  2,  2,  2, 14, 14, 14, 14,
+   14, 14, 14, 14, 14, 14, 14,  2,  2,  2,  2, 14, 14, 14, 14, 14,
+   14,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  3,  3,  3,  3,
+    3,  0,  3,  3,  3,  3,  3,  3,  0,  3,  3,  3,  3,  3,  3,  3,
+    3,  3,  3,  3,  3,  3,  3,  0,  3,  2,  3,  0,  3,  3,  3,  3,
+    3,  3,  3,  3,  3,  3,  3,  3,  3,  3,  3,  3,  0,  3,  3,  3,
+    3,  3,  3,  3,  3,  3,  3,  1,  1,  1,  1,  1,  1,  1,  1,  1,
+    1,  1,  3,  3,  3,  3,  3,  3,  3,  3,  3,  3,  1,  3,  3,  3,
+    3,  3,  3,  3,  3,  3,  3,  3,  3,  3,  3,  3,  3,  3,  3,  3,
+    3,  3,  3,  3,  3,  3,  3,  3,  3,  0,  3,  3, 37, 37, 37, 37,
+   37, 37, 37, 37, 37, 37, 37, 37, 37, 37,  2, 37, 37, 37, 37, 37,
+   37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37,
+   37, 37, 37, 37, 37, 37, 37,  2,  2, 37, 37, 37, 38, 38, 38, 38,
+   38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38,  2,  2,
+    2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2, 64, 64, 64, 64,
+   64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
+   64, 64, 64, 64, 64, 64, 64,  2,  2, 64, 64, 64, 90, 90, 90, 90,
+   90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90,
+   90, 90, 90, 90, 90, 90, 90, 90, 90, 90,  2,  2, 90, 90, 90, 90,
+   90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90,  2, 95, 95, 95, 95,
+   95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95,
+   95, 95, 95, 95, 95, 95, 95, 95,  2,  2, 95,  2, 37, 37, 37, 37,
+   37, 37, 37, 37, 37, 37, 37,  2,  2,  2,  2,  2,  2,  2,  2,  2,
+    2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  3,  3,  3,  3,
+    3,  2,  3,  3,  3,  3,  3,  3,  3,  3,  2,  2,  2,  2,  2,  3,
+    3,  3,  3,  3,  3,  3,  3,  3,  3,  3,  3,  3,  3,  3,  0,  3,
+    3,  3,  3,  3,  3,  3,  3,  3,  3,  3,  3,  3,  7,  7,  7,  7,
+    7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  1,  1,  1,
+    1,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,
+    0,  0,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  5,  5,  5,  5,
+    2,  5,  5,  5,  5,  5,  5,  5,  5,  2,  2,  5,  5,  2,  2,  5,
+    5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,
+    5,  5,  5,  5,  5,  2,  5,  5,  5,  5,  5,  5,  5,  2,  5,  2,
+    2,  2,  5,  5,  5,  5,  2,  2,  5,  5,  5,  5,  5,  5,  5,  5,
+    5,  2,  2,  5,  5,  2,  2,  5,  5,  5,  5,  2,  2,  2,  2,  2,
+    2,  2,  2,  5,  2,  2,  2,  2,  5,  5,  2,  5,  5,  5,  5,  5,
+    2,  2,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,
+    5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  2,  2, 11, 11, 11,
+    2, 11, 11, 11, 11, 11, 11,  2,  2,  2,  2, 11, 11,  2,  2, 11,
+   11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11,
+   11, 11, 11, 11, 11,  2, 11, 11, 11, 11, 11, 11, 11,  2, 11, 11,
+    2, 11, 11,  2, 11, 11,  2,  2, 11,  2, 11, 11, 11, 11, 11,  2,
+    2,  2,  2, 11, 11,  2,  2, 11, 11, 11,  2,  2,  2, 11,  2,  2,
+    2,  2,  2,  2,  2, 11, 11, 11, 11,  2, 11,  2,  2,  2,  2,  2,
+    2,  2, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11,
+   11, 11, 11,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2, 10, 10, 10,
+    2, 10, 10, 10, 10, 10, 10, 10, 10, 10,  2, 10, 10, 10,  2, 10,
+   10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10,
+   10, 10, 10, 10, 10,  2, 10, 10, 10, 10, 10, 10, 10,  2, 10, 10,
+    2, 10, 10, 10, 10, 10,  2,  2, 10, 10, 10, 10, 10, 10, 10, 10,
+   10, 10,  2, 10, 10, 10,  2, 10, 10, 10,  2,  2, 10,  2,  2,  2,
+    2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2, 10, 10, 10, 10,
+    2,  2, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10,  2,  2,
+    2,  2,  2,  2,  2, 10, 10, 10, 10, 10, 10, 10,  2, 21, 21, 21,
+    2, 21, 21, 21, 21, 21, 21, 21, 21,  2,  2, 21, 21,  2,  2, 21,
+   21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
+   21, 21, 21, 21, 21,  2, 21, 21, 21, 21, 21, 21, 21,  2, 21, 21,
+    2, 21, 21, 21, 21, 21,  2,  2, 21, 21, 21, 21, 21, 21, 21, 21,
+   21,  2,  2, 21, 21,  2,  2, 21, 21, 21,  2,  2,  2,  2,  2,  2,
+    2,  2, 21, 21,  2,  2,  2,  2, 21, 21,  2, 21, 21, 21, 21, 21,
+    2,  2, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
+   21, 21, 21, 21,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2, 22, 22,
+    2, 22, 22, 22, 22, 22, 22,  2,  2,  2, 22, 22, 22,  2, 22, 22,
+   22, 22,  2,  2,  2, 22, 22,  2, 22,  2, 22, 22,  2,  2,  2, 22,
+   22,  2,  2,  2, 22, 22, 22,  2,  2,  2, 22, 22, 22, 22, 22, 22,
+   22, 22, 22, 22, 22, 22,  2,  2,  2,  2, 22, 22, 22, 22, 22,  2,
+    2,  2, 22, 22, 22,  2, 22, 22, 22, 22,  2,  2, 22,  2,  2,  2,
+    2,  2,  2, 22,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,
+    2,  2, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22,
+   22, 22, 22, 22, 22, 22, 22,  2,  2,  2,  2,  2, 23, 23, 23, 23,
+   23, 23, 23, 23, 23, 23, 23, 23, 23,  2, 23, 23, 23,  2, 23, 23,
+   23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23,
+   23, 23, 23, 23, 23,  2, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23,
+   23, 23, 23, 23, 23, 23,  2,  2,  2, 23, 23, 23, 23, 23, 23, 23,
+   23,  2, 23, 23, 23,  2, 23, 23, 23, 23,  2,  2,  2,  2,  2,  2,
+    2, 23, 23,  2, 23, 23, 23,  2,  2,  2,  2,  2, 23, 23, 23, 23,
+    2,  2, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23,  2,  2,  2,  2,
+    2,  2,  2, 23, 23, 23, 23, 23, 23, 23, 23, 23, 16, 16, 16, 16,
+   16, 16, 16, 16, 16, 16, 16, 16, 16,  2, 16, 16, 16,  2, 16, 16,
+   16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+   16, 16, 16, 16, 16,  2, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+    2, 16, 16, 16, 16, 16,  2,  2, 16, 16, 16, 16, 16, 16, 16, 16,
+   16,  2, 16, 16, 16,  2, 16, 16, 16, 16,  2,  2,  2,  2,  2,  2,
+    2, 16, 16,  2,  2,  2,  2,  2,  2,  2, 16,  2, 16, 16, 16, 16,
+    2,  2, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,  2, 16, 16,  2,
+    2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2, 20, 20, 20, 20,
+    2, 20, 20, 20, 20, 20, 20, 20, 20,  2, 20, 20, 20,  2, 20, 20,
+   20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
+   20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
+   20,  2, 20, 20, 20,  2, 20, 20, 20, 20, 20, 20,  2,  2,  2,  2,
+   20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
+    2,  2, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,  2,  2, 36, 36,
+    2, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36,
+   36, 36, 36,  2,  2,  2, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36,
+   36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36,  2, 36,
+   36, 36, 36, 36, 36, 36, 36, 36,  2, 36,  2,  2, 36, 36, 36, 36,
+   36, 36, 36,  2,  2,  2, 36,  2,  2,  2,  2, 36, 36, 36, 36, 36,
+   36,  2, 36,  2, 36, 36, 36, 36, 36, 36, 36, 36,  2,  2,  2,  2,
+    2,  2, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36,  2,  2, 36, 36,
+   36,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2, 24, 24, 24,
+   24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
+   24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
+   24, 24, 24, 24, 24, 24, 24,  2,  2,  2,  2,  0, 24, 24, 24, 24,
+   24, 24, 24, 24, 24, 24, 24, 24,  2,  2,  2,  2,  2, 18, 18,  2,
+   18,  2, 18, 18, 18, 18, 18,  2, 18, 18, 18, 18, 18, 18, 18, 18,
+   18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18,
+    2, 18,  2, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18,
+   18, 18, 18, 18, 18, 18, 18, 18, 18, 18,  2,  2, 18, 18, 18, 18,
+   18,  2, 18,  2, 18, 18, 18, 18, 18, 18,  2,  2, 18, 18, 18, 18,
+   18, 18, 18, 18, 18, 18,  2,  2, 18, 18, 18, 18, 25, 25, 25, 25,
+   25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
+   25, 25, 25, 25,  2, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
+   25, 25, 25, 25, 25, 25, 25, 25, 25,  2,  2,  2,  2, 25, 25, 25,
+   25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
+   25, 25, 25, 25, 25, 25, 25, 25, 25,  2, 25, 25, 25, 25, 25, 25,
+   25,  0,  0,  0,  0, 25, 25,  2,  2,  2,  2,  2, 33, 33, 33, 33,
+   33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33,  8,  8,  8,  8,
+    8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,
+    8,  8,  2,  8,  2,  2,  2,  2,  2,  8,  2,  2,  8,  8,  8,  8,
+    8,  8,  8,  8,  8,  8,  8,  0,  8,  8,  8,  8, 12, 12, 12, 12,
+   12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 30, 30, 30, 30,
+   30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30,
+   30, 30, 30, 30, 30,  2, 30, 30, 30, 30,  2,  2, 30, 30, 30, 30,
+   30, 30, 30,  2, 30,  2, 30, 30, 30, 30,  2,  2, 30,  2, 30, 30,
+   30, 30,  2,  2, 30, 30, 30, 30, 30, 30, 30,  2, 30,  2, 30, 30,
+   30, 30,  2,  2, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30,
+   30, 30, 30,  2, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30,
+   30, 30, 30, 30, 30, 30, 30,  2,  2, 30, 30, 30, 30, 30, 30, 30,
+   30, 30, 30, 30, 30, 30, 30, 30, 30,  2,  2,  2, 30, 30, 30, 30,
+   30, 30, 30, 30, 30, 30,  2,  2,  2,  2,  2,  2, 29, 29, 29, 29,
+   29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29,
+   29, 29,  2,  2, 29, 29, 29, 29, 29, 29,  2,  2, 28, 28, 28, 28,
+   28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 34, 34, 34, 34,
+   34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
+   34, 34, 34, 34, 34, 34, 34, 34, 34,  2,  2,  2, 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,  0,  0,  0, 35, 35, 35, 35, 35, 35,
+   35, 35, 35, 35, 35,  2,  2,  2,  2,  2,  2,  2, 45, 45, 45, 45,
+   45, 45, 45, 45, 45, 45, 45, 45, 45,  2, 45, 45, 45, 45, 45, 45,
+   45,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2, 44, 44, 44, 44,
+   44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44,
+   44,  0,  0,  2,  2,  2,  2,  2,  2,  2,  2,  2, 43, 43, 43, 43,
+   43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43,
+    2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2, 46, 46, 46, 46,
+   46, 46, 46, 46, 46, 46, 46, 46, 46,  2, 46, 46, 46,  2, 46, 46,
+    2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2, 31, 31, 31, 31,
+   31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31,
+   31, 31, 31, 31, 31, 31, 31, 31, 31, 31,  2,  2, 31, 31, 31, 31,
+   31, 31, 31, 31, 31, 31,  2,  2,  2,  2,  2,  2, 32, 32,  0,  0,
+   32,  0, 32, 32, 32, 32, 32, 32, 32, 32, 32,  2, 32, 32, 32, 32,
+   32, 32, 32, 32, 32, 32,  2,  2,  2,  2,  2,  2, 32, 32, 32, 32,
+   32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+   32, 32, 32, 32, 32,  2,  2,  2,  2,  2,  2,  2, 32, 32, 32, 32,
+   32, 32, 32, 32, 32, 32, 32,  2,  2,  2,  2,  2, 28, 28, 28, 28,
+   28, 28,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2, 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, 48,  2, 48, 48, 48, 48,
+   48, 48, 48, 48, 48, 48, 48, 48,  2,  2,  2,  2, 48,  2,  2,  2,
+   48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 52, 52, 52, 52,
+   52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52,
+   52, 52, 52, 52, 52, 52, 52, 52, 52, 52,  2,  2, 52, 52, 52, 52,
+   52,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2, 58, 58, 58, 58,
+   58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
+   58, 58, 58, 58, 58, 58, 58, 58,  2,  2,  2,  2, 58, 58, 58, 58,
+   58, 58, 58, 58, 58, 58,  2,  2,  2,  2,  2,  2, 58, 58, 58, 58,
+   58, 58, 58, 58, 58, 58, 58,  2,  2,  2, 58, 58, 54, 54, 54, 54,
+   54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54,
+   54, 54, 54, 54, 54, 54, 54, 54,  2,  2, 54, 54, 91, 91, 91, 91,
+   91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
+   91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,  2, 91, 91, 91, 91,
+   91, 91, 91, 91, 91, 91, 91, 91, 91,  2,  2, 91, 91, 91, 91, 91,
+   91, 91, 91, 91, 91, 91,  2,  2,  2,  2,  2,  2, 91, 91, 91, 91,
+   91, 91, 91, 91, 91, 91, 91, 91, 91, 91,  2,  2,  1,  1,  1,  1,
+    1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  2, 62, 62, 62, 62,
+   62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62,
+   62, 62, 62, 62, 62, 62, 62, 62,  2,  2,  2,  2, 62, 62, 62, 62,
+   62, 62, 62, 62, 62, 62, 62, 62, 62,  2,  2,  2, 76, 76, 76, 76,
+   76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 93, 93, 93, 93,
+   93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93,
+    2,  2,  2,  2,  2,  2,  2,  2, 93, 93, 93, 93, 70, 70, 70, 70,
+   70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70,
+   70, 70, 70, 70,  2,  2,  2, 70, 70, 70, 70, 70, 70, 70, 70, 70,
+   70, 70, 70, 70, 70, 70,  2,  2,  2, 70, 70, 70, 73, 73, 73, 73,
+   73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, 73,  6,  6,  6,  6,
+    6,  6,  6,  6,  6,  2,  2,  2,  2,  2,  2,  2,  8,  8,  8,  8,
+    8,  8,  8,  8,  8,  8,  8,  2,  2,  8,  8,  8, 76, 76, 76, 76,
+   76, 76, 76, 76,  2,  2,  2,  2,  2,  2,  2,  2,  1,  1,  1,  0,
+    1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  1,  1,
+    1,  1,  1,  1,  1,  0,  0,  0,  0,  1,  0,  0,  0,  0,  0,  0,
+    1,  0,  0,  0,  1,  1,  0,  2,  2,  2,  2,  2, 19, 19, 19, 19,
+   19, 19,  9,  9,  9,  9,  9,  6, 19, 19, 19, 19, 19, 19, 19, 19,
+   19, 19, 19, 19, 19, 19, 19, 19, 19,  9,  9,  9,  9,  9, 19, 19,
+   19, 19,  9,  9,  9,  9,  9, 19, 19, 19, 19, 19, 19, 19, 19, 19,
+   19, 19, 19, 19,  6, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
+   19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,  9,  1,  1,  1,  1,
+    1,  1,  1,  1,  1,  1,  2,  1,  1,  1,  1,  1,  9,  9,  9,  9,
+    9,  9,  2,  2,  9,  9,  9,  9,  9,  9,  2,  2,  9,  9,  9,  9,
+    9,  9,  9,  9,  2,  9,  2,  9,  2,  9,  2,  9,  9,  9,  9,  9,
+    9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  2,  2,  9,  9,  9,  9,
+    9,  2,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,
+    2,  2,  9,  9,  9,  9,  9,  9,  2,  9,  9,  9,  2,  2,  9,  9,
+    9,  2,  9,  9,  9,  9,  9,  9,  9,  9,  9,  2,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  1,  1,  0,  0,  0,  0,  0,  0,
+    0,  2,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 19,  2,  2,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 19,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  2, 19, 19, 19, 19,
+   19, 19, 19, 19, 19, 19, 19, 19, 19,  2,  2,  2,  1,  2,  2,  2,
+    2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  0,  0,  0,  0,
+    0,  0,  9,  0,  0,  0, 19, 19,  0,  0,  0,  0,  0,  0, 19,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 19,  0, 19, 19, 19, 19,
+   19, 19, 19, 19, 19,  0,  0,  0,  2,  2,  2,  2,  0,  0,  0,  0,
+    0,  0,  0,  2,  2,  2,  2,  2,  2,  2,  2,  2,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  2,  2,  2,  2,  2, 27, 27, 27, 27,
+   27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27,  0,  0,  0,  0,
+    2,  2,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  2,  2,  0,  0,  0,  0,  0,  0,  0,  0, 56, 56, 56, 56,
+   56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56,
+   56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56,  2, 55, 55, 55, 55,
+   55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55,
+    2,  2,  2,  2,  2, 55, 55, 55, 55, 55, 55, 55, 61, 61, 61, 61,
+   61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61,
+   61, 61, 61, 61,  2,  2,  2,  2,  2,  2,  2, 61, 61,  2,  2,  2,
+    2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2, 61, 30, 30, 30, 30,
+   30, 30, 30,  2,  2,  2,  2,  2,  2,  2,  2,  2, 30, 30, 30, 30,
+   30, 30, 30,  2, 30, 30, 30, 30, 30, 30, 30,  2, 13, 13, 13, 13,
+   13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+   13, 13, 13, 13, 13, 13,  2, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+    2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2, 13, 13, 13, 13,
+   13, 13,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  2,  2,  2,  2,  0,  0,  0,  0,
+    0, 13,  0, 13,  0,  0,  0,  0,  0,  0,  0,  0,  0, 13, 13, 13,
+   13, 13, 13, 13, 13, 13,  1,  1,  1,  1, 12, 12,  0,  0,  0,  0,
+    0,  0,  0,  0, 13, 13, 13, 13,  0,  0,  0,  0,  2, 15, 15, 15,
+   15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+   15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+   15, 15, 15,  2,  2,  1,  1,  0,  0, 15, 15, 15,  0, 17, 17, 17,
+   17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+   17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+   17, 17, 17, 17, 17, 17, 17,  0,  0, 17, 17, 17,  2,  2,  2,  2,
+    2, 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,  2, 12, 12, 12,
+   12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
+   12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,  2, 26, 26, 26, 26,
+   26, 26, 26, 26, 26, 26, 26,  2,  2,  2,  2,  2,  0,  0,  0,  0,
+    2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2, 12, 12, 12, 12,
+   12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,  0, 17, 17, 17, 17,
+   17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,  0, 17, 17, 17, 17,
+   17, 17, 17, 17,  0,  0,  0,  0,  0,  0,  0,  0, 39, 39, 39, 39,
+   39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39,
+   39, 39, 39, 39, 39, 39, 39, 39, 39,  2,  2,  2, 39, 39, 39, 39,
+   39, 39, 39,  2,  2,  2,  2,  2,  2,  2,  2,  2, 86, 86, 86, 86,
+   86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 77, 77, 77, 77,
+   77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77,
+   77, 77, 77, 77, 77, 77, 77, 77,  2,  2,  2,  2, 79, 79, 79, 79,
+   79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79,
+   79, 79, 79, 79,  2,  2,  2,  2,  2,  2,  2,  2,  0,  0, 19, 19,
+   19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
+   19, 19, 19, 19,  0,  0,  0, 19, 19, 19, 19, 19,  2,  2, 19, 19,
+   19, 19, 19,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,
+    2,  2,  2, 19, 19, 19, 19, 19, 19, 19, 19, 19, 60, 60, 60, 60,
+   60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60,
+   60, 60, 60, 60, 60, 60, 60, 60,  2,  2,  2,  2,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  2,  2,  2,  2,  2,  2, 65, 65, 65, 65,
+   65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65,
+   65, 65, 65, 65,  2,  2,  2,  2,  2,  2,  2,  2, 75, 75, 75, 75,
+   75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75,
+   75, 75,  2,  2,  2,  2,  2,  2,  2,  2, 75, 75, 75, 75, 75, 75,
+   75, 75, 75, 75, 75, 75,  2,  2,  2,  2,  2,  2, 69, 69, 69, 69,
+   69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69,
+   69, 69, 69, 69, 69, 69, 69, 69, 69, 69,  0, 69, 74, 74, 74, 74,
+   74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74,
+    2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2, 74, 12, 12, 12, 12,
+   12, 12, 12, 12, 12, 12, 12, 12, 12,  2,  2,  2, 84, 84, 84, 84,
+   84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84,
+   84, 84, 84, 84, 84, 84, 84, 84, 84, 84,  2,  0, 84, 84, 84, 84,
+   84, 84, 84, 84, 84, 84,  2,  2,  2,  2, 84, 84, 33, 33, 33, 33,
+   33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33,  2, 68, 68, 68, 68,
+   68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68,
+   68, 68, 68,  2,  2,  2,  2,  2,  2,  2,  2,  2, 68, 68, 68, 68,
+   68, 68, 68, 68, 68, 68, 68, 68, 68, 68,  2,  2, 68, 68, 68, 68,
+   68, 68, 68, 68, 68, 68,  2,  2, 68, 68, 68, 68, 92, 92, 92, 92,
+   92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92,  2,
+    2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,
+    2,  2,  2,  2,  2,  2,  2, 92, 92, 92, 92, 92, 87, 87, 87, 87,
+   87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87,
+   87, 87, 87,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2, 30, 30, 30,
+   30, 30, 30,  2,  2, 30, 30, 30, 30, 30, 30,  2,  2, 30, 30, 30,
+   30, 30, 30,  2,  2,  2,  2,  2,  2,  2,  2,  2, 19, 19, 19, 19,
+   19, 19, 19, 19, 19, 19, 19,  0, 19, 19, 19, 19, 19, 19, 19, 19,
+   19,  9, 19, 19,  2,  2,  2,  2,  2,  2,  2,  2, 87, 87, 87, 87,
+   87, 87, 87, 87, 87, 87, 87, 87, 87, 87,  2,  2, 87, 87, 87, 87,
+   87, 87, 87, 87, 87, 87,  2,  2,  2,  2,  2,  2, 12, 12, 12, 12,
+    2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2, 12, 12, 12, 12,
+   12, 12, 12,  2,  2,  2,  2, 12, 12, 12, 12, 12, 12, 12, 12, 12,
+   12, 12, 12, 12, 12, 12, 12, 12,  2,  2,  2,  2, 13, 13, 13, 13,
+   13, 13, 13, 13, 13, 13, 13, 13, 13, 13,  2,  2, 13, 13, 13, 13,
+   13, 13, 13, 13, 13, 13,  2,  2,  2,  2,  2,  2, 19, 19, 19, 19,
+   19, 19, 19,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  4,
+    4,  4,  4,  4,  2,  2,  2,  2,  2, 14, 14, 14, 14, 14, 14, 14,
+   14, 14, 14,  2, 14, 14, 14, 14, 14,  2, 14,  2, 14, 14,  2, 14,
+   14,  2, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,  3,  3,  2,  2,
+    2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  3,  3,  3,  3,
+    3,  3,  3,  3,  3,  3,  3,  3,  3,  3,  0,  0,  2,  2,  3,  3,
+    3,  3,  3,  3,  3,  3,  3,  3,  3,  3,  3,  3,  3,  3,  3,  3,
+    3,  3,  3,  3,  2,  2,  2,  2,  2,  2,  2,  2,  3,  3,  3,  3,
+    3,  3,  3,  3,  3,  3,  3,  3,  3,  3,  2,  2,  1,  1,  1,  1,
+    1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  6,  6,  0,  0,  0,  2,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  2,  0,  0,  0,  0,  2,  2,  2,  2,  3,  3,  3,  3,
+    3,  2,  3,  3,  3,  3,  3,  3,  3,  3,  3,  3,  3,  3,  3,  3,
+    3,  3,  3,  3,  3,  3,  3,  3,  3,  2,  2,  0,  2,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+   17, 17, 17, 17, 17, 17, 17, 17, 17, 17,  0,  0,  2,  2, 12, 12,
+   12, 12, 12, 12,  2,  2, 12, 12, 12, 12, 12, 12,  2,  2, 12, 12,
+   12, 12, 12, 12,  2,  2, 12, 12, 12,  2,  2,  2,  0,  0,  0,  0,
+    0,  0,  0,  2,  0,  0,  0,  0,  0,  0,  0,  2,  2,  2,  2,  2,
+    2,  2,  2,  2,  2,  0,  0,  0,  0,  0,  2,  2, 49, 49, 49, 49,
+   49, 49, 49, 49, 49, 49, 49, 49,  2, 49, 49, 49, 49, 49, 49, 49,
+   49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
+   49, 49, 49,  2, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
+   49, 49, 49, 49, 49, 49, 49,  2, 49, 49,  2, 49, 49, 49, 49, 49,
+   49, 49, 49, 49, 49, 49, 49, 49, 49, 49,  2,  2, 49, 49, 49, 49,
+   49, 49, 49, 49, 49, 49, 49,  2,  2,  2,  2,  2,  0,  0,  0,  2,
+    2,  2,  2,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    2,  2,  2,  0,  0,  0,  0,  0,  0,  0,  0,  0,  9,  9,  9,  9,
+    9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  2,  9,  2,  2,  2,
+    2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  2,  2, 71, 71, 71, 71,
+   71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71,
+   71, 71, 71, 71, 71, 71, 71, 71, 71,  2,  2,  2, 67, 67, 67, 67,
+   67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67,  2,  2,  2,
+    2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  1,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 42, 42, 42, 42,
+   42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42,
+    2,  2,  2,  2,  2,  2,  2,  2,  2, 42, 42, 42, 41, 41, 41, 41,
+   41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+   41, 41, 41, 41, 41, 41, 41,  2,  2,  2,  2,  2,118,118,118,118,
+  118,118,118,118,118,118,118,118,118,118,118,118,118,118,118,118,
+  118,118,118,118,118,118,118,  2,  2,  2,  2,  2, 53, 53, 53, 53,
+   53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53,
+   53, 53, 53, 53, 53, 53, 53, 53, 53, 53,  2, 53, 59, 59, 59, 59,
+   59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59,
+    2,  2,  2,  2, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59,
+   59, 59,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2, 40, 40, 40, 40,
+   40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 51, 51, 51, 51,
+   51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 50, 50, 50, 50,
+   50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+   50, 50, 50, 50, 50, 50, 50, 50, 50, 50,  2,  2, 50, 50, 50, 50,
+   50, 50, 50, 50, 50, 50,  2,  2,  2,  2,  2,  2,135,135,135,135,
+  135,135,135,135,135,135,135,135,135,135,135,135,135,135,135,135,
+    2,  2,  2,  2,135,135,135,135,135,135,135,135,135,135,135,135,
+  135,135,135,135,135,135,135,135,  2,  2,  2,  2,106,106,106,106,
+  106,106,106,106,106,106,106,106,106,106,106,106,106,106,106,106,
+  106,106,106,106,  2,  2,  2,  2,  2,  2,  2,  2,104,104,104,104,
+  104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,
+    2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,104,110,110,110,110,
+  110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,
+  110,110,110,  2,  2,  2,  2,  2,  2,  2,  2,  2,110,110,110,110,
+  110,110,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,110,110,110,110,
+  110,110,110,110,  2,  2,  2,  2,  2,  2,  2,  2, 47, 47, 47, 47,
+   47, 47,  2,  2, 47,  2, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+   47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+   47, 47,  2, 47, 47,  2,  2,  2, 47,  2,  2, 47, 81, 81, 81, 81,
+   81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81,
+   81, 81,  2, 81, 81, 81, 81, 81, 81, 81, 81, 81,120,120,120,120,
+  120,120,120,120,120,120,120,120,120,120,120,120,116,116,116,116,
+  116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,
+  116,116,116,116,116,116,116,116,116,116,116,  2,  2,  2,  2,  2,
+    2,  2,  2,116,116,116,116,116,116,116,116,116,128,128,128,128,
+  128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,  2,
+  128,128,  2,  2,  2,  2,  2,128,128,128,128,128, 66, 66, 66, 66,
+   66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66,
+   66, 66, 66, 66, 66, 66, 66, 66,  2,  2,  2, 66, 72, 72, 72, 72,
+   72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72,
+   72, 72, 72, 72, 72, 72,  2,  2,  2,  2,  2, 72, 98, 98, 98, 98,
+   98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 97, 97, 97, 97,
+   97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97,
+   97, 97, 97, 97,  2,  2,  2,  2, 97, 97, 97, 97,  2,  2, 97, 97,
+   97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 57, 57, 57, 57,
+    2, 57, 57,  2,  2,  2,  2,  2, 57, 57, 57, 57, 57, 57, 57, 57,
+    2, 57, 57, 57,  2, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57,
+   57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57,
+   57, 57,  2,  2, 57, 57, 57,  2,  2,  2,  2, 57, 57, 57, 57, 57,
+   57, 57, 57, 57, 57,  2,  2,  2,  2,  2,  2,  2, 88, 88, 88, 88,
+   88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88,117,117,117,117,
+  117,117,117,117,117,117,117,117,117,117,117,117,112,112,112,112,
+  112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,
+  112,112,112,  2,  2,  2,  2,112,112,112,112,112,112,112,112,112,
+  112,112,112,  2,  2,  2,  2,  2,  2,  2,  2,  2, 78, 78, 78, 78,
+   78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78,
+   78, 78,  2,  2,  2, 78, 78, 78, 78, 78, 78, 78, 83, 83, 83, 83,
+   83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83,
+   83, 83,  2,  2, 83, 83, 83, 83, 83, 83, 83, 83, 82, 82, 82, 82,
+   82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82,  2,
+    2,  2,  2,  2, 82, 82, 82, 82, 82, 82, 82, 82,122,122,122,122,
+  122,122,122,122,122,122,122,122,122,122,122,122,122,122,  2,  2,
+    2,  2,  2,  2,  2,122,122,122,122,  2,  2,  2,  2,  2,  2,  2,
+    2,  2,  2,  2,  2,122,122,122,122,122,122,122, 89, 89, 89, 89,
+   89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89,
+   89, 89, 89, 89, 89,  2,  2,  2,  2,  2,  2,  2,130,130,130,130,
+  130,130,130,130,130,130,130,130,130,130,130,130,130,130,130,  2,
+    2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,130,130,130,  2,
+    2,  2,  2,  2,  2,  2,130,130,130,130,130,130,144,144,144,144,
+  144,144,144,144,144,144,144,144,144,144,144,144,144,144,144,144,
+  144,144,144,144,  2,  2,  2,  2,  2,  2,  2,  2,144,144,144,144,
+  144,144,144,144,144,144,  2,  2,  2,  2,  2,  2,  3,  3,  3,  3,
+    3,  3,  3,  3,  3,  3,  3,  3,  3,  3,  3,  2,147,147,147,147,
+  147,147,147,147,147,147,147,147,147,147,147,147,147,147,147,147,
+  147,147,147,147,  2,  2,  2,  2,  2,  2,  2,  2,148,148,148,148,
+  148,148,148,148,148,148,148,148,148,148,148,148,148,148,148,148,
+  148,148,148,148,148,148,  2,  2,  2,  2,  2,  2,149,149,149,149,
+  149,149,149,149,149,149,149,149,149,149,149,149,149,149,149,149,
+  149,149,149,  2,  2,  2,  2,  2,  2,  2,  2,  2, 94, 94, 94, 94,
+   94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94,
+   94, 94, 94, 94, 94, 94, 94, 94, 94, 94,  2,  2,  2,  2, 94, 94,
+   94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94,  2,  2,  2,  2,
+    2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2, 94, 85, 85, 85, 85,
+   85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85,  2,  2,
+    2,  2,  2,  2,  2,  2,  2,  2,  2, 85,  2,  2,101,101,101,101,
+  101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,
+  101,101,101,101,101,  2,  2,  2,  2,  2,  2,  2,101,101,101,101,
+  101,101,101,101,101,101,  2,  2,  2,  2,  2,  2, 96, 96, 96, 96,
+   96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96,
+   96,  2, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96,
+   96, 96, 96,  2,  2,  2,  2,  2,  2,  2,  2,  2,111,111,111,111,
+  111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,
+  111,111,111,  2,  2,  2,  2,  2,  2,  2,  2,  2,100,100,100,100,
+  100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,
+  100,100,100,100,100,100,100,100,100,100,  2,  2,  2, 36, 36, 36,
+   36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36,
+   36,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,108,108,108,108,
+  108,108,108,108,108,108,108,108,108,108,108,108,108,108,  2,108,
+  108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,
+  108,108,108,108,108,108,108,108,108,108,108,  2,129,129,129,129,
+  129,129,129,  2,129,  2,129,129,129,129,  2,129,129,129,129,129,
+  129,129,129,129,129,129,129,129,129,129,  2,129,129,129,129,129,
+  129,129,129,129,129,129,  2,  2,  2,  2,  2,  2,109,109,109,109,
+  109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,
+  109,109,109,109,109,109,109,  2,  2,  2,  2,  2,109,109,109,109,
+  109,109,109,109,109,109,  2,  2,  2,  2,  2,  2,107,107,107,107,
+    2,107,107,107,107,107,107,107,107,  2,  2,107,107,  2,  2,107,
+  107,107,107,107,107,107,107,107,107,107,107,107,107,107,107,107,
+  107,107,107,107,107,  2,107,107,107,107,107,107,107,  2,107,107,
+    2,107,107,107,107,107,  2,  1,107,107,107,107,107,107,107,107,
+  107,  2,  2,107,107,  2,  2,107,107,107,  2,  2,107,  2,  2,  2,
+    2,  2,  2,107,  2,  2,  2,  2,  2,107,107,107,107,107,107,107,
+    2,  2,107,107,107,107,107,107,107,  2,  2,  2,107,107,107,107,
+  107,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,137,137,137,137,
+  137,137,137,137,137,137,137,137,137,137,137,137,137,137,137,137,
+  137,137,137,137,137,137,  2,137,  2,137,137,137,124,124,124,124,
+  124,124,124,124,124,124,124,124,124,124,124,124,124,124,124,124,
+  124,124,124,124,  2,  2,  2,  2,  2,  2,  2,  2,124,124,124,124,
+  124,124,124,124,124,124,  2,  2,  2,  2,  2,  2,123,123,123,123,
+  123,123,123,123,123,123,123,123,123,123,123,123,123,123,123,123,
+  123,123,  2,  2,123,123,123,123,123,123,123,123,123,123,123,123,
+  123,123,123,123,123,123,123,123,123,123,  2,  2,114,114,114,114,
+  114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,
+  114,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,114,114,114,114,
+  114,114,114,114,114,114,  2,  2,  2,  2,  2,  2, 32, 32, 32, 32,
+   32, 32, 32, 32, 32, 32, 32, 32, 32,  2,  2,  2,102,102,102,102,
+  102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,
+  102,102,102,102,102,  2,  2,  2,  2,  2,  2,  2,102,102,102,102,
+  102,102,102,102,102,102,  2,  2,  2,  2,  2,  2,126,126,126,126,
+  126,126,126,126,126,126,126,126,126,126,126,126,126,126,126,126,
+  126,126,126,126,126,126,126,  2,  2,126,126,126,126,126,126,126,
+  126,126,126,126,126,126,126,126,  2,  2,  2,  2,142,142,142,142,
+  142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,
+  142,142,142,142,142,142,142,142,  2,  2,  2,  2,125,125,125,125,
+  125,125,125,125,125,125,125,125,125,125,125,125,125,125,125,  2,
+    2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,125,150,150,150,150,
+  150,150,150,150,  2,  2,150,150,150,150,150,150,150,150,150,150,
+  150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,
+  150,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,141,141,141,141,
+  141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,
+  141,141,141,141,  2,  2,  2,  2,  2,  2,  2,  2,140,140,140,140,
+  140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,  2,
+    2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,121,121,121,121,
+  121,121,121,121,121,121,121,121,121,121,121,121,121,121,121,121,
+  121,121,121,121,121,  2,  2,  2,  2,  2,  2,  2,133,133,133,133,
+  133,133,133,133,133,  2,133,133,133,133,133,133,133,133,133,133,
+  133,133,133,133,133,133,133,133,133,133,133,133,133,133,133,133,
+  133,133,133,  2,133,133,133,133,133,133,133,133,133,133,133,133,
+  133,133,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,133,133,133,133,
+  133,133,133,133,133,133,133,133,133,  2,  2,  2,134,134,134,134,
+  134,134,134,134,134,134,134,134,134,134,134,134,  2,  2,134,134,
+  134,134,134,134,134,134,134,134,134,134,134,134,134,134,134,134,
+  134,134,134,134,  2,134,134,134,134,134,134,134,134,134,134,134,
+  134,134,134,  2,  2,  2,  2,  2,  2,  2,  2,  2,138,138,138,138,
+  138,138,138,  2,138,138,  2,138,138,138,138,138,138,138,138,138,
+  138,138,138,138,138,138,138,138,138,138,138,138,138,138,138,138,
+  138,138,138,  2,  2,  2,138,  2,138,138,  2,138,138,138,138,138,
+  138,138,138,138,  2,  2,  2,  2,  2,  2,  2,  2,138,138,138,138,
+  138,138,138,138,138,138,  2,  2,  2,  2,  2,  2,143,143,143,143,
+  143,143,  2,143,143,  2,143,143,143,143,143,143,143,143,143,143,
+  143,143,143,143,143,143,143,143,143,143,143,143,143,143,143,143,
+  143,143,143,143,143,143,143,143,143,143,143,  2,143,143,  2,143,
+  143,143,143,143,143,  2,  2,  2,  2,  2,  2,  2,143,143,143,143,
+  143,143,143,143,143,143,  2,  2,  2,  2,  2,  2,145,145,145,145,
+  145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,
+  145,145,145,145,145,  2,  2,  2,  2,  2,  2,  2, 22, 22, 22, 22,
+   22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22,  2,  2,
+    2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2, 22, 63, 63, 63, 63,
+   63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63,
+   63, 63, 63, 63, 63, 63,  2,  2,  2,  2,  2,  2, 63, 63, 63, 63,
+   63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63,  2, 63, 63, 63, 63,
+   63,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2, 63, 63, 63, 63,
+    2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2, 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,  2, 80, 80, 80, 80,
+   80, 80, 80, 80, 80,  2,  2,  2,  2,  2,  2,  2,127,127,127,127,
+  127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,
+  127,127,127,  2,  2,  2,  2,  2,  2,  2,  2,  2, 79, 79, 79, 79,
+   79, 79, 79, 79, 79,  2,  2,  2,  2,  2,  2,  2,115,115,115,115,
+  115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
+  115,115,115,115,115,115,115,115,115,115,115,  2,115,115,115,115,
+  115,115,115,115,115,115,  2,  2,  2,  2,115,115,103,103,103,103,
+  103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,
+  103,103,103,103,103,103,103,103,103,103,  2,  2,103,103,103,103,
+  103,103,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,119,119,119,119,
+  119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,
+  119,119,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,119,119,119,119,
+  119,119,119,119,119,119,  2,119,119,119,119,119,119,119,  2,119,
+  119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,
+  119,119,119,119,  2,  2,  2,  2,  2,119,119,119,146,146,146,146,
+  146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,
+  146,146,146,146,146,146,146,  2,  2,  2,  2,  2, 99, 99, 99, 99,
+   99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99,
+   99, 99, 99, 99, 99, 99, 99,  2,  2,  2,  2, 99, 99, 99, 99, 99,
+   99, 99, 99, 99,  2,  2,  2,  2,  2,  2,  2, 99,136,139,  0,  0,
+    2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,136,136,136,136,
+  136,136,136,136,136,136,136,136,136,136,136,136,136,136,136,136,
+  136,136,136,136,  2,  2,  2,  2,  2,  2,  2,  2,136,136,136,  2,
+    2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2, 17, 15, 15, 15,
+   15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+   15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,  2, 15, 15, 15,  2,
+    2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,
+   17, 17, 17, 17,  2,  2,  2,  2,  2,  2,  2,  2,139,139,139,139,
+  139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,
+  139,139,139,139,139,139,139,139,  2,  2,  2,  2,105,105,105,105,
+  105,105,105,105,105,105,105,105,105,105,105,105,105,105,105,105,
+  105,105,105,105,105,105,105,  2,  2,  2,  2,  2,105,105,105,105,
+  105,105,105,105,105,105,105,105,105,  2,  2,  2,105,105,105,105,
+  105,105,105,105,105,  2,  2,  2,  2,  2,  2,  2,105,105,105,105,
+  105,105,105,105,105,105,  2,  2,105,105,105,105,  0,  0,  0,  0,
+    0,  0,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  0,  0,  0,  0,
+    0,  0,  0,  2,  2,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  1,  1,  1,  1,  1,  1,  1,  1,  0,
+    0,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  2,  2,  2,  2,  2,  2,  2,  9,  9,  9,  9,
+    9,  9,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  2,  0,  0,  2,  2,  0,  2,
+    2,  0,  0,  2,  2,  0,  0,  0,  0,  2,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  2,  0,  2,  0,  0,  0,  0,  0,  0,  0,
+    2,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  2,  0,  0,  0,  0,  2,  2,  0,  0,  0,  0,  0,  0,  0,
+    0,  2,  0,  0,  0,  0,  0,  0,  0,  2,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  2,  0,  0,  0,  0,  2,  0,  0,  0,  0,
+    0,  2,  0,  2,  2,  2,  0,  0,  0,  0,  0,  0,  0,  2,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  2,  2,  0,  0,131,131,131,131,
+  131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,
+  131,131,131,131,131,131,131,131,  2,  2,  2,  2,  2,  2,  2,  2,
+    2,  2,  2,  2,  2,  2,  2,131,131,131,131,131,  2,131,131,131,
+  131,131,131,131,131,131,131,131,131,131,131,131, 56, 56, 56, 56,
+   56, 56, 56,  2, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56,
+   56, 56, 56, 56, 56,  2,  2, 56, 56, 56, 56, 56, 56, 56,  2, 56,
+   56,  2, 56, 56, 56, 56, 56,  2,  2,  2,  2,  2,151,151,151,151,
+  151,151,151,151,151,151,151,151,151,151,151,151,151,151,151,151,
+  151,151,151,151,151,151,151,151,151,  2,  2,  2,151,151,151,151,
+  151,151,151,151,151,151,151,151,151,151,  2,  2,151,151,151,151,
+  151,151,151,151,151,151,  2,  2,  2,  2,151,151,152,152,152,152,
+  152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,
+  152,152,152,152,152,152,  2,  2,  2,  2,  2,152,113,113,113,113,
+  113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,
+  113,  2,  2,113,113,113,113,113,113,113,113,113,113,113,113,113,
+  113,113,113,  2,  2,  2,  2,  2,  2,  2,  2,  2,132,132,132,132,
+  132,132,132,132,132,132,132,132,132,132,132,132,132,132,132,132,
+  132,132,132,132,132,132,132,132,  2,  2,  2,  2,132,132,132,132,
+  132,132,132,132,132,132,  2,  2,  2,  2,132,132,  0,  0,  0,  0,
+    0,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  2,  2,  3,  3,  3,  3,
+    2,  3,  3,  3,  3,  3,  3,  3,  3,  3,  3,  3,  2,  3,  3,  2,
+    3,  2,  2,  3,  2,  3,  3,  3,  3,  3,  3,  3,  3,  3,  3,  2,
+    3,  3,  3,  3,  2,  3,  2,  3,  2,  2,  2,  2,  2,  2,  3,  2,
+    2,  2,  2,  3,  2,  3,  2,  3,  2,  3,  3,  3,  2,  3,  3,  2,
+    3,  2,  2,  3,  2,  3,  2,  3,  2,  3,  2,  3,  2,  3,  3,  2,
+    3,  2,  2,  3,  3,  3,  3,  2,  3,  3,  3,  3,  3,  3,  3,  2,
+    3,  3,  3,  3,  2,  3,  3,  3,  3,  2,  3,  2,  3,  3,  3,  3,
+    3,  3,  3,  3,  3,  3,  2,  3,  3,  3,  3,  3,  3,  3,  3,  3,
+    3,  3,  3,  3,  3,  3,  3,  3,  2,  2,  2,  2,  2,  3,  3,  3,
+    2,  3,  3,  3,  3,  3,  2,  3,  3,  3,  3,  3,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  2,  2,  2,  2,  2,  2,  2,
+    2,  2,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 15,  0,  0,  2,
+    2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  0,  0,  2,  2,
+    2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  0,  0,  0,  0,
+    0,  0,  0,  0,  2,  2,  2,  2,  2,  2,  2,  2,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  2,  0,  0,  0,  0,  0,  2,  0,
+    0,  0,  0,  2,  2,  2,  0,  0,  0,  0,  0,  0,  0,  0,  0,  2,
+    2,  0,  0,  0,  0,  0,  0,  2,  2,  2,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  2,  2,  0,  0,  0,  0,  0,  0,  0,
+    2,  2,  2,  2,  0,  0,  0,  2,  2,  2,  2,  2,  0,  0,  0,  2,
+    2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2, 13, 13, 13, 13,
+   13, 13, 13,  2,  2,  2,  2,  2,  2,  2,  2,  2, 13, 13, 13, 13,
+   13,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2, 13, 13,  2,  2,
+    2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2, 13,  2,  2,  2,
+    2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  0,  2,  2,
+    2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  0,  0,  0,  1,
+    2,  3,  4,  5,  6,  0,  0,  0,  0,  7,  8,  9, 10, 11,  0, 12,
+    0,  0,  0,  0, 13,  0,  0, 14,  0,  0,  0,  0,  0,  0,  0,  0,
+   15, 16,  0, 17, 18, 19,  0,  0,  0, 20, 21, 22,  0, 23,  0, 24,
+    0, 25,  0, 26,  0,  0,  0,  0,  0, 27, 28,  0, 29,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0, 30, 31,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0, 32, 33, 34, 35, 36, 37, 38, 39, 40,  0,  0,  0,
+   41,  0, 42, 43, 44, 45, 46, 47, 48,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0, 49,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 50, 51, 52,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+   53, 54, 55, 56, 57, 58, 59, 60, 61, 62,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 63,  0,
+   64,  0,  0,  0,  0,  0,  0,  0,  0, 65,  0,  0,  0,  0, 66,  0,
+    0,  0, 67,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0, 68, 69, 70,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 71, 72, 73, 74,
+   75, 76, 77, 78, 79,  0,
+};
+static const uint16_t
+_hb_ucd_u16[11168] =
+{
+     0,   0,   1,   2,   3,   4,   5,   6,   0,   0,   7,   8,   9,  10,  11,  12,
+    13,  13,  13,  14,  15,  13,  13,  16,  17,  18,  19,  20,  21,  22,  13,  23,
+    13,  13,  13,  24,  25,  11,  11,  11,  11,  26,  11,  27,  28,  29,  30,  31,
+    32,  32,  32,  32,  32,  32,  32,  33,  34,  35,  36,  11,  37,  38,  13,  39,
+     9,   9,   9,  11,  11,  11,  13,  13,  40,  13,  13,  13,  41,  13,  13,  13,
+    13,  13,  13,  42,   9,  43,  11,  11,  44,  45,  32,  46,  47,  48,  49,  50,
+    51,  52,  48,  48,  53,  32,  54,  55,  48,  48,  48,  48,  48,  56,  57,  58,
+    59,  60,  48,  32,  61,  48,  48,  48,  48,  48,  62,  63,  64,  48,  65,  66,
+    48,  67,  68,  69,  48,  70,  71,  72,  72,  72,  48,  73,  72,  74,  75,  32,
+    76,  48,  48,  77,  78,  79,  80,  81,  82,  83,  84,  85,  86,  87,  88,  89,
+    90,  83,  84,  91,  92,  93,  94,  95,  96,  97,  84,  98,  99, 100,  88, 101,
+   102,  83,  84, 103, 104, 105,  88, 106, 107, 108, 109, 110, 111, 112,  94, 113,
+   114, 115,  84, 116, 117, 118,  88, 119, 120, 115,  84, 121, 122, 123,  88, 124,
+   125, 115,  48, 126, 127, 128,  88, 129, 130, 131,  48, 132, 133, 134,  94, 135,
+   136,  48,  48, 137, 138, 139,  72,  72, 140,  48, 141, 142, 143, 144,  72,  72,
+   145, 146, 147, 148, 149,  48, 150, 151, 152, 153,  32, 154, 155, 156,  72,  72,
+    48,  48, 157, 158, 159, 160, 161, 162, 163, 164,   9,   9, 165,  11,  11, 166,
+    48,  48,  48,  48,  48,  48,  48,  48,  48,  48,  48,  48,  48,  48,  48,  48,
+    48,  48,  48,  48, 167, 168,  48,  48, 167,  48,  48, 169, 170, 171,  48,  48,
+    48, 170,  48,  48,  48, 172, 173, 174,  48, 175,   9,   9,   9,   9,   9, 176,
+   177,  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,  48,
+    48,  48,  48,  48,  48,  48, 178,  48, 179, 180,  48,  48,  48,  48, 181, 182,
+   183, 184,  48, 185,  48, 186, 183, 187,  48,  48,  48, 188, 189, 190, 191, 192,
+   193, 191,  48,  48, 194,  48,  48, 195, 196,  48, 197,  48,  48,  48,  48, 198,
+    48, 199, 200, 201, 202,  48, 203, 204,  48,  48, 205,  48, 206, 207, 208, 208,
+    48, 209,  48,  48,  48, 210, 211, 212, 191, 191, 213, 214,  72,  72,  72,  72,
+   215,  48,  48, 216, 217, 159, 218, 219, 220,  48, 221,  64,  48,  48, 222, 223,
+    48,  48, 224, 225, 226,  64,  48, 227, 228,   9,   9, 229, 230, 231, 232, 233,
+    11,  11, 234,  27,  27,  27, 235, 236,  11, 237,  27,  27,  32,  32,  32, 238,
+    13,  13,  13,  13,  13,  13,  13,  13,  13, 239,  13,  13,  13,  13,  13,  13,
+   240, 241, 240, 240, 241, 242, 240, 243, 244, 244, 244, 245, 246, 247, 248, 249,
+   250, 251, 252, 253, 254, 255, 256, 257, 258, 259, 260, 260,  72, 261, 262, 263,
+   264, 265, 266, 267, 268, 269, 270, 270, 271, 272, 273, 208, 274, 275, 208, 276,
+   277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277,
+   278, 208, 279, 208, 208, 208, 208, 280, 208, 281, 277, 282, 208, 283, 284, 208,
+   208, 208, 285,  72, 286,  72, 269, 269, 269, 287, 208, 208, 208, 208, 288, 269,
+   208, 208, 208, 208, 208, 208, 208, 208, 208, 208, 208, 289, 290, 208, 208, 291,
+   208, 208, 208, 208, 208, 208, 292, 208, 208, 208, 208, 208, 208, 208, 208, 208,
+   208, 208, 208, 208, 208, 208, 293, 294, 269, 295, 208, 208, 296, 277, 297, 277,
+   208, 208, 208, 208, 208, 208, 208, 208, 208, 208, 208, 208, 208, 208, 208, 208,
+   277, 277, 277, 277, 277, 277, 277, 277, 298, 299, 277, 277, 277, 300, 277, 301,
+   277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277,
+   208, 208, 208, 277, 302, 208, 208, 303, 208, 304, 208, 208, 208, 208, 208, 208,
+     9,   9, 305,  11,  11, 306, 307, 308,  13,  13,  13,  13,  13,  13, 309, 310,
+    11,  11, 311,  48,  48,  48, 312, 313,  48, 314, 315, 315, 315, 315,  32,  32,
+   316, 317, 318, 319, 320,  72,  72,  72, 208, 321, 208, 208, 208, 208, 208, 322,
+   208, 208, 208, 208, 208, 208, 208, 208, 208, 208, 208, 208, 208, 323,  72, 324,
+   325, 326, 327, 328, 136,  48,  48,  48,  48, 329, 177,  48,  48,  48,  48, 330,
+   331,  48,  48, 136,  48,  48,  48,  48, 199, 332,  48,  71, 208, 208, 322,  48,
+   208, 333, 334, 208, 335, 336, 208, 208, 334, 208, 208, 336, 208, 208, 208, 208,
+   208, 208, 208, 208, 208, 208, 208, 208, 208, 208, 208, 208, 208, 208, 208, 208,
+    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,  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, 198, 208, 208, 208, 208,
+    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,  48,  72,
+    48, 337,  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,
+    48,  48,  48,  48,  48,  48,  48,  48, 150, 208, 208, 208, 285,  48,  48, 227,
+    48,  48,  48,  48,  48,  48,  48,  48,  48,  48,  48,  48,  48,  48,  48,  48,
+   338,  48, 339,  72,  13,  13, 340, 341,  13, 342,  48,  48,  48,  48, 343, 344,
+    31, 345, 346, 347,  13,  13,  13, 348, 349, 350, 351, 352, 353,  72,  72, 354,
+   355,  48, 356, 357,  48,  48,  48, 358, 359,  48,  48, 360, 361, 191,  32, 362,
+    64,  48, 363,  48, 364, 365,  48, 150,  76,  48,  48, 366, 367, 368, 369, 370,
+    48,  48, 371, 372, 373, 374,  48, 375,  48,  48,  48, 376, 377, 378, 379, 380,
+   381, 382, 315,  11,  11, 383, 384,  11,  11,  11,  11,  11,  48,  48, 385, 191,
+    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, 386,  48, 387,  48,  48, 205,
+   388, 388, 388, 388, 388, 388, 388, 388, 388, 388, 388, 388, 388, 388, 388, 388,
+   388, 388, 388, 388, 388, 388, 388, 388, 388, 388, 388, 388, 388, 388, 388, 388,
+   389, 389, 389, 389, 389, 389, 389, 389, 389, 389, 389, 389, 389, 389, 389, 389,
+   389, 389, 389, 389, 389, 389, 389, 389, 389, 389, 389, 389, 389, 389, 389, 389,
+   389, 389, 389, 389, 389, 389, 389, 389, 389, 389, 389, 389, 389, 389, 389, 389,
+    48,  48,  48,  48,  48,  48,  48,  48,  48,  48,  48,  48,  48,  48,  48,  48,
+    48,  48,  48,  48,  48,  48, 203,  48,  48,  48,  48,  48,  48, 206,  72,  72,
+   390, 391, 392, 393, 394,  48,  48,  48,  48,  48,  48, 395, 396, 397,  48,  48,
+    48,  48,  48,  48,  48,  48,  48,  48,  48,  48,  48,  48,  48,  48,  48,  48,
+    48,  48,  48, 398,  72,  48,  48,  48,  48, 399,  48,  48, 400,  72,  72, 401,
+    32, 402,  32, 403, 404, 405, 406, 407,  48,  48,  48,  48,  48,  48,  48, 408,
+   409,   2,   3,   4,   5, 410, 411, 412,  48, 413,  48, 199, 414, 415, 416, 417,
+   418,  48, 171, 419, 203, 203,  72,  72,  48,  48,  48,  48,  48,  48,  48,  71,
+   420, 269, 269, 421, 270, 270, 270, 422, 423, 324, 424,  72,  72, 208, 208, 425,
+    72,  72,  72,  72,  72,  72,  72,  72,  48, 150,  48,  48,  48, 100, 426, 427,
+    48,  48, 428,  48, 429,  48,  48, 430,  48, 431,  48,  48, 432, 433,  72,  72,
+     9,   9, 434,  11,  11,  48,  48,  48,  48, 203, 191,   9,   9, 435,  11, 436,
+    48,  48, 400,  48,  48,  48, 437,  72,  72,  72,  72,  72,  72,  72,  72,  72,
+    48,  48,  48,  48,  48,  48,  48,  48,  48,  48,  48,  48,  48,  48,  48,  48,
+    48,  48,  48, 314,  48, 198, 400,  72,  72,  72,  72,  72,  72,  72,  72,  72,
+   438,  48,  48, 439,  48, 440,  48, 441,  48, 199, 442,  72,  72,  72,  48, 443,
+    48, 444,  48, 445,  72,  72,  72,  72,  48,  48,  48, 446, 269, 447, 269, 269,
+   448, 449,  48, 450, 451, 452,  48, 453,  48, 454,  72,  72, 455,  48, 456, 457,
+    48,  48,  48, 458,  48, 459,  48, 460,  48, 461, 462,  72,  72,  72,  72,  72,
+    48,  48,  48,  48, 195,  72,  72,  72,   9,   9,   9, 463,  11,  11,  11, 464,
+    48,  48, 465, 191,  72,  72,  72,  72,  72,  72,  72,  72,  72,  72,  72,  72,
+    72,  72,  72,  72,  72,  72, 269, 466,  72,  72,  72,  72,  72,  72,  72,  72,
+    48, 454, 467,  48,  62, 468,  72,  72,  72,  72,  72,  72,  72,  72,  48, 314,
+   469,  48,  48, 470, 471, 447, 472, 473, 220,  48,  48, 474, 475,  48, 195, 191,
+   476,  48, 477, 478, 479,  48,  48, 480, 220,  48,  48, 481, 482, 483, 484, 485,
+    48,  97, 486, 487,  72,  72,  72,  72, 488, 489, 490,  48,  48, 491, 492, 191,
+   493,  83,  84, 494, 495, 496, 497, 498,  72,  72,  72,  72,  72,  72,  72,  72,
+    48,  48,  48, 499, 500, 501,  72,  72,  48,  48,  48, 502, 503, 191,  72,  72,
+    72,  72,  72,  72,  72,  72,  72,  72,  48,  48, 504, 505, 506, 507,  72,  72,
+    48,  48,  48, 508, 509, 191, 510,  72,  48,  48, 511, 512, 191,  72,  72,  72,
+    48, 172, 513, 514,  72,  72,  72,  72,  72,  72,  72,  72,  72,  72,  72,  72,
+    48,  48, 486, 515,  72,  72,  72,  72,  72,  72,   9,   9,  11,  11, 147, 516,
+    72,  72,  72,  72,  72,  72,  72,  72,  72,  72, 517,  48,  48, 518, 519,  72,
+   520,  48,  48, 521, 522, 523,  48,  48, 524, 525, 526,  72,  48,  48,  48, 195,
+    72,  72,  72,  72,  72,  72,  72,  72,  72,  72,  72,  72,  72,  72,  72,  72,
+    84,  48, 504, 527, 528, 147, 174, 529,  48, 530, 531, 532,  72,  72,  72,  72,
+   533,  48,  48, 534, 535, 191, 536,  48, 537, 538, 191,  72,  72,  72,  72,  72,
+    72,  72,  72,  72,  72,  72,  72,  72,  72,  72,  72,  72,  72,  72,  48, 539,
+    72,  72,  72,  72,  72,  72,  72,  72,  72,  72,  72,  72, 269, 540, 541, 542,
+    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, 206,  72,  72,  72,  72,  72,  72,
+   270, 270, 270, 270, 270, 270, 543, 544,  48,  48,  48,  48,  48,  48,  48,  48,
+    48,  48,  48,  48, 386,  72,  72,  72,  72,  72,  72,  72,  72,  72,  72,  72,
+    72,  72,  72,  72,  72,  72,  72,  72,  72,  72,  72,  72,  72,  72,  72,  72,
+    72,  72,  72,  72,  72,  72,  72,  72,  72,  72,  72,  72,  72,  72,  72,  72,
+    48,  48, 199, 545,  72,  72,  72,  72,  72,  72,  72,  72,  72,  72,  72,  72,
+    72,  72,  72,  72,  72,  72,  72,  72,  72,  72,  72,  72,  72,  72,  72,  72,
+    48,  48,  48,  48, 314,  72,  72,  72,  72,  72,  72,  72,  72,  72,  72,  72,
+    72,  72,  72,  72,  72,  72,  72,  72,  72,  72,  72,  72,  72,  72,  72,  72,
+    48,  48,  48, 195,  48, 199, 368,  72,  72,  72,  72,  72,  72,  48, 203, 546,
+    48,  48,  48, 547, 548, 549, 550, 551,  48,  72,  72,  72,  72,  72,  72,  72,
+    72,  72,  72,  72,   9,   9,  11,  11, 269, 552,  72,  72,  72,  72,  72,  72,
+    48,  48,  48,  48, 553, 554, 555, 555, 556, 557,  72,  72,  72,  72, 558,  72,
+    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,  48, 400,
+    48,  48,  48,  48,  48,  48,  48,  48,  48,  48,  48,  48,  48,  48,  48, 559,
+    72,  72,  72,  72,  72,  72,  72,  72,  72,  72,  72,  72,  72,  72,  72,  72,
+    48,  48,  48,  48,  48,  48,  48,  48,  48,  48,  48,  48,  48,  48,  48,  48,
+    48, 199,  72,  72,  72, 559, 560,  48,  48,  48,  48,  48,  48,  48,  48,  48,
+    48,  48,  48,  48,  48,  48,  48,  48,  48,  48,  48,  48,  48,  48,  48, 205,
+    72,  72,  72,  72,  72,  72,  72,  72,  72,  72,  72,  72,  72,  72,  72,  72,
+    48,  48,  48,  48,  48,  48,  71, 150, 195, 561, 562,  72,  72,  72,  72,  72,
+    72,  72,  72,  72,  72,  72,  72,  72,  72,  72,  72,  72,  72,  72,  72,  72,
+   208, 208, 208, 208, 208, 208, 208, 208, 208, 208, 208, 208, 208, 208, 208, 323,
+   208, 208, 563, 208, 208, 208, 564, 565, 566, 208, 567, 208, 208, 208, 568,  72,
+   208, 208, 208, 208, 569,  72,  72,  72,  72,  72,  72,  72,  72,  72, 269, 570,
+   208, 208, 208, 208, 208, 285, 269, 451,  72,  72,  72,  72,  72,  72,  72,  72,
+     9, 571,  11, 572, 573, 574, 240,   9, 575, 576, 577, 578, 579,   9, 571,  11,
+   580, 581,  11, 582, 583, 584, 585,   9, 586,  11,   9, 571,  11, 572, 573,  11,
+   240,   9, 575, 585,   9, 586,  11,   9, 571,  11, 587,   9, 588, 589, 590, 591,
+    11, 592,   9, 593, 594, 595, 596,  11, 597,   9, 598,  11, 599, 600, 600, 600,
+   208, 208, 208, 208, 208, 208, 208, 208, 208, 208, 208, 208, 208, 208, 208, 208,
+   208, 208, 208, 208, 208, 208, 208, 208, 208, 208, 208, 208, 208, 208, 208, 208,
+    32,  32,  32, 601,  32,  32, 602, 603, 604, 605,  45,  72,  72,  72,  72,  72,
+    72,  72,  72,  72,  72,  72,  72,  72,  72,  72,  72,  72,  72,  72,  72,  72,
+   606, 607, 608,  72,  72,  72,  72,  72,  72,  72,  72,  72,  72,  72,  72,  72,
+    48,  48, 150, 609, 610,  72,  72,  72,  72,  72,  72,  72,  72,  72,  72,  72,
+    72,  72,  72,  72,  72,  72,  72,  72,  72,  72,  72,  72,  48,  48, 611, 612,
+    72,  72,  72,  72,  72,  72,  72,  72,  72,  72,  72,  72,  72,  72,  72,  72,
+    48,  48,  48,  48,  48,  48,  48,  48,  48,  48,  48,  48, 613, 614,  72,  72,
+     9,   9, 575,  11, 615, 368,  72,  72,  72,  72,  72,  72,  72,  72,  72,  72,
+    72,  72,  72,  72,  72,  72,  72, 484, 269, 269, 616, 617,  72,  72,  72,  72,
+   484, 269, 618, 619,  72,  72,  72,  72,  72,  72,  72,  72,  72,  72,  72,  72,
+   620,  48, 621, 622, 623, 624, 625, 626, 627, 205, 628, 205,  72,  72,  72, 629,
+    72,  72,  72,  72,  72,  72,  72,  72,  72,  72,  72,  72,  72,  72,  72,  72,
+   208, 208, 324, 208, 208, 208, 208, 208, 208, 322, 333, 630, 630, 630, 208, 323,
+   174, 208, 208, 208, 208, 208, 631, 208, 208, 208, 631,  72,  72,  72, 632, 208,
+   633, 208, 208, 324, 568, 634, 323,  72,  72,  72,  72,  72,  72,  72,  72,  72,
+   208, 208, 208, 208, 208, 208, 208, 208, 208, 208, 208, 208, 208, 208, 208, 635,
+   208, 208, 208, 208, 208, 208, 208, 208, 208, 208, 208, 208, 208, 323, 631, 286,
+   208, 208, 208, 208, 208, 208, 208, 322, 208, 208, 208, 208, 208, 568, 324,  72,
+   324, 208, 208, 208, 636, 175, 208, 208, 636, 208, 637,  72,  72,  72,  72,  72,
+   638, 208, 208, 208, 208, 208, 208, 639, 208, 208, 640, 208, 641, 208, 208, 208,
+   208, 208, 208, 208, 208, 322, 637, 642, 633, 323,  72,  72,  72,  72,  72,  72,
+    72,  72,  72,  72,  72,  72,  72,  72,  72,  72,  72,  72,  72,  72,  72,  72,
+    48,  48,  48,  48,  48,  48,  48,  48,  48,  48,  48,  48,  48, 314,  72,  72,
+    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,  48,  48,
+    48,  48,  48, 204,  48,  48,  48,  48,  48,  48,  48,  48,  48,  48,  48,  48,
+    48, 203,  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,
+    48,  48,  48,  48,  48,  48,  48,  48,  48,  48, 643,  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,  48,  48,  48,  48,  48,  48,  48,
+    48,  48,  48,  48,  48,  48,  48,  48,  48,  48,  48,  48,  48,  48, 100,  72,
+    48, 203,  72,  72,  72,  72,  72,  72,  72,  72,  72,  72,  72,  72,  72,  72,
+    72,  72,  72,  72,  72,  72,  72,  72,  72,  72,  72,  72,  72,  72,  72,  72,
+   644,  72, 645, 645, 645, 645, 645, 645,  72,  72,  72,  72,  72,  72,  72,  72,
+    32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  72,
+   389, 389, 389, 389, 389, 389, 389, 389, 389, 389, 389, 389, 389, 389, 389, 389,
+   389, 389, 389, 389, 389, 389, 389, 389, 389, 389, 389, 389, 389, 389, 389, 646,
+   389, 389, 389, 389, 389, 389, 389, 389, 389, 389, 389, 389, 389, 389, 389, 389,
+   389, 389, 389, 389, 389, 389, 389, 389, 389, 389, 389, 389, 389, 389, 389, 647,
+     0,   0,   0,   0,   1,   2,   1,   2,   0,   0,   3,   3,   4,   5,   4,   5,
+     4,   4,   4,   4,   4,   4,   4,   4,   4,   4,   4,   4,   4,   4,   4,   4,
+     4,   4,   4,   4,   4,   4,   4,   4,   4,   4,   4,   6,   0,   0,   7,   0,
+     8,   8,   8,   8,   8,   8,   8,   9,  10,  11,  12,  11,  11,  11,  13,  11,
+    14,  14,  14,  14,  14,  14,  14,  14,  15,  14,  14,  14,  14,  14,  14,  14,
+    14,  14,  14,  16,  17,  18,  17,  17,  19,  20,  21,  21,  22,  21,  23,  24,
+    25,  26,  27,  27,  28,  29,  27,  30,  27,  27,  27,  27,  27,  31,  27,  27,
+    32,  33,  33,  33,  34,  27,  27,  27,  35,  35,  35,  36,  37,  37,  37,  38,
+    39,  39,  40,  41,  42,  43,  44,  45,  45,  45,  27,  46,  45,  47,  48,  27,
+    49,  49,  49,  49,  49,  50,  51,  49,  52,  53,  54,  55,  56,  57,  58,  59,
+    60,  61,  62,  63,  64,  65,  66,  67,  68,  69,  70,  71,  72,  73,  74,  75,
+    76,  77,  78,  79,  80,  81,  82,  83,  84,  85,  86,  87,  88,  89,  90,  91,
+    92,  93,  94,  95,  96,  97,  98,  99, 100, 101, 102, 103, 104, 105, 106, 107,
+   108, 109, 110, 110, 111, 112, 113, 110, 114, 115, 116, 117, 118, 119, 120, 121,
+   122, 123, 123, 124, 123, 125,  45,  45, 126, 127, 128, 129, 130, 131,  45,  45,
+   132, 132, 132, 132, 133, 132, 134, 135, 132, 133, 132, 136, 136, 137,  45,  45,
+   138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 139, 139, 140, 139, 139, 141,
+   142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142,
+   143, 143, 143, 143, 144, 145, 143, 143, 144, 143, 143, 146, 147, 148, 143, 143,
+   143, 147, 143, 143, 143, 149, 143, 150, 143, 151, 152, 152, 152, 152, 152, 153,
+   154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154,
+   154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154,
+   154, 154, 154, 154, 154, 154, 154, 154, 155, 156, 157, 157, 157, 157, 158, 159,
+   160, 161, 162, 163, 164, 165, 166, 167, 168, 168, 168, 168, 168, 169, 170, 170,
+   171, 172, 173, 173, 173, 173, 173, 174, 173, 173, 175, 154, 154, 154, 154, 176,
+   177, 178, 179, 179, 180, 181, 182, 183, 184, 184, 185, 184, 186, 187, 168, 168,
+   188, 189, 190, 190, 190, 191, 190, 192, 193, 193, 194, 195,  45,  45,  45,  45,
+   196, 196, 196, 196, 197, 196, 196, 198, 199, 199, 199, 199, 200, 200, 200, 201,
+   202, 202, 202, 203, 204, 205, 205, 205, 206, 139, 139, 207, 208, 209, 210, 211,
+     4,   4, 212,   4,   4, 213, 214, 215,   4,   4,   4, 216,   8,   8,   8, 217,
+     4,   4,   4,   4,   4,   4,   4,   4,   4,   4,   4,   4,   4,   4,   4,   4,
+    11, 218,  11,  11, 218, 219,  11, 220,  11,  11,  11, 221, 221, 222,  11, 223,
+   224,   0,   0,   0,   0,   0, 225, 226, 227, 228,   0,   0,  45,   8,   8, 229,
+     0,   0, 230, 231, 232,   0,   4,   4, 233,   0,   0,   0,   0,   0,   0,   0,
+     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+     0,   0, 234,  45, 235,  45,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+   236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236,
+     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+     0,   0,   0,   0,   0,   0,   0, 237,   0, 238,   0,   0,   0,   0,   0,   0,
+   239, 239, 240, 239, 239, 240,   4,   4, 241, 241, 241, 241, 241, 241, 241, 242,
+   139, 139, 140, 243, 243, 243, 244, 245, 143, 246, 247, 247, 247, 247,  14,  14,
+     0,   0,   0,   0,   0,  45,  45,  45, 248, 249, 248, 248, 248, 248, 248, 250,
+   248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 251,  45, 252,
+   253,   0, 254, 255, 256, 257, 257, 257, 257, 258, 259, 260, 260, 260, 260, 261,
+   262, 263, 263, 264, 142, 142, 142, 142, 265,   0, 263, 266,   0,   0, 267, 260,
+   142, 265,   0,   0,   0,   0, 142, 268,   0,   0,   0,   0,   0, 260, 260, 269,
+   260, 260, 260, 260, 260, 270,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+   248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248,
+   248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248,
+   248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248,
+   248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 251,   0,   0,   0,   0,
+   248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248,
+   248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248,  45,
+   271, 271, 271, 271, 271, 271, 271, 271, 271, 271, 271, 271, 271, 271, 271, 271,
+   271, 271, 271, 271, 271, 271, 271, 271, 271, 271, 271, 271, 271, 271, 271, 271,
+   271, 271, 271, 271, 271, 271, 271, 271, 272, 271, 271, 271, 273, 274, 274, 274,
+   275, 275, 275, 275, 275, 275, 275, 275, 275, 275, 275, 275, 275, 275, 275, 275,
+   275, 275, 276,  45,  14,  14,  14,  14,  14,  14, 277, 277, 277, 277, 277, 278,
+     0,   0, 279,   4,   4,   4,   4,   4, 280,   4,   4,   4, 281,  45,  45, 282,
+   283, 283, 284, 285, 286, 286, 286, 287, 288, 288, 288, 288, 289, 290,  49,  49,
+   291, 291, 292, 293, 293, 294, 142, 295, 296, 296, 296, 296, 297, 298, 138, 299,
+   300, 300, 300, 301, 302, 303, 138, 138, 304, 304, 304, 304, 305, 306, 307, 308,
+   309, 310, 247,   4,   4, 311, 312, 152, 152, 152, 152, 152, 307, 307, 313, 314,
+   142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142,
+   142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142,
+   142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142,
+   142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 315, 142, 316, 142, 142, 317,
+    45,  45,  45,  45,  45,  45,  45,  45,  45,  45,  45,  45,  45,  45,  45,  45,
+    45,  45,  45,  45,  45,  45,  45,  45,  45,  45,  45,  45,  45,  45,  45,  45,
+    45,  45,  45,  45,  45,  45,  45,  45,  45,  45,  45,  45,  45,  45,  45,  45,
+   248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248,
+   248, 248, 248, 248, 248, 248, 318, 248, 248, 248, 248, 248, 248, 319,  45,  45,
+   320, 321,  21, 322, 323,  27,  27,  27,  27,  27,  27,  27, 324,  47,  27,  27,
+    27,  27,  27,  27,  27,  27,  27,  27,  27,  27,  27,  27,  27,  27,  27,  27,
+    27,  27,  27, 325,  45,  27,  27,  27,  27, 326,  27,  27, 327,  45,  45, 328,
+     8, 285, 329,   0,   0, 330, 331, 332,  27,  27,  27,  27,  27,  27,  27, 333,
+   334,   0,   1,   2,   1,   2, 335, 259, 260, 336, 142, 265, 337, 338, 339, 340,
+   341, 342, 343, 344, 345, 345,  45,  45, 342, 342, 342, 342, 342, 342, 342, 346,
+   347,   0,   0, 348,  11,  11,  11,  11, 349, 252, 350,  45,  45,   0,   0, 351,
+    45,  45,  45,  45,  45,  45,  45,  45, 352, 353, 354, 354, 354, 355, 356, 252,
+   357, 357, 358, 359, 360, 361, 361, 362, 363, 364, 365, 365, 366, 367,  45,  45,
+   368, 368, 368, 368, 368, 369, 369, 369, 370, 371, 372, 373, 373, 374, 373, 375,
+   376, 376, 377, 378, 378, 378, 379,  45,  45,  45,  45,  45,  45,  45,  45,  45,
+   380, 380, 380, 380, 380, 380, 380, 380, 380, 380, 380, 380, 380, 380, 380, 380,
+   380, 380, 380, 381, 380, 382, 383,  45,  45,  45,  45,  45,  45,  45,  45,  45,
+   384, 385, 385, 386, 387, 388, 389, 389, 390, 391, 392,  45,  45,  45, 393, 394,
+   395, 396, 397, 398,  45,  45,  45,  45, 399, 399, 400, 401, 400, 402, 400, 400,
+   403, 404, 405, 406, 407, 407, 408, 408, 409, 409,  45,  45, 410, 410, 411, 412,
+   413, 413, 413, 414, 415, 416, 417, 418, 419, 420, 421,  45,  45,  45,  45,  45,
+   422, 422, 422, 422, 423,  45,  45,  45, 424, 424, 424, 425, 424, 424, 424, 426,
+   427, 427, 428, 429,  45,  45,  45,  45,  45,  45,  45,  45,  45,  45,  45,  45,
+    45,  45,  45,  45,  45,  45,  27, 430,  45,  45,  45,  45,  45,  45,  45,  45,
+   431, 431, 432, 433, 433, 434,  45,  45,  45,  45,  45,  45,  45,  45, 435, 436,
+   437, 437, 437, 437, 438, 439, 437, 440, 441, 441, 441, 441, 442, 443, 444, 445,
+   446, 446, 446, 447, 448, 449, 449, 450, 451, 451, 451, 451, 452, 451, 453, 454,
+   455, 456, 455, 457,  45,  45,  45,  45, 458, 459, 460, 461, 461, 461, 462, 463,
+   464, 465, 466, 467, 468, 469, 470, 471,  45,  45,  45,  45,  45,  45,  45,  45,
+   472, 472, 472, 472, 472, 473,  45,  45, 474, 474, 474, 474, 475, 476,  45,  45,
+    45,  45,  45,  45,  45,  45,  45,  45, 477, 477, 477, 478, 477, 479,  45,  45,
+   480, 480, 480, 480, 481, 482, 483,  45, 484, 484, 484, 485, 486,  45,  45,  45,
+   487, 488, 489, 487,  45,  45,  45,  45,  45,  45,  45,  45,  45,  45,  45,  45,
+   490, 490, 490, 491,  45,  45,  45,  45,  45,  45, 492, 492, 492, 492, 492, 493,
+    45,  45,  45,  45,  45,  45,  45,  45,  45,  45, 494, 495, 495, 494, 496,  45,
+   497, 497, 497, 497, 498, 499, 499, 499, 499, 499, 500,  45, 501, 501, 501, 502,
+    45,  45,  45,  45,  45,  45,  45,  45,  45,  45,  45,  45,  45,  45,  45,  45,
+   503, 504, 504, 505, 506, 504, 507, 508, 508, 509, 510, 511,  45,  45,  45,  45,
+   512, 513, 513, 514, 515, 516, 517, 518, 519, 520, 521,  45,  45,  45,  45,  45,
+    45,  45,  45,  45,  45,  45,  45,  45,  45,  45,  45,  45,  45,  45, 522, 523,
+    45,  45,  45,  45,  45,  45,  45,  45,  45,  45,  45,  45, 524, 524, 524, 525,
+   526, 526, 526, 526, 526, 526, 526, 526, 526, 526, 526, 526, 526, 526, 526, 526,
+   526, 526, 526, 526, 526, 526, 526, 526, 526, 526, 526, 526, 526, 526, 526, 526,
+   526, 526, 526, 526, 526, 526, 526, 526, 526, 526, 526, 526, 526, 526, 526, 526,
+   526, 526, 526, 526, 526, 526, 526, 526, 526, 527,  45,  45,  45,  45,  45,  45,
+   526, 526, 526, 526, 526, 526, 528, 529, 526, 526, 526, 526, 526, 526, 526, 526,
+   526, 526, 526, 526, 530,  45,  45,  45,  45,  45,  45,  45,  45,  45,  45,  45,
+   531, 531, 531, 531, 531, 531, 531, 531, 531, 531, 531, 531, 531, 531, 531, 531,
+   531, 531, 531, 531, 531, 531, 531, 531, 531, 531, 531, 531, 531, 531, 531, 531,
+   531, 531, 532, 533,  45,  45,  45,  45,  45,  45,  45,  45,  45,  45,  45,  45,
+    45,  45,  45,  45,  45,  45,  45,  45,  45,  45,  45,  45,  45,  45,  45,  45,
+   534, 534, 534, 534, 534, 534, 534, 534, 534, 534, 534, 534, 534, 534, 534, 534,
+   534, 534, 534, 534, 534, 534, 534, 534, 534, 534, 534, 534, 534, 534, 534, 534,
+   534, 534, 534, 534, 535,  45,  45,  45,  45,  45,  45,  45,  45,  45,  45,  45,
+    45,  45,  45,  45,  45,  45,  45,  45,  45,  45,  45,  45,  45,  45,  45,  45,
+   277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277,
+   277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277,
+   277, 277, 277, 536, 537, 538, 539,  45,  45,  45,  45,  45,  45, 540, 541, 542,
+   543, 543, 543, 543, 544, 545, 546, 547, 543,  45,  45,  45,  45,  45,  45,  45,
+    45,  45,  45,  45, 548, 548, 548, 548, 548, 549,  45,  45,  45,  45,  45,  45,
+   550, 550, 550, 550, 551, 550, 550, 550, 552, 550,  45,  45,  45,  45, 553,  45,
+   554, 554, 554, 554, 554, 554, 554, 554, 554, 554, 554, 554, 554, 554, 554, 554,
+   554, 554, 554, 554, 554, 554, 554, 554, 554, 554, 554, 554, 554, 554, 554, 554,
+   554, 554, 554, 554, 554, 554, 554, 554, 554, 554, 554, 554, 554, 554, 554, 554,
+   554, 554, 554, 554, 554, 554, 554, 554, 554, 554, 554, 554, 554, 554, 554, 555,
+   554, 554, 554, 554, 554, 554, 554, 554, 554, 554, 554, 554, 554, 554, 554, 556,
+    45,  45,  45,  45,  45,  45,  45,  45,  45,  45,  45,  45,  45,  45,  45,  45,
+   557, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 257,
+   257, 558,  45,  45,  45, 559, 560, 561, 561, 561, 561, 561, 561, 561, 561, 561,
+   561, 561, 561, 561, 561, 561, 561, 561, 561, 561, 561, 561, 561, 561, 561, 562,
+    45,  45,  45,  45,  45,  45,  45,  45,  45,  45,  45,  45,  45,  45,  45,  45,
+   563, 563, 563, 563, 563, 563, 564, 565, 566, 567, 267,  45,  45,  45,  45,  45,
+    45,  45,  45,  45,  45,  45,  45,  45,  45,  45,  45,  45,  45,  45,  45,  45,
+     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0, 568,
+     0,   0, 569,   0,   0,   0, 570, 571, 572,   0, 573,   0,   0,   0, 574,  45,
+    11,  11,  11,  11, 575,  45,  45,  45,  45,  45,  45,  45,  45,  45,   0, 267,
+     0,   0,   0,   0,   0, 234,   0, 574,  45,  45,  45,  45,  45,  45,  45,  45,
+     0,   0,   0,   0,   0, 225,   0,   0,   0, 576, 577, 578, 579,   0,   0,   0,
+   580, 581,   0, 582, 583, 584,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+     0,   0,   0,   0,   0,   0,   0,   0,   0,   0, 238,   0,   0,   0,   0,   0,
+     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0, 585,   0,   0,   0,
+   586, 586, 586, 586, 586, 586, 586, 586, 586, 586, 586, 586, 586, 586, 586, 586,
+   586, 586, 586, 586, 586, 586, 586, 586, 586, 586, 586, 586, 586, 586, 586, 586,
+   586, 586, 586, 586, 586, 586, 586, 586, 587, 588, 589,  45,  45,  45,  45,  45,
+    45,  45,  45,  45,  45,  45,  45,  45,  45,  45,  45,  45,  45,  45,  45,  45,
+   590, 591, 592,  45,  45,  45,  45,  45,  45,  45,  45,  45,  45,  45,  45,  45,
+   593, 593, 594, 595, 596,  45,  45,  45,  45,  45,  45,  45,  45,  45,  45,  45,
+    45,  45,  45,  45,  45,  45,  45,  45,  45,  45,  45,  45, 597, 597, 597, 598,
+    45,  45,  45,  45,  45,  45,  45,  45,  45,  45,  45,  45,  45,  45,  45,  45,
+   599, 599, 599, 599, 599, 599, 599, 599, 599, 599, 599, 599, 600, 601,  45,  45,
+   602, 602, 602, 602, 603, 604,  45,  45,  45,  45,  45,  45,  45,  45,  45,  45,
+    45,  45,  45,  45,  45,  45,  45, 334,   0,   0,   0, 605,  45,  45,  45,  45,
+   334,   0,   0, 606,  45,  45,  45,  45,  45,  45,  45,  45,  45,  45,  45,  45,
+   607,  27, 608, 609, 610, 611, 612, 613, 614, 615, 616, 615,  45,  45,  45, 324,
+    45,  45,  45,  45,  45,  45,  45,  45,  45,  45,  45,  45,  45,  45,  45,  45,
+     0,   0, 252,   0,   0,   0,   0,   0,   0, 267, 227, 334, 334, 334,   0, 568,
+   617,   0,   0,   0,   0,   0, 617,   0,   0,   0, 617,  45,  45,  45, 618,   0,
+   619,   0,   0, 252, 574, 620, 568,  45,  45,  45,  45,  45,  45,  45,  45,  45,
+     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0, 568, 617, 235,
+     0,   0,   0,   0,   0,   0,   0, 267,   0,   0,   0,   0,   0, 574, 252,  45,
+   252,   0,   0,   0, 621, 285,   0,   0, 621,   0, 606,  45,  45,  45,  45,  45,
+   622,   0,   0,   0,   0,   0,   0, 623,   0,   0, 624,   0, 625,   0,   0,   0,
+     0,   0,   0,   0,   0, 267, 606, 626, 627, 568,  45,  45,  45,  45,  45,  45,
+    45,  45,  45,  45,  45,  45,  45,  45,  45,  45,  45,  45,  45,  45,  45,  45,
+   248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 628,  45,  45,
+   248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248,
+   248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248,
+   248, 248, 248, 629, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248,
+   248, 318, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248,
+   248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248,
+   248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 630, 248, 248, 248, 248, 248,
+   248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248,
+   248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248,
+   248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 631,  45,
+   248, 318,  45,  45,  45,  45,  45,  45,  45,  45,  45,  45,  45,  45,  45,  45,
+    45,  45,  45,  45,  45,  45,  45,  45,  45,  45,  45,  45,  45,  45,  45,  45,
+   632,  45,   0,   0,   0,   0,   0,   0,  45,  45,  45,  45,  45,  45,  45,  45,
+     8,   8,   8,   8,   8,   8,   8,   8,   8,   8,   8,   8,   8,   8,   8,   0,
+     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+   939, 940, 941, 942, 946, 948,   0, 962, 969, 970, 971, 976,1001,1002,1003,1008,
+     0,1033,1040,1041,1042,1043,1047,   0,   0,1080,1081,1082,1086,1110,   0,   0,
+  1124,1125,1126,1127,1131,1133,   0,1147,1154,1155,1156,1161,1187,1188,1189,1193,
+     0,1219,1226,1227,1228,1229,1233,   0,   0,1267,1268,1269,1273,1298,   0,1303,
+   943,1128, 944,1129, 954,1139, 958,1143, 959,1144, 960,1145, 961,1146, 964,1149,
+     0,   0, 973,1158, 974,1159, 975,1160, 983,1168, 978,1163, 988,1173, 990,1175,
+   991,1176, 993,1178, 994,1179,   0,   0,1004,1190,1005,1191,1006,1192,1014,1199,
+  1007,   0,   0,   0,1016,1201,1020,1206,   0,1022,1208,1025,1211,1023,1209,   0,
+     0,   0,   0,1032,1218,1037,1223,1035,1221,   0,   0,   0,1044,1230,1045,1231,
+  1049,1235,   0,   0,1058,1244,1064,1250,1060,1246,1066,1252,1067,1253,1072,1258,
+  1069,1255,1077,1264,1074,1261,   0,   0,1083,1270,1084,1271,1085,1272,1088,1275,
+  1089,1276,1096,1283,1103,1290,1111,1299,1115,1118,1307,1120,1309,1121,1310,   0,
+     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+  1053,1239,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,1093,
+  1280,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0, 949,1134,1010,
+  1195,1050,1236,1090,1277,1341,1368,1340,1367,1342,1369,1339,1366,   0,1320,1347,
+  1418,1419,1323,1350,   0,   0, 992,1177,1018,1204,1055,1241,1416,1417,1415,1424,
+  1202,   0,   0,   0, 987,1172,   0,   0,1031,1217,1321,1348,1322,1349,1338,1365,
+   950,1135, 951,1136, 979,1164, 980,1165,1011,1196,1012,1197,1051,1237,1052,1238,
+  1061,1247,1062,1248,1091,1278,1092,1279,1071,1257,1076,1263,   0,   0, 997,1182,
+     0,   0,   0,   0,   0,   0, 945,1130, 982,1167,1337,1364,1335,1362,1046,1232,
+  1422,1423,1113,1301,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+     8,   9,   0,  10,1425,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+     0,   0,   0,   0,   7,   0,   0,   0,   0,   0,   0,   0,   0,   0,   1,   0,
+     0,   0,   0,   0,   0,1314,1427,   5,1434,1438,1443,   0,1450,   0,1455,1461,
+  1514,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,1446,1458,1468,1476,1480,1486,
+  1517,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,1489,1503,1494,1500,1508,   0,
+     0,   0,   0,1520,1521,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+  1526,1528,   0,1525,   0,   0,   0,1522,   0,   0,   0,   0,1536,1532,1539,   0,
+     0,   0,   0,   0,   0,   0,   0,   0,   0,1534,   0,   0,   0,   0,   0,   0,
+     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+     0,   0,   0,   0,   0,   0,   0,   0,   0,1556,   0,   0,   0,   0,   0,   0,
+     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+  1548,1550,   0,1547,   0,   0,   0,1567,   0,   0,   0,   0,1558,1554,1561,   0,
+     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+     0,   0,   0,   0,   0,   0,1568,1569,   0,   0,   0,   0,   0,   0,   0,   0,
+     0,1529,1551,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+  1523,1545,1524,1546,   0,   0,1527,1549,   0,   0,1570,1571,1530,1552,1531,1553,
+     0,   0,1533,1555,1535,1557,1537,1559,   0,   0,1572,1573,1544,1566,1538,1560,
+  1540,1562,1541,1563,1542,1564,   0,   0,1543,1565,   0,   0,   0,   0,   0,   0,
+     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+     0,   0,1606,1607,1609,1608,1610,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+  1613,   0,1611,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+     0,   0,   0,1612,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+     0,   0,   0,   0,   0,   0,   0,   0,   0,1620,   0,   0,   0,   0,   0,   0,
+     0,1623,   0,   0,1624,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+     0,   0,   0,   0,   0,   0,   0,   0,1614,1615,1616,1617,1618,1619,1621,1622,
+     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,1628,1629,   0,   0,   0,
+     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,1625,1626,   0,1627,
+     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+     0,   0,   0,1634,   0,   0,1635,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+     0,   0,   0,   0,   0,   0,   0,   0,   0,1630,1631,1632,   0,   0,1633,   0,
+     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+     0,   0,   0,   0,   0,   0,   0,   0,1639,   0,   0,1638,1640,   0,   0,   0,
+     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,1636,1637,   0,   0,
+     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+     0,   0,   0,   0,1641,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,1642,1644,1643,   0,   0,   0,
+     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+     0,   0,   0,   0,   0,   0,   0,   0,1645,   0,   0,   0,   0,   0,   0,   0,
+     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+  1646,   0,   0,   0,   0,   0,   0,1648,1649,   0,1647,1650,   0,   0,   0,   0,
+     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,1651,1653,1652,   0,   0,   0,
+     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,1654,   0,1655,1657,1656,   0,
+     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+     0,   0,   0,1659,   0,   0,   0,   0,   0,   0,   0,   0,   0,1660,   0,   0,
+     0,   0,1661,   0,   0,   0,   0,1662,   0,   0,   0,   0,1663,   0,   0,   0,
+     0,   0,   0,   0,   0,   0,   0,   0,   0,1658,   0,   0,   0,   0,   0,   0,
+     0,   0,   0,1664,   0,1665,1673,   0,1674,   0,   0,   0,   0,   0,   0,   0,
+     0,1666,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+     0,   0,   0,1668,   0,   0,   0,   0,   0,   0,   0,   0,   0,1669,   0,   0,
+     0,   0,1670,   0,   0,   0,   0,1671,   0,   0,   0,   0,1672,   0,   0,   0,
+     0,   0,   0,   0,   0,   0,   0,   0,   0,1667,   0,   0,   0,   0,   0,   0,
+     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+     0,   0,   0,   0,   0,   0,1675,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+     0,   0,   0,   0,   0,   0,1676,   0,1677,   0,1678,   0,1679,   0,1680,   0,
+     0,   0,1681,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,1682,   0,1683,   0,   0,
+  1684,1685,   0,1686,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+   953,1138, 955,1140, 956,1141, 957,1142,1324,1351, 963,1148, 965,1150, 968,1153,
+   966,1151, 967,1152,1378,1380,1379,1381, 984,1169, 985,1170,1420,1421, 986,1171,
+   989,1174, 995,1180, 998,1183, 996,1181, 999,1184,1000,1185,1015,1200,1329,1356,
+  1017,1203,1019,1205,1021,1207,1024,1210,1687,1688,1027,1213,1026,1212,1028,1214,
+  1029,1215,1030,1216,1034,1220,1036,1222,1039,1225,1038,1224,1334,1361,1336,1363,
+  1382,1384,1383,1385,1056,1242,1057,1243,1059,1245,1063,1249,1689,1690,1065,1251,
+  1068,1254,1070,1256,1386,1387,1388,1389,1691,1692,1073,1259,1075,1262,1079,1266,
+  1078,1265,1095,1282,1098,1285,1097,1284,1390,1391,1392,1393,1099,1286,1100,1287,
+  1101,1288,1102,1289,1105,1292,1104,1291,1106,1294,1107,1295,1108,1296,1114,1302,
+  1119,1308,1122,1311,1123,1312,1186,1260,1293,1305,   0,1394,   0,   0,   0,   0,
+   952,1137, 947,1132,1317,1344,1316,1343,1319,1346,1318,1345,1693,1695,1371,1375,
+  1370,1374,1373,1377,1372,1376,1694,1696, 981,1166, 977,1162, 972,1157,1326,1353,
+  1325,1352,1328,1355,1327,1354,1697,1698,1009,1194,1013,1198,1054,1240,1048,1234,
+  1331,1358,1330,1357,1333,1360,1332,1359,1699,1700,1396,1401,1395,1400,1398,1403,
+  1397,1402,1399,1404,1094,1281,1087,1274,1406,1411,1405,1410,1408,1413,1407,1412,
+  1409,1414,1109,1297,1117,1306,1116,1304,1112,1300,   0,   0,   0,   0,   0,   0,
+  1471,1472,1701,1705,1702,1706,1703,1707,1430,1431,1715,1719,1716,1720,1717,1721,
+  1477,1478,1729,1731,1730,1732,   0,   0,1435,1436,1733,1735,1734,1736,   0,   0,
+  1481,1482,1737,1741,1738,1742,1739,1743,1439,1440,1751,1755,1752,1756,1753,1757,
+  1490,1491,1765,1768,1766,1769,1767,1770,1447,1448,1771,1774,1772,1775,1773,1776,
+  1495,1496,1777,1779,1778,1780,   0,   0,1451,1452,1781,1783,1782,1784,   0,   0,
+  1504,1505,1785,1788,1786,1789,1787,1790,   0,1459,   0,1791,   0,1792,   0,1793,
+  1509,1510,1794,1798,1795,1799,1796,1800,1462,1463,1808,1812,1809,1813,1810,1814,
+  1467,  21,1475,  22,1479,  23,1485,  24,1493,  27,1499,  28,1507,  29,   0,   0,
+  1704,1708,1709,1710,1711,1712,1713,1714,1718,1722,1723,1724,1725,1726,1727,1728,
+  1740,1744,1745,1746,1747,1748,1749,1750,1754,1758,1759,1760,1761,1762,1763,1764,
+  1797,1801,1802,1803,1804,1805,1806,1807,1811,1815,1816,1817,1818,1819,1820,1821,
+  1470,1469,1822,1474,1465,   0,1473,1825,1429,1428,1426,  12,1432,   0,  26,   0,
+     0,1315,1823,1484,1466,   0,1483,1829,1433,  13,1437,  14,1441,1826,1827,1828,
+  1488,1487,1513,  19,   0,   0,1492,1515,1445,1444,1442,  15,   0,1831,1832,1833,
+  1502,1501,1516,  25,1497,1498,1506,1518,1457,1456,1454,  17,1453,1313,  11,   3,
+     0,   0,1824,1512,1519,   0,1511,1830,1449,  16,1460,  18,1464,   4,   0,   0,
+    30,  31,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+     0,   0,   0,   0,   0,   0,  20,   0,   0,   0,   2,   6,   0,   0,   0,   0,
+     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,1834,1835,   0,   0,   0,   0,
+     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,1836,   0,
+     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,1837,1839,1838,
+     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+     0,   0,   0,   0,1840,   0,   0,   0,   0,1841,   0,   0,1842,   0,   0,   0,
+     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+     0,   0,   0,   0,1843,   0,1844,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+     0,1845,   0,   0,1846,   0,   0,1847,   0,1848,   0,   0,   0,   0,   0,   0,
+     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+   937,   0,1850,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,1849, 936, 938,
+  1851,1852,   0,   0,1853,1854,   0,   0,1855,1856,   0,   0,   0,   0,   0,   0,
+  1857,1858,   0,   0,1861,1862,   0,   0,1863,1864,   0,   0,   0,   0,   0,   0,
+     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,1867,1868,1869,1870,
+     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+  1859,1860,1865,1866,   0,   0,   0,   0,   0,   0,1871,1872,1873,1874,   0,   0,
+     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+     0,   0,   0,   0,   0,   0,   0,   0,   0,  32,  33,   0,   0,   0,   0,   0,
+     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,1875,   0,   0,   0,
+     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,1877,   0,1878,   0,
+  1879,   0,1880,   0,1881,   0,1882,   0,1883,   0,1884,   0,1885,   0,1886,   0,
+  1887,   0,1888,   0,   0,1889,   0,1890,   0,1891,   0,   0,   0,   0,   0,   0,
+  1892,1893,   0,1894,1895,   0,1896,1897,   0,1898,1899,   0,1900,1901,   0,   0,
+     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+     0,   0,   0,   0,1876,   0,   0,   0,   0,   0,   0,   0,   0,   0,1902,   0,
+     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,1904,   0,1905,   0,
+  1906,   0,1907,   0,1908,   0,1909,   0,1910,   0,1911,   0,1912,   0,1913,   0,
+  1914,   0,1915,   0,   0,1916,   0,1917,   0,1918,   0,   0,   0,   0,   0,   0,
+  1919,1920,   0,1921,1922,   0,1923,1924,   0,1925,1926,   0,1927,1928,   0,   0,
+     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+     0,   0,   0,   0,1903,   0,   0,1929,1930,1931,1932,   0,   0,   0,1933,   0,
+   710, 385, 724, 715, 455, 103, 186, 825, 825, 242, 751, 205, 241, 336, 524, 601,
+   663, 676, 688, 738, 411, 434, 474, 500, 649, 746, 799, 108, 180, 416, 482, 662,
+   810, 275, 462, 658, 692, 344, 618, 679, 293, 388, 440, 492, 740, 116, 146, 168,
+   368, 414, 481, 527, 606, 660, 665, 722, 781, 803, 809, 538, 553, 588, 642, 758,
+   811, 701, 233, 299, 573, 612, 487, 540, 714, 779, 232, 267, 412, 445, 457, 585,
+   594, 766, 167, 613, 149, 148, 560, 589, 648, 768, 708, 345, 411, 704, 105, 259,
+   313, 496, 518, 174, 542, 120, 307, 101, 430, 372, 584, 183, 228, 529, 650, 697,
+   424, 732, 428, 349, 632, 355, 517, 110, 135, 147, 403, 580, 624, 700, 750, 170,
+   193, 245, 297, 374, 463, 543, 763, 801, 812, 815, 162, 384, 420, 730, 287, 330,
+   337, 366, 459, 476, 509, 558, 591, 610, 726, 652, 734, 759, 154, 163, 198, 473,
+   683, 697, 292, 311, 353, 423, 572, 494, 113, 217, 259, 280, 314, 499, 506, 603,
+   608, 752, 778, 782, 788, 117, 557, 748, 774, 320, 109, 126, 260, 265, 373, 411,
+   479, 523, 655, 737, 823, 380, 765, 161, 395, 398, 438, 451, 502, 516, 537, 583,
+   791, 136, 340, 769, 122, 273, 446, 727, 305, 322, 400, 496, 771, 155, 190, 269,
+   377, 391, 406, 432, 501, 519, 599, 684, 687, 749, 776, 175, 452, 191, 480, 510,
+   659, 772, 805, 813, 397, 444, 619, 566, 568, 575, 491, 471, 707, 111, 636, 156,
+   153, 288, 346, 578, 256, 435, 383, 729, 680, 767, 694, 295, 128, 210,   0,   0,
+   227,   0, 379,   0,   0, 150, 493, 525, 544, 551, 552, 556, 783, 576, 604,   0,
+   661,   0, 703,   0,   0, 735, 743,   0,   0,   0, 793, 794, 795, 808, 741, 773,
+   118, 127, 130, 166, 169, 177, 207, 213, 215, 226, 229, 268, 270, 317, 327, 329,
+   335, 369, 375, 381, 404, 441, 448, 458, 477, 484, 503, 539, 545, 547, 546, 548,
+   549, 550, 554, 555, 561, 564, 569, 591, 593, 595, 598, 607, 620, 625, 625, 651,
+   690, 695, 705, 706, 716, 717, 733, 735, 777, 786, 790, 315, 869, 623,   0,   0,
+   102, 145, 134, 115, 129, 138, 165, 171, 207, 202, 206, 212, 227, 231, 240, 243,
+   250, 254, 294, 296, 303, 308, 319, 325, 321, 329, 326, 335, 341, 357, 360, 362,
+   370, 379, 388, 389, 393, 421, 424, 438, 456, 454, 458, 465, 477, 535, 485, 490,
+   493, 507, 512, 514, 521, 522, 525, 526, 528, 533, 532, 541, 565, 569, 574, 586,
+   591, 597, 607, 637, 647, 674, 691, 693, 695, 698, 703, 699, 705, 704, 702, 706,
+   709, 717, 728, 736, 747, 754, 770, 777, 783, 784, 786, 787, 790, 802, 825, 848,
+   847, 857,  55,  65,  66, 883, 892, 916, 822, 824,   0,   0,   0,   0,   0,   0,
+     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,1586,   0,1605,
+     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,1602,1603,1934,1935,1574,1575,
+  1576,1577,1579,1580,1581,1583,1584,   0,1585,1587,1588,1589,1591,   0,1592,   0,
+  1593,1594,   0,1595,1596,   0,1598,1599,1600,1601,1604,1582,1578,1590,1597,   0,
+     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,1936,   0,1937,   0,   0,   0,
+     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,1938,   0,   0,   0,   0,
+     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,1939,1940,
+     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,1941,1942,   0,   0,   0,
+     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,1944,1943,   0,1945,   0,
+     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,1946,1947,   0,   0,   0,   0,
+     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,1948,1949,
+  1950,1951,1952,1953,1954,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,1955,1956,1957,1959,1958,
+  1960,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+   106, 104, 107, 826, 114, 118, 119, 121, 123, 124, 127, 125,  34, 830, 130, 131,
+   132, 137, 827,  35, 133, 139, 829, 142, 143, 112, 144, 145, 924, 151, 152,  37,
+   157, 158, 159, 160,  38, 165, 166, 169, 171, 172, 173, 174, 176, 177, 178, 179,
+   181, 182, 182, 182, 833, 468, 184, 185, 834, 187, 188, 189, 196, 192, 194, 195,
+   197, 199, 200, 201, 203, 204, 204, 206, 208, 209, 211, 218, 213, 219, 214, 216,
+   153, 234, 221, 222, 223, 220, 225, 224, 230, 835, 235, 236, 237, 238, 239, 244,
+   836, 837, 247, 248, 249, 246, 251,  39,  40, 253, 255, 255, 838, 257, 258, 259,
+   261, 839, 262, 263, 301, 264,  41, 266, 270, 272, 271, 841, 274, 842, 277, 276,
+   278, 281, 282,  42, 283, 284, 285, 286,  43, 843,  44, 289, 290, 291, 293, 934,
+   298, 845, 845, 621, 300, 300,  45, 852, 894, 302, 304,  46, 306, 309, 310, 312,
+   316,  48,  47, 317, 846, 318, 323, 324, 325, 324, 328, 329, 333, 331, 332, 334,
+   335, 336, 338, 339, 342, 343, 347, 351, 849, 350, 348, 352, 354, 359, 850, 361,
+   358, 356,  49, 363, 365, 367, 364,  50, 369, 371, 851, 376, 386, 378,  53, 381,
+    52,  51, 140, 141, 387, 382, 614,  78, 388, 389, 390, 394, 392, 856,  54, 399,
+   396, 402, 404, 858, 405, 401, 407,  55, 408, 409, 410, 413, 859, 415,  56, 417,
+   860, 418,  57, 419, 422, 424, 425, 861, 840, 862, 426, 863, 429, 431, 427, 433,
+   437, 441, 438, 439, 442, 443, 864, 436, 449, 450,  58, 454, 453, 865, 447, 460,
+   866, 867, 461, 466, 465, 464,  59, 467, 470, 469, 472, 828, 475, 868, 478, 870,
+   483, 485, 486, 871, 488, 489, 872, 873, 495, 497,  60, 498,  61,  61, 504, 505,
+   507, 508, 511,  62, 513, 874, 515, 875, 518, 844, 520, 876, 877, 878,  63,  64,
+   528, 880, 879, 881, 882, 530, 531, 531, 533,  66, 534,  67,  68, 884, 536, 538,
+   541,  69, 885, 549, 886, 887, 556, 559,  70, 561, 562, 563, 888, 889, 889, 567,
+    71, 890, 570, 571,  72, 891, 577,  73, 581, 579, 582, 893, 587,  74, 590, 592,
+   596,  75, 895, 896,  76, 897, 600, 898, 602, 605, 607, 899, 900, 609, 901, 611,
+   853,  77, 615, 616,  79, 617, 252, 902, 903, 854, 855, 621, 622, 731,  80, 627,
+   626, 628, 164, 629, 630, 631, 633, 904, 632, 634, 639, 640, 635, 641, 646, 651,
+   638, 643, 644, 645, 905, 907, 906,  81, 653, 654, 656, 911, 657, 908,  82,  83,
+   909, 910,  84, 664, 665, 666, 667, 669, 668, 671, 670, 674, 672, 673, 675,  85,
+   677, 678,  86, 681, 682, 912, 685, 686,  87, 689,  36, 913, 914,  88,  89, 696,
+   702, 709, 711, 915, 712, 713, 718, 719, 917, 831, 721, 720, 723, 832, 725, 728,
+   918, 919, 739, 742, 744, 920, 745, 753, 756, 757, 755, 760, 761, 921, 762,  90,
+   764, 922,  91, 775, 279, 780, 923, 925,  92,  93, 785, 926,  94, 927, 787, 787,
+   789, 928, 792,  95, 796, 797, 798, 800,  96, 929, 802, 804, 806,  97,  98, 807,
+   930,  99, 931, 932, 933, 814, 100, 816, 817, 818, 819, 820, 821, 935,   0,   0,
+     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+};
+static const int16_t
+_hb_ucd_i16[196] =
+{
+      0,    0,    0,    0,    1,   -1,    0,    0,    2,    0,   -2,    0,    0,    0,    0,    2,
+      0,   -2,    0,    0,    0,    0,    0,   16,    0,    0,    0,  -16,    0,    0,    1,   -1,
+      0,    0,    0,    1,   -1,    0,    0,    0,    0,    1,   -1,    0,    3,    3,    3,   -3,
+     -3,   -3,    0,    0,    0, 2016,    0,    0,    0,    0,    0, 2527, 1923, 1914, 1918,    0,
+   2250,    0,    0,    0,    0,    0,    0,  138,    0,    7,    0,    0,   -7,    0,    0,    0,
+      1,   -1,    1,   -1,   -1,    1,   -1,    0, 1824,    0,    0,    0,    0,    0, 2104,    0,
+   2108, 2106,    0, 2106, 1316,    0,    0,    0,    0,    1,   -1,    1,   -1, -138,    0,    0,
+      1,   -1,    8,    8,    8,    0,    7,    7,    0,    0,   -8,   -8,   -8,   -7,   -7,    0,
+      1,   -1,    0,    2,-1316,    1,   -1,    0,   -1,    1,   -1,    1,   -1,    3,    1,   -1,
+     -3,    1,   -1,    1,   -1,    0,    0,-1914,-1918,    0,    0,-1923,-1824,    0,    0,    0,
+      0,-2016,    0,    0,    1,   -1,    0,    1,    0,    0,-2104,    0,    0,    0,    0,-2106,
+  -2108,-2106,    0,    0,    1,   -1,-2250,    0,    0,    0,-2527,    0,    0,   -2,    0,    1,
+     -1,    0,    1,   -1,
+};
+
+static inline uint_fast8_t
+_hb_ucd_gc (unsigned u)
+{
+  return u<1114110u?_hb_ucd_u8[2176+(((_hb_ucd_u16[((_hb_ucd_u8[u>>4>>5])<<5)+((u>>4)&31u)])<<4)+((u)&15u))]:2;
+}
+static inline uint_fast8_t
+_hb_ucd_ccc (unsigned u)
+{
+  return u<125259u?_hb_ucd_u8[14026+(((_hb_ucd_u8[13034+(((_hb_ucd_u8[12544+(u>>4>>4)])<<4)+((u>>4)&15u))])<<4)+((u)&15u))]:0;
+}
+static inline unsigned
+_hb_ucd_b4 (const uint8_t* a, unsigned i)
+{
+  return (a[i>>1]>>((i&1u)<<2))&15u;
+}
+static inline int_fast16_t
+_hb_ucd_bmg (unsigned u)
+{
+  return u<65380u?_hb_ucd_i16[((_hb_ucd_u8[16170+(((_hb_ucd_b4(16042+_hb_ucd_u8,u>>2>>6))<<6)+((u>>2)&63u))])<<2)+((u)&3u)]:0;
+}
+static inline uint_fast8_t
+_hb_ucd_sc (unsigned u)
+{
+  return u<918000u?_hb_ucd_u8[18924+(((_hb_ucd_u16[3008+(((_hb_ucd_u8[17130+(u>>4>>5)])<<5)+((u>>4)&31u))])<<4)+((u)&15u))]:2;
+}
+static inline uint_fast16_t
+_hb_ucd_dm (unsigned u)
+{
+  return u<195102u?_hb_ucd_u16[6048+(((_hb_ucd_u8[29052+(u>>6)])<<6)+((u)&63u))]:0;
+}
+
+
+#elif !defined(HB_NO_UCD_UNASSIGNED)
+
+static const uint8_t
+_hb_ucd_u8[17198] =
+{
+    0,  1,  2,  3,  4,  5,  6,  7,  7,  8,  7,  7,  7,  7,  7,  7,
+    7,  7,  7,  9, 10, 11,  7,  7,  7,  7, 12, 13, 14, 14, 14, 15,
+   16, 17, 18, 19, 20, 21, 22, 21, 23, 21, 21, 21, 21, 24,  7,  7,
+   25, 26, 21, 21, 21, 21, 27, 28, 21, 21, 29, 30, 31, 32, 33, 34,
+    7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,
+    7,  7,  7,  7, 35,  7, 36, 37,  7, 38,  7,  7,  7, 39, 21, 40,
+   21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
+   21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
+   21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
+   21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
+   21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
+   21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
+   21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
+   21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
+   21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
+   21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
+   21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
+   21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
+   21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
+   21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
+   21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
+   21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
+   21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
+   21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
+   21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
+   21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
+   21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
+   21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
+   41, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
+   21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
+   14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+   14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 42,
+   14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+   14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 43,
+    0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15,
+   16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
+   32, 33, 34, 34, 35, 36, 37, 38, 39, 34, 34, 34, 40, 41, 42, 43,
+   44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59,
+   60, 61, 62, 63, 64, 64, 65, 66, 67, 68, 69, 70, 71, 69, 72, 73,
+   69, 69, 64, 74, 64, 64, 75, 76, 77, 78, 79, 80, 81, 82, 69, 83,
+   84, 85, 86, 87, 88, 89, 69, 69, 34, 34, 34, 34, 34, 34, 34, 34,
+   34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
+   34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 90, 34, 34, 34, 34,
+   34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 91,
+   92, 34, 34, 34, 34, 34, 34, 34, 34, 93, 34, 34, 94, 95, 96, 97,
+   98, 99,100,101,102,103,104,105, 34, 34, 34, 34, 34, 34, 34, 34,
+   34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,106,
+  107,107,107,107,107,107,107,107,107,107,107,107,107,107,107,107,
+  108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,
+  108,108, 34, 34,109,110,111,112, 34, 34,113,114,115,116,117,118,
+  119,120,121,122,123,124,125,126,127,128,129,123, 34, 34,130,123,
+  131,132,133,134,135,136,137,138,139,140,141,123,142,123,143,144,
+  145,146,147,148,149,150,151,123,152,153,123,154,155,156,157,123,
+  158,159,123,160,161,162,123,123,163,164,165,166,123,167,123,168,
+   34, 34, 34, 34, 34, 34, 34,169,170, 34,171,123,123,123,123,123,
+  123,123,123,123,123,123,123,123,123,123,123,123,123,123,123,123,
+   34, 34, 34, 34, 34, 34, 34, 34,172,123,123,123,123,123,123,123,
+  123,123,123,123,123,123,123,123, 34, 34, 34, 34,173,123,123,123,
+   34, 34, 34, 34,174,175,176,177,123,123,123,123,178,179,180,181,
+   34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,182,
+   34, 34, 34, 34, 34,183,123,123,123,123,123,123,123,123,123,123,
+   34, 34,184, 34, 34,185,123,123,123,123,123,123,123,123,123,123,
+  123,123,123,123,123,123,123,123,186,187,123,123,123,123,123,123,
+   69,188,189,190,191,192,193,123,194,195,196,197,198,199,200,201,
+   69, 69, 69, 69,202,203,123,123,123,123,123,123,123,123,123,123,
+  204,123,205,123,123,206,123,123,123,123,123,123,123,123,123,123,
+   34,207,208,123,123,123,123,123,209,210,211,123,212,213,123,123,
+  214,215,216,217,218,123, 69,219, 69, 69, 69, 69, 69,220,221,222,
+  223,224,225,226,227,228,123,123,123,123,123,123,123,123,123,123,
+   34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,229, 34, 34,
+   34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,230, 34,
+  231, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
+   34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,232, 34, 34,
+   34, 34, 34, 34, 34, 34, 34,233,123,123,123,123,123,123,123,123,
+   34, 34, 34, 34,234,123,123,123,123,123,123,123,123,123,123,123,
+  235,123,236,237,123,123,123,123,123,123,123,123,123,123,123,123,
+  108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,238,
+  108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,239,
+    0,  0,  0,  0,  0,  0,  0,  0,  1,  2,  3,  2,  4,  5,  6,  2,
+    7,  7,  7,  7,  7,  2,  8,  9, 10, 11, 11, 11, 11, 11, 11, 11,
+   11, 11, 11, 11, 11, 12, 13, 14, 15, 16, 16, 16, 16, 16, 16, 16,
+   16, 16, 16, 16, 16, 17, 18, 19,  1, 20, 20, 21, 22, 23, 24, 25,
+   26, 27, 15,  2, 28, 29, 27, 30, 11, 11, 11, 11, 11, 11, 11, 11,
+   11, 11, 11, 31, 11, 11, 11, 32, 16, 16, 16, 16, 16, 16, 16, 16,
+   16, 16, 16, 33, 16, 16, 16, 16, 32, 32, 32, 32, 32, 32, 32, 32,
+   32, 32, 32, 32, 34, 34, 34, 34, 34, 34, 34, 34, 16, 32, 32, 32,
+   32, 32, 32, 32, 11, 34, 34, 16, 34, 32, 32, 11, 34, 11, 16, 11,
+   11, 34, 32, 11, 32, 16, 11, 34, 32, 32, 32, 11, 34, 16, 32, 11,
+   34, 11, 34, 34, 32, 35, 32, 16, 36, 36, 37, 34, 38, 37, 34, 34,
+   34, 34, 34, 34, 34, 34, 16, 32, 34, 38, 32, 11, 32, 32, 32, 32,
+   32, 32, 16, 16, 16, 11, 34, 32, 34, 34, 11, 32, 32, 32, 32, 32,
+   16, 16, 39, 16, 16, 16, 16, 16, 40, 40, 40, 40, 40, 40, 40, 40,
+   40, 41, 41, 40, 40, 40, 40, 40, 40, 41, 41, 41, 41, 41, 41, 41,
+   40, 40, 42, 41, 41, 41, 42, 42, 41, 41, 41, 41, 41, 41, 41, 41,
+   43, 43, 43, 43, 43, 43, 43, 43, 32, 32, 42, 32, 44, 45, 16, 10,
+   44, 44, 41, 46, 11, 47, 47, 11, 34, 11, 11, 11, 11, 11, 11, 11,
+   11, 48, 11, 11, 11, 11, 16, 16, 16, 16, 16, 16, 16, 16, 16, 34,
+   16, 11, 32, 16, 32, 32, 32, 32, 16, 16, 32, 49, 34, 32, 34, 11,
+   32, 50, 43, 43, 51, 32, 32, 32, 11, 34, 34, 34, 34, 34, 34, 16,
+   48, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 47, 52,  2,  2,  2,
+   16, 16, 16, 16, 53, 54, 55, 56, 57, 43, 43, 43, 43, 43, 43, 43,
+   43, 43, 43, 43, 43, 43, 43, 58, 59, 60, 43, 59, 44, 44, 44, 44,
+   36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 61, 44, 62,
+   36, 63, 64, 44, 44, 44, 44, 44, 65, 65, 65,  8,  9, 66,  2, 67,
+   43, 43, 43, 43, 43, 60, 68,  2, 69, 36, 36, 36, 36, 70, 43, 43,
+    7,  7,  7,  7,  7,  2,  2, 36, 71, 36, 36, 36, 36, 36, 36, 36,
+   36, 36, 72, 43, 43, 43, 73, 50, 43, 43, 74, 75, 76, 43, 43, 36,
+    7,  7,  7,  7,  7, 36, 77, 78,  2,  2,  2,  2,  2,  2,  2, 79,
+   70, 36, 36, 36, 36, 36, 36, 36, 43, 43, 43, 43, 43, 80, 62, 36,
+   36, 36, 36, 43, 43, 43, 43, 43, 71, 44, 44, 44, 44, 44, 44, 44,
+    7,  7,  7,  7,  7, 36, 36, 36, 36, 36, 36, 36, 36, 70, 43, 43,
+   43, 43, 40, 21,  2, 81, 57, 20, 36, 36, 36, 43, 43, 75, 43, 43,
+   43, 43, 75, 43, 75, 43, 43, 44,  2,  2,  2,  2,  2,  2,  2, 64,
+   36, 36, 36, 36, 70, 43, 44, 64, 36, 36, 36, 36, 36, 61, 44, 44,
+   44, 44, 44, 44, 44, 44, 44, 44, 36, 36, 61, 36, 36, 36, 36, 44,
+   44, 57, 43, 43, 43, 43, 43, 43, 43, 82, 43, 43, 43, 43, 43, 43,
+   43, 83, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 83, 71, 84,
+   85, 43, 43, 43, 83, 84, 85, 84, 70, 43, 43, 43, 36, 36, 36, 36,
+   36, 43,  2,  7,  7,  7,  7,  7, 86, 36, 36, 36, 36, 36, 36, 36,
+   70, 84, 62, 36, 36, 36, 61, 62, 61, 62, 36, 36, 36, 36, 36, 36,
+   36, 36, 36, 36, 61, 36, 36, 36, 61, 61, 44, 36, 36, 44, 71, 84,
+   85, 43, 80, 87, 88, 87, 85, 61, 44, 44, 44, 87, 44, 44, 36, 62,
+   36, 43, 44,  7,  7,  7,  7,  7, 36, 20, 27, 27, 27, 56, 63, 80,
+   57, 83, 62, 36, 36, 61, 44, 62, 61, 36, 62, 61, 36, 44, 80, 84,
+   85, 80, 44, 57, 80, 57, 43, 44, 57, 44, 44, 44, 62, 36, 61, 61,
+   44, 44, 44,  7,  7,  7,  7,  7, 43, 36, 70, 64, 44, 44, 44, 44,
+   57, 83, 62, 36, 36, 36, 36, 62, 36, 62, 36, 36, 36, 36, 36, 36,
+   61, 36, 62, 36, 36, 44, 71, 84, 85, 43, 43, 57, 83, 87, 85, 44,
+   61, 44, 44, 44, 44, 44, 44, 44, 66, 44, 44, 44, 62, 43, 43, 43,
+   57, 84, 62, 36, 36, 36, 61, 62, 61, 36, 62, 36, 36, 44, 71, 85,
+   85, 43, 80, 87, 88, 87, 85, 44, 44, 44, 44, 83, 44, 44, 36, 62,
+   78, 27, 27, 27, 44, 44, 44, 44, 44, 71, 62, 36, 36, 61, 44, 36,
+   61, 36, 36, 44, 62, 61, 61, 36, 44, 62, 61, 44, 36, 61, 44, 36,
+   36, 36, 36, 36, 36, 44, 44, 84, 83, 88, 44, 84, 88, 84, 85, 44,
+   61, 44, 44, 87, 44, 44, 44, 44, 27, 89, 67, 67, 56, 90, 44, 44,
+   83, 84, 71, 36, 36, 36, 61, 36, 61, 36, 36, 36, 36, 36, 36, 36,
+   36, 36, 36, 36, 36, 44, 62, 43, 83, 84, 88, 43, 80, 43, 43, 44,
+   44, 44, 57, 80, 36, 61, 44, 44, 44, 44, 44, 91, 27, 27, 27, 89,
+   70, 84, 72, 36, 36, 36, 61, 36, 36, 36, 62, 36, 36, 44, 71, 85,
+   84, 84, 88, 83, 88, 84, 43, 44, 44, 44, 87, 88, 44, 44, 44, 61,
+   62, 61, 44, 44, 44, 44, 44, 44, 43, 84, 62, 36, 36, 36, 61, 36,
+   36, 36, 36, 36, 36, 70, 71, 84, 85, 43, 80, 84, 88, 84, 85, 77,
+   44, 44, 36, 92, 27, 27, 27, 93, 27, 27, 27, 27, 89, 36, 36, 36,
+   44, 84, 62, 36, 36, 36, 36, 36, 36, 36, 36, 61, 44, 36, 36, 36,
+   36, 62, 36, 36, 36, 36, 62, 44, 36, 36, 36, 61, 44, 80, 44, 87,
+   84, 43, 80, 80, 84, 84, 84, 84, 44, 84, 64, 44, 44, 44, 44, 44,
+   62, 36, 36, 36, 36, 36, 36, 36, 70, 36, 43, 43, 43, 80, 44, 94,
+   36, 36, 36, 75, 43, 43, 43, 60,  7,  7,  7,  7,  7,  2, 44, 44,
+   62, 61, 61, 36, 36, 61, 36, 36, 36, 36, 62, 62, 36, 36, 36, 36,
+   70, 36, 43, 43, 43, 43, 71, 44, 36, 36, 61, 81, 43, 43, 43, 44,
+    7,  7,  7,  7,  7, 44, 36, 36, 77, 67,  2,  2,  2,  2,  2,  2,
+    2, 95, 95, 67, 43, 67, 67, 67,  7,  7,  7,  7,  7, 27, 27, 27,
+   27, 27, 50, 50, 50,  4,  4, 84, 36, 36, 36, 36, 62, 36, 36, 36,
+   36, 36, 36, 36, 36, 36, 61, 44, 57, 43, 43, 43, 43, 43, 43, 83,
+   43, 43, 60, 43, 36, 36, 70, 43, 43, 43, 43, 43, 57, 43, 43, 43,
+   43, 43, 43, 43, 43, 43, 80, 67, 67, 67, 67, 76, 67, 67, 90, 67,
+    2,  2, 95, 67, 21, 64, 44, 44, 36, 36, 36, 36, 36, 92, 85, 43,
+   83, 43, 43, 43, 85, 83, 85, 71,  7,  7,  7,  7,  7,  2,  2,  2,
+   36, 36, 36, 84, 43, 36, 36, 43, 71, 84, 96, 92, 84, 84, 84, 36,
+   70, 43, 71, 36, 36, 36, 36, 36, 36, 83, 85, 83, 84, 84, 85, 92,
+    7,  7,  7,  7,  7, 84, 85, 67, 11, 11, 11, 48, 44, 44, 48, 44,
+   16, 16, 16, 16, 16, 53, 45, 16, 36, 36, 36, 36, 61, 36, 36, 44,
+   36, 36, 36, 61, 61, 36, 36, 44, 61, 36, 36, 44, 36, 36, 36, 61,
+   61, 36, 36, 44, 36, 36, 36, 36, 36, 36, 36, 61, 36, 36, 36, 36,
+   36, 36, 36, 36, 36, 61, 57, 43,  2,  2,  2,  2, 97, 27, 27, 27,
+   27, 27, 27, 27, 27, 27, 98, 44, 67, 67, 67, 67, 67, 44, 44, 44,
+   11, 11, 11, 44, 16, 16, 16, 44, 99, 36, 36, 36, 36, 36, 36, 36,
+   36, 36, 36, 36, 36, 36, 77, 72,100, 36, 36, 36, 36, 36, 36, 36,
+   36, 36, 36, 36, 36,101,102, 44, 36, 36, 36, 36, 36, 63,  2,103,
+  104, 36, 36, 36, 61, 44, 44, 44, 36, 36, 36, 36, 36, 36, 61, 36,
+   36, 43, 80, 44, 44, 44, 44, 44, 36, 43, 60, 64, 44, 44, 44, 44,
+   36, 43, 44, 44, 44, 44, 44, 44, 61, 43, 44, 44, 44, 44, 44, 44,
+   36, 36, 43, 85, 43, 43, 43, 84, 84, 84, 84, 83, 85, 43, 43, 43,
+   43, 43,  2, 86,  2, 66, 70, 44,  7,  7,  7,  7,  7, 44, 44, 44,
+   27, 27, 27, 27, 27, 44, 44, 44,  2,  2,  2,105,  2, 59, 43, 68,
+   36,106, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 61, 44, 44, 44,
+   36, 36, 70, 71, 36, 36, 36, 36, 36, 36, 36, 36, 70, 61, 44, 44,
+   36, 36, 36, 44, 44, 44, 44, 44, 36, 36, 36, 36, 36, 36, 36, 61,
+   43, 83, 84, 85, 83, 84, 44, 44, 84, 83, 84, 84, 85, 43, 44, 44,
+   90, 44,  2,  7,  7,  7,  7,  7, 36, 36, 36, 36, 36, 36, 36, 44,
+   36, 36, 61, 44, 44, 44, 44, 44, 36, 36, 36, 36, 36, 36, 44, 44,
+   36, 36, 36, 36, 36, 44, 44, 44,  7,  7,  7,  7,  7, 98, 44, 67,
+   67, 67, 67, 67, 67, 67, 67, 67, 36, 36, 36, 70, 83, 85, 44,  2,
+   36, 36, 92, 83, 43, 43, 43, 80, 83, 83, 85, 43, 43, 43, 83, 84,
+   84, 85, 43, 43, 43, 43, 80, 57,  2,  2,  2, 86,  2,  2,  2, 44,
+   43, 43, 43, 43, 43, 43, 43,107, 43, 43, 96, 36, 36, 36, 36, 36,
+   36, 36, 83, 43, 43, 83, 83, 84, 84, 83, 96, 36, 36, 36, 44, 44,
+   95, 67, 67, 67, 67, 50, 43, 43, 43, 43, 67, 67, 67, 67, 90, 44,
+   43, 96, 36, 36, 36, 36, 36, 36, 92, 43, 43, 84, 43, 85, 43, 36,
+   36, 36, 36, 83, 43, 84, 85, 85, 43, 84, 44, 44, 44, 44,  2,  2,
+   36, 36, 84, 84, 84, 84, 43, 43, 43, 43, 84, 43, 44, 91,  2,  2,
+    7,  7,  7,  7,  7, 44, 62, 36, 36, 36, 36, 36, 40, 40, 40,  2,
+   16, 16, 16, 16,108, 44, 44, 44, 11, 11, 11, 11, 11, 47, 48, 11,
+    2,  2,  2,  2, 44, 44, 44, 44, 43, 60, 43, 43, 43, 43, 43, 43,
+   83, 43, 43, 43, 71, 36, 70, 36, 36, 36, 71, 92, 43, 61, 44, 44,
+   16, 16, 16, 16, 16, 16, 40, 40, 40, 40, 40, 40, 40, 45, 16, 16,
+   16, 16, 16, 16, 45, 16, 16, 16, 16, 16, 16, 16, 16,109, 40, 40,
+   43, 43, 43, 43, 43, 57, 43, 43, 32, 32, 32, 16, 16, 16, 16, 32,
+   16, 16, 16, 16, 11, 11, 11, 11, 16, 16, 16, 44, 11, 11, 11, 44,
+   16, 16, 16, 16, 48, 48, 48, 48, 16, 16, 16, 16, 16, 16, 16, 44,
+   16, 16, 16, 16,110,110,110,110, 16, 16,108, 16, 11, 11,111,112,
+   41, 16,108, 16, 11, 11,111, 41, 16, 16, 44, 16, 11, 11,113, 41,
+   16, 16, 16, 16, 11, 11,114, 41, 44, 16,108, 16, 11, 11,111,115,
+  116,116,116,116,116,117, 65, 65,118,118,118,  2,119,120,119,120,
+    2,  2,  2,  2,121, 65, 65,122,  2,  2,  2,  2,123,124,  2,125,
+  126,  2,127,128,  2,  2,  2,  2,  2,  9,126,  2,  2,  2,  2,129,
+   65, 65, 68, 65, 65, 65, 65, 65,130, 44, 27, 27, 27,  8,127,131,
+   27, 27, 27, 27, 27,  8,127,102, 40, 40, 40, 40, 40, 40, 81, 44,
+   20, 20, 20, 20, 20, 20, 20, 20, 43, 43, 43, 43, 43, 43,132, 51,
+  133, 51,133, 43, 43, 43, 43, 43, 80, 44, 44, 44, 44, 44, 44, 44,
+   67,134, 67,135, 67, 34, 11, 16, 11, 32,135, 67, 49, 11, 11, 67,
+   67, 67,134,134,134, 11, 11,136, 11, 11, 35, 36, 39, 67, 16, 11,
+    8,  8, 49, 16, 16, 26, 67,137, 27, 27, 27, 27, 27, 27, 27, 27,
+  103,103,103,103,103,103,103,103,103,138,139,103,140, 67, 44, 44,
+    8,  8,141, 67, 67,  8, 67, 67,141, 26, 67,141, 67, 67, 67,141,
+   67, 67, 67, 67, 67, 67, 67,  8, 67,141,141, 67, 67, 67, 67, 67,
+   67, 67,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,
+   67, 67, 67, 67,  4,  4, 67, 67,  8, 67, 67, 67,142,143, 67, 67,
+   67, 67, 67, 67, 67, 67,141, 67, 67, 67, 67, 67, 67, 26,  8,  8,
+    8,  8, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67,  8,  8,
+    8, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 90, 44, 44, 44, 44,
+   67, 67, 67, 67, 67, 90, 44, 44, 27, 27, 27, 27, 27, 27, 67, 67,
+   67, 67, 67, 67, 67, 27, 27, 27, 67, 67, 67, 26, 67, 67, 67, 67,
+   26, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67,  8,  8,  8,  8,
+   67, 67, 67, 67, 67, 67, 67, 26, 67, 67, 67, 67,  4,  4,  4,  4,
+    4,  4,  4, 27, 27, 27, 27, 27, 27, 27, 67, 67, 67, 67, 67, 67,
+    8,  8,127,144,  8,  8,  8,  8,  8,  8,  8,  4,  4,  4,  4,  4,
+    8,127,145,145,145,145,145,145,145,145,145,145,144,  8,  8,  8,
+    8,  8,  8,  8,  4,  4,  8,  8,  8,  8,  8,  8,  8,  8,  4,  8,
+    8,  8,141, 26,  8,  8,141, 67, 67, 67, 44, 67, 67, 67, 67, 67,
+   67, 67, 67, 44, 67, 67, 67, 67, 11, 11, 11, 11, 11, 11, 11, 47,
+   16, 16, 16, 16, 16, 16, 16,108, 32, 11, 32, 34, 34, 34, 34, 11,
+   32, 32, 34, 16, 16, 16, 40, 11, 32, 32,137, 67, 67,135, 34,146,
+   43, 32, 44, 44, 91,  2, 97,  2, 16, 16, 16,147, 44, 44,147, 44,
+   36, 36, 36, 36, 44, 44, 44, 52, 64, 44, 44, 44, 44, 44, 44, 57,
+   36, 36, 36, 61, 44, 44, 44, 44, 36, 36, 36, 61, 36, 36, 36, 61,
+    2,119,119,  2,123,124,119,  2,  2,  2,  2,  6,  2,105,119,  2,
+  119,  4,  4,  4,  4,  2,  2, 86,  2,  2,  2,  2,  2,118,  2,  2,
+  105,148,  2,  2,  2,  2,  2,  2, 67, 67, 67, 67, 67, 55, 67, 67,
+   67, 67, 44, 44, 44, 44, 44, 44, 67, 67, 67, 44, 44, 44, 44, 44,
+   67, 67, 67, 67, 67, 67, 44, 44,  1,  2,149,150,  4,  4,  4,  4,
+    4, 67,  4,  4,  4,  4,151,152,153,103,103,103,103, 43, 43, 84,
+  154, 40, 40, 67,103,155, 63, 67, 36, 36, 36, 61, 57,156,157, 69,
+   36, 36, 36, 36, 36, 63, 40, 69, 44, 44, 62, 36, 36, 36, 36, 36,
+   67, 27, 27, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 90,
+   27, 27, 27, 27, 27, 67, 67, 67, 67, 67, 67, 67, 27, 27, 27, 27,
+  158, 27, 27, 27, 27, 27, 27, 27, 36, 36,106, 36, 36, 36, 36, 36,
+   36, 36, 36, 36, 36, 36,159,  2,  7,  7,  7,  7,  7, 36, 44, 44,
+   32, 32, 32, 32, 32, 32, 32, 70, 51,160, 43, 43, 43, 43, 43, 86,
+   32, 32, 32, 32, 32, 32, 40, 43, 36, 36, 36,103,103,103,103,103,
+   43,  2,  2,  2, 44, 44, 44, 44, 41, 41, 41,157, 40, 40, 40, 40,
+   41, 32, 32, 32, 32, 32, 32, 32, 16, 32, 32, 32, 32, 32, 32, 32,
+   45, 16, 16, 16, 34, 34, 34, 32, 32, 32, 32, 32, 42,161, 34, 35,
+   32, 32, 16, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 11, 11, 32,
+   11, 11, 32, 32, 32, 32, 32, 32, 44, 32, 11, 47, 44, 44, 44, 44,
+   44, 44, 44, 62, 40, 35, 36, 36, 36, 71, 36, 71, 36, 70, 36, 36,
+   36, 92, 85, 83, 67, 67, 44, 44, 27, 27, 27, 67,162, 44, 44, 44,
+   36, 36,  2,  2, 44, 44, 44, 44, 84, 36, 36, 36, 36, 36, 36, 36,
+   36, 36, 84, 84, 84, 84, 84, 84, 84, 84, 43, 44, 44, 44, 44,  2,
+   43, 36, 36, 36,  2, 72, 72, 70, 36, 36, 36, 43, 43, 43, 43,  2,
+   36, 36, 36, 70, 43, 43, 43, 43, 43, 84, 44, 44, 44, 44, 44, 91,
+   36, 70, 84, 43, 43, 84, 43, 84,163,  2,  2,  2,  2,  2,  2, 52,
+    7,  7,  7,  7,  7, 44, 44,  2, 36, 36, 70, 69, 36, 36, 36, 36,
+    7,  7,  7,  7,  7, 36, 36, 61, 36, 36, 36, 36, 70, 43, 43, 83,
+   85, 83, 85, 80, 44, 44, 44, 44, 36, 70, 36, 36, 36, 36, 83, 44,
+    7,  7,  7,  7,  7, 44,  2,  2, 69, 36, 36, 77, 67, 92, 83, 36,
+   71, 43, 71, 70, 71, 36, 36, 43, 70, 61, 44, 44, 44, 44, 44, 44,
+   44, 44, 44, 44, 44, 62,106,  2, 36, 36, 36, 36, 36, 92, 43, 84,
+    2,106,164, 80, 44, 44, 44, 44, 62, 36, 36, 61, 62, 36, 36, 61,
+   62, 36, 36, 61, 44, 44, 44, 44, 16, 16, 16, 16, 16,112, 40, 40,
+   16, 16, 16, 16, 44, 44, 44, 44, 36, 92, 85, 84, 83,163, 85, 44,
+   36, 36, 44, 44, 44, 44, 44, 44, 36, 36, 36, 61, 44, 62, 36, 36,
+  165,165,165,165,165,165,165,165,166,166,166,166,166,166,166,166,
+   16, 16, 16,108, 44, 44, 44, 44, 44,147, 16, 16, 44, 44, 62, 71,
+   36, 36, 36, 36,167, 36, 36, 36, 36, 36, 36, 61, 36, 36, 61, 61,
+   36, 62, 61, 36, 36, 36, 36, 36, 36, 41, 41, 41, 41, 41, 41, 41,
+   41, 44, 44, 44, 44, 44, 44, 44, 44, 62, 36, 36, 36, 36, 36, 36,
+   36, 36, 36, 36, 36, 36, 36,145, 44, 36, 36, 36, 36, 36, 36, 36,
+   36, 36, 36, 36, 44, 44, 44, 44, 36, 36, 36, 36, 36, 36,162, 44,
+    2,  2,  2,168,128, 44, 44, 44,  6,169,170,145,145,145,145,145,
+  145,145,128,168,128,  2,125,171,  2, 64,  2,  2,151,145,145,128,
+    2,172,  8,173, 66,  2, 44, 44, 36, 36, 61, 36, 36, 36, 36, 36,
+   36, 36, 36, 36, 36, 36, 61, 79, 91,  2,  3,  2,  4,  5,  6,  2,
+   16, 16, 16, 16, 16, 17, 18,127,128,  4,  2, 36, 36, 36, 36, 36,
+   69, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 40,
+   44, 36, 36, 36, 44, 36, 36, 36, 44, 36, 36, 36, 44, 36, 61, 44,
+   20,174, 56,175, 26,  8,141, 90, 44, 44, 44, 44, 79, 65, 67, 44,
+   36, 36, 36, 36, 36, 36, 62, 36, 36, 36, 36, 36, 36, 61, 36, 62,
+    2, 64, 44,176, 27, 27, 27, 27, 27, 27, 44, 55, 67, 67, 67, 67,
+  103,103,140, 27, 89, 67, 67, 67, 67, 67, 67, 67, 67, 27, 67, 90,
+   90, 44, 44, 44, 44, 44, 44, 44, 67, 67, 67, 67, 67, 67, 50, 44,
+  177, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 44, 44,
+   27, 27, 44, 44, 44, 44, 62, 36,150, 36, 36, 36, 36,178, 44, 44,
+   36, 36, 36, 43, 43, 80, 44, 44, 36, 36, 36, 36, 36, 36, 36, 91,
+   36, 36, 44, 44, 36, 36, 36, 36,179,103,103, 44, 44, 44, 44, 44,
+   11, 11, 11, 11, 16, 16, 16, 16, 11, 11, 44, 44, 16, 16, 16, 16,
+   16, 16, 16, 16, 16, 16, 44, 44, 36, 36, 44, 44, 44, 44, 44, 91,
+   36, 36, 36, 44, 61, 36, 36, 36, 36, 36, 36, 62, 61, 44, 61, 62,
+   36, 36, 36, 91, 27, 27, 27, 27, 36, 36, 36, 77,158, 27, 27, 27,
+   44, 44, 44,176, 27, 27, 27, 27, 36, 61, 36, 44, 44,176, 27, 27,
+   36, 36, 36, 27, 27, 27, 44, 91, 36, 36, 36, 36, 36, 44, 44, 91,
+   36, 36, 36, 36, 44, 44, 27, 36, 44, 27, 27, 27, 27, 27, 27, 27,
+   70, 43, 57, 80, 44, 44, 43, 43, 36, 36, 62, 36, 62, 36, 36, 36,
+   36, 36, 36, 44, 43, 80, 44, 57, 27, 27, 27, 27, 98, 44, 44, 44,
+    2,  2,  2,  2, 64, 44, 44, 44, 36, 36, 36, 36, 36, 36,180, 30,
+   36, 36, 36, 36, 36, 36,180, 27, 36, 36, 36, 36, 78, 36, 36, 36,
+   36, 36, 70, 80, 44,176, 27, 27,  2,  2,  2, 64, 44, 44, 44, 44,
+   36, 36, 36, 44, 91,  2,  2,  2, 36, 36, 36, 44, 27, 27, 27, 27,
+   36, 61, 44, 44, 27, 27, 27, 27, 36, 44, 44, 44, 91,  2, 64, 44,
+   44, 44, 44, 44,176, 27, 27, 27, 11, 47, 44, 44, 44, 44, 44, 44,
+   16,108, 44, 44, 44, 27, 27, 27, 36, 36, 43, 43, 44, 44, 44, 44,
+   27, 27, 27, 27, 27, 27, 27, 98, 27, 27, 27, 93, 44, 44, 44, 44,
+  177, 27, 30,  2,  2, 44, 44, 44, 85, 96, 36, 36, 36, 36, 36, 36,
+   36, 36, 36, 36, 43, 43, 43, 43, 43, 43, 43, 60,  2,  2,  2, 44,
+   27, 27, 27,  7,  7,  7,  7,  7, 44, 44, 44, 44, 44, 44, 44, 57,
+   84, 85, 43, 83, 85, 60,181,  2,  2, 44, 44, 44, 44, 44, 79, 44,
+   43, 71, 36, 36, 36, 36, 36, 36, 36, 36, 36, 70, 43, 43, 85, 43,
+   43, 43, 80,  7,  7,  7,  7,  7,  2,  2, 92, 88, 44, 44, 44, 44,
+   36, 70,  2, 61, 44, 44, 44, 44, 36, 92, 84, 43, 43, 43, 43, 83,
+   96, 36, 63,  2, 59, 43, 60, 44,  7,  7,  7,  7,  7, 63, 63,  2,
+  176, 27, 27, 27, 27, 27, 27, 27, 27, 27, 98, 44, 44, 44, 44, 44,
+   36, 36, 36, 36, 36, 36, 84, 85, 43, 84, 83, 43,  2,  2,  2, 80,
+   36, 36, 36, 61, 61, 36, 36, 62, 36, 36, 36, 36, 36, 36, 36, 62,
+   36, 36, 36, 36, 63, 44, 44, 44, 36, 36, 36, 36, 36, 36, 36, 70,
+   84, 85, 43, 43, 43, 80, 44, 44, 43, 84, 62, 36, 36, 36, 61, 62,
+   61, 36, 62, 36, 36, 57, 71, 84, 83, 84, 88, 87, 88, 87, 84, 44,
+   61, 44, 44, 87, 44, 44, 62, 36, 36, 84, 44, 43, 43, 43, 80, 44,
+   43, 43, 80, 44, 44, 44, 44, 44, 36, 36, 92, 84, 43, 43, 43, 43,
+   84, 43, 83, 71, 36, 63,  2,  2,  7,  7,  7,  7,  7, 91, 91, 71,
+   84, 85, 43, 43, 83, 83, 84, 85, 83, 43, 36, 72, 44, 44, 44, 44,
+   36, 36, 36, 36, 36, 36, 36, 92, 84, 43, 43, 44, 84, 84, 43, 85,
+   60,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2, 36, 36, 43, 44,
+   84, 85, 43, 43, 43, 83, 85, 85, 60,  2, 61, 44, 44, 44, 44, 44,
+    2,  2,  2,  2,  2,  2, 64, 44, 36, 36, 36, 36, 36, 70, 85, 84,
+   43, 43, 43, 85, 61, 44, 44, 44, 84, 43, 43, 85, 43, 43, 44, 44,
+    7,  7,  7,  7,  7, 27,  2, 95, 43, 43, 43, 43, 85, 60, 44, 44,
+   27, 98, 44, 44, 44, 44, 44, 62, 36, 36, 36, 36, 44, 36, 36, 36,
+   92, 84, 43, 43, 44, 43, 84, 84, 71, 72, 88, 44, 44, 44, 44, 44,
+   70, 43, 43, 43, 43, 71, 36, 36, 36, 70, 43, 43, 83, 70, 43, 60,
+    2,  2,  2, 59, 44, 44, 44, 44, 70, 43, 43, 83, 85, 43, 36, 36,
+   36, 36, 36, 36, 36, 43, 43, 43, 43, 43, 43, 83, 43,  2, 72,  2,
+    2, 64, 44, 44, 44, 44, 44, 44, 43, 43, 43, 80, 43, 43, 43, 85,
+   63,  2,  2, 44, 44, 44, 44, 44,  2, 36, 36, 36, 36, 36, 36, 36,
+   44, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 87, 43, 43, 43,
+   83, 43, 85, 80, 44, 44, 44, 44, 36, 36, 36, 61, 36, 62, 36, 36,
+   70, 43, 43, 80, 44, 80, 43, 57, 43, 43, 43, 70, 44, 44, 44, 44,
+   36, 36, 36, 62, 61, 36, 36, 36, 36, 36, 36, 36, 36, 84, 84, 88,
+   43, 87, 85, 85, 61, 44, 44, 44, 36, 70, 83,163, 64, 44, 44, 44,
+   27, 27, 89, 67, 67, 67, 56, 20,162, 67, 67, 67, 67, 67, 67, 67,
+   67, 44, 44, 44, 44, 44, 44, 91,103,103,103,103,103,103,103,178,
+    2,  2, 64, 44, 44, 44, 44, 44, 65, 65, 65, 65, 68, 44, 44, 44,
+   43, 43, 60, 44, 44, 44, 44, 44, 43, 43, 43, 60,  2,  2, 67, 67,
+   40, 40, 95, 44, 44, 44, 44, 44,  7,  7,  7,  7,  7,176, 27, 27,
+   27, 62, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 44, 44, 62, 36,
+   27, 27, 27, 30,  2, 64, 44, 44, 36, 36, 36, 36, 36, 61, 44, 57,
+   92, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84,
+   84, 84, 84, 84, 44, 44, 44, 57, 43, 74, 40, 40, 40, 40, 40, 40,
+   40, 86, 44, 44, 44, 44, 44, 44, 36, 61, 44, 44, 44, 44, 44, 44,
+   44, 44, 36, 36, 44, 44, 44, 44, 36, 36, 36, 36, 36, 44, 50, 60,
+   65, 65, 44, 44, 44, 44, 44, 44, 67, 67, 67, 90, 55, 67, 67, 67,
+   67, 67,182, 85, 43, 67,182, 84, 84,183, 65, 65, 65, 82, 43, 43,
+   43, 76, 50, 43, 43, 43, 67, 67, 67, 67, 67, 67, 67, 43, 43, 67,
+   67, 67, 67, 67, 90, 44, 44, 44, 67, 43, 76, 44, 44, 44, 44, 44,
+   27, 27, 44, 44, 44, 44, 44, 44, 11, 11, 11, 11, 11, 16, 16, 16,
+   16, 16, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 16,
+   16, 16,108, 16, 16, 16, 16, 16, 11, 16, 16, 16, 16, 16, 16, 16,
+   16, 16, 16, 16, 16, 16, 47, 11, 44, 47, 48, 47, 48, 11, 47, 11,
+   11, 11, 11, 16, 16,147,147, 16, 16, 16,147, 16, 16, 16, 16, 16,
+   16, 16, 11, 48, 11, 47, 48, 11, 11, 11, 47, 11, 11, 11, 47, 16,
+   16, 16, 16, 16, 11, 48, 11, 47, 11, 11, 47, 47, 44, 11, 11, 11,
+   47, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 11, 11,
+   11, 11, 11, 16, 16, 16, 16, 16, 16, 16, 16, 44, 11, 11, 11, 11,
+   31, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 33, 16, 16,
+   16, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 31, 16, 16,
+   16, 16, 33, 16, 16, 16, 11, 11, 11, 11, 31, 16, 16, 16, 16, 16,
+   16, 16, 16, 16, 16, 16, 16, 33, 16, 16, 16, 11, 11, 11, 11, 11,
+   11, 11, 11, 11, 11, 11, 11, 31, 16, 16, 16, 16, 33, 16, 16, 16,
+   11, 11, 11, 11, 31, 16, 16, 16, 16, 33, 16, 16, 16, 32, 44,  7,
+    7,  7,  7,  7,  7,  7,  7,  7, 43, 43, 43, 76, 67, 50, 43, 43,
+   43, 43, 43, 43, 43, 43, 76, 67, 67, 67, 50, 67, 67, 67, 67, 67,
+   67, 67, 76, 21,  2,  2, 44, 44, 44, 44, 44, 44, 44, 57, 43, 43,
+   43, 43, 43, 80, 43, 43, 43, 43, 43, 43, 43, 43, 80, 57, 43, 43,
+   43, 57, 80, 43, 43, 80, 44, 44, 43, 43, 43, 74, 40, 40, 40, 44,
+    7,  7,  7,  7,  7, 44, 44, 77, 36, 36, 36, 36, 36, 36, 43, 43,
+    7,  7,  7,  7,  7, 44, 44, 94, 36, 36, 61,176, 27, 27, 27, 27,
+   43, 43, 43, 80, 44, 44, 44, 44, 16, 16, 43, 43, 43, 74, 44, 44,
+   27, 27, 27, 27, 27, 27,158, 27,184, 27, 98, 44, 44, 44, 44, 44,
+   27, 27, 27, 27, 27, 27, 27,158, 27, 27, 27, 27, 27, 27, 27, 44,
+   36, 36, 62, 36, 36, 36, 36, 36, 62, 61, 61, 62, 62, 36, 36, 36,
+   36, 61, 36, 36, 62, 62, 44, 44, 44, 61, 44, 62, 62, 62, 62, 36,
+   62, 61, 61, 62, 62, 62, 62, 62, 62, 61, 61, 62, 36, 61, 36, 36,
+   36, 61, 36, 36, 62, 36, 61, 61, 36, 36, 36, 36, 36, 62, 36, 36,
+   62, 36, 62, 36, 36, 62, 36, 36,  8, 44, 44, 44, 44, 44, 44, 44,
+   55, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 90, 44,
+   44, 44, 44, 67, 67, 67, 67, 67, 67, 90, 44, 44, 44, 44, 44, 44,
+   67, 44, 44, 44, 44, 44, 44, 44, 67, 67, 67, 67, 67, 25, 41, 41,
+   67, 67, 67, 67, 44, 44, 44, 44, 67, 67, 67, 67, 67, 67, 67, 44,
+   67, 67, 67, 67, 67, 67, 55, 67, 67, 55, 67, 90, 44, 67, 67, 67,
+   67, 90, 55, 67, 67, 90, 44, 67, 67, 67, 67, 67, 67, 90, 55, 67,
+   67, 67, 44, 44, 67, 90, 44, 44, 36, 44, 44, 44, 44, 44, 44, 44,
+   79, 44, 44, 44, 44, 44, 44, 44, 65, 65, 65, 65, 65, 65, 65, 65,
+  166,166,166,166,166,166,166, 44,166,166,166,166,166,166,166,  0,
+    0,  0, 29, 21, 21, 21, 23, 21, 22, 18, 21, 25, 21, 17, 13, 13,
+   25, 25, 25, 21, 21,  9,  9,  9,  9, 22, 21, 18, 24, 16, 24,  5,
+    5,  5,  5, 22, 25, 18, 25,  0, 23, 23, 26, 21, 24, 26,  7, 20,
+   25,  1, 26, 24, 26, 25, 15, 15, 24, 15,  7, 19, 15, 21,  9, 25,
+    9,  5,  5, 25,  5,  9,  5,  7,  7,  7,  9,  8,  8,  5,  7,  5,
+    6,  6, 24, 24,  6, 24, 12, 12,  2,  2,  6,  5,  9, 21,  9,  2,
+    2,  9, 25,  9, 26, 12, 11, 11,  2,  6,  5, 21, 17,  2,  2, 26,
+   26, 23,  2, 12, 17, 12, 21, 12, 12, 21,  7,  2,  2,  7,  7, 21,
+   21,  2,  1,  1, 21, 23, 26, 26,  1,  2,  6,  7,  7, 12, 12,  7,
+   21,  7, 12,  1, 12,  6,  6, 12, 12, 26,  7, 26, 26,  7,  2,  1,
+   12,  2,  6,  2,  1, 12, 12, 10, 10, 10, 10, 12, 21,  6,  2, 10,
+   10,  2, 15, 26, 26,  2,  2, 21,  7, 10, 15,  7,  2, 23, 21, 26,
+   10,  7, 21, 15, 15,  2, 17,  7, 29,  7,  7, 22, 18,  2, 14, 14,
+   14,  7, 17, 21,  7,  6, 11,  2,  5,  2,  5,  6,  8,  8,  8, 24,
+    5, 24,  2, 24,  9, 24, 24,  2, 29, 29, 29,  1, 17, 17, 20, 19,
+   22, 20, 27, 28,  1, 29, 21, 20, 19, 21, 21, 16, 16, 21, 25, 22,
+   18, 21, 21, 29, 15,  6, 18,  6, 12, 11, 11, 12,  9, 26, 26,  9,
+   26,  5,  5, 26, 14,  9,  5, 14, 14, 15, 25, 26, 26, 22, 18, 26,
+   18, 25, 18, 22,  5, 12,  2,  5, 22, 21, 26,  6,  7, 14, 17, 22,
+   18, 18, 26, 14, 17,  6, 14,  6, 12, 24, 24,  6, 26, 15,  6, 21,
+   11, 21, 24,  9, 23, 26, 10, 21,  6, 10,  4,  4,  3,  3,  7, 25,
+   21, 22, 17, 16, 16, 22, 16, 16, 25, 17, 25,  2, 25, 24, 23,  2,
+    2, 15, 12, 15, 14,  2, 21, 14,  7, 15, 21,  1, 26, 10, 10,  1,
+   23, 15,  0,  1,  2,  3,  4,  5,  6,  7,  8,  9,  0, 10, 11, 12,
+   13,  0, 14,  0,  0,  0,  0,  0, 15,  0, 16,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0, 17, 18, 19,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 20,
+    0, 21, 22, 23,  0,  0,  0, 24, 25, 26, 27, 28, 29, 30, 31, 32,
+   33,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0, 34,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+   35,  0,  0,  0,  0,  0,  0,  0,  0,  0, 36, 37,  0,  0,  0,  0,
+    0,  0, 38, 39,  0,  0, 40,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    1,  2,  3,  4,  0,  0,  0,  0,  0,  0,  0,  0,  5,  0,  0,  0,
+    0,  0,  0,  0,  6,  7,  8,  0,  9,  0, 10, 11,  0,  0, 12, 13,
+   14, 15, 16,  0,  0,  0,  0, 17, 18, 19, 20,  0,  0,  0, 21, 22,
+    0, 23, 24,  0,  0, 23, 25, 26,  0, 23, 25,  0,  0, 23, 25,  0,
+    0, 23, 25,  0,  0,  0, 25,  0,  0,  0, 27,  0,  0, 23, 25,  0,
+    0, 28, 25,  0,  0,  0, 29,  0,  0, 30, 31,  0,  0, 32, 33,  0,
+   34, 35,  0, 36, 37,  0, 38,  0,  0, 39,  0,  0, 40,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0, 41,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+   42, 42,  0,  0,  0,  0, 43,  0,  0,  0,  0,  0,  0, 44,  0,  0,
+    0, 45,  0,  0,  0,  0,  0,  0, 46,  0,  0, 47,  0, 48,  0,  0,
+    0, 49, 50, 51,  0, 52,  0, 53,  0, 54,  0,  0,  0,  0, 55, 56,
+    0,  0,  0,  0,  0,  0, 57, 58,  0,  0,  0,  0,  0,  0, 59, 60,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 61,
+    0,  0,  0, 62,  0,  0,  0, 63,  0, 64,  0,  0, 65,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 66, 67,  0,  0, 68,
+    0,  0,  0,  0,  0,  0,  0,  0, 69,  0,  0,  0,  0,  0, 50, 70,
+    0, 71, 72,  0,  0, 73, 74,  0,  0,  0,  0,  0,  0, 75, 76, 77,
+    0,  0,  0,  0,  0,  0,  0, 25,  0,  0,  0,  0,  0,  0,  0,  0,
+   78,  0,  0,  0,  0,  0,  0,  0,  0, 79,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0, 80,  0,  0,  0,  0,  0,  0,  0, 81,
+    0,  0,  0, 82,  0,  0,  0,  0, 83, 84,  0,  0,  0,  0,  0, 85,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0, 86,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0, 87,  0,  0,  0,  0,  0,  0,  0, 69, 62,  0, 88,  0,  0,
+   89, 90,  0, 73,  0,  0, 91,  0,  0, 92,  0,  0,  0,  0,  0, 93,
+    0, 94, 25, 95,  0,  0,  0,  0,  0,  0, 96,  0,  0,  0, 97,  0,
+    0,  0,  0,  0,  0, 62, 98,  0,  0, 62,  0,  0,  0, 99,  0,  0,
+    0,100,  0,  0,  0,  0,  0,  0,  0, 88,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0, 74,  0, 42,101,  0,102,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0, 62,  0,  0,  0,  0,  0,  0,
+    0,  0,103,  0,104,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,105,
+    0,106,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,107,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,108,109,110,  0,  0,  0,  0,111,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,112,113,  0,  0,  0,  0,  0,  0,
+    0,106,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,114,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,115,  0,
+    0,  0,116,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    1,  1,  1,  1,  1,  2,  3,  4,  5,  6,  7,  4,  4,  8,  9, 10,
+    1, 11, 12, 13, 14, 15, 16, 17, 18,  1,  1,  1,  0,  0,  0,  0,
+   19,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 20, 21, 22,  1,
+   23,  4, 21, 24, 25, 26, 27, 28, 29, 30,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  1,  1, 31,  0,  0,  0, 32, 33, 34, 35,  1, 36,
+    0,  0,  0,  0, 37,  0,  0,  0,  0,  0,  0,  0,  0, 38,  1, 39,
+   14, 39, 40, 41,  0,  0,  0,  0,  0,  0,  0,  0, 42,  0,  0,  0,
+    0,  0,  0,  0, 43, 36, 44, 45, 21, 45, 46,  0,  0,  0,  0,  0,
+    0,  0, 19,  1, 21,  0,  0, 47,  0,  0,  0,  0,  0, 38, 48,  1,
+    1, 49, 49, 50,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 51,  0,
+    0,  0,  0,  0, 52,  1,  1,  1, 53, 21, 43, 54, 55, 21, 35,  1,
+    0,  0,  0,  0,  0,  0,  0, 56,  0,  0,  0, 57, 58, 59,  0,  0,
+    0,  0,  0, 57,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 60,
+    0,  0,  0, 57,  0, 61,  0,  0,  0,  0,  0,  0,  0,  0, 62, 63,
+    0,  0, 64,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 65,  0,
+    0,  0, 66,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 67,  0,
+    0,  0, 68,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 69,  0,
+    0,  0,  0,  0,  0, 70, 71,  0,  0,  0,  0,  0, 72, 73, 74, 75,
+   76, 77,  0,  0,  0,  0,  0,  0,  0, 78,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0, 79, 80,  0,  0,  0,  0, 47,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0, 49,  0,  0,  0,  0,  0, 63,  0,  0,
+    0,  0,  0,  0, 64,  0,  0, 81,  0,  0, 82,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0, 83,  0,  0,  0,  0,  0,  0, 19, 84,  0,
+   63,  0,  0,  0,  0, 49,  1, 85,  0,  0,  0,  0,  1, 54, 15, 41,
+    0,  0,  0,  0,  0, 56,  0,  0,  0, 63,  0,  0,  0,  0,  0,  0,
+    0,  0, 19, 10,  1,  0,  0,  0,  0,  0, 86,  0,  0,  0,  0,  0,
+    0, 87,  0,  0, 86,  0,  0,  0,  0,  0,  0,  0,  0, 79,  0,  0,
+    0,  0,  0,  0, 88,  9, 12,  4, 89,  8, 90, 47,  0, 59, 50,  0,
+   21,  1, 21, 91, 92,  1,  1,  1,  1,  1,  1,  1,  1, 93, 94, 95,
+    0,  0,  0,  0, 96,  1, 97, 59, 81, 98, 99,  4, 59,  0,  0,  0,
+    0,  0,  0, 19, 50,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 62,
+    1,  1,  1,  1,  1,  1,  1,  1,  0,  0,100,101,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,102,  0,  0,  0,  0, 19,  0,  1,  1, 50,
+    0,  0,  0,  0,  0,  0,  0, 38,  0,  0,  0,  0, 50,  0,  0,  0,
+    0, 64,  0,  0,  0,  0,  0,  0,  1,  1,  1,  1, 50,  0,  0,  0,
+    0,  0, 52, 69,  0,  0,  0,  0,  0,  0,  0,  0, 62,  0,  0,  0,
+    0,  0,  0,  0, 79,  0,  0,  0, 63,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,103,104, 59, 38, 81,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0, 64,  0,  0,  0,  0,  0,  0,  0,  0,  0,105,
+    1, 14,  4, 12,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 47,
+   84,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 38, 88,  0,
+    0,  0,  0,106,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,107, 62,
+    0,108,  0,  0,  0,  0,  0,  0,  0,  1,  0,  0,  0,  0,  0,  0,
+    0,109, 14, 54, 84,  0,  0,  0,  0,  0,  0,  0,  0,  0,110,  0,
+   88,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 62, 63,  0,  0,
+   63,  0, 87,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,110,  0,  0,
+    0,  0,111,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 79, 56,
+    0, 38,  1, 59,  1, 59,  0,  0, 64, 87,  0,  0,  0,  0,  0, 60,
+  112,  0,  0,  0,  0,  0,  0,  0, 56,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,112,  0,  0,  0,  0, 62,  0,  0,  0,  0,  0,
+    0, 62,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 57,  0,
+   87,113,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 62,  0,  0,
+    0,  0,  0,  0,  8, 90,  0,  0,  0,  0,  0,  0,  1, 88,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,114,  0,115,116,117,118,  0, 52,  4,
+  119, 49, 23,  0,  0,  0,  0,  0,  0,  0, 38, 50,  0,  0,  0,  0,
+   38, 59,  0,  0,  0,  0,  0,  0,  1, 88,  1,  1,  1,  1, 39,  1,
+   48,103, 88,  0,  0,  0,  0,  0,  0,  0,  0,  1,  0,  0,  0,  0,
+    0,  0,  0,  0,  4,119,  0,  0,  0,  1,120,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,230,230,230,230,230,232,220,220,220,220,232,216,
+  220,220,220,220,220,202,202,220,220,220,220,202,202,220,220,220,
+    1,  1,  1,  1,  1,220,220,220,220,230,230,230,230,240,230,220,
+  220,220,230,230,230,220,220,  0,230,230,230,220,220,220,220,230,
+  232,220,220,230,233,234,234,233,234,234,233,230,  0,  0,  0,230,
+    0,220,230,230,230,230,220,230,230,230,222,220,230,230,220,220,
+  230,222,228,230, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 19, 20,
+   21, 22,  0, 23,  0, 24, 25,  0,230,220,  0, 18, 30, 31, 32,  0,
+    0,  0,  0, 27, 28, 29, 30, 31, 32, 33, 34,230,230,220,220,230,
+  220,230,230,220, 35,  0,  0,  0,  0,  0,230,230,230,  0,  0,230,
+  230,  0,220,230,230,220,  0,  0,  0, 36,  0,  0,230,220,230,230,
+  220,220,230,220,220,230,220,230,220,230,230,  0,  0,220,  0,  0,
+  230,230,  0,230,  0,230,230,230,230,230,  0,  0,  0,220,220,220,
+    0,  0,  0,220,230,230,  0,220,230,220,220,220, 27, 28, 29,230,
+    7,  0,  0,  0,  0,  9,  0,  0,  0,230,220,230,230,  0,  0,  0,
+    0,  0,230,  0,  0, 84, 91,  0,  0,  0,  0,  9,  9,  0,  0,  0,
+    0,  0,  9,  0,103,103,  9,  0,107,107,107,107,118,118,  9,  0,
+  122,122,122,122,220,220,  0,  0,  0,220,  0,220,  0,216,  0,  0,
+    0,129,130,  0,132,  0,  0,  0,  0,  0,130,130,130,130,  0,  0,
+  130,  0,230,230,  9,  0,230,230,  0,  0,220,  0,  0,  0,  0,  7,
+    0,  9,  9,  0,  0,230,  0,  0,  0,228,  0,  0,  0,222,230,220,
+  220,  0,  0,  0,230,  0,  0,220,  0,  0,  9,  9,  0,  0,  7,  0,
+  230,230,230,  0,230,  0,  1,  1,  1,  0,  0,  0,230,234,214,220,
+  202,230,230,230,230,230,232,228,228,220,  0,230,233,220,230,220,
+  230,230,  1,  1,  1,  1,  1,230,  0,  1,  1,230,220,230,  1,  1,
+    0,  0,218,228,232,222,224,224,  0,  8,  8,  0,230,  0,230,230,
+  220,  0,  0,230,  0,  0, 26,  0,  0,220,  0,230,230,  1,220,  0,
+    0,230,220,  0,  0,  0,220,220,  0,  9,  7,  0,  0,  7,  9,  0,
+    0,  0,  9,  7,  9,  9,  0,  0,  0,  0,  1,  0,  0,216,216,  1,
+    1,  1,  0,  0,  0,226,216,216,216,216,216,  0,220,220,220,  0,
+  230,230,  7,  0, 16, 17, 17, 17, 17, 17, 17, 33, 17, 17, 17, 19,
+   17, 17, 17, 17, 20,101, 17,113,129,169, 17, 27, 28, 17, 17, 17,
+   17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+   17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+   17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+   17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+   17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+   17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+   17, 17, 17,237,  0,  1,  2,  2,  0,  3,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  4,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    5,  0,  0,  0,  0,  6,  7,  8,  9,  0,  0,  0, 10, 11, 12, 13,
+   14, 15, 16, 17, 18, 19,  0,  0,  0,  0,  0,  0,  0,  0,  0, 20,
+    0,  0, 21, 22,  0,  0,  0,  0, 23, 24, 25, 26,  0, 27,  0, 28,
+   29, 30, 31, 32,  0,  0,  0,  0,  0,  0,  0, 33, 34, 35,  0,  0,
+    0,  0,  0,  0, 36,  0,  0,  0,  0,  0,  0,  0,  0,  0, 37, 38,
+    0,  0,  0,  0,  1,  2, 39, 40,  0,  1,  2,  2,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  1,  0,  0,  0,  0,  2,  0,  0,  0,  0,
+    0,  0,  3,  4,  0,  0,  5,  0,  0,  0,  6,  0,  0,  0,  0,  0,
+    0,  0,  7,  1,  0,  0,  0,  0,  0,  0,  8,  9,  0,  0,  0,  0,
+    0,  0, 10,  0,  0, 10,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0, 10,  0,  0,  0, 10,  0,  0,  0,  0,  0,  0, 11, 12,
+    0, 13,  0, 14, 15, 16,  0,  0,  0,  0,  0,  1, 17, 18,  0, 19,
+    7,  1,  0,  0,  0, 20, 20,  7, 20, 20, 20, 20, 20, 20, 20,  8,
+   21,  0, 22,  0,  7, 23, 24,  0, 20, 20, 25,  0,  0,  0, 26, 27,
+    1,  7, 20, 20, 20, 20, 20,  1, 28, 29, 30, 31,  0,  0, 20,  0,
+    0,  0,  0,  0,  0,  0, 10,  0,  0,  0,  0,  0,  0,  0, 20, 20,
+   20,  1,  0,  0,  8, 21, 32,  4,  0, 10,  0, 33,  7, 20, 20, 20,
+    0,  0,  0,  0,  8, 34, 34, 35, 36, 34, 37,  0, 38,  1, 20, 20,
+    0,  0, 39,  0,  1,  1,  0,  8, 21,  1, 20,  0,  0,  0,  1,  0,
+    0, 40,  1,  1,  0,  0,  8, 21,  0,  1,  0,  1,  0,  1,  0,  0,
+    0,  0, 26, 34, 34, 34, 34, 34, 34, 34, 34, 34, 21,  7, 20, 41,
+   34, 34, 34, 34, 34, 34, 34, 34, 34, 21,  0, 42, 43, 44,  0, 45,
+    0,  8, 21,  0,  0,  0,  0,  0,  0,  0,  0, 46,  7,  1, 10,  1,
+    0,  0,  0,  1, 20, 20,  1,  0,  0,  0,  0,  0,  0,  0, 20, 20,
+    1, 20, 20,  0,  0,  0,  0,  0,  0,  0, 26, 21,  0,  1,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  3, 47, 48,  0,  0,  0,
+    0,  0,  0,  0,  0,  1,  2,  3,  4,  5,  6,  7,  7,  8,  7,  7,
+    7,  7,  7,  7,  7,  7,  7,  9, 10, 11, 12, 12, 12, 12, 13, 14,
+   14, 14, 14, 15, 16, 17, 18, 19, 20, 14, 21, 14, 22, 14, 14, 14,
+   14, 23, 24, 24, 25, 26, 14, 14, 14, 14, 27, 28, 14, 14, 29, 30,
+   31, 32, 33, 34,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,
+    7,  7,  7,  7,  7,  7,  7,  7, 35,  7, 36, 37,  7, 38,  7,  7,
+    7, 39, 14, 40, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+   14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+   14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+   14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+   14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+   14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+   14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+   14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+   14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+   14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+   14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+   14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+   14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+   14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+   14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+   14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+   14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+   14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+   14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+   14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+   14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+   14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+   14, 14, 14, 14, 41,  0,  0,  1,  2,  2,  2,  3,  4,  5,  6,  7,
+    8,  9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23,
+   24, 25, 26, 27, 28, 29, 30, 31, 32, 32, 33, 34, 35, 36, 37, 37,
+   37, 37, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50,
+   51, 52,  2,  2, 53, 54, 55, 56, 57, 58, 59, 59, 59, 59, 60, 59,
+   59, 59, 59, 59, 59, 59, 61, 61, 59, 59, 59, 59, 62, 63, 64, 65,
+   66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 59, 70, 70,
+   70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70,
+   70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70,
+   70, 79, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70,
+   70, 70, 70, 70, 70, 80, 81, 81, 81, 81, 81, 81, 81, 81, 81, 82,
+   83, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 32, 32,
+   32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+   32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+   32, 32, 32, 32, 32, 96, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97,
+   97, 97, 97, 97, 97, 97, 97, 97, 70, 70, 98, 99,100,101,102,102,
+  103,104,105,106,107,108,109,110,111,112, 97,113,114,115,116,117,
+  118, 97,119,119,120, 97,121,122,123,124,125,126,127,128,129,130,
+  131, 97,132, 97,133,134,135,136,137,138,139,140,141, 97,142,143,
+   97,144,145,146,147, 97,148,149, 97,150,151,152, 97, 97,153,154,
+  155,156, 97,157, 97,158,159,159,159,159,159,159,159,160,161,159,
+  162, 97, 97, 97, 97, 97,163,163,163,163,163,163,163,163,164, 97,
+   97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97,165,165,
+  165,165,166, 97, 97, 97,167,167,167,167,168,169,170,171, 97, 97,
+   97, 97,172,173,174,175,176,176,176,176,176,176,176,176,176,176,
+  176,176,176,176,176,176,176,176,176,176,176,176,176,176,176,176,
+  176,176,176,176,176,177,176,176,176,176,176,178, 97, 97, 97, 97,
+   97, 97, 97, 97, 97, 97,179,180,181,182,182,183, 97, 97, 97, 97,
+   97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97,184,185,
+   97, 97, 97, 97, 97, 97, 59,186,187,188,189,190,191, 97,192,193,
+  194, 59, 59,195, 59,196,197,197,197,197,197,198, 97, 97, 97, 97,
+   97, 97, 97, 97, 97, 97,199, 97,200, 97, 97,201, 97, 97, 97, 97,
+   97, 97, 97, 97, 97, 97,202,203,204, 97, 97, 97, 97, 97,205,206,
+  207, 97,208,209, 97, 97,210,211,212,213,214, 97, 59, 59, 59, 59,
+   59, 59, 59,215,216,217,218,219,220,221,222,223, 97, 97, 97, 97,
+   97, 97, 97, 97, 97, 97, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70,
+   70, 70, 70,224, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70,
+   70, 70, 70, 70,225, 70,226, 70, 70, 70, 70, 70, 70, 70, 70, 70,
+   70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70,
+   70, 70, 70,227, 70, 70, 70, 70, 70, 70, 70, 70, 70,228, 97, 97,
+   97, 97, 97, 97, 97, 97, 70, 70, 70, 70,229, 97, 97, 97, 97, 97,
+   97, 97, 97, 97, 97, 97,230, 97,231,232,  0,  1,  2,  2,  0,  1,
+    2,  2,  2,  3,  4,  5,  0,  0,  0,  0,  0,  0,  0,  0,  0, 19,
+   19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
+   19,  0,  0,  0,  0,  0,  0,  0, 19,  0,  0,  0,  0,  0, 19, 19,
+   19, 19, 19, 19, 19,  0, 19,  0,  0,  0,  0,  0,  0,  0, 19, 19,
+   19, 19, 19,  0,  0,  0,  0,  0, 26, 26,  0,  0,  0,  0,  1,  1,
+    1,  1,  1,  1,  1,  1,  9,  9,  9,  9,  0,  9,  9,  9,  2,  2,
+    9,  9,  9,  9,  0,  9,  2,  2,  2,  2,  9,  0,  9,  0,  9,  9,
+    9,  2,  9,  2,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,
+    2,  9,  9,  9,  9,  9,  9,  9, 55, 55, 55, 55, 55, 55, 55, 55,
+   55, 55, 55, 55, 55, 55,  6,  6,  6,  6,  6,  6,  6,  6,  6,  6,
+    6,  6,  6,  1,  1,  6,  2,  4,  4,  4,  4,  4,  4,  4,  4,  4,
+    4,  4,  4,  4,  4,  4,  4,  4,  4,  4,  4,  4,  4,  2,  4,  0,
+    4,  2,  2,  4,  4,  4,  2, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+   14, 14, 14, 14, 14, 14,  2,  2,  2,  2,  2,  2,  2,  2, 14, 14,
+   14,  2,  2,  2,  2, 14, 14, 14, 14, 14, 14,  2,  2,  2,  3,  3,
+    3,  3,  3,  0,  3,  3,  3,  3,  3,  3,  0,  3,  3,  3,  3,  3,
+    3,  3,  3,  3,  3,  3,  3,  3,  3,  0,  3,  2,  3,  0,  0,  3,
+    3,  3,  3,  3,  3,  3,  3,  3,  3,  1,  1,  1,  1,  1,  1,  1,
+    1,  1,  1,  1,  3,  3,  1,  3,  3,  3,  3,  3,  3,  3, 37, 37,
+   37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37,  2, 37, 37, 37,
+   37,  2,  2, 37, 37, 37, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38,
+    2,  2,  2,  2,  2,  2, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
+   64,  2,  2, 64, 64, 64, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90,
+   90, 90, 90, 90,  2,  2, 90, 90, 90, 90, 90, 90, 90,  2, 95, 95,
+   95, 95, 95, 95, 95, 95, 95, 95, 95, 95,  2,  2, 95,  2, 37, 37,
+   37,  2,  2,  2,  2,  2,  3,  3,  3,  3,  3,  2,  3,  3,  3,  3,
+    3,  3,  3,  3,  2,  2,  2,  2,  2,  3,  3,  3,  3,  3,  3,  3,
+    0,  3,  3,  3,  3,  3,  7,  7,  7,  7,  7,  7,  7,  7,  7,  1,
+    1,  1,  1,  7,  7,  7,  7,  7,  7,  7,  0,  0,  7,  7,  5,  5,
+    5,  5,  2,  5,  5,  5,  5,  5,  5,  5,  5,  2,  2,  5,  5,  2,
+    2,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  2,
+    5,  5,  5,  5,  5,  5,  5,  2,  5,  2,  2,  2,  5,  5,  5,  5,
+    2,  2,  5,  5,  5,  5,  5,  2,  2,  5,  5,  5,  5,  2,  2,  2,
+    2,  2,  2,  2,  2,  5,  2,  2,  2,  2,  5,  5,  2,  5,  5,  5,
+    5,  5,  2,  2,  5,  5,  5,  5,  5,  5,  5,  5,  5,  2,  2, 11,
+   11, 11,  2, 11, 11, 11, 11, 11, 11,  2,  2,  2,  2, 11, 11,  2,
+    2, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11,  2,
+   11, 11, 11, 11, 11, 11, 11,  2, 11, 11,  2, 11, 11,  2, 11, 11,
+    2,  2, 11,  2, 11, 11, 11,  2,  2, 11, 11, 11,  2,  2,  2, 11,
+    2,  2,  2,  2,  2,  2,  2, 11, 11, 11, 11,  2, 11,  2,  2,  2,
+    2,  2,  2,  2, 11, 11, 11, 11, 11, 11, 11, 11, 11,  2,  2, 10,
+   10, 10,  2, 10, 10, 10, 10, 10, 10, 10, 10, 10,  2, 10, 10, 10,
+    2, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10,  2,
+   10, 10, 10, 10, 10, 10, 10,  2, 10, 10,  2, 10, 10, 10, 10, 10,
+    2,  2, 10, 10, 10, 10, 10, 10,  2, 10, 10, 10,  2,  2, 10,  2,
+    2,  2,  2,  2,  2,  2, 10, 10, 10, 10,  2,  2, 10, 10, 10, 10,
+    2,  2,  2,  2,  2,  2,  2, 10, 10, 10, 10, 10, 10, 10,  2, 21,
+   21, 21,  2, 21, 21, 21, 21, 21, 21, 21, 21,  2,  2, 21, 21,  2,
+    2, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,  2,
+   21, 21, 21, 21, 21, 21, 21,  2, 21, 21,  2, 21, 21, 21, 21, 21,
+    2,  2, 21, 21, 21, 21, 21,  2,  2, 21, 21, 21,  2,  2,  2,  2,
+    2,  2,  2,  2, 21, 21,  2,  2,  2,  2, 21, 21,  2, 21, 21, 21,
+   21, 21,  2,  2, 21, 21,  2,  2, 22, 22,  2, 22, 22, 22, 22, 22,
+   22,  2,  2,  2, 22, 22, 22,  2, 22, 22, 22, 22,  2,  2,  2, 22,
+   22,  2, 22,  2, 22, 22,  2,  2,  2, 22, 22,  2,  2,  2, 22, 22,
+   22, 22, 22, 22, 22, 22, 22, 22,  2,  2,  2,  2, 22, 22, 22,  2,
+    2,  2,  2,  2,  2, 22,  2,  2,  2,  2,  2,  2, 22, 22, 22, 22,
+   22,  2,  2,  2,  2,  2, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23,
+   23, 23, 23,  2, 23, 23, 23,  2, 23, 23, 23, 23, 23, 23, 23, 23,
+    2,  2,  2, 23, 23, 23, 23,  2, 23, 23, 23, 23,  2,  2,  2,  2,
+    2,  2,  2, 23, 23,  2, 23, 23, 23,  2,  2,  2,  2,  2, 23, 23,
+   23, 23,  2,  2, 23, 23,  2,  2,  2,  2,  2,  2,  2, 23, 16, 16,
+   16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,  2, 16, 16, 16,  2,
+   16, 16, 16, 16, 16, 16, 16, 16, 16, 16,  2, 16, 16, 16, 16, 16,
+    2,  2, 16, 16, 16, 16, 16,  2, 16, 16, 16, 16,  2,  2,  2,  2,
+    2,  2,  2, 16, 16,  2,  2,  2,  2,  2,  2,  2, 16,  2, 16, 16,
+   16, 16,  2,  2, 16, 16,  2, 16, 16,  2,  2,  2,  2,  2, 20, 20,
+   20, 20,  2, 20, 20, 20, 20, 20, 20, 20, 20,  2, 20, 20, 20,  2,
+   20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,  2,  2,
+    2,  2, 20, 20, 20, 20, 20, 20, 20, 20,  2,  2, 20, 20,  2,  2,
+   36, 36,  2, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36,
+   36, 36, 36, 36, 36,  2,  2,  2, 36, 36, 36, 36, 36, 36, 36, 36,
+    2, 36, 36, 36, 36, 36, 36, 36, 36, 36,  2, 36,  2,  2,  2,  2,
+   36,  2,  2,  2,  2, 36, 36, 36, 36, 36, 36,  2, 36,  2,  2,  2,
+    2,  2,  2,  2, 36, 36,  2,  2, 36, 36, 36,  2,  2,  2,  2, 24,
+   24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
+   24,  2,  2,  2,  2,  0, 24, 24, 24, 24,  2,  2,  2,  2,  2, 18,
+   18,  2, 18,  2, 18, 18, 18, 18, 18,  2, 18, 18, 18, 18, 18, 18,
+   18, 18, 18, 18, 18, 18, 18, 18, 18, 18,  2, 18,  2, 18, 18, 18,
+   18, 18, 18, 18,  2,  2, 18, 18, 18, 18, 18,  2, 18,  2, 18, 18,
+    2,  2, 18, 18, 18, 18, 25, 25, 25, 25, 25, 25, 25, 25,  2, 25,
+   25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,  2,  2,  2, 25, 25,
+   25, 25, 25,  2, 25, 25, 25, 25, 25, 25, 25,  0,  0,  0,  0, 25,
+   25,  2,  2,  2,  2,  2, 33, 33, 33, 33, 33, 33, 33, 33,  8,  8,
+    8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  2,  8,  2,  2,
+    2,  2,  2,  8,  2,  2,  8,  8,  8,  0,  8,  8,  8,  8, 12, 12,
+   12, 12, 12, 12, 12, 12, 30, 30, 30, 30, 30, 30, 30, 30, 30,  2,
+   30, 30, 30, 30,  2,  2, 30, 30, 30, 30, 30, 30, 30,  2, 30, 30,
+   30,  2,  2, 30, 30, 30, 30, 30, 30, 30, 30,  2,  2,  2, 30, 30,
+    2,  2,  2,  2,  2,  2, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29,
+   29, 29, 29, 29,  2,  2, 28, 28, 28, 28, 28, 28, 28, 28, 34, 34,
+   34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,  2,  2,  2, 35, 35,
+   35, 35, 35, 35, 35, 35, 35, 35, 35,  0,  0,  0, 35, 35, 35,  2,
+    2,  2,  2,  2,  2,  2, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,
+   45, 45, 45,  2, 45, 45, 45, 45, 45, 45, 45,  2,  2,  2, 44, 44,
+   44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44,  0,  0,  2, 43, 43,
+   43, 43, 43, 43, 43, 43, 43, 43, 43, 43,  2,  2,  2,  2, 46, 46,
+   46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46,  2, 46, 46, 46,  2,
+   46, 46,  2,  2,  2,  2, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31,
+   31, 31, 31, 31,  2,  2, 31, 31,  2,  2,  2,  2,  2,  2, 32, 32,
+    0,  0, 32,  0, 32, 32, 32, 32, 32, 32, 32, 32, 32,  2, 32, 32,
+   32, 32, 32, 32, 32, 32, 32, 32,  2,  2,  2,  2,  2,  2, 32,  2,
+    2,  2,  2,  2,  2,  2, 32, 32, 32,  2,  2,  2,  2,  2, 28, 28,
+   28, 28, 28, 28,  2,  2, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48,
+   48, 48, 48, 48, 48,  2, 48, 48, 48, 48,  2,  2,  2,  2, 48,  2,
+    2,  2, 48, 48, 48, 48, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52,
+   52, 52, 52, 52,  2,  2, 52, 52, 52, 52, 52,  2,  2,  2, 58, 58,
+   58, 58, 58, 58, 58, 58, 58, 58, 58, 58,  2,  2,  2,  2, 58, 58,
+    2,  2,  2,  2,  2,  2, 58, 58, 58,  2,  2,  2, 58, 58, 54, 54,
+   54, 54, 54, 54, 54, 54, 54, 54, 54, 54,  2,  2, 54, 54, 91, 91,
+   91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,  2, 91, 91,
+   91, 91, 91,  2,  2, 91, 91, 91,  2,  2,  2,  2,  2,  2, 91, 91,
+   91, 91, 91, 91,  2,  2,  1,  1,  1,  1,  1,  1,  1,  2, 62, 62,
+   62, 62, 62, 62, 62, 62, 62, 62, 62, 62,  2,  2,  2,  2, 62, 62,
+   62, 62, 62,  2,  2,  2, 76, 76, 76, 76, 76, 76, 76, 76, 93, 93,
+   93, 93, 93, 93, 93, 93, 93, 93, 93, 93,  2,  2,  2,  2,  2,  2,
+    2,  2, 93, 93, 93, 93, 70, 70, 70, 70, 70, 70, 70, 70,  2,  2,
+    2, 70, 70, 70, 70, 70, 70, 70,  2,  2,  2, 70, 70, 70, 73, 73,
+   73, 73, 73, 73, 73, 73,  6,  2,  2,  2,  2,  2,  2,  2,  8,  8,
+    8,  2,  2,  8,  8,  8,  1,  1,  1,  0,  1,  1,  1,  1,  1,  0,
+    1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  1,  0,  0,  0,  0,
+    0,  0,  1,  0,  0,  0,  1,  1,  0,  2,  2,  2,  2,  2, 19, 19,
+   19, 19, 19, 19,  9,  9,  9,  9,  9,  6, 19, 19, 19, 19, 19, 19,
+   19, 19, 19,  9,  9,  9,  9,  9, 19, 19, 19, 19,  9,  9,  9,  9,
+    9, 19, 19, 19, 19, 19,  6, 19, 19, 19, 19, 19, 19, 19, 19, 19,
+   19, 19, 19, 19, 19,  9,  1,  1,  2,  1,  1,  1,  1,  1,  9,  9,
+    9,  9,  9,  9,  2,  2,  2,  9,  2,  9,  2,  9,  2,  9,  9,  9,
+    9,  9,  9,  2,  9,  9,  9,  9,  9,  9,  2,  2,  9,  9,  9,  9,
+    9,  9,  2,  9,  9,  9,  2,  2,  9,  9,  9,  2,  9,  9,  9,  9,
+    9,  9,  9,  9,  9,  2,  0,  0,  0,  0,  1,  1,  0,  0,  0,  0,
+    0,  0,  0,  2,  0,  0,  0, 19,  2,  2,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0, 19,  0,  0,  0,  0,  0,  0,  0,  2, 19, 19,
+   19, 19, 19,  2,  2,  2,  1,  2,  2,  2,  2,  2,  2,  2,  0,  0,
+    0,  0,  0,  0,  9,  0,  0,  0, 19, 19,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0, 19,  0, 19,  0,  0,  0,  2,  2,  2,  2,  0,  0,
+    0,  2,  2,  2,  2,  2, 27, 27, 27, 27, 27, 27, 27, 27,  0,  0,
+    0,  0,  2,  2,  0,  0,  0,  0,  0,  0,  0,  0,  2,  2, 56, 56,
+   56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56,  2, 55, 55,
+   55, 55,  2,  2,  2,  2,  2, 55, 55, 55, 55, 55, 55, 55, 61, 61,
+   61, 61, 61, 61, 61, 61,  2,  2,  2,  2,  2,  2,  2, 61, 61,  2,
+    2,  2,  2,  2,  2,  2, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+    2, 13, 13, 13, 13, 13, 13, 13, 13, 13,  2,  2,  2,  2, 13, 13,
+   13, 13, 13, 13,  2,  2,  0,  0,  0,  0,  2,  2,  2,  2,  0,  0,
+    0,  0,  0, 13,  0, 13,  0, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+    1,  1,  1,  1, 12, 12, 13, 13, 13, 13,  0,  0,  0,  0,  2, 15,
+   15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+   15, 15, 15, 15, 15,  2,  2,  1,  1,  0,  0, 15, 15, 15,  0, 17,
+   17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+   17,  0,  0, 17, 17, 17,  2,  2,  2,  2,  2, 26, 26, 26, 26, 26,
+   26, 26, 26, 26, 26, 26,  2, 12, 12, 12, 12, 12, 12, 12, 12, 12,
+   12, 12, 12, 12, 12,  2, 26, 26, 26,  2,  2,  2,  2,  2, 12, 12,
+   12, 12, 12, 12, 12,  0, 17, 17, 17, 17, 17, 17, 17,  0, 39, 39,
+   39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39,  2,  2,  2, 39, 39,
+   39, 39, 39, 39, 39,  2, 86, 86, 86, 86, 86, 86, 86, 86, 77, 77,
+   77, 77, 77, 77, 77, 77, 77, 77, 77, 77,  2,  2,  2,  2, 79, 79,
+   79, 79, 79, 79, 79, 79,  0,  0, 19, 19, 19, 19, 19, 19,  0,  0,
+    0, 19, 19, 19, 19, 19,  2,  2, 19, 19, 19, 19, 19,  2,  2,  2,
+    2,  2,  2,  2,  2, 19, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60,
+   60, 60,  2,  2,  2,  2,  0,  0,  2,  2,  2,  2,  2,  2, 65, 65,
+   65, 65, 65, 65, 65, 65, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75,
+   75, 75, 75, 75,  2,  2,  2,  2,  2,  2,  2,  2, 75, 75, 75, 75,
+    2,  2,  2,  2,  2,  2, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69,
+   69, 69, 69, 69,  0, 69, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74,
+   74, 74,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2, 74, 12, 12,
+   12, 12, 12,  2,  2,  2, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84,
+   84, 84, 84, 84,  2,  0, 84, 84,  2,  2,  2,  2, 84, 84, 33, 33,
+   33, 33, 33, 33, 33,  2, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68,
+   68, 68, 68, 68, 68,  2, 68, 68, 68, 68, 68, 68,  2,  2, 68, 68,
+    2,  2, 68, 68, 68, 68, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92,
+   92,  2,  2,  2,  2,  2,  2,  2,  2, 92, 92, 92, 92, 92, 87, 87,
+   87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87,  2,  2, 30,
+   30, 30, 30, 30, 30,  2, 19, 19, 19,  0, 19, 19, 19, 19, 19, 19,
+   19, 19, 19,  9, 19, 19, 87, 87, 87, 87, 87, 87,  2,  2, 87, 87,
+    2,  2,  2,  2,  2,  2, 12, 12, 12, 12,  2,  2,  2,  2,  2,  2,
+    2, 12, 12, 12, 12, 12, 13, 13,  2,  2,  2,  2,  2,  2, 19, 19,
+   19, 19, 19, 19, 19,  2,  2,  2,  2,  4,  4,  4,  4,  4,  2,  2,
+    2,  2,  2, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,  2, 14, 14,
+   14, 14, 14,  2, 14,  2, 14, 14,  2, 14, 14,  2, 14, 14,  3,  3,
+    2,  2,  2,  2,  2,  2,  3,  3,  3,  3,  3,  3,  0,  0,  2,  2,
+    3,  3,  3,  3,  3,  3,  1,  1,  1,  1,  1,  1,  6,  6,  0,  0,
+    0,  2,  0,  0,  0,  0,  3,  3,  3,  3,  3,  2,  2,  0,  2,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 17, 17, 17, 17,
+   17, 17, 17, 17,  0,  0,  2,  2, 12, 12, 12, 12, 12, 12,  2,  2,
+   12, 12, 12,  2,  2,  2,  2,  0,  0,  0,  0,  0,  2,  2, 49, 49,
+   49, 49, 49, 49, 49, 49, 49, 49, 49, 49,  2, 49, 49, 49, 49, 49,
+   49, 49, 49, 49, 49,  2, 49, 49, 49,  2, 49, 49,  2, 49, 49, 49,
+   49, 49, 49, 49,  2,  2, 49, 49, 49,  2,  2,  2,  2,  2,  0,  0,
+    0,  2,  2,  2,  2,  0,  0,  0,  0,  0,  2,  2,  2,  0,  9,  2,
+    2,  2,  2,  2,  2,  2,  0,  0,  0,  0,  0,  1,  2,  2, 71, 71,
+   71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71,  2,  2,  2, 67, 67,
+   67, 67, 67, 67, 67, 67, 67,  2,  2,  2,  2,  2,  2,  2,  1,  0,
+    0,  0,  0,  0,  0,  0, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42,
+   42, 42,  2,  2,  2,  2,  2,  2,  2,  2,  2, 42, 42, 42, 41, 41,
+   41, 41, 41, 41, 41, 41, 41, 41, 41,  2,  2,  2,  2,  2,118,118,
+  118,118,118,118,118,118,118,118,118,  2,  2,  2,  2,  2, 53, 53,
+   53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53,  2, 53, 59, 59,
+   59, 59, 59, 59, 59, 59, 59, 59, 59, 59,  2,  2,  2,  2, 59, 59,
+   59, 59, 59, 59,  2,  2, 40, 40, 40, 40, 40, 40, 40, 40, 51, 51,
+   51, 51, 51, 51, 51, 51, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+   50, 50, 50, 50,  2,  2, 50, 50,  2,  2,  2,  2,  2,  2,135,135,
+  135,135,135,135,135,135,135,135,135,135,  2,  2,  2,  2,106,106,
+  106,106,106,106,106,106,104,104,104,104,104,104,104,104,104,104,
+  104,104,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,104,110,110,
+  110,110,110,110,110,110,110,110,110,110,110,110,110,  2,110,110,
+  110,110,110,110,  2,  2, 47, 47, 47, 47, 47, 47,  2,  2, 47,  2,
+   47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+   47, 47, 47, 47,  2, 47, 47,  2,  2,  2, 47,  2,  2, 47, 81, 81,
+   81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81,  2, 81,120,120,
+  120,120,120,120,120,120,116,116,116,116,116,116,116,116,116,116,
+  116,116,116,116,116,  2,  2,  2,  2,  2,  2,  2,  2,116,128,128,
+  128,128,128,128,128,128,128,128,128,  2,128,128,  2,  2,  2,  2,
+    2,128,128,128,128,128, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66,
+   66, 66,  2,  2,  2, 66, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72,
+    2,  2,  2,  2,  2, 72, 98, 98, 98, 98, 98, 98, 98, 98, 97, 97,
+   97, 97, 97, 97, 97, 97,  2,  2,  2,  2, 97, 97, 97, 97,  2,  2,
+   97, 97, 97, 97, 97, 97, 57, 57, 57, 57,  2, 57, 57,  2,  2,  2,
+    2,  2, 57, 57, 57, 57, 57, 57, 57, 57,  2, 57, 57, 57,  2, 57,
+   57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57,
+   57, 57, 57, 57,  2,  2, 57, 57, 57,  2,  2,  2,  2, 57, 57,  2,
+    2,  2,  2,  2,  2,  2, 88, 88, 88, 88, 88, 88, 88, 88,117,117,
+  117,117,117,117,117,117,112,112,112,112,112,112,112,112,112,112,
+  112,112,112,112,112,  2,  2,  2,  2,112,112,112,112,112, 78, 78,
+   78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78,  2,  2,  2, 78,
+   78, 78, 78, 78, 78, 78, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83,
+   83, 83, 83, 83,  2,  2, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82,
+   82,  2,  2,  2,  2,  2,122,122,122,122,122,122,122,122,122,122,
+    2,  2,  2,  2,  2,  2,  2,122,122,122,122,  2,  2,  2,  2,122,
+  122,122,122,122,122,122, 89, 89, 89, 89, 89, 89, 89, 89, 89,  2,
+    2,  2,  2,  2,  2,  2,130,130,130,130,130,130,130,130,130,130,
+  130,  2,  2,  2,  2,  2,  2,  2,130,130,130,130,130,130,144,144,
+  144,144,144,144,144,144,144,144,  2,  2,  2,  2,  2,  2,  3,  3,
+    3,  3,  3,  3,  3,  2,147,147,147,147,147,147,147,147,148,148,
+  148,148,148,148,148,148,148,148,  2,  2,  2,  2,  2,  2,149,149,
+  149,149,149,149,149,149,149,149,149,149,149,149,149,  2, 94, 94,
+   94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94,  2,  2,  2,  2,
+   94, 94, 94, 94, 94, 94,  2,  2,  2,  2,  2,  2,  2, 94, 85, 85,
+   85, 85, 85, 85, 85, 85, 85, 85,  2,  2,  2,  2,  2,  2,  2,  2,
+    2,  2,  2, 85,  2,  2,101,101,101,101,101,101,101,101,101,  2,
+    2,  2,  2,  2,  2,  2,101,101,  2,  2,  2,  2,  2,  2, 96, 96,
+   96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96,  2, 96, 96, 96, 96,
+   96, 96, 96, 96, 96,  2,111,111,111,111,111,111,111,111,111,111,
+  111,111,111,111,111,  2,100,100,100,100,100,100,100,100,100,100,
+  100,100,100,100,  2,  2,  2, 36, 36, 36, 36, 36, 36, 36, 36, 36,
+   36, 36, 36,  2,  2,  2,108,108,108,108,108,108,108,108,108,108,
+    2,108,108,108,108,108,108,108,108,108,108,108,108,  2,129,129,
+  129,129,129,129,129,  2,129,  2,129,129,129,129,  2,129,129,129,
+  129,129,129,129,129,129,129,129,129,129,129,129,  2,129,129,129,
+    2,  2,  2,  2,  2,  2,109,109,109,109,109,109,109,109,109,109,
+  109,  2,  2,  2,  2,  2,109,109,  2,  2,  2,  2,  2,  2,107,107,
+  107,107,  2,107,107,107,107,107,107,107,107,  2,  2,107,107,  2,
+    2,107,107,107,107,107,107,107,107,107,107,107,107,107,107,  2,
+  107,107,107,107,107,107,107,  2,107,107,  2,107,107,107,107,107,
+    2,  1,107,107,107,107,107,  2,  2,107,107,107,  2,  2,107,  2,
+    2,  2,  2,  2,  2,107,  2,  2,  2,  2,  2,107,107,107,107,107,
+  107,107,  2,  2,107,107,107,107,107,107,107,  2,  2,  2,137,137,
+  137,137,137,137,137,137,137,137,  2,137,  2,137,137,137,124,124,
+  124,124,124,124,124,124,124,124,  2,  2,  2,  2,  2,  2,123,123,
+  123,123,123,123,123,123,123,123,123,123,123,123,  2,  2,114,114,
+  114,114,114,114,114,114,114,114,114,114,114,  2,  2,  2,114,114,
+    2,  2,  2,  2,  2,  2, 32, 32, 32, 32, 32,  2,  2,  2,102,102,
+  102,102,102,102,102,102,102,  2,  2,  2,  2,  2,  2,  2,102,102,
+    2,  2,  2,  2,  2,  2,126,126,126,126,126,126,126,126,126,126,
+  126,  2,  2,126,126,126,126,126,126,126,  2,  2,  2,  2,142,142,
+  142,142,142,142,142,142,142,142,142,142,  2,  2,  2,  2,125,125,
+  125,125,125,125,125,125,125,125,125,  2,  2,  2,  2,  2,  2,  2,
+    2,  2,  2,  2,  2,125,150,150,150,150,150,150,150,150,  2,  2,
+  150,150,150,150,150,150,150,150,150,150,150,  2,  2,  2,141,141,
+  141,141,141,141,141,141,140,140,140,140,140,140,140,140,140,140,
+  140,  2,  2,  2,  2,  2,121,121,121,121,121,121,121,121,121,  2,
+    2,  2,  2,  2,  2,  2,133,133,133,133,133,133,133,133,133,  2,
+  133,133,133,133,133,133,133,133,133,133,133,133,133,  2,133,133,
+  133,133,133,133,  2,  2,133,133,133,133,133,  2,  2,  2,134,134,
+  134,134,134,134,134,134,  2,  2,134,134,134,134,134,134,  2,134,
+  134,134,134,134,134,134,134,134,134,134,134,134,134,  2,138,138,
+  138,138,138,138,138,  2,138,138,  2,138,138,138,138,138,138,138,
+  138,138,138,138,138,138,  2,  2,138,  2,138,138,  2,138,138,138,
+    2,  2,  2,  2,  2,  2,143,143,143,143,143,143,  2,143,143,  2,
+  143,143,143,143,143,143,143,143,143,143,143,143,143,143,143,143,
+  143,143,143,143,143,  2,143,143,  2,143,143,143,143,143,143,  2,
+    2,  2,  2,  2,  2,  2,143,143,  2,  2,  2,  2,  2,  2,145,145,
+  145,145,145,145,145,145,145,  2,  2,  2,  2,  2,  2,  2, 22, 22,
+    2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2, 22, 63, 63,
+   63, 63, 63, 63, 63, 63, 63, 63,  2,  2,  2,  2,  2,  2, 63, 63,
+   63, 63, 63, 63, 63,  2, 63, 63, 63, 63, 63,  2,  2,  2, 63, 63,
+   63, 63,  2,  2,  2,  2, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80,
+   80, 80, 80, 80, 80,  2, 80,  2,  2,  2,  2,  2,  2,  2,127,127,
+  127,127,127,127,127,127,127,127,127,127,127,127,127,  2, 79,  2,
+    2,  2,  2,  2,  2,  2,115,115,115,115,115,115,115,115,115,115,
+  115,115,115,115,115,  2,115,115,  2,  2,  2,  2,115,115,103,103,
+  103,103,103,103,103,103,103,103,103,103,103,103,  2,  2,119,119,
+  119,119,119,119,119,119,119,119,119,119,119,119,  2,  2,119,119,
+    2,119,119,119,119,119,  2,  2,  2,  2,  2,119,119,119,146,146,
+  146,146,146,146,146,146,146,146,146,  2,  2,  2,  2,  2, 99, 99,
+   99, 99, 99, 99, 99, 99, 99, 99, 99,  2,  2,  2,  2, 99,  2,  2,
+    2,  2,  2,  2,  2, 99,136,139,  0,  0,  2,  2,  2,  2,136,136,
+  136,136,136,136,136,136,136,136,136,  2,  2,  2,  2,  2, 17, 15,
+   15, 15, 15, 15, 15, 15, 15, 15, 15,  2,  2,  2,  2,  2,  2,  2,
+    2,  2, 17, 17, 17, 17,139,139,139,139,139,139,139,139,139,139,
+  139,139,  2,  2,  2,  2,105,105,105,105,105,105,105,105,105,105,
+  105,  2,  2,  2,  2,  2,105,105,105,105,105,  2,  2,  2,105,  2,
+    2,  2,  2,  2,  2,  2,105,105,  2,  2,105,105,105,105,  0,  0,
+    0,  0,  0,  0,  0,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  1,  1,  1,  1,  1,
+    1,  1,  0,  0,  0,  0,  0,  0,  1,  1,  1,  1,  0,  0,  0,  2,
+    2,  2,  2,  2,  2,  2,  2,  2,  0,  2,  2,  0,  0,  2,  2,  0,
+    0,  0,  0,  2,  0,  0,  0,  0,  2,  0,  2,  0,  0,  0,  0,  0,
+    0,  0,  2,  0,  0,  0,  0,  0,  0,  0,  0,  0,  2,  0,  0,  0,
+    0,  2,  2,  0,  0,  0,  0,  0,  2,  0,  0,  0,  0,  2,  0,  0,
+    0,  0,  0,  2,  0,  2,  2,  2,  0,  0,  0,  0,  0,  0,  0,  2,
+    0,  0,  0,  0,  0,  0,131,131,131,131,131,131,131,131,131,131,
+  131,131,  2,  2,  2,  2,  2,  2,  2,131,131,131,131,131,  2,131,
+  131,131,131,131,131,131, 56,  2,  2, 56, 56, 56, 56, 56, 56, 56,
+    2, 56, 56,  2, 56, 56, 56, 56, 56,  2,  2,  2,  2,  2,151,151,
+  151,151,151,151,151,151,151,151,151,151,151,  2,  2,  2,151,151,
+  151,151,151,151,  2,  2,151,151,  2,  2,  2,  2,151,151,152,152,
+  152,152,152,152,152,152,152,152,  2,  2,  2,  2,  2,152,113,113,
+  113,113,113,113,113,113,113,113,113,113,113,  2,  2,113,113,113,
+  113,113,113,113,113,  2,132,132,132,132,132,132,132,132,132,132,
+  132,132,  2,  2,  2,  2,132,132,  2,  2,  2,  2,132,132,  0,  0,
+    0,  0,  0,  2,  2,  2,  3,  3,  3,  3,  2,  3,  3,  3,  2,  3,
+    3,  2,  3,  2,  2,  3,  2,  3,  3,  3,  3,  3,  3,  3,  3,  3,
+    3,  2,  3,  3,  3,  3,  2,  3,  2,  3,  2,  2,  2,  2,  2,  2,
+    3,  2,  2,  2,  2,  3,  2,  3,  2,  3,  2,  3,  3,  3,  2,  3,
+    2,  3,  2,  3,  2,  3,  2,  3,  3,  3,  3,  2,  3,  2,  3,  3,
+    2,  3,  3,  3,  3,  3,  3,  3,  3,  3,  2,  2,  2,  2,  2,  3,
+    3,  3,  2,  3,  3,  3,  2,  2,  2,  2,  2,  2,  0,  0, 15,  0,
+    0,  2,  2,  2,  2,  2,  0,  0,  0,  2,  2,  2,  0,  0, 13, 13,
+   13, 13, 13, 13, 13,  2, 13, 13, 13, 13, 13,  2,  2,  2, 13,  2,
+    2,  2,  2,  2,  2,  2,  2,  0,  2,  2,  2,  2,  2,  2, 16, 50,
+   84,118, 88, 89, 90, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85,
+   85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 91, 85, 85,
+  220, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85,
+   85, 85, 85, 85, 85, 85, 85, 85, 94, 85, 85, 85, 85, 85, 85, 85,
+   85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85,
+   85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 15,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  2,  3,  4,  5,  6,
+    7,  8,  9, 10, 11, 12,  0,  0, 13, 14, 15, 16, 17, 18, 19, 20,
+   21, 22,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0, 23,  0,  0, 24, 25, 26, 27, 28, 29, 30,  0,  0, 31, 32,
+    0, 33,  0, 34,  0, 35,  0,  0,  0,  0, 36, 37, 38, 39,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+   40,  0,  0,  0,  0,  0,  0,  0,  0,  0, 41, 42,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+   43, 44,  0, 45,  0,  0,  0,  0,  0,  0, 46, 47,  0,  0,  0,  0,
+    0, 48,  0, 49,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0, 50, 51,  0,  0,  0, 52,  0,  0, 53,  0,  0,  0,  0,  0,
+    0,  0, 54,  0,  0,  0,  0,  0,  0,  0, 55,  0,  0,  0,  0,  0,
+    0,  0, 56,  0,  0,  0,  0,  0,  0,  0,  0, 57,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0, 58, 59, 60, 61, 62, 63, 64, 65,  0,  0,  0,  0,  0,  0,
+   66,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 67, 68,
+    0, 69, 70,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 71, 72,
+   73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88,
+   89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99,100,101,102,103,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+  104,  0,  0,  0,  0,  0,  0,105,106,  0,107,  0,  0,  0,108,  0,
+  109,  0,110,  0,111,112,113,  0,114,  0,  0,  0,115,  0,  0,  0,
+  116,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,117,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,118,119,120,121,  0,122,123,124,125,126,  0,127,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,128,129,
+  130,131,132,133,134,135,136,137,138,139,140,141,142,143,144,145,
+  146,147,148,149,150,151,152,153,154,155,156,157,  0,  0,  0,158,
+  159,160,161,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,162,163,  0,  0,  0,  0,  0,  0,  0,
+  164,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,165,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,166,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,167,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,168,169,  0,  0,  0,  0,170,171,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,172,173,
+  174,175,176,177,178,179,180,181,182,183,184,185,186,187,188,189,
+  190,191,192,193,194,195,196,197,198,199,200,201,202,203,204,205,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  2,  3,  4,
+};
+static const uint16_t
+_hb_ucd_u16[8944] =
+{
+     0,   0,   1,   2,   3,   4,   5,   6,   0,   0,   7,   8,   9,  10,  11,  12,
+    13,  13,  13,  14,  15,  13,  13,  16,  17,  18,  19,  20,  21,  22,  13,  23,
+    13,  13,  13,  24,  25,  11,  11,  11,  11,  26,  11,  27,  28,  29,  30,  31,
+    32,  32,  32,  32,  32,  32,  32,  33,  34,  35,  36,  11,  37,  38,  13,  39,
+     9,   9,   9,  11,  11,  11,  13,  13,  40,  13,  13,  13,  41,  13,  13,  13,
+    13,  13,  13,  42,   9,  43,  11,  11,  44,  45,  32,  46,  47,  48,  49,  50,
+    51,  52,  48,  48,  53,  32,  54,  55,  48,  48,  48,  48,  48,  56,  57,  58,
+    59,  60,  48,  32,  61,  48,  48,  48,  48,  48,  62,  63,  64,  48,  65,  66,
+    48,  67,  68,  69,  48,  70,  71,  72,  72,  72,  48,  73,  72,  74,  75,  32,
+    76,  48,  48,  77,  78,  79,  80,  81,  82,  83,  84,  85,  86,  87,  88,  89,
+    90,  83,  84,  91,  92,  93,  94,  95,  96,  97,  84,  98,  99, 100,  88, 101,
+   102,  83,  84, 103, 104, 105,  88, 106, 107, 108, 109, 110, 111, 112,  94, 113,
+   114, 115,  84, 116, 117, 118,  88, 119, 120, 115,  84, 121, 122, 123,  88, 124,
+   125, 115,  48, 126, 127, 128,  88, 129, 130, 131,  48, 132, 133, 134,  94, 135,
+   136,  48,  48, 137, 138, 139,  72,  72, 140,  48, 141, 142, 143, 144,  72,  72,
+   145, 146, 147, 148, 149,  48, 150, 151, 152, 153,  32, 154, 155, 156,  72,  72,
+    48,  48, 157, 158, 159, 160, 161, 162, 163, 164,   9,   9, 165,  11,  11, 166,
+    48,  48,  48,  48,  48,  48,  48,  48,  48,  48,  48,  48, 167, 168,  48,  48,
+   167,  48,  48, 169, 170, 171,  48,  48,  48, 170,  48,  48,  48, 172, 173, 174,
+    48, 175,   9,   9,   9,   9,   9, 176, 177,  48,  48,  48,  48,  48,  48,  48,
+    48,  48,  48,  48,  48,  48, 178,  48, 179, 180,  48,  48,  48,  48, 181, 182,
+   183, 184,  48, 185,  48, 186, 183, 187,  48,  48,  48, 188, 189, 190, 191, 192,
+   193, 191,  48,  48, 194,  48,  48, 195, 196,  48, 197,  48,  48,  48,  48, 198,
+    48, 199, 200, 201, 202,  48, 203, 204,  48,  48, 205,  48, 206, 207, 208, 208,
+    48, 209,  48,  48,  48, 210, 211, 212, 191, 191, 213, 214,  72,  72,  72,  72,
+   215,  48,  48, 216, 217, 159, 218, 219, 220,  48, 221,  64,  48,  48, 222, 223,
+    48,  48, 224, 225, 226,  64,  48, 227, 228,   9,   9, 229, 230, 231, 232, 233,
+    11,  11, 234,  27,  27,  27, 235, 236,  11, 237,  27,  27,  32,  32,  32, 238,
+    13,  13,  13,  13,  13,  13,  13,  13,  13, 239,  13,  13,  13,  13,  13,  13,
+   240, 241, 240, 240, 241, 242, 240, 243, 244, 244, 244, 245, 246, 247, 248, 249,
+   250, 251, 252, 253, 254, 255, 256, 257, 258, 259, 260, 260,  72, 261, 262, 263,
+   264, 265, 266, 267, 268, 269, 270, 270, 271, 272, 273, 208, 274, 275, 208, 276,
+   277, 277, 277, 277, 277, 277, 277, 277, 278, 208, 279, 208, 208, 208, 208, 280,
+   208, 281, 277, 282, 208, 283, 284, 208, 208, 208, 285,  72, 286,  72, 269, 269,
+   269, 287, 208, 208, 208, 208, 288, 269, 208, 208, 208, 208, 208, 208, 208, 208,
+   208, 208, 208, 289, 290, 208, 208, 291, 208, 208, 208, 208, 208, 208, 292, 208,
+   208, 208, 208, 208, 208, 208, 293, 294, 269, 295, 208, 208, 296, 277, 297, 277,
+   298, 299, 277, 277, 277, 300, 277, 301, 208, 208, 208, 277, 302, 208, 208, 303,
+   208, 304, 208, 208, 208, 208, 208, 208,   9,   9, 305,  11,  11, 306, 307, 308,
+    13,  13,  13,  13,  13,  13, 309, 310,  11,  11, 311,  48,  48,  48, 312, 313,
+    48, 314, 315, 315, 315, 315,  32,  32, 316, 317, 318, 319, 320,  72,  72,  72,
+   208, 321, 208, 208, 208, 208, 208, 322, 208, 208, 208, 208, 208, 323,  72, 324,
+   325, 326, 327, 328, 136,  48,  48,  48,  48, 329, 177,  48,  48,  48,  48, 330,
+   331,  48,  48, 136,  48,  48,  48,  48, 199, 332,  48,  71, 208, 208, 322,  48,
+   208, 333, 334, 208, 335, 336, 208, 208, 334, 208, 208, 336, 208, 208, 208, 208,
+    48,  48,  48, 198, 208, 208, 208, 208,  48,  48,  48,  48,  48,  48,  48,  72,
+    48, 337,  48,  48,  48,  48,  48,  48, 150, 208, 208, 208, 285,  48,  48, 227,
+   338,  48, 339,  72,  13,  13, 340, 341,  13, 342,  48,  48,  48,  48, 343, 344,
+    31, 345, 346, 347,  13,  13,  13, 348, 349, 350, 351, 352, 353,  72,  72, 354,
+   355,  48, 356, 357,  48,  48,  48, 358, 359,  48,  48, 360, 361, 191,  32, 362,
+    64,  48, 363,  48, 364, 365,  48, 150,  76,  48,  48, 366, 367, 368, 369, 370,
+    48,  48, 371, 372, 373, 374,  48, 375,  48,  48,  48, 376, 377, 378, 379, 380,
+   381, 382, 315,  11,  11, 383, 384,  11,  11,  11,  11,  11,  48,  48, 385, 191,
+    48,  48, 386,  48, 387,  48,  48, 205, 388, 388, 388, 388, 388, 388, 388, 388,
+   389, 389, 389, 389, 389, 389, 389, 389,  48,  48,  48,  48,  48,  48, 203,  48,
+    48,  48,  48,  48,  48, 206,  72,  72, 390, 391, 392, 393, 394,  48,  48,  48,
+    48,  48,  48, 395, 396, 397,  48,  48,  48,  48,  48, 398,  72,  48,  48,  48,
+    48, 399,  48,  48, 400,  72,  72, 401,  32, 402,  32, 403, 404, 405, 406, 407,
+    48,  48,  48,  48,  48,  48,  48, 408, 409,   2,   3,   4,   5, 410, 411, 412,
+    48, 413,  48, 199, 414, 415, 416, 417, 418,  48, 171, 419, 203, 203,  72,  72,
+    48,  48,  48,  48,  48,  48,  48,  71, 420, 269, 269, 421, 270, 270, 270, 422,
+   423, 324, 424,  72,  72, 208, 208, 425,  72,  72,  72,  72,  72,  72,  72,  72,
+    48, 150,  48,  48,  48, 100, 426, 427,  48,  48, 428,  48, 429,  48,  48, 430,
+    48, 431,  48,  48, 432, 433,  72,  72,   9,   9, 434,  11,  11,  48,  48,  48,
+    48, 203, 191,   9,   9, 435,  11, 436,  48,  48, 400,  48,  48,  48, 437,  72,
+    48,  48,  48, 314,  48, 198, 400,  72, 438,  48,  48, 439,  48, 440,  48, 441,
+    48, 199, 442,  72,  72,  72,  48, 443,  48, 444,  48, 445,  72,  72,  72,  72,
+    48,  48,  48, 446, 269, 447, 269, 269, 448, 449,  48, 450, 451, 452,  48, 453,
+    48, 454,  72,  72, 455,  48, 456, 457,  48,  48,  48, 458,  48, 459,  48, 460,
+    48, 461, 462,  72,  72,  72,  72,  72,  48,  48,  48,  48, 195,  72,  72,  72,
+     9,   9,   9, 463,  11,  11,  11, 464,  48,  48, 465, 191,  72,  72,  72,  72,
+    72,  72,  72,  72,  72,  72, 269, 466,  48, 454, 467,  48,  62, 468,  72,  72,
+    72,  72,  72,  72,  72,  72,  48, 314, 469,  48,  48, 470, 471, 447, 472, 473,
+   220,  48,  48, 474, 475,  48, 195, 191, 476,  48, 477, 478, 479,  48,  48, 480,
+   220,  48,  48, 481, 482, 483, 484, 485,  48,  97, 486, 487,  72,  72,  72,  72,
+   488, 489, 490,  48,  48, 491, 492, 191, 493,  83,  84, 494, 495, 496, 497, 498,
+    48,  48,  48, 499, 500, 501,  72,  72,  48,  48,  48, 502, 503, 191,  72,  72,
+    48,  48, 504, 505, 506, 507,  72,  72,  48,  48,  48, 508, 509, 191, 510,  72,
+    48,  48, 511, 512, 191,  72,  72,  72,  48, 172, 513, 514,  72,  72,  72,  72,
+    48,  48, 486, 515,  72,  72,  72,  72,  72,  72,   9,   9,  11,  11, 147, 516,
+    72,  72, 517,  48,  48, 518, 519,  72, 520,  48,  48, 521, 522, 523,  48,  48,
+   524, 525, 526,  72,  48,  48,  48, 195,  84,  48, 504, 527, 528, 147, 174, 529,
+    48, 530, 531, 532,  72,  72,  72,  72, 533,  48,  48, 534, 535, 191, 536,  48,
+   537, 538, 191,  72,  72,  72,  72,  72,  72,  72,  72,  72,  72,  72,  48, 539,
+    72,  72,  72,  72, 269, 540, 541, 542,  48, 206,  72,  72,  72,  72,  72,  72,
+   270, 270, 270, 270, 270, 270, 543, 544,  48,  48,  48,  48, 386,  72,  72,  72,
+    48,  48, 199, 545,  72,  72,  72,  72,  48,  48,  48,  48, 314,  72,  72,  72,
+    48,  48,  48, 195,  48, 199, 368,  72,  72,  72,  72,  72,  72,  48, 203, 546,
+    48,  48,  48, 547, 548, 549, 550, 551,  48,  72,  72,  72,  72,  72,  72,  72,
+    72,  72,  72,  72,   9,   9,  11,  11, 269, 552,  72,  72,  72,  72,  72,  72,
+    48,  48,  48,  48, 553, 554, 555, 555, 556, 557,  72,  72,  72,  72, 558,  72,
+    48,  48,  48,  48,  48,  48,  48, 400,  48,  48,  48,  48,  48,  48,  48, 559,
+    48, 199,  72,  72,  72, 559, 560,  48,  48,  48,  48,  48,  48,  48,  48, 205,
+    48,  48,  48,  48,  48,  48,  71, 150, 195, 561, 562,  72,  72,  72,  72,  72,
+   208, 208, 208, 208, 208, 208, 208, 323, 208, 208, 563, 208, 208, 208, 564, 565,
+   566, 208, 567, 208, 208, 208, 568,  72, 208, 208, 208, 208, 569,  72,  72,  72,
+    72,  72,  72,  72,  72,  72, 269, 570, 208, 208, 208, 208, 208, 285, 269, 451,
+     9, 571,  11, 572, 573, 574, 240,   9, 575, 576, 577, 578, 579,   9, 571,  11,
+   580, 581,  11, 582, 583, 584, 585,   9, 586,  11,   9, 571,  11, 572, 573,  11,
+   240,   9, 575, 585,   9, 586,  11,   9, 571,  11, 587,   9, 588, 589, 590, 591,
+    11, 592,   9, 593, 594, 595, 596,  11, 597,   9, 598,  11, 599, 600, 600, 600,
+    32,  32,  32, 601,  32,  32, 602, 603, 604, 605,  45,  72,  72,  72,  72,  72,
+   606, 607, 608,  72,  72,  72,  72,  72,  48,  48, 150, 609, 610,  72,  72,  72,
+    72,  72,  72,  72,  48,  48, 611, 612,  48,  48,  48,  48, 613, 614,  72,  72,
+     9,   9, 575,  11, 615, 368,  72,  72,  72,  72,  72,  72,  72,  72,  72, 484,
+   269, 269, 616, 617,  72,  72,  72,  72, 484, 269, 618, 619,  72,  72,  72,  72,
+   620,  48, 621, 622, 623, 624, 625, 626, 627, 205, 628, 205,  72,  72,  72, 629,
+   208, 208, 324, 208, 208, 208, 208, 208, 208, 322, 333, 630, 630, 630, 208, 323,
+   174, 208, 208, 208, 208, 208, 631, 208, 208, 208, 631,  72,  72,  72, 632, 208,
+   633, 208, 208, 324, 568, 634, 323,  72, 208, 208, 208, 208, 208, 208, 208, 635,
+   208, 208, 208, 208, 208, 323, 631, 286, 208, 208, 208, 208, 208, 208, 208, 322,
+   208, 208, 208, 208, 208, 568, 324,  72, 324, 208, 208, 208, 636, 175, 208, 208,
+   636, 208, 637,  72,  72,  72,  72,  72, 638, 208, 208, 208, 208, 208, 208, 639,
+   208, 208, 640, 208, 641, 208, 208, 208, 208, 208, 208, 208, 208, 322, 637, 642,
+   633, 323,  72,  72,  72,  72,  72,  72,  48,  48,  48,  48,  48, 314,  72,  72,
+    48,  48,  48, 204,  48,  48,  48,  48,  48, 203,  48,  48,  48,  48,  48,  48,
+    48,  48, 643,  48,  48,  48,  48,  48,  48,  48,  48,  48,  48,  48, 100,  72,
+    48, 203,  72,  72,  72,  72,  72,  72, 644,  72, 645, 645, 645, 645, 645, 645,
+    32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  72,
+   389, 389, 389, 389, 389, 389, 389, 646, 389, 389, 389, 389, 389, 389, 389, 647,
+     0,   0,   0,   0,   0,   0,   0,   0,   1,   2,   2,   3,   1,   2,   2,   3,
+     0,   0,   0,   0,   0,   4,   0,   4,   2,   2,   5,   2,   2,   2,   5,   2,
+     2,   2,   2,   2,   2,   2,   2,   2,   2,   2,   2,   2,   2,   2,   2,   2,
+     2,   2,   2,   2,   2,   2,   2,   6,   0,   0,   0,   0,   7,   8,   0,   0,
+     9,   9,   9,   9,   9,   9,   9,   9,   9,   9,   9,   9,   9,   9,  10,  11,
+    12,  13,  14,  14,  15,  14,  14,  14,  14,  14,  14,  14,  16,  17,  14,  14,
+    18,  18,  18,  18,  18,  18,  18,  18,  18,  18,  18,  18,  18,  18,  18,  18,
+    19,  18,  18,  18,  18,  18,  18,  18,  18,  18,  18,  18,  18,  18,  18,  18,
+    18,  18,  18,  18,  18,  18,  20,  21,  21,  21,  22,  20,  21,  21,  21,  21,
+    21,  23,  24,  25,  25,  25,  25,  25,  25,  26,  25,  25,  25,  27,  28,  26,
+    29,  30,  31,  32,  31,  31,  31,  31,  33,  34,  35,  31,  31,  31,  36,  31,
+    31,  31,  31,  31,  31,  31,  31,  31,  31,  31,  31,  29,  31,  31,  31,  31,
+    37,  38,  37,  37,  37,  37,  37,  37,  37,  39,  31,  31,  31,  31,  31,  31,
+    40,  40,  40,  40,  40,  40,  41,  26,  42,  42,  42,  42,  42,  42,  42,  43,
+    44,  44,  44,  44,  44,  45,  44,  46,  47,  47,  47,  48,  37,  49,  26,  26,
+    26,  26,  26,  26,  31,  31,  50,  51,  26,  26,  52,  31,  53,  31,  31,  31,
+    54,  54,  54,  54,  54,  54,  54,  54,  54,  54,  55,  54,  56,  54,  54,  54,
+    57,  58,  59,  60,  60,  61,  62,  63,  58,  64,  65,  66,  67,  60,  60,  68,
+    69,  70,  71,  72,  72,  73,  74,  75,  70,  76,  77,  78,  79,  72,  80,  26,
+    81,  82,  83,  84,  84,  85,  86,  87,  82,  88,  89,  26,  90,  84,  91,  92,
+    93,  94,  95,  96,  96,  97,  98,  99,  94, 100, 101, 102, 103,  96,  96,  26,
+   104, 105, 106, 107, 108, 105, 109, 110, 105, 106, 111,  26, 112, 109, 109, 113,
+   114, 115, 116, 114, 114, 116, 114, 117, 115, 118, 119, 120, 121, 114, 122, 114,
+   123, 124, 125, 123, 123, 125, 126, 127, 124, 128, 129, 130, 131, 123, 132,  26,
+   133, 134, 135, 136, 136, 136, 136, 136, 134, 135, 137, 136, 138, 136, 136, 136,
+   139, 140, 141, 142, 140, 140, 143, 144, 141, 145, 146, 140, 147, 140, 148,  26,
+   149, 150, 150, 150, 150, 150, 150, 151, 150, 150, 150, 152,  26,  26,  26,  26,
+   153, 154, 155, 155, 156, 155, 155, 157, 158, 157, 155, 159,  26,  26,  26,  26,
+   160, 160, 160, 160, 160, 160, 160, 160, 160, 161, 160, 160, 160, 162, 161, 160,
+   160, 160, 160, 161, 160, 160, 160, 163, 160, 163, 164, 165,  26,  26,  26,  26,
+   166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166,
+   166, 166, 166, 166, 167, 167, 167, 167, 168, 169, 167, 167, 167, 167, 167, 170,
+   171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171,
+   172, 172, 172, 172, 172, 172, 172, 172, 172, 173, 174, 173, 172, 172, 172, 172,
+   172, 173, 172, 172, 172, 172, 173, 174, 173, 172, 174, 172, 172, 172, 172, 172,
+   172, 172, 173, 172, 172, 172, 172, 172, 172, 172, 172, 175, 172, 172, 172, 176,
+   172, 172, 172, 177, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 179, 179,
+   180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180,
+   181, 181, 181, 182, 183, 183, 183, 183, 183, 183, 183, 183, 183, 184, 183, 185,
+   186, 187, 188,  26, 189, 189, 190,  26, 191, 191, 192,  26, 193, 194, 195,  26,
+   196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 197, 196, 198, 196, 198,
+   199, 200, 201, 202, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 203,
+   201, 201, 201, 201, 201, 204, 180, 180, 180, 180, 180, 180, 180, 180, 205,  26,
+   206, 206, 206, 207, 206, 208, 206, 208, 209, 206, 210, 210, 210, 211, 212,  26,
+   213, 213, 213, 213, 213, 214, 213, 213, 213, 215, 213, 216, 196, 196, 196, 196,
+   217, 217, 217, 218, 219, 219, 219, 219, 219, 219, 219, 220, 219, 219, 219, 221,
+   219, 222, 219, 222, 219, 223,   9, 224,  26,  26,  26,  26,  26,  26,  26,  26,
+   225, 225, 225, 225, 225, 225, 225, 225, 225, 226, 225, 225, 225, 225, 225, 227,
+   228, 228, 228, 228, 228, 228, 228, 228, 229, 229, 229, 229, 229, 229, 230, 231,
+   232, 232, 232, 232, 232, 232, 232, 233, 232, 234, 235, 235, 235, 235, 235, 235,
+    18, 236, 167, 167, 167, 167, 167, 237, 228,  26, 238,   9, 239, 240, 241, 242,
+     2,   2,   2,   2, 243, 244,   2,   2,   2,   2,   2, 245, 246, 247,   2, 248,
+     2,   2,   2,   2,   2,   2,   2, 249,   9,   9,   9,   9,   9,   9,   9, 250,
+    14,  14, 251, 251,  14,  14,  14,  14, 251, 251,  14, 252,  14,  14,  14, 251,
+    14,  14,  14,  14,  14,  14, 253,  14, 253,  14, 254, 255,  14,  14, 256, 257,
+     0, 258,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0, 259,   0, 260, 261,
+     0, 262,   2, 263,   0,   0,   0,   0,  26,  26,   9,   9,   9,   9, 264,  26,
+     0,   0,   0,   0, 265, 266,   4,   0,   0, 267,   0,   0,   2,   2,   2,   2,
+     2, 268,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+     0,   0,   0,   0, 262,  26,  26,  26,   0, 269,  26,  26,   0,   0,   0,   0,
+   270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270,
+     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0, 271,   0,
+     0,   0, 272,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+   273, 273, 273, 273, 273, 274, 273, 273, 273, 273, 273, 274,   2,   2,   2,   2,
+    17,  17,  17,  17,  17,  17,  17,  17,  17,  17,  17,  17,  17,  17, 275, 276,
+   167, 167, 167, 167, 168, 169, 277, 277, 277, 277, 277, 277, 277, 278, 279, 278,
+   172, 172, 174,  26, 174, 174, 174, 174, 174, 174, 174, 174,  18,  18,  18,  18,
+     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,  26,  26,  26,  26,  26,  26,
+   280, 280, 280, 281, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 282,  26,
+   280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280,
+   280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 283,  26,  26,  26,   0, 284,
+   285,   0,   0,   0, 286, 287,   0, 288, 289, 290, 290, 290, 290, 290, 290, 290,
+   290, 290, 291, 292, 293, 294, 294, 294, 294, 294, 294, 294, 294, 294, 294, 295,
+   296, 297, 297, 297, 297, 297, 298, 171, 171, 171, 171, 171, 171, 171, 171, 171,
+   171, 299,   0,   0, 297, 297, 297, 300,   0,   0,   0,   0, 284,  26, 294, 294,
+   171, 171, 171, 299,   0,   0,   0,   0,   0,   0,   0,   0, 171, 171, 171, 301,
+     0,   0,   0,   0,   0,   0,   0,   0,   0,   0, 294, 294, 294, 294, 294, 302,
+   294, 294, 294, 294, 294, 294, 294, 294, 294, 294, 294,   0,   0,   0,   0,   0,
+   280, 280, 280, 280, 280, 280, 283,  26,   0,   0,   0,   0,   0,   0,   0,   0,
+   280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280,  26,  26,
+   303, 303, 303, 303, 303, 303, 303, 303, 303, 303, 303, 303, 303, 303, 303, 303,
+   303, 304, 303, 303, 303, 303, 303, 303, 305,  26, 306, 306, 306, 306, 306, 306,
+   307, 307, 307, 307, 307, 307, 307, 307, 307, 307, 307, 307, 307, 307, 307, 307,
+   307, 307, 307, 307, 307, 308,  26,  26,  18,  18,  18,  18,  18,  18,  18,  18,
+    18,  18,  18,  18, 309, 309, 309, 309, 309, 309, 309, 309, 309, 309, 309,  26,
+     0,   0,   0,   0, 310,   2,   2,   2,   2,   2,   2,   2,   2,   2,   2,   2,
+     2, 311,   2,   2,   2,   2,   2,   2, 312,  26,  26,  26,  26,  26, 313,   2,
+   314, 314, 314, 314, 314, 315,   0, 316, 317, 317, 317, 317, 317, 317, 317,  26,
+   318, 318, 318, 318, 318, 318, 318, 318, 319, 320, 318, 321,  54,  54,  54,  54,
+   322, 322, 322, 322, 322, 323, 324, 324, 324, 324, 325, 326, 171, 171, 171, 327,
+   328, 328, 328, 328, 328, 328, 328, 328, 328, 329, 328, 330, 166, 166, 166, 331,
+   332, 332, 332, 332, 332, 332, 333,  26, 332, 334, 332, 335, 166, 166, 166, 166,
+   336, 336, 336, 336, 336, 336, 336, 336, 337,  26,  26, 338, 339, 339, 340,  26,
+   341, 341, 341,  26, 174, 174,   2,   2,   2,   2,   2, 342, 343,  26, 178, 178,
+   178, 178, 178, 178, 178, 178, 178, 178, 339, 339, 339, 339, 339, 344, 339, 345,
+   171, 171, 171, 171, 346,  26, 171, 171, 299, 347, 171, 171, 171, 171, 171, 346,
+    26,  26,  26,  26,  26,  26,  26,  26,  26,  26,  26,  26,  26,  26,  26,  26,
+   280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 283, 280, 280,
+   280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 348,  26,  26,  26,  26,
+   349,  26, 350, 351,  25,  25, 352, 353, 354,  25,  31,  31,  31,  31,  31,  31,
+    31,  31,  31,  31,  31,  31,  31,  31, 355,  26,  52,  31,  31,  31,  31,  31,
+    31,  31,  31,  31,  31,  31,  31,  31,  31,  31,  31,  31,  31,  31,  31,  31,
+    31,  31,  31,  31,  31,  31,  31, 356,  26,  26,  31,  31,  31,  31,  31,  31,
+    31,  31, 357,  31,  31,  31,  31,  31,  31,  26,  26,  26,  26,  26,  31,  51,
+     9,   9,   0, 316,   9, 358,   0,   0,   0,   0, 359,   0, 262, 284,  50,  31,
+    31,  31,  31,  31,  31,  31,  31,  31,  31,  31,  31,  31,  31,  31,  31, 360,
+   361,   0,   0,   0,   1,   2,   2,   3,   1,   2,   2,   3, 362, 294, 293, 294,
+   294, 294, 294, 363, 171, 171, 171, 299, 364, 364, 364, 365, 262, 262,  26, 366,
+   367, 368, 367, 367, 369, 367, 367, 370, 367, 371, 367, 371,  26,  26,  26,  26,
+   367, 367, 367, 367, 367, 367, 367, 367, 367, 367, 367, 367, 367, 367, 367, 372,
+   373,   0,   0,   0,   0,   0, 374,   0,  14,  14,  14,  14,  14,  14,  14,  14,
+    14, 257,   0, 284, 375,  26,  26,  26,  26,  26,   0,   0,   0,   0,   0, 376,
+   377, 377, 377, 378, 379, 379, 379, 379, 379, 379, 380,  26, 381,   0,   0, 284,
+   382, 382, 382, 382, 383, 384, 385, 385, 385, 386, 387, 387, 387, 387, 387, 388,
+   389, 389, 389, 390, 391, 391, 391, 391, 392, 391, 393,  26,  26,  26,  26,  26,
+   394, 394, 394, 394, 394, 394, 394, 394, 394, 394, 395, 395, 395, 395, 395, 395,
+   396, 396, 396, 397, 396, 398, 399, 399, 399, 399, 400, 399, 399, 399, 399, 400,
+   401, 401, 401, 401, 401,  26, 402, 402, 402, 402, 402, 402, 403, 404,  26,  26,
+   405, 405, 405, 405, 405, 405, 405, 405, 405, 405, 405, 405, 405, 405, 405, 405,
+   405, 405, 405, 405, 405, 405, 406,  26, 405, 405, 407,  26, 405,  26,  26,  26,
+   408, 409, 410, 410, 410, 410, 411, 412, 413, 413, 414, 413, 415, 415, 415, 415,
+   416, 416, 416, 417, 418, 416,  26,  26,  26,  26,  26,  26, 419, 419, 420, 421,
+   422, 422, 422, 423, 424, 424, 424, 425,  26,  26,  26,  26,  26,  26,  26,  26,
+   426, 426, 426, 426, 427, 427, 427, 428, 427, 427, 429, 427, 427, 427, 427, 427,
+   430, 431, 432, 433, 434, 434, 435, 436, 434, 437, 434, 437, 438, 438, 438, 438,
+   439, 439, 439, 439,  26,  26,  26,  26, 440, 440, 440, 440, 441, 442, 441,  26,
+   443, 443, 443, 443, 443, 443, 444, 445, 446, 446, 447, 446, 448, 448, 449, 448,
+   450, 450, 451, 452,  26, 453,  26,  26,  26,  26,  26,  26,  26,  26,  26,  26,
+   454, 454, 454, 454, 454, 454, 454, 454, 454, 455,  26,  26,  26,  26,  26,  26,
+   456, 456, 456, 456, 456, 456, 457,  26, 456, 456, 456, 456, 456, 456, 457, 458,
+   459, 459, 459, 459, 459,  26, 459, 460,  26,  26,  26,  26,  26,  26,  26,  26,
+    26,  26,  26,  26,  26,  26,  26,  26,  26,  26,  26,  26,  31,  31,  31, 461,
+   462, 462, 462, 462, 462,  26, 463, 463, 463, 463, 463, 464,  26,  26,  26,  26,
+    26,  26,  26,  26,  26,  26,  26,  26,  26,  26,  26,  26, 465, 465, 466,  26,
+   467, 467, 467, 467, 467, 467, 467, 467, 467, 468, 469, 467, 467, 467,  26, 470,
+   471, 471, 471, 471, 471, 471, 471, 471, 472, 473, 474, 474, 474, 475, 474, 476,
+   477, 477, 477, 477, 477, 477, 478, 477, 479,  26, 480, 480, 480, 480, 481,  26,
+   482, 482, 482, 482, 482, 482, 482, 482, 482, 483, 482, 482, 484, 140, 485,  26,
+   486, 486, 487, 486, 486, 486, 486, 488,  26,  26,  26,  26,  26,  26,  26,  26,
+   489, 490, 491, 492, 491, 493, 494, 494, 494, 494, 494, 494, 494, 495, 494, 496,
+   497, 498, 499, 500, 500, 501, 502, 503, 498, 504, 505, 506, 507, 508, 508,  26,
+   509, 509, 509, 509, 509, 509, 509, 509, 509, 509, 509, 510,  26,  26,  26,  26,
+   511, 511, 511, 511, 511, 511, 511, 511, 511,  26, 511, 512,  26,  26,  26,  26,
+   513, 513, 513, 513, 513, 513, 514, 513, 513, 513, 513, 514,  26,  26,  26,  26,
+   515, 515, 515, 515, 515, 515, 515, 515, 516,  26, 515, 517, 201, 518,  26,  26,
+   519, 519, 519, 519, 519, 519, 519, 520, 519, 521,  26,  26,  26,  26,  26,  26,
+   522, 522, 522, 523, 522, 524, 522, 522,  26,  26,  26,  26,  26,  26,  26,  26,
+   525, 525, 525, 525, 525, 525, 525, 526,  26,  26,  26,  26,  26,  26,  26,  26,
+    26,  26,  26,  26, 527, 527, 527, 527, 527, 527, 527, 527, 527, 527, 528, 529,
+    26,  26,  26,  26, 530, 531, 530, 530, 530, 530, 530, 531, 532,  26,  26,  26,
+   533, 533, 533, 533, 533, 533, 533, 533, 533,  26, 534, 534, 534, 534, 534, 534,
+   534, 534, 534, 534, 535,  26,  26,  26, 536, 536, 536, 536, 536, 536, 536, 537,
+   538, 539, 538, 538, 538, 538, 540, 538, 541,  26, 538, 538, 538, 542, 543, 543,
+   543, 543, 544, 543, 543, 545, 546,  26,  26,  26,  26,  26,  26,  26,  26,  26,
+   547, 548, 549, 549, 549, 549, 547, 550, 549,  26, 549, 551, 552, 553, 554, 554,
+   554, 555, 556, 557, 554, 558,  26,  26,  26,  26,  26,  26,  26,  26,  26,  26,
+    26,  26,  26,  26,  26,  26,  26,  26,  26,  26,  26,  26, 559, 559, 559, 560,
+    26,  26,  26,  26,  26,  26,  26,  26, 109, 109, 109, 109, 109, 109, 561, 562,
+   563, 563, 563, 563, 563, 563, 563, 563, 563, 563, 563, 563, 563, 563, 563, 563,
+   563, 563, 563, 564,  26,  26,  26,  26,  26,  26,  26,  26,  26,  26,  26,  26,
+   563, 563, 563, 563, 563, 563, 563, 563, 563, 563, 563, 563, 563, 565, 566,  26,
+   563, 563, 563, 563, 563, 563, 563, 563, 567,  26,  26,  26,  26,  26,  26,  26,
+   568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, 568,
+   568, 568, 568, 568, 568, 569, 568, 570,  26,  26,  26,  26,  26,  26,  26,  26,
+   571, 571, 571, 571, 571, 571, 571, 571, 571, 571, 571, 571, 571, 571, 571, 571,
+   571, 571, 571, 571, 571, 571, 571, 571, 572,  26,  26,  26,  26,  26,  26,  26,
+   309, 309, 309, 309, 309, 309, 309, 309, 309, 309, 309, 309, 309, 309, 309, 309,
+   309, 309, 309, 309, 309, 309, 309, 573, 574, 574, 574, 575, 574, 576,  26,  26,
+    26,  26,  26,  26,  26,  26,  26,  26,  26,  26, 577, 577, 577, 578, 578,  26,
+   579, 579, 579, 579, 579, 579, 579, 579, 580,  26, 579, 581, 581, 579, 579, 582,
+   579, 579,  26,  26,  26,  26,  26,  26,  26,  26,  26,  26,  26,  26,  26,  26,
+    26,  26,  26,  26,  26,  26,  26,  26, 583, 583, 583, 583, 583, 583, 583, 583,
+   583, 583, 583, 584,  26,  26,  26,  26,  26,  26,  26,  26,  26,  26,  26,  26,
+   585, 585, 585, 585, 585, 585, 585, 585, 585, 586, 585, 585, 585, 585, 585, 585,
+   585, 587, 585, 585,  26,  26,  26,  26,  26,  26,  26,  26, 588,  26,  26,  26,
+   589, 589, 589, 589, 589, 589, 589, 589, 589, 589, 589, 589, 589, 589, 589, 589,
+   589, 589, 589, 589, 589, 589, 589, 589, 589, 589, 589, 589, 589, 589, 589,  26,
+   589, 589, 589, 589, 589, 589, 589, 589, 589, 589, 589, 589, 589, 589, 590,  26,
+   591, 290, 290, 290, 290, 290, 290, 290, 290, 290, 290, 290, 290, 290, 290, 290,
+   290, 290, 290, 290, 290, 290, 290, 290, 290, 290, 290, 290, 290, 290, 290, 290,
+   290, 290, 290, 291,  26,  26,  26,  26,  26,  26, 592,  26, 593,  26, 594, 594,
+   594, 594, 594, 594, 594, 594, 594, 594, 594, 594, 594, 594, 594, 594, 594, 594,
+   594, 594, 594, 594, 594, 594, 594, 594, 594, 594, 594, 594, 594, 594, 594, 595,
+   596, 596, 596, 596, 596, 596, 596, 596, 596, 596, 596, 596, 596, 597, 596, 598,
+   596, 599, 596, 600, 284,  26,  26,  26,  26,  26,  26,  26,  26,  26,  26,  26,
+     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0, 272,  26,
+     0,   0,   0,   0, 262, 361,   0,   0,   0,   0,   0,   0, 601, 602,   0, 603,
+   604, 605,   0,   0,   0, 606,   0,   0,   0,   0,   0,   0,   0, 607,  26,  26,
+    14,  14,  14,  14,  14,  14,  14,  14, 251,  26,  26,  26,  26,  26,  26,  26,
+    26,  26,  26,  26,  26,  26,  26,  26,  26,  26,  26,  26,   0,   0, 284,  26,
+     0,   0,   0,   0,   0,   0,   0,   0,   0,   0, 262,  26,   0,   0,   0, 607,
+     0,   0,   0,   0,   0,   0,   0,   0,   0,   0, 259,   0,   0,   0,   0,   0,
+     0,   0,   0, 259, 608, 609,   0, 610, 611,   0,   0,   0,   0,   0,   0,   0,
+   612, 613, 259, 259,   0,   0,   0, 614, 615, 616, 617,   0,   0,   0,   0,   0,
+     0,   0,   0,   0, 272,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+     0,   0,   0,   0,   0,   0,   0,   0,   0, 271,   0,   0,   0,   0,   0,   0,
+   618, 618, 618, 618, 618, 618, 618, 618, 618, 618, 618, 618, 618, 618, 618, 618,
+   618, 619,  26, 620, 621, 618,  26,  26,  26,  26,  26,  26,  26,  26,  26,  26,
+   274, 273, 273, 622, 623, 624,  26,  26,  26,  26,  26,  26,  26,  26,  26,  26,
+   625, 625, 625, 625, 625, 626, 625, 627, 625, 628,  26,  26,  26,  26,  26,  26,
+    26,  26,  26,  26,  26,  26,  26,  26, 629, 629, 629, 629, 629, 629, 629, 630,
+   631, 631, 631, 631, 631, 631, 631, 631, 631, 631, 631, 631, 631, 631, 631, 631,
+   631, 631, 631, 631, 631, 631, 631, 631, 632, 631, 633,  26,  26,  26,  26,  26,
+   634, 634, 634, 634, 634, 634, 634, 634, 634, 635, 634, 636,  26,  26,  26,  26,
+    26,  26,  26,  26,  26,  26,  26,  26,  26,  26,  26,  26,  26,  26, 361,   0,
+     0,   0,   0,   0,   0,   0, 637,  26,  26,  26,  26,  26,  26,  26,  26,  26,
+   361,   0,   0,   0,   0,   0,   0, 272,  26,  26,  26,  26,  26,  26,  26,  26,
+   638,  31,  31,  31, 639, 640, 641, 642, 643, 644, 639, 645, 639, 641, 641, 646,
+    31, 647,  31, 648, 649, 647,  31, 648,  26,  26,  26,  26,  26,  26, 355,  26,
+     0,   0,   0,   0,   0, 284,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+     0,   0, 284,  26,   0, 262, 361,   0, 361,   0, 361,   0,   0,   0, 272,  26,
+     0, 637,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0, 637,   0,   0,
+     0,   0,   0,   0,   0, 637,  26,  26,  26,  26,  26,  26, 650,   0,   0,   0,
+   651,  26,   0,   0,   0,   0,   0, 284,   0, 607, 316,  26, 272,  26,  26,  26,
+     0,   0,   0,   0,   0,   0,   0,   0,   0,   0, 272,  26,   0, 637,   0, 269,
+     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0, 284,  26,
+     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0, 607,   0, 284,  26,  26,
+     0, 284,   0,   0,   0,   0,   0,   0,   0,  26,   0, 316,   0,   0,   0,   0,
+     0,  26,   0,   0,   0, 272,  26,  26,  26,  26,  26,  26,  26,  26,  26,  26,
+     0, 611,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0, 614, 616,
+     0,   0,   0,   0, 613, 652,   0,   0,   0, 613,   0,   0,   0,   0,   0,   0,
+     0,   0,   0,   0,   0,   0,   0,   0,   0,   0, 284,  26,   0, 272, 284, 269,
+   269,  26, 272,  26,  26,  26,  26,  26,  26,  26,  26,  26,  26,  26,  26,  26,
+   280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 653,  26,  26,  26,  26,  26,
+   280, 280, 280, 280, 280, 280, 654,  26, 280, 280, 280, 280, 280, 280, 280, 280,
+   280, 280, 280, 283, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280,
+   280, 280, 280, 280, 348,  26, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280,
+   280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 655,  26,  26,  26,
+   280, 280, 280, 283,  26,  26,  26,  26,  26,  26,  26,  26,  26,  26,  26,  26,
+   656,  26,  26,  26,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+     9,   9,   9,   9,   9,   9,   9,   9,   9,   9,   9,   9,   9,   9,   9,   9,
+     9,   9,   9,   9,   9,   9,   9,   9,   9,   9,   9,   9,   9,   9,   0,   0,
+     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+   939, 940, 941, 942, 946, 948,   0, 962, 969, 970, 971, 976,1001,1002,1003,1008,
+     0,1033,1040,1041,1042,1043,1047,   0,   0,1080,1081,1082,1086,1110,   0,   0,
+  1124,1125,1126,1127,1131,1133,   0,1147,1154,1155,1156,1161,1187,1188,1189,1193,
+     0,1219,1226,1227,1228,1229,1233,   0,   0,1267,1268,1269,1273,1298,   0,1303,
+   943,1128, 944,1129, 954,1139, 958,1143, 959,1144, 960,1145, 961,1146, 964,1149,
+     0,   0, 973,1158, 974,1159, 975,1160, 983,1168, 978,1163, 988,1173, 990,1175,
+   991,1176, 993,1178, 994,1179,   0,   0,1004,1190,1005,1191,1006,1192,1014,1199,
+  1007,   0,   0,   0,1016,1201,1020,1206,   0,1022,1208,1025,1211,1023,1209,   0,
+     0,   0,   0,1032,1218,1037,1223,1035,1221,   0,   0,   0,1044,1230,1045,1231,
+  1049,1235,   0,   0,1058,1244,1064,1250,1060,1246,1066,1252,1067,1253,1072,1258,
+  1069,1255,1077,1264,1074,1261,   0,   0,1083,1270,1084,1271,1085,1272,1088,1275,
+  1089,1276,1096,1283,1103,1290,1111,1299,1115,1118,1307,1120,1309,1121,1310,   0,
+  1053,1239,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,1093,
+  1280,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0, 949,1134,1010,
+  1195,1050,1236,1090,1277,1341,1368,1340,1367,1342,1369,1339,1366,   0,1320,1347,
+  1418,1419,1323,1350,   0,   0, 992,1177,1018,1204,1055,1241,1416,1417,1415,1424,
+  1202,   0,   0,   0, 987,1172,   0,   0,1031,1217,1321,1348,1322,1349,1338,1365,
+   950,1135, 951,1136, 979,1164, 980,1165,1011,1196,1012,1197,1051,1237,1052,1238,
+  1061,1247,1062,1248,1091,1278,1092,1279,1071,1257,1076,1263,   0,   0, 997,1182,
+     0,   0,   0,   0,   0,   0, 945,1130, 982,1167,1337,1364,1335,1362,1046,1232,
+  1422,1423,1113,1301,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+     8,   9,   0,  10,1425,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+     0,   0,   0,   0,   7,   0,   0,   0,   0,   0,   0,   0,   0,   0,   1,   0,
+     0,   0,   0,   0,   0,1314,1427,   5,1434,1438,1443,   0,1450,   0,1455,1461,
+  1514,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,1446,1458,1468,1476,1480,1486,
+  1517,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,1489,1503,1494,1500,1508,   0,
+     0,   0,   0,1520,1521,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+  1526,1528,   0,1525,   0,   0,   0,1522,   0,   0,   0,   0,1536,1532,1539,   0,
+     0,   0,   0,   0,   0,   0,   0,   0,   0,1534,   0,   0,   0,   0,   0,   0,
+     0,   0,   0,   0,   0,   0,   0,   0,   0,1556,   0,   0,   0,   0,   0,   0,
+  1548,1550,   0,1547,   0,   0,   0,1567,   0,   0,   0,   0,1558,1554,1561,   0,
+     0,   0,   0,   0,   0,   0,1568,1569,   0,   0,   0,   0,   0,   0,   0,   0,
+     0,1529,1551,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+  1523,1545,1524,1546,   0,   0,1527,1549,   0,   0,1570,1571,1530,1552,1531,1553,
+     0,   0,1533,1555,1535,1557,1537,1559,   0,   0,1572,1573,1544,1566,1538,1560,
+  1540,1562,1541,1563,1542,1564,   0,   0,1543,1565,   0,   0,   0,   0,   0,   0,
+     0,   0,1606,1607,1609,1608,1610,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+  1613,   0,1611,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+     0,   0,   0,1612,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+     0,   0,   0,   0,   0,   0,   0,   0,   0,1620,   0,   0,   0,   0,   0,   0,
+     0,1623,   0,   0,1624,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+     0,   0,   0,   0,   0,   0,   0,   0,1614,1615,1616,1617,1618,1619,1621,1622,
+     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,1628,1629,   0,   0,   0,
+     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,1625,1626,   0,1627,
+     0,   0,   0,1634,   0,   0,1635,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+     0,   0,   0,   0,   0,   0,   0,   0,   0,1630,1631,1632,   0,   0,1633,   0,
+     0,   0,   0,   0,   0,   0,   0,   0,1639,   0,   0,1638,1640,   0,   0,   0,
+     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,1636,1637,   0,   0,
+     0,   0,   0,   0,1641,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,1642,1644,1643,   0,   0,   0,
+     0,   0,   0,   0,   0,   0,   0,   0,1645,   0,   0,   0,   0,   0,   0,   0,
+  1646,   0,   0,   0,   0,   0,   0,1648,1649,   0,1647,1650,   0,   0,   0,   0,
+     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,1651,1653,1652,   0,   0,   0,
+     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,1654,   0,1655,1657,1656,   0,
+     0,   0,   0,1659,   0,   0,   0,   0,   0,   0,   0,   0,   0,1660,   0,   0,
+     0,   0,1661,   0,   0,   0,   0,1662,   0,   0,   0,   0,1663,   0,   0,   0,
+     0,   0,   0,   0,   0,   0,   0,   0,   0,1658,   0,   0,   0,   0,   0,   0,
+     0,   0,   0,1664,   0,1665,1673,   0,1674,   0,   0,   0,   0,   0,   0,   0,
+     0,1666,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+     0,   0,   0,1668,   0,   0,   0,   0,   0,   0,   0,   0,   0,1669,   0,   0,
+     0,   0,1670,   0,   0,   0,   0,1671,   0,   0,   0,   0,1672,   0,   0,   0,
+     0,   0,   0,   0,   0,   0,   0,   0,   0,1667,   0,   0,   0,   0,   0,   0,
+     0,   0,   0,   0,   0,   0,1675,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+     0,   0,   0,   0,   0,   0,1676,   0,1677,   0,1678,   0,1679,   0,1680,   0,
+     0,   0,1681,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,1682,   0,1683,   0,   0,
+  1684,1685,   0,1686,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+   953,1138, 955,1140, 956,1141, 957,1142,1324,1351, 963,1148, 965,1150, 968,1153,
+   966,1151, 967,1152,1378,1380,1379,1381, 984,1169, 985,1170,1420,1421, 986,1171,
+   989,1174, 995,1180, 998,1183, 996,1181, 999,1184,1000,1185,1015,1200,1329,1356,
+  1017,1203,1019,1205,1021,1207,1024,1210,1687,1688,1027,1213,1026,1212,1028,1214,
+  1029,1215,1030,1216,1034,1220,1036,1222,1039,1225,1038,1224,1334,1361,1336,1363,
+  1382,1384,1383,1385,1056,1242,1057,1243,1059,1245,1063,1249,1689,1690,1065,1251,
+  1068,1254,1070,1256,1386,1387,1388,1389,1691,1692,1073,1259,1075,1262,1079,1266,
+  1078,1265,1095,1282,1098,1285,1097,1284,1390,1391,1392,1393,1099,1286,1100,1287,
+  1101,1288,1102,1289,1105,1292,1104,1291,1106,1294,1107,1295,1108,1296,1114,1302,
+  1119,1308,1122,1311,1123,1312,1186,1260,1293,1305,   0,1394,   0,   0,   0,   0,
+   952,1137, 947,1132,1317,1344,1316,1343,1319,1346,1318,1345,1693,1695,1371,1375,
+  1370,1374,1373,1377,1372,1376,1694,1696, 981,1166, 977,1162, 972,1157,1326,1353,
+  1325,1352,1328,1355,1327,1354,1697,1698,1009,1194,1013,1198,1054,1240,1048,1234,
+  1331,1358,1330,1357,1333,1360,1332,1359,1699,1700,1396,1401,1395,1400,1398,1403,
+  1397,1402,1399,1404,1094,1281,1087,1274,1406,1411,1405,1410,1408,1413,1407,1412,
+  1409,1414,1109,1297,1117,1306,1116,1304,1112,1300,   0,   0,   0,   0,   0,   0,
+  1471,1472,1701,1705,1702,1706,1703,1707,1430,1431,1715,1719,1716,1720,1717,1721,
+  1477,1478,1729,1731,1730,1732,   0,   0,1435,1436,1733,1735,1734,1736,   0,   0,
+  1481,1482,1737,1741,1738,1742,1739,1743,1439,1440,1751,1755,1752,1756,1753,1757,
+  1490,1491,1765,1768,1766,1769,1767,1770,1447,1448,1771,1774,1772,1775,1773,1776,
+  1495,1496,1777,1779,1778,1780,   0,   0,1451,1452,1781,1783,1782,1784,   0,   0,
+  1504,1505,1785,1788,1786,1789,1787,1790,   0,1459,   0,1791,   0,1792,   0,1793,
+  1509,1510,1794,1798,1795,1799,1796,1800,1462,1463,1808,1812,1809,1813,1810,1814,
+  1467,  21,1475,  22,1479,  23,1485,  24,1493,  27,1499,  28,1507,  29,   0,   0,
+  1704,1708,1709,1710,1711,1712,1713,1714,1718,1722,1723,1724,1725,1726,1727,1728,
+  1740,1744,1745,1746,1747,1748,1749,1750,1754,1758,1759,1760,1761,1762,1763,1764,
+  1797,1801,1802,1803,1804,1805,1806,1807,1811,1815,1816,1817,1818,1819,1820,1821,
+  1470,1469,1822,1474,1465,   0,1473,1825,1429,1428,1426,  12,1432,   0,  26,   0,
+     0,1315,1823,1484,1466,   0,1483,1829,1433,  13,1437,  14,1441,1826,1827,1828,
+  1488,1487,1513,  19,   0,   0,1492,1515,1445,1444,1442,  15,   0,1831,1832,1833,
+  1502,1501,1516,  25,1497,1498,1506,1518,1457,1456,1454,  17,1453,1313,  11,   3,
+     0,   0,1824,1512,1519,   0,1511,1830,1449,  16,1460,  18,1464,   4,   0,   0,
+    30,  31,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+     0,   0,   0,   0,   0,   0,  20,   0,   0,   0,   2,   6,   0,   0,   0,   0,
+     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,1834,1835,   0,   0,   0,   0,
+     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,1836,   0,
+     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,1837,1839,1838,
+     0,   0,   0,   0,1840,   0,   0,   0,   0,1841,   0,   0,1842,   0,   0,   0,
+     0,   0,   0,   0,1843,   0,1844,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+     0,1845,   0,   0,1846,   0,   0,1847,   0,1848,   0,   0,   0,   0,   0,   0,
+   937,   0,1850,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,1849, 936, 938,
+  1851,1852,   0,   0,1853,1854,   0,   0,1855,1856,   0,   0,   0,   0,   0,   0,
+  1857,1858,   0,   0,1861,1862,   0,   0,1863,1864,   0,   0,   0,   0,   0,   0,
+     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,1867,1868,1869,1870,
+  1859,1860,1865,1866,   0,   0,   0,   0,   0,   0,1871,1872,1873,1874,   0,   0,
+     0,   0,   0,   0,   0,   0,   0,   0,   0,  32,  33,   0,   0,   0,   0,   0,
+     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,1875,   0,   0,   0,
+     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,1877,   0,1878,   0,
+  1879,   0,1880,   0,1881,   0,1882,   0,1883,   0,1884,   0,1885,   0,1886,   0,
+  1887,   0,1888,   0,   0,1889,   0,1890,   0,1891,   0,   0,   0,   0,   0,   0,
+  1892,1893,   0,1894,1895,   0,1896,1897,   0,1898,1899,   0,1900,1901,   0,   0,
+     0,   0,   0,   0,1876,   0,   0,   0,   0,   0,   0,   0,   0,   0,1902,   0,
+     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,1904,   0,1905,   0,
+  1906,   0,1907,   0,1908,   0,1909,   0,1910,   0,1911,   0,1912,   0,1913,   0,
+  1914,   0,1915,   0,   0,1916,   0,1917,   0,1918,   0,   0,   0,   0,   0,   0,
+  1919,1920,   0,1921,1922,   0,1923,1924,   0,1925,1926,   0,1927,1928,   0,   0,
+     0,   0,   0,   0,1903,   0,   0,1929,1930,1931,1932,   0,   0,   0,1933,   0,
+   710, 385, 724, 715, 455, 103, 186, 825, 825, 242, 751, 205, 241, 336, 524, 601,
+   663, 676, 688, 738, 411, 434, 474, 500, 649, 746, 799, 108, 180, 416, 482, 662,
+   810, 275, 462, 658, 692, 344, 618, 679, 293, 388, 440, 492, 740, 116, 146, 168,
+   368, 414, 481, 527, 606, 660, 665, 722, 781, 803, 809, 538, 553, 588, 642, 758,
+   811, 701, 233, 299, 573, 612, 487, 540, 714, 779, 232, 267, 412, 445, 457, 585,
+   594, 766, 167, 613, 149, 148, 560, 589, 648, 768, 708, 345, 411, 704, 105, 259,
+   313, 496, 518, 174, 542, 120, 307, 101, 430, 372, 584, 183, 228, 529, 650, 697,
+   424, 732, 428, 349, 632, 355, 517, 110, 135, 147, 403, 580, 624, 700, 750, 170,
+   193, 245, 297, 374, 463, 543, 763, 801, 812, 815, 162, 384, 420, 730, 287, 330,
+   337, 366, 459, 476, 509, 558, 591, 610, 726, 652, 734, 759, 154, 163, 198, 473,
+   683, 697, 292, 311, 353, 423, 572, 494, 113, 217, 259, 280, 314, 499, 506, 603,
+   608, 752, 778, 782, 788, 117, 557, 748, 774, 320, 109, 126, 260, 265, 373, 411,
+   479, 523, 655, 737, 823, 380, 765, 161, 395, 398, 438, 451, 502, 516, 537, 583,
+   791, 136, 340, 769, 122, 273, 446, 727, 305, 322, 400, 496, 771, 155, 190, 269,
+   377, 391, 406, 432, 501, 519, 599, 684, 687, 749, 776, 175, 452, 191, 480, 510,
+   659, 772, 805, 813, 397, 444, 619, 566, 568, 575, 491, 471, 707, 111, 636, 156,
+   153, 288, 346, 578, 256, 435, 383, 729, 680, 767, 694, 295, 128, 210,   0,   0,
+   227,   0, 379,   0,   0, 150, 493, 525, 544, 551, 552, 556, 783, 576, 604,   0,
+   661,   0, 703,   0,   0, 735, 743,   0,   0,   0, 793, 794, 795, 808, 741, 773,
+   118, 127, 130, 166, 169, 177, 207, 213, 215, 226, 229, 268, 270, 317, 327, 329,
+   335, 369, 375, 381, 404, 441, 448, 458, 477, 484, 503, 539, 545, 547, 546, 548,
+   549, 550, 554, 555, 561, 564, 569, 591, 593, 595, 598, 607, 620, 625, 625, 651,
+   690, 695, 705, 706, 716, 717, 733, 735, 777, 786, 790, 315, 869, 623,   0,   0,
+   102, 145, 134, 115, 129, 138, 165, 171, 207, 202, 206, 212, 227, 231, 240, 243,
+   250, 254, 294, 296, 303, 308, 319, 325, 321, 329, 326, 335, 341, 357, 360, 362,
+   370, 379, 388, 389, 393, 421, 424, 438, 456, 454, 458, 465, 477, 535, 485, 490,
+   493, 507, 512, 514, 521, 522, 525, 526, 528, 533, 532, 541, 565, 569, 574, 586,
+   591, 597, 607, 637, 647, 674, 691, 693, 695, 698, 703, 699, 705, 704, 702, 706,
+   709, 717, 728, 736, 747, 754, 770, 777, 783, 784, 786, 787, 790, 802, 825, 848,
+   847, 857,  55,  65,  66, 883, 892, 916, 822, 824,   0,   0,   0,   0,   0,   0,
+     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,1586,   0,1605,
+     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,1602,1603,1934,1935,1574,1575,
+  1576,1577,1579,1580,1581,1583,1584,   0,1585,1587,1588,1589,1591,   0,1592,   0,
+  1593,1594,   0,1595,1596,   0,1598,1599,1600,1601,1604,1582,1578,1590,1597,   0,
+     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,1936,   0,1937,   0,   0,   0,
+     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,1938,   0,   0,   0,   0,
+     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,1939,1940,
+     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,1941,1942,   0,   0,   0,
+     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,1944,1943,   0,1945,   0,
+     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,1946,1947,   0,   0,   0,   0,
+     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,1948,1949,
+  1950,1951,1952,1953,1954,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,1955,1956,1957,1959,1958,
+  1960,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+   106, 104, 107, 826, 114, 118, 119, 121, 123, 124, 127, 125,  34, 830, 130, 131,
+   132, 137, 827,  35, 133, 139, 829, 142, 143, 112, 144, 145, 924, 151, 152,  37,
+   157, 158, 159, 160,  38, 165, 166, 169, 171, 172, 173, 174, 176, 177, 178, 179,
+   181, 182, 182, 182, 833, 468, 184, 185, 834, 187, 188, 189, 196, 192, 194, 195,
+   197, 199, 200, 201, 203, 204, 204, 206, 208, 209, 211, 218, 213, 219, 214, 216,
+   153, 234, 221, 222, 223, 220, 225, 224, 230, 835, 235, 236, 237, 238, 239, 244,
+   836, 837, 247, 248, 249, 246, 251,  39,  40, 253, 255, 255, 838, 257, 258, 259,
+   261, 839, 262, 263, 301, 264,  41, 266, 270, 272, 271, 841, 274, 842, 277, 276,
+   278, 281, 282,  42, 283, 284, 285, 286,  43, 843,  44, 289, 290, 291, 293, 934,
+   298, 845, 845, 621, 300, 300,  45, 852, 894, 302, 304,  46, 306, 309, 310, 312,
+   316,  48,  47, 317, 846, 318, 323, 324, 325, 324, 328, 329, 333, 331, 332, 334,
+   335, 336, 338, 339, 342, 343, 347, 351, 849, 350, 348, 352, 354, 359, 850, 361,
+   358, 356,  49, 363, 365, 367, 364,  50, 369, 371, 851, 376, 386, 378,  53, 381,
+    52,  51, 140, 141, 387, 382, 614,  78, 388, 389, 390, 394, 392, 856,  54, 399,
+   396, 402, 404, 858, 405, 401, 407,  55, 408, 409, 410, 413, 859, 415,  56, 417,
+   860, 418,  57, 419, 422, 424, 425, 861, 840, 862, 426, 863, 429, 431, 427, 433,
+   437, 441, 438, 439, 442, 443, 864, 436, 449, 450,  58, 454, 453, 865, 447, 460,
+   866, 867, 461, 466, 465, 464,  59, 467, 470, 469, 472, 828, 475, 868, 478, 870,
+   483, 485, 486, 871, 488, 489, 872, 873, 495, 497,  60, 498,  61,  61, 504, 505,
+   507, 508, 511,  62, 513, 874, 515, 875, 518, 844, 520, 876, 877, 878,  63,  64,
+   528, 880, 879, 881, 882, 530, 531, 531, 533,  66, 534,  67,  68, 884, 536, 538,
+   541,  69, 885, 549, 886, 887, 556, 559,  70, 561, 562, 563, 888, 889, 889, 567,
+    71, 890, 570, 571,  72, 891, 577,  73, 581, 579, 582, 893, 587,  74, 590, 592,
+   596,  75, 895, 896,  76, 897, 600, 898, 602, 605, 607, 899, 900, 609, 901, 611,
+   853,  77, 615, 616,  79, 617, 252, 902, 903, 854, 855, 621, 622, 731,  80, 627,
+   626, 628, 164, 629, 630, 631, 633, 904, 632, 634, 639, 640, 635, 641, 646, 651,
+   638, 643, 644, 645, 905, 907, 906,  81, 653, 654, 656, 911, 657, 908,  82,  83,
+   909, 910,  84, 664, 665, 666, 667, 669, 668, 671, 670, 674, 672, 673, 675,  85,
+   677, 678,  86, 681, 682, 912, 685, 686,  87, 689,  36, 913, 914,  88,  89, 696,
+   702, 709, 711, 915, 712, 713, 718, 719, 917, 831, 721, 720, 723, 832, 725, 728,
+   918, 919, 739, 742, 744, 920, 745, 753, 756, 757, 755, 760, 761, 921, 762,  90,
+   764, 922,  91, 775, 279, 780, 923, 925,  92,  93, 785, 926,  94, 927, 787, 787,
+   789, 928, 792,  95, 796, 797, 798, 800,  96, 929, 802, 804, 806,  97,  98, 807,
+   930,  99, 931, 932, 933, 814, 100, 816, 817, 818, 819, 820, 821, 935,   0,   0,
+};
+static const int16_t
+_hb_ucd_i16[196] =
+{
+      0,    0,    0,    0,    1,   -1,    0,    0,    2,    0,   -2,    0,    0,    0,    0,    2,
+      0,   -2,    0,    0,    0,    0,    0,   16,    0,    0,    0,  -16,    0,    0,    1,   -1,
+      0,    0,    0,    1,   -1,    0,    0,    0,    0,    1,   -1,    0,    3,    3,    3,   -3,
+     -3,   -3,    0,    0,    0, 2016,    0,    0,    0,    0,    0, 2527, 1923, 1914, 1918,    0,
+   2250,    0,    0,    0,    0,    0,    0,  138,    0,    7,    0,    0,   -7,    0,    0,    0,
+      1,   -1,    1,   -1,   -1,    1,   -1,    0, 1824,    0,    0,    0,    0,    0, 2104,    0,
+   2108, 2106,    0, 2106, 1316,    0,    0,    0,    0,    1,   -1,    1,   -1, -138,    0,    0,
+      1,   -1,    8,    8,    8,    0,    7,    7,    0,    0,   -8,   -8,   -8,   -7,   -7,    0,
+      1,   -1,    0,    2,-1316,    1,   -1,    0,   -1,    1,   -1,    1,   -1,    3,    1,   -1,
+     -3,    1,   -1,    1,   -1,    0,    0,-1914,-1918,    0,    0,-1923,-1824,    0,    0,    0,
+      0,-2016,    0,    0,    1,   -1,    0,    1,    0,    0,-2104,    0,    0,    0,    0,-2106,
+  -2108,-2106,    0,    0,    1,   -1,-2250,    0,    0,    0,-2527,    0,    0,   -2,    0,    1,
+     -1,    0,    1,   -1,
+};
+
+static inline uint_fast8_t
+_hb_ucd_gc (unsigned u)
+{
+  return u<1114110u?_hb_ucd_u8[6432+(((_hb_ucd_u8[1248+(((_hb_ucd_u16[((_hb_ucd_u8[544+(((_hb_ucd_u8[u>>1>>3>>3>>4])<<4)+((u>>1>>3>>3)&15u))])<<3)+((u>>1>>3)&7u)])<<3)+((u>>1)&7u))])<<1)+((u)&1u))]:2;
+}
+static inline uint_fast8_t
+_hb_ucd_ccc (unsigned u)
+{
+  return u<125259u?_hb_ucd_u8[8640+(((_hb_ucd_u8[7704+(((_hb_ucd_u8[7048+(((_hb_ucd_u8[6802+(u>>2>>3>>4)])<<4)+((u>>2>>3)&15u))])<<3)+((u>>2)&7u))])<<2)+((u)&3u))]:0;
+}
+static inline unsigned
+_hb_ucd_b4 (const uint8_t* a, unsigned i)
+{
+  return (a[i>>1]>>((i&1u)<<2))&15u;
+}
+static inline int_fast16_t
+_hb_ucd_bmg (unsigned u)
+{
+  return u<65380u?_hb_ucd_i16[((_hb_ucd_u8[9372+(((_hb_ucd_u8[9252+(((_hb_ucd_b4(9124+_hb_ucd_u8,u>>2>>3>>3))<<3)+((u>>2>>3)&7u))])<<3)+((u>>2)&7u))])<<2)+((u)&3u)]:0;
+}
+static inline uint_fast8_t
+_hb_ucd_sc (unsigned u)
+{
+  return u<918000u?_hb_ucd_u8[10822+(((_hb_ucd_u16[1920+(((_hb_ucd_u8[10150+(((_hb_ucd_u8[9700+(u>>3>>4>>4)])<<4)+((u>>3>>4)&15u))])<<4)+((u>>3)&15u))])<<3)+((u)&7u))]:2;
+}
+static inline uint_fast16_t
+_hb_ucd_dm (unsigned u)
+{
+  return u<195102u?_hb_ucd_u16[5648+(((_hb_ucd_u8[16174+(((_hb_ucd_b4(16078+_hb_ucd_u8,u>>4>>6))<<6)+((u>>4)&63u))])<<4)+((u)&15u))]:0;
+}
+
+
+#else
+
+static const uint8_t
+_hb_ucd_u8[13072] =
+{
+    0,  1,  2,  3,  4,  5,  5,  5,  5,  5,  6,  5,  5,  7,  8,  9,
+   10, 11, 12, 13, 14, 15, 16,  5, 17, 15, 15, 18, 15, 19, 20, 21,
+    5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5, 22, 23,
+   15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+   15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+   15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+   15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+   15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+   15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+   15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+   15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+   15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+   15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+   15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+   24, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+    8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,
+    8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,
+    0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15,
+   16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
+   32, 33, 34, 34, 34, 34, 35, 36, 37, 34, 34, 34, 38, 39, 40, 41,
+   42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57,
+   58, 59, 60, 61, 62, 62, 63, 64, 65, 66, 67, 68, 69, 67, 70, 71,
+   67, 67, 62, 72, 62, 62, 73, 67, 74, 75, 76, 77, 78, 67, 67, 67,
+   79, 80, 34, 81, 82, 83, 67, 67, 34, 34, 34, 34, 34, 34, 34, 34,
+   34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
+   34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
+   34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 84, 34, 34, 34, 34,
+   34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
+   34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
+   85, 34, 34, 34, 34, 34, 34, 34, 34, 86, 34, 34, 87, 88, 89, 90,
+   91, 92, 93, 94, 95, 96, 97, 98, 34, 34, 34, 34, 34, 34, 34, 34,
+   34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
+   99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99,
+  100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,
+  100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,
+  100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,
+  100,100, 34, 34, 34, 34,101,102, 34, 34,103,104,105,106,107,108,
+   34, 34,109,110,111,112,113,114,115,116,117,111, 34, 34, 34,111,
+  118,119,120,121,122,123,124,125, 34,126,127,111,128,111,129, 34,
+  130,131,132,133,134,135,136,111,137,138,111,139,140,141,142,111,
+  143,144,111,145,146,147,111,111,148,149,150,151,111,152,111,153,
+   34, 34, 34, 34, 34, 34, 34, 34,154, 34, 34,111,111,111,111,111,
+  111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,
+   34, 34, 34, 34, 34, 34, 34, 34,155,111,111,111,111,111,111,111,
+  111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,
+  111,111,111,111,111,111,111,111, 34, 34, 34, 34, 34,111,111,111,
+  111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,
+  111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,
+  111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,
+  111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,
+   34, 34, 34, 34,156,157,158, 34,111,111,111,111,159,160,161,162,
+   34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
+   34, 34, 34, 34, 34, 34,111,111,111,111,111,111,111,111,111,111,
+   34, 34, 34, 34, 34, 34,111,111,111,111,111,111,111,111,111,111,
+  111,111,111,111,111,111,111,111, 34,163,111,111,111,111,111,111,
+   67, 67,164,165,166,128, 65,111,167,168,169,170,171,172,173,174,
+   67, 67, 67, 67,175,176,111,111,111,111,111,111,111,111,111,111,
+  177,111,178,111,111,179,111,111,111,111,111,111,111,111,111,111,
+   34,180,181,111,111,111,111,111,128,182,183,111, 34,184,111,111,
+   67, 67,185, 67, 67,111, 67,186, 67, 67, 67, 67, 67, 67, 67, 67,
+   67, 67, 67, 67, 67, 67,111,111,111,111,111,111,111,111,111,111,
+   34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
+   34, 34, 34, 34, 34, 34, 34, 34,111,111,111,111,111,111,111,111,
+  111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,
+   34, 34, 34, 34, 34,111,111,111,111,111,111,111,111,111,111,111,
+  187,111,177,177,111,111,111,111,111,111,111,111,111,111,111,111,
+  111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,
+    0,  0,  0,  0,  0,  0,  0,  0,  1,  2,  3,  2,  4,  5,  6,  2,
+    7,  7,  7,  7,  7,  2,  8,  9, 10, 11, 11, 11, 11, 11, 11, 11,
+   11, 11, 11, 11, 11, 12, 13, 14, 15, 16, 16, 16, 16, 16, 16, 16,
+   16, 16, 16, 16, 16, 17, 18, 19,  1, 20, 20, 21, 22, 23, 24, 25,
+   26, 27, 15,  2, 28, 29, 27, 30, 11, 11, 11, 11, 11, 11, 11, 11,
+   11, 11, 11, 31, 11, 11, 11, 32, 16, 16, 16, 16, 16, 16, 16, 16,
+   16, 16, 16, 33, 16, 16, 16, 16, 32, 32, 32, 32, 32, 32, 32, 32,
+   32, 32, 32, 32, 34, 34, 34, 34, 34, 34, 34, 34, 16, 32, 32, 32,
+   32, 32, 32, 32, 11, 34, 34, 16, 34, 32, 32, 11, 34, 11, 16, 11,
+   11, 34, 32, 11, 32, 16, 11, 34, 32, 32, 32, 11, 34, 16, 32, 11,
+   34, 11, 34, 34, 32, 35, 32, 16, 36, 36, 37, 34, 38, 37, 34, 34,
+   34, 34, 34, 34, 34, 34, 16, 32, 34, 38, 32, 11, 32, 32, 32, 32,
+   32, 32, 16, 16, 16, 11, 34, 32, 34, 34, 11, 32, 32, 32, 32, 32,
+   16, 16, 39, 16, 16, 16, 16, 16, 40, 40, 40, 40, 40, 40, 40, 40,
+   40, 41, 41, 40, 40, 40, 40, 40, 40, 41, 41, 41, 41, 41, 41, 41,
+   40, 40, 42, 41, 41, 41, 42, 42, 41, 41, 41, 41, 41, 41, 41, 41,
+   43, 43, 43, 43, 43, 43, 43, 43, 32, 32, 42, 32, 16, 44, 16, 10,
+   41, 41, 41, 45, 11, 11, 11, 11, 34, 11, 11, 11, 11, 11, 11, 11,
+   11, 11, 11, 11, 11, 11, 16, 16, 16, 16, 16, 16, 16, 16, 16, 34,
+   16, 11, 32, 16, 32, 32, 32, 32, 16, 16, 32, 46, 34, 32, 34, 11,
+   32, 47, 43, 43, 48, 32, 32, 32, 11, 34, 34, 34, 34, 34, 34, 16,
+   11, 11, 11, 11, 49,  2,  2,  2, 16, 16, 16, 16, 50, 51, 52, 53,
+   54, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 55,
+   56, 57, 43, 56, 43, 43, 43, 43, 36, 36, 36, 36, 36, 36, 36, 36,
+   36, 58,  2,  2,  2,  2,  2,  2, 59, 59, 59,  8,  9, 60,  2, 61,
+   43, 43, 43, 43, 43, 57, 59,  2, 62, 36, 36, 36, 36, 63, 43, 43,
+    7,  7,  7,  7,  7,  2,  2, 36, 64, 36, 36, 36, 36, 36, 36, 36,
+   36, 36, 65, 43, 43, 43, 66, 47, 43, 43, 67, 68, 69, 43, 43, 36,
+    7,  7,  7,  7,  7, 36, 70, 71,  2,  2,  2,  2,  2,  2,  2, 72,
+   63, 36, 36, 36, 36, 36, 36, 36, 43, 43, 43, 43, 43, 43, 64, 36,
+   36, 36, 36, 43, 43, 43, 43, 43,  7,  7,  7,  7,  7, 36, 36, 36,
+   36, 36, 36, 36, 36, 63, 43, 43, 43, 43, 40, 21,  2, 40, 68, 20,
+   36, 36, 36, 43, 43, 68, 43, 43, 43, 43, 68, 43, 68, 43, 43, 43,
+    2,  2,  2,  2,  2,  2,  2,  2, 36, 36, 36, 36, 63, 43, 43,  2,
+   36, 63, 43, 43, 43, 43, 43, 43, 43, 73, 43, 43, 43, 43, 43, 43,
+   43, 74, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 74, 64, 75,
+   76, 43, 43, 43, 74, 75, 76, 75, 63, 43, 43, 43, 36, 36, 36, 36,
+   36, 43,  2,  7,  7,  7,  7,  7, 77, 36, 36, 36, 36, 36, 36, 36,
+   63, 75, 78, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 64, 75,
+   76, 43, 43, 74, 75, 75, 76, 36, 36, 36, 36, 79, 75, 75, 36, 36,
+   36, 43, 43,  7,  7,  7,  7,  7, 36, 20, 27, 27, 27, 53, 58, 43,
+   43, 74, 78, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 43, 75,
+   76, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 64, 36, 36, 36,
+   36, 36, 36,  7,  7,  7,  7,  7, 43, 36, 63,  2,  2,  2,  2,  2,
+   76, 43, 43, 43, 74, 75, 76, 43, 60, 20, 20, 20, 80, 43, 43, 43,
+   43, 75, 78, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 64, 76,
+   76, 43, 43, 74, 75, 75, 76, 43, 43, 43, 43, 74, 75, 75, 36, 36,
+   71, 27, 27, 27, 27, 27, 27, 27, 43, 64, 36, 36, 36, 36, 36, 36,
+   36, 36, 36, 36, 36, 36, 36, 75, 74, 75, 75, 75, 75, 75, 76, 43,
+   36, 36, 36, 79, 75, 75, 75, 75, 75, 75, 75,  7,  7,  7,  7,  7,
+   27, 81, 61, 61, 53, 61, 61, 61, 74, 75, 64, 36, 36, 36, 36, 36,
+   36, 36, 36, 36, 36, 36, 36, 43, 74, 75, 75, 43, 43, 43, 43, 43,
+   43, 43, 43, 43, 36, 36, 36, 36,  7,  7,  7, 82, 27, 27, 27, 81,
+   63, 75, 65, 36, 36, 36, 36, 36, 75, 75, 75, 74, 75, 75, 43, 43,
+   43, 43, 74, 75, 75, 75, 75, 36, 83, 36, 36, 36, 36, 36, 36, 36,
+   36, 36, 36, 36, 36, 63, 64, 75, 76, 43, 43, 75, 75, 75, 76, 70,
+   61, 61, 36, 79, 27, 27, 27, 84, 27, 27, 27, 27, 81, 36, 36, 36,
+   75, 75, 78, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 43, 43, 74,
+   75, 43, 43, 43, 75, 75, 75, 75,  7, 75,  2,  2,  2,  2,  2,  2,
+   63, 36, 43, 43, 43, 43, 43, 85, 36, 36, 36, 68, 43, 43, 43, 57,
+    7,  7,  7,  7,  7,  2,  2,  2, 63, 36, 43, 43, 43, 43, 64, 36,
+   36, 36, 36, 40, 43, 43, 43, 43,  7,  7,  7,  7,  7,  7, 36, 36,
+   70, 61,  2,  2,  2,  2,  2,  2,  2, 86, 86, 61, 43, 61, 61, 61,
+    7,  7,  7,  7,  7, 27, 27, 27, 27, 27, 47, 47, 47,  4,  4, 75,
+   63, 43, 43, 43, 43, 43, 43, 74, 43, 43, 57, 43, 36, 36, 63, 43,
+   43, 43, 43, 43, 43, 43, 43, 61, 61, 61, 61, 69, 61, 61, 61, 61,
+    2,  2, 86, 61, 21,  2,  2,  2, 36, 36, 36, 36, 36, 79, 76, 43,
+   74, 43, 43, 43, 76, 74, 76, 64, 36, 36, 36, 75, 43, 36, 36, 43,
+   64, 75, 78, 79, 75, 75, 75, 36, 63, 43, 64, 36, 36, 36, 36, 36,
+   36, 74, 76, 74, 75, 75, 76, 79,  7,  7,  7,  7,  7, 75, 76, 61,
+   16, 16, 16, 16, 16, 50, 44, 16, 36, 36, 36, 36, 36, 36, 63, 43,
+    2,  2,  2,  2, 87, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27,
+   61, 61, 61, 61, 61, 61, 61, 61, 11, 11, 11, 11, 16, 16, 16, 16,
+   88, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 70, 65,
+   89, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 90, 91, 91,
+   36, 36, 36, 36, 36, 58,  2, 92, 93, 36, 36, 36, 36, 36, 36, 36,
+   36, 43, 43, 43, 43, 43, 43, 43, 36, 43, 57,  2,  2,  2,  2,  2,
+   36, 36, 43, 76, 43, 43, 43, 75, 75, 75, 75, 74, 76, 43, 43, 43,
+   43, 43,  2, 77,  2, 60, 63, 43,  7,  7,  7,  7,  7,  7,  7,  7,
+    2,  2,  2, 94,  2, 56, 43, 59, 36, 95, 36, 36, 36, 36, 36, 36,
+   36, 36, 63, 64, 36, 36, 36, 36, 36, 36, 36, 36, 63, 36, 36, 36,
+   43, 74, 75, 76, 74, 75, 75, 75, 75, 74, 75, 75, 76, 43, 43, 43,
+   61, 61,  2,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7, 27, 27, 61,
+   36, 36, 36, 63, 74, 76, 43,  2, 36, 36, 79, 74, 43, 43, 43, 43,
+   74, 74, 76, 43, 43, 43, 74, 75, 75, 76, 43, 43, 43, 43, 43, 43,
+    2,  2,  2, 77,  2,  2,  2,  2, 43, 43, 43, 43, 43, 43, 43, 48,
+   48, 48, 48, 48, 48, 48, 48, 48, 43, 43, 78, 36, 36, 36, 36, 36,
+   36, 36, 74, 43, 43, 74, 74, 75, 75, 74, 78, 36, 36, 36, 36, 36,
+   86, 61, 61, 61, 61, 47, 43, 43, 43, 43, 61, 61, 61, 61, 61, 61,
+   43, 78, 36, 36, 36, 36, 36, 36, 79, 43, 43, 75, 43, 76, 43, 36,
+   36, 36, 36, 74, 43, 75, 76, 76, 43, 75, 75, 75, 75, 75,  2,  2,
+   36, 36, 75, 75, 75, 75, 43, 43, 43, 43, 75, 43, 43, 57,  2,  2,
+    7,  7,  7,  7,  7,  7, 83, 36, 36, 36, 36, 36, 40, 40, 40,  2,
+   43, 57, 43, 43, 43, 43, 43, 43, 74, 43, 43, 43, 64, 36, 63, 36,
+   36, 36, 64, 79, 43, 36, 36, 36, 16, 16, 16, 16, 16, 16, 40, 40,
+   40, 40, 40, 40, 40, 44, 16, 16, 16, 16, 16, 16, 44, 16, 16, 16,
+   16, 16, 16, 16, 16, 96, 40, 40, 32, 32, 32, 16, 16, 16, 16, 32,
+   16, 16, 16, 16, 11, 11, 11, 11, 16, 16, 16, 16, 34, 11, 11, 11,
+   16, 16, 16, 16, 97, 97, 97, 97, 16, 16, 16, 16, 11, 11, 98, 99,
+   41, 16, 16, 16, 11, 11, 98, 41, 16, 16, 16, 16, 11, 11,100, 41,
+  101,101,101,101,101,102, 59, 59, 51, 51, 51,  2,103,104,103,104,
+    2,  2,  2,  2,105, 59, 59,106,  2,  2,  2,  2,107,108,  2,109,
+  110,  2,111,112,  2,  2,  2,  2,  2,  9,110,  2,  2,  2,  2,113,
+   59, 59, 59, 59, 59, 59, 59, 59,114, 40, 27, 27, 27,  8,111,115,
+   27, 27, 27, 27, 27,  8,111, 91, 20, 20, 20, 20, 20, 20, 20, 20,
+   43, 43, 43, 43, 43, 43,116, 48,117, 48,117, 43, 43, 43, 43, 43,
+   61,118, 61,119, 61, 34, 11, 16, 11, 32,119, 61, 46, 11, 11, 61,
+   61, 61,118,118,118, 11, 11,120, 11, 11, 35, 36, 39, 61, 16, 11,
+    8,  8, 46, 16, 16, 26, 61,121, 92, 92, 92, 92, 92, 92, 92, 92,
+   92,122,123, 92,124, 61, 61, 61,  8,  8,125, 61, 61,  8, 61, 61,
+  125, 26, 61,125, 61, 61, 61,125, 61, 61, 61, 61, 61, 61, 61,  8,
+   61,125,125, 61, 61, 61, 61, 61, 61, 61,  8,  8,  8,  8,  8,  8,
+    8,  8,  8,  8,  8,  8,  8,  8, 61, 61, 61, 61,  4,  4, 61, 61,
+    8, 61, 61, 61,126,127, 61, 61, 61, 61, 61, 61, 61, 61,125, 61,
+   61, 61, 61, 61, 61, 26,  8,  8,  8,  8, 61, 61, 61, 61, 61, 61,
+   61, 61, 61, 61, 61, 61,  8,  8,  8, 61, 61, 61, 61, 61, 61, 61,
+   27, 27, 27, 27, 27, 27, 61, 61, 61, 61, 61, 61, 61, 27, 27, 27,
+   61, 61, 61, 26, 61, 61, 61, 61, 26, 61, 61, 61, 61, 61, 61, 61,
+   61, 61, 61, 61,  8,  8,  8,  8, 61, 61, 61, 61, 61, 61, 61, 26,
+   61, 61, 61, 61,  4,  4,  4,  4,  4,  4,  4, 27, 27, 27, 27, 27,
+   27, 27, 61, 61, 61, 61, 61, 61,  8,  8,111,128,  8,  8,  8,  8,
+    8,  8,  8,  4,  4,  4,  4,  4,  8,111,129,129,129,129,129,129,
+  129,129,129,129,128,  8,  8,  8,  8,  8,  8,  8,  4,  4,  8,  8,
+    8,  8,  8,  8,  8,  8,  4,  8,  8,  8,125, 26,  8,  8,125, 61,
+   32, 11, 32, 34, 34, 34, 34, 11, 32, 32, 34, 16, 16, 16, 40, 11,
+   32, 32,121, 61, 61,119, 34,130, 43, 32, 16, 16, 50,  2, 87,  2,
+   36, 36, 36, 36, 36, 36, 36, 95,  2,  2,  2,  2,  2,  2,  2, 56,
+    2,103,103,  2,107,108,103,  2,  2,  2,  2,  6,  2, 94,103,  2,
+  103,  4,  4,  4,  4,  2,  2, 77,  2,  2,  2,  2,  2, 51,  2,  2,
+   94,131,  2,  2,  2,  2,  2,  2,  1,  2,132,133,  4,  4,  4,  4,
+    4, 61,  4,  4,  4,  4,134, 91,135, 92, 92, 92, 92, 43, 43, 75,
+  136, 40, 40, 61, 92,137, 58, 61, 71, 36, 36, 36, 36, 36, 36, 36,
+   36, 36, 36, 36, 63,138,139, 62, 36, 36, 36, 36, 36, 58, 40, 62,
+   61, 27, 27, 61, 61, 61, 61, 61, 27, 27, 27, 27, 27, 61, 61, 61,
+   61, 61, 61, 61, 27, 27, 27, 27,140, 27, 27, 27, 27, 27, 27, 27,
+   36, 36, 95, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36,141,  2,
+   32, 32, 32, 32, 32, 32, 32, 63, 48,142, 43, 43, 43, 43, 43, 77,
+   32, 32, 32, 32, 32, 32, 40, 43, 36, 36, 36, 92, 92, 92, 92, 92,
+   43,  2,  2,  2,  2,  2,  2,  2, 41, 41, 41,139, 40, 40, 40, 40,
+   41, 32, 32, 32, 32, 32, 32, 32, 16, 32, 32, 32, 32, 32, 32, 32,
+   44, 16, 16, 16, 34, 34, 34, 32, 32, 32, 32, 32, 42,143, 34, 35,
+   32, 32, 16, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 11, 11, 32,
+   11, 11, 32, 32, 32, 32, 32, 32, 16, 32, 11, 11, 11, 11, 11, 11,
+   11, 11, 11,144, 40, 35, 36, 36, 36, 64, 36, 64, 36, 63, 36, 36,
+   36, 79, 76, 74, 61, 61, 61, 61, 27, 27, 27, 61,145, 61, 61, 61,
+   36, 36,  2,  2,  2,  2,  2,  2, 75, 36, 36, 36, 36, 36, 36, 36,
+   36, 36, 75, 75, 75, 75, 75, 75, 75, 75, 43, 43, 43, 43, 43,  2,
+   43, 36, 36, 36,  2, 65, 65, 63, 36, 36, 36, 43, 43, 43, 43,  2,
+   36, 36, 36, 63, 43, 43, 43, 43, 43, 75, 75, 75, 75, 75, 75,146,
+   36, 63, 75, 43, 43, 75, 43, 75,146,  2,  2,  2,  2,  2,  2, 77,
+    7,  7,  7,  7,  7,  7,  7,  2, 36, 36, 63, 62, 36, 36, 36, 36,
+   36, 36, 36, 36, 63, 43, 43, 74, 76, 74, 76, 43, 43, 43, 43, 43,
+   36, 63, 36, 36, 36, 36, 74, 75,  7,  7,  7,  7,  7,  7,  2,  2,
+   62, 36, 36, 70, 61, 79, 74, 36, 64, 43, 64, 63, 64, 36, 36, 43,
+   36, 36, 36, 36, 36, 36, 95,  2, 36, 36, 36, 36, 36, 79, 43, 75,
+    2, 95,147, 43, 43, 43, 43, 43, 16, 16, 16, 16, 16, 99, 40, 40,
+   36, 79, 76, 75, 74,146, 76, 43,148,148,148,148,148,148,148,148,
+  149,149,149,149,149,149,149,149, 16, 16, 16, 16, 16, 16, 35, 64,
+   36, 36, 36, 36,150, 36, 36, 36, 36, 41, 41, 41, 41, 41, 41, 41,
+   41,151, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36,129,
+  152,152,152,152,152,152,152,152, 36, 36, 36, 36, 36, 36,145, 61,
+    2,  2,  2,153,112,  2,  2,  2,  6,154,155,129,129,129,129,129,
+  129,129,112,153,112,  2,109,156,  2,  2,  2,  2,134,129,129,112,
+    2,157,  8,  8, 60,  2,  2,  2, 36, 36, 36, 36, 36, 36, 36,158,
+    2,  2,  3,  2,  4,  5,  6,  2, 16, 16, 16, 16, 16, 17, 18,111,
+  112,  4,  2, 36, 36, 36, 36, 36, 62, 36, 36, 36, 36, 36, 36, 36,
+   36, 36, 36, 36, 36, 36, 36, 40, 20,159, 53, 20, 26,  8,125, 61,
+   61, 61, 61, 61,160, 59, 61, 61,  2,  2,  2, 87, 27, 27, 27, 27,
+   27, 27, 27, 81, 61, 61, 61, 61, 92, 92,124, 27, 81, 61, 61, 61,
+   61, 61, 61, 61, 61, 27, 61, 61, 61, 61, 61, 61, 61, 61, 47, 43,
+  161,161,161,161,161,161,161,161,162, 27, 27, 27, 27, 27, 27, 27,
+   27, 27, 27, 27, 27, 27, 84, 36,133, 36, 36, 36, 36, 92, 92, 92,
+   36, 36, 36, 36, 36, 36, 36, 58,163, 92, 92, 92, 92, 92, 92, 92,
+   36, 36, 36, 58, 27, 27, 27, 27, 36, 36, 36, 70,140, 27, 27, 27,
+   36, 36, 36,164, 27, 27, 27, 27, 36, 36, 36, 36, 36,164, 27, 27,
+   36, 36, 36, 27, 27, 27, 27, 30, 36, 36, 36, 36, 36, 36, 27, 36,
+   63, 43, 43, 43, 43, 43, 43, 43, 36, 36, 36, 36, 43, 43, 43, 43,
+   36, 36, 36, 36, 36, 36,164, 30, 36, 36, 36, 36, 36, 36,164, 27,
+   36, 36, 36, 36, 71, 36, 36, 36, 36, 36, 63, 43, 43,162, 27, 27,
+   36, 36, 36, 36, 58,  2,  2,  2, 36, 36, 36, 36, 27, 27, 27, 27,
+   16, 16, 16, 16, 16, 27, 27, 27, 36, 36, 43, 43, 43, 43, 43, 43,
+   27, 27, 27, 84, 36, 36, 36, 36,162, 27, 30,  2,  2,  2,  2,  2,
+   76, 78, 36, 36, 36, 36, 36, 36, 43, 43, 43, 57,  2,  2,  2,  2,
+    2, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27,  7,  7,  7,  7,  7,
+    7,  7,  7,  7,  7,  7,  7,165, 75, 76, 43, 74, 76, 57, 72,  2,
+    2,  2,  2,  2,  2,  2, 72, 59, 36, 36, 36, 63, 43, 43, 76, 43,
+   43, 43, 43,  7,  7,  7,  7,  7,  2,  2, 79, 75, 75, 75, 75, 75,
+   36, 63,  2, 36, 36, 36, 36, 36, 36, 79, 75, 43, 43, 43, 43, 74,
+   78, 36, 58,  2, 56, 43, 57,  2,  7,  7,  7,  7,  7, 58, 58,  2,
+   87, 27, 27, 27, 27, 27, 27, 27, 36, 36, 36, 36, 36, 36, 75, 76,
+   43, 75, 74, 43,  2,  2,  2, 43, 36, 36, 36, 36, 36, 36, 36, 63,
+   74, 75, 75, 75, 75, 75, 75, 75, 36, 36, 36, 79, 75, 75, 78, 36,
+   36, 75, 75, 43, 43, 43, 43, 43, 36, 36, 79, 75, 43, 43, 43, 43,
+   75, 43, 74, 64, 36, 58,  2,  2,  7,  7,  7,  7,  7, 82,  2, 64,
+   75, 76, 43, 43, 74, 74, 75, 76, 74, 43, 36, 65, 36, 36, 36, 36,
+   36, 36, 36, 36, 36, 36, 36, 79, 75, 43, 43, 43, 75, 75, 43, 76,
+   57,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2, 36, 36, 43, 43,
+   75, 76, 43, 43, 43, 74, 76, 76, 57,  2, 36, 36, 36, 36, 36, 36,
+   36, 36, 36, 36, 36, 63, 76, 75, 43, 43, 43, 76, 36, 36, 36, 36,
+   75, 43, 43, 76, 43, 43, 43, 43,  7,  7,  7,  7,  7, 27,  2, 86,
+   43, 43, 43, 43, 76, 57,  2,  2, 27, 27, 27, 27, 27, 27, 27, 84,
+   79, 75, 43, 43, 43, 43, 75, 75, 64, 65, 75, 75, 75, 75, 75, 75,
+   75, 75, 75, 75, 75, 75, 75, 75, 63, 43, 43, 43, 43, 64, 36, 36,
+   36, 63, 43, 43, 74, 63, 43, 57,  2,  2,  2, 56, 43, 43, 43, 43,
+   63, 43, 43, 74, 76, 43, 36, 36, 36, 36, 36, 36, 36, 43, 43, 43,
+   43, 43, 43, 74, 43,  2, 65,  2, 43, 43, 43, 43, 43, 43, 43, 76,
+   58,  2,  2,  2,  2,  2,  2,  2,  2, 36, 36, 36, 36, 36, 36, 36,
+   43, 43, 43, 43, 74, 43, 43, 43, 74, 43, 76, 43, 43, 43, 43, 43,
+   43, 43, 43, 63, 43, 43, 43, 43, 36, 36, 36, 36, 36, 75, 75, 75,
+   43, 74, 76, 76, 36, 36, 36, 36, 36, 63, 74,146,  2,  2,  2,  2,
+   27, 27, 81, 61, 61, 61, 53, 20,145, 61, 61, 61, 61, 61, 61, 61,
+   61, 61, 61, 61, 61, 61, 61, 21, 43, 43, 57,  2,  2,  2,  2,  2,
+   43, 43, 43, 57,  2,  2, 61, 61, 40, 40, 86, 61, 61, 61, 61, 61,
+    7,  7,  7,  7,  7,166, 27, 27, 27, 84, 36, 36, 36, 36, 36, 36,
+   27, 27, 27, 30,  2,  2,  2,  2, 79, 75, 75, 75, 75, 75, 75, 75,
+   75, 75, 75, 75, 75, 75, 75, 76, 43, 67, 40, 40, 40, 40, 40, 40,
+   40, 77, 40, 40, 40, 40, 40, 40, 36, 36, 36, 36, 36, 36, 47, 57,
+   61, 61,167, 76, 43, 61,167, 75, 75,168, 59, 59, 59, 73, 43, 43,
+   43, 69, 47, 43, 43, 43, 61, 61, 61, 61, 61, 61, 61, 43, 43, 61,
+   61, 43, 69, 61, 61, 61, 61, 61, 11, 11, 11, 11, 11, 16, 16, 16,
+   16, 16, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 16,
+   11, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 11, 11,
+   11, 11, 11, 16, 16, 16, 16, 16, 31, 16, 16, 16, 16, 16, 16, 16,
+   16, 16, 16, 16, 16, 33, 16, 16, 16, 11, 11, 11, 11, 11, 11, 11,
+   11, 11, 11, 11, 11, 31, 16, 16, 16, 16, 33, 16, 16, 16, 11, 11,
+   11, 11, 31, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 33,
+   16, 16, 16, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 31,
+   16, 16, 16, 16, 33, 16, 16, 16, 11, 11, 11, 11, 31, 16, 16, 16,
+   16, 33, 16, 16, 16, 32, 16,  7, 43, 43, 43, 69, 61, 47, 43, 43,
+   43, 43, 43, 43, 43, 43, 69, 61, 61, 61, 47, 61, 61, 61, 61, 61,
+   61, 61, 69, 21,  2,  2,  2,  2,  2,  2,  2,  2,  2, 56, 43, 43,
+   43, 43, 43, 67, 40, 40, 40, 40,  7,  7,  7,  7,  7,  7,  7, 70,
+   36, 36, 36, 36, 36, 36, 43, 43,  7,  7,  7,  7,  7,  7,  7,169,
+   16, 16, 43, 43, 43, 67, 40, 40, 27, 27, 27, 27, 27, 27,140, 27,
+  170, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27,140,
+   61, 61, 61, 61, 61, 25, 41, 41,  0,  0, 29, 21, 21, 21, 23, 21,
+   22, 18, 21, 25, 21, 17, 13, 13, 25, 25, 25, 21, 21,  9,  9,  9,
+    9, 22, 21, 18, 24, 16, 24,  5,  5,  5,  5, 22, 25, 18, 25,  0,
+   23, 23, 26, 21, 24, 26,  7, 20, 25,  1, 26, 24, 26, 25, 15, 15,
+   24, 15,  7, 19, 15, 21,  9, 25,  9,  5,  5, 25,  5,  9,  5,  7,
+    7,  7,  9,  8,  8,  5,  7,  5,  6,  6, 24, 24,  6, 24, 12, 12,
+    6,  5,  9, 21, 25,  9, 26, 12, 11, 11,  9,  6,  5, 21, 17, 17,
+   17, 26, 26, 23, 23, 12, 17, 12, 21, 12, 12, 21,  7, 21,  1,  1,
+   21, 23, 26, 26,  6,  7,  7, 12, 12,  7, 21,  7, 12,  1, 12,  6,
+    6, 12, 12, 26,  7, 26, 26,  7, 21,  1,  1, 12, 12, 10, 10, 10,
+   10, 12, 21,  6, 10,  7,  7, 10, 23,  7, 15, 26, 13, 21, 13,  7,
+   15,  7, 12, 23, 21, 26, 21, 15, 17,  7, 29,  7,  7, 22, 18, 18,
+   14, 14, 14,  7, 17, 21,  7,  6,  5,  6,  8,  8,  8, 24,  5, 24,
+    9, 24, 29, 29, 29,  1, 20, 19, 22, 20, 27, 28,  1, 29, 21, 20,
+   19, 21, 21, 16, 16, 21, 25, 22, 18, 21, 21, 29, 15,  6, 18,  6,
+   12, 11, 11, 12,  9, 26, 26,  9, 26,  5,  5, 26, 14,  9,  5, 14,
+   14, 15, 25, 26, 26, 22, 18, 26, 18, 25, 18, 22,  5, 12, 22, 21,
+   26,  6,  7, 14, 17, 22, 26, 14, 17,  6, 14,  6, 12, 24, 24,  6,
+   26, 15,  6, 21, 11, 21, 24,  9,  9,  7, 23, 26, 10, 21,  6, 10,
+    4,  4,  3,  3,  7, 25, 24,  7, 22, 22, 21, 22, 17, 16, 16, 22,
+   16, 16, 25, 17,  7,  1, 25, 24, 26,  1,  2,  2, 12, 15, 21, 14,
+    7, 15, 13, 12, 13, 15, 26, 10, 10,  1, 13, 23, 23, 15,  0,  1,
+    2,  3,  4,  5,  6,  7,  8,  9,  9, 10, 11,  9,  9,  9,  9,  9,
+    9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,
+    9,  9,  9,  9,  9,  9,  9, 12, 13,  9,  9,  9,  9,  9,  9,  9,
+    9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9, 14, 15, 16,  9,
+   17, 18, 19, 20, 21, 22,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,
+    9,  9,  9,  9,  9,  9,  9,  9, 23,  9,  9,  9,  9,  9,  9,  9,
+    9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9, 24,  9,  9,
+    9,  9, 25,  9,  9,  9, 26,  9, 27,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  1,  2,  0,  0,  0,  0,  3,  0,  0,  0,
+    4,  5,  6,  7,  0,  8,  9, 10,  0, 11, 12, 13,  0, 14, 15, 16,
+   15, 17, 15, 18, 15, 18, 15, 18,  0, 18,  0, 19, 15, 18, 20, 18,
+    0, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30,  0, 31,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0, 32,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0, 33,  0,  0, 34,  0,  0, 35,  0, 36,  0,
+    0,  0, 37, 38, 39,  0, 40, 41, 42, 43, 44,  0,  0, 45,  0,  0,
+    0, 46,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 47,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 48,  0, 49,
+    0, 50,  0,  0,  0,  0,  0,  0,  0,  0, 51,  0, 52,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0, 53, 54, 55,  0,  0,  0,  0, 56,  0,  0, 57, 58, 59,
+   60, 61,  0,  0, 62, 63,  0,  0,  0, 64,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0, 65,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0, 66,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0, 67,  0,  0,  0, 68,  0, 69,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0, 70,  0,  0, 71,  0,  0,  0,  0,  0,  0,  0,  0, 72,  0,
+    0,  0,  0,  0,  0,  0,  0, 73,  0,  0,  0, 74, 75,  0, 76, 60,
+    0, 77, 78,  0,  0, 79, 80, 81,  0,  0,  0, 82,  0, 83,  0,  0,
+   49, 84, 49,  0, 85,  0, 86,  0,  0,  0, 75,  0,  0,  0,  0,  0,
+    0, 87, 88, 89, 90,  0,  0,  0,  0,  0, 49,  0,  0,  0,  0, 91,
+   92,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0, 93, 94,  0,  0,  0,  0,  0, 95,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 96,
+   97,  0,  0, 98,  0,  0,  0,  0,  0,  0, 99,  0,  0,  0, 94,  0,
+    0,  0,  0,  0,  0,100,  0,  0,  0,  0,  0,  0,  0,101,  0,102,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  2,
+    3,  4,  5,  6,  7,  0,  8,  0,  0,  0,  0,  9, 10, 11, 12,  0,
+    0,  0,  0, 13,  0,  0, 14, 15,  0, 16,  0, 17, 18,  0,  0, 19,
+    0, 20, 21,  0,  0,  0,  0,  0, 22, 23,  0, 24, 25,  0,  0, 26,
+    0,  0,  0, 27, 28, 29,  0,  0,  0, 30, 31, 32,  0,  0, 31,  0,
+    0, 33, 31,  0,  0,  0, 31, 34,  0,  0,  0,  0,  0, 35, 36,  0,
+    0,  0,  0,  0,  0, 37, 38,  0,  0,  0,  0,  0,  0, 39, 40,  0,
+    0,  0,  0, 41,  0, 42,  0,  0,  0, 43, 44,  0,  0,  0, 45,  0,
+    0,  0,  0,  0,  0, 46, 47,  0,  0,  0,  0, 48,  0,  0,  0, 49,
+    0, 49,  0, 50,  0,  0,  0,  0, 51,  0,  0,  0,  0, 52,  0, 53,
+    0,  0,  0,  0, 54, 55,  0,  0,  0, 56,  0,  0,  0, 57, 49,  0,
+   58, 59,  0,  0, 60,  0,  0,  0, 61, 62,  0,  0,  0, 63,  0, 64,
+   65, 66, 67, 68,  1, 69,  0, 70, 71, 72,  0,  0, 73, 74,  0,  0,
+    0, 75,  0,  0,  1,  1,  0,  0, 76,  0,  0, 77,  0,  0,  0,  0,
+   73, 78,  0, 79,  0,  0,  0,  0,  0, 74, 80,  0,  0,  0, 49,  0,
+    1, 74,  0,  0, 81,  0,  0, 82,  0,  0,  0,  0,  0, 83, 54,  0,
+    0,  0,  0,  0,  0, 84, 85,  0,  0, 80,  0,  0, 31,  0,  0, 86,
+    0,  0,  0,  0, 87,  0,  0,  0,  0, 47,  0,  0, 88,  0,  0,  0,
+    0, 89, 90,  0,  0, 91,  0,  0, 92,  0,  0,  0, 93,  0, 94, 88,
+    0,  0, 80,  0,  0, 75,  0,  0,  0, 95, 96,  0,  0, 97, 98,  0,
+    0,  0,  0,  0,  0, 99,  0,  0,100,  0,  0,  0,  0,101, 31,  0,
+  102,103,104, 33,  0,  0,105,  0,  0,  0,106,  0,  0,  0,  0,  0,
+    0,107,  0,  0,108,  0,  0,  0, 54,  0,  0,  0,  0, 49,109,  0,
+    0,  0,  0,110,  0,  0,111,  0,  0,  0,  0,109,  0,  0,  0,  0,
+    0,112,  0,  0,  0,113,  0,114,  0,  0,  0,  0,115,116,117,  0,
+  118,  0,119,  0,  0,  0,120,121,122,  0,  0,  0,123,  0,  0,124,
+    0,  0,125,  0,  0,  0,  0,  0,  0,  0,  1,  1,  1,  1,  1,  2,
+    3,  4,  5,  6,  7,  4,  4,  8,  9, 10,  1, 11, 12, 13, 14, 15,
+   16, 17, 18,  1,  1,  1, 19,  1,  0,  0, 20, 21, 22,  1, 23,  4,
+   21, 24, 25, 26, 27, 28, 29, 30,  0,  0,  1,  1, 31,  0,  0,  0,
+   32, 33, 34, 35,  1, 36, 37,  0,  0,  0,  0, 38,  1, 39, 14, 39,
+   40, 41, 42,  0,  0,  0, 43, 36, 44, 45, 21, 45, 46,  0,  0,  0,
+   19,  1, 21,  0,  0, 47,  0, 38, 48,  1,  1, 49, 49, 50,  0,  0,
+   51,  0, 52,  1,  1,  1, 53, 21, 43, 54, 55, 21, 35,  1,  0,  0,
+    0, 56,  0,  0,  0, 57, 58, 59,  0,  0,  0,  0,  0, 60,  0, 61,
+    0,  0,  0,  0, 62, 63,  0,  0, 64,  0,  0,  0, 65,  0,  0,  0,
+   66,  0,  0,  0, 67,  0,  0,  0, 68,  0,  0,  0, 69,  0,  0, 70,
+   71,  0, 72, 73, 74, 75, 76, 77,  0,  0,  0, 78,  0,  0,  0, 79,
+   80,  0,  0,  0,  0, 47,  0,  0,  0, 49,  0, 63,  0,  0, 64,  0,
+    0, 81,  0,  0, 82,  0,  0,  0, 83,  0,  0, 19, 84,  0, 63,  0,
+    0,  0,  0, 49,  1, 85,  1, 54, 15, 41,  0, 56,  0,  0,  0,  0,
+   19, 10,  1,  0,  0,  0,  0,  0, 86,  0,  0, 87,  0,  0, 86,  0,
+    0,  0,  0, 79,  0,  0, 88,  9, 12,  4, 89,  8, 90, 47,  0, 59,
+   50,  0, 21,  1, 21, 91, 92,  1,  1,  1,  1, 93, 94, 95, 96,  1,
+   97, 59, 81, 98, 99,  4, 59,  0,  0,  0,  0,  0,  0, 19, 50,  0,
+    0,  0,  0,  0,  0, 62,  0,  0,100,101,  0,  0,102,  0,  0,  1,
+    1, 50,  0,  0,  0, 38,  0, 64,  0,  0,  0,  0, 52, 69, 62,  0,
+    0,  0, 79,  0,  0,  0,103,104, 59, 38, 81,  0,  0,  0,  0,  0,
+    0,105,  1, 14,  4, 12, 84,  0,  0,  0,  0, 38, 88,  0,  0,  0,
+    0,106,  0,  0,107, 62,  0,108,  0,  0,  0,  1,  0,  0,  0,109,
+   14, 54,  0,  0,110,  0, 88,  0,  0,  0, 62, 63,  0,  0, 63,  0,
+   87,  0,  0,110,  0,  0,  0,  0,111,  0,  0,  0, 79, 56,  0, 38,
+    1, 59,  1, 59,  0,  0, 64, 87,  0,  0,112,  0,  0,  0, 56,  0,
+    0,  0,  0,112,  0,  0,  0,  0, 62,  0,  0, 62,  0,  0,  0,  0,
+   57,  0, 87,113,  0,  0,  8, 90,  0,  0,  1, 88,  0,  0,  0,  0,
+    0,114,  0,115,116,117,118,  0, 52,  4,119, 49, 23,  0,  0,  0,
+   38, 50, 38, 59,  0,  0,  1, 88,  1,  1,  1,  1, 39,  1, 48,103,
+   88,  0,  0,  0,  0,  1,  4,119,  0,  0,  0,  1,120,  0,  0,  0,
+    0,  0,230,230,230,230,230,232,220,220,220,220,232,216,220,220,
+  220,220,220,202,202,220,220,220,220,202,202,220,220,220,  1,  1,
+    1,  1,  1,220,220,220,220,230,230,230,230,240,230,220,220,220,
+  230,230,230,220,220,  0,230,230,230,220,220,220,220,230,232,220,
+  220,230,233,234,234,233,234,234,233,230,  0,  0,  0,230,  0,220,
+  230,230,230,230,220,230,230,230,222,220,230,230,220,220,230,222,
+  228,230, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 19, 20, 21, 22,
+    0, 23,  0, 24, 25,  0,230,220,  0, 18, 30, 31, 32,  0,  0,  0,
+    0, 27, 28, 29, 30, 31, 32, 33, 34,230,230,220,220,230,220,230,
+  230,220, 35,  0,  0,  0,  0,  0,230,230,230,  0,  0,230,230,  0,
+  220,230,230,220,  0,  0,  0, 36,  0,  0,230,220,230,230,220,220,
+  230,220,220,230,220,230,220,230,230,  0,  0,220,  0,  0,230,230,
+    0,230,  0,230,230,230,230,230,  0,  0,  0,220,220,220,  0,  0,
+    0,220,230,230,  0,220,230,220,220,220, 27, 28, 29,230,  7,  0,
+    0,  0,  0,  9,  0,  0,  0,230,220,230,230,  0,  0,  0,  0,  0,
+  230,  0,  0, 84, 91,  0,  0,  0,  0,  9,  9,  0,  0,  0,  0,  0,
+    9,  0,103,103,  9,  0,107,107,107,107,118,118,  9,  0,122,122,
+  122,122,220,220,  0,  0,  0,220,  0,220,  0,216,  0,  0,  0,129,
+  130,  0,132,  0,  0,  0,  0,  0,130,130,130,130,  0,  0,130,  0,
+  230,230,  9,  0,230,230,  0,  0,220,  0,  0,  0,  0,  7,  0,  9,
+    9,  0,  0,230,  0,  0,  0,228,  0,  0,  0,222,230,220,220,  0,
+    0,  0,230,  0,  0,220,  0,  0,  9,  9,  0,  0,  7,  0,230,230,
+  230,  0,230,  0,  1,  1,  1,  0,  0,  0,230,234,214,220,202,230,
+  230,230,230,230,232,228,228,220,  0,230,233,220,230,220,230,230,
+    1,  1,  1,  1,  1,230,  0,  1,  1,230,220,230,  1,  1,  0,  0,
+  218,228,232,222,224,224,  0,  8,  8,  0,230,  0,230,230,220,  0,
+    0,230,  0,  0, 26,  0,  0,220,  0,230,230,  1,220,  0,  0,230,
+  220,  0,  0,  0,220,220,  0,  9,  7,  0,  0,  7,  9,  0,  0,  0,
+    9,  7,  9,  9,  0,  0,  0,  0,  1,  0,  0,216,216,  1,  1,  1,
+    0,  0,  0,226,216,216,216,216,216,  0,220,220,220,  0,230,230,
+    7,  0, 16, 17, 17, 33, 17, 49, 17, 17, 84, 97,135,145, 26, 17,
+   17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+   17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+   17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+   17,177,  0,  1,  2,  3,  3,  3,  3,  3,  3,  3,  3,  3,  3,  3,
+    3,  3,  3,  3,  3,  3,  4,  3,  3,  3,  3,  3,  5,  3,  3,  3,
+    3,  3,  6,  7,  8,  3,  3,  3,  3,  3,  9, 10, 11, 12, 13,  3,
+    3,  3,  3,  3,  3,  3,  3, 14,  3, 15,  3,  3,  3,  3,  3,  3,
+   16, 17, 18, 19, 20, 21,  3,  3,  3, 22, 23,  3,  3,  3,  3,  3,
+    3,  3, 24,  3,  3,  3,  3,  3,  3,  3,  3, 25,  3,  3, 26, 27,
+    0,  1,  0,  0,  0,  0,  0,  1,  0,  2,  0,  0,  0,  3,  0,  0,
+    0,  3,  0,  0,  0,  0,  0,  4,  0,  5,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  6,  0,  0,  0,  7,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  8,  9,  0,  0,  0,  0,  0,
+    0,  9,  0,  9,  0,  0,  0,  0,  0,  0,  0, 10, 11, 12, 13,  0,
+    0, 14, 15, 16,  6,  0, 17, 18, 19, 19, 19, 20, 21, 22, 23, 24,
+   19, 25,  0, 26, 27, 19, 19, 28, 29, 30,  0, 31,  0,  0,  0,  8,
+    0,  0,  0,  0,  0,  0,  0, 19, 28,  0, 32, 33,  9, 34, 35, 19,
+    0,  0, 36, 37, 38, 39, 40, 19,  0, 41, 42, 43, 44, 31,  0,  1,
+   45, 42,  0,  0,  0,  0,  0, 32, 14, 14,  0,  0,  0,  0, 14,  0,
+    0, 46, 47, 47, 47, 47, 48, 49, 47, 47, 47, 47, 50, 51, 52, 53,
+   43, 21,  0,  0,  0,  0,  0,  0,  0, 54,  6, 55,  0, 14, 19,  1,
+    0,  0,  0, 19, 56, 31,  0,  0,  0,  0,  0,  0,  0, 57, 14,  0,
+    0,  0,  0,  1,  0,  2,  0,  0,  0,  3,  0,  0,  0, 58, 59,  0,
+    0,  0,  0,  0,  0,  0,  1,  0,  0,  0,  0,  0,  2,  3,  0,  4,
+    5,  0,  0,  6,  0,  0,  0,  7,  0,  0,  0,  1,  1,  0,  0,  8,
+    9,  0,  8,  9,  0,  0,  0,  0,  8,  9, 10, 11, 12,  0,  0,  0,
+   13,  0,  0,  0,  0, 14, 15, 16, 17,  0,  0,  0,  1,  0,  0, 18,
+   19,  0,  0,  0, 20,  0,  0,  0,  1,  1,  1,  1,  0,  1,  1,  1,
+    1,  1,  1,  1,  0,  8, 21,  9,  0,  0, 22,  0,  0,  0,  0,  1,
+    0, 23, 24, 25,  0,  0, 26,  0,  0,  0,  8, 21, 27,  0,  1,  0,
+    0,  1,  1,  1,  1,  0,  1, 28, 29, 30,  0, 31, 32, 20,  1,  1,
+    0,  0,  0,  8, 21,  9,  1,  4,  5,  0,  0,  0, 33,  9,  0,  1,
+    1,  1,  0,  8, 21, 21, 21, 21, 34,  1, 35, 21, 21, 21,  9, 36,
+    0,  0, 37, 38,  1,  0, 39,  0,  0,  0,  1,  0,  1,  0,  0,  0,
+    0,  8, 21,  9,  1,  0,  0,  0, 40,  0,  8, 21, 21, 21, 21, 21,
+   21, 21, 21,  9,  0,  1,  1,  1,  1,  8, 21, 21, 21,  9,  0,  0,
+    0, 41,  0, 42, 43,  0,  0,  0,  1, 44,  0,  0,  0, 45,  8,  9,
+    1,  0,  1,  0,  1,  1,  8, 21, 21,  9,  0,  4,  5,  8,  9,  1,
+    0,  0,  0,  1,  2,  3,  4,  5,  6,  7,  7,  8,  7,  7,  7,  7,
+    7,  7,  7,  7,  7,  7,  9, 10, 11, 11, 11, 11, 11, 12, 12, 12,
+   12, 13, 14, 15, 16, 17, 18, 12, 19, 12, 20, 12, 12, 12, 12, 21,
+   22, 22, 22, 23, 12, 12, 12, 12, 24, 25, 12, 12, 26, 27, 28, 29,
+   30, 31,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,
+    7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7, 32,
+   12, 33, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
+   12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
+   12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
+   12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
+   12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
+   12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
+   12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
+   12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
+   12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
+   12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
+   12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
+   12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
+   12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
+   12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
+   12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
+   12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
+   12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
+   12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
+   12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
+   12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
+   12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
+   12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
+   12, 12, 34,  0,  0,  1,  2,  2,  2,  3,  4,  5,  6,  7,  8,  9,
+   10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25,
+   26, 27, 28, 29, 30, 31, 32, 32, 33, 33, 33, 34, 35, 35, 35, 35,
+   35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50,
+    2,  2, 51, 51, 52, 53, 54, 55, 56, 56, 56, 56, 56, 56, 56, 56,
+   56, 56, 56, 56, 57, 57, 56, 56, 56, 56, 56, 56, 58, 59, 60, 61,
+   56, 62, 62, 63, 64, 65, 66, 67, 68, 69, 70, 56, 62, 62, 62, 62,
+   62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62,
+   62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 71,
+   62, 62, 62, 62, 72, 72, 72, 72, 72, 72, 72, 72, 72, 73, 74, 74,
+   75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 32, 32, 32, 32,
+   32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+   32, 32, 32, 32, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87,
+   87, 87, 87, 87, 87, 87, 62, 62, 62, 62, 88, 89, 89, 89, 90, 89,
+   91, 92, 93, 94, 95, 95, 96, 97, 87, 98, 99,100,101,102,103, 87,
+  104,104,104, 87,105,106,107,108,109,110,111,112,113,114,115, 87,
+   89, 87,116,117,118,119,120,121,122,123,124, 87,125,126, 87,127,
+  128,129,130, 87,131,132, 87,133,134,135, 87, 87,136,137,138,139,
+   87,140, 87, 21,141,141,141,141,141,141,141,141,141,141,141, 87,
+   87, 87, 87, 87,142,142,142,142,142,142,142,142,142, 87, 87, 87,
+   87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87,143,143,143,143,
+  143, 87, 87, 87,144,144,144,144,145,146,147,147, 87, 87, 87, 87,
+  148,148,149,150,151,151,151,151,151,151,151,151,151,151,151,151,
+  151,151,151,151,151,151,151,151,151,151, 87, 87, 87, 87, 87, 87,
+   87, 87, 87, 87,152,153,154,155,155,155, 87, 87, 87, 87, 87, 87,
+   87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87,156,157, 87, 87,
+   87, 87, 87, 87, 56, 56,158,159, 51, 56, 56, 87, 56, 56, 56, 56,
+   56, 56, 56, 56,160,160,160,160,160,160, 87, 87, 87, 87, 87, 87,
+   87, 87, 87, 87,161, 87,162, 87, 87,163, 87, 87, 87, 87, 87, 87,
+   87, 87, 87, 87,164,164,165, 87, 87, 87, 87, 87, 56, 56, 56, 87,
+   89, 89, 87, 87, 56, 56, 56, 56,166, 87, 56, 56, 56, 56, 56, 56,
+   56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 87, 87, 87, 87, 87, 87,
+   87, 87, 87, 87, 62, 62, 62, 62, 62, 62, 62, 62, 87, 87, 87, 87,
+   87, 87, 87, 87, 62, 62, 62, 62, 62, 87, 87, 87, 87, 87, 87, 87,
+   87, 87, 87, 87, 56, 87,167,167,  0,  1,  2,  2,  0,  1,  2,  2,
+    2,  3,  4,  5,  0,  0,  0,  0,  1,  2,  1,  2,  0,  0,  3,  3,
+    4,  5,  4,  5,  4,  4,  4,  4,  4,  4,  4,  4,  4,  4,  4,  6,
+    0,  0,  7,  0,  8,  8,  8,  8,  8,  8,  8,  9, 10, 11, 11, 11,
+   11, 11, 12, 11, 13, 13, 13, 13, 13, 13, 13, 13, 14, 13, 13, 13,
+   13, 13, 13, 13, 13, 13, 13, 15, 16, 16, 16, 16, 17, 18, 19, 19,
+   19, 19, 19, 19, 20, 21, 22, 22, 23, 24, 22, 25, 22, 22, 22, 22,
+   22, 26, 22, 22, 27, 27, 27, 27, 27, 22, 22, 22, 28, 28, 28, 28,
+   29, 29, 29, 29, 30, 30, 30, 30, 31, 31, 27, 27, 22, 22, 22, 22,
+   22, 22, 32, 22, 33, 33, 33, 33, 33, 34, 35, 33, 36, 36, 36, 36,
+   36, 36, 36, 36, 37, 37, 37, 37, 37, 37, 37, 37, 38, 38, 38, 38,
+   38, 38, 38, 38, 39, 39, 39, 39, 39, 39, 39, 39, 40, 40, 40, 40,
+   40, 40, 40, 40, 41, 41, 41, 41, 41, 41, 41, 41, 42, 42, 42, 42,
+   42, 42, 42, 42, 43, 43, 43, 43, 43, 43, 43, 43, 44, 44, 44, 44,
+   44, 44, 44, 44, 45, 45, 45, 46, 45, 45, 45, 45, 47, 47, 47, 47,
+   47, 47, 47, 47, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48,
+   48, 49, 48, 48, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 51, 51,
+   51, 51, 51, 52, 53, 53, 53, 53, 53, 53, 53, 53, 54, 54, 54, 54,
+   54, 54, 54, 54, 54, 54, 55, 55, 55, 55, 55, 55, 56, 56, 56, 56,
+   56, 56, 56, 56, 57, 57, 58, 58, 58, 58, 59, 58, 60, 60, 61, 62,
+   63, 63, 64, 64, 65, 65, 65, 65, 65, 65, 65, 65, 66, 67, 67, 67,
+   67, 67, 67, 67, 67, 67, 67, 56, 56, 56, 56, 56, 68, 68, 68, 68,
+   68, 69, 69, 69, 70, 70, 70, 70, 70, 70, 65, 65, 71, 71, 72, 72,
+   72, 72, 72, 72, 72, 72, 72,  8,  8,  8,  8,  8, 73, 73, 73, 73,
+   73, 73, 73, 73, 74, 74, 74, 74, 75, 75, 75, 75, 76, 76, 76, 76,
+   76, 77, 77, 77, 13, 51, 51, 51, 74, 78, 79, 80,  4,  4, 81,  4,
+    4, 82, 83, 84,  4,  4,  4, 85,  8,  8,  8,  8, 11, 11, 11, 11,
+   11, 11, 11, 11, 86,  0,  0,  0,  0,  0,  0, 87,  0,  4,  0,  0,
+    0,  8,  8,  8,  0,  0, 88, 89, 90,  0,  4,  4,  6,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 91, 91, 91, 91,
+   91, 91, 91, 91, 92, 92, 92, 92, 92, 92,  4,  4, 93, 93, 93, 93,
+   93, 93, 93, 93, 51, 51, 51, 94, 94, 94, 94, 94, 54, 54, 54, 54,
+   54, 54, 13, 13, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95,
+   95, 95, 95,  0, 96,  0, 97, 98, 99,100,100,100,100,101,102,103,
+  103,103,103,104,105,105,105,106, 53, 53, 53, 53, 53,  0,105,105,
+    0,  0,  0,103, 53, 53,  0,  0,  0,  0, 53,107,  0,  0,  0,  0,
+    0,103,103,108,103,103,103,103,103,109,  0,  0, 95, 95, 95, 95,
+    0,  0,  0,  0,110,110,110,110,110,110,110,110,110,110,110,110,
+  110,111,111,111,112,112,112,112,112,112,112,112,112,112,112,112,
+   13, 13, 13, 13, 13, 13,113,113,113,113,113,113,  0,  0,114,  4,
+    4,  4,  4,  4,115,  4,  4,  4,  4,  4,  4,  4,116,116,116,  0,
+  117,117,117,117,118,118,118,118,118,118, 33, 33,119,119,120,121,
+  121,121, 53, 53,122,122,122,122,123,122, 50, 50,124,124,124,124,
+  124,124, 50, 50,125,125,125,125,125,125,126,126, 54, 54, 54,  4,
+    4,127,128, 55, 55, 55, 55, 55,126,126,126,126,129,129,129,129,
+  129,129,129,129,  4,130, 19, 19, 19, 22, 22, 22, 22, 22, 22, 22,
+   22, 22, 22, 22, 22, 22, 22,131,  0, 22, 22, 22,  8,  0,132,  0,
+    0,  0,  0, 22, 22, 22, 22, 22, 22, 22, 22,133,  0,  0,  1,  2,
+    1,  2,134,102,103,135, 53, 53, 53, 53,  0,  0,136,136,136,136,
+  136,136,136,136,  0,  0,  0,  0, 11, 11, 11, 11, 11,  0, 11, 11,
+   11,  0,  0,137,138,138,139,139,139,139,140,  0,141,141,141,142,
+  142,143,143,143,144,144,145,145,145,145,145,145,146,146,146,146,
+  146,147,147,147,148,148,148,149,149,149,149,149,150,150,150,151,
+  151,151,151,151,152,152,152,152,152,152,152,152,153,153,153,153,
+  154,154,155,155,156,156,156,156,156,156,157,157,158,158,159,159,
+  159,159,159,159,160,160,161,161,161,161,161,161,162,162,162,162,
+  162,162,163,163,164,164,164,164,165,165,165,165,166,166,166,166,
+  167,167,168,168,169,169,169,169,169,169,169,169,170,170,170,170,
+  170,170,170,170,171,171,171,171,171,171,171,171,172,172,172,172,
+  172,172,172,172,173,173,173,174,174,174,174,174,175,175,175,175,
+  175,175,175,175,176,176,176,176,176,176,176,176,177,177,177,177,
+  177,178,178,178,179,179,179,179,179,180,180,180,181,181,181,181,
+  181,181,182, 44,183,183,183,183,183,183,183,183,184,184,184,185,
+  185,185,185,185,186,186,186,187,186,186,186,186,188,188,188,188,
+  188,188,188,188,189,189,189,189,189,189,189,189,190,190,190,190,
+  190,190,190,190,191,191,191,191,191,191, 67, 67,192,192,192,192,
+  192,192,192,192,193,193,193,193,193,193,193,193,194,194,194,194,
+  194,194,194,194,195,195,195,195,195,195,195,195,196,196,196,196,
+  196,196,196,196,197,197,197,197,197,198,198,198,198,198,198,198,
+  199,199,199,199,200,200,200,200,200,200,200,201,201,201,201,201,
+  201,201,201,201,202,202,202,202,202,202,203,203,203,203,203,203,
+  203,203,203,203,204,204,204,204,204,204,204,204,205,205,205,205,
+  205,205,205,205,206,206,206,206,206,206,206,206,207,207,207,207,
+  207,207,207,207,113,113,113,113,113,113,113,113,113,113,113,113,
+  208,208,208,208,209,209,209,209,209,209,209,209,210,210,210,210,
+  210,210,210,210,211,211,211,211,211,211,211,211,212,212,212,212,
+  212,212,212,212,212,212,212,212,212,212,213,  0,214,214,214,214,
+  214,214,214,214,215,100,100,100,100,100,100,100,100,100,100,100,
+  100,100,100,100,100,100,100,100,100,100,216,217,217,217,217,217,
+  217,217,217,217,218,218,218,218,218,218,218,218,218,218,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,219,220,221,  0,222,  0,
+    0,  0,  0,  0,223,223,223,223,223,223,223,223, 92, 92, 92, 92,
+   92, 92, 92, 92,224,224,224,224,224,224,224,224,225,225,225,225,
+  225,225,225,225,226,226,226,226,226,226,226,226,227,227,227,227,
+  227,227,227,227,228,  0,  0,  0,  0,  0,  0,  0,  8,  8,  8,  8,
+    8,  8,  8,  8,  0,  0,  0,  0,  1,  2,  2,  2,  2,  2,  3,  0,
+    0,  0,  4,  0,  2,  2,  2,  2,  2,  3,  2,  2,  2,  2,  5,  0,
+    2,  5,  6,  0,  7,  7,  7,  7,  8,  9,  8, 10,  8, 11,  8,  8,
+    8,  8,  8,  8, 12, 13, 13, 13, 14, 14, 14, 14, 14, 15, 14, 14,
+   16, 17, 17, 17, 17, 17, 17, 17, 17, 17, 18, 17, 19, 20, 20, 20,
+   20, 20, 20, 20, 21, 22, 21, 23, 21, 21, 24, 24, 21, 21, 21, 21,
+   23, 21, 25,  7,  7, 26, 21, 21, 27, 21, 21, 21, 21, 21, 21, 22,
+   28, 28, 28, 28, 29, 29, 29, 29, 30, 30, 30, 30, 31, 31, 31, 31,
+   32, 32, 32, 32, 33, 21, 21, 21, 34, 34, 34, 34, 35, 36, 34, 34,
+   34, 37, 34, 34, 38, 38, 38, 38, 39, 39, 39, 39, 40, 40, 40, 40,
+   41, 41, 41, 41, 42, 42, 42, 42, 43, 43, 43, 43, 44, 44, 44, 44,
+   45, 45, 45, 45, 46, 46, 46, 46, 47, 47, 47, 47, 47, 47, 47, 48,
+   49, 49, 49, 49, 50, 50, 50, 50, 50, 51, 52, 50, 53, 53, 53, 53,
+   54, 54, 54, 54, 54, 54, 55, 54, 56, 56, 56, 56, 57, 57, 57, 57,
+   58, 58, 58, 58, 59, 59, 59, 59, 60, 60, 60, 60, 61, 61, 61, 61,
+   61, 61, 62, 63, 64, 64, 64, 64, 65, 65, 65, 65, 65, 66,  0,  0,
+   67, 67, 67, 67, 68, 68, 68, 68, 69, 69, 69, 69, 70, 71, 72, 72,
+   72, 72, 72, 72, 73, 73, 73, 73, 74, 74, 74, 74, 75, 75, 75, 75,
+   76, 76, 76, 76, 77, 77, 77, 77, 78, 78, 78, 78, 79, 79, 79, 79,
+   80, 80, 80, 80, 81, 81, 81, 81, 82, 82, 82, 82, 83,  7,  7,  7,
+   84,  7, 85, 86,  0, 85, 87,  0,  2, 88, 89,  2,  2,  2,  2, 90,
+   91, 88, 92,  2,  2,  2, 93,  2,  2,  2,  2, 94,  0,  0,  0, 87,
+    1,  0,  0, 95,  0, 96, 97,  0,  4,  0,  0,  0,  0,  0,  0,  4,
+   98, 98, 98, 98, 99, 99, 99, 99, 13, 13, 13, 13,100,100,100,100,
+  101,101,101,101,  0,102,  0,  0,103,101,104,105,  0,  0,101,  0,
+  106,107,107,107,107,107,107,107,107,107,108,106,109,110,110,110,
+  110,110,110,110,110,110,111,109,112,112,112,112,113, 56, 56, 56,
+   56, 56, 56,114,110,110,110,111,110,110,  0,  0,115,115,115,115,
+  116,116,116,116,117,117,117,117,118,118,118,118, 97,  2,  2,  2,
+    2,  2, 95,  2,119,119,119,119,120,120,120,120,121,121,121,121,
+  122,122,122,122,122,122,122,123,124,124,124,124,125,125,125,125,
+  125,125,125,126,127,127,127,127,128,128,128,128,129,129,129,129,
+    2,  2,  3,  2,  2,130,  2,  2,131,131,131,131,132, 17, 17, 19,
+   21, 21, 21,133,  7,  7,  7,134, 21, 21, 21, 24,  0,135,110,110,
+  110,110,110,136,137,137,137,137,  0,  0,  0,138,139,139,139,139,
+  140,140,140,140, 85,  0,  0,  0,141,141,141,141,142,142,142,142,
+  143,143,143,143,144,144,144,144,145,145,145,145,146,146,146,146,
+  147,147,147,147,148,148,148,148,149,149,149,149,150,150,150,150,
+  151,151,151,151,152,152,152,152,153,153,153,153,154,154,154,154,
+  155,155,155,155,156,156,156,156,157,157,157,157,158,158,158,158,
+  159,159,159,159,160,160,160,160,161,161,161,161,162,162,162,162,
+  163,163,163,163,164,164,164,164,165,165,165,165,166,166,166,166,
+  167,167,167,167,168,168,168,168,169,169,169,169,170,170,170,170,
+  171,171,171,171,172,172,172,172,173,173,173,173,174,174,174,174,
+  175,175,175,175,176,176,176,176,177,177,177,177,178,178,178,178,
+  179,179,179,179,180,180,180,180,181,181,181,181,182, 46, 46, 46,
+  183,183,183,183,184,184,184,184,185,185,185,185,186,186,186,186,
+  186,186,187,186,188,188,188,188,189,189,189,189,190,190,190,190,
+  191,191,191,191,192,192,192,192,193,193,193,193,194,194,194,194,
+  195,195,195,195,196,196,196,196,197,197,197,197,198,198,198,198,
+  199,199,199,199,200,200,200,200,201,201,201,201,202,202,202,202,
+  203,203,203,203,204,204,204,204,205,205,205,205,206,206,206,206,
+  207,207,207,207,208,208,208,208,209,209,209,209,210,210,210,210,
+  211,211,211,211,212,212,212,212,213,  0,  0,  0,214,214,214,214,
+  215,107,107,107,107,110,110,110,216,216,216,216,217,217,217,217,
+    0,218, 87,  0,  0,  0,218,  7, 83,138,  7,  0,  0,  0,219, 87,
+  220,220,220,220,221,221,221,221,222,222,222,222,223,223,223,223,
+  224,224,224,224,225,  0,  0,  0,  0,  0,  0,  0,  0, 19, 19, 19,
+   19, 19, 19, 19, 19, 19, 19,  0,  0,  0, 19,  0, 19,  0,  0,  0,
+    0,  0, 26, 26,  1,  1,  1,  1,  9,  9,  9,  9,  0,  9,  9,  9,
+    9,  9,  0,  9,  9,  0,  9,  0,  9,  9, 55, 55, 55, 55, 55, 55,
+    6,  6,  6,  6,  6,  1,  1,  6,  6,  4,  4,  4,  4,  4,  4,  4,
+    4,  0,  4,  4,  4, 14, 14, 14, 14, 14, 14, 14,  3,  3,  3,  3,
+    3,  0,  3,  3,  0,  3,  3,  3,  3,  3,  3,  0,  3,  3,  3,  1,
+    1,  1,  3,  3,  1,  3,  3,  3, 37, 37, 37, 37, 38, 38, 38, 38,
+   64, 64, 64, 64, 90, 90, 90, 90, 95, 95, 95, 95,  3,  3,  0,  3,
+    7,  7,  7,  7,  7,  1,  1,  1,  1,  7,  7,  7,  0,  0,  7,  7,
+    5,  5,  5,  5, 11, 11, 11, 11, 10, 10, 10, 10, 21, 21, 21, 21,
+   22, 22, 22, 22, 23, 23, 23, 23, 16, 16, 16, 16, 20, 20, 20, 20,
+   36, 36, 36, 36, 24, 24, 24, 24, 24, 24, 24,  0, 18, 18, 18, 18,
+   25, 25, 25, 25, 25,  0,  0,  0,  0, 25, 25, 25, 33, 33, 33, 33,
+    8,  8,  8,  8,  8,  8,  8,  0, 12, 12, 12, 12, 30, 30, 30, 30,
+   29, 29, 29, 29, 28, 28, 28, 28, 34, 34, 34, 34, 35, 35, 35, 35,
+   35, 35, 35,  0,  0,  0, 35, 35, 45, 45, 45, 45, 44, 44, 44, 44,
+   44,  0,  0,  0, 43, 43, 43, 43, 46, 46, 46, 46, 31, 31, 31, 31,
+   32, 32,  0,  0, 32,  0, 32, 32, 32, 32, 32, 32, 48, 48, 48, 48,
+   52, 52, 52, 52, 58, 58, 58, 58, 54, 54, 54, 54, 91, 91, 91, 91,
+   62, 62, 62, 62, 76, 76, 76, 76, 93, 93, 93, 93, 70, 70, 70, 70,
+   73, 73, 73, 73,  1,  1,  1,  0,  1,  0,  1,  1,  1,  0,  0,  0,
+    0,  1,  0,  0,  1,  1,  0,  0, 19, 19,  9,  9,  9,  9,  9,  6,
+   19,  9,  9,  9,  9,  9, 19, 19,  9,  9,  9, 19,  6, 19, 19, 19,
+   19, 19, 19,  9,  0,  0,  0, 19,  0,  0,  9,  0,  0,  0, 19, 19,
+   27, 27, 27, 27, 56, 56, 56, 56, 61, 61, 61, 61, 13, 13, 13, 13,
+    0, 13,  0, 13,  0, 13, 13, 13, 13, 13,  1,  1,  1,  1, 12, 12,
+    0, 15, 15, 15, 15, 15, 15, 15, 15,  1,  1,  0,  0, 17, 17, 17,
+   17, 17, 17, 17, 17, 17, 17,  0, 26, 26, 26, 26, 26, 12, 12, 12,
+   12, 12, 12,  0, 39, 39, 39, 39, 86, 86, 86, 86, 77, 77, 77, 77,
+   79, 79, 79, 79, 60, 60, 60, 60, 65, 65, 65, 65, 75, 75, 75, 75,
+   69, 69, 69, 69, 69, 69,  0, 69, 74, 74, 74, 74, 84, 84, 84, 84,
+   84, 84, 84,  0, 68, 68, 68, 68, 92, 92, 92, 92, 87, 87, 87, 87,
+   19,  9, 19, 19,  2,  2,  2,  2, 19, 19, 19,  4,  3,  3,  0,  0,
+    1,  1,  6,  6,  0,  0, 17, 17, 17, 17,  0,  0, 49, 49, 49, 49,
+    0,  1,  1,  1, 71, 71, 71, 71, 67, 67, 67, 67, 42, 42, 42, 42,
+   41, 41, 41, 41,118,118,118,118, 53, 53, 53, 53, 59, 59, 59, 59,
+   40, 40, 40, 40, 51, 51, 51, 51, 50, 50, 50, 50,135,135,135,135,
+  106,106,106,106,104,104,104,104,110,110,110,110, 47, 47, 47, 47,
+   81, 81, 81, 81,120,120,120,120,116,116,116,116,128,128,128,128,
+   66, 66, 66, 66, 72, 72, 72, 72, 98, 98, 98, 98, 97, 97, 97, 97,
+   57, 57, 57, 57, 88, 88, 88, 88,117,117,117,117,112,112,112,112,
+   78, 78, 78, 78, 83, 83, 83, 83, 82, 82, 82, 82,122,122,122,122,
+   89, 89, 89, 89,130,130,130,130,144,144,144,144,147,147,147,147,
+  148,148,148,148,149,149,149,149, 94, 94, 94, 94, 85, 85, 85, 85,
+  101,101,101,101, 96, 96, 96, 96,111,111,111,111,100,100,100,100,
+  100, 36, 36, 36,108,108,108,108,129,129,129,129,109,109,109,109,
+  107,107,107,107,107,107,107,  1,137,137,137,137,124,124,124,124,
+  123,123,123,123,114,114,114,114,102,102,102,102,126,126,126,126,
+  142,142,142,142,125,125,125,125,150,150,150,150,141,141,141,141,
+  140,140,140,140,121,121,121,121,133,133,133,133,134,134,134,134,
+  138,138,138,138,143,143,143,143,145,145,145,145, 63, 63, 63, 63,
+   80, 80, 80, 80,127,127,127,127,115,115,115,115,103,103,103,103,
+  119,119,119,119,146,146,146,146, 99, 99, 99, 99,136,139,  0,  0,
+  136,136,136,136, 17, 15, 15, 15,139,139,139,139,105,105,105,105,
+    0,  0,  0,  1,  0,  0,  1,  1,131,131,131,131,151,151,151,151,
+  152,152,152,152,113,113,113,113,132,132,132,132, 15,  0,  0,  0,
+   16, 50, 84,118, 88, 89, 90, 85, 85, 85, 85, 85, 85, 85, 85, 85,
+   85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 91,
+   85, 85,220, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85,
+   85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 94, 85, 85, 85, 85, 85,
+   85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85,
+   85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 15,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  2,  3,  4,
+    5,  6,  7,  8,  9, 10, 11, 12,  0,  0, 13, 14, 15, 16, 17, 18,
+   19, 20, 21, 22,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0, 23,  0,  0, 24, 25, 26, 27, 28, 29, 30,  0,  0,
+   31, 32,  0, 33,  0, 34,  0, 35,  0,  0,  0,  0, 36, 37, 38, 39,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0, 40,  0,  0,  0,  0,  0,  0,  0,  0,  0, 41, 42,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0, 43, 44,  0, 45,  0,  0,  0,  0,  0,  0, 46, 47,  0,  0,
+    0,  0,  0, 48,  0, 49,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0, 50, 51,  0,  0,  0, 52,  0,  0, 53,  0,  0,  0,
+    0,  0,  0,  0, 54,  0,  0,  0,  0,  0,  0,  0, 55,  0,  0,  0,
+    0,  0,  0,  0, 56,  0,  0,  0,  0,  0,  0,  0,  0, 57,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0, 58, 59, 60, 61, 62, 63, 64, 65,  0,  0,  0,  0,
+    0,  0, 66,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+   67, 68,  0, 69, 70,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+   71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86,
+   87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99,100,101,102,
+  103,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,104,  0,  0,  0,  0,  0,  0,105,106,  0,107,  0,  0,  0,
+  108,  0,109,  0,110,  0,111,112,113,  0,114,  0,  0,  0,115,  0,
+    0,  0,116,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,117,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,118,119,120,121,  0,122,123,124,125,126,  0,127,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+  128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,
+  144,145,146,147,148,149,150,151,152,153,154,155,156,157,  0,  0,
+    0,158,159,160,161,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,162,163,  0,  0,  0,  0,  0,
+    0,  0,164,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,165,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,166,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,167,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,168,169,  0,  0,  0,  0,170,171,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+  172,173,174,175,176,177,178,179,180,181,182,183,184,185,186,187,
+  188,189,190,191,192,193,194,195,196,197,198,199,200,201,202,203,
+  204,205,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  2,  3,  4,
+};
+static const uint16_t
+_hb_ucd_u16[4800] =
+{
+     0,   0,   1,   2,   3,   4,   5,   6,   0,   0,   7,   8,   9,  10,  11,  12,
+    13,  13,  13,  14,  15,  13,  13,  16,  17,  18,  19,  20,  21,  22,  13,  23,
+    13,  13,  13,  24,  25,  11,  11,  11,  11,  26,  11,  27,  28,  29,  30,  31,
+    32,  32,  32,  32,  32,  32,  32,  33,  34,  35,  36,  11,  37,  38,  13,  39,
+     9,   9,   9,  11,  11,  11,  13,  13,  40,  13,  13,  13,  41,  13,  13,  13,
+    13,  13,  13,  35,   9,  42,  11,  11,  43,  44,  32,  45,  46,  47,  47,  48,
+    49,  50,  47,  47,  51,  32,  52,  53,  47,  47,  47,  47,  47,  54,  55,  56,
+    57,  58,  47,  32,  59,  47,  47,  47,  47,  47,  60,  53,  61,  47,  62,  63,
+    47,  64,  65,  66,  47,  67,  47,  47,  47,  47,  47,  47,  47,  68,  69,  32,
+    70,  47,  47,  71,  72,  73,  74,  75,  76,  47,  47,  77,  78,  79,  80,  81,
+    82,  47,  47,  83,  84,  85,  86,  87,  82,  47,  47,  77,  88,  47,  80,  89,
+    90,  47,  47,  91,  92,  93,  80,  94,  95,  47,  47,  96,  97,  98,  99, 100,
+   101,  47,  47, 102, 103, 104,  80, 105, 106,  47,  47,  91, 107, 108,  80, 109,
+    90,  47,  47, 110, 111, 112,  80, 113, 114,  47,  47,  47, 115, 116,  99, 117,
+    47,  47,  47, 118, 119, 120,  66,  66,  47,  47,  47, 121, 122, 123,  47,  47,
+   124, 125, 126, 127,  47,  47,  47, 128, 129,  32,  32, 130, 131, 132,  66,  66,
+    47,  47, 133, 134, 120, 135, 136, 137, 138, 139,   9,   9,   9,  11,  11, 140,
+    47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47,  47, 141, 142, 143,
+    47, 144,   9,   9,   9,   9,   9, 145, 146,  47,  47,  47,  47,  47,  47,  47,
+    47,  47,  47,  47,  47,  47, 147,  47, 148, 149,  47,  47,  47,  47, 150, 151,
+    47, 152,  47, 153,  47, 152,  47, 152,  47,  47,  47, 154, 155, 156, 157, 143,
+   158, 157,  47,  47, 159,  47,  47,  47, 160,  47, 161,  47,  47,  47,  47,  47,
+    47,  47, 162, 163, 164,  47,  47,  47,  47,  47,  47,  47,  47, 165, 144, 144,
+    47, 166,  47,  47,  47, 167, 168, 169, 157, 157, 170, 171, 172, 172, 172, 172,
+   173,  47,  47, 174, 175, 120, 176, 177, 178,  47, 179,  61,  47,  47, 180, 181,
+    47,  47, 182, 183, 184,  61,  47, 185,  11,   9,   9,   9,  66, 186, 187, 188,
+    11,  11, 189,  27,  27,  27, 190, 191,  11, 192,  27,  27,  32,  32,  32,  32,
+    13,  13,  13,  13,  13,  13,  13,  13,  13, 193,  13,  13,  13,  13,  13,  13,
+   194, 194, 194, 194, 194, 195, 194,  11, 196, 196, 196, 197, 198, 199, 199, 198,
+   200, 201, 202, 203, 204, 205, 206, 207, 208,  27, 209, 209, 209, 210, 211,  32,
+   212, 213, 214, 215, 216, 143, 217, 217, 218, 219, 220, 144, 221, 222, 144, 223,
+   224, 224, 224, 224, 224, 224, 224, 224, 225, 144, 226, 144, 144, 144, 144, 227,
+   144, 228, 224, 229, 144, 230, 231, 144, 144, 144, 144, 144, 144, 144, 143, 143,
+   143, 232, 144, 144, 144, 144, 233, 143, 144, 144, 144, 144, 144, 144, 144, 144,
+   144, 144, 144, 234, 235, 144, 144, 236, 144, 144, 144, 144, 144, 144, 237, 144,
+   144, 144, 144, 144, 144, 144, 238, 239, 143, 240, 144, 144, 241, 224, 242, 224,
+   243, 244, 224, 224, 224, 245, 224, 246, 144, 144, 144, 224, 247, 144, 144, 144,
+     9,   9,   9,  11,  11,  11, 248, 249,  13,  13,  13,  13,  13,  13, 250, 251,
+    11,  11,  11,  47,  47,  47, 252, 253,  47,  47,  47,  47,  47,  47,  32,  32,
+   254, 255, 256, 257, 258,  66,  66,  66, 259, 260, 261, 262, 263,  47,  47,  47,
+    47, 264, 146,  47,  47,  47,  47, 265,  47, 266,  47,  47, 144, 144, 144,  47,
+   144, 144, 267, 144, 268, 269, 144, 144, 267, 144, 144, 269, 144, 144, 144, 144,
+    47,  47,  47,  47, 144, 144, 144, 144,  47, 270,  47,  47,  47,  47,  47,  47,
+    47, 144, 144, 144, 144,  47,  47, 185, 271,  47,  61,  47,  13,  13, 272, 273,
+    13, 274,  47,  47,  47,  47, 275, 276,  31, 277, 278, 279,  13,  13,  13, 280,
+   281, 282, 283, 284, 285,   9,   9, 286, 287,  47, 288, 289,  47,  47,  47, 290,
+   291,  47,  47, 292, 293, 157,  32, 294,  61,  47, 295,  47, 296, 297,  47,  47,
+    70,  47,  47, 298, 299, 300, 301,  61,  47,  47, 302, 303, 304, 305,  47, 306,
+    47,  47,  47, 307,  58, 308, 309, 310,  47,  47,  47,  11,  11, 311,  11,  11,
+    11,  11,  11,  11,  47,  47, 312, 157, 313, 313, 313, 313, 313, 313, 313, 313,
+   314, 314, 314, 314, 314, 314, 314, 314,  11, 315, 316,  47,  47,  47,  47,  47,
+    47,  47,  47, 317,  31, 318,  47,  47,  47,  47,  47, 319, 320,  47,  47,  47,
+    47,  47,  47,  47,  47,  47,  47, 321,  32, 322,  32, 323, 324, 325, 326,  47,
+    47,  47,  47,  47,  47,  47,  47, 327, 328,   2,   3,   4,   5, 329, 330, 331,
+    47, 332,  47,  47,  47,  47, 333, 334, 335, 143, 143, 336, 217, 217, 217, 337,
+   338, 144, 144, 144, 144, 144, 144, 339, 340, 340, 340, 340, 340, 340, 340, 340,
+    47,  47,  47,  47,  47,  47, 341, 143,  47,  47, 342,  47, 343,  47,  47,  60,
+    47, 344,  47,  47,  47, 345, 217, 217,   9,   9, 145,  11,  11,  47,  47,  47,
+    47,  47, 157,   9,   9, 145,  11,  11,  47,  47,  47,  47,  47,  47, 344,  66,
+    47,  47,  47,  47,  47, 346,  47, 347,  47,  47, 348, 143, 143, 143,  47, 349,
+    47, 350,  47, 344,  66,  66,  66,  66,  47,  47,  47, 351, 143, 143, 143, 143,
+   352,  47,  47, 353, 143,  66,  47, 354,  47, 355, 143, 143, 356,  47, 357,  66,
+    47,  47,  47, 358,  47, 359,  47, 359,  47, 358, 142, 143, 143, 143, 143, 143,
+     9,   9,   9,   9,  11,  11,  11, 360,  47,  47, 361, 157, 157, 157, 157, 157,
+   143, 143, 143, 143, 143, 143, 143, 143,  47, 355, 362,  47,  60, 363,  66,  66,
+   364,  47,  47, 353, 365, 366, 367, 368, 178,  47,  47, 369, 370,  47,  47, 157,
+    95,  47, 371, 372, 373,  47,  47, 374, 178,  47,  47, 375, 376, 377, 378, 143,
+    47,  47, 379, 380,  32,  32,  32,  32,  47,  47, 358,  47,  47, 381, 169, 157,
+    90,  47,  47, 110, 382, 383, 384,  32,  47,  47,  47, 385, 386, 387,  47,  47,
+    47,  47,  47, 388, 389, 157, 157, 157,  47,  47, 390, 391, 392, 393,  32,  32,
+    47,  47,  47, 394, 395, 157,  66,  66,  47,  47, 396, 397, 157, 157, 157, 157,
+    47, 141, 398, 399, 144, 144, 144, 144,  47,  47, 379, 400,  66,  66,  66,  66,
+     9,   9,   9,   9,  11,  11, 126, 401,  47,  47,  47,  47,  47, 402, 403, 404,
+   405,  47,  47, 406, 407, 408,  47,  47, 409, 410,  66,  66,  47,  47,  47,  47,
+    47,  47, 390, 411, 412, 126, 143, 413,  47, 152, 414, 415,  32,  32,  32,  32,
+    47,  47,  47, 352, 416, 157,  47,  47, 417, 418, 157, 157, 157, 157, 157, 157,
+    47,  47,  47,  47,  47,  47,  47, 419, 143, 143, 143, 143, 143, 420, 421, 422,
+   217, 217, 217, 217, 217, 217, 217,  66,  47,  47,  47, 206, 206, 206, 206, 206,
+    47,  47,  47,  47,  47,  47, 300,  66,  47,  47,  47,  47,  47,  47,  47, 423,
+    47,  47,  47, 424, 425, 426, 427,  47,   9,   9,   9,   9,   9,   9,  11,  11,
+   143, 428,  66,  66,  66,  66,  66,  66,  47,  47,  47,  47, 381, 429, 404, 404,
+   430, 431,  27,  27,  27,  27, 432,  27,  47, 433, 206, 206, 206, 206, 206, 206,
+   144, 144, 144, 144, 144, 144, 434, 435, 436, 144, 437, 144, 144, 144, 144, 144,
+   144, 144, 144, 144, 438, 144, 144, 144,   9, 439,  11, 440, 441,  11, 194,   9,
+   442, 443,   9, 444,  11,   9, 439,  11, 440, 441,  11, 194,   9, 442, 443,   9,
+   444,  11,   9, 439,  11, 440, 441,  11, 194,   9, 442, 443,   9, 444,  11,   9,
+   439,  11, 194,   9, 445, 446, 447, 448,  11, 449,   9, 450, 451, 452, 453,  11,
+   454,   9, 455,  11, 456, 157, 157, 157,  32,  32,  32, 457,  32,  32, 458, 459,
+   460, 461,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,
+    47,  47,  47, 462, 463, 144, 144, 144,  47,  47,  47,  47,  47,  47, 464, 465,
+    47,  47,  47,  47, 348,  32,  32,  32,   9,   9, 442,  11, 466, 300,  66,  66,
+   143, 143, 467, 468, 143, 143, 143, 143, 143, 143, 469, 143, 143, 143, 143, 143,
+    47,  47,  47,  47,  47,  47,  47, 224, 143, 144, 144, 144, 144, 144, 144, 144,
+   144, 144, 144, 144, 144, 144, 144, 470, 206, 206, 206, 206, 206, 206, 206, 206,
+     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+   939, 940, 941, 942, 946, 948,   0, 962, 969, 970, 971, 976,1001,1002,1003,1008,
+     0,1033,1040,1041,1042,1043,1047,   0,   0,1080,1081,1082,1086,1110,   0,   0,
+  1124,1125,1126,1127,1131,1133,   0,1147,1154,1155,1156,1161,1187,1188,1189,1193,
+     0,1219,1226,1227,1228,1229,1233,   0,   0,1267,1268,1269,1273,1298,   0,1303,
+   943,1128, 944,1129, 954,1139, 958,1143, 959,1144, 960,1145, 961,1146, 964,1149,
+     0,   0, 973,1158, 974,1159, 975,1160, 983,1168, 978,1163, 988,1173, 990,1175,
+   991,1176, 993,1178, 994,1179,   0,   0,1004,1190,1005,1191,1006,1192,1014,1199,
+  1007,   0,   0,   0,1016,1201,1020,1206,   0,1022,1208,1025,1211,1023,1209,   0,
+     0,   0,   0,1032,1218,1037,1223,1035,1221,   0,   0,   0,1044,1230,1045,1231,
+  1049,1235,   0,   0,1058,1244,1064,1250,1060,1246,1066,1252,1067,1253,1072,1258,
+  1069,1255,1077,1264,1074,1261,   0,   0,1083,1270,1084,1271,1085,1272,1088,1275,
+  1089,1276,1096,1283,1103,1290,1111,1299,1115,1118,1307,1120,1309,1121,1310,   0,
+  1053,1239,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,1093,
+  1280,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0, 949,1134,1010,
+  1195,1050,1236,1090,1277,1341,1368,1340,1367,1342,1369,1339,1366,   0,1320,1347,
+  1418,1419,1323,1350,   0,   0, 992,1177,1018,1204,1055,1241,1416,1417,1415,1424,
+  1202,   0,   0,   0, 987,1172,   0,   0,1031,1217,1321,1348,1322,1349,1338,1365,
+   950,1135, 951,1136, 979,1164, 980,1165,1011,1196,1012,1197,1051,1237,1052,1238,
+  1061,1247,1062,1248,1091,1278,1092,1279,1071,1257,1076,1263,   0,   0, 997,1182,
+     0,   0,   0,   0,   0,   0, 945,1130, 982,1167,1337,1364,1335,1362,1046,1232,
+  1422,1423,1113,1301,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+     8,   9,   0,  10,1425,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+     0,   0,   0,   0,   7,   0,   0,   0,   0,   0,   0,   0,   0,   0,   1,   0,
+     0,   0,   0,   0,   0,1314,1427,   5,1434,1438,1443,   0,1450,   0,1455,1461,
+  1514,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,1446,1458,1468,1476,1480,1486,
+  1517,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,1489,1503,1494,1500,1508,   0,
+     0,   0,   0,1520,1521,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+  1526,1528,   0,1525,   0,   0,   0,1522,   0,   0,   0,   0,1536,1532,1539,   0,
+     0,   0,   0,   0,   0,   0,   0,   0,   0,1534,   0,   0,   0,   0,   0,   0,
+     0,   0,   0,   0,   0,   0,   0,   0,   0,1556,   0,   0,   0,   0,   0,   0,
+  1548,1550,   0,1547,   0,   0,   0,1567,   0,   0,   0,   0,1558,1554,1561,   0,
+     0,   0,   0,   0,   0,   0,1568,1569,   0,   0,   0,   0,   0,   0,   0,   0,
+     0,1529,1551,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+  1523,1545,1524,1546,   0,   0,1527,1549,   0,   0,1570,1571,1530,1552,1531,1553,
+     0,   0,1533,1555,1535,1557,1537,1559,   0,   0,1572,1573,1544,1566,1538,1560,
+  1540,1562,1541,1563,1542,1564,   0,   0,1543,1565,   0,   0,   0,   0,   0,   0,
+     0,   0,1606,1607,1609,1608,1610,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+  1613,   0,1611,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+     0,   0,   0,1612,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+     0,   0,   0,   0,   0,   0,   0,   0,   0,1620,   0,   0,   0,   0,   0,   0,
+     0,1623,   0,   0,1624,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+     0,   0,   0,   0,   0,   0,   0,   0,1614,1615,1616,1617,1618,1619,1621,1622,
+     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,1628,1629,   0,   0,   0,
+     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,1625,1626,   0,1627,
+     0,   0,   0,1634,   0,   0,1635,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+     0,   0,   0,   0,   0,   0,   0,   0,   0,1630,1631,1632,   0,   0,1633,   0,
+     0,   0,   0,   0,   0,   0,   0,   0,1639,   0,   0,1638,1640,   0,   0,   0,
+     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,1636,1637,   0,   0,
+     0,   0,   0,   0,1641,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,1642,1644,1643,   0,   0,   0,
+     0,   0,   0,   0,   0,   0,   0,   0,1645,   0,   0,   0,   0,   0,   0,   0,
+  1646,   0,   0,   0,   0,   0,   0,1648,1649,   0,1647,1650,   0,   0,   0,   0,
+     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,1651,1653,1652,   0,   0,   0,
+     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,1654,   0,1655,1657,1656,   0,
+     0,   0,   0,1659,   0,   0,   0,   0,   0,   0,   0,   0,   0,1660,   0,   0,
+     0,   0,1661,   0,   0,   0,   0,1662,   0,   0,   0,   0,1663,   0,   0,   0,
+     0,   0,   0,   0,   0,   0,   0,   0,   0,1658,   0,   0,   0,   0,   0,   0,
+     0,   0,   0,1664,   0,1665,1673,   0,1674,   0,   0,   0,   0,   0,   0,   0,
+     0,1666,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+     0,   0,   0,1668,   0,   0,   0,   0,   0,   0,   0,   0,   0,1669,   0,   0,
+     0,   0,1670,   0,   0,   0,   0,1671,   0,   0,   0,   0,1672,   0,   0,   0,
+     0,   0,   0,   0,   0,   0,   0,   0,   0,1667,   0,   0,   0,   0,   0,   0,
+     0,   0,   0,   0,   0,   0,1675,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+     0,   0,   0,   0,   0,   0,1676,   0,1677,   0,1678,   0,1679,   0,1680,   0,
+     0,   0,1681,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,1682,   0,1683,   0,   0,
+  1684,1685,   0,1686,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+   953,1138, 955,1140, 956,1141, 957,1142,1324,1351, 963,1148, 965,1150, 968,1153,
+   966,1151, 967,1152,1378,1380,1379,1381, 984,1169, 985,1170,1420,1421, 986,1171,
+   989,1174, 995,1180, 998,1183, 996,1181, 999,1184,1000,1185,1015,1200,1329,1356,
+  1017,1203,1019,1205,1021,1207,1024,1210,1687,1688,1027,1213,1026,1212,1028,1214,
+  1029,1215,1030,1216,1034,1220,1036,1222,1039,1225,1038,1224,1334,1361,1336,1363,
+  1382,1384,1383,1385,1056,1242,1057,1243,1059,1245,1063,1249,1689,1690,1065,1251,
+  1068,1254,1070,1256,1386,1387,1388,1389,1691,1692,1073,1259,1075,1262,1079,1266,
+  1078,1265,1095,1282,1098,1285,1097,1284,1390,1391,1392,1393,1099,1286,1100,1287,
+  1101,1288,1102,1289,1105,1292,1104,1291,1106,1294,1107,1295,1108,1296,1114,1302,
+  1119,1308,1122,1311,1123,1312,1186,1260,1293,1305,   0,1394,   0,   0,   0,   0,
+   952,1137, 947,1132,1317,1344,1316,1343,1319,1346,1318,1345,1693,1695,1371,1375,
+  1370,1374,1373,1377,1372,1376,1694,1696, 981,1166, 977,1162, 972,1157,1326,1353,
+  1325,1352,1328,1355,1327,1354,1697,1698,1009,1194,1013,1198,1054,1240,1048,1234,
+  1331,1358,1330,1357,1333,1360,1332,1359,1699,1700,1396,1401,1395,1400,1398,1403,
+  1397,1402,1399,1404,1094,1281,1087,1274,1406,1411,1405,1410,1408,1413,1407,1412,
+  1409,1414,1109,1297,1117,1306,1116,1304,1112,1300,   0,   0,   0,   0,   0,   0,
+  1471,1472,1701,1705,1702,1706,1703,1707,1430,1431,1715,1719,1716,1720,1717,1721,
+  1477,1478,1729,1731,1730,1732,   0,   0,1435,1436,1733,1735,1734,1736,   0,   0,
+  1481,1482,1737,1741,1738,1742,1739,1743,1439,1440,1751,1755,1752,1756,1753,1757,
+  1490,1491,1765,1768,1766,1769,1767,1770,1447,1448,1771,1774,1772,1775,1773,1776,
+  1495,1496,1777,1779,1778,1780,   0,   0,1451,1452,1781,1783,1782,1784,   0,   0,
+  1504,1505,1785,1788,1786,1789,1787,1790,   0,1459,   0,1791,   0,1792,   0,1793,
+  1509,1510,1794,1798,1795,1799,1796,1800,1462,1463,1808,1812,1809,1813,1810,1814,
+  1467,  21,1475,  22,1479,  23,1485,  24,1493,  27,1499,  28,1507,  29,   0,   0,
+  1704,1708,1709,1710,1711,1712,1713,1714,1718,1722,1723,1724,1725,1726,1727,1728,
+  1740,1744,1745,1746,1747,1748,1749,1750,1754,1758,1759,1760,1761,1762,1763,1764,
+  1797,1801,1802,1803,1804,1805,1806,1807,1811,1815,1816,1817,1818,1819,1820,1821,
+  1470,1469,1822,1474,1465,   0,1473,1825,1429,1428,1426,  12,1432,   0,  26,   0,
+     0,1315,1823,1484,1466,   0,1483,1829,1433,  13,1437,  14,1441,1826,1827,1828,
+  1488,1487,1513,  19,   0,   0,1492,1515,1445,1444,1442,  15,   0,1831,1832,1833,
+  1502,1501,1516,  25,1497,1498,1506,1518,1457,1456,1454,  17,1453,1313,  11,   3,
+     0,   0,1824,1512,1519,   0,1511,1830,1449,  16,1460,  18,1464,   4,   0,   0,
+    30,  31,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+     0,   0,   0,   0,   0,   0,  20,   0,   0,   0,   2,   6,   0,   0,   0,   0,
+     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,1834,1835,   0,   0,   0,   0,
+     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,1836,   0,
+     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,1837,1839,1838,
+     0,   0,   0,   0,1840,   0,   0,   0,   0,1841,   0,   0,1842,   0,   0,   0,
+     0,   0,   0,   0,1843,   0,1844,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+     0,1845,   0,   0,1846,   0,   0,1847,   0,1848,   0,   0,   0,   0,   0,   0,
+   937,   0,1850,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,1849, 936, 938,
+  1851,1852,   0,   0,1853,1854,   0,   0,1855,1856,   0,   0,   0,   0,   0,   0,
+  1857,1858,   0,   0,1861,1862,   0,   0,1863,1864,   0,   0,   0,   0,   0,   0,
+     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,1867,1868,1869,1870,
+  1859,1860,1865,1866,   0,   0,   0,   0,   0,   0,1871,1872,1873,1874,   0,   0,
+     0,   0,   0,   0,   0,   0,   0,   0,   0,  32,  33,   0,   0,   0,   0,   0,
+     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,1875,   0,   0,   0,
+     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,1877,   0,1878,   0,
+  1879,   0,1880,   0,1881,   0,1882,   0,1883,   0,1884,   0,1885,   0,1886,   0,
+  1887,   0,1888,   0,   0,1889,   0,1890,   0,1891,   0,   0,   0,   0,   0,   0,
+  1892,1893,   0,1894,1895,   0,1896,1897,   0,1898,1899,   0,1900,1901,   0,   0,
+     0,   0,   0,   0,1876,   0,   0,   0,   0,   0,   0,   0,   0,   0,1902,   0,
+     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,1904,   0,1905,   0,
+  1906,   0,1907,   0,1908,   0,1909,   0,1910,   0,1911,   0,1912,   0,1913,   0,
+  1914,   0,1915,   0,   0,1916,   0,1917,   0,1918,   0,   0,   0,   0,   0,   0,
+  1919,1920,   0,1921,1922,   0,1923,1924,   0,1925,1926,   0,1927,1928,   0,   0,
+     0,   0,   0,   0,1903,   0,   0,1929,1930,1931,1932,   0,   0,   0,1933,   0,
+   710, 385, 724, 715, 455, 103, 186, 825, 825, 242, 751, 205, 241, 336, 524, 601,
+   663, 676, 688, 738, 411, 434, 474, 500, 649, 746, 799, 108, 180, 416, 482, 662,
+   810, 275, 462, 658, 692, 344, 618, 679, 293, 388, 440, 492, 740, 116, 146, 168,
+   368, 414, 481, 527, 606, 660, 665, 722, 781, 803, 809, 538, 553, 588, 642, 758,
+   811, 701, 233, 299, 573, 612, 487, 540, 714, 779, 232, 267, 412, 445, 457, 585,
+   594, 766, 167, 613, 149, 148, 560, 589, 648, 768, 708, 345, 411, 704, 105, 259,
+   313, 496, 518, 174, 542, 120, 307, 101, 430, 372, 584, 183, 228, 529, 650, 697,
+   424, 732, 428, 349, 632, 355, 517, 110, 135, 147, 403, 580, 624, 700, 750, 170,
+   193, 245, 297, 374, 463, 543, 763, 801, 812, 815, 162, 384, 420, 730, 287, 330,
+   337, 366, 459, 476, 509, 558, 591, 610, 726, 652, 734, 759, 154, 163, 198, 473,
+   683, 697, 292, 311, 353, 423, 572, 494, 113, 217, 259, 280, 314, 499, 506, 603,
+   608, 752, 778, 782, 788, 117, 557, 748, 774, 320, 109, 126, 260, 265, 373, 411,
+   479, 523, 655, 737, 823, 380, 765, 161, 395, 398, 438, 451, 502, 516, 537, 583,
+   791, 136, 340, 769, 122, 273, 446, 727, 305, 322, 400, 496, 771, 155, 190, 269,
+   377, 391, 406, 432, 501, 519, 599, 684, 687, 749, 776, 175, 452, 191, 480, 510,
+   659, 772, 805, 813, 397, 444, 619, 566, 568, 575, 491, 471, 707, 111, 636, 156,
+   153, 288, 346, 578, 256, 435, 383, 729, 680, 767, 694, 295, 128, 210,   0,   0,
+   227,   0, 379,   0,   0, 150, 493, 525, 544, 551, 552, 556, 783, 576, 604,   0,
+   661,   0, 703,   0,   0, 735, 743,   0,   0,   0, 793, 794, 795, 808, 741, 773,
+   118, 127, 130, 166, 169, 177, 207, 213, 215, 226, 229, 268, 270, 317, 327, 329,
+   335, 369, 375, 381, 404, 441, 448, 458, 477, 484, 503, 539, 545, 547, 546, 548,
+   549, 550, 554, 555, 561, 564, 569, 591, 593, 595, 598, 607, 620, 625, 625, 651,
+   690, 695, 705, 706, 716, 717, 733, 735, 777, 786, 790, 315, 869, 623,   0,   0,
+   102, 145, 134, 115, 129, 138, 165, 171, 207, 202, 206, 212, 227, 231, 240, 243,
+   250, 254, 294, 296, 303, 308, 319, 325, 321, 329, 326, 335, 341, 357, 360, 362,
+   370, 379, 388, 389, 393, 421, 424, 438, 456, 454, 458, 465, 477, 535, 485, 490,
+   493, 507, 512, 514, 521, 522, 525, 526, 528, 533, 532, 541, 565, 569, 574, 586,
+   591, 597, 607, 637, 647, 674, 691, 693, 695, 698, 703, 699, 705, 704, 702, 706,
+   709, 717, 728, 736, 747, 754, 770, 777, 783, 784, 786, 787, 790, 802, 825, 848,
+   847, 857,  55,  65,  66, 883, 892, 916, 822, 824,   0,   0,   0,   0,   0,   0,
+     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,1586,   0,1605,
+     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,1602,1603,1934,1935,1574,1575,
+  1576,1577,1579,1580,1581,1583,1584,   0,1585,1587,1588,1589,1591,   0,1592,   0,
+  1593,1594,   0,1595,1596,   0,1598,1599,1600,1601,1604,1582,1578,1590,1597,   0,
+     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,1936,   0,1937,   0,   0,   0,
+     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,1938,   0,   0,   0,   0,
+     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,1939,1940,
+     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,1941,1942,   0,   0,   0,
+     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,1944,1943,   0,1945,   0,
+     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,1946,1947,   0,   0,   0,   0,
+     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,1948,1949,
+  1950,1951,1952,1953,1954,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,1955,1956,1957,1959,1958,
+  1960,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+   106, 104, 107, 826, 114, 118, 119, 121, 123, 124, 127, 125,  34, 830, 130, 131,
+   132, 137, 827,  35, 133, 139, 829, 142, 143, 112, 144, 145, 924, 151, 152,  37,
+   157, 158, 159, 160,  38, 165, 166, 169, 171, 172, 173, 174, 176, 177, 178, 179,
+   181, 182, 182, 182, 833, 468, 184, 185, 834, 187, 188, 189, 196, 192, 194, 195,
+   197, 199, 200, 201, 203, 204, 204, 206, 208, 209, 211, 218, 213, 219, 214, 216,
+   153, 234, 221, 222, 223, 220, 225, 224, 230, 835, 235, 236, 237, 238, 239, 244,
+   836, 837, 247, 248, 249, 246, 251,  39,  40, 253, 255, 255, 838, 257, 258, 259,
+   261, 839, 262, 263, 301, 264,  41, 266, 270, 272, 271, 841, 274, 842, 277, 276,
+   278, 281, 282,  42, 283, 284, 285, 286,  43, 843,  44, 289, 290, 291, 293, 934,
+   298, 845, 845, 621, 300, 300,  45, 852, 894, 302, 304,  46, 306, 309, 310, 312,
+   316,  48,  47, 317, 846, 318, 323, 324, 325, 324, 328, 329, 333, 331, 332, 334,
+   335, 336, 338, 339, 342, 343, 347, 351, 849, 350, 348, 352, 354, 359, 850, 361,
+   358, 356,  49, 363, 365, 367, 364,  50, 369, 371, 851, 376, 386, 378,  53, 381,
+    52,  51, 140, 141, 387, 382, 614,  78, 388, 389, 390, 394, 392, 856,  54, 399,
+   396, 402, 404, 858, 405, 401, 407,  55, 408, 409, 410, 413, 859, 415,  56, 417,
+   860, 418,  57, 419, 422, 424, 425, 861, 840, 862, 426, 863, 429, 431, 427, 433,
+   437, 441, 438, 439, 442, 443, 864, 436, 449, 450,  58, 454, 453, 865, 447, 460,
+   866, 867, 461, 466, 465, 464,  59, 467, 470, 469, 472, 828, 475, 868, 478, 870,
+   483, 485, 486, 871, 488, 489, 872, 873, 495, 497,  60, 498,  61,  61, 504, 505,
+   507, 508, 511,  62, 513, 874, 515, 875, 518, 844, 520, 876, 877, 878,  63,  64,
+   528, 880, 879, 881, 882, 530, 531, 531, 533,  66, 534,  67,  68, 884, 536, 538,
+   541,  69, 885, 549, 886, 887, 556, 559,  70, 561, 562, 563, 888, 889, 889, 567,
+    71, 890, 570, 571,  72, 891, 577,  73, 581, 579, 582, 893, 587,  74, 590, 592,
+   596,  75, 895, 896,  76, 897, 600, 898, 602, 605, 607, 899, 900, 609, 901, 611,
+   853,  77, 615, 616,  79, 617, 252, 902, 903, 854, 855, 621, 622, 731,  80, 627,
+   626, 628, 164, 629, 630, 631, 633, 904, 632, 634, 639, 640, 635, 641, 646, 651,
+   638, 643, 644, 645, 905, 907, 906,  81, 653, 654, 656, 911, 657, 908,  82,  83,
+   909, 910,  84, 664, 665, 666, 667, 669, 668, 671, 670, 674, 672, 673, 675,  85,
+   677, 678,  86, 681, 682, 912, 685, 686,  87, 689,  36, 913, 914,  88,  89, 696,
+   702, 709, 711, 915, 712, 713, 718, 719, 917, 831, 721, 720, 723, 832, 725, 728,
+   918, 919, 739, 742, 744, 920, 745, 753, 756, 757, 755, 760, 761, 921, 762,  90,
+   764, 922,  91, 775, 279, 780, 923, 925,  92,  93, 785, 926,  94, 927, 787, 787,
+   789, 928, 792,  95, 796, 797, 798, 800,  96, 929, 802, 804, 806,  97,  98, 807,
+   930,  99, 931, 932, 933, 814, 100, 816, 817, 818, 819, 820, 821, 935,   0,   0,
+};
+static const int16_t
+_hb_ucd_i16[92] =
+{
+      0,    0,    1,   -1,    2,    0,   -2,    0,    0,    2,    0,   -2,    0,   16,    0,  -16,
+      0,    1,   -1,    0,    3,    3,    3,   -3,   -3,   -3,    0, 2016,    0, 2527, 1923, 1914,
+   1918,    0, 2250,    0,    0,  138,    0,    7,   -7,    0,   -1,    1, 1824,    0, 2104,    0,
+   2108, 2106,    0, 2106, 1316,    0,   -1, -138,    8,    8,    8,    0,    7,    7,   -8,   -8,
+     -8,   -7,-1316,    1,   -1,    3,   -3,    1,    0,-1914,-1918,    0,    0,-1923,-1824,    0,
+      0,-2016,-2104,    0,    0,-2106,-2108,-2106,-2250,    0,-2527,    0,
+};
+
+static inline uint_fast8_t
+_hb_ucd_gc (unsigned u)
+{
+  return u<1114112u?_hb_ucd_u8[4840+(((_hb_ucd_u8[1072+(((_hb_ucd_u16[((_hb_ucd_u8[272+(((_hb_ucd_u8[u>>1>>3>>3>>5])<<5)+((u>>1>>3>>3)&31u))])<<3)+((u>>1>>3)&7u)])<<3)+((u>>1)&7u))])<<1)+((u)&1u))]:2;
+}
+static inline uint_fast8_t
+_hb_ucd_ccc (unsigned u)
+{
+  return u<125259u?_hb_ucd_u8[6670+(((_hb_ucd_u8[6166+(((_hb_ucd_u8[5754+(((_hb_ucd_u8[5306+(((_hb_ucd_u8[5182+(u>>2>>2>>2>>4)])<<4)+((u>>2>>2>>2)&15u))])<<2)+((u>>2>>2)&3u))])<<2)+((u>>2)&3u))])<<2)+((u)&3u))]:0;
+}
+static inline unsigned
+_hb_ucd_b4 (const uint8_t* a, unsigned i)
+{
+  return (a[i>>1]>>((i&1u)<<2))&15u;
+}
+static inline int_fast16_t
+_hb_ucd_bmg (unsigned u)
+{
+  return u<65380u?_hb_ucd_i16[((_hb_ucd_u8[7538+(((_hb_ucd_u8[7314+(((_hb_ucd_u8[7218+(((_hb_ucd_b4(7154+_hb_ucd_u8,u>>1>>2>>3>>3))<<3)+((u>>1>>2>>3)&7u))])<<3)+((u>>1>>2)&7u))])<<2)+((u>>1)&3u))])<<1)+((u)&1u)]:0;
+}
+static inline uint_fast8_t
+_hb_ucd_sc (unsigned u)
+{
+  return u<918016u?_hb_ucd_u8[11048+(((_hb_ucd_u8[10132+(((_hb_ucd_u8[8788+(((_hb_ucd_u8[8228+(((_hb_ucd_u8[7778+(u>>2>>2>>3>>4)])<<4)+((u>>2>>2>>3)&15u))])<<3)+((u>>2>>2)&7u))])<<2)+((u>>2)&3u))])<<2)+((u)&3u))]:2;
+}
+static inline uint_fast16_t
+_hb_ucd_dm (unsigned u)
+{
+  return u<195102u?_hb_ucd_u16[1504+(((_hb_ucd_u8[12048+(((_hb_ucd_b4(11952+_hb_ucd_u8,u>>4>>6))<<6)+((u>>4)&63u))])<<4)+((u)&15u))]:0;
+}
+
+#endif
+
+
+#endif /* HB_UCD_TABLE_HH */
+
+/* == End of generated table == */
diff --git a/src/hb-ucd.cc b/src/hb-ucd.cc
new file mode 100644 (file)
index 0000000..b29f2a9
--- /dev/null
@@ -0,0 +1,246 @@
+/*
+ * Copyright (C) 2012 Grigori Goronzy <greg@kinoho.net>
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include "hb.hh"
+#include "hb-unicode.hh"
+#include "hb-machinery.hh"
+
+#include "hb-ucd-table.hh"
+
+static hb_unicode_combining_class_t
+hb_ucd_combining_class (hb_unicode_funcs_t *ufuncs HB_UNUSED,
+                       hb_codepoint_t unicode,
+                       void *user_data HB_UNUSED)
+{
+  return (hb_unicode_combining_class_t) _hb_ucd_ccc (unicode);
+}
+
+static hb_unicode_general_category_t
+hb_ucd_general_category (hb_unicode_funcs_t *ufuncs HB_UNUSED,
+                        hb_codepoint_t unicode,
+                        void *user_data HB_UNUSED)
+{
+  return (hb_unicode_general_category_t) _hb_ucd_gc (unicode);
+}
+
+static hb_codepoint_t
+hb_ucd_mirroring (hb_unicode_funcs_t *ufuncs HB_UNUSED,
+                 hb_codepoint_t unicode,
+                 void *user_data HB_UNUSED)
+{
+  return unicode + _hb_ucd_bmg (unicode);
+}
+
+static hb_script_t
+hb_ucd_script (hb_unicode_funcs_t *ufuncs HB_UNUSED,
+              hb_codepoint_t unicode,
+              void *user_data HB_UNUSED)
+{
+  return _hb_ucd_sc_map[_hb_ucd_sc (unicode)];
+}
+
+
+#define SBASE 0xAC00u
+#define LBASE 0x1100u
+#define VBASE 0x1161u
+#define TBASE 0x11A7u
+#define SCOUNT 11172u
+#define LCOUNT 19u
+#define VCOUNT 21u
+#define TCOUNT 28u
+#define NCOUNT (VCOUNT * TCOUNT)
+
+static inline bool
+_hb_ucd_decompose_hangul (hb_codepoint_t ab, hb_codepoint_t *a, hb_codepoint_t *b)
+{
+  unsigned si = ab - SBASE;
+
+  if (si >= SCOUNT)
+    return false;
+
+  if (si % TCOUNT)
+  {
+    /* LV,T */
+    *a = SBASE + (si / TCOUNT) * TCOUNT;
+    *b = TBASE + (si % TCOUNT);
+    return true;
+  } else {
+    /* L,V */
+    *a = LBASE + (si / NCOUNT);
+    *b = VBASE + (si % NCOUNT) / TCOUNT;
+    return true;
+  }
+}
+
+static inline bool
+_hb_ucd_compose_hangul (hb_codepoint_t a, hb_codepoint_t b, hb_codepoint_t *ab)
+{
+  if (a >= SBASE && a < (SBASE + SCOUNT) && b > TBASE && b < (TBASE + TCOUNT) &&
+    !((a - SBASE) % TCOUNT))
+  {
+    /* LV,T */
+    *ab = a + (b - TBASE);
+    return true;
+  }
+  else if (a >= LBASE && a < (LBASE + LCOUNT) && b >= VBASE && b < (VBASE + VCOUNT))
+  {
+    /* L,V */
+    int li = a - LBASE;
+    int vi = b - VBASE;
+    *ab = SBASE + li * NCOUNT + vi * TCOUNT;
+    return true;
+  }
+  else
+    return false;
+}
+
+static int
+_cmp_pair (const void *_key, const void *_item)
+{
+  uint64_t& a = * (uint64_t*) _key;
+  uint64_t b = (* (uint64_t*) _item) & HB_CODEPOINT_ENCODE3(0x1FFFFFu, 0x1FFFFFu, 0);
+
+  return a < b ? -1 : a > b ? +1 : 0;
+}
+static int
+_cmp_pair_11_7_14 (const void *_key, const void *_item)
+{
+  uint32_t& a = * (uint32_t*) _key;
+  uint32_t b = (* (uint32_t*) _item) & HB_CODEPOINT_ENCODE3_11_7_14(0x1FFFFFu, 0x1FFFFFu, 0);
+
+  return a < b ? -1 : a > b ? +1 : 0;
+}
+
+static hb_bool_t
+hb_ucd_compose (hb_unicode_funcs_t *ufuncs HB_UNUSED,
+               hb_codepoint_t a, hb_codepoint_t b, hb_codepoint_t *ab,
+               void *user_data HB_UNUSED)
+{
+  if (_hb_ucd_compose_hangul (a, b, ab)) return true;
+
+  hb_codepoint_t u = 0;
+
+  if ((a & 0xFFFFF800u) == 0x0000u && (b & 0xFFFFFF80) == 0x0300u)
+  {
+    uint32_t k = HB_CODEPOINT_ENCODE3_11_7_14 (a, b, 0);
+    uint32_t *v = (uint32_t*) hb_bsearch (&k, _hb_ucd_dm2_u32_map,
+                                         ARRAY_LENGTH (_hb_ucd_dm2_u32_map),
+                                         sizeof (*_hb_ucd_dm2_u32_map),
+                                         _cmp_pair_11_7_14);
+    if (likely (!v)) return false;
+    u = HB_CODEPOINT_DECODE3_11_7_14_3 (*v);
+  }
+  else
+  {
+    uint64_t k = HB_CODEPOINT_ENCODE3 (a, b, 0);
+    uint64_t *v = (uint64_t*) hb_bsearch (&k, _hb_ucd_dm2_u64_map,
+                                         ARRAY_LENGTH (_hb_ucd_dm2_u64_map),
+                                         sizeof (*_hb_ucd_dm2_u64_map),
+                                         _cmp_pair);
+    if (likely (!v)) return false;
+    u = HB_CODEPOINT_DECODE3_3 (*v);
+  }
+
+  if (unlikely (!u)) return false;
+  *ab = u;
+  return true;
+}
+
+static hb_bool_t
+hb_ucd_decompose (hb_unicode_funcs_t *ufuncs HB_UNUSED,
+                 hb_codepoint_t ab, hb_codepoint_t *a, hb_codepoint_t *b,
+                 void *user_data HB_UNUSED)
+{
+  if (_hb_ucd_decompose_hangul (ab, a, b)) return true;
+
+  unsigned i = _hb_ucd_dm (ab);
+
+  if (likely (!i)) return false;
+  i--;
+
+  if (i < ARRAY_LENGTH (_hb_ucd_dm1_p0_map) + ARRAY_LENGTH (_hb_ucd_dm1_p2_map))
+  {
+    if (i < ARRAY_LENGTH (_hb_ucd_dm1_p0_map))
+      *a = _hb_ucd_dm1_p0_map[i];
+    else
+    {
+      i -= ARRAY_LENGTH (_hb_ucd_dm1_p0_map);
+      *a = 0x20000 | _hb_ucd_dm1_p2_map[i];
+    }
+    *b = 0;
+    return true;
+  }
+  i -= ARRAY_LENGTH (_hb_ucd_dm1_p0_map) + ARRAY_LENGTH (_hb_ucd_dm1_p2_map);
+
+  if (i < ARRAY_LENGTH (_hb_ucd_dm2_u32_map))
+  {
+    uint32_t v = _hb_ucd_dm2_u32_map[i];
+    *a = HB_CODEPOINT_DECODE3_11_7_14_1 (v);
+    *b = HB_CODEPOINT_DECODE3_11_7_14_2 (v);
+    return true;
+  }
+  i -= ARRAY_LENGTH (_hb_ucd_dm2_u32_map);
+
+  uint64_t v = _hb_ucd_dm2_u64_map[i];
+  *a = HB_CODEPOINT_DECODE3_1 (v);
+  *b = HB_CODEPOINT_DECODE3_2 (v);
+  return true;
+}
+
+
+#if HB_USE_ATEXIT
+static void free_static_ucd_funcs ();
+#endif
+
+static struct hb_ucd_unicode_funcs_lazy_loader_t : hb_unicode_funcs_lazy_loader_t<hb_ucd_unicode_funcs_lazy_loader_t>
+{
+  static hb_unicode_funcs_t *create ()
+  {
+    hb_unicode_funcs_t *funcs = hb_unicode_funcs_create (nullptr);
+
+    hb_unicode_funcs_set_combining_class_func (funcs, hb_ucd_combining_class, nullptr, nullptr);
+    hb_unicode_funcs_set_general_category_func (funcs, hb_ucd_general_category, nullptr, nullptr);
+    hb_unicode_funcs_set_mirroring_func (funcs, hb_ucd_mirroring, nullptr, nullptr);
+    hb_unicode_funcs_set_script_func (funcs, hb_ucd_script, nullptr, nullptr);
+    hb_unicode_funcs_set_compose_func (funcs, hb_ucd_compose, nullptr, nullptr);
+    hb_unicode_funcs_set_decompose_func (funcs, hb_ucd_decompose, nullptr, nullptr);
+
+    hb_unicode_funcs_make_immutable (funcs);
+
+#if HB_USE_ATEXIT
+    atexit (free_static_ucd_funcs);
+#endif
+
+    return funcs;
+  }
+} static_ucd_funcs;
+
+#if HB_USE_ATEXIT
+static
+void free_static_ucd_funcs ()
+{
+  static_ucd_funcs.free_instance ();
+}
+#endif
+
+hb_unicode_funcs_t *
+hb_ucd_get_unicode_funcs ()
+{
+#ifdef HB_NO_UCD
+  return hb_unicode_funcs_get_empty ();
+#endif
+  return static_ucd_funcs.get_unconst ();
+}
diff --git a/src/hb-ucdn.cc b/src/hb-ucdn.cc
deleted file mode 100644 (file)
index 8230bf1..0000000
+++ /dev/null
@@ -1,272 +0,0 @@
-/*
- * Copyright (C) 2012 Grigori Goronzy <greg@kinoho.net>
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
- * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- */
-
-#include "hb.hh"
-
-#include "hb-machinery.hh"
-
-#include "ucdn.h"
-
-static const hb_script_t ucdn_script_translate[] =
-{
-    HB_SCRIPT_COMMON,
-    HB_SCRIPT_LATIN,
-    HB_SCRIPT_GREEK,
-    HB_SCRIPT_CYRILLIC,
-    HB_SCRIPT_ARMENIAN,
-    HB_SCRIPT_HEBREW,
-    HB_SCRIPT_ARABIC,
-    HB_SCRIPT_SYRIAC,
-    HB_SCRIPT_THAANA,
-    HB_SCRIPT_DEVANAGARI,
-    HB_SCRIPT_BENGALI,
-    HB_SCRIPT_GURMUKHI,
-    HB_SCRIPT_GUJARATI,
-    HB_SCRIPT_ORIYA,
-    HB_SCRIPT_TAMIL,
-    HB_SCRIPT_TELUGU,
-    HB_SCRIPT_KANNADA,
-    HB_SCRIPT_MALAYALAM,
-    HB_SCRIPT_SINHALA,
-    HB_SCRIPT_THAI,
-    HB_SCRIPT_LAO,
-    HB_SCRIPT_TIBETAN,
-    HB_SCRIPT_MYANMAR,
-    HB_SCRIPT_GEORGIAN,
-    HB_SCRIPT_HANGUL,
-    HB_SCRIPT_ETHIOPIC,
-    HB_SCRIPT_CHEROKEE,
-    HB_SCRIPT_CANADIAN_SYLLABICS,
-    HB_SCRIPT_OGHAM,
-    HB_SCRIPT_RUNIC,
-    HB_SCRIPT_KHMER,
-    HB_SCRIPT_MONGOLIAN,
-    HB_SCRIPT_HIRAGANA,
-    HB_SCRIPT_KATAKANA,
-    HB_SCRIPT_BOPOMOFO,
-    HB_SCRIPT_HAN,
-    HB_SCRIPT_YI,
-    HB_SCRIPT_OLD_ITALIC,
-    HB_SCRIPT_GOTHIC,
-    HB_SCRIPT_DESERET,
-    HB_SCRIPT_INHERITED,
-    HB_SCRIPT_TAGALOG,
-    HB_SCRIPT_HANUNOO,
-    HB_SCRIPT_BUHID,
-    HB_SCRIPT_TAGBANWA,
-    HB_SCRIPT_LIMBU,
-    HB_SCRIPT_TAI_LE,
-    HB_SCRIPT_LINEAR_B,
-    HB_SCRIPT_UGARITIC,
-    HB_SCRIPT_SHAVIAN,
-    HB_SCRIPT_OSMANYA,
-    HB_SCRIPT_CYPRIOT,
-    HB_SCRIPT_BRAILLE,
-    HB_SCRIPT_BUGINESE,
-    HB_SCRIPT_COPTIC,
-    HB_SCRIPT_NEW_TAI_LUE,
-    HB_SCRIPT_GLAGOLITIC,
-    HB_SCRIPT_TIFINAGH,
-    HB_SCRIPT_SYLOTI_NAGRI,
-    HB_SCRIPT_OLD_PERSIAN,
-    HB_SCRIPT_KHAROSHTHI,
-    HB_SCRIPT_BALINESE,
-    HB_SCRIPT_CUNEIFORM,
-    HB_SCRIPT_PHOENICIAN,
-    HB_SCRIPT_PHAGS_PA,
-    HB_SCRIPT_NKO,
-    HB_SCRIPT_SUNDANESE,
-    HB_SCRIPT_LEPCHA,
-    HB_SCRIPT_OL_CHIKI,
-    HB_SCRIPT_VAI,
-    HB_SCRIPT_SAURASHTRA,
-    HB_SCRIPT_KAYAH_LI,
-    HB_SCRIPT_REJANG,
-    HB_SCRIPT_LYCIAN,
-    HB_SCRIPT_CARIAN,
-    HB_SCRIPT_LYDIAN,
-    HB_SCRIPT_CHAM,
-    HB_SCRIPT_TAI_THAM,
-    HB_SCRIPT_TAI_VIET,
-    HB_SCRIPT_AVESTAN,
-    HB_SCRIPT_EGYPTIAN_HIEROGLYPHS,
-    HB_SCRIPT_SAMARITAN,
-    HB_SCRIPT_LISU,
-    HB_SCRIPT_BAMUM,
-    HB_SCRIPT_JAVANESE,
-    HB_SCRIPT_MEETEI_MAYEK,
-    HB_SCRIPT_IMPERIAL_ARAMAIC,
-    HB_SCRIPT_OLD_SOUTH_ARABIAN,
-    HB_SCRIPT_INSCRIPTIONAL_PARTHIAN,
-    HB_SCRIPT_INSCRIPTIONAL_PAHLAVI,
-    HB_SCRIPT_OLD_TURKIC,
-    HB_SCRIPT_KAITHI,
-    HB_SCRIPT_BATAK,
-    HB_SCRIPT_BRAHMI,
-    HB_SCRIPT_MANDAIC,
-    HB_SCRIPT_CHAKMA,
-    HB_SCRIPT_MEROITIC_CURSIVE,
-    HB_SCRIPT_MEROITIC_HIEROGLYPHS,
-    HB_SCRIPT_MIAO,
-    HB_SCRIPT_SHARADA,
-    HB_SCRIPT_SORA_SOMPENG,
-    HB_SCRIPT_TAKRI,
-    HB_SCRIPT_UNKNOWN,
-    HB_SCRIPT_BASSA_VAH,
-    HB_SCRIPT_CAUCASIAN_ALBANIAN,
-    HB_SCRIPT_DUPLOYAN,
-    HB_SCRIPT_ELBASAN,
-    HB_SCRIPT_GRANTHA,
-    HB_SCRIPT_KHOJKI,
-    HB_SCRIPT_KHUDAWADI,
-    HB_SCRIPT_LINEAR_A,
-    HB_SCRIPT_MAHAJANI,
-    HB_SCRIPT_MANICHAEAN,
-    HB_SCRIPT_MENDE_KIKAKUI,
-    HB_SCRIPT_MODI,
-    HB_SCRIPT_MRO,
-    HB_SCRIPT_NABATAEAN,
-    HB_SCRIPT_OLD_NORTH_ARABIAN,
-    HB_SCRIPT_OLD_PERMIC,
-    HB_SCRIPT_PAHAWH_HMONG,
-    HB_SCRIPT_PALMYRENE,
-    HB_SCRIPT_PAU_CIN_HAU,
-    HB_SCRIPT_PSALTER_PAHLAVI,
-    HB_SCRIPT_SIDDHAM,
-    HB_SCRIPT_TIRHUTA,
-    HB_SCRIPT_WARANG_CITI,
-    HB_SCRIPT_AHOM,
-    HB_SCRIPT_ANATOLIAN_HIEROGLYPHS,
-    HB_SCRIPT_HATRAN,
-    HB_SCRIPT_MULTANI,
-    HB_SCRIPT_OLD_HUNGARIAN,
-    HB_SCRIPT_SIGNWRITING,
-    HB_SCRIPT_ADLAM,
-    HB_SCRIPT_BHAIKSUKI,
-    HB_SCRIPT_MARCHEN,
-    HB_SCRIPT_NEWA,
-    HB_SCRIPT_OSAGE,
-    HB_SCRIPT_TANGUT,
-    HB_SCRIPT_MASARAM_GONDI,
-    HB_SCRIPT_NUSHU,
-    HB_SCRIPT_SOYOMBO,
-    HB_SCRIPT_ZANABAZAR_SQUARE,
-    HB_SCRIPT_DOGRA,
-    HB_SCRIPT_GUNJALA_GONDI,
-    HB_SCRIPT_HANIFI_ROHINGYA,
-    HB_SCRIPT_MAKASAR,
-    HB_SCRIPT_MEDEFAIDRIN,
-    HB_SCRIPT_OLD_SOGDIAN,
-    HB_SCRIPT_SOGDIAN,
-    HB_SCRIPT_ELYMAIC,
-    HB_SCRIPT_NANDINAGARI,
-    HB_SCRIPT_NYIAKENG_PUACHUE_HMONG,
-    HB_SCRIPT_WANCHO,
-};
-
-static hb_unicode_combining_class_t
-hb_ucdn_combining_class(hb_unicode_funcs_t *ufuncs HB_UNUSED,
-                       hb_codepoint_t unicode,
-                       void *user_data HB_UNUSED)
-{
-    return (hb_unicode_combining_class_t) ucdn_get_combining_class(unicode);
-}
-
-static hb_unicode_general_category_t
-hb_ucdn_general_category(hb_unicode_funcs_t *ufuncs HB_UNUSED,
-                        hb_codepoint_t unicode,
-                        void *user_data HB_UNUSED)
-{
-    return (hb_unicode_general_category_t)ucdn_get_general_category(unicode);
-}
-
-static hb_codepoint_t
-hb_ucdn_mirroring(hb_unicode_funcs_t *ufuncs HB_UNUSED,
-                 hb_codepoint_t unicode,
-                 void *user_data HB_UNUSED)
-{
-    return ucdn_mirror(unicode);
-}
-
-static hb_script_t
-hb_ucdn_script(hb_unicode_funcs_t *ufuncs HB_UNUSED,
-              hb_codepoint_t unicode,
-              void *user_data HB_UNUSED)
-{
-    return ucdn_script_translate[ucdn_get_script(unicode)];
-}
-
-static hb_bool_t
-hb_ucdn_compose(hb_unicode_funcs_t *ufuncs HB_UNUSED,
-               hb_codepoint_t a, hb_codepoint_t b, hb_codepoint_t *ab,
-               void *user_data HB_UNUSED)
-{
-    return ucdn_compose(ab, a, b);
-}
-
-static hb_bool_t
-hb_ucdn_decompose(hb_unicode_funcs_t *ufuncs HB_UNUSED,
-                 hb_codepoint_t ab, hb_codepoint_t *a, hb_codepoint_t *b,
-                 void *user_data HB_UNUSED)
-{
-    return ucdn_decompose(ab, a, b);
-}
-
-
-#if HB_USE_ATEXIT
-static void free_static_ucdn_funcs ();
-#endif
-
-static struct hb_ucdn_unicode_funcs_lazy_loader_t : hb_unicode_funcs_lazy_loader_t<hb_ucdn_unicode_funcs_lazy_loader_t>
-{
-  static hb_unicode_funcs_t *create ()
-  {
-    hb_unicode_funcs_t *funcs = hb_unicode_funcs_create (nullptr);
-
-    hb_unicode_funcs_set_combining_class_func (funcs, hb_ucdn_combining_class, nullptr, nullptr);
-    hb_unicode_funcs_set_general_category_func (funcs, hb_ucdn_general_category, nullptr, nullptr);
-    hb_unicode_funcs_set_mirroring_func (funcs, hb_ucdn_mirroring, nullptr, nullptr);
-    hb_unicode_funcs_set_script_func (funcs, hb_ucdn_script, nullptr, nullptr);
-    hb_unicode_funcs_set_compose_func (funcs, hb_ucdn_compose, nullptr, nullptr);
-    hb_unicode_funcs_set_decompose_func (funcs, hb_ucdn_decompose, nullptr, nullptr);
-
-    hb_unicode_funcs_make_immutable (funcs);
-
-#if HB_USE_ATEXIT
-    atexit (free_static_ucdn_funcs);
-#endif
-
-    return funcs;
-  }
-} static_ucdn_funcs;
-
-#if HB_USE_ATEXIT
-static
-void free_static_ucdn_funcs ()
-{
-  static_ucdn_funcs.free_instance ();
-}
-#endif
-
-extern "C" HB_INTERNAL
-hb_unicode_funcs_t *
-hb_ucdn_get_unicode_funcs ();
-
-hb_unicode_funcs_t *
-hb_ucdn_get_unicode_funcs ()
-{
-  return static_ucdn_funcs.get_unconst ();
-}
diff --git a/src/hb-ucdn/COPYING b/src/hb-ucdn/COPYING
deleted file mode 100644 (file)
index be5205c..0000000
+++ /dev/null
@@ -1,13 +0,0 @@
-The contents of this directory are licensed under the following terms:
-
-Permission to use, copy, modify, and/or distribute this software for any
-purpose with or without fee is hereby granted, provided that the above
-copyright notice and this permission notice appear in all copies.
-
-THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
-WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
-MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
-ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
-WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
-ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
-OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
diff --git a/src/hb-ucdn/Makefile.am b/src/hb-ucdn/Makefile.am
deleted file mode 100644 (file)
index 73b5502..0000000
+++ /dev/null
@@ -1,16 +0,0 @@
-## Process this file with automake to produce Makefile.in
-
-noinst_LTLIBRARIES = libhb-ucdn.la
-
-include Makefile.sources
-
-libhb_ucdn_la_SOURCES = $(LIBHB_UCDN_sources)
-libhb_ucdn_la_CPPFLAGS = \
-       -I$(top_srcdir) \
-       -I$(top_srcdir)/src \
-       -I$(top_builddir)/src
-libhb_ucdn_la_LIBADD =
-
-EXTRA_DIST = README COPYING
-
--include $(top_srcdir)/git.mk
diff --git a/src/hb-ucdn/Makefile.in b/src/hb-ucdn/Makefile.in
deleted file mode 100644 (file)
index 509bed2..0000000
+++ /dev/null
@@ -1,692 +0,0 @@
-# Makefile.in generated by automake 1.16.1 from Makefile.am.
-# @configure_input@
-
-# Copyright (C) 1994-2018 Free Software Foundation, Inc.
-
-# This Makefile.in is free software; the Free Software Foundation
-# gives unlimited permission to copy and/or distribute it,
-# with or without modifications, as long as this notice is preserved.
-
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
-# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
-# PARTICULAR PURPOSE.
-
-@SET_MAKE@
-
-VPATH = @srcdir@
-am__is_gnu_make = { \
-  if test -z '$(MAKELEVEL)'; then \
-    false; \
-  elif test -n '$(MAKE_HOST)'; then \
-    true; \
-  elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \
-    true; \
-  else \
-    false; \
-  fi; \
-}
-am__make_running_with_option = \
-  case $${target_option-} in \
-      ?) ;; \
-      *) echo "am__make_running_with_option: internal error: invalid" \
-              "target option '$${target_option-}' specified" >&2; \
-         exit 1;; \
-  esac; \
-  has_opt=no; \
-  sane_makeflags=$$MAKEFLAGS; \
-  if $(am__is_gnu_make); then \
-    sane_makeflags=$$MFLAGS; \
-  else \
-    case $$MAKEFLAGS in \
-      *\\[\ \  ]*) \
-        bs=\\; \
-        sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \
-          | sed "s/$$bs$$bs[$$bs $$bs  ]*//g"`;; \
-    esac; \
-  fi; \
-  skip_next=no; \
-  strip_trailopt () \
-  { \
-    flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \
-  }; \
-  for flg in $$sane_makeflags; do \
-    test $$skip_next = yes && { skip_next=no; continue; }; \
-    case $$flg in \
-      *=*|--*) continue;; \
-        -*I) strip_trailopt 'I'; skip_next=yes;; \
-      -*I?*) strip_trailopt 'I';; \
-        -*O) strip_trailopt 'O'; skip_next=yes;; \
-      -*O?*) strip_trailopt 'O';; \
-        -*l) strip_trailopt 'l'; skip_next=yes;; \
-      -*l?*) strip_trailopt 'l';; \
-      -[dEDm]) skip_next=yes;; \
-      -[JT]) skip_next=yes;; \
-    esac; \
-    case $$flg in \
-      *$$target_option*) has_opt=yes; break;; \
-    esac; \
-  done; \
-  test $$has_opt = yes
-am__make_dryrun = (target_option=n; $(am__make_running_with_option))
-am__make_keepgoing = (target_option=k; $(am__make_running_with_option))
-pkgdatadir = $(datadir)/@PACKAGE@
-pkgincludedir = $(includedir)/@PACKAGE@
-pkglibdir = $(libdir)/@PACKAGE@
-pkglibexecdir = $(libexecdir)/@PACKAGE@
-am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
-install_sh_DATA = $(install_sh) -c -m 644
-install_sh_PROGRAM = $(install_sh) -c
-install_sh_SCRIPT = $(install_sh) -c
-INSTALL_HEADER = $(INSTALL_DATA)
-transform = $(program_transform_name)
-NORMAL_INSTALL = :
-PRE_INSTALL = :
-POST_INSTALL = :
-NORMAL_UNINSTALL = :
-PRE_UNINSTALL = :
-POST_UNINSTALL = :
-build_triplet = @build@
-host_triplet = @host@
-subdir = src/hb-ucdn
-ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
-am__aclocal_m4_deps = $(top_srcdir)/m4/ax_check_link_flag.m4 \
-       $(top_srcdir)/m4/ax_code_coverage.m4 \
-       $(top_srcdir)/m4/ax_pthread.m4 $(top_srcdir)/m4/gtk-doc.m4 \
-       $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \
-       $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \
-       $(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/configure.ac
-am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
-       $(ACLOCAL_M4)
-DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON)
-mkinstalldirs = $(install_sh) -d
-CONFIG_HEADER = $(top_builddir)/config.h
-CONFIG_CLEAN_FILES =
-CONFIG_CLEAN_VPATH_FILES =
-LTLIBRARIES = $(noinst_LTLIBRARIES)
-libhb_ucdn_la_DEPENDENCIES =
-am__objects_1 =
-am__objects_2 = libhb_ucdn_la-ucdn.lo $(am__objects_1)
-am_libhb_ucdn_la_OBJECTS = $(am__objects_2)
-libhb_ucdn_la_OBJECTS = $(am_libhb_ucdn_la_OBJECTS)
-AM_V_lt = $(am__v_lt_@AM_V@)
-am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@)
-am__v_lt_0 = --silent
-am__v_lt_1 = 
-AM_V_P = $(am__v_P_@AM_V@)
-am__v_P_ = $(am__v_P_@AM_DEFAULT_V@)
-am__v_P_0 = false
-am__v_P_1 = :
-AM_V_GEN = $(am__v_GEN_@AM_V@)
-am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@)
-am__v_GEN_0 = @echo "  GEN     " $@;
-am__v_GEN_1 = 
-AM_V_at = $(am__v_at_@AM_V@)
-am__v_at_ = $(am__v_at_@AM_DEFAULT_V@)
-am__v_at_0 = @
-am__v_at_1 = 
-DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)
-depcomp = $(SHELL) $(top_srcdir)/depcomp
-am__maybe_remake_depfiles = depfiles
-am__depfiles_remade = ./$(DEPDIR)/libhb_ucdn_la-ucdn.Plo
-am__mv = mv -f
-COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
-       $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
-LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
-       $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \
-       $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \
-       $(AM_CFLAGS) $(CFLAGS)
-AM_V_CC = $(am__v_CC_@AM_V@)
-am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@)
-am__v_CC_0 = @echo "  CC      " $@;
-am__v_CC_1 = 
-CCLD = $(CC)
-LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
-       $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
-       $(AM_LDFLAGS) $(LDFLAGS) -o $@
-AM_V_CCLD = $(am__v_CCLD_@AM_V@)
-am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@)
-am__v_CCLD_0 = @echo "  CCLD    " $@;
-am__v_CCLD_1 = 
-SOURCES = $(libhb_ucdn_la_SOURCES)
-DIST_SOURCES = $(libhb_ucdn_la_SOURCES)
-am__can_run_installinfo = \
-  case $$AM_UPDATE_INFO_DIR in \
-    n|no|NO) false;; \
-    *) (install-info --version) >/dev/null 2>&1;; \
-  esac
-am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP)
-# Read a list of newline-separated strings from the standard input,
-# and print each of them once, without duplicates.  Input order is
-# *not* preserved.
-am__uniquify_input = $(AWK) '\
-  BEGIN { nonempty = 0; } \
-  { items[$$0] = 1; nonempty = 1; } \
-  END { if (nonempty) { for (i in items) print i; }; } \
-'
-# Make sure the list of sources is unique.  This is necessary because,
-# e.g., the same source file might be shared among _SOURCES variables
-# for different programs/libraries.
-am__define_uniq_tagged_files = \
-  list='$(am__tagged_files)'; \
-  unique=`for i in $$list; do \
-    if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
-  done | $(am__uniquify_input)`
-ETAGS = etags
-CTAGS = ctags
-am__DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.sources \
-       $(top_srcdir)/depcomp COPYING README
-DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
-ACLOCAL = @ACLOCAL@
-AMTAR = @AMTAR@
-AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
-AR = @AR@
-AUTOCONF = @AUTOCONF@
-AUTOHEADER = @AUTOHEADER@
-AUTOMAKE = @AUTOMAKE@
-AWK = @AWK@
-CAIRO_CFLAGS = @CAIRO_CFLAGS@
-CAIRO_FT_CFLAGS = @CAIRO_FT_CFLAGS@
-CAIRO_FT_LIBS = @CAIRO_FT_LIBS@
-CAIRO_LIBS = @CAIRO_LIBS@
-CC = @CC@
-CCDEPMODE = @CCDEPMODE@
-CFLAGS = @CFLAGS@
-CODE_COVERAGE_CFLAGS = @CODE_COVERAGE_CFLAGS@
-CODE_COVERAGE_CPPFLAGS = @CODE_COVERAGE_CPPFLAGS@
-CODE_COVERAGE_CXXFLAGS = @CODE_COVERAGE_CXXFLAGS@
-CODE_COVERAGE_ENABLED = @CODE_COVERAGE_ENABLED@
-CODE_COVERAGE_LDFLAGS = @CODE_COVERAGE_LDFLAGS@
-CODE_COVERAGE_LIBS = @CODE_COVERAGE_LIBS@
-CORETEXT_CFLAGS = @CORETEXT_CFLAGS@
-CORETEXT_LIBS = @CORETEXT_LIBS@
-CPP = @CPP@
-CPPFLAGS = @CPPFLAGS@
-CXX = @CXX@
-CXXCPP = @CXXCPP@
-CXXDEPMODE = @CXXDEPMODE@
-CXXFLAGS = @CXXFLAGS@
-CYGPATH_W = @CYGPATH_W@
-DEFS = @DEFS@
-DEPDIR = @DEPDIR@
-DIRECTWRITE_CXXFLAGS = @DIRECTWRITE_CXXFLAGS@
-DIRECTWRITE_LIBS = @DIRECTWRITE_LIBS@
-DLLTOOL = @DLLTOOL@
-DSYMUTIL = @DSYMUTIL@
-DUMPBIN = @DUMPBIN@
-ECHO_C = @ECHO_C@
-ECHO_N = @ECHO_N@
-ECHO_T = @ECHO_T@
-EGREP = @EGREP@
-EXEEXT = @EXEEXT@
-FGREP = @FGREP@
-FONTCONFIG_CFLAGS = @FONTCONFIG_CFLAGS@
-FONTCONFIG_LIBS = @FONTCONFIG_LIBS@
-FREETYPE_CFLAGS = @FREETYPE_CFLAGS@
-FREETYPE_DEPS = @FREETYPE_DEPS@
-FREETYPE_LIBS = @FREETYPE_LIBS@
-GCOV = @GCOV@
-GENHTML = @GENHTML@
-GIT = @GIT@
-GLIB_CFLAGS = @GLIB_CFLAGS@
-GLIB_DEPS = @GLIB_DEPS@
-GLIB_LIBS = @GLIB_LIBS@
-GLIB_MKENUMS = @GLIB_MKENUMS@
-GOBJECT_CFLAGS = @GOBJECT_CFLAGS@
-GOBJECT_LIBS = @GOBJECT_LIBS@
-GRAPHITE2_CFLAGS = @GRAPHITE2_CFLAGS@
-GRAPHITE2_DEPS = @GRAPHITE2_DEPS@
-GRAPHITE2_LIBS = @GRAPHITE2_LIBS@
-GREP = @GREP@
-GTKDOC_CHECK = @GTKDOC_CHECK@
-GTKDOC_CHECK_PATH = @GTKDOC_CHECK_PATH@
-GTKDOC_DEPS_CFLAGS = @GTKDOC_DEPS_CFLAGS@
-GTKDOC_DEPS_LIBS = @GTKDOC_DEPS_LIBS@
-GTKDOC_MKPDF = @GTKDOC_MKPDF@
-GTKDOC_REBASE = @GTKDOC_REBASE@
-HB_LIBTOOL_VERSION_INFO = @HB_LIBTOOL_VERSION_INFO@
-HB_VERSION = @HB_VERSION@
-HB_VERSION_MAJOR = @HB_VERSION_MAJOR@
-HB_VERSION_MICRO = @HB_VERSION_MICRO@
-HB_VERSION_MINOR = @HB_VERSION_MINOR@
-HTML_DIR = @HTML_DIR@
-ICU_CFLAGS = @ICU_CFLAGS@
-ICU_CONFIG = @ICU_CONFIG@
-ICU_LIBS = @ICU_LIBS@
-INSTALL = @INSTALL@
-INSTALL_DATA = @INSTALL_DATA@
-INSTALL_PROGRAM = @INSTALL_PROGRAM@
-INSTALL_SCRIPT = @INSTALL_SCRIPT@
-INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
-INTROSPECTION_CFLAGS = @INTROSPECTION_CFLAGS@
-INTROSPECTION_COMPILER = @INTROSPECTION_COMPILER@
-INTROSPECTION_GENERATE = @INTROSPECTION_GENERATE@
-INTROSPECTION_GIRDIR = @INTROSPECTION_GIRDIR@
-INTROSPECTION_LIBS = @INTROSPECTION_LIBS@
-INTROSPECTION_MAKEFILE = @INTROSPECTION_MAKEFILE@
-INTROSPECTION_SCANNER = @INTROSPECTION_SCANNER@
-INTROSPECTION_TYPELIBDIR = @INTROSPECTION_TYPELIBDIR@
-LCOV = @LCOV@
-LD = @LD@
-LDFLAGS = @LDFLAGS@
-LIBOBJS = @LIBOBJS@
-LIBS = @LIBS@
-LIBTOOL = @LIBTOOL@
-LIPO = @LIPO@
-LN_S = @LN_S@
-LTLIBOBJS = @LTLIBOBJS@
-LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@
-MAKEINFO = @MAKEINFO@
-MANIFEST_TOOL = @MANIFEST_TOOL@
-MKDIR_P = @MKDIR_P@
-NM = @NM@
-NMEDIT = @NMEDIT@
-OBJDUMP = @OBJDUMP@
-OBJEXT = @OBJEXT@
-OTOOL = @OTOOL@
-OTOOL64 = @OTOOL64@
-PACKAGE = @PACKAGE@
-PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
-PACKAGE_NAME = @PACKAGE_NAME@
-PACKAGE_STRING = @PACKAGE_STRING@
-PACKAGE_TARNAME = @PACKAGE_TARNAME@
-PACKAGE_URL = @PACKAGE_URL@
-PACKAGE_VERSION = @PACKAGE_VERSION@
-PATH_SEPARATOR = @PATH_SEPARATOR@
-PKG_CONFIG = @PKG_CONFIG@
-PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@
-PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
-PTHREAD_CC = @PTHREAD_CC@
-PTHREAD_CFLAGS = @PTHREAD_CFLAGS@
-PTHREAD_LIBS = @PTHREAD_LIBS@
-RAGEL = @RAGEL@
-RANLIB = @RANLIB@
-SED = @SED@
-SET_MAKE = @SET_MAKE@
-SHELL = @SHELL@
-STRIP = @STRIP@
-UNISCRIBE_CFLAGS = @UNISCRIBE_CFLAGS@
-UNISCRIBE_LIBS = @UNISCRIBE_LIBS@
-VERSION = @VERSION@
-abs_builddir = @abs_builddir@
-abs_srcdir = @abs_srcdir@
-abs_top_builddir = @abs_top_builddir@
-abs_top_srcdir = @abs_top_srcdir@
-ac_ct_AR = @ac_ct_AR@
-ac_ct_CC = @ac_ct_CC@
-ac_ct_CXX = @ac_ct_CXX@
-ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
-am__include = @am__include@
-am__leading_dot = @am__leading_dot@
-am__quote = @am__quote@
-am__tar = @am__tar@
-am__untar = @am__untar@
-ax_pthread_config = @ax_pthread_config@
-bindir = @bindir@
-build = @build@
-build_alias = @build_alias@
-build_cpu = @build_cpu@
-build_os = @build_os@
-build_vendor = @build_vendor@
-builddir = @builddir@
-datadir = @datadir@
-datarootdir = @datarootdir@
-docdir = @docdir@
-dvidir = @dvidir@
-exec_prefix = @exec_prefix@
-have_gobject = @have_gobject@
-host = @host@
-host_alias = @host_alias@
-host_cpu = @host_cpu@
-host_os = @host_os@
-host_vendor = @host_vendor@
-htmldir = @htmldir@
-includedir = @includedir@
-infodir = @infodir@
-install_sh = @install_sh@
-libdir = @libdir@
-libexecdir = @libexecdir@
-localedir = @localedir@
-localstatedir = @localstatedir@
-mandir = @mandir@
-mkdir_p = @mkdir_p@
-oldincludedir = @oldincludedir@
-pdfdir = @pdfdir@
-prefix = @prefix@
-program_transform_name = @program_transform_name@
-psdir = @psdir@
-sbindir = @sbindir@
-sharedstatedir = @sharedstatedir@
-srcdir = @srcdir@
-sysconfdir = @sysconfdir@
-target_alias = @target_alias@
-top_build_prefix = @top_build_prefix@
-top_builddir = @top_builddir@
-top_srcdir = @top_srcdir@
-noinst_LTLIBRARIES = libhb-ucdn.la
-NULL = 
-LIBHB_UCDN_sources = \
-       ucdn.h \
-       ucdn.c \
-       ucdn_db.h \
-       $(NULL)
-
-libhb_ucdn_la_SOURCES = $(LIBHB_UCDN_sources)
-libhb_ucdn_la_CPPFLAGS = \
-       -I$(top_srcdir) \
-       -I$(top_srcdir)/src \
-       -I$(top_builddir)/src
-
-libhb_ucdn_la_LIBADD = 
-EXTRA_DIST = README COPYING
-all: all-am
-
-.SUFFIXES:
-.SUFFIXES: .c .lo .o .obj
-$(srcdir)/Makefile.in:  $(srcdir)/Makefile.am $(srcdir)/Makefile.sources $(am__configure_deps)
-       @for dep in $?; do \
-         case '$(am__configure_deps)' in \
-           *$$dep*) \
-             ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
-               && { if test -f $@; then exit 0; else break; fi; }; \
-             exit 1;; \
-         esac; \
-       done; \
-       echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnits src/hb-ucdn/Makefile'; \
-       $(am__cd) $(top_srcdir) && \
-         $(AUTOMAKE) --gnits src/hb-ucdn/Makefile
-Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
-       @case '$?' in \
-         *config.status*) \
-           cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
-         *) \
-           echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \
-           cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \
-       esac;
-$(srcdir)/Makefile.sources $(am__empty):
-
-$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
-       cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
-
-$(top_srcdir)/configure:  $(am__configure_deps)
-       cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
-$(ACLOCAL_M4):  $(am__aclocal_m4_deps)
-       cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
-$(am__aclocal_m4_deps):
-
-clean-noinstLTLIBRARIES:
-       -test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES)
-       @list='$(noinst_LTLIBRARIES)'; \
-       locs=`for p in $$list; do echo $$p; done | \
-             sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \
-             sort -u`; \
-       test -z "$$locs" || { \
-         echo rm -f $${locs}; \
-         rm -f $${locs}; \
-       }
-
-libhb-ucdn.la: $(libhb_ucdn_la_OBJECTS) $(libhb_ucdn_la_DEPENDENCIES) $(EXTRA_libhb_ucdn_la_DEPENDENCIES) 
-       $(AM_V_CCLD)$(LINK)  $(libhb_ucdn_la_OBJECTS) $(libhb_ucdn_la_LIBADD) $(LIBS)
-
-mostlyclean-compile:
-       -rm -f *.$(OBJEXT)
-
-distclean-compile:
-       -rm -f *.tab.c
-
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libhb_ucdn_la-ucdn.Plo@am__quote@ # am--include-marker
-
-$(am__depfiles_remade):
-       @$(MKDIR_P) $(@D)
-       @echo '# dummy' >$@-t && $(am__mv) $@-t $@
-
-am--depfiles: $(am__depfiles_remade)
-
-.c.o:
-@am__fastdepCC_TRUE@   $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
-@am__fastdepCC_TRUE@   $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
-@AMDEP_TRUE@@am__fastdepCC_FALSE@      $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
-@AMDEP_TRUE@@am__fastdepCC_FALSE@      DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@  $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $<
-
-.c.obj:
-@am__fastdepCC_TRUE@   $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'`
-@am__fastdepCC_TRUE@   $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
-@AMDEP_TRUE@@am__fastdepCC_FALSE@      $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
-@AMDEP_TRUE@@am__fastdepCC_FALSE@      DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@  $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'`
-
-.c.lo:
-@am__fastdepCC_TRUE@   $(AM_V_CC)$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
-@am__fastdepCC_TRUE@   $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo
-@AMDEP_TRUE@@am__fastdepCC_FALSE@      $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
-@AMDEP_TRUE@@am__fastdepCC_FALSE@      DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@  $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $<
-
-libhb_ucdn_la-ucdn.lo: ucdn.c
-@am__fastdepCC_TRUE@   $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libhb_ucdn_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libhb_ucdn_la-ucdn.lo -MD -MP -MF $(DEPDIR)/libhb_ucdn_la-ucdn.Tpo -c -o libhb_ucdn_la-ucdn.lo `test -f 'ucdn.c' || echo '$(srcdir)/'`ucdn.c
-@am__fastdepCC_TRUE@   $(AM_V_at)$(am__mv) $(DEPDIR)/libhb_ucdn_la-ucdn.Tpo $(DEPDIR)/libhb_ucdn_la-ucdn.Plo
-@AMDEP_TRUE@@am__fastdepCC_FALSE@      $(AM_V_CC)source='ucdn.c' object='libhb_ucdn_la-ucdn.lo' libtool=yes @AMDEPBACKSLASH@
-@AMDEP_TRUE@@am__fastdepCC_FALSE@      DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@  $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libhb_ucdn_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libhb_ucdn_la-ucdn.lo `test -f 'ucdn.c' || echo '$(srcdir)/'`ucdn.c
-
-mostlyclean-libtool:
-       -rm -f *.lo
-
-clean-libtool:
-       -rm -rf .libs _libs
-
-ID: $(am__tagged_files)
-       $(am__define_uniq_tagged_files); mkid -fID $$unique
-tags: tags-am
-TAGS: tags
-
-tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
-       set x; \
-       here=`pwd`; \
-       $(am__define_uniq_tagged_files); \
-       shift; \
-       if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \
-         test -n "$$unique" || unique=$$empty_fix; \
-         if test $$# -gt 0; then \
-           $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
-             "$$@" $$unique; \
-         else \
-           $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
-             $$unique; \
-         fi; \
-       fi
-ctags: ctags-am
-
-CTAGS: ctags
-ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
-       $(am__define_uniq_tagged_files); \
-       test -z "$(CTAGS_ARGS)$$unique" \
-         || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
-            $$unique
-
-GTAGS:
-       here=`$(am__cd) $(top_builddir) && pwd` \
-         && $(am__cd) $(top_srcdir) \
-         && gtags -i $(GTAGS_ARGS) "$$here"
-cscopelist: cscopelist-am
-
-cscopelist-am: $(am__tagged_files)
-       list='$(am__tagged_files)'; \
-       case "$(srcdir)" in \
-         [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \
-         *) sdir=$(subdir)/$(srcdir) ;; \
-       esac; \
-       for i in $$list; do \
-         if test -f "$$i"; then \
-           echo "$(subdir)/$$i"; \
-         else \
-           echo "$$sdir/$$i"; \
-         fi; \
-       done >> $(top_builddir)/cscope.files
-
-distclean-tags:
-       -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
-
-distdir: $(BUILT_SOURCES)
-       $(MAKE) $(AM_MAKEFLAGS) distdir-am
-
-distdir-am: $(DISTFILES)
-       @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
-       topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
-       list='$(DISTFILES)'; \
-         dist_files=`for file in $$list; do echo $$file; done | \
-         sed -e "s|^$$srcdirstrip/||;t" \
-             -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
-       case $$dist_files in \
-         */*) $(MKDIR_P) `echo "$$dist_files" | \
-                          sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
-                          sort -u` ;; \
-       esac; \
-       for file in $$dist_files; do \
-         if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
-         if test -d $$d/$$file; then \
-           dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
-           if test -d "$(distdir)/$$file"; then \
-             find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
-           fi; \
-           if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
-             cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
-             find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
-           fi; \
-           cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
-         else \
-           test -f "$(distdir)/$$file" \
-           || cp -p $$d/$$file "$(distdir)/$$file" \
-           || exit 1; \
-         fi; \
-       done
-check-am: all-am
-check: check-am
-all-am: Makefile $(LTLIBRARIES)
-installdirs:
-install: install-am
-install-exec: install-exec-am
-install-data: install-data-am
-uninstall: uninstall-am
-
-install-am: all-am
-       @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
-
-installcheck: installcheck-am
-install-strip:
-       if test -z '$(STRIP)'; then \
-         $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
-           install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
-             install; \
-       else \
-         $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
-           install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
-           "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
-       fi
-mostlyclean-generic:
-
-clean-generic:
-
-distclean-generic:
-       -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
-       -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
-
-maintainer-clean-generic:
-       @echo "This command is intended for maintainers to use"
-       @echo "it deletes files that may require special tools to rebuild."
-clean: clean-am
-
-clean-am: clean-generic clean-libtool clean-noinstLTLIBRARIES \
-       mostlyclean-am
-
-distclean: distclean-am
-               -rm -f ./$(DEPDIR)/libhb_ucdn_la-ucdn.Plo
-       -rm -f Makefile
-distclean-am: clean-am distclean-compile distclean-generic \
-       distclean-tags
-
-dvi: dvi-am
-
-dvi-am:
-
-html: html-am
-
-html-am:
-
-info: info-am
-
-info-am:
-
-install-data-am:
-
-install-dvi: install-dvi-am
-
-install-dvi-am:
-
-install-exec-am:
-
-install-html: install-html-am
-
-install-html-am:
-
-install-info: install-info-am
-
-install-info-am:
-
-install-man:
-
-install-pdf: install-pdf-am
-
-install-pdf-am:
-
-install-ps: install-ps-am
-
-install-ps-am:
-
-installcheck-am:
-
-maintainer-clean: maintainer-clean-am
-               -rm -f ./$(DEPDIR)/libhb_ucdn_la-ucdn.Plo
-       -rm -f Makefile
-maintainer-clean-am: distclean-am maintainer-clean-generic
-
-mostlyclean: mostlyclean-am
-
-mostlyclean-am: mostlyclean-compile mostlyclean-generic \
-       mostlyclean-libtool
-
-pdf: pdf-am
-
-pdf-am:
-
-ps: ps-am
-
-ps-am:
-
-uninstall-am:
-
-.MAKE: install-am install-strip
-
-.PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-am clean \
-       clean-generic clean-libtool clean-noinstLTLIBRARIES \
-       cscopelist-am ctags ctags-am distclean distclean-compile \
-       distclean-generic distclean-libtool distclean-tags distdir dvi \
-       dvi-am html html-am info info-am install install-am \
-       install-data install-data-am install-dvi install-dvi-am \
-       install-exec install-exec-am install-html install-html-am \
-       install-info install-info-am install-man install-pdf \
-       install-pdf-am install-ps install-ps-am install-strip \
-       installcheck installcheck-am installdirs maintainer-clean \
-       maintainer-clean-generic mostlyclean mostlyclean-compile \
-       mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
-       tags tags-am uninstall uninstall-am
-
-.PRECIOUS: Makefile
-
-
--include $(top_srcdir)/git.mk
-
-# Tell versions [3.59,3.63) of GNU make to not export all variables.
-# Otherwise a system limit (for SysV at least) may be exceeded.
-.NOEXPORT:
diff --git a/src/hb-ucdn/Makefile.sources b/src/hb-ucdn/Makefile.sources
deleted file mode 100644 (file)
index cb823b6..0000000
+++ /dev/null
@@ -1,7 +0,0 @@
-NULL =
-
-LIBHB_UCDN_sources = \
-       ucdn.h \
-       ucdn.c \
-       ucdn_db.h \
-       $(NULL)
diff --git a/src/hb-ucdn/README b/src/hb-ucdn/README
deleted file mode 100644 (file)
index 2203ae6..0000000
+++ /dev/null
@@ -1,40 +0,0 @@
-Contents of this directory are derived from UCDN:
-
-  https://github.com/grigorig/ucdn
-
-The original README follows:
-
-
-UCDN - Unicode Database and Normalization
-
-UCDN is a Unicode support library. Currently, it provides access
-to basic character properties contained in the Unicode Character
-Database and low-level normalization functions (pairwise canonical
-composition/decomposition and compatibility decomposition). More
-functionality might be provided in the future, such as additional
-properties, string normalization and encoding conversion.
-
-UCDN uses standard C89 with no particular dependencies or requirements
-except for stdint.h, and can be easily integrated into existing
-projects. However, it can also be used as a standalone library,
-and a CMake build script is provided for this. The first motivation
-behind UCDN development was to provide a standalone set of Unicode
-functions for the HarfBuzz OpenType shaping library. For this purpose,
-a HarfBuzz-specific wrapper is shipped along with it (hb-ucdn.h).
-
-UCDN is published under the ISC license, please see the license header
-in the C source code for more information. The makeunicodata.py script
-required for parsing Unicode database files is licensed under the
-PSF license, please see PYTHON-LICENSE for more information.
-
-UCDN was written by Grigori Goronzy <greg@kinoho.net>.
-
-How to Use
-
-Include ucdn.c, ucdn.h and ucdn_db.h in your project. Now, just use the
-functions as documented in ucdn.h.
-
-In some cases, it might be necessary to regenerate the Unicode
-database file. The script makeunicodedata.py (Python 3.x required)
-fetches the appropriate files and dumps the compressed database into
-ucdn_db.h.
diff --git a/src/hb-ucdn/ucdn.c b/src/hb-ucdn/ucdn.c
deleted file mode 100644 (file)
index 30747fe..0000000
+++ /dev/null
@@ -1,360 +0,0 @@
-/*
- * Copyright (C) 2012 Grigori Goronzy <greg@kinoho.net>
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
- * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <stdint.h>
-#include "ucdn.h"
-
-typedef struct {
-    unsigned char category;
-    unsigned char combining;
-    unsigned char bidi_class;
-    unsigned char east_asian_width;
-    unsigned char script;
-    unsigned char linebreak_class;
-} UCDRecord;
-
-typedef struct {
-    unsigned short from, to;
-} MirrorPair;
-
-typedef struct {
-  unsigned short from, to;
-  unsigned char type;
-} BracketPair;
-
-typedef struct {
-    unsigned int start;
-    short count, index;
-} Reindex;
-
-#include "ucdn_db.h"
-
-/* constants required for Hangul (de)composition */
-#define SBASE 0xAC00
-#define LBASE 0x1100
-#define VBASE 0x1161
-#define TBASE 0x11A7
-#define SCOUNT 11172
-#define LCOUNT 19
-#define VCOUNT 21
-#define TCOUNT 28
-#define NCOUNT (VCOUNT * TCOUNT)
-
-static const UCDRecord *get_ucd_record(uint32_t code)
-{
-    int index, offset;
-
-    if (code >= 0x110000)
-        index = 0;
-    else {
-        index  = index0[code >> (SHIFT1+SHIFT2)] << SHIFT1;
-        offset = (code >> SHIFT2) & ((1<<SHIFT1) - 1);
-        index  = index1[index + offset] << SHIFT2;
-        offset = code & ((1<<SHIFT2) - 1);
-        index  = index2[index + offset];
-    }
-
-    return &ucd_records[index];
-}
-
-static const unsigned short *get_decomp_record(uint32_t code)
-{
-    int index, offset;
-
-    if (code >= 0x110000)
-        index = 0;
-    else {
-        index  = decomp_index0[code >> (DECOMP_SHIFT1+DECOMP_SHIFT2)]
-            << DECOMP_SHIFT1;
-        offset = (code >> DECOMP_SHIFT2) & ((1<<DECOMP_SHIFT1) - 1);
-        index  = decomp_index1[index + offset] << DECOMP_SHIFT2;
-        offset = code & ((1<<DECOMP_SHIFT2) - 1);
-        index  = decomp_index2[index + offset];
-    }
-
-    return &decomp_data[index];
-}
-
-static int compare_reindex(const void *a, const void *b)
-{
-    Reindex *ra = (Reindex *)a;
-    Reindex *rb = (Reindex *)b;
-
-    if (ra->start < rb->start)
-        return -1;
-    else if (ra->start > (rb->start + rb->count))
-        return 1;
-    else
-        return 0;
-}
-
-static int get_comp_index(uint32_t code, const Reindex *idx, size_t len)
-{
-    Reindex *res;
-    Reindex r = {0, 0, 0};
-    r.start = code;
-    res = (Reindex *) bsearch(&r, idx, len, sizeof(Reindex), compare_reindex);
-
-    if (res != NULL)
-        return res->index + (code - res->start);
-    else
-        return -1;
-}
-
-static int compare_mp(const void *a, const void *b)
-{
-    MirrorPair *mpa = (MirrorPair *)a;
-    MirrorPair *mpb = (MirrorPair *)b;
-    return mpa->from - mpb->from;
-}
-
-static int compare_bp(const void *a, const void *b)
-{
-    BracketPair *bpa = (BracketPair *)a;
-    BracketPair *bpb = (BracketPair *)b;
-    return bpa->from - bpb->from;
-}
-
-static BracketPair *search_bp(uint32_t code)
-{
-    BracketPair bp = {0,0,2};
-    BracketPair *res;
-
-    bp.from = code;
-    res = (BracketPair *) bsearch(&bp, bracket_pairs, BIDI_BRACKET_LEN,
-                                 sizeof(BracketPair), compare_bp);
-    return res;
-}
-
-static int hangul_pair_decompose(uint32_t code, uint32_t *a, uint32_t *b)
-{
-    int si = code - SBASE;
-
-    if (si < 0 || si >= SCOUNT)
-        return 0;
-
-    if (si % TCOUNT) {
-        /* LV,T */
-        *a = SBASE + (si / TCOUNT) * TCOUNT;
-        *b = TBASE + (si % TCOUNT);
-        return 3;
-    } else {
-        /* L,V */
-        *a = LBASE + (si / NCOUNT);
-        *b = VBASE + (si % NCOUNT) / TCOUNT;
-        return 2;
-    }
-}
-
-static int hangul_pair_compose(uint32_t *code, uint32_t a, uint32_t b)
-{
-    if (a >= SBASE && a < (SBASE + SCOUNT) && b >= TBASE && b < (TBASE + TCOUNT)) {
-        /* LV,T */
-        *code = a + (b - TBASE);
-        return 3;
-    } else if (a >= LBASE && a < (LBASE + LCOUNT) && b >= VBASE && b < (VBASE + VCOUNT)) {
-        /* L,V */
-        int li = a - LBASE;
-        int vi = b - VBASE;
-        *code = SBASE + li * NCOUNT + vi * TCOUNT;
-        return 2;
-    } else {
-        return 0;
-    }
-}
-
-static uint32_t decode_utf16(const unsigned short **code_ptr)
-{
-    const unsigned short *code = *code_ptr;
-
-    if (code[0] < 0xd800 || code[0] > 0xdc00) {
-        *code_ptr += 1;
-        return (uint32_t)code[0];
-    } else {
-        *code_ptr += 2;
-        return 0x10000 + ((uint32_t)code[1] - 0xdc00) +
-            (((uint32_t)code[0] - 0xd800) << 10);
-    }
-}
-
-const char *ucdn_get_unicode_version(void)
-{
-    return UNIDATA_VERSION;
-}
-
-int ucdn_get_combining_class(uint32_t code)
-{
-    return get_ucd_record(code)->combining;
-}
-
-int ucdn_get_east_asian_width(uint32_t code)
-{
-    return get_ucd_record(code)->east_asian_width;
-}
-
-int ucdn_get_general_category(uint32_t code)
-{
-    return get_ucd_record(code)->category;
-}
-
-int ucdn_get_bidi_class(uint32_t code)
-{
-    return get_ucd_record(code)->bidi_class;
-}
-
-int ucdn_get_mirrored(uint32_t code)
-{
-    return ucdn_mirror(code) != code;
-}
-
-int ucdn_get_script(uint32_t code)
-{
-    return get_ucd_record(code)->script;
-}
-
-int ucdn_get_linebreak_class(uint32_t code)
-{
-    return get_ucd_record(code)->linebreak_class;
-}
-
-int ucdn_get_resolved_linebreak_class(uint32_t code)
-{
-    const UCDRecord *record = get_ucd_record(code);
-
-    switch (record->linebreak_class)
-    {
-    case UCDN_LINEBREAK_CLASS_AI:
-    case UCDN_LINEBREAK_CLASS_SG:
-    case UCDN_LINEBREAK_CLASS_XX:
-        return UCDN_LINEBREAK_CLASS_AL;
-
-    case UCDN_LINEBREAK_CLASS_SA:
-        if (record->category == UCDN_GENERAL_CATEGORY_MC ||
-                record->category == UCDN_GENERAL_CATEGORY_MN)
-            return UCDN_LINEBREAK_CLASS_CM;
-        return UCDN_LINEBREAK_CLASS_AL;
-
-    case UCDN_LINEBREAK_CLASS_CJ:
-        return UCDN_LINEBREAK_CLASS_NS;
-
-    case UCDN_LINEBREAK_CLASS_CB:
-        return UCDN_LINEBREAK_CLASS_B2;
-
-    case UCDN_LINEBREAK_CLASS_NL:
-        return UCDN_LINEBREAK_CLASS_BK;
-
-    default:
-        return record->linebreak_class;
-    }
-}
-
-uint32_t ucdn_mirror(uint32_t code)
-{
-    MirrorPair mp = {0};
-    MirrorPair *res;
-
-    mp.from = code;
-    res = (MirrorPair *) bsearch(&mp, mirror_pairs, BIDI_MIRROR_LEN,
-                                sizeof(MirrorPair), compare_mp);
-
-    if (res == NULL)
-        return code;
-    else
-        return res->to;
-}
-
-uint32_t ucdn_paired_bracket(uint32_t code)
-{
-    BracketPair *res = search_bp(code);
-    if (res == NULL)
-        return code;
-    else
-        return res->to;
-}
-
-int ucdn_paired_bracket_type(uint32_t code)
-{
-    BracketPair *res = search_bp(code);
-    if (res == NULL)
-        return UCDN_BIDI_PAIRED_BRACKET_TYPE_NONE;
-    else
-        return res->type;
-}
-
-int ucdn_decompose(uint32_t code, uint32_t *a, uint32_t *b)
-{
-    const unsigned short *rec;
-    int len;
-
-    if (hangul_pair_decompose(code, a, b))
-        return 1;
-
-    rec = get_decomp_record(code);
-    len = rec[0] >> 8;
-
-    if ((rec[0] & 0xff) != 0 || len == 0)
-        return 0;
-
-    rec++;
-    *a = decode_utf16(&rec);
-    if (len > 1)
-        *b = decode_utf16(&rec);
-    else
-        *b = 0;
-
-    return 1;
-}
-
-int ucdn_compose(uint32_t *code, uint32_t a, uint32_t b)
-{
-    int l, r, index, indexi, offset;
-
-    if (hangul_pair_compose(code, a, b))
-        return 1;
-
-    l = get_comp_index(a, nfc_first, sizeof(nfc_first) / sizeof(Reindex));
-    r = get_comp_index(b, nfc_last, sizeof(nfc_last) / sizeof(Reindex));
-
-    if (l < 0 || r < 0)
-        return 0;
-
-    indexi = l * TOTAL_LAST + r;
-    index  = comp_index0[indexi >> (COMP_SHIFT1+COMP_SHIFT2)] << COMP_SHIFT1;
-    offset = (indexi >> COMP_SHIFT2) & ((1<<COMP_SHIFT1) - 1);
-    index  = comp_index1[index + offset] << COMP_SHIFT2;
-    offset = indexi & ((1<<COMP_SHIFT2) - 1);
-    *code  = comp_data[index + offset];
-
-    return *code != 0;
-}
-
-int ucdn_compat_decompose(uint32_t code, uint32_t *decomposed)
-{
-    int i, len;
-    const unsigned short *rec = get_decomp_record(code);
-    len = rec[0] >> 8;
-
-    if (len == 0)
-        return 0;
-
-    rec++;
-    for (i = 0; i < len; i++)
-        decomposed[i] = decode_utf16(&rec);
-
-    return len;
-}
diff --git a/src/hb-ucdn/ucdn.h b/src/hb-ucdn/ucdn.h
deleted file mode 100644 (file)
index 1317d4f..0000000
+++ /dev/null
@@ -1,472 +0,0 @@
-/*
- * Copyright (C) 2012 Grigori Goronzy <greg@kinoho.net>
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
- * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- */
-
-#ifndef UCDN_H
-#define UCDN_H
-
-
-
-#if defined(__GNUC__) && (__GNUC__ >= 4) && !defined(__MINGW32__)
-# define HB_BEGIN_VISIBILITY _Pragma ("GCC visibility push(hidden)")
-# define HB_END_VISIBILITY _Pragma ("GCC visibility pop")
-#else
-# define HB_BEGIN_VISIBILITY
-# define HB_END_VISIBILITY
-#endif
-#ifdef __cplusplus
-# define HB_BEGIN_HEADER  extern "C" { HB_BEGIN_VISIBILITY
-# define HB_END_HEADER  HB_END_VISIBILITY }
-#else
-# define HB_BEGIN_HEADER  HB_BEGIN_VISIBILITY
-# define HB_END_HEADER  HB_END_VISIBILITY
-#endif
-
-HB_BEGIN_HEADER
-
-#if defined (_SVR4) || defined (SVR4) || defined (__OpenBSD__) || \
-    defined (_sgi) || defined (__sun) || defined (sun) || \
-    defined (__digital__) || defined (__HP_cc)
-#  include <inttypes.h>
-#elif defined (_AIX)
-#  include <sys/inttypes.h>
-#elif defined (_MSC_VER) && _MSC_VER < 1600
-/* VS 2010 (_MSC_VER 1600) has stdint.h */
-typedef __int8 int8_t;
-typedef unsigned __int8 uint8_t;
-typedef __int16 int16_t;
-typedef unsigned __int16 uint16_t;
-typedef __int32 int32_t;
-typedef unsigned __int32 uint32_t;
-typedef __int64 int64_t;
-typedef unsigned __int64 uint64_t;
-#else
-#  include <stdint.h>
-#endif
-
-
-#define UCDN_EAST_ASIAN_F 0
-#define UCDN_EAST_ASIAN_H 1
-#define UCDN_EAST_ASIAN_W 2
-#define UCDN_EAST_ASIAN_NA 3
-#define UCDN_EAST_ASIAN_A 4
-#define UCDN_EAST_ASIAN_N 5
-
-#define UCDN_SCRIPT_COMMON 0
-#define UCDN_SCRIPT_LATIN 1
-#define UCDN_SCRIPT_GREEK 2
-#define UCDN_SCRIPT_CYRILLIC 3
-#define UCDN_SCRIPT_ARMENIAN 4
-#define UCDN_SCRIPT_HEBREW 5
-#define UCDN_SCRIPT_ARABIC 6
-#define UCDN_SCRIPT_SYRIAC 7
-#define UCDN_SCRIPT_THAANA 8
-#define UCDN_SCRIPT_DEVANAGARI 9
-#define UCDN_SCRIPT_BENGALI 10
-#define UCDN_SCRIPT_GURMUKHI 11
-#define UCDN_SCRIPT_GUJARATI 12
-#define UCDN_SCRIPT_ORIYA 13
-#define UCDN_SCRIPT_TAMIL 14
-#define UCDN_SCRIPT_TELUGU 15
-#define UCDN_SCRIPT_KANNADA 16
-#define UCDN_SCRIPT_MALAYALAM 17
-#define UCDN_SCRIPT_SINHALA 18
-#define UCDN_SCRIPT_THAI 19
-#define UCDN_SCRIPT_LAO 20
-#define UCDN_SCRIPT_TIBETAN 21
-#define UCDN_SCRIPT_MYANMAR 22
-#define UCDN_SCRIPT_GEORGIAN 23
-#define UCDN_SCRIPT_HANGUL 24
-#define UCDN_SCRIPT_ETHIOPIC 25
-#define UCDN_SCRIPT_CHEROKEE 26
-#define UCDN_SCRIPT_CANADIAN_ABORIGINAL 27
-#define UCDN_SCRIPT_OGHAM 28
-#define UCDN_SCRIPT_RUNIC 29
-#define UCDN_SCRIPT_KHMER 30
-#define UCDN_SCRIPT_MONGOLIAN 31
-#define UCDN_SCRIPT_HIRAGANA 32
-#define UCDN_SCRIPT_KATAKANA 33
-#define UCDN_SCRIPT_BOPOMOFO 34
-#define UCDN_SCRIPT_HAN 35
-#define UCDN_SCRIPT_YI 36
-#define UCDN_SCRIPT_OLD_ITALIC 37
-#define UCDN_SCRIPT_GOTHIC 38
-#define UCDN_SCRIPT_DESERET 39
-#define UCDN_SCRIPT_INHERITED 40
-#define UCDN_SCRIPT_TAGALOG 41
-#define UCDN_SCRIPT_HANUNOO 42
-#define UCDN_SCRIPT_BUHID 43
-#define UCDN_SCRIPT_TAGBANWA 44
-#define UCDN_SCRIPT_LIMBU 45
-#define UCDN_SCRIPT_TAI_LE 46
-#define UCDN_SCRIPT_LINEAR_B 47
-#define UCDN_SCRIPT_UGARITIC 48
-#define UCDN_SCRIPT_SHAVIAN 49
-#define UCDN_SCRIPT_OSMANYA 50
-#define UCDN_SCRIPT_CYPRIOT 51
-#define UCDN_SCRIPT_BRAILLE 52
-#define UCDN_SCRIPT_BUGINESE 53
-#define UCDN_SCRIPT_COPTIC 54
-#define UCDN_SCRIPT_NEW_TAI_LUE 55
-#define UCDN_SCRIPT_GLAGOLITIC 56
-#define UCDN_SCRIPT_TIFINAGH 57
-#define UCDN_SCRIPT_SYLOTI_NAGRI 58
-#define UCDN_SCRIPT_OLD_PERSIAN 59
-#define UCDN_SCRIPT_KHAROSHTHI 60
-#define UCDN_SCRIPT_BALINESE 61
-#define UCDN_SCRIPT_CUNEIFORM 62
-#define UCDN_SCRIPT_PHOENICIAN 63
-#define UCDN_SCRIPT_PHAGS_PA 64
-#define UCDN_SCRIPT_NKO 65
-#define UCDN_SCRIPT_SUNDANESE 66
-#define UCDN_SCRIPT_LEPCHA 67
-#define UCDN_SCRIPT_OL_CHIKI 68
-#define UCDN_SCRIPT_VAI 69
-#define UCDN_SCRIPT_SAURASHTRA 70
-#define UCDN_SCRIPT_KAYAH_LI 71
-#define UCDN_SCRIPT_REJANG 72
-#define UCDN_SCRIPT_LYCIAN 73
-#define UCDN_SCRIPT_CARIAN 74
-#define UCDN_SCRIPT_LYDIAN 75
-#define UCDN_SCRIPT_CHAM 76
-#define UCDN_SCRIPT_TAI_THAM 77
-#define UCDN_SCRIPT_TAI_VIET 78
-#define UCDN_SCRIPT_AVESTAN 79
-#define UCDN_SCRIPT_EGYPTIAN_HIEROGLYPHS 80
-#define UCDN_SCRIPT_SAMARITAN 81
-#define UCDN_SCRIPT_LISU 82
-#define UCDN_SCRIPT_BAMUM 83
-#define UCDN_SCRIPT_JAVANESE 84
-#define UCDN_SCRIPT_MEETEI_MAYEK 85
-#define UCDN_SCRIPT_IMPERIAL_ARAMAIC 86
-#define UCDN_SCRIPT_OLD_SOUTH_ARABIAN 87
-#define UCDN_SCRIPT_INSCRIPTIONAL_PARTHIAN 88
-#define UCDN_SCRIPT_INSCRIPTIONAL_PAHLAVI 89
-#define UCDN_SCRIPT_OLD_TURKIC 90
-#define UCDN_SCRIPT_KAITHI 91
-#define UCDN_SCRIPT_BATAK 92
-#define UCDN_SCRIPT_BRAHMI 93
-#define UCDN_SCRIPT_MANDAIC 94
-#define UCDN_SCRIPT_CHAKMA 95
-#define UCDN_SCRIPT_MEROITIC_CURSIVE 96
-#define UCDN_SCRIPT_MEROITIC_HIEROGLYPHS 97
-#define UCDN_SCRIPT_MIAO 98
-#define UCDN_SCRIPT_SHARADA 99
-#define UCDN_SCRIPT_SORA_SOMPENG 100
-#define UCDN_SCRIPT_TAKRI 101
-#define UCDN_SCRIPT_UNKNOWN 102
-#define UCDN_SCRIPT_BASSA_VAH 103
-#define UCDN_SCRIPT_CAUCASIAN_ALBANIAN 104
-#define UCDN_SCRIPT_DUPLOYAN 105
-#define UCDN_SCRIPT_ELBASAN 106
-#define UCDN_SCRIPT_GRANTHA 107
-#define UCDN_SCRIPT_KHOJKI 108
-#define UCDN_SCRIPT_KHUDAWADI 109
-#define UCDN_SCRIPT_LINEAR_A 110
-#define UCDN_SCRIPT_MAHAJANI 111
-#define UCDN_SCRIPT_MANICHAEAN 112
-#define UCDN_SCRIPT_MENDE_KIKAKUI 113
-#define UCDN_SCRIPT_MODI 114
-#define UCDN_SCRIPT_MRO 115
-#define UCDN_SCRIPT_NABATAEAN 116
-#define UCDN_SCRIPT_OLD_NORTH_ARABIAN 117
-#define UCDN_SCRIPT_OLD_PERMIC 118
-#define UCDN_SCRIPT_PAHAWH_HMONG 119
-#define UCDN_SCRIPT_PALMYRENE 120
-#define UCDN_SCRIPT_PAU_CIN_HAU 121
-#define UCDN_SCRIPT_PSALTER_PAHLAVI 122
-#define UCDN_SCRIPT_SIDDHAM 123
-#define UCDN_SCRIPT_TIRHUTA 124
-#define UCDN_SCRIPT_WARANG_CITI 125
-#define UCDN_SCRIPT_AHOM 126
-#define UCDN_SCRIPT_ANATOLIAN_HIEROGLYPHS 127
-#define UCDN_SCRIPT_HATRAN 128
-#define UCDN_SCRIPT_MULTANI 129
-#define UCDN_SCRIPT_OLD_HUNGARIAN 130
-#define UCDN_SCRIPT_SIGNWRITING 131
-#define UCDN_SCRIPT_ADLAM 132
-#define UCDN_SCRIPT_BHAIKSUKI 133
-#define UCDN_SCRIPT_MARCHEN 134
-#define UCDN_SCRIPT_NEWA 135
-#define UCDN_SCRIPT_OSAGE 136
-#define UCDN_SCRIPT_TANGUT 137
-#define UCDN_SCRIPT_MASARAM_GONDI 138
-#define UCDN_SCRIPT_NUSHU 139
-#define UCDN_SCRIPT_SOYOMBO 140
-#define UCDN_SCRIPT_ZANABAZAR_SQUARE 141
-#define UCDN_SCRIPT_DOGRA 142
-#define UCDN_SCRIPT_GUNJALA_GONDI 143
-#define UCDN_SCRIPT_HANIFI_ROHINGYA 144
-#define UCDN_SCRIPT_MAKASAR 145
-#define UCDN_SCRIPT_MEDEFAIDRIN 146
-#define UCDN_SCRIPT_OLD_SOGDIAN 147
-#define UCDN_SCRIPT_SOGDIAN 148
-#define UCDN_SCRIPT_ELYMAIC 149
-#define UCDN_SCRIPT_NANDINAGARI 150
-#define UCDN_SCRIPT_NYIAKENG_PUACHUE_HMONG 151
-#define UCDN_SCRIPT_WANCHO 152
-
-#define UCDN_LINEBREAK_CLASS_OP 0
-#define UCDN_LINEBREAK_CLASS_CL 1
-#define UCDN_LINEBREAK_CLASS_CP 2
-#define UCDN_LINEBREAK_CLASS_QU 3
-#define UCDN_LINEBREAK_CLASS_GL 4
-#define UCDN_LINEBREAK_CLASS_NS 5
-#define UCDN_LINEBREAK_CLASS_EX 6
-#define UCDN_LINEBREAK_CLASS_SY 7
-#define UCDN_LINEBREAK_CLASS_IS 8
-#define UCDN_LINEBREAK_CLASS_PR 9
-#define UCDN_LINEBREAK_CLASS_PO 10
-#define UCDN_LINEBREAK_CLASS_NU 11
-#define UCDN_LINEBREAK_CLASS_AL 12
-#define UCDN_LINEBREAK_CLASS_HL 13
-#define UCDN_LINEBREAK_CLASS_ID 14
-#define UCDN_LINEBREAK_CLASS_IN 15
-#define UCDN_LINEBREAK_CLASS_HY 16
-#define UCDN_LINEBREAK_CLASS_BA 17
-#define UCDN_LINEBREAK_CLASS_BB 18
-#define UCDN_LINEBREAK_CLASS_B2 19
-#define UCDN_LINEBREAK_CLASS_ZW 20
-#define UCDN_LINEBREAK_CLASS_CM 21
-#define UCDN_LINEBREAK_CLASS_WJ 22
-#define UCDN_LINEBREAK_CLASS_H2 23
-#define UCDN_LINEBREAK_CLASS_H3 24
-#define UCDN_LINEBREAK_CLASS_JL 25
-#define UCDN_LINEBREAK_CLASS_JV 26
-#define UCDN_LINEBREAK_CLASS_JT 27
-#define UCDN_LINEBREAK_CLASS_RI 28
-#define UCDN_LINEBREAK_CLASS_AI 29
-#define UCDN_LINEBREAK_CLASS_BK 30
-#define UCDN_LINEBREAK_CLASS_CB 31
-#define UCDN_LINEBREAK_CLASS_CJ 32
-#define UCDN_LINEBREAK_CLASS_CR 33
-#define UCDN_LINEBREAK_CLASS_LF 34
-#define UCDN_LINEBREAK_CLASS_NL 35
-#define UCDN_LINEBREAK_CLASS_SA 36
-#define UCDN_LINEBREAK_CLASS_SG 37
-#define UCDN_LINEBREAK_CLASS_SP 38
-#define UCDN_LINEBREAK_CLASS_XX 39
-#define UCDN_LINEBREAK_CLASS_ZWJ 40
-#define UCDN_LINEBREAK_CLASS_EB 41
-#define UCDN_LINEBREAK_CLASS_EM 42
-
-#define UCDN_GENERAL_CATEGORY_CC 0
-#define UCDN_GENERAL_CATEGORY_CF 1
-#define UCDN_GENERAL_CATEGORY_CN 2
-#define UCDN_GENERAL_CATEGORY_CO 3
-#define UCDN_GENERAL_CATEGORY_CS 4
-#define UCDN_GENERAL_CATEGORY_LL 5
-#define UCDN_GENERAL_CATEGORY_LM 6
-#define UCDN_GENERAL_CATEGORY_LO 7
-#define UCDN_GENERAL_CATEGORY_LT 8
-#define UCDN_GENERAL_CATEGORY_LU 9
-#define UCDN_GENERAL_CATEGORY_MC 10
-#define UCDN_GENERAL_CATEGORY_ME 11
-#define UCDN_GENERAL_CATEGORY_MN 12
-#define UCDN_GENERAL_CATEGORY_ND 13
-#define UCDN_GENERAL_CATEGORY_NL 14
-#define UCDN_GENERAL_CATEGORY_NO 15
-#define UCDN_GENERAL_CATEGORY_PC 16
-#define UCDN_GENERAL_CATEGORY_PD 17
-#define UCDN_GENERAL_CATEGORY_PE 18
-#define UCDN_GENERAL_CATEGORY_PF 19
-#define UCDN_GENERAL_CATEGORY_PI 20
-#define UCDN_GENERAL_CATEGORY_PO 21
-#define UCDN_GENERAL_CATEGORY_PS 22
-#define UCDN_GENERAL_CATEGORY_SC 23
-#define UCDN_GENERAL_CATEGORY_SK 24
-#define UCDN_GENERAL_CATEGORY_SM 25
-#define UCDN_GENERAL_CATEGORY_SO 26
-#define UCDN_GENERAL_CATEGORY_ZL 27
-#define UCDN_GENERAL_CATEGORY_ZP 28
-#define UCDN_GENERAL_CATEGORY_ZS 29
-
-#define UCDN_BIDI_CLASS_L 0
-#define UCDN_BIDI_CLASS_LRE 1
-#define UCDN_BIDI_CLASS_LRO 2
-#define UCDN_BIDI_CLASS_R 3
-#define UCDN_BIDI_CLASS_AL 4
-#define UCDN_BIDI_CLASS_RLE 5
-#define UCDN_BIDI_CLASS_RLO 6
-#define UCDN_BIDI_CLASS_PDF 7
-#define UCDN_BIDI_CLASS_EN 8
-#define UCDN_BIDI_CLASS_ES 9
-#define UCDN_BIDI_CLASS_ET 10
-#define UCDN_BIDI_CLASS_AN 11
-#define UCDN_BIDI_CLASS_CS 12
-#define UCDN_BIDI_CLASS_NSM 13
-#define UCDN_BIDI_CLASS_BN 14
-#define UCDN_BIDI_CLASS_B 15
-#define UCDN_BIDI_CLASS_S 16
-#define UCDN_BIDI_CLASS_WS 17
-#define UCDN_BIDI_CLASS_ON 18
-#define UCDN_BIDI_CLASS_LRI 19
-#define UCDN_BIDI_CLASS_RLI 20
-#define UCDN_BIDI_CLASS_FSI 21
-#define UCDN_BIDI_CLASS_PDI 22
-
-#define UCDN_BIDI_PAIRED_BRACKET_TYPE_OPEN 0
-#define UCDN_BIDI_PAIRED_BRACKET_TYPE_CLOSE 1
-#define UCDN_BIDI_PAIRED_BRACKET_TYPE_NONE 2
-
-/**
- * Return version of the Unicode database.
- *
- * @return Unicode database version
- */
-const char *ucdn_get_unicode_version(void);
-
-/**
- * Get combining class of a codepoint.
- *
- * @param code Unicode codepoint
- * @return combining class value, as defined in UAX#44
- */
-int ucdn_get_combining_class(uint32_t code);
-
-/**
- * Get east-asian width of a codepoint.
- *
- * @param code Unicode codepoint
- * @return value according to UCDN_EAST_ASIAN_* and as defined in UAX#11.
- */
-int ucdn_get_east_asian_width(uint32_t code);
-
-/**
- * Get general category of a codepoint.
- *
- * @param code Unicode codepoint
- * @return value according to UCDN_GENERAL_CATEGORY_* and as defined in
- * UAX#44.
- */
-int ucdn_get_general_category(uint32_t code);
-
-/**
- * Get bidirectional class of a codepoint.
- *
- * @param code Unicode codepoint
- * @return value according to UCDN_BIDI_CLASS_* and as defined in UAX#44.
- */
-int ucdn_get_bidi_class(uint32_t code);
-
-/**
- * Get script of a codepoint.
- *
- * @param code Unicode codepoint
- * @return value according to UCDN_SCRIPT_* and as defined in UAX#24.
- */
-int ucdn_get_script(uint32_t code);
-
-/**
- * Get unresolved linebreak class of a codepoint. This does not take
- * rule LB1 of UAX#14 into account. See ucdn_get_resolved_linebreak_class()
- * for resolved linebreak classes.
- *
- * @param code Unicode codepoint
- * @return value according to UCDN_LINEBREAK_* and as defined in UAX#14.
- */
-int ucdn_get_linebreak_class(uint32_t code);
-
-/**
- * Get resolved linebreak class of a codepoint. This resolves characters
- * in the AI, SG, XX, SA and CJ classes according to rule LB1 of UAX#14.
- * In addition the CB class is resolved as the equivalent B2 class and
- * the NL class is resolved as the equivalent BK class.
- *
- * @param code Unicode codepoint
- * @return value according to UCDN_LINEBREAK_* and as defined in UAX#14.
- */
-int ucdn_get_resolved_linebreak_class(uint32_t code);
-
-/**
- * Check if codepoint can be mirrored.
- *
- * @param code Unicode codepoint
- * @return 1 if mirrored character exists, otherwise 0
- */
-int ucdn_get_mirrored(uint32_t code);
-
-/**
- * Mirror a codepoint.
- *
- * @param code Unicode codepoint
- * @return mirrored codepoint or the original codepoint if no
- * mirrored character exists
- */
-uint32_t ucdn_mirror(uint32_t code);
-
-/**
- * Get paired bracket for a codepoint.
- *
- * @param code Unicode codepoint
- * @return paired bracket codepoint or the original codepoint if no
- * paired bracket character exists
- */
-uint32_t ucdn_paired_bracket(uint32_t code);
-
-/**
- * Get paired bracket type for a codepoint.
- *
- * @param code Unicode codepoint
- * @return value according to UCDN_BIDI_PAIRED_BRACKET_TYPE_* and as defined
- * in UAX#9.
- *
- */
-int ucdn_paired_bracket_type(uint32_t code);
-
-/**
- * Pairwise canonical decomposition of a codepoint. This includes
- * Hangul Jamo decomposition (see chapter 3.12 of the Unicode core
- * specification).
- *
- * Hangul is decomposed into L and V jamos for LV forms, and an
- * LV precomposed syllable and a T jamo for LVT forms.
- *
- * @param code Unicode codepoint
- * @param a filled with first codepoint of decomposition
- * @param b filled with second codepoint of decomposition, or 0
- * @return success
- */
-int ucdn_decompose(uint32_t code, uint32_t *a, uint32_t *b);
-
-/**
- * Compatibility decomposition of a codepoint.
- *
- * @param code Unicode codepoint
- * @param decomposed filled with decomposition, must be able to hold 18
- * characters
- * @return length of decomposition or 0 in case none exists
- */
-int ucdn_compat_decompose(uint32_t code, uint32_t *decomposed);
-
-/**
- * Pairwise canonical composition of two codepoints. This includes
- * Hangul Jamo composition (see chapter 3.12 of the Unicode core
- * specification).
- *
- * Hangul composition expects either L and V jamos, or an LV
- * precomposed syllable and a T jamo. This is exactly the inverse
- * of pairwise Hangul decomposition.
- *
- * @param code filled with composition
- * @param a first codepoint
- * @param b second codepoint
- * @return success
- */
-int ucdn_compose(uint32_t *code, uint32_t a, uint32_t b);
-
-HB_END_HEADER
-
-#endif
diff --git a/src/hb-ucdn/ucdn_db.h b/src/hb-ucdn/ucdn_db.h
deleted file mode 100644 (file)
index 8f1310f..0000000
+++ /dev/null
@@ -1,5790 +0,0 @@
-/* this file was generated by makeunicodedata.py 3.2 */
-
-#define UNIDATA_VERSION "12.0.0"
-/* a list of unique database records */
-static const UCDRecord ucd_records[] = {
-    {2, 0, 18, 5, 102, 39},
-    {0, 0, 14, 5, 0, 21},
-    {0, 0, 16, 5, 0, 17},
-    {0, 0, 15, 5, 0, 34},
-    {0, 0, 16, 5, 0, 30},
-    {0, 0, 17, 5, 0, 30},
-    {0, 0, 15, 5, 0, 33},
-    {0, 0, 15, 5, 0, 21},
-    {0, 0, 16, 5, 0, 21},
-    {29, 0, 17, 3, 0, 38},
-    {21, 0, 18, 3, 0, 6},
-    {21, 0, 18, 3, 0, 3},
-    {21, 0, 10, 3, 0, 12},
-    {23, 0, 10, 3, 0, 9},
-    {21, 0, 10, 3, 0, 10},
-    {21, 0, 18, 3, 0, 12},
-    {22, 0, 18, 3, 0, 0},
-    {18, 0, 18, 3, 0, 2},
-    {25, 0, 9, 3, 0, 9},
-    {21, 0, 12, 3, 0, 8},
-    {17, 0, 9, 3, 0, 16},
-    {21, 0, 12, 3, 0, 7},
-    {13, 0, 8, 3, 0, 11},
-    {21, 0, 18, 3, 0, 8},
-    {25, 0, 18, 3, 0, 12},
-    {9, 0, 0, 3, 1, 12},
-    {21, 0, 18, 3, 0, 9},
-    {24, 0, 18, 3, 0, 12},
-    {16, 0, 18, 3, 0, 12},
-    {5, 0, 0, 3, 1, 12},
-    {25, 0, 18, 3, 0, 17},
-    {18, 0, 18, 3, 0, 1},
-    {0, 0, 15, 5, 0, 35},
-    {29, 0, 12, 5, 0, 4},
-    {21, 0, 18, 4, 0, 0},
-    {23, 0, 10, 3, 0, 10},
-    {23, 0, 10, 4, 0, 9},
-    {26, 0, 18, 3, 0, 12},
-    {21, 0, 18, 4, 0, 29},
-    {24, 0, 18, 4, 0, 29},
-    {26, 0, 18, 5, 0, 12},
-    {7, 0, 0, 4, 1, 29},
-    {20, 0, 18, 5, 0, 3},
-    {1, 0, 14, 4, 0, 17},
-    {26, 0, 18, 4, 0, 12},
-    {26, 0, 10, 4, 0, 10},
-    {25, 0, 10, 4, 0, 9},
-    {15, 0, 8, 4, 0, 29},
-    {24, 0, 18, 4, 0, 18},
-    {5, 0, 0, 5, 0, 12},
-    {19, 0, 18, 5, 0, 3},
-    {15, 0, 18, 4, 0, 29},
-    {9, 0, 0, 5, 1, 12},
-    {9, 0, 0, 4, 1, 12},
-    {25, 0, 18, 4, 0, 29},
-    {5, 0, 0, 4, 1, 12},
-    {5, 0, 0, 5, 1, 12},
-    {7, 0, 0, 5, 1, 12},
-    {8, 0, 0, 5, 1, 12},
-    {6, 0, 0, 5, 1, 12},
-    {6, 0, 18, 5, 0, 12},
-    {6, 0, 0, 5, 0, 12},
-    {24, 0, 18, 5, 0, 12},
-    {24, 0, 18, 4, 0, 12},
-    {6, 0, 18, 4, 0, 29},
-    {6, 0, 18, 5, 0, 18},
-    {6, 0, 0, 4, 0, 29},
-    {24, 0, 18, 5, 34, 12},
-    {12, 230, 13, 4, 40, 21},
-    {12, 232, 13, 4, 40, 21},
-    {12, 220, 13, 4, 40, 21},
-    {12, 216, 13, 4, 40, 21},
-    {12, 202, 13, 4, 40, 21},
-    {12, 1, 13, 4, 40, 21},
-    {12, 240, 13, 4, 40, 21},
-    {12, 0, 13, 4, 40, 4},
-    {12, 233, 13, 4, 40, 4},
-    {12, 234, 13, 4, 40, 4},
-    {9, 0, 0, 5, 2, 12},
-    {5, 0, 0, 5, 2, 12},
-    {24, 0, 18, 5, 2, 12},
-    {2, 0, 18, 5, 102, 39},
-    {6, 0, 0, 5, 2, 12},
-    {21, 0, 18, 5, 0, 8},
-    {21, 0, 18, 5, 0, 12},
-    {9, 0, 0, 4, 2, 12},
-    {5, 0, 0, 4, 2, 12},
-    {9, 0, 0, 5, 54, 12},
-    {5, 0, 0, 5, 54, 12},
-    {25, 0, 18, 5, 2, 12},
-    {9, 0, 0, 5, 3, 12},
-    {9, 0, 0, 4, 3, 12},
-    {5, 0, 0, 4, 3, 12},
-    {5, 0, 0, 5, 3, 12},
-    {26, 0, 0, 5, 3, 12},
-    {12, 230, 13, 5, 3, 21},
-    {12, 230, 13, 5, 40, 21},
-    {11, 0, 13, 5, 3, 21},
-    {9, 0, 0, 5, 4, 12},
-    {6, 0, 0, 5, 4, 12},
-    {21, 0, 0, 5, 4, 12},
-    {5, 0, 0, 5, 4, 12},
-    {21, 0, 0, 5, 0, 8},
-    {17, 0, 18, 5, 4, 17},
-    {26, 0, 18, 5, 4, 12},
-    {23, 0, 10, 5, 4, 9},
-    {12, 220, 13, 5, 5, 21},
-    {12, 230, 13, 5, 5, 21},
-    {12, 222, 13, 5, 5, 21},
-    {12, 228, 13, 5, 5, 21},
-    {12, 10, 13, 5, 5, 21},
-    {12, 11, 13, 5, 5, 21},
-    {12, 12, 13, 5, 5, 21},
-    {12, 13, 13, 5, 5, 21},
-    {12, 14, 13, 5, 5, 21},
-    {12, 15, 13, 5, 5, 21},
-    {12, 16, 13, 5, 5, 21},
-    {12, 17, 13, 5, 5, 21},
-    {12, 18, 13, 5, 5, 21},
-    {12, 19, 13, 5, 5, 21},
-    {12, 20, 13, 5, 5, 21},
-    {12, 21, 13, 5, 5, 21},
-    {12, 22, 13, 5, 5, 21},
-    {17, 0, 3, 5, 5, 17},
-    {12, 23, 13, 5, 5, 21},
-    {21, 0, 3, 5, 5, 12},
-    {12, 24, 13, 5, 5, 21},
-    {12, 25, 13, 5, 5, 21},
-    {21, 0, 3, 5, 5, 6},
-    {7, 0, 3, 5, 5, 13},
-    {1, 0, 11, 5, 6, 12},
-    {1, 0, 11, 5, 0, 12},
-    {25, 0, 18, 5, 6, 12},
-    {25, 0, 4, 5, 6, 12},
-    {21, 0, 10, 5, 6, 10},
-    {23, 0, 4, 5, 6, 10},
-    {21, 0, 12, 5, 0, 8},
-    {21, 0, 4, 5, 6, 8},
-    {26, 0, 18, 5, 6, 12},
-    {12, 230, 13, 5, 6, 21},
-    {12, 30, 13, 5, 6, 21},
-    {12, 31, 13, 5, 6, 21},
-    {12, 32, 13, 5, 6, 21},
-    {21, 0, 4, 5, 0, 6},
-    {1, 0, 4, 5, 6, 21},
-    {21, 0, 4, 5, 6, 6},
-    {7, 0, 4, 5, 6, 12},
-    {6, 0, 4, 5, 0, 12},
-    {12, 27, 13, 5, 40, 21},
-    {12, 28, 13, 5, 40, 21},
-    {12, 29, 13, 5, 40, 21},
-    {12, 30, 13, 5, 40, 21},
-    {12, 31, 13, 5, 40, 21},
-    {12, 32, 13, 5, 40, 21},
-    {12, 33, 13, 5, 40, 21},
-    {12, 34, 13, 5, 40, 21},
-    {12, 220, 13, 5, 40, 21},
-    {12, 220, 13, 5, 6, 21},
-    {13, 0, 11, 5, 6, 11},
-    {21, 0, 11, 5, 6, 11},
-    {21, 0, 4, 5, 6, 12},
-    {12, 35, 13, 5, 40, 21},
-    {6, 0, 4, 5, 6, 12},
-    {13, 0, 8, 5, 6, 11},
-    {26, 0, 4, 5, 6, 12},
-    {21, 0, 4, 5, 7, 12},
-    {1, 0, 4, 5, 7, 12},
-    {7, 0, 4, 5, 7, 12},
-    {12, 36, 13, 5, 7, 21},
-    {12, 230, 13, 5, 7, 21},
-    {12, 220, 13, 5, 7, 21},
-    {7, 0, 4, 5, 8, 12},
-    {12, 0, 13, 5, 8, 21},
-    {13, 0, 3, 5, 65, 11},
-    {7, 0, 3, 5, 65, 12},
-    {12, 230, 13, 5, 65, 21},
-    {12, 220, 13, 5, 65, 21},
-    {6, 0, 3, 5, 65, 12},
-    {26, 0, 18, 5, 65, 12},
-    {21, 0, 18, 5, 65, 12},
-    {21, 0, 18, 5, 65, 8},
-    {21, 0, 18, 5, 65, 6},
-    {23, 0, 3, 5, 65, 9},
-    {7, 0, 3, 5, 81, 12},
-    {12, 230, 13, 5, 81, 21},
-    {6, 0, 3, 5, 81, 12},
-    {21, 0, 3, 5, 81, 12},
-    {7, 0, 3, 5, 94, 12},
-    {12, 220, 13, 5, 94, 21},
-    {21, 0, 3, 5, 94, 12},
-    {12, 27, 13, 5, 6, 21},
-    {12, 28, 13, 5, 6, 21},
-    {12, 29, 13, 5, 6, 21},
-    {12, 0, 13, 5, 9, 21},
-    {10, 0, 0, 5, 9, 21},
-    {7, 0, 0, 5, 9, 12},
-    {12, 7, 13, 5, 9, 21},
-    {12, 9, 13, 5, 9, 21},
-    {21, 0, 0, 5, 0, 17},
-    {13, 0, 0, 5, 9, 11},
-    {21, 0, 0, 5, 9, 12},
-    {6, 0, 0, 5, 9, 12},
-    {7, 0, 0, 5, 10, 12},
-    {12, 0, 13, 5, 10, 21},
-    {10, 0, 0, 5, 10, 21},
-    {12, 7, 13, 5, 10, 21},
-    {12, 9, 13, 5, 10, 21},
-    {13, 0, 0, 5, 10, 11},
-    {23, 0, 10, 5, 10, 10},
-    {15, 0, 0, 5, 10, 12},
-    {15, 0, 0, 5, 10, 10},
-    {26, 0, 0, 5, 10, 12},
-    {23, 0, 10, 5, 10, 9},
-    {21, 0, 0, 5, 10, 12},
-    {12, 230, 13, 5, 10, 21},
-    {12, 0, 13, 5, 11, 21},
-    {10, 0, 0, 5, 11, 21},
-    {7, 0, 0, 5, 11, 12},
-    {12, 7, 13, 5, 11, 21},
-    {12, 9, 13, 5, 11, 21},
-    {13, 0, 0, 5, 11, 11},
-    {21, 0, 0, 5, 11, 12},
-    {12, 0, 13, 5, 12, 21},
-    {10, 0, 0, 5, 12, 21},
-    {7, 0, 0, 5, 12, 12},
-    {12, 7, 13, 5, 12, 21},
-    {12, 9, 13, 5, 12, 21},
-    {13, 0, 0, 5, 12, 11},
-    {21, 0, 0, 5, 12, 12},
-    {23, 0, 10, 5, 12, 9},
-    {12, 0, 13, 5, 13, 21},
-    {10, 0, 0, 5, 13, 21},
-    {7, 0, 0, 5, 13, 12},
-    {12, 7, 13, 5, 13, 21},
-    {12, 9, 13, 5, 13, 21},
-    {13, 0, 0, 5, 13, 11},
-    {26, 0, 0, 5, 13, 12},
-    {15, 0, 0, 5, 13, 12},
-    {12, 0, 13, 5, 14, 21},
-    {7, 0, 0, 5, 14, 12},
-    {10, 0, 0, 5, 14, 21},
-    {12, 9, 13, 5, 14, 21},
-    {13, 0, 0, 5, 14, 11},
-    {15, 0, 0, 5, 14, 12},
-    {26, 0, 18, 5, 14, 12},
-    {23, 0, 10, 5, 14, 9},
-    {12, 0, 13, 5, 15, 21},
-    {10, 0, 0, 5, 15, 21},
-    {7, 0, 0, 5, 15, 12},
-    {12, 9, 13, 5, 15, 21},
-    {12, 84, 13, 5, 15, 21},
-    {12, 91, 13, 5, 15, 21},
-    {13, 0, 0, 5, 15, 11},
-    {21, 0, 0, 5, 15, 18},
-    {15, 0, 18, 5, 15, 12},
-    {26, 0, 0, 5, 15, 12},
-    {7, 0, 0, 5, 16, 12},
-    {12, 0, 13, 5, 16, 21},
-    {10, 0, 0, 5, 16, 21},
-    {21, 0, 0, 5, 16, 18},
-    {12, 7, 13, 5, 16, 21},
-    {12, 0, 0, 5, 16, 21},
-    {12, 9, 13, 5, 16, 21},
-    {13, 0, 0, 5, 16, 11},
-    {12, 0, 13, 5, 17, 21},
-    {10, 0, 0, 5, 17, 21},
-    {7, 0, 0, 5, 17, 12},
-    {12, 9, 13, 5, 17, 21},
-    {26, 0, 0, 5, 17, 12},
-    {15, 0, 0, 5, 17, 12},
-    {13, 0, 0, 5, 17, 11},
-    {26, 0, 0, 5, 17, 10},
-    {10, 0, 0, 5, 18, 21},
-    {7, 0, 0, 5, 18, 12},
-    {12, 9, 13, 5, 18, 21},
-    {12, 0, 13, 5, 18, 21},
-    {13, 0, 0, 5, 18, 11},
-    {21, 0, 0, 5, 18, 12},
-    {7, 0, 0, 5, 19, 36},
-    {12, 0, 13, 5, 19, 36},
-    {12, 103, 13, 5, 19, 36},
-    {12, 9, 13, 5, 19, 36},
-    {23, 0, 10, 5, 0, 9},
-    {6, 0, 0, 5, 19, 36},
-    {12, 107, 13, 5, 19, 36},
-    {21, 0, 0, 5, 19, 12},
-    {13, 0, 0, 5, 19, 11},
-    {21, 0, 0, 5, 19, 17},
-    {7, 0, 0, 5, 20, 36},
-    {12, 0, 13, 5, 20, 36},
-    {12, 118, 13, 5, 20, 36},
-    {12, 9, 13, 5, 20, 36},
-    {6, 0, 0, 5, 20, 36},
-    {12, 122, 13, 5, 20, 36},
-    {13, 0, 0, 5, 20, 11},
-    {7, 0, 0, 5, 21, 12},
-    {26, 0, 0, 5, 21, 18},
-    {21, 0, 0, 5, 21, 18},
-    {21, 0, 0, 5, 21, 12},
-    {21, 0, 0, 5, 21, 4},
-    {21, 0, 0, 5, 21, 17},
-    {21, 0, 0, 5, 21, 6},
-    {26, 0, 0, 5, 21, 12},
-    {12, 220, 13, 5, 21, 21},
-    {13, 0, 0, 5, 21, 11},
-    {15, 0, 0, 5, 21, 12},
-    {26, 0, 0, 5, 21, 17},
-    {12, 216, 13, 5, 21, 21},
-    {22, 0, 18, 5, 21, 0},
-    {18, 0, 18, 5, 21, 1},
-    {10, 0, 0, 5, 21, 21},
-    {12, 129, 13, 5, 21, 21},
-    {12, 130, 13, 5, 21, 21},
-    {12, 0, 13, 5, 21, 21},
-    {12, 132, 13, 5, 21, 21},
-    {10, 0, 0, 5, 21, 17},
-    {12, 230, 13, 5, 21, 21},
-    {12, 9, 13, 5, 21, 21},
-    {26, 0, 0, 5, 0, 12},
-    {7, 0, 0, 5, 22, 36},
-    {10, 0, 0, 5, 22, 36},
-    {12, 0, 13, 5, 22, 36},
-    {12, 7, 13, 5, 22, 36},
-    {12, 9, 13, 5, 22, 36},
-    {13, 0, 0, 5, 22, 11},
-    {21, 0, 0, 5, 22, 17},
-    {21, 0, 0, 5, 22, 12},
-    {12, 220, 13, 5, 22, 36},
-    {26, 0, 0, 5, 22, 36},
-    {9, 0, 0, 5, 23, 12},
-    {5, 0, 0, 5, 23, 12},
-    {21, 0, 0, 5, 0, 12},
-    {6, 0, 0, 5, 23, 12},
-    {7, 0, 0, 2, 24, 25},
-    {7, 0, 0, 5, 24, 26},
-    {7, 0, 0, 5, 24, 27},
-    {7, 0, 0, 5, 25, 12},
-    {12, 230, 13, 5, 25, 21},
-    {21, 0, 0, 5, 25, 12},
-    {21, 0, 0, 5, 25, 17},
-    {15, 0, 0, 5, 25, 12},
-    {26, 0, 18, 5, 25, 12},
-    {9, 0, 0, 5, 26, 12},
-    {5, 0, 0, 5, 26, 12},
-    {17, 0, 18, 5, 27, 17},
-    {7, 0, 0, 5, 27, 12},
-    {26, 0, 0, 5, 27, 12},
-    {21, 0, 0, 5, 27, 12},
-    {29, 0, 17, 5, 28, 17},
-    {7, 0, 0, 5, 28, 12},
-    {22, 0, 18, 5, 28, 0},
-    {18, 0, 18, 5, 28, 1},
-    {7, 0, 0, 5, 29, 12},
-    {14, 0, 0, 5, 29, 12},
-    {7, 0, 0, 5, 41, 12},
-    {12, 0, 13, 5, 41, 21},
-    {12, 9, 13, 5, 41, 21},
-    {7, 0, 0, 5, 42, 12},
-    {12, 0, 13, 5, 42, 21},
-    {12, 9, 13, 5, 42, 21},
-    {7, 0, 0, 5, 43, 12},
-    {12, 0, 13, 5, 43, 21},
-    {7, 0, 0, 5, 44, 12},
-    {12, 0, 13, 5, 44, 21},
-    {7, 0, 0, 5, 30, 36},
-    {12, 0, 13, 5, 30, 36},
-    {10, 0, 0, 5, 30, 36},
-    {12, 9, 13, 5, 30, 36},
-    {21, 0, 0, 5, 30, 17},
-    {21, 0, 0, 5, 30, 5},
-    {6, 0, 0, 5, 30, 36},
-    {21, 0, 0, 5, 30, 12},
-    {23, 0, 10, 5, 30, 9},
-    {12, 230, 13, 5, 30, 36},
-    {13, 0, 0, 5, 30, 11},
-    {15, 0, 18, 5, 30, 12},
-    {21, 0, 18, 5, 31, 12},
-    {21, 0, 18, 5, 0, 6},
-    {21, 0, 18, 5, 31, 17},
-    {21, 0, 18, 5, 0, 17},
-    {17, 0, 18, 5, 31, 18},
-    {21, 0, 18, 5, 31, 6},
-    {12, 0, 13, 5, 31, 21},
-    {1, 0, 14, 5, 31, 4},
-    {13, 0, 0, 5, 31, 11},
-    {7, 0, 0, 5, 31, 12},
-    {6, 0, 0, 5, 31, 12},
-    {12, 228, 13, 5, 31, 21},
-    {7, 0, 0, 5, 45, 12},
-    {12, 0, 13, 5, 45, 21},
-    {10, 0, 0, 5, 45, 21},
-    {12, 222, 13, 5, 45, 21},
-    {12, 230, 13, 5, 45, 21},
-    {12, 220, 13, 5, 45, 21},
-    {26, 0, 18, 5, 45, 12},
-    {21, 0, 18, 5, 45, 6},
-    {13, 0, 0, 5, 45, 11},
-    {7, 0, 0, 5, 46, 36},
-    {7, 0, 0, 5, 55, 36},
-    {13, 0, 0, 5, 55, 11},
-    {15, 0, 0, 5, 55, 36},
-    {26, 0, 18, 5, 55, 36},
-    {26, 0, 18, 5, 30, 12},
-    {7, 0, 0, 5, 53, 12},
-    {12, 230, 13, 5, 53, 21},
-    {12, 220, 13, 5, 53, 21},
-    {10, 0, 0, 5, 53, 21},
-    {12, 0, 13, 5, 53, 21},
-    {21, 0, 0, 5, 53, 12},
-    {7, 0, 0, 5, 77, 36},
-    {10, 0, 0, 5, 77, 36},
-    {12, 0, 13, 5, 77, 36},
-    {12, 9, 13, 5, 77, 36},
-    {12, 230, 13, 5, 77, 36},
-    {12, 220, 13, 5, 77, 21},
-    {13, 0, 0, 5, 77, 11},
-    {21, 0, 0, 5, 77, 36},
-    {6, 0, 0, 5, 77, 36},
-    {11, 0, 13, 5, 40, 21},
-    {12, 0, 13, 5, 61, 21},
-    {10, 0, 0, 5, 61, 21},
-    {7, 0, 0, 5, 61, 12},
-    {12, 7, 13, 5, 61, 21},
-    {10, 9, 0, 5, 61, 21},
-    {13, 0, 0, 5, 61, 11},
-    {21, 0, 0, 5, 61, 17},
-    {21, 0, 0, 5, 61, 12},
-    {26, 0, 0, 5, 61, 12},
-    {12, 230, 13, 5, 61, 21},
-    {12, 220, 13, 5, 61, 21},
-    {12, 0, 13, 5, 66, 21},
-    {10, 0, 0, 5, 66, 21},
-    {7, 0, 0, 5, 66, 12},
-    {10, 9, 0, 5, 66, 21},
-    {12, 9, 13, 5, 66, 21},
-    {13, 0, 0, 5, 66, 11},
-    {7, 0, 0, 5, 92, 12},
-    {12, 7, 13, 5, 92, 21},
-    {10, 0, 0, 5, 92, 21},
-    {12, 0, 13, 5, 92, 21},
-    {10, 9, 0, 5, 92, 21},
-    {21, 0, 0, 5, 92, 12},
-    {7, 0, 0, 5, 67, 12},
-    {10, 0, 0, 5, 67, 21},
-    {12, 0, 13, 5, 67, 21},
-    {12, 7, 13, 5, 67, 21},
-    {21, 0, 0, 5, 67, 17},
-    {13, 0, 0, 5, 67, 11},
-    {13, 0, 0, 5, 68, 11},
-    {7, 0, 0, 5, 68, 12},
-    {6, 0, 0, 5, 68, 12},
-    {21, 0, 0, 5, 68, 17},
-    {21, 0, 0, 5, 66, 12},
-    {12, 1, 13, 5, 40, 21},
-    {10, 0, 0, 5, 0, 21},
-    {7, 0, 0, 5, 0, 12},
-    {6, 0, 0, 5, 3, 12},
-    {12, 234, 13, 5, 40, 21},
-    {12, 214, 13, 5, 40, 21},
-    {12, 202, 13, 5, 40, 21},
-    {12, 232, 13, 5, 40, 21},
-    {12, 228, 13, 5, 40, 21},
-    {12, 233, 13, 5, 40, 21},
-    {8, 0, 0, 5, 2, 12},
-    {24, 0, 18, 5, 2, 18},
-    {29, 0, 17, 5, 0, 17},
-    {29, 0, 17, 5, 0, 4},
-    {1, 0, 14, 5, 0, 20},
-    {1, 0, 14, 5, 40, 21},
-    {1, 0, 14, 5, 40, 40},
-    {1, 0, 0, 5, 0, 21},
-    {1, 0, 3, 5, 0, 21},
-    {17, 0, 18, 4, 0, 17},
-    {17, 0, 18, 5, 0, 4},
-    {17, 0, 18, 5, 0, 17},
-    {17, 0, 18, 4, 0, 19},
-    {17, 0, 18, 4, 0, 29},
-    {20, 0, 18, 4, 0, 3},
-    {19, 0, 18, 4, 0, 3},
-    {22, 0, 18, 5, 0, 0},
-    {21, 0, 18, 4, 0, 12},
-    {21, 0, 18, 4, 0, 15},
-    {21, 0, 18, 4, 0, 17},
-    {27, 0, 17, 5, 0, 30},
-    {28, 0, 15, 5, 0, 30},
-    {1, 0, 1, 5, 0, 21},
-    {1, 0, 5, 5, 0, 21},
-    {1, 0, 7, 5, 0, 21},
-    {1, 0, 2, 5, 0, 21},
-    {1, 0, 6, 5, 0, 21},
-    {21, 0, 10, 4, 0, 10},
-    {21, 0, 10, 5, 0, 10},
-    {21, 0, 18, 4, 0, 10},
-    {21, 0, 18, 5, 0, 10},
-    {21, 0, 18, 5, 0, 5},
-    {16, 0, 18, 5, 0, 12},
-    {25, 0, 12, 5, 0, 8},
-    {18, 0, 18, 5, 0, 1},
-    {25, 0, 18, 5, 0, 12},
-    {1, 0, 14, 5, 0, 22},
-    {1, 0, 14, 5, 0, 12},
-    {1, 0, 19, 5, 0, 21},
-    {1, 0, 20, 5, 0, 21},
-    {1, 0, 21, 5, 0, 21},
-    {1, 0, 22, 5, 0, 21},
-    {1, 0, 14, 5, 0, 21},
-    {15, 0, 8, 5, 0, 12},
-    {25, 0, 9, 5, 0, 12},
-    {6, 0, 0, 4, 1, 29},
-    {23, 0, 10, 5, 0, 10},
-    {23, 0, 10, 1, 0, 9},
-    {2, 0, 18, 5, 102, 9},
-    {9, 0, 0, 5, 0, 12},
-    {26, 0, 18, 4, 0, 10},
-    {26, 0, 18, 4, 0, 29},
-    {5, 0, 0, 4, 0, 29},
-    {26, 0, 18, 4, 0, 9},
-    {9, 0, 0, 4, 1, 29},
-    {26, 0, 10, 5, 0, 12},
-    {15, 0, 18, 5, 0, 12},
-    {15, 0, 18, 4, 0, 12},
-    {15, 0, 18, 5, 0, 29},
-    {14, 0, 0, 4, 1, 29},
-    {14, 0, 0, 5, 1, 12},
-    {25, 0, 9, 5, 0, 9},
-    {25, 0, 10, 5, 0, 9},
-    {25, 0, 18, 5, 0, 15},
-    {26, 0, 18, 2, 0, 14},
-    {22, 0, 18, 2, 0, 0},
-    {18, 0, 18, 2, 0, 1},
-    {26, 0, 18, 2, 0, 12},
-    {26, 0, 18, 5, 0, 14},
-    {26, 0, 0, 4, 0, 29},
-    {26, 0, 18, 5, 0, 29},
-    {25, 0, 18, 2, 0, 12},
-    {26, 0, 18, 4, 0, 14},
-    {26, 0, 18, 5, 0, 41},
-    {26, 0, 18, 4, 0, 41},
-    {26, 0, 18, 2, 0, 41},
-    {26, 0, 18, 2, 0, 29},
-    {26, 0, 18, 5, 0, 3},
-    {26, 0, 18, 5, 0, 6},
-    {26, 0, 0, 5, 52, 12},
-    {9, 0, 0, 5, 56, 12},
-    {5, 0, 0, 5, 56, 12},
-    {26, 0, 18, 5, 54, 12},
-    {12, 230, 13, 5, 54, 21},
-    {21, 0, 18, 5, 54, 6},
-    {21, 0, 18, 5, 54, 17},
-    {15, 0, 18, 5, 54, 12},
-    {7, 0, 0, 5, 57, 12},
-    {6, 0, 0, 5, 57, 12},
-    {21, 0, 0, 5, 57, 17},
-    {12, 9, 13, 5, 57, 21},
-    {21, 0, 18, 5, 0, 3},
-    {21, 0, 18, 5, 0, 0},
-    {17, 0, 18, 5, 0, 12},
-    {17, 0, 18, 5, 0, 19},
-    {26, 0, 18, 2, 35, 14},
-    {29, 0, 17, 0, 0, 17},
-    {21, 0, 18, 2, 0, 1},
-    {21, 0, 18, 2, 0, 14},
-    {6, 0, 0, 2, 35, 5},
-    {7, 0, 0, 2, 0, 14},
-    {14, 0, 0, 2, 35, 14},
-    {17, 0, 18, 2, 0, 5},
-    {12, 218, 13, 2, 40, 21},
-    {12, 228, 13, 2, 40, 21},
-    {12, 232, 13, 2, 40, 21},
-    {12, 222, 13, 2, 40, 21},
-    {10, 224, 0, 2, 24, 21},
-    {17, 0, 18, 2, 0, 14},
-    {6, 0, 0, 2, 0, 14},
-    {6, 0, 0, 2, 0, 21},
-    {7, 0, 0, 2, 0, 5},
-    {7, 0, 0, 2, 32, 32},
-    {7, 0, 0, 2, 32, 14},
-    {12, 8, 13, 2, 40, 21},
-    {24, 0, 18, 2, 0, 5},
-    {6, 0, 0, 2, 32, 5},
-    {7, 0, 0, 2, 33, 32},
-    {7, 0, 0, 2, 33, 14},
-    {21, 0, 18, 2, 0, 5},
-    {6, 0, 0, 2, 0, 32},
-    {6, 0, 0, 2, 33, 5},
-    {7, 0, 0, 2, 34, 14},
-    {7, 0, 0, 2, 24, 14},
-    {26, 0, 0, 2, 0, 14},
-    {15, 0, 0, 2, 0, 14},
-    {26, 0, 0, 2, 24, 14},
-    {26, 0, 18, 2, 24, 14},
-    {15, 0, 0, 4, 0, 29},
-    {15, 0, 18, 2, 0, 14},
-    {26, 0, 0, 2, 33, 14},
-    {7, 0, 0, 2, 35, 14},
-    {2, 0, 18, 2, 102, 14},
-    {7, 0, 0, 2, 36, 14},
-    {6, 0, 0, 2, 36, 5},
-    {26, 0, 18, 2, 36, 14},
-    {7, 0, 0, 5, 82, 12},
-    {6, 0, 0, 5, 82, 12},
-    {21, 0, 0, 5, 82, 17},
-    {7, 0, 0, 5, 69, 12},
-    {6, 0, 0, 5, 69, 12},
-    {21, 0, 18, 5, 69, 17},
-    {21, 0, 18, 5, 69, 6},
-    {13, 0, 0, 5, 69, 11},
-    {7, 0, 0, 5, 3, 12},
-    {21, 0, 18, 5, 3, 12},
-    {6, 0, 18, 5, 3, 12},
-    {7, 0, 0, 5, 83, 12},
-    {14, 0, 0, 5, 83, 12},
-    {12, 230, 13, 5, 83, 21},
-    {21, 0, 0, 5, 83, 12},
-    {21, 0, 0, 5, 83, 17},
-    {24, 0, 0, 5, 0, 12},
-    {7, 0, 0, 5, 58, 12},
-    {12, 0, 13, 5, 58, 21},
-    {12, 9, 13, 5, 58, 21},
-    {10, 0, 0, 5, 58, 21},
-    {26, 0, 18, 5, 58, 12},
-    {15, 0, 0, 5, 0, 12},
-    {7, 0, 0, 5, 64, 12},
-    {21, 0, 18, 5, 64, 18},
-    {21, 0, 18, 5, 64, 6},
-    {10, 0, 0, 5, 70, 21},
-    {7, 0, 0, 5, 70, 12},
-    {12, 9, 13, 5, 70, 21},
-    {12, 0, 13, 5, 70, 21},
-    {21, 0, 0, 5, 70, 17},
-    {13, 0, 0, 5, 70, 11},
-    {12, 230, 13, 5, 9, 21},
-    {21, 0, 0, 5, 9, 18},
-    {13, 0, 0, 5, 71, 11},
-    {7, 0, 0, 5, 71, 12},
-    {12, 0, 13, 5, 71, 21},
-    {12, 220, 13, 5, 71, 21},
-    {21, 0, 0, 5, 71, 17},
-    {7, 0, 0, 5, 72, 12},
-    {12, 0, 13, 5, 72, 21},
-    {10, 0, 0, 5, 72, 21},
-    {10, 9, 0, 5, 72, 21},
-    {21, 0, 0, 5, 72, 12},
-    {12, 0, 13, 5, 84, 21},
-    {10, 0, 0, 5, 84, 21},
-    {7, 0, 0, 5, 84, 12},
-    {12, 7, 13, 5, 84, 21},
-    {10, 9, 0, 5, 84, 21},
-    {21, 0, 0, 5, 84, 12},
-    {21, 0, 0, 5, 84, 17},
-    {13, 0, 0, 5, 84, 11},
-    {6, 0, 0, 5, 22, 36},
-    {7, 0, 0, 5, 76, 12},
-    {12, 0, 13, 5, 76, 21},
-    {10, 0, 0, 5, 76, 21},
-    {13, 0, 0, 5, 76, 11},
-    {21, 0, 0, 5, 76, 12},
-    {21, 0, 0, 5, 76, 17},
-    {7, 0, 0, 5, 78, 36},
-    {12, 230, 13, 5, 78, 36},
-    {12, 220, 13, 5, 78, 36},
-    {6, 0, 0, 5, 78, 36},
-    {21, 0, 0, 5, 78, 36},
-    {7, 0, 0, 5, 85, 12},
-    {10, 0, 0, 5, 85, 21},
-    {12, 0, 13, 5, 85, 21},
-    {21, 0, 0, 5, 85, 17},
-    {6, 0, 0, 5, 85, 12},
-    {12, 9, 13, 5, 85, 21},
-    {13, 0, 0, 5, 85, 11},
-    {7, 0, 0, 2, 24, 23},
-    {7, 0, 0, 2, 24, 24},
-    {4, 0, 0, 5, 102, 37},
-    {3, 0, 0, 4, 102, 39},
-    {12, 26, 13, 5, 5, 21},
-    {25, 0, 9, 5, 5, 12},
-    {24, 0, 4, 5, 6, 12},
-    {12, 0, 13, 4, 40, 21},
-    {21, 0, 18, 2, 0, 8},
-    {21, 0, 18, 2, 0, 6},
-    {21, 0, 18, 2, 0, 15},
-    {16, 0, 18, 2, 0, 14},
-    {21, 0, 12, 2, 0, 1},
-    {21, 0, 12, 2, 0, 5},
-    {21, 0, 10, 2, 0, 14},
-    {25, 0, 9, 2, 0, 14},
-    {17, 0, 9, 2, 0, 14},
-    {25, 0, 18, 2, 0, 14},
-    {23, 0, 10, 2, 0, 9},
-    {21, 0, 10, 2, 0, 10},
-    {21, 0, 18, 0, 0, 6},
-    {21, 0, 18, 0, 0, 14},
-    {21, 0, 10, 0, 0, 14},
-    {23, 0, 10, 0, 0, 9},
-    {21, 0, 10, 0, 0, 10},
-    {22, 0, 18, 0, 0, 0},
-    {18, 0, 18, 0, 0, 1},
-    {25, 0, 9, 0, 0, 14},
-    {21, 0, 12, 0, 0, 1},
-    {17, 0, 9, 0, 0, 14},
-    {21, 0, 12, 0, 0, 14},
-    {13, 0, 8, 0, 0, 14},
-    {21, 0, 12, 0, 0, 5},
-    {21, 0, 18, 0, 0, 5},
-    {25, 0, 18, 0, 0, 14},
-    {9, 0, 0, 0, 1, 14},
-    {24, 0, 18, 0, 0, 14},
-    {16, 0, 18, 0, 0, 14},
-    {5, 0, 0, 0, 1, 14},
-    {21, 0, 18, 1, 0, 1},
-    {22, 0, 18, 1, 0, 0},
-    {18, 0, 18, 1, 0, 1},
-    {21, 0, 18, 1, 0, 5},
-    {7, 0, 0, 1, 33, 14},
-    {7, 0, 0, 1, 33, 32},
-    {6, 0, 0, 1, 0, 32},
-    {6, 0, 0, 1, 0, 5},
-    {7, 0, 0, 1, 24, 14},
-    {23, 0, 10, 0, 0, 10},
-    {26, 0, 18, 0, 0, 14},
-    {26, 0, 18, 1, 0, 12},
-    {25, 0, 18, 1, 0, 12},
-    {1, 0, 18, 5, 0, 21},
-    {26, 0, 18, 5, 0, 31},
-    {7, 0, 0, 5, 47, 12},
-    {14, 0, 18, 5, 2, 12},
-    {15, 0, 18, 5, 2, 12},
-    {26, 0, 18, 5, 2, 12},
-    {26, 0, 0, 5, 2, 12},
-    {7, 0, 0, 5, 73, 12},
-    {7, 0, 0, 5, 74, 12},
-    {7, 0, 0, 5, 37, 12},
-    {15, 0, 0, 5, 37, 12},
-    {7, 0, 0, 5, 38, 12},
-    {14, 0, 0, 5, 38, 12},
-    {7, 0, 0, 5, 118, 12},
-    {12, 230, 13, 5, 118, 21},
-    {7, 0, 0, 5, 48, 12},
-    {21, 0, 0, 5, 48, 17},
-    {7, 0, 0, 5, 59, 12},
-    {21, 0, 0, 5, 59, 17},
-    {14, 0, 0, 5, 59, 12},
-    {9, 0, 0, 5, 39, 12},
-    {5, 0, 0, 5, 39, 12},
-    {7, 0, 0, 5, 49, 12},
-    {7, 0, 0, 5, 50, 12},
-    {13, 0, 0, 5, 50, 11},
-    {9, 0, 0, 5, 136, 12},
-    {5, 0, 0, 5, 136, 12},
-    {7, 0, 0, 5, 106, 12},
-    {7, 0, 0, 5, 104, 12},
-    {21, 0, 0, 5, 104, 12},
-    {7, 0, 0, 5, 110, 12},
-    {7, 0, 3, 5, 51, 12},
-    {7, 0, 3, 5, 86, 12},
-    {21, 0, 3, 5, 86, 17},
-    {15, 0, 3, 5, 86, 12},
-    {7, 0, 3, 5, 120, 12},
-    {26, 0, 3, 5, 120, 12},
-    {15, 0, 3, 5, 120, 12},
-    {7, 0, 3, 5, 116, 12},
-    {15, 0, 3, 5, 116, 12},
-    {7, 0, 3, 5, 128, 12},
-    {15, 0, 3, 5, 128, 12},
-    {7, 0, 3, 5, 63, 12},
-    {15, 0, 3, 5, 63, 12},
-    {21, 0, 18, 5, 63, 17},
-    {7, 0, 3, 5, 75, 12},
-    {21, 0, 3, 5, 75, 12},
-    {7, 0, 3, 5, 97, 12},
-    {7, 0, 3, 5, 96, 12},
-    {15, 0, 3, 5, 96, 12},
-    {7, 0, 3, 5, 60, 12},
-    {12, 0, 13, 5, 60, 21},
-    {12, 220, 13, 5, 60, 21},
-    {12, 230, 13, 5, 60, 21},
-    {12, 1, 13, 5, 60, 21},
-    {12, 9, 13, 5, 60, 21},
-    {15, 0, 3, 5, 60, 12},
-    {21, 0, 3, 5, 60, 17},
-    {21, 0, 3, 5, 60, 12},
-    {7, 0, 3, 5, 87, 12},
-    {15, 0, 3, 5, 87, 12},
-    {21, 0, 3, 5, 87, 12},
-    {7, 0, 3, 5, 117, 12},
-    {15, 0, 3, 5, 117, 12},
-    {7, 0, 3, 5, 112, 12},
-    {26, 0, 3, 5, 112, 12},
-    {12, 230, 13, 5, 112, 21},
-    {12, 220, 13, 5, 112, 21},
-    {15, 0, 3, 5, 112, 12},
-    {21, 0, 3, 5, 112, 17},
-    {21, 0, 3, 5, 112, 15},
-    {7, 0, 3, 5, 79, 12},
-    {21, 0, 18, 5, 79, 17},
-    {7, 0, 3, 5, 88, 12},
-    {15, 0, 3, 5, 88, 12},
-    {7, 0, 3, 5, 89, 12},
-    {15, 0, 3, 5, 89, 12},
-    {7, 0, 3, 5, 122, 12},
-    {21, 0, 3, 5, 122, 12},
-    {15, 0, 3, 5, 122, 12},
-    {7, 0, 3, 5, 90, 12},
-    {9, 0, 3, 5, 130, 12},
-    {5, 0, 3, 5, 130, 12},
-    {15, 0, 3, 5, 130, 12},
-    {7, 0, 4, 5, 144, 12},
-    {12, 230, 13, 5, 144, 21},
-    {13, 0, 11, 5, 144, 11},
-    {15, 0, 11, 5, 6, 12},
-    {7, 0, 3, 5, 147, 12},
-    {15, 0, 3, 5, 147, 12},
-    {7, 0, 4, 5, 148, 12},
-    {12, 220, 13, 5, 148, 21},
-    {12, 230, 13, 5, 148, 21},
-    {15, 0, 4, 5, 148, 12},
-    {21, 0, 4, 5, 148, 12},
-    {7, 0, 3, 5, 149, 12},
-    {10, 0, 0, 5, 93, 21},
-    {12, 0, 13, 5, 93, 21},
-    {7, 0, 0, 5, 93, 12},
-    {12, 9, 13, 5, 93, 21},
-    {21, 0, 0, 5, 93, 17},
-    {21, 0, 0, 5, 93, 12},
-    {15, 0, 18, 5, 93, 12},
-    {13, 0, 0, 5, 93, 11},
-    {12, 0, 13, 5, 91, 21},
-    {10, 0, 0, 5, 91, 21},
-    {7, 0, 0, 5, 91, 12},
-    {12, 9, 13, 5, 91, 21},
-    {12, 7, 13, 5, 91, 21},
-    {21, 0, 0, 5, 91, 12},
-    {1, 0, 0, 5, 91, 12},
-    {21, 0, 0, 5, 91, 17},
-    {7, 0, 0, 5, 100, 12},
-    {13, 0, 0, 5, 100, 11},
-    {12, 230, 13, 5, 95, 21},
-    {7, 0, 0, 5, 95, 12},
-    {12, 0, 13, 5, 95, 21},
-    {10, 0, 0, 5, 95, 21},
-    {12, 9, 13, 5, 95, 21},
-    {13, 0, 0, 5, 95, 11},
-    {21, 0, 0, 5, 95, 17},
-    {7, 0, 0, 5, 111, 12},
-    {12, 7, 13, 5, 111, 21},
-    {21, 0, 0, 5, 111, 12},
-    {21, 0, 0, 5, 111, 18},
-    {12, 0, 13, 5, 99, 21},
-    {10, 0, 0, 5, 99, 21},
-    {7, 0, 0, 5, 99, 12},
-    {10, 9, 0, 5, 99, 21},
-    {21, 0, 0, 5, 99, 17},
-    {21, 0, 0, 5, 99, 12},
-    {12, 7, 13, 5, 99, 21},
-    {13, 0, 0, 5, 99, 11},
-    {21, 0, 0, 5, 99, 18},
-    {15, 0, 0, 5, 18, 12},
-    {7, 0, 0, 5, 108, 12},
-    {10, 0, 0, 5, 108, 21},
-    {12, 0, 13, 5, 108, 21},
-    {10, 9, 0, 5, 108, 21},
-    {12, 7, 13, 5, 108, 21},
-    {21, 0, 0, 5, 108, 17},
-    {21, 0, 0, 5, 108, 12},
-    {7, 0, 0, 5, 129, 12},
-    {21, 0, 0, 5, 129, 17},
-    {7, 0, 0, 5, 109, 12},
-    {12, 0, 13, 5, 109, 21},
-    {10, 0, 0, 5, 109, 21},
-    {12, 7, 13, 5, 109, 21},
-    {12, 9, 13, 5, 109, 21},
-    {13, 0, 0, 5, 109, 11},
-    {12, 0, 13, 5, 107, 21},
-    {10, 0, 0, 5, 107, 21},
-    {7, 0, 0, 5, 107, 12},
-    {12, 7, 13, 5, 40, 21},
-    {12, 7, 13, 5, 107, 21},
-    {10, 9, 0, 5, 107, 21},
-    {12, 230, 13, 5, 107, 21},
-    {7, 0, 0, 5, 135, 12},
-    {10, 0, 0, 5, 135, 21},
-    {12, 0, 13, 5, 135, 21},
-    {12, 9, 13, 5, 135, 21},
-    {12, 7, 13, 5, 135, 21},
-    {21, 0, 0, 5, 135, 17},
-    {21, 0, 0, 5, 135, 12},
-    {13, 0, 0, 5, 135, 11},
-    {12, 230, 13, 5, 135, 21},
-    {7, 0, 0, 5, 124, 12},
-    {10, 0, 0, 5, 124, 21},
-    {12, 0, 13, 5, 124, 21},
-    {12, 9, 13, 5, 124, 21},
-    {12, 7, 13, 5, 124, 21},
-    {21, 0, 0, 5, 124, 12},
-    {13, 0, 0, 5, 124, 11},
-    {7, 0, 0, 5, 123, 12},
-    {10, 0, 0, 5, 123, 21},
-    {12, 0, 13, 5, 123, 21},
-    {12, 9, 13, 5, 123, 21},
-    {12, 7, 13, 5, 123, 21},
-    {21, 0, 0, 5, 123, 18},
-    {21, 0, 0, 5, 123, 17},
-    {21, 0, 0, 5, 123, 6},
-    {21, 0, 0, 5, 123, 12},
-    {7, 0, 0, 5, 114, 12},
-    {10, 0, 0, 5, 114, 21},
-    {12, 0, 13, 5, 114, 21},
-    {12, 9, 13, 5, 114, 21},
-    {21, 0, 0, 5, 114, 17},
-    {21, 0, 0, 5, 114, 12},
-    {13, 0, 0, 5, 114, 11},
-    {21, 0, 18, 5, 31, 18},
-    {7, 0, 0, 5, 101, 12},
-    {12, 0, 13, 5, 101, 21},
-    {10, 0, 0, 5, 101, 21},
-    {10, 9, 0, 5, 101, 21},
-    {12, 7, 13, 5, 101, 21},
-    {13, 0, 0, 5, 101, 11},
-    {7, 0, 0, 5, 126, 36},
-    {12, 0, 13, 5, 126, 36},
-    {10, 0, 0, 5, 126, 36},
-    {12, 9, 13, 5, 126, 36},
-    {13, 0, 0, 5, 126, 11},
-    {15, 0, 0, 5, 126, 36},
-    {21, 0, 0, 5, 126, 17},
-    {26, 0, 0, 5, 126, 36},
-    {7, 0, 0, 5, 142, 12},
-    {10, 0, 0, 5, 142, 21},
-    {12, 0, 13, 5, 142, 21},
-    {12, 9, 13, 5, 142, 21},
-    {12, 7, 13, 5, 142, 21},
-    {21, 0, 0, 5, 142, 12},
-    {9, 0, 0, 5, 125, 12},
-    {5, 0, 0, 5, 125, 12},
-    {13, 0, 0, 5, 125, 11},
-    {15, 0, 0, 5, 125, 12},
-    {7, 0, 0, 5, 125, 12},
-    {7, 0, 0, 5, 150, 12},
-    {10, 0, 0, 5, 150, 21},
-    {12, 0, 13, 5, 150, 21},
-    {12, 9, 13, 5, 150, 21},
-    {21, 0, 0, 5, 150, 18},
-    {7, 0, 0, 5, 141, 12},
-    {12, 0, 13, 5, 141, 21},
-    {12, 0, 0, 5, 141, 21},
-    {12, 9, 13, 5, 141, 21},
-    {10, 0, 0, 5, 141, 21},
-    {21, 0, 0, 5, 141, 18},
-    {21, 0, 0, 5, 141, 12},
-    {21, 0, 0, 5, 141, 17},
-    {7, 0, 0, 5, 140, 12},
-    {12, 0, 13, 5, 140, 21},
-    {10, 0, 0, 5, 140, 21},
-    {12, 9, 13, 5, 140, 21},
-    {21, 0, 0, 5, 140, 17},
-    {21, 0, 0, 5, 140, 18},
-    {7, 0, 0, 5, 121, 12},
-    {7, 0, 0, 5, 133, 12},
-    {10, 0, 0, 5, 133, 21},
-    {12, 0, 13, 5, 133, 21},
-    {12, 9, 0, 5, 133, 21},
-    {21, 0, 0, 5, 133, 17},
-    {13, 0, 0, 5, 133, 11},
-    {15, 0, 0, 5, 133, 12},
-    {21, 0, 0, 5, 134, 18},
-    {21, 0, 0, 5, 134, 6},
-    {7, 0, 0, 5, 134, 12},
-    {12, 0, 13, 5, 134, 21},
-    {10, 0, 0, 5, 134, 21},
-    {7, 0, 0, 5, 138, 12},
-    {12, 0, 13, 5, 138, 21},
-    {12, 7, 13, 5, 138, 21},
-    {12, 9, 13, 5, 138, 21},
-    {13, 0, 0, 5, 138, 11},
-    {7, 0, 0, 5, 143, 12},
-    {10, 0, 0, 5, 143, 21},
-    {12, 0, 13, 5, 143, 21},
-    {12, 9, 13, 5, 143, 21},
-    {13, 0, 0, 5, 143, 11},
-    {7, 0, 0, 5, 145, 12},
-    {12, 0, 13, 5, 145, 21},
-    {10, 0, 0, 5, 145, 21},
-    {21, 0, 0, 5, 145, 12},
-    {23, 0, 10, 5, 14, 10},
-    {21, 0, 0, 5, 14, 17},
-    {7, 0, 0, 5, 62, 12},
-    {14, 0, 0, 5, 62, 12},
-    {21, 0, 0, 5, 62, 17},
-    {7, 0, 0, 5, 80, 12},
-    {7, 0, 0, 5, 80, 0},
-    {7, 0, 0, 5, 80, 1},
-    {1, 0, 0, 5, 80, 4},
-    {1, 0, 0, 5, 80, 0},
-    {1, 0, 0, 5, 80, 1},
-    {7, 0, 0, 5, 127, 12},
-    {7, 0, 0, 5, 127, 0},
-    {7, 0, 0, 5, 127, 1},
-    {7, 0, 0, 5, 115, 12},
-    {13, 0, 0, 5, 115, 11},
-    {21, 0, 0, 5, 115, 17},
-    {7, 0, 0, 5, 103, 12},
-    {12, 1, 13, 5, 103, 21},
-    {21, 0, 0, 5, 103, 17},
-    {7, 0, 0, 5, 119, 12},
-    {12, 230, 13, 5, 119, 21},
-    {21, 0, 0, 5, 119, 17},
-    {21, 0, 0, 5, 119, 12},
-    {26, 0, 0, 5, 119, 12},
-    {6, 0, 0, 5, 119, 12},
-    {13, 0, 0, 5, 119, 11},
-    {15, 0, 0, 5, 119, 12},
-    {9, 0, 0, 5, 146, 12},
-    {5, 0, 0, 5, 146, 12},
-    {15, 0, 0, 5, 146, 12},
-    {21, 0, 0, 5, 146, 17},
-    {21, 0, 0, 5, 146, 12},
-    {7, 0, 0, 5, 98, 12},
-    {12, 0, 13, 5, 98, 21},
-    {10, 0, 0, 5, 98, 21},
-    {6, 0, 0, 5, 98, 12},
-    {6, 0, 0, 2, 137, 5},
-    {6, 0, 0, 2, 139, 5},
-    {6, 0, 0, 2, 0, 5},
-    {7, 0, 0, 2, 137, 14},
-    {7, 0, 0, 2, 139, 14},
-    {7, 0, 0, 5, 105, 12},
-    {26, 0, 0, 5, 105, 12},
-    {12, 0, 13, 5, 105, 21},
-    {12, 1, 13, 5, 105, 21},
-    {21, 0, 0, 5, 105, 17},
-    {10, 216, 0, 5, 0, 21},
-    {10, 226, 0, 5, 0, 21},
-    {12, 230, 13, 5, 2, 21},
-    {25, 0, 0, 5, 0, 12},
-    {13, 0, 8, 5, 0, 11},
-    {26, 0, 0, 5, 131, 12},
-    {12, 0, 13, 5, 131, 21},
-    {21, 0, 0, 5, 131, 17},
-    {21, 0, 0, 5, 131, 12},
-    {12, 230, 13, 5, 56, 21},
-    {7, 0, 0, 5, 151, 12},
-    {12, 230, 13, 5, 151, 21},
-    {6, 0, 0, 5, 151, 12},
-    {13, 0, 0, 5, 151, 11},
-    {26, 0, 0, 5, 151, 12},
-    {7, 0, 0, 5, 152, 12},
-    {12, 230, 13, 5, 152, 21},
-    {13, 0, 0, 5, 152, 11},
-    {23, 0, 10, 5, 152, 9},
-    {7, 0, 3, 5, 113, 12},
-    {15, 0, 3, 5, 113, 12},
-    {12, 220, 13, 5, 113, 21},
-    {9, 0, 3, 5, 132, 12},
-    {5, 0, 3, 5, 132, 12},
-    {12, 230, 13, 5, 132, 21},
-    {12, 7, 13, 5, 132, 21},
-    {6, 0, 3, 5, 132, 12},
-    {13, 0, 3, 5, 132, 11},
-    {21, 0, 3, 5, 132, 0},
-    {15, 0, 4, 5, 0, 12},
-    {26, 0, 4, 5, 0, 10},
-    {23, 0, 4, 5, 0, 10},
-    {26, 0, 4, 5, 0, 12},
-    {2, 0, 18, 5, 102, 14},
-    {26, 0, 0, 2, 0, 29},
-    {26, 0, 0, 5, 0, 28},
-    {26, 0, 0, 2, 32, 14},
-    {24, 0, 18, 2, 0, 42},
-    {26, 0, 18, 5, 0, 5},
-};
-
-#define BIDI_MIRROR_LEN 420
-static const MirrorPair mirror_pairs[] = {
-    {40, 41},
-    {41, 40},
-    {60, 62},
-    {62, 60},
-    {91, 93},
-    {93, 91},
-    {123, 125},
-    {125, 123},
-    {171, 187},
-    {187, 171},
-    {3898, 3899},
-    {3899, 3898},
-    {3900, 3901},
-    {3901, 3900},
-    {5787, 5788},
-    {5788, 5787},
-    {8249, 8250},
-    {8250, 8249},
-    {8261, 8262},
-    {8262, 8261},
-    {8317, 8318},
-    {8318, 8317},
-    {8333, 8334},
-    {8334, 8333},
-    {8712, 8715},
-    {8713, 8716},
-    {8714, 8717},
-    {8715, 8712},
-    {8716, 8713},
-    {8717, 8714},
-    {8725, 10741},
-    {8735, 11262},
-    {8736, 10659},
-    {8737, 10651},
-    {8738, 10656},
-    {8740, 10990},
-    {8764, 8765},
-    {8765, 8764},
-    {8771, 8909},
-    {8773, 8780},
-    {8780, 8773},
-    {8786, 8787},
-    {8787, 8786},
-    {8788, 8789},
-    {8789, 8788},
-    {8804, 8805},
-    {8805, 8804},
-    {8806, 8807},
-    {8807, 8806},
-    {8808, 8809},
-    {8809, 8808},
-    {8810, 8811},
-    {8811, 8810},
-    {8814, 8815},
-    {8815, 8814},
-    {8816, 8817},
-    {8817, 8816},
-    {8818, 8819},
-    {8819, 8818},
-    {8820, 8821},
-    {8821, 8820},
-    {8822, 8823},
-    {8823, 8822},
-    {8824, 8825},
-    {8825, 8824},
-    {8826, 8827},
-    {8827, 8826},
-    {8828, 8829},
-    {8829, 8828},
-    {8830, 8831},
-    {8831, 8830},
-    {8832, 8833},
-    {8833, 8832},
-    {8834, 8835},
-    {8835, 8834},
-    {8836, 8837},
-    {8837, 8836},
-    {8838, 8839},
-    {8839, 8838},
-    {8840, 8841},
-    {8841, 8840},
-    {8842, 8843},
-    {8843, 8842},
-    {8847, 8848},
-    {8848, 8847},
-    {8849, 8850},
-    {8850, 8849},
-    {8856, 10680},
-    {8866, 8867},
-    {8867, 8866},
-    {8870, 10974},
-    {8872, 10980},
-    {8873, 10979},
-    {8875, 10981},
-    {8880, 8881},
-    {8881, 8880},
-    {8882, 8883},
-    {8883, 8882},
-    {8884, 8885},
-    {8885, 8884},
-    {8886, 8887},
-    {8887, 8886},
-    {8888, 10204},
-    {8905, 8906},
-    {8906, 8905},
-    {8907, 8908},
-    {8908, 8907},
-    {8909, 8771},
-    {8912, 8913},
-    {8913, 8912},
-    {8918, 8919},
-    {8919, 8918},
-    {8920, 8921},
-    {8921, 8920},
-    {8922, 8923},
-    {8923, 8922},
-    {8924, 8925},
-    {8925, 8924},
-    {8926, 8927},
-    {8927, 8926},
-    {8928, 8929},
-    {8929, 8928},
-    {8930, 8931},
-    {8931, 8930},
-    {8932, 8933},
-    {8933, 8932},
-    {8934, 8935},
-    {8935, 8934},
-    {8936, 8937},
-    {8937, 8936},
-    {8938, 8939},
-    {8939, 8938},
-    {8940, 8941},
-    {8941, 8940},
-    {8944, 8945},
-    {8945, 8944},
-    {8946, 8954},
-    {8947, 8955},
-    {8948, 8956},
-    {8950, 8957},
-    {8951, 8958},
-    {8954, 8946},
-    {8955, 8947},
-    {8956, 8948},
-    {8957, 8950},
-    {8958, 8951},
-    {8968, 8969},
-    {8969, 8968},
-    {8970, 8971},
-    {8971, 8970},
-    {9001, 9002},
-    {9002, 9001},
-    {10088, 10089},
-    {10089, 10088},
-    {10090, 10091},
-    {10091, 10090},
-    {10092, 10093},
-    {10093, 10092},
-    {10094, 10095},
-    {10095, 10094},
-    {10096, 10097},
-    {10097, 10096},
-    {10098, 10099},
-    {10099, 10098},
-    {10100, 10101},
-    {10101, 10100},
-    {10179, 10180},
-    {10180, 10179},
-    {10181, 10182},
-    {10182, 10181},
-    {10184, 10185},
-    {10185, 10184},
-    {10187, 10189},
-    {10189, 10187},
-    {10197, 10198},
-    {10198, 10197},
-    {10204, 8888},
-    {10205, 10206},
-    {10206, 10205},
-    {10210, 10211},
-    {10211, 10210},
-    {10212, 10213},
-    {10213, 10212},
-    {10214, 10215},
-    {10215, 10214},
-    {10216, 10217},
-    {10217, 10216},
-    {10218, 10219},
-    {10219, 10218},
-    {10220, 10221},
-    {10221, 10220},
-    {10222, 10223},
-    {10223, 10222},
-    {10627, 10628},
-    {10628, 10627},
-    {10629, 10630},
-    {10630, 10629},
-    {10631, 10632},
-    {10632, 10631},
-    {10633, 10634},
-    {10634, 10633},
-    {10635, 10636},
-    {10636, 10635},
-    {10637, 10640},
-    {10638, 10639},
-    {10639, 10638},
-    {10640, 10637},
-    {10641, 10642},
-    {10642, 10641},
-    {10643, 10644},
-    {10644, 10643},
-    {10645, 10646},
-    {10646, 10645},
-    {10647, 10648},
-    {10648, 10647},
-    {10651, 8737},
-    {10656, 8738},
-    {10659, 8736},
-    {10660, 10661},
-    {10661, 10660},
-    {10664, 10665},
-    {10665, 10664},
-    {10666, 10667},
-    {10667, 10666},
-    {10668, 10669},
-    {10669, 10668},
-    {10670, 10671},
-    {10671, 10670},
-    {10680, 8856},
-    {10688, 10689},
-    {10689, 10688},
-    {10692, 10693},
-    {10693, 10692},
-    {10703, 10704},
-    {10704, 10703},
-    {10705, 10706},
-    {10706, 10705},
-    {10708, 10709},
-    {10709, 10708},
-    {10712, 10713},
-    {10713, 10712},
-    {10714, 10715},
-    {10715, 10714},
-    {10728, 10729},
-    {10729, 10728},
-    {10741, 8725},
-    {10744, 10745},
-    {10745, 10744},
-    {10748, 10749},
-    {10749, 10748},
-    {10795, 10796},
-    {10796, 10795},
-    {10797, 10798},
-    {10798, 10797},
-    {10804, 10805},
-    {10805, 10804},
-    {10812, 10813},
-    {10813, 10812},
-    {10852, 10853},
-    {10853, 10852},
-    {10873, 10874},
-    {10874, 10873},
-    {10875, 10876},
-    {10876, 10875},
-    {10877, 10878},
-    {10878, 10877},
-    {10879, 10880},
-    {10880, 10879},
-    {10881, 10882},
-    {10882, 10881},
-    {10883, 10884},
-    {10884, 10883},
-    {10885, 10886},
-    {10886, 10885},
-    {10887, 10888},
-    {10888, 10887},
-    {10889, 10890},
-    {10890, 10889},
-    {10891, 10892},
-    {10892, 10891},
-    {10893, 10894},
-    {10894, 10893},
-    {10895, 10896},
-    {10896, 10895},
-    {10897, 10898},
-    {10898, 10897},
-    {10899, 10900},
-    {10900, 10899},
-    {10901, 10902},
-    {10902, 10901},
-    {10903, 10904},
-    {10904, 10903},
-    {10905, 10906},
-    {10906, 10905},
-    {10907, 10908},
-    {10908, 10907},
-    {10909, 10910},
-    {10910, 10909},
-    {10911, 10912},
-    {10912, 10911},
-    {10913, 10914},
-    {10914, 10913},
-    {10918, 10919},
-    {10919, 10918},
-    {10920, 10921},
-    {10921, 10920},
-    {10922, 10923},
-    {10923, 10922},
-    {10924, 10925},
-    {10925, 10924},
-    {10927, 10928},
-    {10928, 10927},
-    {10929, 10930},
-    {10930, 10929},
-    {10931, 10932},
-    {10932, 10931},
-    {10933, 10934},
-    {10934, 10933},
-    {10935, 10936},
-    {10936, 10935},
-    {10937, 10938},
-    {10938, 10937},
-    {10939, 10940},
-    {10940, 10939},
-    {10941, 10942},
-    {10942, 10941},
-    {10943, 10944},
-    {10944, 10943},
-    {10945, 10946},
-    {10946, 10945},
-    {10947, 10948},
-    {10948, 10947},
-    {10949, 10950},
-    {10950, 10949},
-    {10951, 10952},
-    {10952, 10951},
-    {10953, 10954},
-    {10954, 10953},
-    {10955, 10956},
-    {10956, 10955},
-    {10957, 10958},
-    {10958, 10957},
-    {10959, 10960},
-    {10960, 10959},
-    {10961, 10962},
-    {10962, 10961},
-    {10963, 10964},
-    {10964, 10963},
-    {10965, 10966},
-    {10966, 10965},
-    {10974, 8870},
-    {10979, 8873},
-    {10980, 8872},
-    {10981, 8875},
-    {10988, 10989},
-    {10989, 10988},
-    {10990, 8740},
-    {10999, 11000},
-    {11000, 10999},
-    {11001, 11002},
-    {11002, 11001},
-    {11262, 8735},
-    {11778, 11779},
-    {11779, 11778},
-    {11780, 11781},
-    {11781, 11780},
-    {11785, 11786},
-    {11786, 11785},
-    {11788, 11789},
-    {11789, 11788},
-    {11804, 11805},
-    {11805, 11804},
-    {11808, 11809},
-    {11809, 11808},
-    {11810, 11811},
-    {11811, 11810},
-    {11812, 11813},
-    {11813, 11812},
-    {11814, 11815},
-    {11815, 11814},
-    {11816, 11817},
-    {11817, 11816},
-    {12296, 12297},
-    {12297, 12296},
-    {12298, 12299},
-    {12299, 12298},
-    {12300, 12301},
-    {12301, 12300},
-    {12302, 12303},
-    {12303, 12302},
-    {12304, 12305},
-    {12305, 12304},
-    {12308, 12309},
-    {12309, 12308},
-    {12310, 12311},
-    {12311, 12310},
-    {12312, 12313},
-    {12313, 12312},
-    {12314, 12315},
-    {12315, 12314},
-    {65113, 65114},
-    {65114, 65113},
-    {65115, 65116},
-    {65116, 65115},
-    {65117, 65118},
-    {65118, 65117},
-    {65124, 65125},
-    {65125, 65124},
-    {65288, 65289},
-    {65289, 65288},
-    {65308, 65310},
-    {65310, 65308},
-    {65339, 65341},
-    {65341, 65339},
-    {65371, 65373},
-    {65373, 65371},
-    {65375, 65376},
-    {65376, 65375},
-    {65378, 65379},
-    {65379, 65378},
-};
-
-#define BIDI_BRACKET_LEN 120
-static const BracketPair bracket_pairs[] = {
-    {40, 41, 0},
-    {41, 40, 1},
-    {91, 93, 0},
-    {93, 91, 1},
-    {123, 125, 0},
-    {125, 123, 1},
-    {3898, 3899, 0},
-    {3899, 3898, 1},
-    {3900, 3901, 0},
-    {3901, 3900, 1},
-    {5787, 5788, 0},
-    {5788, 5787, 1},
-    {8261, 8262, 0},
-    {8262, 8261, 1},
-    {8317, 8318, 0},
-    {8318, 8317, 1},
-    {8333, 8334, 0},
-    {8334, 8333, 1},
-    {8968, 8969, 0},
-    {8969, 8968, 1},
-    {8970, 8971, 0},
-    {8971, 8970, 1},
-    {9001, 9002, 0},
-    {9002, 9001, 1},
-    {10088, 10089, 0},
-    {10089, 10088, 1},
-    {10090, 10091, 0},
-    {10091, 10090, 1},
-    {10092, 10093, 0},
-    {10093, 10092, 1},
-    {10094, 10095, 0},
-    {10095, 10094, 1},
-    {10096, 10097, 0},
-    {10097, 10096, 1},
-    {10098, 10099, 0},
-    {10099, 10098, 1},
-    {10100, 10101, 0},
-    {10101, 10100, 1},
-    {10181, 10182, 0},
-    {10182, 10181, 1},
-    {10214, 10215, 0},
-    {10215, 10214, 1},
-    {10216, 10217, 0},
-    {10217, 10216, 1},
-    {10218, 10219, 0},
-    {10219, 10218, 1},
-    {10220, 10221, 0},
-    {10221, 10220, 1},
-    {10222, 10223, 0},
-    {10223, 10222, 1},
-    {10627, 10628, 0},
-    {10628, 10627, 1},
-    {10629, 10630, 0},
-    {10630, 10629, 1},
-    {10631, 10632, 0},
-    {10632, 10631, 1},
-    {10633, 10634, 0},
-    {10634, 10633, 1},
-    {10635, 10636, 0},
-    {10636, 10635, 1},
-    {10637, 10640, 0},
-    {10638, 10639, 1},
-    {10639, 10638, 0},
-    {10640, 10637, 1},
-    {10641, 10642, 0},
-    {10642, 10641, 1},
-    {10643, 10644, 0},
-    {10644, 10643, 1},
-    {10645, 10646, 0},
-    {10646, 10645, 1},
-    {10647, 10648, 0},
-    {10648, 10647, 1},
-    {10712, 10713, 0},
-    {10713, 10712, 1},
-    {10714, 10715, 0},
-    {10715, 10714, 1},
-    {10748, 10749, 0},
-    {10749, 10748, 1},
-    {11810, 11811, 0},
-    {11811, 11810, 1},
-    {11812, 11813, 0},
-    {11813, 11812, 1},
-    {11814, 11815, 0},
-    {11815, 11814, 1},
-    {11816, 11817, 0},
-    {11817, 11816, 1},
-    {12296, 12297, 0},
-    {12297, 12296, 1},
-    {12298, 12299, 0},
-    {12299, 12298, 1},
-    {12300, 12301, 0},
-    {12301, 12300, 1},
-    {12302, 12303, 0},
-    {12303, 12302, 1},
-    {12304, 12305, 0},
-    {12305, 12304, 1},
-    {12308, 12309, 0},
-    {12309, 12308, 1},
-    {12310, 12311, 0},
-    {12311, 12310, 1},
-    {12312, 12313, 0},
-    {12313, 12312, 1},
-    {12314, 12315, 0},
-    {12315, 12314, 1},
-    {65113, 65114, 0},
-    {65114, 65113, 1},
-    {65115, 65116, 0},
-    {65116, 65115, 1},
-    {65117, 65118, 0},
-    {65118, 65117, 1},
-    {65288, 65289, 0},
-    {65289, 65288, 1},
-    {65339, 65341, 0},
-    {65341, 65339, 1},
-    {65371, 65373, 0},
-    {65373, 65371, 1},
-    {65375, 65376, 0},
-    {65376, 65375, 1},
-    {65378, 65379, 0},
-    {65379, 65378, 1},
-};
-
-/* Reindexing of NFC first characters. */
-#define TOTAL_FIRST 376
-#define TOTAL_LAST 62
-static const Reindex nfc_first[] = {
-  { 60, 2, 0},
-  { 65, 15, 3},
-  { 82, 8, 19},
-  { 97, 15, 28},
-  { 114, 8, 44},
-  { 168, 0, 53},
-  { 194, 0, 54},
-  { 196, 3, 55},
-  { 202, 0, 59},
-  { 207, 0, 60},
-  { 212, 2, 61},
-  { 216, 0, 64},
-  { 220, 0, 65},
-  { 226, 0, 66},
-  { 228, 3, 67},
-  { 234, 0, 71},
-  { 239, 0, 72},
-  { 244, 2, 73},
-  { 248, 0, 76},
-  { 252, 0, 77},
-  { 258, 1, 78},
-  { 274, 1, 80},
-  { 332, 1, 82},
-  { 346, 1, 84},
-  { 352, 1, 86},
-  { 360, 3, 88},
-  { 383, 0, 92},
-  { 416, 1, 93},
-  { 431, 1, 95},
-  { 439, 0, 97},
-  { 490, 1, 98},
-  { 550, 3, 100},
-  { 558, 1, 104},
-  { 658, 0, 106},
-  { 913, 0, 107},
-  { 917, 0, 108},
-  { 919, 0, 109},
-  { 921, 0, 110},
-  { 927, 0, 111},
-  { 929, 0, 112},
-  { 933, 0, 113},
-  { 937, 0, 114},
-  { 940, 0, 115},
-  { 942, 0, 116},
-  { 945, 0, 117},
-  { 949, 0, 118},
-  { 951, 0, 119},
-  { 953, 0, 120},
-  { 959, 0, 121},
-  { 961, 0, 122},
-  { 965, 0, 123},
-  { 969, 2, 124},
-  { 974, 0, 127},
-  { 978, 0, 128},
-  { 1030, 0, 129},
-  { 1040, 0, 130},
-  { 1043, 0, 131},
-  { 1045, 3, 132},
-  { 1050, 0, 136},
-  { 1054, 0, 137},
-  { 1059, 0, 138},
-  { 1063, 0, 139},
-  { 1067, 0, 140},
-  { 1069, 0, 141},
-  { 1072, 0, 142},
-  { 1075, 0, 143},
-  { 1077, 3, 144},
-  { 1082, 0, 148},
-  { 1086, 0, 149},
-  { 1091, 0, 150},
-  { 1095, 0, 151},
-  { 1099, 0, 152},
-  { 1101, 0, 153},
-  { 1110, 0, 154},
-  { 1140, 1, 155},
-  { 1240, 1, 157},
-  { 1256, 1, 159},
-  { 1575, 0, 161},
-  { 1608, 0, 162},
-  { 1610, 0, 163},
-  { 1729, 0, 164},
-  { 1746, 0, 165},
-  { 1749, 0, 166},
-  { 2344, 0, 167},
-  { 2352, 0, 168},
-  { 2355, 0, 169},
-  { 2503, 0, 170},
-  { 2887, 0, 171},
-  { 2962, 0, 172},
-  { 3014, 1, 173},
-  { 3142, 0, 175},
-  { 3263, 0, 176},
-  { 3270, 0, 177},
-  { 3274, 0, 178},
-  { 3398, 1, 179},
-  { 3545, 0, 181},
-  { 3548, 0, 182},
-  { 4133, 0, 183},
-  { 6917, 0, 184},
-  { 6919, 0, 185},
-  { 6921, 0, 186},
-  { 6923, 0, 187},
-  { 6925, 0, 188},
-  { 6929, 0, 189},
-  { 6970, 0, 190},
-  { 6972, 0, 191},
-  { 6974, 1, 192},
-  { 6978, 0, 194},
-  { 7734, 1, 195},
-  { 7770, 1, 197},
-  { 7778, 1, 199},
-  { 7840, 1, 201},
-  { 7864, 1, 203},
-  { 7884, 1, 205},
-  { 7936, 17, 207},
-  { 7960, 1, 225},
-  { 7968, 17, 227},
-  { 7992, 1, 245},
-  { 8000, 1, 247},
-  { 8008, 1, 249},
-  { 8016, 1, 251},
-  { 8025, 0, 253},
-  { 8032, 16, 254},
-  { 8052, 0, 271},
-  { 8060, 0, 272},
-  { 8118, 0, 273},
-  { 8127, 0, 274},
-  { 8134, 0, 275},
-  { 8182, 0, 276},
-  { 8190, 0, 277},
-  { 8592, 0, 278},
-  { 8594, 0, 279},
-  { 8596, 0, 280},
-  { 8656, 0, 281},
-  { 8658, 0, 282},
-  { 8660, 0, 283},
-  { 8707, 0, 284},
-  { 8712, 0, 285},
-  { 8715, 0, 286},
-  { 8739, 0, 287},
-  { 8741, 0, 288},
-  { 8764, 0, 289},
-  { 8771, 0, 290},
-  { 8773, 0, 291},
-  { 8776, 0, 292},
-  { 8781, 0, 293},
-  { 8801, 0, 294},
-  { 8804, 1, 295},
-  { 8818, 1, 297},
-  { 8822, 1, 299},
-  { 8826, 3, 301},
-  { 8834, 1, 305},
-  { 8838, 1, 307},
-  { 8849, 1, 309},
-  { 8866, 0, 311},
-  { 8872, 1, 312},
-  { 8875, 0, 314},
-  { 8882, 3, 315},
-  { 12358, 0, 319},
-  { 12363, 0, 320},
-  { 12365, 0, 321},
-  { 12367, 0, 322},
-  { 12369, 0, 323},
-  { 12371, 0, 324},
-  { 12373, 0, 325},
-  { 12375, 0, 326},
-  { 12377, 0, 327},
-  { 12379, 0, 328},
-  { 12381, 0, 329},
-  { 12383, 0, 330},
-  { 12385, 0, 331},
-  { 12388, 0, 332},
-  { 12390, 0, 333},
-  { 12392, 0, 334},
-  { 12399, 0, 335},
-  { 12402, 0, 336},
-  { 12405, 0, 337},
-  { 12408, 0, 338},
-  { 12411, 0, 339},
-  { 12445, 0, 340},
-  { 12454, 0, 341},
-  { 12459, 0, 342},
-  { 12461, 0, 343},
-  { 12463, 0, 344},
-  { 12465, 0, 345},
-  { 12467, 0, 346},
-  { 12469, 0, 347},
-  { 12471, 0, 348},
-  { 12473, 0, 349},
-  { 12475, 0, 350},
-  { 12477, 0, 351},
-  { 12479, 0, 352},
-  { 12481, 0, 353},
-  { 12484, 0, 354},
-  { 12486, 0, 355},
-  { 12488, 0, 356},
-  { 12495, 0, 357},
-  { 12498, 0, 358},
-  { 12501, 0, 359},
-  { 12504, 0, 360},
-  { 12507, 0, 361},
-  { 12527, 3, 362},
-  { 12541, 0, 366},
-  { 69785, 0, 367},
-  { 69787, 0, 368},
-  { 69797, 0, 369},
-  { 69937, 1, 370},
-  { 70471, 0, 372},
-  { 70841, 0, 373},
-  { 71096, 1, 374},
-  {0,0,0}
-};
-
-static const Reindex nfc_last[] = {
-  { 768, 4, 0},
-  { 774, 6, 5},
-  { 783, 0, 12},
-  { 785, 0, 13},
-  { 787, 1, 14},
-  { 795, 0, 16},
-  { 803, 5, 17},
-  { 813, 1, 23},
-  { 816, 1, 25},
-  { 824, 0, 27},
-  { 834, 0, 28},
-  { 837, 0, 29},
-  { 1619, 2, 30},
-  { 2364, 0, 33},
-  { 2494, 0, 34},
-  { 2519, 0, 35},
-  { 2878, 0, 36},
-  { 2902, 1, 37},
-  { 3006, 0, 39},
-  { 3031, 0, 40},
-  { 3158, 0, 41},
-  { 3266, 0, 42},
-  { 3285, 1, 43},
-  { 3390, 0, 45},
-  { 3415, 0, 46},
-  { 3530, 0, 47},
-  { 3535, 0, 48},
-  { 3551, 0, 49},
-  { 4142, 0, 50},
-  { 6965, 0, 51},
-  { 12441, 1, 52},
-  { 69818, 0, 54},
-  { 69927, 0, 55},
-  { 70462, 0, 56},
-  { 70487, 0, 57},
-  { 70832, 0, 58},
-  { 70842, 0, 59},
-  { 70845, 0, 60},
-  { 71087, 0, 61},
-  {0,0,0}
-};
-
-#define UCDN_EAST_ASIAN_F 0
-#define UCDN_EAST_ASIAN_H 1
-#define UCDN_EAST_ASIAN_W 2
-#define UCDN_EAST_ASIAN_NA 3
-#define UCDN_EAST_ASIAN_A 4
-#define UCDN_EAST_ASIAN_N 5
-
-#define UCDN_SCRIPT_COMMON 0
-#define UCDN_SCRIPT_LATIN 1
-#define UCDN_SCRIPT_GREEK 2
-#define UCDN_SCRIPT_CYRILLIC 3
-#define UCDN_SCRIPT_ARMENIAN 4
-#define UCDN_SCRIPT_HEBREW 5
-#define UCDN_SCRIPT_ARABIC 6
-#define UCDN_SCRIPT_SYRIAC 7
-#define UCDN_SCRIPT_THAANA 8
-#define UCDN_SCRIPT_DEVANAGARI 9
-#define UCDN_SCRIPT_BENGALI 10
-#define UCDN_SCRIPT_GURMUKHI 11
-#define UCDN_SCRIPT_GUJARATI 12
-#define UCDN_SCRIPT_ORIYA 13
-#define UCDN_SCRIPT_TAMIL 14
-#define UCDN_SCRIPT_TELUGU 15
-#define UCDN_SCRIPT_KANNADA 16
-#define UCDN_SCRIPT_MALAYALAM 17
-#define UCDN_SCRIPT_SINHALA 18
-#define UCDN_SCRIPT_THAI 19
-#define UCDN_SCRIPT_LAO 20
-#define UCDN_SCRIPT_TIBETAN 21
-#define UCDN_SCRIPT_MYANMAR 22
-#define UCDN_SCRIPT_GEORGIAN 23
-#define UCDN_SCRIPT_HANGUL 24
-#define UCDN_SCRIPT_ETHIOPIC 25
-#define UCDN_SCRIPT_CHEROKEE 26
-#define UCDN_SCRIPT_CANADIAN_ABORIGINAL 27
-#define UCDN_SCRIPT_OGHAM 28
-#define UCDN_SCRIPT_RUNIC 29
-#define UCDN_SCRIPT_KHMER 30
-#define UCDN_SCRIPT_MONGOLIAN 31
-#define UCDN_SCRIPT_HIRAGANA 32
-#define UCDN_SCRIPT_KATAKANA 33
-#define UCDN_SCRIPT_BOPOMOFO 34
-#define UCDN_SCRIPT_HAN 35
-#define UCDN_SCRIPT_YI 36
-#define UCDN_SCRIPT_OLD_ITALIC 37
-#define UCDN_SCRIPT_GOTHIC 38
-#define UCDN_SCRIPT_DESERET 39
-#define UCDN_SCRIPT_INHERITED 40
-#define UCDN_SCRIPT_TAGALOG 41
-#define UCDN_SCRIPT_HANUNOO 42
-#define UCDN_SCRIPT_BUHID 43
-#define UCDN_SCRIPT_TAGBANWA 44
-#define UCDN_SCRIPT_LIMBU 45
-#define UCDN_SCRIPT_TAI_LE 46
-#define UCDN_SCRIPT_LINEAR_B 47
-#define UCDN_SCRIPT_UGARITIC 48
-#define UCDN_SCRIPT_SHAVIAN 49
-#define UCDN_SCRIPT_OSMANYA 50
-#define UCDN_SCRIPT_CYPRIOT 51
-#define UCDN_SCRIPT_BRAILLE 52
-#define UCDN_SCRIPT_BUGINESE 53
-#define UCDN_SCRIPT_COPTIC 54
-#define UCDN_SCRIPT_NEW_TAI_LUE 55
-#define UCDN_SCRIPT_GLAGOLITIC 56
-#define UCDN_SCRIPT_TIFINAGH 57
-#define UCDN_SCRIPT_SYLOTI_NAGRI 58
-#define UCDN_SCRIPT_OLD_PERSIAN 59
-#define UCDN_SCRIPT_KHAROSHTHI 60
-#define UCDN_SCRIPT_BALINESE 61
-#define UCDN_SCRIPT_CUNEIFORM 62
-#define UCDN_SCRIPT_PHOENICIAN 63
-#define UCDN_SCRIPT_PHAGS_PA 64
-#define UCDN_SCRIPT_NKO 65
-#define UCDN_SCRIPT_SUNDANESE 66
-#define UCDN_SCRIPT_LEPCHA 67
-#define UCDN_SCRIPT_OL_CHIKI 68
-#define UCDN_SCRIPT_VAI 69
-#define UCDN_SCRIPT_SAURASHTRA 70
-#define UCDN_SCRIPT_KAYAH_LI 71
-#define UCDN_SCRIPT_REJANG 72
-#define UCDN_SCRIPT_LYCIAN 73
-#define UCDN_SCRIPT_CARIAN 74
-#define UCDN_SCRIPT_LYDIAN 75
-#define UCDN_SCRIPT_CHAM 76
-#define UCDN_SCRIPT_TAI_THAM 77
-#define UCDN_SCRIPT_TAI_VIET 78
-#define UCDN_SCRIPT_AVESTAN 79
-#define UCDN_SCRIPT_EGYPTIAN_HIEROGLYPHS 80
-#define UCDN_SCRIPT_SAMARITAN 81
-#define UCDN_SCRIPT_LISU 82
-#define UCDN_SCRIPT_BAMUM 83
-#define UCDN_SCRIPT_JAVANESE 84
-#define UCDN_SCRIPT_MEETEI_MAYEK 85
-#define UCDN_SCRIPT_IMPERIAL_ARAMAIC 86
-#define UCDN_SCRIPT_OLD_SOUTH_ARABIAN 87
-#define UCDN_SCRIPT_INSCRIPTIONAL_PARTHIAN 88
-#define UCDN_SCRIPT_INSCRIPTIONAL_PAHLAVI 89
-#define UCDN_SCRIPT_OLD_TURKIC 90
-#define UCDN_SCRIPT_KAITHI 91
-#define UCDN_SCRIPT_BATAK 92
-#define UCDN_SCRIPT_BRAHMI 93
-#define UCDN_SCRIPT_MANDAIC 94
-#define UCDN_SCRIPT_CHAKMA 95
-#define UCDN_SCRIPT_MEROITIC_CURSIVE 96
-#define UCDN_SCRIPT_MEROITIC_HIEROGLYPHS 97
-#define UCDN_SCRIPT_MIAO 98
-#define UCDN_SCRIPT_SHARADA 99
-#define UCDN_SCRIPT_SORA_SOMPENG 100
-#define UCDN_SCRIPT_TAKRI 101
-#define UCDN_SCRIPT_UNKNOWN 102
-#define UCDN_SCRIPT_BASSA_VAH 103
-#define UCDN_SCRIPT_CAUCASIAN_ALBANIAN 104
-#define UCDN_SCRIPT_DUPLOYAN 105
-#define UCDN_SCRIPT_ELBASAN 106
-#define UCDN_SCRIPT_GRANTHA 107
-#define UCDN_SCRIPT_KHOJKI 108
-#define UCDN_SCRIPT_KHUDAWADI 109
-#define UCDN_SCRIPT_LINEAR_A 110
-#define UCDN_SCRIPT_MAHAJANI 111
-#define UCDN_SCRIPT_MANICHAEAN 112
-#define UCDN_SCRIPT_MENDE_KIKAKUI 113
-#define UCDN_SCRIPT_MODI 114
-#define UCDN_SCRIPT_MRO 115
-#define UCDN_SCRIPT_NABATAEAN 116
-#define UCDN_SCRIPT_OLD_NORTH_ARABIAN 117
-#define UCDN_SCRIPT_OLD_PERMIC 118
-#define UCDN_SCRIPT_PAHAWH_HMONG 119
-#define UCDN_SCRIPT_PALMYRENE 120
-#define UCDN_SCRIPT_PAU_CIN_HAU 121
-#define UCDN_SCRIPT_PSALTER_PAHLAVI 122
-#define UCDN_SCRIPT_SIDDHAM 123
-#define UCDN_SCRIPT_TIRHUTA 124
-#define UCDN_SCRIPT_WARANG_CITI 125
-#define UCDN_SCRIPT_AHOM 126
-#define UCDN_SCRIPT_ANATOLIAN_HIEROGLYPHS 127
-#define UCDN_SCRIPT_HATRAN 128
-#define UCDN_SCRIPT_MULTANI 129
-#define UCDN_SCRIPT_OLD_HUNGARIAN 130
-#define UCDN_SCRIPT_SIGNWRITING 131
-#define UCDN_SCRIPT_ADLAM 132
-#define UCDN_SCRIPT_BHAIKSUKI 133
-#define UCDN_SCRIPT_MARCHEN 134
-#define UCDN_SCRIPT_NEWA 135
-#define UCDN_SCRIPT_OSAGE 136
-#define UCDN_SCRIPT_TANGUT 137
-#define UCDN_SCRIPT_MASARAM_GONDI 138
-#define UCDN_SCRIPT_NUSHU 139
-#define UCDN_SCRIPT_SOYOMBO 140
-#define UCDN_SCRIPT_ZANABAZAR_SQUARE 141
-#define UCDN_SCRIPT_DOGRA 142
-#define UCDN_SCRIPT_GUNJALA_GONDI 143
-#define UCDN_SCRIPT_HANIFI_ROHINGYA 144
-#define UCDN_SCRIPT_MAKASAR 145
-#define UCDN_SCRIPT_MEDEFAIDRIN 146
-#define UCDN_SCRIPT_OLD_SOGDIAN 147
-#define UCDN_SCRIPT_SOGDIAN 148
-#define UCDN_SCRIPT_ELYMAIC 149
-#define UCDN_SCRIPT_NANDINAGARI 150
-#define UCDN_SCRIPT_NYIAKENG_PUACHUE_HMONG 151
-#define UCDN_SCRIPT_WANCHO 152
-
-#define UCDN_GENERAL_CATEGORY_CC 0
-#define UCDN_GENERAL_CATEGORY_CF 1
-#define UCDN_GENERAL_CATEGORY_CN 2
-#define UCDN_GENERAL_CATEGORY_CO 3
-#define UCDN_GENERAL_CATEGORY_CS 4
-#define UCDN_GENERAL_CATEGORY_LL 5
-#define UCDN_GENERAL_CATEGORY_LM 6
-#define UCDN_GENERAL_CATEGORY_LO 7
-#define UCDN_GENERAL_CATEGORY_LT 8
-#define UCDN_GENERAL_CATEGORY_LU 9
-#define UCDN_GENERAL_CATEGORY_MC 10
-#define UCDN_GENERAL_CATEGORY_ME 11
-#define UCDN_GENERAL_CATEGORY_MN 12
-#define UCDN_GENERAL_CATEGORY_ND 13
-#define UCDN_GENERAL_CATEGORY_NL 14
-#define UCDN_GENERAL_CATEGORY_NO 15
-#define UCDN_GENERAL_CATEGORY_PC 16
-#define UCDN_GENERAL_CATEGORY_PD 17
-#define UCDN_GENERAL_CATEGORY_PE 18
-#define UCDN_GENERAL_CATEGORY_PF 19
-#define UCDN_GENERAL_CATEGORY_PI 20
-#define UCDN_GENERAL_CATEGORY_PO 21
-#define UCDN_GENERAL_CATEGORY_PS 22
-#define UCDN_GENERAL_CATEGORY_SC 23
-#define UCDN_GENERAL_CATEGORY_SK 24
-#define UCDN_GENERAL_CATEGORY_SM 25
-#define UCDN_GENERAL_CATEGORY_SO 26
-#define UCDN_GENERAL_CATEGORY_ZL 27
-#define UCDN_GENERAL_CATEGORY_ZP 28
-#define UCDN_GENERAL_CATEGORY_ZS 29
-
-#define UCDN_BIDI_CLASS_L 0
-#define UCDN_BIDI_CLASS_LRE 1
-#define UCDN_BIDI_CLASS_LRO 2
-#define UCDN_BIDI_CLASS_R 3
-#define UCDN_BIDI_CLASS_AL 4
-#define UCDN_BIDI_CLASS_RLE 5
-#define UCDN_BIDI_CLASS_RLO 6
-#define UCDN_BIDI_CLASS_PDF 7
-#define UCDN_BIDI_CLASS_EN 8
-#define UCDN_BIDI_CLASS_ES 9
-#define UCDN_BIDI_CLASS_ET 10
-#define UCDN_BIDI_CLASS_AN 11
-#define UCDN_BIDI_CLASS_CS 12
-#define UCDN_BIDI_CLASS_NSM 13
-#define UCDN_BIDI_CLASS_BN 14
-#define UCDN_BIDI_CLASS_B 15
-#define UCDN_BIDI_CLASS_S 16
-#define UCDN_BIDI_CLASS_WS 17
-#define UCDN_BIDI_CLASS_ON 18
-#define UCDN_BIDI_CLASS_LRI 19
-#define UCDN_BIDI_CLASS_RLI 20
-#define UCDN_BIDI_CLASS_FSI 21
-#define UCDN_BIDI_CLASS_PDI 22
-
-/* index tables for the database records */
-#define SHIFT1 5
-#define SHIFT2 3
-static const unsigned char index0[] = {
-    0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 
-    21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 
-    39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 52, 52, 52, 52, 
-    52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 
-    52, 52, 53, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 
-    52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 
-    52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 
-    52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 
-    52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 54, 55, 56, 56, 56, 57, 
-    58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 65, 66, 67, 68, 
-    69, 70, 71, 65, 66, 67, 68, 69, 70, 71, 65, 66, 67, 68, 69, 70, 71, 65, 
-    66, 67, 68, 69, 70, 71, 65, 66, 67, 68, 69, 70, 71, 65, 72, 73, 73, 73, 
-    73, 73, 73, 73, 73, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 
-    74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 52, 75, 76, 77, 78, 79, 
-    80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 
-    98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 
-    113, 113, 113, 114, 115, 116, 108, 108, 108, 108, 108, 108, 108, 108, 
-    108, 108, 117, 117, 118, 119, 120, 108, 108, 108, 108, 108, 108, 108, 
-    108, 108, 108, 108, 108, 108, 108, 108, 121, 122, 123, 108, 108, 108, 
-    108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 
-    108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 
-    108, 108, 124, 124, 125, 126, 108, 108, 127, 128, 129, 129, 129, 129, 
-    129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 
-    129, 129, 129, 129, 129, 130, 129, 129, 131, 108, 108, 108, 108, 108, 
-    108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 
-    108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 
-    108, 108, 108, 108, 132, 133, 134, 108, 108, 108, 108, 108, 108, 108, 
-    108, 108, 135, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 
-    108, 108, 108, 108, 108, 108, 108, 108, 136, 137, 138, 139, 140, 141, 
-    142, 143, 144, 144, 145, 108, 108, 108, 108, 108, 146, 147, 148, 108, 
-    108, 108, 108, 108, 149, 150, 108, 108, 151, 152, 153, 108, 154, 155, 
-    156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 165, 165, 165, 166, 52, 
-    52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 
-    52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 
-    52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 
-    52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 
-    52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 
-    52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 
-    52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 
-    52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 
-    52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 
-    52, 52, 52, 167, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 
-    52, 52, 168, 169, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 
-    52, 52, 52, 52, 52, 52, 52, 170, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 
-    52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 
-    171, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 52, 52, 
-    173, 172, 172, 172, 172, 174, 172, 172, 172, 172, 172, 172, 172, 172, 
-    172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 
-    172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 
-    172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 
-    172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 
-    172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 
-    172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 
-    172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 
-    172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 
-    172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 
-    172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 
-    172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 
-    172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 
-    172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 
-    172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 
-    172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 
-    172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 
-    172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 
-    172, 172, 172, 172, 172, 172, 172, 172, 172, 174, 108, 108, 108, 108, 
-    108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 
-    108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 
-    108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 
-    108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 
-    108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 
-    108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 
-    108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 
-    108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 
-    108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 
-    108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 
-    108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 
-    108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 
-    108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 
-    108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 
-    108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 
-    108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 
-    108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 
-    108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 
-    108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 
-    108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 
-    108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 
-    108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 
-    108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 
-    108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 
-    108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 
-    108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 
-    108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 
-    108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 
-    108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 
-    108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 
-    108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 
-    108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 
-    108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 
-    108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 
-    108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 
-    108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 
-    108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 
-    108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 
-    108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 
-    108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 
-    108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 
-    108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 
-    108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 
-    108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 
-    108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 
-    108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 
-    108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 
-    108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 
-    108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 
-    108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 
-    108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 
-    108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 
-    108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 
-    108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 
-    108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 
-    108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 
-    108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 
-    108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 
-    108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 
-    108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 
-    108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 
-    108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 
-    108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 
-    108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 
-    108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 
-    108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 
-    108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 
-    108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 
-    108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 
-    108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 
-    108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 
-    108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 
-    108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 
-    108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 
-    108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 
-    108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 
-    108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 
-    108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 
-    108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 
-    108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 
-    108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 
-    108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 
-    108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 
-    108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 
-    108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 
-    108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 
-    108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 
-    108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 
-    108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 
-    108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 
-    108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 
-    108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 
-    108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 
-    108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 
-    108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 
-    108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 
-    108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 
-    108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 
-    108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 
-    108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 
-    108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 
-    108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 
-    108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 
-    108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 
-    108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 
-    108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 
-    108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 
-    108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 
-    108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 
-    108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 
-    108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 
-    108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 
-    108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 
-    108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 
-    108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 
-    108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 
-    108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 
-    108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 
-    108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 
-    108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 
-    108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 
-    108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 
-    108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 
-    108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 
-    108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 
-    108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 
-    108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 
-    108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 
-    108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 
-    108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 
-    108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 
-    108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 
-    108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 
-    108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 
-    108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 
-    108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 
-    108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 
-    108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 
-    108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 
-    108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 
-    108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 
-    108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 
-    108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 
-    108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 
-    108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 
-    108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 
-    108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 
-    108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 
-    108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 
-    108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 
-    108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 
-    108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 
-    108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 
-    108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 
-    108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 
-    108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 
-    108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 
-    108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 
-    108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 
-    108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 
-    108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 
-    108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 
-    108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 
-    108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 
-    108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 
-    108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 
-    108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 
-    108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 
-    108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 
-    108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 
-    108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 
-    108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 
-    108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 
-    108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 
-    108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 
-    108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 
-    108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 
-    108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 
-    108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 
-    108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 
-    108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 
-    108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 
-    108, 108, 108, 108, 108, 108, 108, 108, 175, 176, 108, 108, 108, 108, 
-    108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 
-    108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 
-    108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 
-    108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 
-    108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 
-    108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 
-    108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 
-    108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 
-    108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 
-    108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 
-    108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 
-    108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 
-    108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 
-    108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 
-    108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 
-    108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 
-    108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 
-    108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 74, 74, 74, 
-    74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 
-    74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 
-    74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 
-    74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 
-    74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 
-    74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 
-    74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 
-    74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 
-    74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 
-    74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 
-    74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 
-    74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 
-    74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 
-    74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 
-    177, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 
-    74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 
-    74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 
-    74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 
-    74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 
-    74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 
-    74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 
-    74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 
-    74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 
-    74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 
-    74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 
-    74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 
-    74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 
-    74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 
-    74, 74, 74, 74, 177, 
-};
-
-static const unsigned short index1[] = {
-    0, 1, 0, 2, 3, 4, 5, 6, 7, 8, 8, 9, 10, 11, 11, 12, 13, 0, 0, 0, 14, 15, 
-    16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 29, 31, 32, 
-    33, 34, 35, 27, 30, 29, 27, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 
-    47, 48, 27, 27, 49, 27, 27, 27, 27, 27, 27, 27, 50, 51, 52, 27, 53, 54, 
-    53, 54, 54, 54, 54, 54, 55, 54, 54, 54, 56, 57, 58, 59, 60, 61, 62, 63, 
-    64, 64, 65, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 65, 77, 78, 
-    79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 
-    97, 97, 97, 97, 98, 98, 98, 98, 99, 100, 101, 101, 101, 101, 102, 103, 
-    101, 101, 101, 101, 101, 101, 104, 105, 101, 101, 101, 101, 101, 101, 
-    101, 101, 101, 101, 101, 101, 106, 107, 107, 107, 108, 109, 110, 110, 
-    110, 110, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 120, 
-    120, 121, 122, 119, 123, 124, 125, 126, 127, 127, 127, 127, 128, 129, 
-    130, 131, 132, 133, 134, 127, 127, 127, 127, 127, 127, 127, 127, 127, 
-    127, 127, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 144, 144, 
-    145, 146, 147, 148, 127, 127, 127, 127, 127, 127, 149, 149, 149, 149, 
-    150, 151, 152, 119, 153, 154, 155, 155, 155, 156, 157, 158, 159, 159, 
-    160, 161, 162, 163, 164, 165, 166, 166, 166, 167, 144, 168, 119, 119, 
-    119, 119, 119, 119, 127, 127, 169, 170, 119, 119, 171, 125, 172, 173, 
-    174, 175, 176, 177, 177, 177, 177, 177, 177, 178, 179, 180, 181, 177, 
-    182, 183, 184, 177, 185, 186, 187, 188, 188, 189, 190, 191, 192, 193, 
-    194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 203, 204, 205, 206, 
-    207, 208, 209, 210, 211, 212, 213, 119, 214, 215, 216, 217, 217, 218, 
-    219, 220, 221, 222, 223, 119, 224, 225, 226, 227, 228, 229, 230, 231, 
-    231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 119, 242, 243, 
-    244, 245, 246, 243, 247, 248, 249, 250, 251, 119, 252, 253, 254, 255, 
-    256, 257, 258, 259, 259, 258, 259, 260, 261, 262, 263, 264, 265, 266, 
-    267, 268, 269, 270, 271, 272, 272, 271, 273, 274, 275, 276, 277, 278, 
-    279, 280, 281, 119, 282, 283, 284, 285, 285, 285, 285, 286, 287, 288, 
-    289, 290, 291, 292, 293, 294, 295, 296, 297, 298, 296, 296, 299, 300, 
-    297, 301, 302, 303, 304, 305, 306, 119, 307, 308, 308, 308, 308, 308, 
-    309, 310, 311, 312, 313, 314, 119, 119, 119, 119, 315, 316, 317, 317, 
-    318, 317, 319, 320, 321, 322, 323, 324, 119, 119, 119, 119, 325, 326, 
-    327, 328, 329, 330, 331, 332, 333, 334, 333, 333, 333, 335, 336, 337, 
-    338, 339, 340, 341, 340, 340, 340, 342, 343, 344, 345, 346, 119, 119, 
-    119, 119, 347, 347, 347, 347, 347, 348, 349, 350, 351, 352, 353, 354, 
-    355, 356, 357, 347, 358, 359, 351, 360, 361, 361, 361, 361, 362, 363, 
-    364, 364, 364, 364, 364, 365, 366, 366, 366, 366, 366, 366, 366, 366, 
-    366, 366, 366, 366, 367, 367, 367, 367, 367, 367, 367, 367, 367, 368, 
-    368, 368, 368, 368, 368, 368, 368, 368, 368, 368, 369, 369, 369, 369, 
-    369, 369, 369, 369, 369, 370, 371, 370, 369, 369, 369, 369, 369, 370, 
-    369, 369, 369, 369, 370, 371, 370, 369, 371, 369, 369, 369, 369, 369, 
-    369, 369, 370, 369, 369, 369, 369, 369, 369, 369, 369, 372, 373, 374, 
-    375, 376, 369, 369, 377, 378, 379, 379, 379, 379, 379, 379, 379, 379, 
-    379, 379, 380, 381, 382, 383, 383, 383, 383, 383, 383, 383, 383, 383, 
-    383, 383, 383, 383, 383, 383, 383, 383, 383, 383, 383, 383, 383, 383, 
-    383, 383, 383, 383, 383, 383, 383, 383, 383, 383, 383, 383, 383, 383, 
-    383, 383, 383, 383, 383, 383, 383, 383, 383, 383, 383, 383, 383, 383, 
-    383, 383, 383, 383, 383, 383, 383, 383, 383, 383, 383, 383, 383, 383, 
-    383, 383, 383, 383, 383, 383, 383, 383, 383, 383, 383, 384, 383, 383, 
-    385, 386, 386, 387, 388, 388, 388, 388, 388, 388, 388, 388, 388, 389, 
-    390, 391, 392, 393, 394, 119, 395, 395, 396, 119, 397, 397, 398, 119, 
-    399, 400, 401, 119, 402, 402, 402, 402, 402, 402, 403, 404, 405, 406, 
-    407, 408, 409, 410, 411, 412, 413, 414, 415, 416, 417, 417, 417, 417, 
-    418, 417, 417, 417, 417, 417, 417, 419, 420, 417, 417, 417, 417, 421, 
-    383, 383, 383, 383, 383, 383, 383, 383, 422, 119, 423, 423, 423, 424, 
-    425, 426, 427, 428, 429, 430, 431, 431, 431, 432, 433, 119, 434, 434, 
-    434, 434, 434, 435, 434, 434, 434, 436, 437, 438, 439, 439, 439, 439, 
-    440, 440, 441, 442, 443, 443, 443, 443, 443, 443, 444, 445, 446, 447, 
-    448, 449, 450, 451, 450, 451, 452, 453, 454, 455, 119, 119, 119, 119, 
-    119, 119, 119, 119, 456, 457, 457, 457, 457, 457, 458, 459, 460, 461, 
-    462, 463, 464, 465, 466, 467, 468, 469, 469, 469, 470, 471, 472, 473, 
-    474, 474, 474, 474, 475, 476, 477, 478, 479, 479, 479, 479, 480, 481, 
-    482, 483, 484, 485, 486, 487, 488, 488, 488, 489, 100, 490, 361, 361, 
-    361, 361, 361, 491, 492, 119, 493, 494, 495, 496, 497, 498, 54, 54, 54, 
-    54, 499, 500, 56, 56, 56, 56, 56, 501, 502, 503, 54, 504, 54, 54, 54, 
-    505, 56, 56, 56, 506, 507, 508, 509, 510, 510, 510, 511, 512, 27, 27, 27, 
-    27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 513, 514, 27, 
-    27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 515, 516, 517, 518, 515, 516, 
-    515, 516, 517, 518, 515, 519, 515, 516, 515, 517, 515, 520, 515, 520, 
-    515, 520, 521, 522, 523, 524, 525, 526, 515, 527, 528, 529, 530, 531, 
-    532, 533, 534, 535, 536, 537, 538, 539, 540, 541, 542, 543, 544, 545, 
-    546, 547, 56, 548, 549, 550, 551, 552, 553, 553, 554, 555, 556, 557, 558, 
-    119, 559, 560, 561, 562, 563, 564, 565, 566, 567, 568, 569, 570, 571, 
-    572, 571, 573, 574, 575, 576, 577, 578, 579, 580, 581, 580, 582, 583, 
-    580, 584, 580, 585, 586, 587, 588, 589, 590, 591, 592, 593, 594, 586, 
-    595, 596, 586, 597, 598, 586, 586, 598, 586, 599, 600, 599, 586, 586, 
-    601, 586, 586, 586, 586, 586, 602, 586, 586, 580, 603, 604, 605, 606, 
-    607, 608, 609, 609, 609, 609, 609, 609, 609, 609, 610, 580, 580, 611, 
-    612, 586, 586, 613, 580, 580, 580, 580, 585, 606, 614, 615, 580, 580, 
-    580, 580, 580, 616, 119, 119, 119, 580, 617, 119, 119, 618, 618, 618, 
-    618, 618, 619, 619, 620, 621, 621, 621, 621, 621, 621, 621, 621, 621, 
-    622, 618, 623, 624, 624, 624, 624, 624, 624, 624, 624, 624, 625, 624, 
-    624, 624, 624, 626, 580, 624, 624, 627, 580, 628, 629, 630, 631, 632, 
-    633, 629, 580, 627, 634, 580, 635, 636, 637, 638, 639, 580, 580, 580, 
-    640, 641, 642, 643, 580, 644, 645, 580, 646, 580, 580, 647, 648, 649, 
-    650, 580, 651, 652, 653, 654, 655, 656, 657, 658, 659, 660, 661, 580, 
-    580, 580, 662, 580, 663, 580, 664, 665, 666, 667, 668, 669, 618, 670, 
-    670, 671, 580, 580, 580, 662, 672, 673, 586, 586, 586, 674, 675, 586, 
-    586, 676, 676, 676, 676, 676, 676, 676, 676, 676, 676, 676, 676, 676, 
-    676, 676, 676, 676, 676, 676, 676, 676, 676, 676, 676, 676, 676, 676, 
-    676, 676, 676, 676, 676, 586, 586, 586, 586, 586, 586, 586, 586, 586, 
-    586, 586, 586, 586, 586, 586, 586, 677, 678, 678, 679, 586, 586, 586, 
-    586, 586, 586, 586, 680, 586, 586, 586, 681, 586, 586, 586, 586, 586, 
-    586, 586, 586, 586, 586, 586, 586, 586, 586, 586, 586, 586, 586, 586, 
-    586, 586, 586, 586, 586, 586, 586, 586, 586, 586, 586, 586, 586, 580, 
-    580, 580, 682, 580, 580, 586, 586, 683, 684, 685, 629, 580, 580, 686, 
-    580, 580, 580, 687, 580, 580, 580, 580, 580, 580, 580, 580, 580, 580, 
-    580, 580, 580, 688, 688, 688, 688, 688, 689, 690, 690, 690, 690, 690, 
-    691, 692, 693, 694, 695, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 
-    696, 697, 698, 699, 364, 364, 364, 364, 700, 701, 702, 702, 702, 702, 
-    702, 702, 702, 703, 704, 705, 369, 369, 371, 119, 371, 371, 371, 371, 
-    371, 371, 371, 371, 706, 706, 706, 706, 707, 708, 709, 710, 711, 712, 
-    713, 714, 715, 716, 119, 119, 119, 119, 119, 119, 717, 717, 717, 718, 
-    717, 717, 717, 717, 717, 717, 717, 717, 717, 717, 719, 119, 717, 717, 
-    717, 717, 717, 717, 717, 717, 717, 717, 717, 717, 717, 717, 717, 717, 
-    717, 717, 717, 717, 717, 717, 717, 717, 717, 717, 720, 119, 119, 119, 
-    721, 722, 723, 724, 725, 726, 727, 728, 729, 730, 731, 732, 733, 733, 
-    734, 733, 733, 733, 735, 736, 737, 738, 739, 740, 741, 741, 742, 741, 
-    741, 741, 743, 744, 745, 746, 747, 748, 748, 748, 748, 748, 749, 750, 
-    750, 750, 750, 750, 750, 750, 750, 750, 750, 751, 752, 753, 748, 748, 
-    748, 754, 721, 721, 721, 721, 722, 119, 755, 755, 756, 756, 756, 757, 
-    758, 759, 753, 753, 753, 760, 761, 762, 756, 756, 756, 763, 758, 759, 
-    753, 753, 753, 753, 764, 762, 753, 765, 766, 766, 766, 766, 766, 767, 
-    766, 766, 766, 766, 766, 766, 766, 766, 766, 766, 766, 753, 753, 753, 
-    768, 769, 753, 753, 753, 753, 753, 753, 753, 753, 753, 753, 753, 770, 
-    753, 753, 753, 768, 771, 771, 771, 771, 771, 771, 771, 771, 771, 771, 
-    771, 771, 771, 771, 771, 771, 771, 771, 771, 771, 771, 771, 771, 771, 
-    771, 771, 771, 771, 771, 771, 771, 771, 771, 771, 771, 771, 771, 771, 
-    771, 771, 771, 771, 771, 771, 771, 771, 771, 771, 771, 771, 771, 771, 
-    771, 771, 772, 773, 580, 580, 580, 580, 580, 580, 580, 580, 771, 771, 
-    771, 771, 771, 771, 771, 771, 771, 771, 771, 771, 771, 771, 771, 771, 
-    771, 771, 771, 771, 771, 771, 771, 771, 771, 771, 771, 771, 771, 771, 
-    773, 773, 774, 774, 775, 774, 774, 774, 774, 774, 774, 774, 774, 774, 
-    774, 774, 774, 774, 774, 774, 774, 774, 774, 774, 774, 774, 774, 774, 
-    774, 774, 774, 774, 774, 774, 774, 774, 774, 774, 774, 774, 774, 774, 
-    774, 774, 774, 774, 774, 774, 774, 774, 774, 774, 774, 774, 774, 774, 
-    774, 774, 774, 774, 774, 774, 774, 774, 774, 774, 774, 774, 774, 774, 
-    774, 774, 774, 774, 774, 774, 774, 774, 774, 774, 774, 774, 774, 776, 
-    777, 777, 777, 777, 777, 777, 778, 119, 779, 779, 779, 779, 779, 780, 
-    781, 781, 781, 781, 781, 781, 781, 781, 781, 781, 781, 781, 781, 781, 
-    781, 781, 781, 781, 781, 781, 781, 781, 781, 781, 781, 781, 781, 781, 
-    781, 781, 781, 781, 781, 782, 781, 781, 783, 784, 119, 119, 101, 101, 
-    101, 101, 101, 785, 786, 787, 101, 101, 101, 788, 789, 789, 789, 789, 
-    789, 789, 789, 789, 790, 791, 792, 119, 64, 64, 793, 794, 795, 27, 796, 
-    27, 27, 27, 27, 27, 27, 27, 797, 798, 27, 799, 800, 27, 27, 801, 802, 27, 
-    803, 119, 119, 119, 119, 119, 804, 805, 806, 807, 808, 808, 809, 810, 
-    811, 812, 813, 813, 813, 813, 813, 813, 814, 119, 815, 816, 816, 816, 
-    816, 816, 817, 818, 819, 820, 821, 822, 823, 823, 824, 825, 826, 827, 
-    828, 828, 829, 830, 831, 831, 832, 833, 834, 835, 366, 366, 366, 836, 
-    837, 838, 838, 838, 838, 838, 839, 840, 841, 842, 843, 844, 845, 347, 
-    351, 846, 847, 847, 847, 847, 847, 848, 849, 119, 850, 851, 852, 853, 
-    347, 347, 854, 855, 856, 856, 856, 856, 856, 856, 857, 858, 859, 119, 
-    119, 860, 861, 862, 863, 119, 864, 864, 864, 119, 371, 371, 54, 54, 54, 
-    54, 54, 865, 866, 119, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 
-    861, 861, 861, 861, 868, 869, 870, 871, 872, 873, 873, 874, 873, 873, 
-    873, 872, 873, 873, 874, 873, 873, 873, 872, 873, 873, 874, 873, 873, 
-    873, 872, 873, 873, 874, 873, 873, 873, 872, 873, 873, 874, 873, 873, 
-    873, 872, 873, 873, 874, 873, 873, 873, 872, 873, 873, 874, 873, 873, 
-    873, 872, 873, 873, 874, 873, 873, 873, 872, 873, 873, 874, 873, 873, 
-    873, 872, 873, 873, 874, 873, 873, 873, 872, 873, 873, 874, 873, 873, 
-    873, 872, 873, 873, 874, 873, 873, 873, 872, 873, 873, 874, 873, 873, 
-    873, 872, 873, 873, 874, 873, 873, 873, 872, 873, 873, 874, 873, 873, 
-    873, 872, 873, 873, 874, 873, 873, 873, 872, 873, 873, 874, 873, 873, 
-    873, 872, 873, 873, 874, 873, 873, 873, 872, 873, 873, 874, 873, 873, 
-    873, 872, 873, 873, 874, 873, 873, 873, 872, 873, 873, 874, 873, 873, 
-    873, 872, 873, 873, 874, 873, 873, 873, 872, 873, 873, 874, 873, 873, 
-    873, 872, 873, 873, 874, 873, 873, 873, 872, 873, 873, 874, 873, 873, 
-    873, 872, 873, 873, 874, 873, 873, 873, 872, 873, 873, 874, 873, 873, 
-    873, 872, 873, 873, 874, 873, 873, 873, 872, 873, 873, 874, 873, 873, 
-    873, 872, 873, 873, 874, 873, 873, 873, 872, 873, 873, 874, 873, 873, 
-    873, 872, 873, 873, 874, 873, 873, 873, 873, 873, 873, 872, 873, 873, 
-    874, 873, 873, 873, 872, 873, 873, 874, 873, 873, 873, 872, 873, 873, 
-    875, 119, 367, 367, 876, 877, 368, 368, 368, 368, 368, 878, 879, 879, 
-    879, 879, 879, 879, 879, 879, 879, 879, 879, 879, 879, 879, 879, 879, 
-    879, 879, 879, 879, 879, 879, 879, 879, 879, 879, 879, 879, 879, 879, 
-    879, 879, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 
-    880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 
-    880, 880, 880, 880, 880, 880, 771, 771, 771, 771, 771, 771, 771, 771, 
-    771, 771, 771, 771, 771, 772, 771, 771, 771, 771, 771, 771, 771, 771, 
-    771, 771, 771, 771, 771, 881, 773, 773, 773, 773, 882, 119, 883, 884, 
-    120, 885, 886, 887, 888, 120, 127, 127, 127, 127, 127, 127, 127, 127, 
-    127, 127, 127, 127, 889, 890, 891, 119, 892, 127, 127, 127, 127, 127, 
-    127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 
-    127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 
-    127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 893, 119, 119, 
-    127, 127, 127, 127, 127, 127, 127, 127, 894, 127, 127, 127, 127, 127, 
-    127, 119, 119, 119, 119, 119, 127, 895, 896, 896, 897, 898, 899, 900, 
-    901, 902, 903, 904, 905, 906, 907, 908, 169, 127, 127, 127, 127, 127, 
-    127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 909, 910, 911, 
-    912, 913, 914, 915, 915, 916, 917, 918, 918, 919, 920, 921, 922, 923, 
-    923, 923, 923, 924, 925, 925, 925, 926, 927, 927, 927, 928, 929, 930, 
-    119, 931, 932, 933, 932, 932, 934, 932, 932, 935, 932, 936, 932, 936, 
-    119, 119, 119, 119, 932, 932, 932, 932, 932, 932, 932, 932, 932, 932, 
-    932, 932, 932, 932, 932, 937, 938, 939, 939, 939, 939, 939, 940, 609, 
-    941, 941, 941, 941, 941, 941, 942, 943, 944, 945, 580, 946, 947, 119, 
-    119, 119, 119, 119, 609, 609, 609, 609, 609, 948, 119, 119, 119, 119, 
-    119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 949, 949, 
-    949, 950, 951, 951, 951, 951, 951, 951, 952, 119, 953, 954, 954, 955, 
-    956, 956, 956, 956, 957, 958, 959, 959, 960, 961, 962, 962, 962, 962, 
-    963, 964, 965, 965, 965, 966, 967, 967, 967, 967, 968, 967, 969, 119, 
-    119, 119, 119, 119, 970, 970, 970, 970, 970, 971, 971, 971, 971, 971, 
-    972, 972, 972, 972, 972, 972, 973, 973, 973, 974, 975, 976, 977, 977, 
-    977, 977, 978, 979, 979, 979, 979, 980, 981, 981, 981, 981, 981, 119, 
-    982, 982, 982, 982, 982, 982, 983, 984, 119, 119, 119, 119, 119, 119, 
-    119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 985, 985, 
-    985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 
-    985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 
-    985, 985, 985, 985, 985, 985, 985, 985, 986, 119, 985, 985, 987, 119, 
-    985, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 
-    119, 119, 119, 119, 119, 119, 988, 989, 990, 990, 990, 990, 991, 992, 
-    993, 993, 994, 995, 996, 996, 997, 998, 999, 999, 999, 1000, 1001, 1002, 
-    119, 119, 119, 119, 119, 119, 1003, 1003, 1004, 1005, 1006, 1006, 1007, 
-    1008, 1009, 1009, 1009, 1010, 119, 119, 119, 119, 119, 119, 119, 119, 
-    1011, 1011, 1011, 1011, 1012, 1012, 1012, 1013, 1014, 1014, 1015, 1014, 
-    1014, 1014, 1014, 1014, 1016, 1017, 1018, 1019, 1020, 1020, 1021, 1022, 
-    1023, 1024, 1025, 1026, 1027, 1027, 1027, 1028, 1029, 1029, 1029, 1030, 
-    119, 119, 119, 119, 1031, 1032, 1031, 1031, 1033, 1034, 1035, 119, 1036, 
-    1036, 1036, 1036, 1036, 1036, 1037, 1038, 1039, 1039, 1040, 1041, 1042, 
-    1042, 1043, 1044, 1045, 1045, 1046, 1047, 119, 1048, 119, 119, 119, 119, 
-    119, 119, 119, 119, 119, 119, 1049, 1049, 1049, 1049, 1049, 1049, 1049, 
-    1049, 1049, 1050, 119, 119, 119, 119, 119, 119, 1051, 1051, 1051, 1051, 
-    1051, 1051, 1052, 119, 1053, 1053, 1053, 1053, 1053, 1053, 1054, 1055, 
-    1056, 1056, 1056, 1056, 1057, 119, 1058, 1059, 119, 119, 119, 119, 119, 
-    119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 
-    119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 
-    119, 119, 119, 1060, 1060, 1060, 1061, 119, 119, 119, 119, 119, 119, 119, 
-    119, 119, 119, 119, 119, 119, 119, 119, 119, 1062, 1062, 1062, 1063, 
-    1064, 119, 1065, 1065, 1066, 1067, 1068, 1069, 119, 119, 119, 119, 119, 
-    119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 1070, 1070, 1071, 
-    119, 1072, 1073, 1073, 1073, 1073, 1073, 1073, 1074, 1075, 1076, 1077, 
-    1078, 1079, 1080, 119, 1081, 1082, 1083, 1083, 1083, 1083, 1083, 1084, 
-    1085, 1086, 1087, 1088, 1088, 1088, 1089, 1090, 1091, 1092, 1093, 1093, 
-    1093, 1094, 1095, 1096, 1097, 1098, 119, 1099, 1099, 1099, 1099, 1100, 
-    119, 1101, 1102, 1102, 1102, 1102, 1102, 1103, 1104, 1105, 1106, 1107, 
-    1108, 1109, 1110, 1111, 119, 1112, 1112, 1113, 1112, 1112, 1114, 1115, 
-    1116, 119, 119, 119, 119, 119, 119, 119, 119, 1117, 1118, 1119, 1120, 
-    1119, 1121, 1122, 1122, 1122, 1122, 1122, 1123, 1124, 1125, 1126, 1127, 
-    1128, 1129, 1130, 1131, 1131, 1132, 1133, 1134, 1135, 1136, 1137, 1138, 
-    1139, 1140, 1140, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 
-    119, 119, 119, 119, 119, 119, 1141, 1141, 1141, 1141, 1141, 1141, 1142, 
-    1143, 1144, 1145, 1146, 1147, 119, 119, 119, 119, 1148, 1148, 1148, 1148, 
-    1148, 1148, 1149, 1150, 1151, 119, 1152, 1153, 119, 119, 119, 119, 119, 
-    119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 
-    119, 1154, 1154, 1154, 1154, 1154, 1155, 1156, 1157, 1158, 1159, 1160, 
-    1161, 119, 119, 119, 119, 1162, 1162, 1162, 1162, 1162, 1162, 1163, 1164, 
-    1165, 119, 1166, 1167, 1168, 1169, 119, 119, 1170, 1170, 1170, 1170, 
-    1170, 1171, 1172, 1173, 1174, 1175, 119, 119, 119, 119, 119, 119, 1176, 
-    1176, 1176, 1177, 1178, 1179, 1180, 1181, 119, 119, 119, 119, 119, 119, 
-    119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 
-    119, 119, 119, 119, 1182, 1182, 1182, 1182, 1182, 1183, 1184, 1185, 119, 
-    119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 1186, 1186, 1186, 
-    1186, 1187, 1187, 1187, 1187, 1188, 1189, 1190, 1191, 119, 119, 119, 119, 
-    119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 
-    119, 119, 1192, 1193, 1192, 1192, 1192, 1192, 1194, 1195, 1196, 119, 119, 
-    119, 1197, 1198, 1199, 1199, 1199, 1199, 1200, 1201, 1202, 119, 1203, 
-    1204, 1205, 1205, 1205, 1205, 1205, 1206, 1207, 1208, 1209, 119, 119, 
-    119, 1210, 1210, 1210, 1210, 1210, 1210, 1210, 1211, 119, 119, 119, 119, 
-    119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 
-    119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 
-    1212, 1213, 1212, 1212, 1212, 1214, 1215, 1216, 1217, 119, 1218, 1219, 
-    1220, 1221, 1222, 1223, 1223, 1223, 1224, 1225, 1225, 1226, 1227, 119, 
-    119, 119, 119, 119, 119, 119, 119, 119, 1228, 1229, 1230, 1230, 1230, 
-    1230, 1231, 1232, 1233, 119, 1234, 1235, 1236, 1237, 1238, 1238, 1238, 
-    1239, 1240, 1241, 1242, 1243, 119, 119, 119, 119, 119, 119, 119, 119, 
-    119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 
-    119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 
-    119, 119, 1244, 1244, 1245, 1246, 119, 119, 119, 119, 119, 119, 119, 119, 
-    119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 
-    119, 119, 1247, 1247, 1248, 1249, 1250, 1251, 1252, 1253, 1254, 1254, 
-    1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 
-    1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 
-    1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 
-    1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 
-    1254, 1255, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 
-    1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 
-    1256, 1257, 1258, 119, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 
-    1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 
-    1254, 1254, 1254, 1254, 1259, 119, 119, 119, 119, 119, 119, 119, 119, 
-    119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 
-    119, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 
-    1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 
-    1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 
-    1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1261, 1260, 1260, 1260, 
-    1260, 1262, 1263, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 
-    1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 
-    1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1264, 1260, 1260, 1260, 
-    1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 1260, 
-    1260, 1260, 1260, 1260, 1260, 1260, 1265, 1266, 1267, 119, 119, 119, 119, 
-    119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 
-    119, 119, 119, 119, 119, 119, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 
-    1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 
-    1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 
-    1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 
-    1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 
-    1268, 1268, 1269, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 
-    1268, 1268, 1268, 1268, 1268, 1270, 119, 119, 119, 119, 119, 119, 119, 
-    119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 
-    119, 119, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 
-    789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 
-    789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, 1271, 
-    1272, 1272, 1272, 1273, 1274, 1275, 119, 119, 119, 119, 119, 119, 119, 
-    119, 119, 119, 119, 119, 1276, 1276, 1276, 1277, 1278, 119, 1279, 1279, 
-    1279, 1279, 1279, 1279, 1280, 1281, 1282, 119, 1283, 1284, 1285, 1279, 
-    1279, 1286, 1279, 1279, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 
-    119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 1287, 1287, 
-    1287, 1287, 1288, 1288, 1288, 1288, 1289, 1289, 1290, 1291, 119, 119, 
-    119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 1292, 1292, 1292, 1292, 
-    1292, 1292, 1292, 1292, 1292, 1293, 1294, 1295, 1295, 1295, 1295, 1295, 
-    1295, 1296, 1297, 1298, 119, 119, 119, 119, 119, 119, 119, 119, 1299, 
-    119, 119, 119, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 
-    1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 
-    1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 
-    1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 
-    1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 
-    1300, 1300, 1300, 1300, 1300, 1300, 119, 1300, 1300, 1300, 1300, 1300, 
-    1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 
-    1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 
-    1300, 1301, 119, 1302, 733, 733, 733, 733, 733, 733, 733, 733, 733, 733, 
-    733, 733, 733, 733, 733, 733, 733, 733, 733, 733, 733, 733, 733, 733, 
-    733, 733, 733, 733, 733, 733, 733, 733, 733, 733, 1303, 119, 119, 119, 
-    119, 119, 119, 1304, 119, 1305, 119, 1306, 1306, 1306, 1306, 1306, 1306, 
-    1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 
-    1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 
-    1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 
-    1306, 1306, 1306, 1306, 1306, 1306, 1306, 1307, 1308, 1308, 1308, 1308, 
-    1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1308, 1309, 1308, 1310, 
-    1308, 1311, 1308, 1312, 1313, 119, 119, 119, 119, 119, 119, 119, 119, 
-    119, 119, 119, 609, 609, 609, 609, 609, 609, 609, 609, 609, 609, 609, 
-    609, 609, 609, 609, 609, 609, 609, 609, 609, 609, 609, 609, 609, 609, 
-    609, 609, 609, 609, 609, 1314, 119, 609, 609, 609, 609, 1315, 1316, 609, 
-    609, 609, 609, 609, 609, 1317, 1318, 1319, 1320, 1321, 1322, 609, 609, 
-    609, 1323, 609, 609, 609, 609, 609, 609, 609, 1324, 119, 119, 944, 944, 
-    944, 944, 944, 944, 944, 944, 1325, 119, 119, 119, 119, 119, 119, 119, 
-    119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 939, 939, 
-    1326, 119, 580, 580, 580, 580, 580, 580, 580, 580, 580, 580, 616, 119, 
-    939, 939, 939, 1327, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 
-    119, 119, 119, 119, 119, 119, 1328, 1328, 1328, 1329, 1330, 1330, 1331, 
-    1328, 1328, 1332, 1333, 1330, 1330, 1328, 1328, 1328, 1329, 1330, 1330, 
-    1334, 1335, 1336, 1332, 1337, 1338, 1330, 1328, 1328, 1328, 1329, 1330, 
-    1330, 1339, 1340, 1341, 1342, 1330, 1330, 1330, 1343, 1344, 1345, 1346, 
-    1330, 1330, 1331, 1328, 1328, 1332, 1330, 1330, 1330, 1328, 1328, 1328, 
-    1329, 1330, 1330, 1331, 1328, 1328, 1332, 1330, 1330, 1330, 1328, 1328, 
-    1328, 1329, 1330, 1330, 1331, 1328, 1328, 1332, 1330, 1330, 1330, 1328, 
-    1328, 1328, 1329, 1330, 1330, 1347, 1328, 1328, 1328, 1348, 1330, 1330, 
-    1349, 1350, 1328, 1328, 1351, 1330, 1330, 1352, 1331, 1328, 1328, 1353, 
-    1330, 1330, 1354, 1355, 1328, 1328, 1356, 1330, 1330, 1330, 1357, 1328, 
-    1328, 1328, 1348, 1330, 1330, 1349, 1358, 1359, 1359, 1359, 1359, 1359, 
-    1359, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 
-    1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 
-    1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1360, 1361, 1361, 1361, 
-    1361, 1361, 1361, 1362, 1363, 1361, 1361, 1361, 1361, 1361, 1364, 1365, 
-    1360, 1366, 1367, 119, 1368, 1369, 1361, 119, 119, 119, 119, 119, 119, 
-    119, 119, 119, 119, 1370, 1371, 1371, 1372, 1373, 1374, 119, 119, 119, 
-    119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 
-    119, 119, 119, 119, 119, 119, 119, 119, 119, 1375, 1375, 1375, 1375, 
-    1375, 1376, 1377, 1378, 1379, 1380, 119, 119, 119, 119, 119, 119, 119, 
-    119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 
-    119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 
-    119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 1381, 1381, 1381, 
-    1381, 1381, 1382, 1383, 1384, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 
-    1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 1385, 
-    1385, 1385, 1385, 1385, 1385, 1386, 1387, 1388, 119, 119, 119, 119, 119, 
-    1389, 1389, 1389, 1389, 1390, 1391, 1391, 1391, 1392, 1393, 1394, 1395, 
-    119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 
-    119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 
-    119, 119, 119, 119, 119, 119, 1396, 1397, 1397, 1397, 1397, 1397, 1397, 
-    1398, 1399, 119, 119, 119, 119, 119, 119, 119, 119, 119, 1396, 1397, 
-    1397, 1397, 1397, 1400, 1397, 1401, 119, 119, 119, 119, 119, 119, 119, 
-    119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 
-    119, 119, 119, 1402, 127, 127, 127, 1403, 1404, 1405, 1406, 1407, 1408, 
-    1403, 1409, 1403, 1405, 1405, 1410, 127, 1411, 127, 1412, 1413, 1411, 
-    127, 1412, 119, 119, 119, 119, 119, 119, 1414, 119, 1415, 1416, 1416, 
-    1416, 1416, 1417, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 1416, 
-    1416, 1416, 1416, 1417, 1418, 1416, 1419, 1420, 1416, 1420, 1421, 1420, 
-    1416, 1416, 1416, 1422, 1418, 619, 1423, 621, 621, 621, 1424, 621, 621, 
-    621, 621, 621, 621, 621, 1425, 621, 621, 621, 1426, 1427, 1428, 621, 
-    1429, 1418, 1418, 1418, 1418, 1418, 1418, 1430, 1431, 1431, 1431, 1432, 
-    1418, 753, 753, 753, 753, 753, 1433, 753, 1434, 1435, 1418, 1436, 1418, 
-    1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 
-    1418, 1418, 1418, 1418, 1418, 1418, 721, 721, 721, 721, 1437, 1438, 1439, 
-    721, 721, 721, 721, 721, 721, 721, 721, 1440, 1441, 721, 1442, 1443, 721, 
-    721, 1444, 1445, 1446, 1447, 1442, 1416, 721, 721, 1448, 1449, 721, 721, 
-    721, 721, 721, 721, 721, 1450, 1451, 1452, 1453, 721, 1454, 1452, 1452, 
-    1455, 1456, 1457, 1458, 721, 1459, 1460, 1461, 721, 721, 721, 721, 721, 
-    721, 721, 721, 1462, 1463, 721, 1464, 642, 1465, 721, 1466, 1467, 580, 
-    1468, 721, 721, 721, 1416, 1469, 1470, 1416, 1416, 1471, 1416, 1415, 
-    1416, 1416, 1416, 1416, 1416, 1472, 1473, 1416, 1416, 1472, 1474, 721, 
-    721, 721, 721, 721, 721, 721, 721, 1475, 1476, 580, 580, 580, 580, 1477, 
-    1478, 721, 721, 721, 721, 1479, 721, 1480, 721, 1481, 1482, 1483, 1418, 
-    1416, 1484, 1485, 1486, 580, 580, 580, 580, 580, 580, 580, 580, 580, 580, 
-    580, 580, 580, 580, 1487, 1418, 580, 580, 580, 580, 580, 580, 580, 580, 
-    580, 580, 1488, 1489, 721, 1490, 1418, 1418, 580, 1487, 580, 580, 580, 
-    580, 580, 580, 580, 1418, 580, 1491, 580, 580, 580, 580, 580, 1418, 580, 
-    580, 580, 1492, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 
-    1418, 580, 1493, 721, 1452, 1494, 721, 1452, 1495, 721, 721, 721, 721, 
-    721, 721, 1496, 1497, 721, 721, 721, 721, 1498, 1499, 1500, 1501, 721, 
-    1502, 1503, 1504, 721, 721, 721, 721, 580, 580, 580, 580, 580, 580, 580, 
-    580, 580, 580, 1487, 1418, 1416, 1422, 1490, 1486, 1486, 1418, 1436, 
-    1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 
-    1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 
-    1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 
-    1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 
-    1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 
-    1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 
-    1418, 1418, 1418, 1418, 1505, 771, 771, 771, 771, 771, 771, 771, 771, 
-    771, 771, 771, 771, 771, 771, 771, 771, 771, 771, 771, 771, 771, 771, 
-    771, 771, 771, 771, 1506, 773, 773, 773, 773, 773, 771, 771, 771, 771, 
-    771, 771, 1507, 773, 771, 771, 771, 771, 771, 771, 771, 771, 771, 771, 
-    771, 771, 771, 771, 771, 771, 771, 771, 771, 771, 771, 771, 771, 771, 
-    771, 771, 771, 772, 771, 771, 771, 771, 771, 771, 771, 771, 771, 771, 
-    771, 771, 771, 771, 771, 771, 771, 771, 771, 771, 771, 771, 771, 771, 
-    771, 771, 771, 771, 771, 771, 771, 771, 771, 771, 771, 771, 771, 771, 
-    771, 771, 771, 771, 771, 771, 771, 771, 771, 771, 881, 773, 771, 771, 
-    771, 771, 771, 771, 771, 771, 771, 771, 771, 771, 771, 771, 771, 771, 
-    771, 771, 771, 771, 771, 771, 771, 771, 771, 771, 771, 771, 771, 771, 
-    771, 771, 771, 771, 771, 771, 771, 771, 1508, 773, 773, 773, 773, 773, 
-    773, 773, 773, 773, 773, 773, 773, 773, 773, 773, 773, 773, 773, 773, 
-    773, 773, 773, 773, 773, 773, 773, 773, 773, 773, 773, 773, 773, 773, 
-    773, 773, 771, 771, 771, 772, 773, 773, 773, 773, 773, 773, 773, 773, 
-    773, 773, 773, 773, 773, 773, 773, 773, 773, 773, 773, 773, 773, 773, 
-    773, 773, 773, 773, 773, 773, 773, 773, 773, 773, 773, 773, 773, 773, 
-    773, 773, 773, 773, 773, 773, 773, 773, 773, 773, 773, 773, 773, 773, 
-    773, 773, 773, 773, 773, 773, 773, 773, 773, 1509, 1510, 119, 119, 119, 
-    1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 1511, 
-    119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 
-    119, 119, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 
-    896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, 
-    896, 896, 896, 896, 119, 119, 880, 880, 880, 880, 880, 880, 880, 880, 
-    880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 880, 
-    880, 880, 880, 880, 880, 880, 880, 880, 880, 1512, 
-};
-
-static const unsigned short index2[] = {
-    1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 3, 4, 5, 6, 1, 1, 1, 1, 1, 1, 7, 7, 7, 8, 
-    9, 10, 11, 12, 13, 14, 15, 11, 16, 17, 15, 18, 19, 20, 19, 21, 22, 22, 
-    22, 22, 22, 22, 22, 22, 22, 22, 19, 23, 24, 24, 24, 10, 15, 25, 25, 25, 
-    25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 16, 26, 17, 
-    27, 28, 27, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 
-    29, 29, 29, 16, 30, 31, 24, 1, 1, 1, 1, 1, 1, 32, 1, 1, 33, 34, 35, 13, 
-    36, 13, 37, 38, 39, 40, 41, 42, 24, 43, 44, 27, 45, 46, 47, 47, 48, 49, 
-    38, 38, 39, 47, 41, 50, 51, 51, 51, 34, 52, 52, 52, 52, 52, 52, 53, 52, 
-    52, 52, 52, 52, 52, 52, 52, 52, 53, 52, 52, 52, 52, 52, 52, 54, 53, 52, 
-    52, 52, 52, 52, 53, 55, 55, 55, 56, 56, 56, 56, 55, 56, 55, 55, 55, 56, 
-    55, 55, 56, 56, 55, 56, 55, 55, 56, 56, 56, 54, 55, 55, 55, 56, 55, 56, 
-    55, 56, 52, 55, 52, 56, 52, 56, 52, 56, 52, 56, 52, 56, 52, 56, 52, 56, 
-    52, 55, 52, 55, 52, 56, 52, 56, 52, 56, 52, 55, 52, 56, 52, 56, 52, 56, 
-    52, 56, 52, 56, 53, 55, 52, 55, 53, 55, 52, 56, 52, 56, 55, 52, 56, 52, 
-    56, 52, 56, 53, 55, 53, 55, 52, 55, 52, 56, 52, 55, 55, 53, 55, 52, 55, 
-    52, 56, 52, 56, 53, 55, 52, 56, 52, 56, 52, 52, 56, 52, 56, 52, 56, 56, 
-    56, 52, 52, 56, 52, 56, 52, 52, 56, 52, 52, 52, 56, 56, 52, 52, 52, 52, 
-    56, 52, 52, 56, 52, 52, 52, 56, 56, 56, 52, 52, 56, 52, 52, 56, 52, 56, 
-    52, 56, 52, 52, 56, 52, 56, 56, 52, 56, 52, 52, 56, 52, 52, 52, 56, 52, 
-    56, 52, 52, 56, 56, 57, 52, 56, 56, 56, 57, 57, 57, 57, 52, 58, 56, 52, 
-    58, 56, 52, 58, 56, 52, 55, 52, 55, 52, 55, 52, 55, 52, 55, 52, 55, 52, 
-    55, 52, 55, 56, 52, 56, 56, 52, 58, 56, 52, 56, 52, 52, 52, 56, 52, 56, 
-    56, 56, 56, 56, 56, 56, 52, 52, 56, 52, 52, 56, 56, 52, 56, 52, 52, 52, 
-    52, 56, 56, 55, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 
-    56, 56, 56, 56, 57, 56, 56, 56, 59, 59, 59, 59, 59, 59, 59, 59, 59, 60, 
-    60, 61, 61, 61, 61, 61, 61, 61, 62, 62, 63, 62, 60, 64, 65, 64, 64, 64, 
-    65, 64, 60, 60, 66, 61, 62, 62, 62, 62, 62, 62, 39, 39, 39, 39, 62, 39, 
-    62, 48, 59, 59, 59, 59, 59, 62, 62, 62, 62, 62, 67, 67, 60, 62, 61, 62, 
-    62, 62, 62, 62, 62, 62, 62, 62, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 
-    68, 68, 68, 69, 70, 70, 70, 70, 69, 71, 70, 70, 70, 70, 70, 72, 72, 70, 
-    70, 70, 70, 72, 72, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 73, 73, 
-    73, 73, 73, 70, 70, 70, 70, 68, 68, 68, 68, 68, 68, 68, 68, 74, 68, 70, 
-    70, 70, 68, 68, 68, 70, 70, 75, 68, 68, 68, 70, 70, 70, 70, 68, 69, 70, 
-    70, 68, 76, 77, 77, 76, 77, 77, 76, 68, 68, 68, 68, 68, 78, 79, 78, 79, 
-    60, 80, 78, 79, 81, 81, 82, 79, 79, 79, 83, 78, 81, 81, 81, 81, 80, 62, 
-    78, 84, 78, 78, 78, 81, 78, 81, 78, 78, 79, 85, 85, 85, 85, 85, 85, 85, 
-    85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 81, 85, 85, 85, 85, 85, 85, 85, 
-    78, 78, 79, 79, 79, 79, 79, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 
-    86, 86, 86, 86, 86, 86, 79, 86, 86, 86, 86, 86, 86, 86, 79, 79, 79, 79, 
-    79, 78, 79, 79, 78, 78, 78, 79, 79, 79, 78, 79, 78, 79, 78, 79, 78, 79, 
-    78, 79, 87, 88, 87, 88, 87, 88, 87, 88, 87, 88, 87, 88, 87, 88, 79, 79, 
-    79, 79, 78, 79, 89, 78, 79, 78, 78, 79, 79, 78, 78, 78, 90, 91, 90, 90, 
-    90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 91, 91, 91, 91, 91, 91, 
-    91, 91, 92, 92, 92, 92, 92, 92, 92, 92, 93, 92, 93, 93, 93, 93, 93, 93, 
-    93, 93, 93, 93, 93, 93, 93, 93, 90, 93, 90, 93, 90, 93, 90, 93, 90, 93, 
-    94, 95, 95, 96, 96, 95, 97, 97, 90, 93, 90, 93, 90, 93, 90, 90, 93, 90, 
-    93, 90, 93, 90, 93, 90, 93, 90, 93, 90, 93, 93, 81, 98, 98, 98, 98, 98, 
-    98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 81, 
-    81, 99, 100, 100, 100, 100, 100, 100, 101, 101, 101, 101, 101, 101, 101, 
-    101, 101, 102, 103, 81, 81, 104, 104, 105, 81, 106, 107, 107, 107, 107, 
-    106, 107, 107, 107, 108, 106, 107, 107, 107, 107, 107, 107, 106, 106, 
-    106, 106, 106, 106, 107, 107, 106, 107, 107, 108, 109, 107, 110, 111, 
-    112, 113, 114, 115, 116, 117, 118, 119, 119, 120, 121, 122, 123, 124, 
-    125, 126, 127, 125, 107, 106, 128, 118, 81, 81, 81, 81, 81, 81, 81, 81, 
-    129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 81, 81, 81, 81, 
-    129, 129, 129, 129, 125, 125, 81, 81, 81, 130, 130, 130, 130, 130, 131, 
-    132, 132, 133, 134, 134, 135, 136, 137, 138, 138, 139, 139, 139, 139, 
-    139, 139, 139, 139, 140, 141, 142, 143, 144, 81, 145, 143, 146, 146, 146, 
-    146, 146, 146, 146, 146, 147, 146, 146, 146, 146, 146, 146, 146, 146, 
-    146, 146, 148, 149, 150, 151, 152, 153, 154, 155, 96, 96, 156, 157, 139, 
-    139, 139, 139, 139, 157, 139, 139, 157, 158, 158, 158, 158, 158, 158, 
-    158, 158, 158, 158, 134, 159, 159, 160, 146, 146, 161, 146, 146, 146, 
-    146, 146, 146, 146, 146, 146, 146, 146, 145, 146, 139, 139, 139, 139, 
-    139, 139, 139, 131, 138, 139, 139, 139, 139, 157, 139, 162, 162, 139, 
-    139, 138, 157, 139, 139, 157, 146, 146, 163, 163, 163, 163, 163, 163, 
-    163, 163, 163, 163, 146, 146, 146, 164, 164, 146, 165, 165, 165, 165, 
-    165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 81, 166, 167, 168, 167, 
-    167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 169, 
-    170, 169, 169, 170, 169, 169, 170, 170, 170, 169, 170, 170, 169, 170, 
-    169, 169, 169, 170, 169, 170, 169, 170, 169, 170, 169, 169, 81, 81, 167, 
-    167, 167, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 
-    171, 171, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 171, 81, 
-    81, 81, 81, 81, 81, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 
-    174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 
-    174, 174, 174, 175, 175, 175, 175, 175, 175, 175, 176, 175, 177, 177, 
-    178, 179, 180, 181, 177, 81, 81, 176, 182, 182, 183, 183, 183, 183, 183, 
-    183, 183, 183, 183, 183, 183, 183, 183, 183, 184, 184, 184, 184, 185, 
-    184, 184, 184, 184, 184, 184, 184, 184, 184, 185, 184, 184, 184, 185, 
-    184, 184, 184, 184, 184, 81, 81, 186, 186, 186, 186, 186, 186, 186, 186, 
-    186, 186, 186, 186, 186, 186, 186, 81, 187, 187, 187, 187, 187, 187, 187, 
-    187, 187, 188, 188, 188, 81, 81, 189, 81, 167, 167, 167, 81, 81, 81, 81, 
-    81, 146, 146, 146, 146, 146, 81, 146, 146, 146, 146, 146, 146, 146, 146, 
-    81, 81, 81, 81, 81, 157, 139, 139, 139, 139, 139, 139, 131, 157, 139, 
-    139, 157, 139, 139, 157, 139, 139, 139, 157, 157, 157, 190, 191, 192, 
-    139, 139, 139, 157, 139, 139, 157, 157, 139, 139, 139, 139, 139, 193, 
-    193, 193, 194, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 
-    195, 195, 195, 193, 194, 196, 195, 194, 194, 194, 193, 193, 193, 193, 
-    193, 193, 193, 193, 194, 194, 194, 194, 197, 194, 194, 195, 96, 156, 96, 
-    96, 193, 193, 193, 195, 195, 193, 193, 198, 198, 199, 199, 199, 199, 199, 
-    199, 199, 199, 199, 199, 200, 201, 195, 195, 195, 195, 195, 195, 202, 
-    203, 204, 204, 81, 202, 202, 202, 202, 202, 202, 202, 202, 81, 81, 202, 
-    202, 81, 81, 202, 202, 202, 202, 202, 202, 202, 202, 202, 202, 202, 202, 
-    202, 202, 81, 202, 202, 202, 202, 202, 202, 202, 81, 202, 81, 81, 81, 
-    202, 202, 202, 202, 81, 81, 205, 202, 204, 204, 204, 203, 203, 203, 203, 
-    81, 81, 204, 204, 81, 81, 204, 204, 206, 202, 81, 81, 81, 81, 81, 81, 81, 
-    81, 204, 81, 81, 81, 81, 202, 202, 81, 202, 202, 202, 203, 203, 81, 81, 
-    207, 207, 207, 207, 207, 207, 207, 207, 207, 207, 202, 202, 208, 208, 
-    209, 209, 209, 209, 209, 210, 211, 212, 202, 213, 214, 81, 81, 215, 215, 
-    216, 81, 217, 217, 217, 217, 217, 217, 81, 81, 81, 81, 217, 217, 81, 81, 
-    217, 217, 217, 217, 217, 217, 217, 217, 217, 217, 217, 217, 217, 217, 81, 
-    217, 217, 217, 217, 217, 217, 217, 81, 217, 217, 81, 217, 217, 81, 217, 
-    217, 81, 81, 218, 81, 216, 216, 216, 215, 215, 81, 81, 81, 81, 215, 215, 
-    81, 81, 215, 215, 219, 81, 81, 81, 215, 81, 81, 81, 81, 81, 81, 81, 217, 
-    217, 217, 217, 81, 217, 81, 81, 81, 81, 81, 81, 81, 220, 220, 220, 220, 
-    220, 220, 220, 220, 220, 220, 215, 215, 217, 217, 217, 215, 221, 81, 81, 
-    222, 222, 223, 81, 224, 224, 224, 224, 224, 224, 224, 224, 224, 81, 224, 
-    224, 224, 81, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 
-    224, 224, 81, 224, 224, 224, 224, 224, 224, 224, 81, 224, 224, 81, 224, 
-    224, 224, 224, 224, 81, 81, 225, 224, 223, 223, 223, 222, 222, 222, 222, 
-    222, 81, 222, 222, 223, 81, 223, 223, 226, 81, 81, 224, 81, 81, 81, 81, 
-    81, 81, 81, 224, 224, 222, 222, 81, 81, 227, 227, 227, 227, 227, 227, 
-    227, 227, 227, 227, 228, 229, 81, 81, 81, 81, 81, 81, 81, 224, 222, 222, 
-    222, 222, 222, 222, 81, 230, 231, 231, 81, 232, 232, 232, 232, 232, 232, 
-    232, 232, 81, 81, 232, 232, 81, 81, 232, 232, 232, 232, 232, 232, 232, 
-    232, 232, 232, 232, 232, 232, 232, 81, 232, 232, 232, 232, 232, 232, 232, 
-    81, 232, 232, 81, 232, 232, 232, 232, 232, 81, 81, 233, 232, 231, 230, 
-    231, 230, 230, 230, 230, 81, 81, 231, 231, 81, 81, 231, 231, 234, 81, 81, 
-    81, 81, 81, 81, 81, 81, 230, 231, 81, 81, 81, 81, 232, 232, 81, 232, 232, 
-    232, 230, 230, 81, 81, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 
-    236, 232, 237, 237, 237, 237, 237, 237, 81, 81, 238, 239, 81, 239, 239, 
-    239, 239, 239, 239, 81, 81, 81, 239, 239, 239, 81, 239, 239, 239, 239, 
-    81, 81, 81, 239, 239, 81, 239, 81, 239, 239, 81, 81, 81, 239, 239, 81, 
-    81, 81, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 81, 81, 81, 81, 
-    240, 240, 238, 240, 240, 81, 81, 81, 240, 240, 240, 81, 240, 240, 240, 
-    241, 81, 81, 239, 81, 81, 81, 81, 81, 81, 240, 81, 81, 81, 81, 81, 81, 
-    242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 243, 243, 243, 244, 
-    244, 244, 244, 244, 244, 245, 244, 81, 81, 81, 81, 81, 246, 247, 247, 
-    247, 246, 248, 248, 248, 248, 248, 248, 248, 248, 81, 248, 248, 248, 81, 
-    248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 
-    248, 248, 81, 81, 81, 248, 246, 246, 246, 247, 247, 247, 247, 81, 246, 
-    246, 246, 81, 246, 246, 246, 249, 81, 81, 81, 81, 81, 81, 81, 250, 251, 
-    81, 248, 248, 248, 81, 81, 81, 81, 81, 248, 248, 246, 246, 81, 81, 252, 
-    252, 252, 252, 252, 252, 252, 252, 252, 252, 81, 81, 81, 81, 81, 81, 81, 
-    253, 254, 254, 254, 254, 254, 254, 254, 255, 256, 257, 258, 258, 259, 
-    256, 256, 256, 256, 256, 256, 256, 256, 81, 256, 256, 256, 81, 256, 256, 
-    256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 
-    256, 256, 81, 256, 256, 256, 256, 256, 81, 81, 260, 256, 258, 261, 258, 
-    258, 258, 258, 258, 81, 261, 258, 258, 81, 258, 258, 257, 262, 81, 81, 
-    81, 81, 81, 81, 81, 258, 258, 81, 81, 81, 81, 81, 81, 81, 256, 81, 256, 
-    256, 257, 257, 81, 81, 263, 263, 263, 263, 263, 263, 263, 263, 263, 263, 
-    81, 256, 256, 81, 81, 81, 81, 81, 264, 264, 265, 265, 81, 266, 266, 266, 
-    266, 266, 266, 266, 266, 81, 266, 266, 266, 81, 266, 266, 266, 266, 266, 
-    266, 266, 266, 266, 266, 266, 266, 266, 266, 266, 266, 266, 267, 267, 
-    266, 265, 265, 265, 264, 264, 264, 264, 81, 265, 265, 265, 81, 265, 265, 
-    265, 267, 266, 268, 81, 81, 81, 81, 266, 266, 266, 265, 269, 269, 269, 
-    269, 269, 269, 269, 266, 266, 266, 264, 264, 81, 81, 270, 270, 270, 270, 
-    270, 270, 270, 270, 270, 270, 269, 269, 269, 269, 269, 269, 269, 269, 
-    269, 271, 266, 266, 266, 266, 266, 266, 81, 81, 272, 272, 81, 273, 273, 
-    273, 273, 273, 273, 273, 273, 273, 273, 273, 273, 273, 273, 273, 273, 
-    273, 273, 81, 81, 81, 273, 273, 273, 273, 273, 273, 273, 273, 81, 273, 
-    273, 273, 273, 273, 273, 273, 273, 273, 81, 273, 81, 81, 81, 81, 274, 81, 
-    81, 81, 81, 272, 272, 272, 275, 275, 275, 81, 275, 81, 272, 272, 272, 
-    272, 272, 272, 272, 272, 81, 81, 81, 81, 81, 81, 276, 276, 276, 276, 276, 
-    276, 276, 276, 276, 276, 81, 81, 272, 272, 277, 81, 81, 81, 81, 278, 278, 
-    278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 
-    279, 278, 278, 279, 279, 279, 279, 280, 280, 281, 81, 81, 81, 81, 282, 
-    278, 278, 278, 278, 278, 278, 283, 279, 284, 284, 284, 284, 279, 279, 
-    279, 285, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 287, 287, 81, 
-    81, 81, 81, 81, 288, 288, 81, 288, 81, 288, 288, 288, 288, 288, 81, 288, 
-    288, 288, 288, 288, 288, 288, 288, 288, 288, 288, 288, 288, 288, 288, 
-    288, 81, 288, 81, 288, 288, 289, 288, 288, 289, 289, 289, 289, 290, 290, 
-    291, 289, 289, 288, 81, 81, 288, 288, 288, 288, 288, 81, 292, 81, 293, 
-    293, 293, 293, 289, 289, 81, 81, 294, 294, 294, 294, 294, 294, 294, 294, 
-    294, 294, 81, 81, 288, 288, 288, 288, 295, 296, 296, 296, 297, 298, 297, 
-    297, 299, 297, 297, 300, 299, 301, 301, 301, 301, 301, 299, 302, 301, 
-    302, 302, 302, 303, 303, 302, 302, 302, 302, 302, 302, 304, 304, 304, 
-    304, 304, 304, 304, 304, 304, 304, 305, 305, 305, 305, 305, 305, 305, 
-    305, 305, 305, 306, 303, 302, 303, 302, 307, 308, 309, 308, 309, 310, 
-    310, 295, 295, 295, 295, 295, 295, 295, 295, 81, 295, 295, 295, 295, 295, 
-    295, 295, 295, 295, 295, 295, 295, 81, 81, 81, 81, 311, 312, 313, 314, 
-    313, 313, 313, 313, 313, 312, 312, 312, 312, 313, 315, 312, 313, 316, 
-    316, 317, 300, 316, 316, 295, 295, 295, 295, 295, 313, 313, 313, 313, 
-    313, 313, 313, 313, 313, 313, 313, 81, 313, 313, 313, 313, 313, 313, 313, 
-    313, 313, 313, 313, 313, 81, 306, 306, 302, 302, 302, 302, 302, 302, 303, 
-    302, 302, 302, 302, 302, 302, 81, 302, 302, 297, 297, 300, 297, 298, 318, 
-    318, 318, 318, 299, 299, 81, 81, 81, 81, 81, 319, 319, 319, 319, 319, 
-    319, 319, 319, 319, 319, 319, 320, 320, 321, 321, 321, 321, 320, 321, 
-    321, 321, 321, 321, 322, 320, 323, 323, 320, 320, 321, 321, 319, 324, 
-    324, 324, 324, 324, 324, 324, 324, 324, 324, 325, 325, 326, 326, 326, 
-    326, 319, 319, 319, 319, 319, 319, 320, 320, 321, 321, 319, 319, 319, 
-    319, 321, 321, 321, 319, 320, 320, 320, 319, 319, 320, 320, 320, 320, 
-    320, 320, 320, 319, 319, 319, 321, 321, 321, 321, 319, 319, 319, 319, 
-    319, 321, 320, 320, 321, 321, 320, 320, 320, 320, 320, 320, 327, 319, 
-    320, 324, 324, 320, 320, 320, 321, 328, 328, 329, 329, 329, 329, 329, 
-    329, 329, 329, 329, 329, 329, 329, 329, 329, 81, 329, 81, 81, 81, 81, 81, 
-    329, 81, 81, 330, 330, 330, 330, 330, 330, 330, 330, 330, 330, 330, 331, 
-    332, 330, 330, 330, 333, 333, 333, 333, 333, 333, 333, 333, 334, 334, 
-    334, 334, 334, 334, 334, 334, 335, 335, 335, 335, 335, 335, 335, 335, 
-    336, 336, 336, 336, 336, 336, 336, 336, 336, 81, 336, 336, 336, 336, 81, 
-    81, 336, 336, 336, 336, 336, 336, 336, 81, 336, 336, 336, 81, 81, 337, 
-    337, 337, 338, 339, 338, 338, 338, 338, 338, 338, 338, 340, 340, 340, 
-    340, 340, 340, 340, 340, 340, 340, 340, 340, 340, 340, 340, 340, 340, 
-    340, 340, 340, 81, 81, 81, 341, 341, 341, 341, 341, 341, 341, 341, 341, 
-    341, 81, 81, 81, 81, 81, 81, 342, 342, 342, 342, 342, 342, 342, 342, 342, 
-    342, 342, 342, 342, 342, 81, 81, 343, 343, 343, 343, 343, 343, 81, 81, 
-    344, 345, 345, 345, 345, 345, 345, 345, 345, 345, 345, 345, 345, 345, 
-    345, 345, 345, 345, 345, 345, 345, 346, 347, 345, 348, 349, 349, 349, 
-    349, 349, 349, 349, 349, 349, 349, 349, 349, 349, 349, 349, 349, 349, 
-    349, 350, 351, 81, 81, 81, 352, 352, 352, 352, 352, 352, 352, 352, 352, 
-    352, 352, 198, 198, 198, 353, 353, 353, 352, 352, 352, 352, 352, 352, 
-    352, 352, 81, 81, 81, 81, 81, 81, 81, 354, 354, 354, 354, 354, 354, 354, 
-    354, 354, 354, 354, 354, 354, 81, 354, 354, 354, 354, 355, 355, 356, 81, 
-    81, 81, 357, 357, 357, 357, 357, 357, 357, 357, 357, 357, 358, 358, 359, 
-    198, 198, 81, 360, 360, 360, 360, 360, 360, 360, 360, 360, 360, 361, 361, 
-    81, 81, 81, 81, 362, 362, 362, 362, 362, 362, 362, 362, 362, 362, 362, 
-    362, 362, 81, 362, 362, 362, 81, 363, 363, 81, 81, 81, 81, 364, 364, 364, 
-    364, 364, 364, 364, 364, 364, 364, 364, 364, 365, 365, 366, 365, 365, 
-    365, 365, 365, 365, 365, 366, 366, 366, 366, 366, 366, 366, 366, 365, 
-    366, 366, 365, 365, 365, 365, 365, 365, 365, 365, 365, 367, 365, 368, 
-    368, 369, 370, 368, 371, 368, 372, 364, 373, 81, 81, 374, 374, 374, 374, 
-    374, 374, 374, 374, 374, 374, 81, 81, 81, 81, 81, 81, 375, 375, 375, 375, 
-    375, 375, 375, 375, 375, 375, 81, 81, 81, 81, 81, 81, 376, 376, 377, 377, 
-    378, 379, 380, 376, 381, 381, 376, 382, 382, 382, 383, 81, 384, 384, 384, 
-    384, 384, 384, 384, 384, 384, 384, 81, 81, 81, 81, 81, 81, 385, 385, 385, 
-    385, 385, 385, 385, 385, 385, 385, 385, 386, 385, 385, 385, 385, 385, 81, 
-    81, 81, 81, 81, 81, 81, 385, 385, 385, 385, 385, 382, 382, 385, 385, 387, 
-    385, 81, 81, 81, 81, 81, 345, 345, 345, 345, 345, 345, 81, 81, 388, 388, 
-    388, 388, 388, 388, 388, 388, 388, 388, 388, 388, 388, 388, 388, 81, 389, 
-    389, 389, 390, 390, 390, 390, 389, 389, 390, 390, 390, 81, 81, 81, 81, 
-    390, 390, 389, 390, 390, 390, 390, 390, 390, 391, 392, 393, 81, 81, 81, 
-    81, 394, 81, 81, 81, 395, 395, 396, 396, 396, 396, 396, 396, 396, 396, 
-    396, 396, 397, 397, 397, 397, 397, 397, 397, 397, 397, 397, 397, 397, 
-    397, 397, 81, 81, 397, 397, 397, 397, 397, 81, 81, 81, 398, 398, 398, 
-    398, 398, 398, 398, 398, 398, 398, 398, 398, 81, 81, 81, 81, 398, 398, 
-    81, 81, 81, 81, 81, 81, 399, 399, 399, 399, 399, 399, 399, 399, 399, 399, 
-    400, 81, 81, 81, 401, 401, 402, 402, 402, 402, 402, 402, 402, 402, 403, 
-    403, 403, 403, 403, 403, 403, 403, 403, 403, 403, 403, 403, 403, 403, 
-    404, 405, 406, 406, 407, 81, 81, 408, 408, 409, 409, 409, 409, 409, 409, 
-    409, 409, 409, 409, 409, 409, 409, 410, 411, 410, 411, 411, 411, 411, 
-    411, 411, 411, 81, 412, 410, 411, 410, 410, 411, 411, 411, 411, 411, 411, 
-    411, 411, 410, 410, 410, 410, 410, 410, 411, 411, 413, 413, 413, 413, 
-    413, 413, 413, 413, 81, 81, 414, 415, 415, 415, 415, 415, 415, 415, 415, 
-    415, 415, 81, 81, 81, 81, 81, 81, 416, 416, 416, 416, 416, 416, 416, 417, 
-    416, 416, 416, 416, 416, 416, 81, 81, 96, 96, 96, 96, 96, 156, 156, 156, 
-    156, 156, 156, 96, 96, 156, 418, 81, 419, 419, 419, 419, 420, 421, 421, 
-    421, 421, 421, 421, 421, 421, 421, 421, 421, 421, 421, 421, 421, 422, 
-    420, 419, 419, 419, 419, 419, 420, 419, 420, 420, 420, 420, 420, 419, 
-    420, 423, 421, 421, 421, 421, 421, 421, 421, 81, 81, 81, 81, 424, 424, 
-    424, 424, 424, 424, 424, 424, 424, 424, 425, 425, 426, 425, 425, 425, 
-    425, 427, 427, 427, 427, 427, 427, 427, 427, 427, 427, 428, 429, 428, 
-    428, 428, 428, 428, 428, 428, 427, 427, 427, 427, 427, 427, 427, 427, 
-    427, 81, 81, 81, 430, 430, 431, 432, 432, 432, 432, 432, 432, 432, 432, 
-    432, 432, 432, 432, 432, 432, 431, 430, 430, 430, 430, 431, 431, 430, 
-    430, 433, 434, 430, 430, 432, 432, 435, 435, 435, 435, 435, 435, 435, 
-    435, 435, 435, 432, 432, 432, 432, 432, 432, 436, 436, 436, 436, 436, 
-    436, 436, 436, 436, 436, 436, 436, 436, 436, 437, 438, 439, 439, 438, 
-    438, 438, 439, 438, 439, 439, 439, 440, 440, 81, 81, 81, 81, 81, 81, 81, 
-    81, 441, 441, 441, 441, 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, 
-    442, 442, 443, 443, 443, 443, 443, 443, 443, 443, 444, 444, 444, 444, 
-    444, 444, 444, 444, 443, 443, 444, 445, 81, 81, 81, 446, 446, 446, 446, 
-    446, 447, 447, 447, 447, 447, 447, 447, 447, 447, 447, 81, 81, 81, 442, 
-    442, 442, 448, 448, 448, 448, 448, 448, 448, 448, 448, 448, 449, 449, 
-    449, 449, 449, 449, 449, 449, 449, 449, 449, 449, 449, 449, 450, 450, 
-    450, 450, 450, 450, 451, 451, 93, 81, 81, 81, 81, 81, 81, 81, 329, 329, 
-    329, 81, 81, 329, 329, 329, 452, 452, 452, 452, 452, 452, 452, 452, 96, 
-    96, 96, 331, 453, 156, 156, 156, 156, 156, 96, 96, 156, 156, 156, 156, 
-    96, 454, 453, 453, 453, 453, 453, 453, 453, 455, 455, 455, 455, 156, 455, 
-    455, 455, 455, 455, 455, 96, 455, 455, 454, 96, 96, 455, 81, 81, 81, 81, 
-    81, 56, 56, 56, 56, 56, 56, 79, 79, 79, 79, 79, 93, 59, 59, 59, 59, 59, 
-    59, 59, 59, 59, 82, 82, 82, 82, 82, 59, 59, 59, 59, 82, 82, 82, 82, 82, 
-    56, 56, 56, 56, 56, 456, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 59, 59, 
-    59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 82, 96, 96, 156, 96, 96, 96, 96, 
-    96, 96, 96, 156, 96, 96, 457, 458, 156, 459, 96, 96, 96, 96, 96, 96, 96, 
-    96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 460, 461, 461, 
-    156, 81, 96, 462, 156, 96, 156, 52, 56, 52, 56, 52, 56, 56, 56, 56, 56, 
-    56, 56, 56, 56, 52, 56, 79, 79, 79, 79, 79, 79, 79, 79, 78, 78, 78, 78, 
-    78, 78, 78, 78, 79, 79, 79, 79, 79, 79, 81, 81, 78, 78, 78, 78, 78, 78, 
-    81, 81, 81, 78, 81, 78, 81, 78, 81, 78, 463, 463, 463, 463, 463, 463, 
-    463, 463, 79, 79, 79, 79, 79, 81, 79, 79, 78, 78, 78, 78, 463, 80, 79, 
-    80, 80, 80, 79, 79, 79, 81, 79, 79, 78, 78, 78, 78, 463, 80, 80, 80, 79, 
-    79, 79, 79, 81, 81, 79, 79, 78, 78, 78, 78, 81, 80, 80, 80, 78, 78, 78, 
-    78, 78, 80, 80, 80, 81, 81, 79, 79, 79, 81, 79, 79, 78, 78, 78, 78, 463, 
-    464, 80, 81, 465, 465, 465, 465, 465, 465, 465, 466, 465, 465, 465, 467, 
-    468, 469, 470, 471, 472, 473, 474, 472, 475, 476, 38, 84, 477, 478, 479, 
-    42, 477, 478, 479, 42, 38, 38, 480, 84, 481, 481, 481, 482, 483, 484, 
-    485, 486, 487, 488, 489, 33, 490, 491, 490, 490, 491, 492, 493, 493, 84, 
-    42, 50, 38, 494, 494, 480, 495, 495, 84, 84, 84, 496, 479, 497, 494, 494, 
-    494, 84, 84, 84, 84, 84, 84, 84, 84, 498, 84, 495, 84, 379, 84, 379, 379, 
-    379, 379, 84, 379, 379, 465, 499, 500, 500, 500, 500, 81, 501, 502, 503, 
-    504, 505, 505, 505, 505, 505, 505, 506, 59, 81, 81, 47, 506, 506, 506, 
-    506, 506, 507, 507, 498, 479, 497, 508, 506, 47, 47, 47, 47, 506, 506, 
-    506, 506, 506, 507, 507, 498, 479, 497, 81, 59, 59, 59, 59, 59, 81, 81, 
-    81, 282, 282, 282, 282, 282, 282, 282, 509, 282, 510, 282, 282, 36, 282, 
-    282, 282, 282, 282, 282, 282, 282, 282, 509, 282, 282, 282, 282, 509, 
-    282, 282, 509, 282, 511, 511, 511, 511, 511, 511, 511, 511, 96, 96, 453, 
-    453, 96, 96, 96, 96, 453, 453, 453, 96, 96, 418, 418, 418, 418, 96, 418, 
-    418, 418, 453, 453, 96, 156, 96, 453, 453, 156, 156, 156, 156, 96, 81, 
-    81, 81, 81, 81, 81, 81, 40, 40, 512, 513, 40, 514, 40, 512, 40, 513, 49, 
-    512, 512, 512, 49, 49, 512, 512, 512, 515, 40, 512, 516, 40, 498, 512, 
-    512, 512, 512, 512, 40, 40, 40, 514, 514, 40, 512, 40, 85, 40, 512, 40, 
-    52, 517, 512, 512, 518, 49, 512, 512, 52, 512, 49, 455, 455, 455, 455, 
-    49, 40, 40, 49, 49, 512, 512, 498, 498, 498, 498, 498, 512, 49, 49, 49, 
-    49, 40, 498, 40, 40, 56, 318, 519, 519, 519, 520, 51, 521, 519, 519, 519, 
-    519, 519, 51, 520, 520, 51, 519, 522, 522, 522, 522, 522, 522, 522, 522, 
-    522, 522, 522, 522, 523, 523, 523, 523, 522, 522, 523, 523, 523, 523, 
-    523, 523, 523, 523, 523, 52, 56, 523, 523, 523, 523, 51, 40, 40, 81, 81, 
-    81, 81, 54, 54, 54, 54, 54, 514, 514, 514, 514, 514, 498, 498, 40, 40, 
-    40, 40, 498, 40, 40, 498, 40, 40, 498, 40, 40, 40, 40, 40, 40, 40, 498, 
-    40, 40, 40, 40, 40, 40, 40, 40, 40, 44, 44, 40, 40, 40, 40, 40, 40, 40, 
-    40, 40, 40, 40, 40, 498, 498, 40, 40, 54, 40, 54, 40, 40, 40, 40, 40, 40, 
-    40, 40, 40, 40, 44, 40, 40, 40, 40, 498, 498, 498, 498, 498, 498, 498, 
-    498, 498, 498, 498, 498, 54, 498, 54, 54, 498, 498, 498, 54, 54, 498, 
-    498, 54, 498, 498, 498, 54, 498, 54, 524, 525, 498, 54, 498, 498, 498, 
-    498, 54, 498, 498, 54, 54, 54, 54, 498, 498, 54, 498, 54, 498, 54, 54, 
-    54, 54, 54, 54, 498, 54, 498, 498, 498, 498, 498, 54, 54, 54, 54, 498, 
-    498, 498, 498, 54, 54, 498, 498, 54, 498, 498, 498, 54, 498, 498, 498, 
-    498, 498, 54, 498, 498, 498, 498, 498, 54, 54, 498, 498, 54, 54, 54, 54, 
-    498, 498, 54, 54, 498, 498, 54, 54, 498, 498, 498, 498, 498, 54, 498, 
-    498, 498, 54, 498, 498, 498, 498, 498, 498, 498, 498, 498, 498, 498, 498, 
-    498, 54, 498, 498, 498, 498, 498, 498, 498, 526, 479, 497, 479, 497, 40, 
-    40, 40, 40, 40, 40, 514, 40, 40, 40, 40, 40, 40, 40, 527, 527, 40, 40, 
-    40, 40, 498, 498, 40, 40, 40, 40, 40, 40, 40, 528, 529, 40, 40, 40, 40, 
-    40, 40, 40, 40, 40, 40, 40, 318, 318, 318, 318, 318, 318, 318, 318, 318, 
-    318, 318, 318, 318, 40, 498, 40, 40, 40, 40, 40, 40, 40, 40, 318, 40, 40, 
-    40, 40, 40, 498, 498, 498, 498, 498, 498, 498, 498, 498, 40, 40, 40, 40, 
-    40, 530, 530, 530, 530, 40, 40, 40, 527, 531, 531, 527, 40, 40, 40, 40, 
-    40, 40, 40, 40, 40, 40, 40, 81, 40, 40, 40, 81, 81, 81, 81, 81, 51, 51, 
-    51, 51, 51, 51, 51, 51, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 
-    532, 532, 532, 532, 532, 532, 532, 532, 532, 532, 532, 532, 532, 532, 
-    521, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 520, 514, 514, 514, 
-    514, 514, 514, 514, 514, 514, 514, 514, 514, 40, 40, 40, 40, 514, 514, 
-    514, 514, 533, 40, 40, 40, 40, 40, 514, 514, 514, 514, 40, 40, 514, 514, 
-    40, 514, 514, 514, 514, 514, 514, 514, 40, 40, 40, 40, 40, 40, 40, 40, 
-    514, 514, 40, 40, 514, 54, 40, 40, 40, 40, 514, 514, 40, 40, 514, 54, 40, 
-    40, 40, 40, 514, 514, 514, 40, 40, 514, 40, 40, 514, 514, 40, 40, 40, 40, 
-    40, 40, 40, 514, 498, 498, 498, 498, 498, 534, 534, 498, 531, 531, 531, 
-    531, 40, 514, 514, 40, 40, 514, 40, 40, 40, 40, 514, 514, 40, 40, 40, 40, 
-    527, 527, 533, 533, 531, 40, 531, 531, 535, 536, 535, 531, 40, 531, 531, 
-    531, 40, 40, 40, 40, 514, 40, 514, 40, 40, 40, 40, 40, 530, 530, 530, 
-    530, 530, 530, 530, 530, 530, 530, 530, 530, 40, 40, 40, 40, 514, 514, 
-    40, 514, 514, 514, 40, 514, 535, 514, 514, 40, 514, 514, 40, 54, 40, 40, 
-    40, 40, 40, 40, 40, 527, 40, 40, 40, 530, 40, 40, 40, 40, 40, 40, 40, 40, 
-    40, 40, 514, 514, 40, 530, 40, 40, 40, 40, 40, 40, 40, 40, 530, 530, 318, 
-    40, 40, 40, 40, 40, 40, 40, 40, 527, 527, 535, 531, 531, 531, 531, 527, 
-    527, 535, 535, 535, 514, 514, 514, 514, 535, 530, 535, 535, 535, 514, 
-    535, 527, 514, 514, 514, 535, 535, 514, 514, 535, 514, 514, 535, 535, 
-    535, 40, 514, 40, 40, 40, 40, 514, 514, 527, 514, 514, 514, 514, 514, 
-    514, 535, 527, 527, 535, 527, 514, 535, 535, 537, 527, 514, 514, 527, 
-    535, 535, 531, 531, 531, 531, 531, 530, 40, 40, 531, 531, 538, 538, 536, 
-    536, 40, 40, 530, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 44, 40, 
-    40, 40, 40, 40, 40, 530, 40, 530, 40, 40, 40, 40, 530, 530, 530, 40, 539, 
-    40, 40, 40, 540, 540, 540, 540, 540, 540, 40, 541, 541, 531, 40, 40, 40, 
-    479, 497, 479, 497, 479, 497, 479, 497, 479, 497, 479, 497, 479, 497, 51, 
-    51, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 40, 530, 
-    530, 530, 40, 40, 40, 40, 40, 40, 40, 530, 498, 498, 498, 498, 498, 479, 
-    497, 498, 498, 498, 498, 498, 498, 498, 16, 31, 16, 31, 16, 31, 16, 31, 
-    479, 497, 542, 542, 542, 542, 542, 542, 542, 542, 498, 498, 498, 479, 
-    497, 16, 31, 479, 497, 479, 497, 479, 497, 479, 497, 479, 497, 498, 498, 
-    498, 498, 498, 498, 498, 479, 497, 479, 497, 498, 498, 498, 498, 498, 
-    498, 498, 498, 479, 497, 498, 498, 40, 40, 40, 530, 530, 40, 40, 40, 498, 
-    498, 498, 498, 498, 40, 40, 498, 498, 498, 498, 498, 498, 40, 40, 40, 
-    530, 40, 40, 40, 40, 539, 514, 514, 40, 40, 40, 40, 81, 81, 40, 40, 40, 
-    40, 40, 40, 40, 40, 81, 81, 543, 543, 543, 543, 543, 543, 543, 543, 543, 
-    543, 543, 543, 543, 543, 543, 81, 544, 544, 544, 544, 544, 544, 544, 544, 
-    544, 544, 544, 544, 544, 544, 544, 81, 52, 56, 52, 52, 52, 56, 56, 52, 
-    56, 52, 56, 52, 56, 52, 52, 52, 52, 56, 52, 56, 56, 52, 56, 56, 56, 56, 
-    56, 56, 59, 59, 52, 52, 87, 88, 87, 88, 88, 545, 545, 545, 545, 545, 545, 
-    87, 88, 87, 88, 546, 546, 546, 87, 88, 81, 81, 81, 81, 81, 547, 548, 548, 
-    548, 549, 547, 548, 330, 330, 330, 330, 330, 330, 81, 330, 81, 81, 81, 
-    81, 81, 330, 81, 81, 550, 550, 550, 550, 550, 550, 550, 550, 81, 81, 81, 
-    81, 81, 81, 81, 551, 552, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 
-    81, 81, 553, 95, 95, 95, 95, 95, 95, 95, 95, 554, 554, 42, 50, 42, 50, 
-    554, 554, 554, 42, 50, 554, 42, 50, 379, 379, 379, 379, 379, 379, 379, 
-    379, 84, 474, 555, 379, 556, 84, 42, 50, 84, 84, 42, 50, 479, 497, 479, 
-    497, 479, 497, 479, 497, 379, 379, 379, 379, 377, 60, 379, 379, 84, 379, 
-    379, 84, 84, 84, 84, 84, 557, 557, 379, 379, 379, 84, 474, 379, 479, 379, 
-    379, 379, 379, 379, 379, 379, 379, 84, 379, 84, 379, 379, 558, 558, 558, 
-    558, 558, 558, 558, 558, 558, 558, 81, 558, 558, 558, 558, 558, 558, 558, 
-    558, 558, 81, 81, 81, 81, 558, 558, 558, 558, 558, 558, 81, 81, 527, 527, 
-    527, 527, 527, 527, 527, 527, 527, 527, 527, 527, 81, 81, 81, 81, 559, 
-    560, 560, 561, 527, 562, 563, 564, 528, 529, 528, 529, 528, 529, 528, 
-    529, 528, 529, 527, 527, 528, 529, 528, 529, 528, 529, 528, 529, 565, 
-    528, 529, 529, 527, 564, 564, 564, 564, 564, 564, 564, 564, 564, 566, 
-    567, 568, 569, 570, 570, 571, 572, 572, 572, 572, 573, 527, 527, 564, 
-    564, 564, 562, 574, 561, 527, 531, 81, 575, 576, 575, 576, 575, 576, 575, 
-    576, 575, 576, 576, 576, 576, 576, 576, 576, 576, 576, 576, 576, 576, 
-    576, 576, 576, 576, 576, 575, 576, 576, 576, 576, 576, 576, 576, 575, 
-    576, 575, 576, 575, 576, 576, 576, 576, 576, 576, 575, 576, 576, 576, 
-    576, 576, 576, 575, 575, 81, 81, 577, 577, 578, 578, 579, 579, 576, 565, 
-    580, 581, 580, 581, 580, 581, 580, 581, 580, 581, 581, 581, 581, 581, 
-    581, 581, 581, 581, 581, 581, 581, 581, 581, 581, 581, 581, 580, 581, 
-    581, 581, 581, 581, 581, 581, 580, 581, 580, 581, 580, 581, 581, 581, 
-    581, 581, 581, 580, 581, 581, 581, 581, 581, 581, 580, 580, 581, 581, 
-    581, 581, 582, 583, 584, 584, 581, 81, 81, 81, 81, 81, 585, 585, 585, 
-    585, 585, 585, 585, 585, 585, 585, 585, 81, 586, 586, 586, 586, 586, 586, 
-    586, 586, 586, 586, 586, 586, 586, 586, 586, 586, 586, 586, 586, 586, 
-    586, 586, 81, 587, 587, 588, 588, 588, 588, 587, 587, 587, 587, 587, 587, 
-    587, 587, 587, 587, 585, 585, 585, 81, 81, 81, 81, 81, 580, 580, 580, 
-    580, 580, 580, 580, 580, 589, 589, 589, 589, 589, 589, 589, 589, 589, 
-    589, 589, 589, 589, 590, 590, 81, 588, 588, 588, 588, 588, 588, 588, 588, 
-    588, 588, 587, 587, 587, 587, 587, 587, 591, 591, 591, 591, 591, 591, 
-    591, 591, 527, 592, 592, 592, 592, 592, 592, 592, 592, 592, 592, 592, 
-    592, 592, 592, 592, 589, 589, 589, 589, 590, 590, 590, 587, 587, 592, 
-    592, 592, 592, 592, 592, 592, 587, 587, 587, 587, 527, 527, 527, 527, 
-    593, 593, 593, 593, 593, 593, 593, 593, 593, 593, 593, 593, 593, 593, 
-    593, 81, 587, 587, 587, 587, 587, 587, 587, 527, 527, 527, 527, 587, 587, 
-    587, 587, 587, 587, 587, 587, 587, 587, 587, 527, 527, 594, 594, 594, 
-    594, 594, 594, 594, 594, 594, 594, 594, 594, 594, 594, 595, 595, 595, 
-    595, 595, 595, 595, 595, 595, 595, 596, 596, 596, 596, 596, 596, 596, 
-    596, 596, 596, 596, 596, 596, 597, 596, 596, 596, 596, 596, 596, 596, 81, 
-    81, 81, 598, 598, 598, 598, 598, 598, 598, 598, 598, 598, 598, 598, 598, 
-    598, 598, 81, 599, 599, 599, 599, 599, 599, 599, 599, 600, 600, 600, 600, 
-    600, 600, 601, 601, 602, 602, 602, 602, 602, 602, 602, 602, 602, 602, 
-    602, 602, 603, 604, 605, 604, 606, 606, 606, 606, 606, 606, 606, 606, 
-    606, 606, 602, 602, 81, 81, 81, 81, 90, 93, 90, 93, 90, 93, 607, 95, 97, 
-    97, 97, 608, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 608, 609, 90, 93, 
-    90, 93, 456, 456, 95, 95, 610, 610, 610, 610, 610, 610, 610, 610, 610, 
-    610, 610, 610, 610, 610, 611, 611, 611, 611, 611, 611, 611, 611, 611, 
-    611, 612, 612, 613, 614, 614, 614, 614, 614, 62, 62, 62, 62, 62, 62, 62, 
-    60, 60, 60, 60, 60, 60, 60, 60, 60, 62, 62, 52, 56, 52, 56, 52, 56, 56, 
-    56, 52, 56, 52, 56, 52, 56, 59, 56, 56, 56, 56, 56, 56, 56, 56, 52, 56, 
-    52, 56, 52, 52, 56, 60, 615, 615, 52, 56, 52, 56, 57, 52, 56, 52, 56, 56, 
-    56, 52, 56, 52, 56, 52, 52, 52, 52, 52, 56, 52, 52, 52, 52, 52, 56, 52, 
-    56, 81, 81, 52, 56, 52, 52, 52, 81, 81, 81, 81, 81, 81, 81, 81, 57, 59, 
-    59, 56, 57, 57, 57, 57, 57, 616, 616, 617, 616, 616, 616, 618, 616, 616, 
-    616, 616, 617, 616, 616, 616, 616, 616, 616, 616, 616, 616, 616, 616, 
-    616, 616, 616, 616, 619, 619, 617, 617, 619, 620, 620, 620, 620, 81, 81, 
-    81, 81, 621, 621, 621, 621, 621, 621, 318, 318, 509, 518, 81, 81, 81, 81, 
-    81, 81, 622, 622, 622, 622, 622, 622, 622, 622, 622, 622, 622, 622, 623, 
-    623, 624, 624, 625, 625, 626, 626, 626, 626, 626, 626, 626, 626, 626, 
-    626, 626, 626, 626, 626, 626, 626, 626, 626, 625, 625, 625, 625, 625, 
-    625, 625, 625, 625, 625, 625, 625, 625, 625, 625, 625, 627, 628, 81, 81, 
-    81, 81, 81, 81, 81, 81, 629, 629, 630, 630, 630, 630, 630, 630, 630, 630, 
-    630, 630, 81, 81, 81, 81, 81, 81, 631, 631, 631, 631, 631, 631, 631, 631, 
-    631, 631, 195, 195, 195, 195, 195, 195, 200, 200, 200, 195, 632, 195, 
-    195, 193, 633, 633, 633, 633, 633, 633, 633, 633, 633, 633, 634, 634, 
-    634, 634, 634, 634, 634, 634, 634, 634, 634, 634, 634, 634, 634, 634, 
-    634, 634, 634, 634, 635, 635, 635, 635, 635, 636, 636, 636, 198, 637, 
-    638, 638, 638, 638, 638, 638, 638, 638, 638, 638, 638, 638, 638, 638, 
-    638, 639, 639, 639, 639, 639, 639, 639, 639, 639, 639, 639, 640, 641, 81, 
-    81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 642, 333, 333, 333, 333, 333, 81, 
-    81, 81, 643, 643, 643, 644, 645, 645, 645, 645, 645, 645, 645, 645, 645, 
-    645, 645, 645, 645, 645, 645, 646, 644, 644, 643, 643, 643, 643, 644, 
-    644, 643, 643, 644, 644, 647, 648, 648, 648, 648, 648, 648, 649, 649, 
-    649, 648, 648, 648, 648, 81, 61, 650, 650, 650, 650, 650, 650, 650, 650, 
-    650, 650, 81, 81, 81, 81, 648, 648, 319, 319, 319, 319, 319, 321, 651, 
-    319, 324, 324, 319, 319, 319, 319, 319, 81, 652, 652, 652, 652, 652, 652, 
-    652, 652, 652, 653, 653, 653, 653, 653, 653, 654, 654, 653, 653, 654, 
-    654, 653, 653, 81, 652, 652, 652, 653, 652, 652, 652, 652, 652, 652, 652, 
-    652, 653, 654, 81, 81, 655, 655, 655, 655, 655, 655, 655, 655, 655, 655, 
-    81, 81, 656, 657, 657, 657, 651, 319, 319, 319, 319, 319, 319, 328, 328, 
-    328, 319, 320, 321, 320, 319, 319, 658, 658, 658, 658, 658, 658, 658, 
-    658, 659, 658, 659, 659, 660, 658, 658, 659, 659, 658, 658, 658, 658, 
-    658, 659, 659, 658, 659, 658, 81, 81, 81, 81, 81, 81, 81, 81, 658, 658, 
-    661, 662, 662, 663, 663, 663, 663, 663, 663, 663, 663, 663, 663, 663, 
-    664, 665, 665, 664, 664, 666, 666, 663, 667, 667, 664, 668, 81, 81, 336, 
-    336, 336, 336, 336, 336, 81, 56, 56, 56, 615, 59, 59, 59, 59, 56, 56, 56, 
-    56, 56, 79, 56, 56, 343, 343, 343, 343, 343, 343, 343, 343, 663, 663, 
-    663, 664, 664, 665, 664, 664, 665, 664, 664, 666, 664, 668, 81, 81, 669, 
-    669, 669, 669, 669, 669, 669, 669, 669, 669, 81, 81, 81, 81, 81, 81, 670, 
-    671, 671, 671, 671, 671, 671, 671, 671, 671, 671, 671, 671, 671, 671, 
-    671, 671, 671, 671, 671, 670, 671, 671, 671, 671, 671, 671, 671, 81, 81, 
-    81, 81, 334, 334, 334, 334, 334, 334, 334, 81, 81, 81, 81, 335, 335, 335, 
-    335, 335, 335, 335, 335, 335, 81, 81, 81, 81, 672, 672, 672, 672, 672, 
-    672, 672, 672, 673, 673, 673, 673, 673, 673, 673, 673, 594, 594, 595, 
-    595, 595, 595, 595, 595, 56, 56, 56, 56, 56, 56, 56, 81, 81, 81, 81, 101, 
-    101, 101, 101, 101, 81, 81, 81, 81, 81, 129, 674, 129, 129, 675, 129, 
-    129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 81, 129, 129, 
-    129, 129, 129, 81, 129, 81, 129, 129, 81, 129, 129, 81, 129, 129, 146, 
-    146, 676, 676, 676, 676, 676, 676, 676, 676, 676, 676, 676, 676, 676, 
-    676, 676, 676, 81, 81, 81, 81, 81, 81, 81, 81, 81, 146, 146, 146, 146, 
-    146, 146, 146, 146, 146, 146, 146, 497, 479, 81, 81, 146, 146, 146, 146, 
-    146, 146, 146, 146, 146, 146, 135, 138, 81, 81, 677, 677, 677, 677, 677, 
-    677, 677, 677, 678, 560, 560, 678, 678, 679, 679, 528, 529, 680, 81, 81, 
-    81, 81, 81, 81, 96, 96, 96, 96, 96, 96, 96, 156, 156, 156, 156, 156, 156, 
-    156, 95, 95, 561, 571, 571, 681, 681, 528, 529, 528, 529, 528, 529, 528, 
-    529, 528, 529, 528, 529, 528, 529, 528, 529, 561, 561, 528, 529, 561, 
-    561, 561, 561, 681, 681, 681, 682, 561, 682, 81, 582, 683, 679, 679, 571, 
-    528, 529, 528, 529, 528, 529, 684, 561, 561, 685, 686, 687, 687, 687, 81, 
-    561, 688, 689, 561, 81, 81, 81, 81, 146, 146, 146, 146, 146, 81, 81, 499, 
-    81, 690, 691, 692, 693, 694, 691, 691, 695, 696, 691, 697, 698, 699, 698, 
-    700, 701, 701, 701, 701, 701, 701, 701, 701, 701, 701, 702, 703, 704, 
-    704, 704, 690, 691, 705, 705, 705, 705, 705, 705, 705, 705, 705, 705, 
-    705, 705, 705, 705, 705, 705, 705, 705, 695, 691, 696, 706, 707, 706, 
-    708, 708, 708, 708, 708, 708, 708, 708, 708, 708, 708, 708, 708, 708, 
-    708, 708, 708, 708, 695, 704, 696, 704, 695, 696, 709, 710, 711, 709, 
-    712, 713, 714, 714, 714, 714, 714, 714, 714, 714, 714, 715, 713, 713, 
-    713, 713, 713, 713, 713, 713, 713, 713, 713, 713, 713, 713, 713, 713, 
-    713, 713, 713, 713, 713, 716, 716, 717, 717, 717, 717, 717, 717, 717, 
-    717, 717, 717, 717, 717, 717, 717, 717, 81, 81, 81, 717, 717, 717, 717, 
-    717, 717, 81, 81, 717, 717, 717, 81, 81, 81, 718, 693, 704, 706, 719, 
-    693, 693, 81, 720, 721, 721, 721, 721, 720, 720, 81, 81, 722, 722, 722, 
-    723, 514, 81, 81, 724, 724, 724, 724, 724, 724, 724, 724, 724, 724, 724, 
-    724, 81, 724, 724, 724, 724, 724, 724, 724, 724, 724, 724, 81, 724, 724, 
-    724, 81, 724, 724, 81, 724, 724, 724, 724, 724, 724, 724, 81, 81, 724, 
-    724, 724, 81, 81, 81, 81, 81, 198, 379, 198, 81, 81, 81, 81, 621, 621, 
-    621, 621, 621, 621, 621, 621, 621, 621, 621, 621, 621, 81, 81, 81, 318, 
-    725, 725, 725, 725, 725, 725, 725, 725, 725, 725, 725, 725, 725, 726, 
-    726, 726, 726, 727, 727, 727, 727, 727, 727, 727, 727, 727, 727, 727, 
-    727, 727, 727, 727, 727, 727, 726, 726, 727, 728, 728, 81, 40, 40, 40, 
-    40, 81, 81, 81, 81, 727, 81, 81, 81, 81, 81, 81, 81, 318, 318, 318, 318, 
-    318, 156, 81, 81, 729, 729, 729, 729, 729, 729, 729, 729, 729, 729, 729, 
-    729, 729, 81, 81, 81, 730, 730, 730, 730, 730, 730, 730, 730, 730, 81, 
-    81, 81, 81, 81, 81, 81, 156, 506, 506, 506, 506, 506, 506, 506, 506, 506, 
-    506, 506, 506, 506, 506, 506, 506, 506, 506, 506, 81, 81, 81, 81, 731, 
-    731, 731, 731, 731, 731, 731, 731, 732, 732, 732, 732, 81, 81, 81, 81, 
-    81, 81, 81, 81, 81, 731, 731, 731, 733, 733, 733, 733, 733, 733, 733, 
-    733, 733, 734, 733, 733, 733, 733, 733, 733, 733, 733, 734, 81, 81, 81, 
-    81, 81, 735, 735, 735, 735, 735, 735, 735, 735, 735, 735, 735, 735, 735, 
-    735, 736, 736, 736, 736, 736, 81, 81, 81, 81, 81, 737, 737, 737, 737, 
-    737, 737, 737, 737, 737, 737, 737, 737, 737, 737, 81, 738, 739, 739, 739, 
-    739, 739, 739, 739, 739, 739, 739, 739, 739, 81, 81, 81, 81, 740, 741, 
-    741, 741, 741, 741, 81, 81, 742, 742, 742, 742, 742, 742, 742, 742, 743, 
-    743, 743, 743, 743, 743, 743, 743, 744, 744, 744, 744, 744, 744, 744, 
-    744, 745, 745, 745, 745, 745, 745, 745, 745, 745, 745, 745, 745, 745, 
-    745, 81, 81, 746, 746, 746, 746, 746, 746, 746, 746, 746, 746, 81, 81, 
-    81, 81, 81, 81, 747, 747, 747, 747, 747, 747, 747, 747, 747, 747, 747, 
-    747, 81, 81, 81, 81, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 
-    748, 748, 81, 81, 81, 81, 749, 749, 749, 749, 749, 749, 749, 749, 750, 
-    750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 81, 81, 81, 81, 
-    81, 81, 81, 81, 81, 81, 81, 751, 752, 752, 752, 752, 752, 752, 752, 752, 
-    752, 752, 752, 752, 752, 752, 752, 81, 752, 752, 752, 752, 752, 752, 81, 
-    81, 753, 753, 753, 753, 753, 753, 81, 81, 753, 81, 753, 753, 753, 753, 
-    753, 753, 753, 753, 753, 753, 753, 753, 753, 753, 753, 753, 753, 753, 
-    753, 753, 81, 753, 753, 81, 81, 81, 753, 81, 81, 753, 754, 754, 754, 754, 
-    754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 81, 755, 756, 756, 756, 
-    756, 756, 756, 756, 756, 757, 757, 757, 757, 757, 757, 757, 757, 757, 
-    757, 757, 757, 757, 757, 757, 758, 758, 759, 759, 759, 759, 759, 759, 
-    759, 760, 760, 760, 760, 760, 760, 760, 760, 760, 760, 760, 760, 760, 
-    760, 760, 81, 81, 81, 81, 81, 81, 81, 81, 761, 761, 761, 761, 761, 761, 
-    761, 761, 761, 762, 762, 762, 762, 762, 762, 762, 762, 762, 762, 762, 81, 
-    762, 762, 81, 81, 81, 81, 81, 763, 763, 763, 763, 763, 764, 764, 764, 
-    764, 764, 764, 764, 764, 764, 764, 764, 764, 764, 764, 765, 765, 765, 
-    765, 765, 765, 81, 81, 81, 766, 767, 767, 767, 767, 767, 767, 767, 767, 
-    767, 767, 81, 81, 81, 81, 81, 768, 769, 769, 769, 769, 769, 769, 769, 
-    769, 770, 770, 770, 770, 770, 770, 770, 770, 81, 81, 81, 81, 771, 771, 
-    770, 770, 771, 771, 771, 771, 771, 771, 771, 771, 81, 81, 771, 771, 771, 
-    771, 771, 771, 772, 773, 773, 773, 81, 773, 773, 81, 81, 81, 81, 81, 773, 
-    774, 773, 775, 772, 772, 772, 772, 81, 772, 772, 772, 81, 772, 772, 772, 
-    772, 772, 772, 772, 772, 772, 772, 772, 772, 772, 772, 772, 772, 772, 
-    772, 772, 772, 772, 81, 81, 775, 776, 774, 81, 81, 81, 81, 777, 778, 778, 
-    778, 778, 778, 778, 778, 778, 778, 81, 81, 81, 81, 81, 81, 81, 779, 779, 
-    779, 779, 779, 779, 779, 779, 780, 81, 81, 81, 81, 81, 81, 81, 781, 781, 
-    781, 781, 781, 781, 781, 781, 781, 781, 781, 781, 781, 782, 782, 783, 
-    784, 784, 784, 784, 784, 784, 784, 784, 784, 784, 784, 784, 784, 785, 
-    785, 785, 786, 786, 786, 786, 786, 786, 786, 786, 787, 786, 786, 786, 
-    786, 786, 786, 786, 786, 786, 786, 786, 786, 788, 789, 81, 81, 81, 81, 
-    790, 790, 790, 790, 790, 791, 791, 791, 791, 791, 791, 792, 81, 793, 793, 
-    793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, 81, 81, 81, 
-    794, 794, 794, 794, 794, 794, 794, 795, 795, 795, 795, 795, 795, 795, 
-    795, 795, 795, 795, 795, 795, 795, 81, 81, 796, 796, 796, 796, 796, 796, 
-    796, 796, 797, 797, 797, 797, 797, 797, 797, 797, 797, 797, 797, 81, 81, 
-    81, 81, 81, 798, 798, 798, 798, 798, 798, 798, 798, 799, 799, 799, 799, 
-    799, 799, 799, 799, 799, 799, 81, 81, 81, 81, 81, 81, 81, 800, 800, 800, 
-    800, 81, 81, 81, 81, 801, 801, 801, 801, 801, 801, 801, 802, 802, 802, 
-    802, 802, 802, 802, 802, 802, 81, 81, 81, 81, 81, 81, 81, 803, 803, 803, 
-    803, 803, 803, 803, 803, 803, 803, 803, 81, 81, 81, 81, 81, 804, 804, 
-    804, 804, 804, 804, 804, 804, 804, 804, 804, 81, 81, 81, 81, 81, 81, 81, 
-    805, 805, 805, 805, 805, 805, 806, 806, 806, 806, 806, 806, 806, 806, 
-    806, 806, 806, 806, 807, 807, 807, 807, 808, 808, 808, 808, 808, 808, 
-    808, 808, 808, 808, 81, 81, 81, 81, 81, 81, 809, 809, 809, 809, 809, 809, 
-    809, 809, 809, 809, 809, 809, 809, 809, 809, 81, 810, 810, 810, 810, 810, 
-    810, 810, 810, 810, 810, 810, 810, 810, 811, 811, 811, 811, 811, 811, 
-    811, 811, 811, 811, 810, 812, 812, 812, 812, 812, 812, 812, 812, 812, 
-    812, 812, 812, 812, 812, 813, 813, 814, 814, 814, 813, 814, 813, 813, 
-    813, 813, 815, 815, 815, 815, 816, 816, 816, 816, 816, 81, 81, 81, 81, 
-    81, 81, 817, 817, 817, 817, 817, 817, 817, 817, 817, 817, 817, 817, 817, 
-    817, 817, 81, 818, 819, 818, 820, 820, 820, 820, 820, 820, 820, 820, 820, 
-    820, 820, 820, 820, 819, 819, 819, 819, 819, 819, 819, 819, 819, 819, 
-    819, 819, 819, 819, 821, 822, 822, 823, 823, 823, 823, 823, 81, 81, 81, 
-    81, 824, 824, 824, 824, 824, 824, 824, 824, 824, 824, 824, 824, 824, 824, 
-    824, 824, 824, 824, 824, 824, 825, 825, 825, 825, 825, 825, 825, 825, 
-    825, 825, 81, 81, 81, 81, 81, 81, 81, 821, 826, 826, 827, 828, 828, 828, 
-    828, 828, 828, 828, 828, 828, 828, 828, 828, 828, 827, 827, 827, 826, 
-    826, 826, 826, 827, 827, 829, 830, 831, 831, 832, 833, 833, 833, 833, 81, 
-    81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 832, 81, 81, 834, 834, 834, 834, 
-    834, 834, 834, 834, 834, 81, 81, 81, 81, 81, 81, 81, 835, 835, 835, 835, 
-    835, 835, 835, 835, 835, 835, 81, 81, 81, 81, 81, 81, 836, 836, 836, 837, 
-    837, 837, 837, 837, 837, 837, 837, 837, 837, 837, 837, 837, 837, 837, 
-    837, 837, 837, 837, 837, 838, 838, 838, 838, 838, 839, 838, 838, 838, 
-    838, 838, 838, 840, 840, 81, 841, 841, 841, 841, 841, 841, 841, 841, 841, 
-    841, 842, 842, 842, 842, 837, 839, 839, 81, 843, 843, 843, 843, 843, 843, 
-    843, 843, 843, 843, 843, 844, 845, 846, 843, 81, 847, 847, 848, 849, 849, 
-    849, 849, 849, 849, 849, 849, 849, 849, 849, 849, 849, 849, 849, 849, 
-    848, 848, 848, 847, 847, 847, 847, 847, 847, 847, 847, 847, 848, 850, 
-    849, 849, 849, 849, 851, 851, 852, 851, 847, 853, 847, 847, 852, 81, 81, 
-    854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 849, 855, 849, 851, 
-    851, 851, 81, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 856, 
-    856, 856, 856, 856, 856, 856, 856, 856, 81, 81, 81, 857, 857, 857, 857, 
-    857, 857, 857, 857, 857, 857, 81, 857, 857, 857, 857, 857, 857, 857, 857, 
-    857, 858, 858, 858, 859, 859, 859, 858, 858, 859, 860, 861, 859, 862, 
-    862, 863, 862, 862, 863, 859, 81, 864, 864, 864, 864, 864, 864, 864, 81, 
-    864, 81, 864, 864, 864, 864, 81, 864, 864, 864, 864, 864, 864, 864, 864, 
-    864, 864, 864, 864, 864, 864, 864, 81, 864, 864, 865, 81, 81, 81, 81, 81, 
-    81, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 866, 
-    866, 867, 868, 868, 868, 867, 867, 867, 867, 867, 867, 869, 870, 81, 81, 
-    81, 81, 81, 871, 871, 871, 871, 871, 871, 871, 871, 871, 871, 81, 81, 81, 
-    81, 81, 81, 872, 872, 873, 873, 81, 874, 874, 874, 874, 874, 874, 874, 
-    874, 81, 81, 874, 874, 81, 81, 874, 874, 874, 874, 874, 874, 874, 874, 
-    874, 874, 874, 874, 874, 874, 81, 874, 874, 874, 874, 874, 874, 874, 81, 
-    874, 874, 81, 874, 874, 874, 874, 874, 81, 875, 876, 874, 873, 873, 872, 
-    873, 873, 873, 873, 81, 81, 873, 873, 81, 81, 873, 873, 877, 81, 81, 874, 
-    81, 81, 81, 81, 81, 81, 873, 81, 81, 81, 81, 81, 874, 874, 874, 874, 874, 
-    873, 873, 81, 81, 878, 878, 878, 878, 878, 878, 878, 81, 81, 81, 879, 
-    879, 879, 879, 879, 879, 879, 879, 879, 879, 879, 879, 879, 880, 880, 
-    880, 881, 881, 881, 881, 881, 881, 881, 881, 880, 880, 882, 881, 881, 
-    880, 883, 879, 879, 879, 879, 884, 884, 884, 884, 885, 886, 886, 886, 
-    886, 886, 886, 886, 886, 886, 886, 81, 884, 81, 885, 887, 879, 888, 888, 
-    888, 888, 888, 888, 888, 888, 889, 889, 889, 890, 890, 890, 890, 890, 
-    890, 889, 890, 889, 889, 889, 889, 890, 890, 889, 891, 892, 888, 888, 
-    893, 888, 894, 894, 894, 894, 894, 894, 894, 894, 894, 894, 81, 81, 81, 
-    81, 81, 81, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, 
-    895, 895, 895, 896, 896, 896, 897, 897, 897, 897, 81, 81, 896, 896, 896, 
-    896, 897, 897, 896, 898, 899, 900, 901, 901, 902, 902, 903, 903, 903, 
-    901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 
-    901, 895, 895, 895, 895, 897, 897, 81, 81, 904, 904, 904, 904, 904, 904, 
-    904, 904, 905, 905, 905, 906, 906, 906, 906, 906, 906, 906, 906, 905, 
-    905, 906, 905, 907, 906, 908, 908, 909, 904, 81, 81, 81, 910, 910, 910, 
-    910, 910, 910, 910, 910, 910, 910, 81, 81, 81, 81, 81, 81, 911, 911, 911, 
-    911, 911, 911, 911, 911, 911, 911, 911, 911, 911, 81, 81, 81, 912, 912, 
-    912, 912, 912, 912, 912, 912, 912, 912, 912, 913, 914, 913, 914, 914, 
-    913, 913, 913, 913, 913, 913, 915, 916, 912, 81, 81, 81, 81, 81, 81, 81, 
-    917, 917, 917, 917, 917, 917, 917, 917, 917, 917, 81, 81, 81, 81, 81, 81, 
-    918, 918, 918, 918, 918, 918, 918, 918, 918, 918, 918, 81, 81, 919, 919, 
-    919, 920, 920, 919, 919, 919, 919, 920, 919, 919, 919, 919, 921, 81, 81, 
-    81, 81, 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, 923, 923, 924, 
-    924, 924, 925, 926, 926, 926, 926, 926, 926, 926, 926, 926, 926, 926, 
-    926, 927, 927, 927, 928, 928, 928, 928, 928, 928, 928, 928, 928, 927, 
-    929, 930, 931, 81, 81, 81, 81, 932, 932, 932, 932, 932, 932, 932, 932, 
-    933, 933, 933, 933, 933, 933, 933, 933, 934, 934, 934, 934, 934, 934, 
-    934, 934, 934, 934, 935, 935, 935, 935, 935, 935, 935, 935, 935, 81, 81, 
-    81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 936, 937, 937, 937, 937, 937, 
-    937, 937, 937, 81, 81, 937, 937, 937, 937, 937, 937, 937, 938, 938, 938, 
-    939, 939, 939, 939, 81, 81, 939, 939, 938, 938, 938, 938, 940, 937, 941, 
-    937, 938, 81, 81, 81, 942, 943, 943, 943, 943, 943, 943, 944, 944, 943, 
-    943, 942, 942, 942, 942, 942, 942, 942, 942, 942, 942, 942, 942, 942, 
-    942, 942, 942, 943, 945, 943, 943, 943, 943, 946, 942, 943, 943, 943, 
-    943, 947, 948, 949, 949, 949, 949, 947, 948, 945, 950, 951, 951, 951, 
-    951, 951, 951, 952, 952, 951, 951, 951, 950, 950, 950, 950, 950, 950, 
-    950, 950, 950, 950, 950, 950, 950, 950, 951, 951, 951, 951, 951, 951, 
-    951, 951, 951, 951, 951, 951, 951, 952, 951, 953, 954, 954, 954, 950, 
-    955, 955, 955, 954, 954, 81, 81, 81, 81, 81, 956, 956, 956, 956, 956, 
-    956, 956, 956, 956, 81, 81, 81, 81, 81, 81, 81, 957, 957, 957, 957, 957, 
-    957, 957, 957, 957, 81, 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, 
-    957, 957, 957, 958, 959, 959, 959, 959, 959, 959, 959, 81, 959, 959, 959, 
-    959, 959, 959, 958, 960, 957, 961, 961, 961, 961, 961, 81, 81, 962, 962, 
-    962, 962, 962, 962, 962, 962, 962, 962, 963, 963, 963, 963, 963, 963, 
-    963, 963, 963, 963, 963, 963, 963, 963, 963, 963, 963, 963, 963, 81, 81, 
-    81, 964, 965, 966, 966, 966, 966, 966, 966, 966, 966, 966, 966, 966, 966, 
-    966, 966, 81, 81, 967, 967, 967, 967, 967, 967, 967, 967, 967, 967, 967, 
-    967, 967, 967, 81, 968, 967, 967, 967, 967, 967, 967, 967, 968, 967, 967, 
-    968, 967, 967, 81, 969, 969, 969, 969, 969, 969, 969, 81, 969, 969, 81, 
-    969, 969, 969, 969, 969, 969, 969, 969, 969, 969, 969, 969, 969, 969, 
-    970, 970, 970, 970, 970, 970, 81, 81, 81, 970, 81, 970, 970, 81, 970, 
-    970, 970, 971, 970, 972, 972, 969, 970, 973, 973, 973, 973, 973, 973, 
-    973, 973, 973, 973, 81, 81, 81, 81, 81, 81, 974, 974, 974, 974, 974, 974, 
-    81, 974, 974, 81, 974, 974, 974, 974, 974, 974, 974, 974, 974, 974, 974, 
-    974, 974, 974, 974, 974, 975, 975, 975, 975, 975, 81, 976, 976, 81, 975, 
-    975, 976, 975, 977, 974, 81, 81, 81, 81, 81, 81, 81, 978, 978, 978, 978, 
-    978, 978, 978, 978, 978, 978, 81, 81, 81, 81, 81, 81, 979, 979, 979, 979, 
-    979, 979, 979, 979, 979, 979, 979, 980, 980, 981, 981, 982, 982, 81, 81, 
-    81, 81, 81, 81, 81, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 
-    243, 243, 243, 244, 244, 244, 244, 244, 244, 244, 244, 983, 983, 983, 
-    983, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 
-    244, 244, 244, 244, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 
-    984, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 81, 81, 81, 81, 
-    81, 81, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 986, 
-    986, 986, 81, 987, 987, 987, 987, 987, 81, 81, 81, 985, 985, 985, 985, 
-    81, 81, 81, 81, 988, 988, 988, 988, 988, 988, 988, 988, 989, 989, 989, 
-    990, 990, 990, 988, 988, 988, 988, 990, 988, 988, 988, 989, 990, 989, 
-    990, 988, 988, 988, 988, 988, 988, 988, 989, 990, 990, 988, 988, 988, 
-    988, 988, 988, 988, 988, 988, 988, 988, 81, 991, 991, 991, 991, 991, 991, 
-    991, 992, 993, 81, 81, 81, 81, 81, 81, 81, 994, 994, 994, 994, 994, 994, 
-    994, 994, 994, 994, 994, 994, 994, 994, 995, 996, 994, 994, 994, 994, 
-    994, 994, 994, 81, 610, 81, 81, 81, 81, 81, 81, 81, 997, 997, 997, 997, 
-    997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 997, 81, 998, 998, 998, 
-    998, 998, 998, 998, 998, 998, 998, 81, 81, 81, 81, 999, 999, 1000, 1000, 
-    1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 
-    81, 81, 1001, 1001, 1001, 1001, 1001, 1002, 81, 81, 1003, 1003, 1003, 
-    1003, 1003, 1003, 1003, 1003, 1004, 1004, 1004, 1004, 1004, 1004, 1004, 
-    1005, 1005, 1005, 1006, 1006, 1007, 1007, 1007, 1007, 1008, 1008, 1008, 
-    1008, 1005, 1007, 81, 81, 1009, 1009, 1009, 1009, 1009, 1009, 1009, 1009, 
-    1009, 1009, 81, 1010, 1010, 1010, 1010, 1010, 1010, 1010, 81, 1003, 1003, 
-    1003, 1003, 1003, 81, 81, 81, 81, 81, 1003, 1003, 1003, 1011, 1011, 1011, 
-    1011, 1011, 1011, 1011, 1011, 1012, 1012, 1012, 1012, 1012, 1012, 1012, 
-    1012, 1013, 1013, 1013, 1013, 1013, 1013, 1013, 1013, 1013, 1013, 1013, 
-    1013, 1013, 1013, 1013, 1014, 1014, 1015, 1015, 81, 81, 81, 81, 81, 1016, 
-    1016, 1016, 1016, 1016, 1016, 1016, 1016, 1016, 1016, 1016, 81, 81, 81, 
-    81, 1017, 1016, 1018, 1018, 1018, 1018, 1018, 1018, 1018, 1018, 1018, 
-    1018, 1018, 1018, 1018, 1018, 1018, 81, 81, 81, 81, 81, 81, 81, 1017, 
-    1017, 1017, 1017, 1019, 1019, 1019, 1019, 1019, 1019, 1019, 1019, 1019, 
-    1019, 1019, 1019, 1019, 1020, 1021, 582, 1022, 81, 81, 81, 81, 1023, 
-    1023, 1023, 1023, 1023, 1023, 1023, 1023, 1023, 1023, 1023, 81, 81, 81, 
-    81, 81, 581, 576, 576, 576, 576, 576, 576, 576, 576, 576, 576, 576, 576, 
-    576, 576, 81, 575, 575, 575, 81, 81, 81, 81, 81, 81, 81, 81, 81, 580, 
-    580, 580, 580, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 
-    1024, 1024, 1024, 81, 81, 81, 81, 1025, 1025, 1025, 1025, 1025, 1025, 
-    1025, 1025, 1025, 1025, 1025, 81, 81, 81, 81, 81, 1025, 1025, 1025, 1025, 
-    1025, 81, 81, 81, 1025, 81, 81, 81, 81, 81, 81, 81, 1025, 1025, 81, 81, 
-    1026, 1027, 1028, 1029, 505, 505, 505, 505, 81, 81, 81, 81, 318, 318, 
-    318, 318, 318, 318, 81, 81, 318, 318, 318, 318, 318, 318, 318, 81, 81, 
-    318, 318, 318, 318, 318, 318, 318, 318, 318, 318, 318, 318, 1030, 1030, 
-    453, 453, 453, 318, 318, 318, 1031, 1030, 1030, 1030, 1030, 1030, 505, 
-    505, 505, 505, 505, 505, 505, 505, 156, 156, 156, 156, 156, 156, 156, 
-    156, 318, 318, 96, 96, 96, 96, 96, 156, 156, 318, 318, 318, 318, 318, 
-    318, 96, 96, 96, 96, 318, 318, 318, 81, 81, 81, 81, 81, 81, 81, 727, 727, 
-    1032, 1032, 1032, 727, 81, 81, 621, 621, 621, 621, 81, 81, 81, 81, 621, 
-    81, 81, 81, 81, 81, 81, 81, 512, 512, 512, 512, 512, 512, 512, 512, 512, 
-    512, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 
-    49, 512, 512, 512, 512, 512, 512, 512, 512, 512, 512, 49, 49, 49, 49, 49, 
-    49, 49, 81, 49, 49, 49, 49, 49, 49, 512, 81, 512, 512, 81, 81, 512, 81, 
-    81, 512, 512, 81, 81, 512, 512, 512, 512, 81, 512, 512, 49, 49, 81, 49, 
-    81, 49, 49, 49, 49, 49, 49, 49, 81, 49, 49, 49, 49, 49, 49, 49, 512, 512, 
-    81, 512, 512, 512, 512, 81, 81, 512, 512, 512, 512, 512, 512, 512, 512, 
-    81, 512, 512, 512, 512, 512, 512, 512, 81, 49, 49, 512, 512, 81, 512, 
-    512, 512, 512, 81, 512, 512, 512, 512, 512, 81, 512, 81, 81, 81, 512, 
-    512, 512, 512, 512, 512, 512, 81, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 
-    49, 49, 81, 81, 512, 1033, 49, 49, 49, 49, 49, 49, 49, 49, 49, 498, 49, 
-    49, 49, 49, 49, 49, 512, 512, 512, 512, 512, 512, 512, 512, 512, 1033, 
-    49, 49, 49, 49, 49, 49, 49, 49, 49, 498, 49, 49, 512, 512, 512, 512, 512, 
-    1033, 49, 49, 49, 49, 49, 49, 49, 49, 49, 498, 49, 49, 49, 49, 49, 49, 
-    512, 512, 512, 512, 512, 512, 512, 512, 512, 1033, 49, 498, 49, 49, 49, 
-    49, 49, 49, 49, 49, 512, 49, 81, 81, 1034, 1034, 1034, 1034, 1034, 1034, 
-    1034, 1034, 1034, 1034, 1035, 1035, 1035, 1035, 1035, 1035, 1035, 1035, 
-    1036, 1036, 1036, 1036, 1036, 1036, 1036, 1036, 1036, 1036, 1036, 1036, 
-    1036, 1036, 1036, 1035, 1035, 1035, 1035, 1036, 1036, 1036, 1036, 1036, 
-    1036, 1036, 1036, 1036, 1036, 1035, 1035, 1035, 1035, 1035, 1035, 1035, 
-    1035, 1036, 1035, 1035, 1035, 1035, 1035, 1035, 1036, 1035, 1035, 1037, 
-    1037, 1037, 1037, 1038, 81, 81, 81, 81, 81, 81, 81, 1036, 1036, 1036, 
-    1036, 1036, 81, 1036, 1036, 1036, 1036, 1036, 1036, 1036, 1039, 1039, 
-    1039, 1039, 1039, 1039, 1039, 81, 1039, 1039, 1039, 1039, 1039, 1039, 
-    1039, 1039, 1039, 81, 81, 1039, 1039, 1039, 1039, 1039, 1039, 1039, 81, 
-    1039, 1039, 81, 1039, 1039, 1039, 1039, 1039, 81, 81, 81, 81, 81, 1040, 
-    1040, 1040, 1040, 1040, 1040, 1040, 1040, 1040, 1040, 1040, 1040, 1040, 
-    81, 81, 81, 1041, 1041, 1041, 1041, 1041, 1041, 1041, 1042, 1042, 1042, 
-    1042, 1042, 1042, 1042, 81, 81, 1043, 1043, 1043, 1043, 1043, 1043, 1043, 
-    1043, 1043, 1043, 81, 81, 81, 81, 1040, 1044, 1045, 1045, 1045, 1045, 
-    1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1046, 1046, 1046, 1046, 
-    1047, 1047, 1047, 1047, 1047, 1047, 1047, 1047, 1047, 1047, 81, 81, 81, 
-    81, 81, 1048, 1049, 1049, 1049, 1049, 1049, 1049, 1049, 1049, 1049, 1049, 
-    1049, 1049, 1049, 81, 81, 1050, 1050, 1050, 1050, 1050, 1050, 1050, 1050, 
-    1050, 1051, 1051, 1051, 1051, 1051, 1051, 1051, 81, 1052, 1052, 1052, 
-    1052, 1052, 1052, 1052, 1052, 1052, 1052, 1053, 1053, 1053, 1053, 1053, 
-    1053, 1053, 1053, 1053, 1053, 1053, 1053, 1053, 1053, 1053, 1053, 1053, 
-    1053, 1054, 1054, 1054, 1054, 1054, 1054, 1055, 1056, 81, 81, 81, 81, 
-    1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 81, 81, 81, 
-    81, 1058, 1058, 81, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 
-    1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1060, 1059, 
-    1059, 1059, 1061, 1059, 1059, 1059, 1059, 81, 81, 81, 1059, 1059, 1059, 
-    1059, 1059, 1059, 1062, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 81, 81, 
-    146, 146, 146, 146, 81, 146, 146, 146, 81, 146, 146, 81, 146, 81, 81, 
-    146, 81, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 81, 146, 146, 
-    146, 146, 81, 146, 81, 146, 81, 81, 81, 81, 81, 81, 146, 81, 81, 81, 81, 
-    146, 81, 146, 81, 146, 81, 146, 146, 146, 81, 146, 81, 146, 81, 146, 81, 
-    146, 81, 146, 146, 146, 146, 81, 146, 81, 146, 146, 81, 146, 146, 146, 
-    146, 146, 146, 146, 146, 146, 81, 81, 81, 81, 81, 146, 146, 146, 81, 146, 
-    146, 146, 132, 132, 81, 81, 81, 81, 81, 81, 531, 531, 531, 531, 527, 531, 
-    531, 531, 531, 531, 531, 531, 531, 531, 531, 531, 531, 531, 531, 531, 
-    1063, 1063, 1063, 1063, 1063, 1063, 1063, 1063, 1063, 1063, 1063, 1063, 
-    531, 531, 531, 531, 531, 531, 531, 1063, 1063, 531, 531, 531, 531, 531, 
-    531, 531, 531, 531, 531, 531, 531, 531, 531, 527, 531, 531, 531, 531, 
-    531, 531, 1063, 1063, 47, 47, 47, 521, 521, 1063, 1063, 1063, 532, 532, 
-    532, 532, 532, 532, 318, 40, 532, 532, 40, 40, 40, 1063, 1063, 1063, 532, 
-    532, 532, 532, 532, 532, 1064, 532, 532, 1064, 1064, 1064, 1064, 1064, 
-    1064, 1064, 1064, 1064, 1064, 532, 532, 532, 532, 532, 532, 532, 532, 
-    532, 532, 1063, 1063, 1063, 1063, 1063, 1063, 1063, 1063, 1063, 1065, 
-    1065, 1065, 1065, 1065, 1065, 1065, 1065, 1065, 1065, 1066, 587, 587, 
-    1063, 1063, 1063, 1063, 1063, 587, 587, 587, 587, 1063, 1063, 1063, 1063, 
-    587, 1063, 1063, 1063, 1063, 1063, 1063, 1063, 587, 587, 1063, 1063, 
-    1063, 1063, 1063, 1063, 527, 527, 527, 527, 527, 527, 1063, 1063, 527, 
-    531, 531, 531, 531, 531, 531, 531, 531, 531, 531, 531, 531, 527, 527, 
-    527, 527, 527, 527, 527, 527, 527, 531, 527, 527, 527, 527, 527, 527, 
-    531, 527, 527, 527, 527, 527, 527, 527, 538, 527, 527, 527, 527, 527, 
-    527, 531, 531, 531, 531, 531, 531, 531, 531, 40, 40, 531, 531, 527, 527, 
-    527, 527, 527, 530, 530, 527, 527, 527, 527, 527, 530, 527, 527, 527, 
-    527, 527, 538, 538, 538, 527, 527, 538, 527, 527, 538, 536, 536, 531, 
-    531, 527, 527, 531, 531, 531, 527, 531, 531, 531, 527, 527, 527, 1067, 
-    1067, 1067, 1067, 1067, 527, 527, 527, 527, 527, 527, 527, 531, 527, 531, 
-    538, 538, 527, 527, 538, 538, 538, 538, 538, 538, 538, 538, 538, 538, 
-    538, 527, 527, 527, 527, 527, 527, 527, 527, 527, 527, 527, 527, 527, 
-    538, 538, 538, 527, 527, 527, 538, 527, 527, 527, 527, 538, 538, 538, 
-    527, 538, 538, 538, 527, 527, 527, 527, 527, 527, 527, 538, 527, 538, 
-    527, 527, 527, 527, 527, 527, 530, 527, 530, 527, 530, 527, 527, 527, 
-    527, 527, 538, 527, 527, 527, 527, 530, 527, 530, 530, 527, 527, 527, 
-    527, 527, 527, 527, 527, 527, 527, 531, 531, 527, 530, 530, 530, 530, 
-    530, 530, 530, 527, 527, 527, 527, 527, 527, 527, 527, 530, 530, 530, 
-    530, 530, 530, 527, 527, 527, 527, 527, 530, 530, 530, 530, 530, 530, 
-    530, 530, 530, 530, 530, 530, 40, 40, 40, 40, 531, 527, 527, 527, 527, 
-    531, 531, 531, 531, 531, 536, 536, 531, 531, 531, 531, 538, 531, 531, 
-    531, 531, 531, 536, 531, 531, 531, 531, 538, 538, 531, 531, 531, 531, 
-    531, 40, 40, 40, 40, 40, 40, 40, 40, 531, 531, 531, 531, 40, 40, 531, 
-    527, 527, 527, 527, 527, 527, 527, 527, 527, 527, 538, 538, 538, 527, 
-    527, 527, 538, 538, 538, 538, 538, 40, 40, 40, 40, 40, 40, 540, 540, 540, 
-    1068, 1068, 1068, 40, 40, 40, 40, 527, 527, 527, 538, 527, 527, 527, 527, 
-    527, 527, 527, 527, 538, 538, 538, 527, 538, 527, 527, 527, 527, 527, 
-    531, 531, 531, 531, 531, 531, 538, 531, 531, 531, 527, 527, 527, 531, 
-    531, 527, 1063, 1063, 531, 531, 531, 527, 527, 1063, 1063, 1063, 531, 
-    531, 531, 531, 527, 527, 527, 527, 527, 527, 527, 1063, 1063, 1063, 1063, 
-    1063, 40, 40, 40, 40, 1063, 1063, 1063, 1063, 40, 40, 40, 40, 40, 531, 
-    531, 531, 531, 1063, 1063, 1063, 1063, 1063, 1063, 1063, 527, 527, 527, 
-    527, 1063, 1063, 1063, 1063, 40, 40, 1063, 1063, 1063, 1063, 1063, 1063, 
-    40, 40, 40, 40, 40, 40, 1063, 1063, 40, 40, 40, 40, 1063, 527, 527, 538, 
-    527, 527, 527, 527, 527, 527, 538, 527, 538, 538, 527, 527, 538, 538, 
-    538, 527, 527, 527, 1063, 527, 527, 527, 527, 1063, 1063, 1063, 527, 527, 
-    527, 527, 527, 527, 527, 527, 527, 1063, 1063, 527, 527, 527, 527, 527, 
-    527, 1063, 1063, 1063, 527, 527, 527, 527, 527, 527, 527, 538, 538, 527, 
-    538, 538, 527, 538, 527, 527, 527, 527, 527, 527, 527, 1063, 1063, 538, 
-    538, 538, 527, 538, 538, 538, 538, 538, 538, 538, 538, 538, 538, 538, 
-    538, 538, 527, 527, 1063, 1063, 1063, 1063, 1063, 1063, 81, 81, 594, 594, 
-    594, 594, 594, 594, 594, 595, 594, 594, 594, 594, 594, 595, 595, 595, 
-    594, 595, 595, 595, 595, 595, 595, 595, 595, 595, 595, 595, 595, 595, 81, 
-    81, 81, 505, 81, 81, 81, 81, 81, 81, 505, 505, 505, 505, 505, 505, 505, 
-    505, 673, 673, 673, 673, 673, 673, 81, 81, 
-};
-
-/* decomposition data */
-static const unsigned short decomp_data[] = {
-    0, 257, 32, 514, 32, 776, 259, 97, 514, 32, 772, 259, 50, 259, 51, 514, 
-    32, 769, 258, 956, 514, 32, 807, 259, 49, 259, 111, 772, 49, 8260, 52, 
-    772, 49, 8260, 50, 772, 51, 8260, 52, 512, 65, 768, 512, 65, 769, 512, 
-    65, 770, 512, 65, 771, 512, 65, 776, 512, 65, 778, 512, 67, 807, 512, 69, 
-    768, 512, 69, 769, 512, 69, 770, 512, 69, 776, 512, 73, 768, 512, 73, 
-    769, 512, 73, 770, 512, 73, 776, 512, 78, 771, 512, 79, 768, 512, 79, 
-    769, 512, 79, 770, 512, 79, 771, 512, 79, 776, 512, 85, 768, 512, 85, 
-    769, 512, 85, 770, 512, 85, 776, 512, 89, 769, 512, 97, 768, 512, 97, 
-    769, 512, 97, 770, 512, 97, 771, 512, 97, 776, 512, 97, 778, 512, 99, 
-    807, 512, 101, 768, 512, 101, 769, 512, 101, 770, 512, 101, 776, 512, 
-    105, 768, 512, 105, 769, 512, 105, 770, 512, 105, 776, 512, 110, 771, 
-    512, 111, 768, 512, 111, 769, 512, 111, 770, 512, 111, 771, 512, 111, 
-    776, 512, 117, 768, 512, 117, 769, 512, 117, 770, 512, 117, 776, 512, 
-    121, 769, 512, 121, 776, 512, 65, 772, 512, 97, 772, 512, 65, 774, 512, 
-    97, 774, 512, 65, 808, 512, 97, 808, 512, 67, 769, 512, 99, 769, 512, 67, 
-    770, 512, 99, 770, 512, 67, 775, 512, 99, 775, 512, 67, 780, 512, 99, 
-    780, 512, 68, 780, 512, 100, 780, 512, 69, 772, 512, 101, 772, 512, 69, 
-    774, 512, 101, 774, 512, 69, 775, 512, 101, 775, 512, 69, 808, 512, 101, 
-    808, 512, 69, 780, 512, 101, 780, 512, 71, 770, 512, 103, 770, 512, 71, 
-    774, 512, 103, 774, 512, 71, 775, 512, 103, 775, 512, 71, 807, 512, 103, 
-    807, 512, 72, 770, 512, 104, 770, 512, 73, 771, 512, 105, 771, 512, 73, 
-    772, 512, 105, 772, 512, 73, 774, 512, 105, 774, 512, 73, 808, 512, 105, 
-    808, 512, 73, 775, 514, 73, 74, 514, 105, 106, 512, 74, 770, 512, 106, 
-    770, 512, 75, 807, 512, 107, 807, 512, 76, 769, 512, 108, 769, 512, 76, 
-    807, 512, 108, 807, 512, 76, 780, 512, 108, 780, 514, 76, 183, 514, 108, 
-    183, 512, 78, 769, 512, 110, 769, 512, 78, 807, 512, 110, 807, 512, 78, 
-    780, 512, 110, 780, 514, 700, 110, 512, 79, 772, 512, 111, 772, 512, 79, 
-    774, 512, 111, 774, 512, 79, 779, 512, 111, 779, 512, 82, 769, 512, 114, 
-    769, 512, 82, 807, 512, 114, 807, 512, 82, 780, 512, 114, 780, 512, 83, 
-    769, 512, 115, 769, 512, 83, 770, 512, 115, 770, 512, 83, 807, 512, 115, 
-    807, 512, 83, 780, 512, 115, 780, 512, 84, 807, 512, 116, 807, 512, 84, 
-    780, 512, 116, 780, 512, 85, 771, 512, 117, 771, 512, 85, 772, 512, 117, 
-    772, 512, 85, 774, 512, 117, 774, 512, 85, 778, 512, 117, 778, 512, 85, 
-    779, 512, 117, 779, 512, 85, 808, 512, 117, 808, 512, 87, 770, 512, 119, 
-    770, 512, 89, 770, 512, 121, 770, 512, 89, 776, 512, 90, 769, 512, 122, 
-    769, 512, 90, 775, 512, 122, 775, 512, 90, 780, 512, 122, 780, 258, 115, 
-    512, 79, 795, 512, 111, 795, 512, 85, 795, 512, 117, 795, 514, 68, 381, 
-    514, 68, 382, 514, 100, 382, 514, 76, 74, 514, 76, 106, 514, 108, 106, 
-    514, 78, 74, 514, 78, 106, 514, 110, 106, 512, 65, 780, 512, 97, 780, 
-    512, 73, 780, 512, 105, 780, 512, 79, 780, 512, 111, 780, 512, 85, 780, 
-    512, 117, 780, 512, 220, 772, 512, 252, 772, 512, 220, 769, 512, 252, 
-    769, 512, 220, 780, 512, 252, 780, 512, 220, 768, 512, 252, 768, 512, 
-    196, 772, 512, 228, 772, 512, 550, 772, 512, 551, 772, 512, 198, 772, 
-    512, 230, 772, 512, 71, 780, 512, 103, 780, 512, 75, 780, 512, 107, 780, 
-    512, 79, 808, 512, 111, 808, 512, 490, 772, 512, 491, 772, 512, 439, 780, 
-    512, 658, 780, 512, 106, 780, 514, 68, 90, 514, 68, 122, 514, 100, 122, 
-    512, 71, 769, 512, 103, 769, 512, 78, 768, 512, 110, 768, 512, 197, 769, 
-    512, 229, 769, 512, 198, 769, 512, 230, 769, 512, 216, 769, 512, 248, 
-    769, 512, 65, 783, 512, 97, 783, 512, 65, 785, 512, 97, 785, 512, 69, 
-    783, 512, 101, 783, 512, 69, 785, 512, 101, 785, 512, 73, 783, 512, 105, 
-    783, 512, 73, 785, 512, 105, 785, 512, 79, 783, 512, 111, 783, 512, 79, 
-    785, 512, 111, 785, 512, 82, 783, 512, 114, 783, 512, 82, 785, 512, 114, 
-    785, 512, 85, 783, 512, 117, 783, 512, 85, 785, 512, 117, 785, 512, 83, 
-    806, 512, 115, 806, 512, 84, 806, 512, 116, 806, 512, 72, 780, 512, 104, 
-    780, 512, 65, 775, 512, 97, 775, 512, 69, 807, 512, 101, 807, 512, 214, 
-    772, 512, 246, 772, 512, 213, 772, 512, 245, 772, 512, 79, 775, 512, 111, 
-    775, 512, 558, 772, 512, 559, 772, 512, 89, 772, 512, 121, 772, 259, 104, 
-    259, 614, 259, 106, 259, 114, 259, 633, 259, 635, 259, 641, 259, 119, 
-    259, 121, 514, 32, 774, 514, 32, 775, 514, 32, 778, 514, 32, 808, 514, 
-    32, 771, 514, 32, 779, 259, 611, 259, 108, 259, 115, 259, 120, 259, 661, 
-    256, 768, 256, 769, 256, 787, 512, 776, 769, 256, 697, 514, 32, 837, 256, 
-    59, 514, 32, 769, 512, 168, 769, 512, 913, 769, 256, 183, 512, 917, 769, 
-    512, 919, 769, 512, 921, 769, 512, 927, 769, 512, 933, 769, 512, 937, 
-    769, 512, 970, 769, 512, 921, 776, 512, 933, 776, 512, 945, 769, 512, 
-    949, 769, 512, 951, 769, 512, 953, 769, 512, 971, 769, 512, 953, 776, 
-    512, 965, 776, 512, 959, 769, 512, 965, 769, 512, 969, 769, 258, 946, 
-    258, 952, 258, 933, 512, 978, 769, 512, 978, 776, 258, 966, 258, 960, 
-    258, 954, 258, 961, 258, 962, 258, 920, 258, 949, 258, 931, 512, 1045, 
-    768, 512, 1045, 776, 512, 1043, 769, 512, 1030, 776, 512, 1050, 769, 512, 
-    1048, 768, 512, 1059, 774, 512, 1048, 774, 512, 1080, 774, 512, 1077, 
-    768, 512, 1077, 776, 512, 1075, 769, 512, 1110, 776, 512, 1082, 769, 512, 
-    1080, 768, 512, 1091, 774, 512, 1140, 783, 512, 1141, 783, 512, 1046, 
-    774, 512, 1078, 774, 512, 1040, 774, 512, 1072, 774, 512, 1040, 776, 512, 
-    1072, 776, 512, 1045, 774, 512, 1077, 774, 512, 1240, 776, 512, 1241, 
-    776, 512, 1046, 776, 512, 1078, 776, 512, 1047, 776, 512, 1079, 776, 512, 
-    1048, 772, 512, 1080, 772, 512, 1048, 776, 512, 1080, 776, 512, 1054, 
-    776, 512, 1086, 776, 512, 1256, 776, 512, 1257, 776, 512, 1069, 776, 512, 
-    1101, 776, 512, 1059, 772, 512, 1091, 772, 512, 1059, 776, 512, 1091, 
-    776, 512, 1059, 779, 512, 1091, 779, 512, 1063, 776, 512, 1095, 776, 512, 
-    1067, 776, 512, 1099, 776, 514, 1381, 1410, 512, 1575, 1619, 512, 1575, 
-    1620, 512, 1608, 1620, 512, 1575, 1621, 512, 1610, 1620, 514, 1575, 1652, 
-    514, 1608, 1652, 514, 1735, 1652, 514, 1610, 1652, 512, 1749, 1620, 512, 
-    1729, 1620, 512, 1746, 1620, 512, 2344, 2364, 512, 2352, 2364, 512, 2355, 
-    2364, 512, 2325, 2364, 512, 2326, 2364, 512, 2327, 2364, 512, 2332, 2364, 
-    512, 2337, 2364, 512, 2338, 2364, 512, 2347, 2364, 512, 2351, 2364, 512, 
-    2503, 2494, 512, 2503, 2519, 512, 2465, 2492, 512, 2466, 2492, 512, 2479, 
-    2492, 512, 2610, 2620, 512, 2616, 2620, 512, 2582, 2620, 512, 2583, 2620, 
-    512, 2588, 2620, 512, 2603, 2620, 512, 2887, 2902, 512, 2887, 2878, 512, 
-    2887, 2903, 512, 2849, 2876, 512, 2850, 2876, 512, 2962, 3031, 512, 3014, 
-    3006, 512, 3015, 3006, 512, 3014, 3031, 512, 3142, 3158, 512, 3263, 3285, 
-    512, 3270, 3285, 512, 3270, 3286, 512, 3270, 3266, 512, 3274, 3285, 512, 
-    3398, 3390, 512, 3399, 3390, 512, 3398, 3415, 512, 3545, 3530, 512, 3545, 
-    3535, 512, 3548, 3530, 512, 3545, 3551, 514, 3661, 3634, 514, 3789, 3762, 
-    514, 3755, 3737, 514, 3755, 3745, 257, 3851, 512, 3906, 4023, 512, 3916, 
-    4023, 512, 3921, 4023, 512, 3926, 4023, 512, 3931, 4023, 512, 3904, 4021, 
-    512, 3953, 3954, 512, 3953, 3956, 512, 4018, 3968, 514, 4018, 3969, 512, 
-    4019, 3968, 514, 4019, 3969, 512, 3953, 3968, 512, 3986, 4023, 512, 3996, 
-    4023, 512, 4001, 4023, 512, 4006, 4023, 512, 4011, 4023, 512, 3984, 4021, 
-    512, 4133, 4142, 259, 4316, 512, 6917, 6965, 512, 6919, 6965, 512, 6921, 
-    6965, 512, 6923, 6965, 512, 6925, 6965, 512, 6929, 6965, 512, 6970, 6965, 
-    512, 6972, 6965, 512, 6974, 6965, 512, 6975, 6965, 512, 6978, 6965, 259, 
-    65, 259, 198, 259, 66, 259, 68, 259, 69, 259, 398, 259, 71, 259, 72, 259, 
-    73, 259, 74, 259, 75, 259, 76, 259, 77, 259, 78, 259, 79, 259, 546, 259, 
-    80, 259, 82, 259, 84, 259, 85, 259, 87, 259, 97, 259, 592, 259, 593, 259, 
-    7426, 259, 98, 259, 100, 259, 101, 259, 601, 259, 603, 259, 604, 259, 
-    103, 259, 107, 259, 109, 259, 331, 259, 111, 259, 596, 259, 7446, 259, 
-    7447, 259, 112, 259, 116, 259, 117, 259, 7453, 259, 623, 259, 118, 259, 
-    7461, 259, 946, 259, 947, 259, 948, 259, 966, 259, 967, 261, 105, 261, 
-    114, 261, 117, 261, 118, 261, 946, 261, 947, 261, 961, 261, 966, 261, 
-    967, 259, 1085, 259, 594, 259, 99, 259, 597, 259, 240, 259, 604, 259, 
-    102, 259, 607, 259, 609, 259, 613, 259, 616, 259, 617, 259, 618, 259, 
-    7547, 259, 669, 259, 621, 259, 7557, 259, 671, 259, 625, 259, 624, 259, 
-    626, 259, 627, 259, 628, 259, 629, 259, 632, 259, 642, 259, 643, 259, 
-    427, 259, 649, 259, 650, 259, 7452, 259, 651, 259, 652, 259, 122, 259, 
-    656, 259, 657, 259, 658, 259, 952, 512, 65, 805, 512, 97, 805, 512, 66, 
-    775, 512, 98, 775, 512, 66, 803, 512, 98, 803, 512, 66, 817, 512, 98, 
-    817, 512, 199, 769, 512, 231, 769, 512, 68, 775, 512, 100, 775, 512, 68, 
-    803, 512, 100, 803, 512, 68, 817, 512, 100, 817, 512, 68, 807, 512, 100, 
-    807, 512, 68, 813, 512, 100, 813, 512, 274, 768, 512, 275, 768, 512, 274, 
-    769, 512, 275, 769, 512, 69, 813, 512, 101, 813, 512, 69, 816, 512, 101, 
-    816, 512, 552, 774, 512, 553, 774, 512, 70, 775, 512, 102, 775, 512, 71, 
-    772, 512, 103, 772, 512, 72, 775, 512, 104, 775, 512, 72, 803, 512, 104, 
-    803, 512, 72, 776, 512, 104, 776, 512, 72, 807, 512, 104, 807, 512, 72, 
-    814, 512, 104, 814, 512, 73, 816, 512, 105, 816, 512, 207, 769, 512, 239, 
-    769, 512, 75, 769, 512, 107, 769, 512, 75, 803, 512, 107, 803, 512, 75, 
-    817, 512, 107, 817, 512, 76, 803, 512, 108, 803, 512, 7734, 772, 512, 
-    7735, 772, 512, 76, 817, 512, 108, 817, 512, 76, 813, 512, 108, 813, 512, 
-    77, 769, 512, 109, 769, 512, 77, 775, 512, 109, 775, 512, 77, 803, 512, 
-    109, 803, 512, 78, 775, 512, 110, 775, 512, 78, 803, 512, 110, 803, 512, 
-    78, 817, 512, 110, 817, 512, 78, 813, 512, 110, 813, 512, 213, 769, 512, 
-    245, 769, 512, 213, 776, 512, 245, 776, 512, 332, 768, 512, 333, 768, 
-    512, 332, 769, 512, 333, 769, 512, 80, 769, 512, 112, 769, 512, 80, 775, 
-    512, 112, 775, 512, 82, 775, 512, 114, 775, 512, 82, 803, 512, 114, 803, 
-    512, 7770, 772, 512, 7771, 772, 512, 82, 817, 512, 114, 817, 512, 83, 
-    775, 512, 115, 775, 512, 83, 803, 512, 115, 803, 512, 346, 775, 512, 347, 
-    775, 512, 352, 775, 512, 353, 775, 512, 7778, 775, 512, 7779, 775, 512, 
-    84, 775, 512, 116, 775, 512, 84, 803, 512, 116, 803, 512, 84, 817, 512, 
-    116, 817, 512, 84, 813, 512, 116, 813, 512, 85, 804, 512, 117, 804, 512, 
-    85, 816, 512, 117, 816, 512, 85, 813, 512, 117, 813, 512, 360, 769, 512, 
-    361, 769, 512, 362, 776, 512, 363, 776, 512, 86, 771, 512, 118, 771, 512, 
-    86, 803, 512, 118, 803, 512, 87, 768, 512, 119, 768, 512, 87, 769, 512, 
-    119, 769, 512, 87, 776, 512, 119, 776, 512, 87, 775, 512, 119, 775, 512, 
-    87, 803, 512, 119, 803, 512, 88, 775, 512, 120, 775, 512, 88, 776, 512, 
-    120, 776, 512, 89, 775, 512, 121, 775, 512, 90, 770, 512, 122, 770, 512, 
-    90, 803, 512, 122, 803, 512, 90, 817, 512, 122, 817, 512, 104, 817, 512, 
-    116, 776, 512, 119, 778, 512, 121, 778, 514, 97, 702, 512, 383, 775, 512, 
-    65, 803, 512, 97, 803, 512, 65, 777, 512, 97, 777, 512, 194, 769, 512, 
-    226, 769, 512, 194, 768, 512, 226, 768, 512, 194, 777, 512, 226, 777, 
-    512, 194, 771, 512, 226, 771, 512, 7840, 770, 512, 7841, 770, 512, 258, 
-    769, 512, 259, 769, 512, 258, 768, 512, 259, 768, 512, 258, 777, 512, 
-    259, 777, 512, 258, 771, 512, 259, 771, 512, 7840, 774, 512, 7841, 774, 
-    512, 69, 803, 512, 101, 803, 512, 69, 777, 512, 101, 777, 512, 69, 771, 
-    512, 101, 771, 512, 202, 769, 512, 234, 769, 512, 202, 768, 512, 234, 
-    768, 512, 202, 777, 512, 234, 777, 512, 202, 771, 512, 234, 771, 512, 
-    7864, 770, 512, 7865, 770, 512, 73, 777, 512, 105, 777, 512, 73, 803, 
-    512, 105, 803, 512, 79, 803, 512, 111, 803, 512, 79, 777, 512, 111, 777, 
-    512, 212, 769, 512, 244, 769, 512, 212, 768, 512, 244, 768, 512, 212, 
-    777, 512, 244, 777, 512, 212, 771, 512, 244, 771, 512, 7884, 770, 512, 
-    7885, 770, 512, 416, 769, 512, 417, 769, 512, 416, 768, 512, 417, 768, 
-    512, 416, 777, 512, 417, 777, 512, 416, 771, 512, 417, 771, 512, 416, 
-    803, 512, 417, 803, 512, 85, 803, 512, 117, 803, 512, 85, 777, 512, 117, 
-    777, 512, 431, 769, 512, 432, 769, 512, 431, 768, 512, 432, 768, 512, 
-    431, 777, 512, 432, 777, 512, 431, 771, 512, 432, 771, 512, 431, 803, 
-    512, 432, 803, 512, 89, 768, 512, 121, 768, 512, 89, 803, 512, 121, 803, 
-    512, 89, 777, 512, 121, 777, 512, 89, 771, 512, 121, 771, 512, 945, 787, 
-    512, 945, 788, 512, 7936, 768, 512, 7937, 768, 512, 7936, 769, 512, 7937, 
-    769, 512, 7936, 834, 512, 7937, 834, 512, 913, 787, 512, 913, 788, 512, 
-    7944, 768, 512, 7945, 768, 512, 7944, 769, 512, 7945, 769, 512, 7944, 
-    834, 512, 7945, 834, 512, 949, 787, 512, 949, 788, 512, 7952, 768, 512, 
-    7953, 768, 512, 7952, 769, 512, 7953, 769, 512, 917, 787, 512, 917, 788, 
-    512, 7960, 768, 512, 7961, 768, 512, 7960, 769, 512, 7961, 769, 512, 951, 
-    787, 512, 951, 788, 512, 7968, 768, 512, 7969, 768, 512, 7968, 769, 512, 
-    7969, 769, 512, 7968, 834, 512, 7969, 834, 512, 919, 787, 512, 919, 788, 
-    512, 7976, 768, 512, 7977, 768, 512, 7976, 769, 512, 7977, 769, 512, 
-    7976, 834, 512, 7977, 834, 512, 953, 787, 512, 953, 788, 512, 7984, 768, 
-    512, 7985, 768, 512, 7984, 769, 512, 7985, 769, 512, 7984, 834, 512, 
-    7985, 834, 512, 921, 787, 512, 921, 788, 512, 7992, 768, 512, 7993, 768, 
-    512, 7992, 769, 512, 7993, 769, 512, 7992, 834, 512, 7993, 834, 512, 959, 
-    787, 512, 959, 788, 512, 8000, 768, 512, 8001, 768, 512, 8000, 769, 512, 
-    8001, 769, 512, 927, 787, 512, 927, 788, 512, 8008, 768, 512, 8009, 768, 
-    512, 8008, 769, 512, 8009, 769, 512, 965, 787, 512, 965, 788, 512, 8016, 
-    768, 512, 8017, 768, 512, 8016, 769, 512, 8017, 769, 512, 8016, 834, 512, 
-    8017, 834, 512, 933, 788, 512, 8025, 768, 512, 8025, 769, 512, 8025, 834, 
-    512, 969, 787, 512, 969, 788, 512, 8032, 768, 512, 8033, 768, 512, 8032, 
-    769, 512, 8033, 769, 512, 8032, 834, 512, 8033, 834, 512, 937, 787, 512, 
-    937, 788, 512, 8040, 768, 512, 8041, 768, 512, 8040, 769, 512, 8041, 769, 
-    512, 8040, 834, 512, 8041, 834, 512, 945, 768, 256, 940, 512, 949, 768, 
-    256, 941, 512, 951, 768, 256, 942, 512, 953, 768, 256, 943, 512, 959, 
-    768, 256, 972, 512, 965, 768, 256, 973, 512, 969, 768, 256, 974, 512, 
-    7936, 837, 512, 7937, 837, 512, 7938, 837, 512, 7939, 837, 512, 7940, 
-    837, 512, 7941, 837, 512, 7942, 837, 512, 7943, 837, 512, 7944, 837, 512, 
-    7945, 837, 512, 7946, 837, 512, 7947, 837, 512, 7948, 837, 512, 7949, 
-    837, 512, 7950, 837, 512, 7951, 837, 512, 7968, 837, 512, 7969, 837, 512, 
-    7970, 837, 512, 7971, 837, 512, 7972, 837, 512, 7973, 837, 512, 7974, 
-    837, 512, 7975, 837, 512, 7976, 837, 512, 7977, 837, 512, 7978, 837, 512, 
-    7979, 837, 512, 7980, 837, 512, 7981, 837, 512, 7982, 837, 512, 7983, 
-    837, 512, 8032, 837, 512, 8033, 837, 512, 8034, 837, 512, 8035, 837, 512, 
-    8036, 837, 512, 8037, 837, 512, 8038, 837, 512, 8039, 837, 512, 8040, 
-    837, 512, 8041, 837, 512, 8042, 837, 512, 8043, 837, 512, 8044, 837, 512, 
-    8045, 837, 512, 8046, 837, 512, 8047, 837, 512, 945, 774, 512, 945, 772, 
-    512, 8048, 837, 512, 945, 837, 512, 940, 837, 512, 945, 834, 512, 8118, 
-    837, 512, 913, 774, 512, 913, 772, 512, 913, 768, 256, 902, 512, 913, 
-    837, 514, 32, 787, 256, 953, 514, 32, 787, 514, 32, 834, 512, 168, 834, 
-    512, 8052, 837, 512, 951, 837, 512, 942, 837, 512, 951, 834, 512, 8134, 
-    837, 512, 917, 768, 256, 904, 512, 919, 768, 256, 905, 512, 919, 837, 
-    512, 8127, 768, 512, 8127, 769, 512, 8127, 834, 512, 953, 774, 512, 953, 
-    772, 512, 970, 768, 256, 912, 512, 953, 834, 512, 970, 834, 512, 921, 
-    774, 512, 921, 772, 512, 921, 768, 256, 906, 512, 8190, 768, 512, 8190, 
-    769, 512, 8190, 834, 512, 965, 774, 512, 965, 772, 512, 971, 768, 256, 
-    944, 512, 961, 787, 512, 961, 788, 512, 965, 834, 512, 971, 834, 512, 
-    933, 774, 512, 933, 772, 512, 933, 768, 256, 910, 512, 929, 788, 512, 
-    168, 768, 256, 901, 256, 96, 512, 8060, 837, 512, 969, 837, 512, 974, 
-    837, 512, 969, 834, 512, 8182, 837, 512, 927, 768, 256, 908, 512, 937, 
-    768, 256, 911, 512, 937, 837, 256, 180, 514, 32, 788, 256, 8194, 256, 
-    8195, 258, 32, 258, 32, 258, 32, 258, 32, 258, 32, 257, 32, 258, 32, 258, 
-    32, 258, 32, 257, 8208, 514, 32, 819, 258, 46, 514, 46, 46, 770, 46, 46, 
-    46, 257, 32, 514, 8242, 8242, 770, 8242, 8242, 8242, 514, 8245, 8245, 
-    770, 8245, 8245, 8245, 514, 33, 33, 514, 32, 773, 514, 63, 63, 514, 63, 
-    33, 514, 33, 63, 1026, 8242, 8242, 8242, 8242, 258, 32, 259, 48, 259, 
-    105, 259, 52, 259, 53, 259, 54, 259, 55, 259, 56, 259, 57, 259, 43, 259, 
-    8722, 259, 61, 259, 40, 259, 41, 259, 110, 261, 48, 261, 49, 261, 50, 
-    261, 51, 261, 52, 261, 53, 261, 54, 261, 55, 261, 56, 261, 57, 261, 43, 
-    261, 8722, 261, 61, 261, 40, 261, 41, 261, 97, 261, 101, 261, 111, 261, 
-    120, 261, 601, 261, 104, 261, 107, 261, 108, 261, 109, 261, 110, 261, 
-    112, 261, 115, 261, 116, 514, 82, 115, 770, 97, 47, 99, 770, 97, 47, 115, 
-    262, 67, 514, 176, 67, 770, 99, 47, 111, 770, 99, 47, 117, 258, 400, 514, 
-    176, 70, 262, 103, 262, 72, 262, 72, 262, 72, 262, 104, 262, 295, 262, 
-    73, 262, 73, 262, 76, 262, 108, 262, 78, 514, 78, 111, 262, 80, 262, 81, 
-    262, 82, 262, 82, 262, 82, 515, 83, 77, 770, 84, 69, 76, 515, 84, 77, 
-    262, 90, 256, 937, 262, 90, 256, 75, 256, 197, 262, 66, 262, 67, 262, 
-    101, 262, 69, 262, 70, 262, 77, 262, 111, 258, 1488, 258, 1489, 258, 
-    1490, 258, 1491, 262, 105, 770, 70, 65, 88, 262, 960, 262, 947, 262, 915, 
-    262, 928, 262, 8721, 262, 68, 262, 100, 262, 101, 262, 105, 262, 106, 
-    772, 49, 8260, 55, 772, 49, 8260, 57, 1028, 49, 8260, 49, 48, 772, 49, 
-    8260, 51, 772, 50, 8260, 51, 772, 49, 8260, 53, 772, 50, 8260, 53, 772, 
-    51, 8260, 53, 772, 52, 8260, 53, 772, 49, 8260, 54, 772, 53, 8260, 54, 
-    772, 49, 8260, 56, 772, 51, 8260, 56, 772, 53, 8260, 56, 772, 55, 8260, 
-    56, 516, 49, 8260, 258, 73, 514, 73, 73, 770, 73, 73, 73, 514, 73, 86, 
-    258, 86, 514, 86, 73, 770, 86, 73, 73, 1026, 86, 73, 73, 73, 514, 73, 88, 
-    258, 88, 514, 88, 73, 770, 88, 73, 73, 258, 76, 258, 67, 258, 68, 258, 
-    77, 258, 105, 514, 105, 105, 770, 105, 105, 105, 514, 105, 118, 258, 118, 
-    514, 118, 105, 770, 118, 105, 105, 1026, 118, 105, 105, 105, 514, 105, 
-    120, 258, 120, 514, 120, 105, 770, 120, 105, 105, 258, 108, 258, 99, 258, 
-    100, 258, 109, 772, 48, 8260, 51, 512, 8592, 824, 512, 8594, 824, 512, 
-    8596, 824, 512, 8656, 824, 512, 8660, 824, 512, 8658, 824, 512, 8707, 
-    824, 512, 8712, 824, 512, 8715, 824, 512, 8739, 824, 512, 8741, 824, 514, 
-    8747, 8747, 770, 8747, 8747, 8747, 514, 8750, 8750, 770, 8750, 8750, 
-    8750, 512, 8764, 824, 512, 8771, 824, 512, 8773, 824, 512, 8776, 824, 
-    512, 61, 824, 512, 8801, 824, 512, 8781, 824, 512, 60, 824, 512, 62, 824, 
-    512, 8804, 824, 512, 8805, 824, 512, 8818, 824, 512, 8819, 824, 512, 
-    8822, 824, 512, 8823, 824, 512, 8826, 824, 512, 8827, 824, 512, 8834, 
-    824, 512, 8835, 824, 512, 8838, 824, 512, 8839, 824, 512, 8866, 824, 512, 
-    8872, 824, 512, 8873, 824, 512, 8875, 824, 512, 8828, 824, 512, 8829, 
-    824, 512, 8849, 824, 512, 8850, 824, 512, 8882, 824, 512, 8883, 824, 512, 
-    8884, 824, 512, 8885, 824, 256, 12296, 256, 12297, 263, 49, 263, 50, 263, 
-    51, 263, 52, 263, 53, 263, 54, 263, 55, 263, 56, 263, 57, 519, 49, 48, 
-    519, 49, 49, 519, 49, 50, 519, 49, 51, 519, 49, 52, 519, 49, 53, 519, 49, 
-    54, 519, 49, 55, 519, 49, 56, 519, 49, 57, 519, 50, 48, 770, 40, 49, 41, 
-    770, 40, 50, 41, 770, 40, 51, 41, 770, 40, 52, 41, 770, 40, 53, 41, 770, 
-    40, 54, 41, 770, 40, 55, 41, 770, 40, 56, 41, 770, 40, 57, 41, 1026, 40, 
-    49, 48, 41, 1026, 40, 49, 49, 41, 1026, 40, 49, 50, 41, 1026, 40, 49, 51, 
-    41, 1026, 40, 49, 52, 41, 1026, 40, 49, 53, 41, 1026, 40, 49, 54, 41, 
-    1026, 40, 49, 55, 41, 1026, 40, 49, 56, 41, 1026, 40, 49, 57, 41, 1026, 
-    40, 50, 48, 41, 514, 49, 46, 514, 50, 46, 514, 51, 46, 514, 52, 46, 514, 
-    53, 46, 514, 54, 46, 514, 55, 46, 514, 56, 46, 514, 57, 46, 770, 49, 48, 
-    46, 770, 49, 49, 46, 770, 49, 50, 46, 770, 49, 51, 46, 770, 49, 52, 46, 
-    770, 49, 53, 46, 770, 49, 54, 46, 770, 49, 55, 46, 770, 49, 56, 46, 770, 
-    49, 57, 46, 770, 50, 48, 46, 770, 40, 97, 41, 770, 40, 98, 41, 770, 40, 
-    99, 41, 770, 40, 100, 41, 770, 40, 101, 41, 770, 40, 102, 41, 770, 40, 
-    103, 41, 770, 40, 104, 41, 770, 40, 105, 41, 770, 40, 106, 41, 770, 40, 
-    107, 41, 770, 40, 108, 41, 770, 40, 109, 41, 770, 40, 110, 41, 770, 40, 
-    111, 41, 770, 40, 112, 41, 770, 40, 113, 41, 770, 40, 114, 41, 770, 40, 
-    115, 41, 770, 40, 116, 41, 770, 40, 117, 41, 770, 40, 118, 41, 770, 40, 
-    119, 41, 770, 40, 120, 41, 770, 40, 121, 41, 770, 40, 122, 41, 263, 65, 
-    263, 66, 263, 67, 263, 68, 263, 69, 263, 70, 263, 71, 263, 72, 263, 73, 
-    263, 74, 263, 75, 263, 76, 263, 77, 263, 78, 263, 79, 263, 80, 263, 81, 
-    263, 82, 263, 83, 263, 84, 263, 85, 263, 86, 263, 87, 263, 88, 263, 89, 
-    263, 90, 263, 97, 263, 98, 263, 99, 263, 100, 263, 101, 263, 102, 263, 
-    103, 263, 104, 263, 105, 263, 106, 263, 107, 263, 108, 263, 109, 263, 
-    110, 263, 111, 263, 112, 263, 113, 263, 114, 263, 115, 263, 116, 263, 
-    117, 263, 118, 263, 119, 263, 120, 263, 121, 263, 122, 263, 48, 1026, 
-    8747, 8747, 8747, 8747, 770, 58, 58, 61, 514, 61, 61, 770, 61, 61, 61, 
-    512, 10973, 824, 261, 106, 259, 86, 259, 11617, 258, 27597, 258, 40863, 
-    258, 19968, 258, 20008, 258, 20022, 258, 20031, 258, 20057, 258, 20101, 
-    258, 20108, 258, 20128, 258, 20154, 258, 20799, 258, 20837, 258, 20843, 
-    258, 20866, 258, 20886, 258, 20907, 258, 20960, 258, 20981, 258, 20992, 
-    258, 21147, 258, 21241, 258, 21269, 258, 21274, 258, 21304, 258, 21313, 
-    258, 21340, 258, 21353, 258, 21378, 258, 21430, 258, 21448, 258, 21475, 
-    258, 22231, 258, 22303, 258, 22763, 258, 22786, 258, 22794, 258, 22805, 
-    258, 22823, 258, 22899, 258, 23376, 258, 23424, 258, 23544, 258, 23567, 
-    258, 23586, 258, 23608, 258, 23662, 258, 23665, 258, 24027, 258, 24037, 
-    258, 24049, 258, 24062, 258, 24178, 258, 24186, 258, 24191, 258, 24308, 
-    258, 24318, 258, 24331, 258, 24339, 258, 24400, 258, 24417, 258, 24435, 
-    258, 24515, 258, 25096, 258, 25142, 258, 25163, 258, 25903, 258, 25908, 
-    258, 25991, 258, 26007, 258, 26020, 258, 26041, 258, 26080, 258, 26085, 
-    258, 26352, 258, 26376, 258, 26408, 258, 27424, 258, 27490, 258, 27513, 
-    258, 27571, 258, 27595, 258, 27604, 258, 27611, 258, 27663, 258, 27668, 
-    258, 27700, 258, 28779, 258, 29226, 258, 29238, 258, 29243, 258, 29247, 
-    258, 29255, 258, 29273, 258, 29275, 258, 29356, 258, 29572, 258, 29577, 
-    258, 29916, 258, 29926, 258, 29976, 258, 29983, 258, 29992, 258, 30000, 
-    258, 30091, 258, 30098, 258, 30326, 258, 30333, 258, 30382, 258, 30399, 
-    258, 30446, 258, 30683, 258, 30690, 258, 30707, 258, 31034, 258, 31160, 
-    258, 31166, 258, 31348, 258, 31435, 258, 31481, 258, 31859, 258, 31992, 
-    258, 32566, 258, 32593, 258, 32650, 258, 32701, 258, 32769, 258, 32780, 
-    258, 32786, 258, 32819, 258, 32895, 258, 32905, 258, 33251, 258, 33258, 
-    258, 33267, 258, 33276, 258, 33292, 258, 33307, 258, 33311, 258, 33390, 
-    258, 33394, 258, 33400, 258, 34381, 258, 34411, 258, 34880, 258, 34892, 
-    258, 34915, 258, 35198, 258, 35211, 258, 35282, 258, 35328, 258, 35895, 
-    258, 35910, 258, 35925, 258, 35960, 258, 35997, 258, 36196, 258, 36208, 
-    258, 36275, 258, 36523, 258, 36554, 258, 36763, 258, 36784, 258, 36789, 
-    258, 37009, 258, 37193, 258, 37318, 258, 37324, 258, 37329, 258, 38263, 
-    258, 38272, 258, 38428, 258, 38582, 258, 38585, 258, 38632, 258, 38737, 
-    258, 38750, 258, 38754, 258, 38761, 258, 38859, 258, 38893, 258, 38899, 
-    258, 38913, 258, 39080, 258, 39131, 258, 39135, 258, 39318, 258, 39321, 
-    258, 39340, 258, 39592, 258, 39640, 258, 39647, 258, 39717, 258, 39727, 
-    258, 39730, 258, 39740, 258, 39770, 258, 40165, 258, 40565, 258, 40575, 
-    258, 40613, 258, 40635, 258, 40643, 258, 40653, 258, 40657, 258, 40697, 
-    258, 40701, 258, 40718, 258, 40723, 258, 40736, 258, 40763, 258, 40778, 
-    258, 40786, 258, 40845, 258, 40860, 258, 40864, 264, 32, 258, 12306, 258, 
-    21313, 258, 21316, 258, 21317, 512, 12363, 12441, 512, 12365, 12441, 512, 
-    12367, 12441, 512, 12369, 12441, 512, 12371, 12441, 512, 12373, 12441, 
-    512, 12375, 12441, 512, 12377, 12441, 512, 12379, 12441, 512, 12381, 
-    12441, 512, 12383, 12441, 512, 12385, 12441, 512, 12388, 12441, 512, 
-    12390, 12441, 512, 12392, 12441, 512, 12399, 12441, 512, 12399, 12442, 
-    512, 12402, 12441, 512, 12402, 12442, 512, 12405, 12441, 512, 12405, 
-    12442, 512, 12408, 12441, 512, 12408, 12442, 512, 12411, 12441, 512, 
-    12411, 12442, 512, 12358, 12441, 514, 32, 12441, 514, 32, 12442, 512, 
-    12445, 12441, 521, 12424, 12426, 512, 12459, 12441, 512, 12461, 12441, 
-    512, 12463, 12441, 512, 12465, 12441, 512, 12467, 12441, 512, 12469, 
-    12441, 512, 12471, 12441, 512, 12473, 12441, 512, 12475, 12441, 512, 
-    12477, 12441, 512, 12479, 12441, 512, 12481, 12441, 512, 12484, 12441, 
-    512, 12486, 12441, 512, 12488, 12441, 512, 12495, 12441, 512, 12495, 
-    12442, 512, 12498, 12441, 512, 12498, 12442, 512, 12501, 12441, 512, 
-    12501, 12442, 512, 12504, 12441, 512, 12504, 12442, 512, 12507, 12441, 
-    512, 12507, 12442, 512, 12454, 12441, 512, 12527, 12441, 512, 12528, 
-    12441, 512, 12529, 12441, 512, 12530, 12441, 512, 12541, 12441, 521, 
-    12467, 12488, 258, 4352, 258, 4353, 258, 4522, 258, 4354, 258, 4524, 258, 
-    4525, 258, 4355, 258, 4356, 258, 4357, 258, 4528, 258, 4529, 258, 4530, 
-    258, 4531, 258, 4532, 258, 4533, 258, 4378, 258, 4358, 258, 4359, 258, 
-    4360, 258, 4385, 258, 4361, 258, 4362, 258, 4363, 258, 4364, 258, 4365, 
-    258, 4366, 258, 4367, 258, 4368, 258, 4369, 258, 4370, 258, 4449, 258, 
-    4450, 258, 4451, 258, 4452, 258, 4453, 258, 4454, 258, 4455, 258, 4456, 
-    258, 4457, 258, 4458, 258, 4459, 258, 4460, 258, 4461, 258, 4462, 258, 
-    4463, 258, 4464, 258, 4465, 258, 4466, 258, 4467, 258, 4468, 258, 4469, 
-    258, 4448, 258, 4372, 258, 4373, 258, 4551, 258, 4552, 258, 4556, 258, 
-    4558, 258, 4563, 258, 4567, 258, 4569, 258, 4380, 258, 4573, 258, 4575, 
-    258, 4381, 258, 4382, 258, 4384, 258, 4386, 258, 4387, 258, 4391, 258, 
-    4393, 258, 4395, 258, 4396, 258, 4397, 258, 4398, 258, 4399, 258, 4402, 
-    258, 4406, 258, 4416, 258, 4423, 258, 4428, 258, 4593, 258, 4594, 258, 
-    4439, 258, 4440, 258, 4441, 258, 4484, 258, 4485, 258, 4488, 258, 4497, 
-    258, 4498, 258, 4500, 258, 4510, 258, 4513, 259, 19968, 259, 20108, 259, 
-    19977, 259, 22235, 259, 19978, 259, 20013, 259, 19979, 259, 30002, 259, 
-    20057, 259, 19993, 259, 19969, 259, 22825, 259, 22320, 259, 20154, 770, 
-    40, 4352, 41, 770, 40, 4354, 41, 770, 40, 4355, 41, 770, 40, 4357, 41, 
-    770, 40, 4358, 41, 770, 40, 4359, 41, 770, 40, 4361, 41, 770, 40, 4363, 
-    41, 770, 40, 4364, 41, 770, 40, 4366, 41, 770, 40, 4367, 41, 770, 40, 
-    4368, 41, 770, 40, 4369, 41, 770, 40, 4370, 41, 1026, 40, 4352, 4449, 41, 
-    1026, 40, 4354, 4449, 41, 1026, 40, 4355, 4449, 41, 1026, 40, 4357, 4449, 
-    41, 1026, 40, 4358, 4449, 41, 1026, 40, 4359, 4449, 41, 1026, 40, 4361, 
-    4449, 41, 1026, 40, 4363, 4449, 41, 1026, 40, 4364, 4449, 41, 1026, 40, 
-    4366, 4449, 41, 1026, 40, 4367, 4449, 41, 1026, 40, 4368, 4449, 41, 1026, 
-    40, 4369, 4449, 41, 1026, 40, 4370, 4449, 41, 1026, 40, 4364, 4462, 41, 
-    1794, 40, 4363, 4457, 4364, 4453, 4523, 41, 1538, 40, 4363, 4457, 4370, 
-    4462, 41, 770, 40, 19968, 41, 770, 40, 20108, 41, 770, 40, 19977, 41, 
-    770, 40, 22235, 41, 770, 40, 20116, 41, 770, 40, 20845, 41, 770, 40, 
-    19971, 41, 770, 40, 20843, 41, 770, 40, 20061, 41, 770, 40, 21313, 41, 
-    770, 40, 26376, 41, 770, 40, 28779, 41, 770, 40, 27700, 41, 770, 40, 
-    26408, 41, 770, 40, 37329, 41, 770, 40, 22303, 41, 770, 40, 26085, 41, 
-    770, 40, 26666, 41, 770, 40, 26377, 41, 770, 40, 31038, 41, 770, 40, 
-    21517, 41, 770, 40, 29305, 41, 770, 40, 36001, 41, 770, 40, 31069, 41, 
-    770, 40, 21172, 41, 770, 40, 20195, 41, 770, 40, 21628, 41, 770, 40, 
-    23398, 41, 770, 40, 30435, 41, 770, 40, 20225, 41, 770, 40, 36039, 41, 
-    770, 40, 21332, 41, 770, 40, 31085, 41, 770, 40, 20241, 41, 770, 40, 
-    33258, 41, 770, 40, 33267, 41, 263, 21839, 263, 24188, 263, 25991, 263, 
-    31631, 778, 80, 84, 69, 519, 50, 49, 519, 50, 50, 519, 50, 51, 519, 50, 
-    52, 519, 50, 53, 519, 50, 54, 519, 50, 55, 519, 50, 56, 519, 50, 57, 519, 
-    51, 48, 519, 51, 49, 519, 51, 50, 519, 51, 51, 519, 51, 52, 519, 51, 53, 
-    263, 4352, 263, 4354, 263, 4355, 263, 4357, 263, 4358, 263, 4359, 263, 
-    4361, 263, 4363, 263, 4364, 263, 4366, 263, 4367, 263, 4368, 263, 4369, 
-    263, 4370, 519, 4352, 4449, 519, 4354, 4449, 519, 4355, 4449, 519, 4357, 
-    4449, 519, 4358, 4449, 519, 4359, 4449, 519, 4361, 4449, 519, 4363, 4449, 
-    519, 4364, 4449, 519, 4366, 4449, 519, 4367, 4449, 519, 4368, 4449, 519, 
-    4369, 4449, 519, 4370, 4449, 1287, 4366, 4449, 4535, 4352, 4457, 1031, 
-    4364, 4462, 4363, 4468, 519, 4363, 4462, 263, 19968, 263, 20108, 263, 
-    19977, 263, 22235, 263, 20116, 263, 20845, 263, 19971, 263, 20843, 263, 
-    20061, 263, 21313, 263, 26376, 263, 28779, 263, 27700, 263, 26408, 263, 
-    37329, 263, 22303, 263, 26085, 263, 26666, 263, 26377, 263, 31038, 263, 
-    21517, 263, 29305, 263, 36001, 263, 31069, 263, 21172, 263, 31192, 263, 
-    30007, 263, 22899, 263, 36969, 263, 20778, 263, 21360, 263, 27880, 263, 
-    38917, 263, 20241, 263, 20889, 263, 27491, 263, 19978, 263, 20013, 263, 
-    19979, 263, 24038, 263, 21491, 263, 21307, 263, 23447, 263, 23398, 263, 
-    30435, 263, 20225, 263, 36039, 263, 21332, 263, 22812, 519, 51, 54, 519, 
-    51, 55, 519, 51, 56, 519, 51, 57, 519, 52, 48, 519, 52, 49, 519, 52, 50, 
-    519, 52, 51, 519, 52, 52, 519, 52, 53, 519, 52, 54, 519, 52, 55, 519, 52, 
-    56, 519, 52, 57, 519, 53, 48, 514, 49, 26376, 514, 50, 26376, 514, 51, 
-    26376, 514, 52, 26376, 514, 53, 26376, 514, 54, 26376, 514, 55, 26376, 
-    514, 56, 26376, 514, 57, 26376, 770, 49, 48, 26376, 770, 49, 49, 26376, 
-    770, 49, 50, 26376, 522, 72, 103, 778, 101, 114, 103, 522, 101, 86, 778, 
-    76, 84, 68, 263, 12450, 263, 12452, 263, 12454, 263, 12456, 263, 12458, 
-    263, 12459, 263, 12461, 263, 12463, 263, 12465, 263, 12467, 263, 12469, 
-    263, 12471, 263, 12473, 263, 12475, 263, 12477, 263, 12479, 263, 12481, 
-    263, 12484, 263, 12486, 263, 12488, 263, 12490, 263, 12491, 263, 12492, 
-    263, 12493, 263, 12494, 263, 12495, 263, 12498, 263, 12501, 263, 12504, 
-    263, 12507, 263, 12510, 263, 12511, 263, 12512, 263, 12513, 263, 12514, 
-    263, 12516, 263, 12518, 263, 12520, 263, 12521, 263, 12522, 263, 12523, 
-    263, 12524, 263, 12525, 263, 12527, 263, 12528, 263, 12529, 263, 12530, 
-    1034, 12450, 12497, 12540, 12488, 1034, 12450, 12523, 12501, 12449, 1034, 
-    12450, 12531, 12506, 12450, 778, 12450, 12540, 12523, 1034, 12452, 12491, 
-    12531, 12464, 778, 12452, 12531, 12481, 778, 12454, 12457, 12531, 1290, 
-    12456, 12473, 12463, 12540, 12489, 1034, 12456, 12540, 12459, 12540, 778, 
-    12458, 12531, 12473, 778, 12458, 12540, 12512, 778, 12459, 12452, 12522, 
-    1034, 12459, 12521, 12483, 12488, 1034, 12459, 12525, 12522, 12540, 778, 
-    12460, 12525, 12531, 778, 12460, 12531, 12510, 522, 12462, 12460, 778, 
-    12462, 12491, 12540, 1034, 12461, 12517, 12522, 12540, 1034, 12462, 
-    12523, 12480, 12540, 522, 12461, 12525, 1290, 12461, 12525, 12464, 12521, 
-    12512, 1546, 12461, 12525, 12513, 12540, 12488, 12523, 1290, 12461, 
-    12525, 12527, 12483, 12488, 778, 12464, 12521, 12512, 1290, 12464, 12521, 
-    12512, 12488, 12531, 1290, 12463, 12523, 12476, 12452, 12525, 1034, 
-    12463, 12525, 12540, 12493, 778, 12465, 12540, 12473, 778, 12467, 12523, 
-    12490, 778, 12467, 12540, 12509, 1034, 12469, 12452, 12463, 12523, 1290, 
-    12469, 12531, 12481, 12540, 12512, 1034, 12471, 12522, 12531, 12464, 778, 
-    12475, 12531, 12481, 778, 12475, 12531, 12488, 778, 12480, 12540, 12473, 
-    522, 12487, 12471, 522, 12489, 12523, 522, 12488, 12531, 522, 12490, 
-    12494, 778, 12494, 12483, 12488, 778, 12495, 12452, 12484, 1290, 12497, 
-    12540, 12475, 12531, 12488, 778, 12497, 12540, 12484, 1034, 12496, 12540, 
-    12524, 12523, 1290, 12500, 12450, 12473, 12488, 12523, 778, 12500, 12463, 
-    12523, 522, 12500, 12467, 522, 12499, 12523, 1290, 12501, 12449, 12521, 
-    12483, 12489, 1034, 12501, 12451, 12540, 12488, 1290, 12502, 12483, 
-    12471, 12455, 12523, 778, 12501, 12521, 12531, 1290, 12504, 12463, 12479, 
-    12540, 12523, 522, 12506, 12477, 778, 12506, 12491, 12498, 778, 12504, 
-    12523, 12484, 778, 12506, 12531, 12473, 778, 12506, 12540, 12472, 778, 
-    12505, 12540, 12479, 1034, 12509, 12452, 12531, 12488, 778, 12508, 12523, 
-    12488, 522, 12507, 12531, 778, 12509, 12531, 12489, 778, 12507, 12540, 
-    12523, 778, 12507, 12540, 12531, 1034, 12510, 12452, 12463, 12525, 778, 
-    12510, 12452, 12523, 778, 12510, 12483, 12495, 778, 12510, 12523, 12463, 
-    1290, 12510, 12531, 12471, 12519, 12531, 1034, 12511, 12463, 12525, 
-    12531, 522, 12511, 12522, 1290, 12511, 12522, 12496, 12540, 12523, 522, 
-    12513, 12460, 1034, 12513, 12460, 12488, 12531, 1034, 12513, 12540, 
-    12488, 12523, 778, 12516, 12540, 12489, 778, 12516, 12540, 12523, 778, 
-    12518, 12450, 12531, 1034, 12522, 12483, 12488, 12523, 522, 12522, 12521, 
-    778, 12523, 12500, 12540, 1034, 12523, 12540, 12502, 12523, 522, 12524, 
-    12512, 1290, 12524, 12531, 12488, 12466, 12531, 778, 12527, 12483, 12488, 
-    514, 48, 28857, 514, 49, 28857, 514, 50, 28857, 514, 51, 28857, 514, 52, 
-    28857, 514, 53, 28857, 514, 54, 28857, 514, 55, 28857, 514, 56, 28857, 
-    514, 57, 28857, 770, 49, 48, 28857, 770, 49, 49, 28857, 770, 49, 50, 
-    28857, 770, 49, 51, 28857, 770, 49, 52, 28857, 770, 49, 53, 28857, 770, 
-    49, 54, 28857, 770, 49, 55, 28857, 770, 49, 56, 28857, 770, 49, 57, 
-    28857, 770, 50, 48, 28857, 770, 50, 49, 28857, 770, 50, 50, 28857, 770, 
-    50, 51, 28857, 770, 50, 52, 28857, 778, 104, 80, 97, 522, 100, 97, 522, 
-    65, 85, 778, 98, 97, 114, 522, 111, 86, 522, 112, 99, 522, 100, 109, 778, 
-    100, 109, 178, 778, 100, 109, 179, 522, 73, 85, 522, 24179, 25104, 522, 
-    26157, 21644, 522, 22823, 27491, 522, 26126, 27835, 1034, 26666, 24335, 
-    20250, 31038, 522, 112, 65, 522, 110, 65, 522, 956, 65, 522, 109, 65, 
-    522, 107, 65, 522, 75, 66, 522, 77, 66, 522, 71, 66, 778, 99, 97, 108, 
-    1034, 107, 99, 97, 108, 522, 112, 70, 522, 110, 70, 522, 956, 70, 522, 
-    956, 103, 522, 109, 103, 522, 107, 103, 522, 72, 122, 778, 107, 72, 122, 
-    778, 77, 72, 122, 778, 71, 72, 122, 778, 84, 72, 122, 522, 956, 8467, 
-    522, 109, 8467, 522, 100, 8467, 522, 107, 8467, 522, 102, 109, 522, 110, 
-    109, 522, 956, 109, 522, 109, 109, 522, 99, 109, 522, 107, 109, 778, 109, 
-    109, 178, 778, 99, 109, 178, 522, 109, 178, 778, 107, 109, 178, 778, 109, 
-    109, 179, 778, 99, 109, 179, 522, 109, 179, 778, 107, 109, 179, 778, 109, 
-    8725, 115, 1034, 109, 8725, 115, 178, 522, 80, 97, 778, 107, 80, 97, 778, 
-    77, 80, 97, 778, 71, 80, 97, 778, 114, 97, 100, 1290, 114, 97, 100, 8725, 
-    115, 1546, 114, 97, 100, 8725, 115, 178, 522, 112, 115, 522, 110, 115, 
-    522, 956, 115, 522, 109, 115, 522, 112, 86, 522, 110, 86, 522, 956, 86, 
-    522, 109, 86, 522, 107, 86, 522, 77, 86, 522, 112, 87, 522, 110, 87, 522, 
-    956, 87, 522, 109, 87, 522, 107, 87, 522, 77, 87, 522, 107, 937, 522, 77, 
-    937, 1034, 97, 46, 109, 46, 522, 66, 113, 522, 99, 99, 522, 99, 100, 
-    1034, 67, 8725, 107, 103, 778, 67, 111, 46, 522, 100, 66, 522, 71, 121, 
-    522, 104, 97, 522, 72, 80, 522, 105, 110, 522, 75, 75, 522, 75, 77, 522, 
-    107, 116, 522, 108, 109, 522, 108, 110, 778, 108, 111, 103, 522, 108, 
-    120, 522, 109, 98, 778, 109, 105, 108, 778, 109, 111, 108, 522, 80, 72, 
-    1034, 112, 46, 109, 46, 778, 80, 80, 77, 522, 80, 82, 522, 115, 114, 522, 
-    83, 118, 522, 87, 98, 778, 86, 8725, 109, 778, 65, 8725, 109, 514, 49, 
-    26085, 514, 50, 26085, 514, 51, 26085, 514, 52, 26085, 514, 53, 26085, 
-    514, 54, 26085, 514, 55, 26085, 514, 56, 26085, 514, 57, 26085, 770, 49, 
-    48, 26085, 770, 49, 49, 26085, 770, 49, 50, 26085, 770, 49, 51, 26085, 
-    770, 49, 52, 26085, 770, 49, 53, 26085, 770, 49, 54, 26085, 770, 49, 55, 
-    26085, 770, 49, 56, 26085, 770, 49, 57, 26085, 770, 50, 48, 26085, 770, 
-    50, 49, 26085, 770, 50, 50, 26085, 770, 50, 51, 26085, 770, 50, 52, 
-    26085, 770, 50, 53, 26085, 770, 50, 54, 26085, 770, 50, 55, 26085, 770, 
-    50, 56, 26085, 770, 50, 57, 26085, 770, 51, 48, 26085, 770, 51, 49, 
-    26085, 778, 103, 97, 108, 259, 1098, 259, 1100, 259, 42863, 259, 294, 
-    259, 339, 259, 42791, 259, 43831, 259, 619, 259, 43858, 256, 35912, 256, 
-    26356, 256, 36554, 256, 36040, 256, 28369, 256, 20018, 256, 21477, 256, 
-    40860, 256, 40860, 256, 22865, 256, 37329, 256, 21895, 256, 22856, 256, 
-    25078, 256, 30313, 256, 32645, 256, 34367, 256, 34746, 256, 35064, 256, 
-    37007, 256, 27138, 256, 27931, 256, 28889, 256, 29662, 256, 33853, 256, 
-    37226, 256, 39409, 256, 20098, 256, 21365, 256, 27396, 256, 29211, 256, 
-    34349, 256, 40478, 256, 23888, 256, 28651, 256, 34253, 256, 35172, 256, 
-    25289, 256, 33240, 256, 34847, 256, 24266, 256, 26391, 256, 28010, 256, 
-    29436, 256, 37070, 256, 20358, 256, 20919, 256, 21214, 256, 25796, 256, 
-    27347, 256, 29200, 256, 30439, 256, 32769, 256, 34310, 256, 34396, 256, 
-    36335, 256, 38706, 256, 39791, 256, 40442, 256, 30860, 256, 31103, 256, 
-    32160, 256, 33737, 256, 37636, 256, 40575, 256, 35542, 256, 22751, 256, 
-    24324, 256, 31840, 256, 32894, 256, 29282, 256, 30922, 256, 36034, 256, 
-    38647, 256, 22744, 256, 23650, 256, 27155, 256, 28122, 256, 28431, 256, 
-    32047, 256, 32311, 256, 38475, 256, 21202, 256, 32907, 256, 20956, 256, 
-    20940, 256, 31260, 256, 32190, 256, 33777, 256, 38517, 256, 35712, 256, 
-    25295, 256, 27138, 256, 35582, 256, 20025, 256, 23527, 256, 24594, 256, 
-    29575, 256, 30064, 256, 21271, 256, 30971, 256, 20415, 256, 24489, 256, 
-    19981, 256, 27852, 256, 25976, 256, 32034, 256, 21443, 256, 22622, 256, 
-    30465, 256, 33865, 256, 35498, 256, 27578, 256, 36784, 256, 27784, 256, 
-    25342, 256, 33509, 256, 25504, 256, 30053, 256, 20142, 256, 20841, 256, 
-    20937, 256, 26753, 256, 31975, 256, 33391, 256, 35538, 256, 37327, 256, 
-    21237, 256, 21570, 256, 22899, 256, 24300, 256, 26053, 256, 28670, 256, 
-    31018, 256, 38317, 256, 39530, 256, 40599, 256, 40654, 256, 21147, 256, 
-    26310, 256, 27511, 256, 36706, 256, 24180, 256, 24976, 256, 25088, 256, 
-    25754, 256, 28451, 256, 29001, 256, 29833, 256, 31178, 256, 32244, 256, 
-    32879, 256, 36646, 256, 34030, 256, 36899, 256, 37706, 256, 21015, 256, 
-    21155, 256, 21693, 256, 28872, 256, 35010, 256, 35498, 256, 24265, 256, 
-    24565, 256, 25467, 256, 27566, 256, 31806, 256, 29557, 256, 20196, 256, 
-    22265, 256, 23527, 256, 23994, 256, 24604, 256, 29618, 256, 29801, 256, 
-    32666, 256, 32838, 256, 37428, 256, 38646, 256, 38728, 256, 38936, 256, 
-    20363, 256, 31150, 256, 37300, 256, 38584, 256, 24801, 256, 20102, 256, 
-    20698, 256, 23534, 256, 23615, 256, 26009, 256, 27138, 256, 29134, 256, 
-    30274, 256, 34044, 256, 36988, 256, 40845, 256, 26248, 256, 38446, 256, 
-    21129, 256, 26491, 256, 26611, 256, 27969, 256, 28316, 256, 29705, 256, 
-    30041, 256, 30827, 256, 32016, 256, 39006, 256, 20845, 256, 25134, 256, 
-    38520, 256, 20523, 256, 23833, 256, 28138, 256, 36650, 256, 24459, 256, 
-    24900, 256, 26647, 256, 29575, 256, 38534, 256, 21033, 256, 21519, 256, 
-    23653, 256, 26131, 256, 26446, 256, 26792, 256, 27877, 256, 29702, 256, 
-    30178, 256, 32633, 256, 35023, 256, 35041, 256, 37324, 256, 38626, 256, 
-    21311, 256, 28346, 256, 21533, 256, 29136, 256, 29848, 256, 34298, 256, 
-    38563, 256, 40023, 256, 40607, 256, 26519, 256, 28107, 256, 33256, 256, 
-    31435, 256, 31520, 256, 31890, 256, 29376, 256, 28825, 256, 35672, 256, 
-    20160, 256, 33590, 256, 21050, 256, 20999, 256, 24230, 256, 25299, 256, 
-    31958, 256, 23429, 256, 27934, 256, 26292, 256, 36667, 256, 34892, 256, 
-    38477, 256, 35211, 256, 24275, 256, 20800, 256, 21952, 256, 22618, 256, 
-    26228, 256, 20958, 256, 29482, 256, 30410, 256, 31036, 256, 31070, 256, 
-    31077, 256, 31119, 256, 38742, 256, 31934, 256, 32701, 256, 34322, 256, 
-    35576, 256, 36920, 256, 37117, 256, 39151, 256, 39164, 256, 39208, 256, 
-    40372, 256, 37086, 256, 38583, 256, 20398, 256, 20711, 256, 20813, 256, 
-    21193, 256, 21220, 256, 21329, 256, 21917, 256, 22022, 256, 22120, 256, 
-    22592, 256, 22696, 256, 23652, 256, 23662, 256, 24724, 256, 24936, 256, 
-    24974, 256, 25074, 256, 25935, 256, 26082, 256, 26257, 256, 26757, 256, 
-    28023, 256, 28186, 256, 28450, 256, 29038, 256, 29227, 256, 29730, 256, 
-    30865, 256, 31038, 256, 31049, 256, 31048, 256, 31056, 256, 31062, 256, 
-    31069, 256, 31117, 256, 31118, 256, 31296, 256, 31361, 256, 31680, 256, 
-    32244, 256, 32265, 256, 32321, 256, 32626, 256, 32773, 256, 33261, 256, 
-    33401, 256, 33401, 256, 33879, 256, 35088, 256, 35222, 256, 35585, 256, 
-    35641, 256, 36051, 256, 36104, 256, 36790, 256, 36920, 256, 38627, 256, 
-    38911, 256, 38971, 256, 24693, 256, 55376, 57070, 256, 33304, 256, 20006, 
-    256, 20917, 256, 20840, 256, 20352, 256, 20805, 256, 20864, 256, 21191, 
-    256, 21242, 256, 21917, 256, 21845, 256, 21913, 256, 21986, 256, 22618, 
-    256, 22707, 256, 22852, 256, 22868, 256, 23138, 256, 23336, 256, 24274, 
-    256, 24281, 256, 24425, 256, 24493, 256, 24792, 256, 24910, 256, 24840, 
-    256, 24974, 256, 24928, 256, 25074, 256, 25140, 256, 25540, 256, 25628, 
-    256, 25682, 256, 25942, 256, 26228, 256, 26391, 256, 26395, 256, 26454, 
-    256, 27513, 256, 27578, 256, 27969, 256, 28379, 256, 28363, 256, 28450, 
-    256, 28702, 256, 29038, 256, 30631, 256, 29237, 256, 29359, 256, 29482, 
-    256, 29809, 256, 29958, 256, 30011, 256, 30237, 256, 30239, 256, 30410, 
-    256, 30427, 256, 30452, 256, 30538, 256, 30528, 256, 30924, 256, 31409, 
-    256, 31680, 256, 31867, 256, 32091, 256, 32244, 256, 32574, 256, 32773, 
-    256, 33618, 256, 33775, 256, 34681, 256, 35137, 256, 35206, 256, 35222, 
-    256, 35519, 256, 35576, 256, 35531, 256, 35585, 256, 35582, 256, 35565, 
-    256, 35641, 256, 35722, 256, 36104, 256, 36664, 256, 36978, 256, 37273, 
-    256, 37494, 256, 38524, 256, 38627, 256, 38742, 256, 38875, 256, 38911, 
-    256, 38923, 256, 38971, 256, 39698, 256, 40860, 256, 55370, 56394, 256, 
-    55370, 56388, 256, 55372, 57301, 256, 15261, 256, 16408, 256, 16441, 256, 
-    55380, 56905, 256, 55383, 56528, 256, 55391, 57043, 256, 40771, 256, 
-    40846, 514, 102, 102, 514, 102, 105, 514, 102, 108, 770, 102, 102, 105, 
-    770, 102, 102, 108, 514, 383, 116, 514, 115, 116, 514, 1396, 1398, 514, 
-    1396, 1381, 514, 1396, 1387, 514, 1406, 1398, 514, 1396, 1389, 512, 1497, 
-    1460, 512, 1522, 1463, 262, 1506, 262, 1488, 262, 1491, 262, 1492, 262, 
-    1499, 262, 1500, 262, 1501, 262, 1512, 262, 1514, 262, 43, 512, 1513, 
-    1473, 512, 1513, 1474, 512, 64329, 1473, 512, 64329, 1474, 512, 1488, 
-    1463, 512, 1488, 1464, 512, 1488, 1468, 512, 1489, 1468, 512, 1490, 1468, 
-    512, 1491, 1468, 512, 1492, 1468, 512, 1493, 1468, 512, 1494, 1468, 512, 
-    1496, 1468, 512, 1497, 1468, 512, 1498, 1468, 512, 1499, 1468, 512, 1500, 
-    1468, 512, 1502, 1468, 512, 1504, 1468, 512, 1505, 1468, 512, 1507, 1468, 
-    512, 1508, 1468, 512, 1510, 1468, 512, 1511, 1468, 512, 1512, 1468, 512, 
-    1513, 1468, 512, 1514, 1468, 512, 1493, 1465, 512, 1489, 1471, 512, 1499, 
-    1471, 512, 1508, 1471, 514, 1488, 1500, 267, 1649, 268, 1649, 267, 1659, 
-    268, 1659, 269, 1659, 270, 1659, 267, 1662, 268, 1662, 269, 1662, 270, 
-    1662, 267, 1664, 268, 1664, 269, 1664, 270, 1664, 267, 1658, 268, 1658, 
-    269, 1658, 270, 1658, 267, 1663, 268, 1663, 269, 1663, 270, 1663, 267, 
-    1657, 268, 1657, 269, 1657, 270, 1657, 267, 1700, 268, 1700, 269, 1700, 
-    270, 1700, 267, 1702, 268, 1702, 269, 1702, 270, 1702, 267, 1668, 268, 
-    1668, 269, 1668, 270, 1668, 267, 1667, 268, 1667, 269, 1667, 270, 1667, 
-    267, 1670, 268, 1670, 269, 1670, 270, 1670, 267, 1671, 268, 1671, 269, 
-    1671, 270, 1671, 267, 1677, 268, 1677, 267, 1676, 268, 1676, 267, 1678, 
-    268, 1678, 267, 1672, 268, 1672, 267, 1688, 268, 1688, 267, 1681, 268, 
-    1681, 267, 1705, 268, 1705, 269, 1705, 270, 1705, 267, 1711, 268, 1711, 
-    269, 1711, 270, 1711, 267, 1715, 268, 1715, 269, 1715, 270, 1715, 267, 
-    1713, 268, 1713, 269, 1713, 270, 1713, 267, 1722, 268, 1722, 267, 1723, 
-    268, 1723, 269, 1723, 270, 1723, 267, 1728, 268, 1728, 267, 1729, 268, 
-    1729, 269, 1729, 270, 1729, 267, 1726, 268, 1726, 269, 1726, 270, 1726, 
-    267, 1746, 268, 1746, 267, 1747, 268, 1747, 267, 1709, 268, 1709, 269, 
-    1709, 270, 1709, 267, 1735, 268, 1735, 267, 1734, 268, 1734, 267, 1736, 
-    268, 1736, 267, 1655, 267, 1739, 268, 1739, 267, 1733, 268, 1733, 267, 
-    1737, 268, 1737, 267, 1744, 268, 1744, 269, 1744, 270, 1744, 269, 1609, 
-    270, 1609, 523, 1574, 1575, 524, 1574, 1575, 523, 1574, 1749, 524, 1574, 
-    1749, 523, 1574, 1608, 524, 1574, 1608, 523, 1574, 1735, 524, 1574, 1735, 
-    523, 1574, 1734, 524, 1574, 1734, 523, 1574, 1736, 524, 1574, 1736, 523, 
-    1574, 1744, 524, 1574, 1744, 525, 1574, 1744, 523, 1574, 1609, 524, 1574, 
-    1609, 525, 1574, 1609, 267, 1740, 268, 1740, 269, 1740, 270, 1740, 523, 
-    1574, 1580, 523, 1574, 1581, 523, 1574, 1605, 523, 1574, 1609, 523, 1574, 
-    1610, 523, 1576, 1580, 523, 1576, 1581, 523, 1576, 1582, 523, 1576, 1605, 
-    523, 1576, 1609, 523, 1576, 1610, 523, 1578, 1580, 523, 1578, 1581, 523, 
-    1578, 1582, 523, 1578, 1605, 523, 1578, 1609, 523, 1578, 1610, 523, 1579, 
-    1580, 523, 1579, 1605, 523, 1579, 1609, 523, 1579, 1610, 523, 1580, 1581, 
-    523, 1580, 1605, 523, 1581, 1580, 523, 1581, 1605, 523, 1582, 1580, 523, 
-    1582, 1581, 523, 1582, 1605, 523, 1587, 1580, 523, 1587, 1581, 523, 1587, 
-    1582, 523, 1587, 1605, 523, 1589, 1581, 523, 1589, 1605, 523, 1590, 1580, 
-    523, 1590, 1581, 523, 1590, 1582, 523, 1590, 1605, 523, 1591, 1581, 523, 
-    1591, 1605, 523, 1592, 1605, 523, 1593, 1580, 523, 1593, 1605, 523, 1594, 
-    1580, 523, 1594, 1605, 523, 1601, 1580, 523, 1601, 1581, 523, 1601, 1582, 
-    523, 1601, 1605, 523, 1601, 1609, 523, 1601, 1610, 523, 1602, 1581, 523, 
-    1602, 1605, 523, 1602, 1609, 523, 1602, 1610, 523, 1603, 1575, 523, 1603, 
-    1580, 523, 1603, 1581, 523, 1603, 1582, 523, 1603, 1604, 523, 1603, 1605, 
-    523, 1603, 1609, 523, 1603, 1610, 523, 1604, 1580, 523, 1604, 1581, 523, 
-    1604, 1582, 523, 1604, 1605, 523, 1604, 1609, 523, 1604, 1610, 523, 1605, 
-    1580, 523, 1605, 1581, 523, 1605, 1582, 523, 1605, 1605, 523, 1605, 1609, 
-    523, 1605, 1610, 523, 1606, 1580, 523, 1606, 1581, 523, 1606, 1582, 523, 
-    1606, 1605, 523, 1606, 1609, 523, 1606, 1610, 523, 1607, 1580, 523, 1607, 
-    1605, 523, 1607, 1609, 523, 1607, 1610, 523, 1610, 1580, 523, 1610, 1581, 
-    523, 1610, 1582, 523, 1610, 1605, 523, 1610, 1609, 523, 1610, 1610, 523, 
-    1584, 1648, 523, 1585, 1648, 523, 1609, 1648, 779, 32, 1612, 1617, 779, 
-    32, 1613, 1617, 779, 32, 1614, 1617, 779, 32, 1615, 1617, 779, 32, 1616, 
-    1617, 779, 32, 1617, 1648, 524, 1574, 1585, 524, 1574, 1586, 524, 1574, 
-    1605, 524, 1574, 1606, 524, 1574, 1609, 524, 1574, 1610, 524, 1576, 1585, 
-    524, 1576, 1586, 524, 1576, 1605, 524, 1576, 1606, 524, 1576, 1609, 524, 
-    1576, 1610, 524, 1578, 1585, 524, 1578, 1586, 524, 1578, 1605, 524, 1578, 
-    1606, 524, 1578, 1609, 524, 1578, 1610, 524, 1579, 1585, 524, 1579, 1586, 
-    524, 1579, 1605, 524, 1579, 1606, 524, 1579, 1609, 524, 1579, 1610, 524, 
-    1601, 1609, 524, 1601, 1610, 524, 1602, 1609, 524, 1602, 1610, 524, 1603, 
-    1575, 524, 1603, 1604, 524, 1603, 1605, 524, 1603, 1609, 524, 1603, 1610, 
-    524, 1604, 1605, 524, 1604, 1609, 524, 1604, 1610, 524, 1605, 1575, 524, 
-    1605, 1605, 524, 1606, 1585, 524, 1606, 1586, 524, 1606, 1605, 524, 1606, 
-    1606, 524, 1606, 1609, 524, 1606, 1610, 524, 1609, 1648, 524, 1610, 1585, 
-    524, 1610, 1586, 524, 1610, 1605, 524, 1610, 1606, 524, 1610, 1609, 524, 
-    1610, 1610, 525, 1574, 1580, 525, 1574, 1581, 525, 1574, 1582, 525, 1574, 
-    1605, 525, 1574, 1607, 525, 1576, 1580, 525, 1576, 1581, 525, 1576, 1582, 
-    525, 1576, 1605, 525, 1576, 1607, 525, 1578, 1580, 525, 1578, 1581, 525, 
-    1578, 1582, 525, 1578, 1605, 525, 1578, 1607, 525, 1579, 1605, 525, 1580, 
-    1581, 525, 1580, 1605, 525, 1581, 1580, 525, 1581, 1605, 525, 1582, 1580, 
-    525, 1582, 1605, 525, 1587, 1580, 525, 1587, 1581, 525, 1587, 1582, 525, 
-    1587, 1605, 525, 1589, 1581, 525, 1589, 1582, 525, 1589, 1605, 525, 1590, 
-    1580, 525, 1590, 1581, 525, 1590, 1582, 525, 1590, 1605, 525, 1591, 1581, 
-    525, 1592, 1605, 525, 1593, 1580, 525, 1593, 1605, 525, 1594, 1580, 525, 
-    1594, 1605, 525, 1601, 1580, 525, 1601, 1581, 525, 1601, 1582, 525, 1601, 
-    1605, 525, 1602, 1581, 525, 1602, 1605, 525, 1603, 1580, 525, 1603, 1581, 
-    525, 1603, 1582, 525, 1603, 1604, 525, 1603, 1605, 525, 1604, 1580, 525, 
-    1604, 1581, 525, 1604, 1582, 525, 1604, 1605, 525, 1604, 1607, 525, 1605, 
-    1580, 525, 1605, 1581, 525, 1605, 1582, 525, 1605, 1605, 525, 1606, 1580, 
-    525, 1606, 1581, 525, 1606, 1582, 525, 1606, 1605, 525, 1606, 1607, 525, 
-    1607, 1580, 525, 1607, 1605, 525, 1607, 1648, 525, 1610, 1580, 525, 1610, 
-    1581, 525, 1610, 1582, 525, 1610, 1605, 525, 1610, 1607, 526, 1574, 1605, 
-    526, 1574, 1607, 526, 1576, 1605, 526, 1576, 1607, 526, 1578, 1605, 526, 
-    1578, 1607, 526, 1579, 1605, 526, 1579, 1607, 526, 1587, 1605, 526, 1587, 
-    1607, 526, 1588, 1605, 526, 1588, 1607, 526, 1603, 1604, 526, 1603, 1605, 
-    526, 1604, 1605, 526, 1606, 1605, 526, 1606, 1607, 526, 1610, 1605, 526, 
-    1610, 1607, 782, 1600, 1614, 1617, 782, 1600, 1615, 1617, 782, 1600, 
-    1616, 1617, 523, 1591, 1609, 523, 1591, 1610, 523, 1593, 1609, 523, 1593, 
-    1610, 523, 1594, 1609, 523, 1594, 1610, 523, 1587, 1609, 523, 1587, 1610, 
-    523, 1588, 1609, 523, 1588, 1610, 523, 1581, 1609, 523, 1581, 1610, 523, 
-    1580, 1609, 523, 1580, 1610, 523, 1582, 1609, 523, 1582, 1610, 523, 1589, 
-    1609, 523, 1589, 1610, 523, 1590, 1609, 523, 1590, 1610, 523, 1588, 1580, 
-    523, 1588, 1581, 523, 1588, 1582, 523, 1588, 1605, 523, 1588, 1585, 523, 
-    1587, 1585, 523, 1589, 1585, 523, 1590, 1585, 524, 1591, 1609, 524, 1591, 
-    1610, 524, 1593, 1609, 524, 1593, 1610, 524, 1594, 1609, 524, 1594, 1610, 
-    524, 1587, 1609, 524, 1587, 1610, 524, 1588, 1609, 524, 1588, 1610, 524, 
-    1581, 1609, 524, 1581, 1610, 524, 1580, 1609, 524, 1580, 1610, 524, 1582, 
-    1609, 524, 1582, 1610, 524, 1589, 1609, 524, 1589, 1610, 524, 1590, 1609, 
-    524, 1590, 1610, 524, 1588, 1580, 524, 1588, 1581, 524, 1588, 1582, 524, 
-    1588, 1605, 524, 1588, 1585, 524, 1587, 1585, 524, 1589, 1585, 524, 1590, 
-    1585, 525, 1588, 1580, 525, 1588, 1581, 525, 1588, 1582, 525, 1588, 1605, 
-    525, 1587, 1607, 525, 1588, 1607, 525, 1591, 1605, 526, 1587, 1580, 526, 
-    1587, 1581, 526, 1587, 1582, 526, 1588, 1580, 526, 1588, 1581, 526, 1588, 
-    1582, 526, 1591, 1605, 526, 1592, 1605, 524, 1575, 1611, 523, 1575, 1611, 
-    781, 1578, 1580, 1605, 780, 1578, 1581, 1580, 781, 1578, 1581, 1580, 781, 
-    1578, 1581, 1605, 781, 1578, 1582, 1605, 781, 1578, 1605, 1580, 781, 
-    1578, 1605, 1581, 781, 1578, 1605, 1582, 780, 1580, 1605, 1581, 781, 
-    1580, 1605, 1581, 780, 1581, 1605, 1610, 780, 1581, 1605, 1609, 781, 
-    1587, 1581, 1580, 781, 1587, 1580, 1581, 780, 1587, 1580, 1609, 780, 
-    1587, 1605, 1581, 781, 1587, 1605, 1581, 781, 1587, 1605, 1580, 780, 
-    1587, 1605, 1605, 781, 1587, 1605, 1605, 780, 1589, 1581, 1581, 781, 
-    1589, 1581, 1581, 780, 1589, 1605, 1605, 780, 1588, 1581, 1605, 781, 
-    1588, 1581, 1605, 780, 1588, 1580, 1610, 780, 1588, 1605, 1582, 781, 
-    1588, 1605, 1582, 780, 1588, 1605, 1605, 781, 1588, 1605, 1605, 780, 
-    1590, 1581, 1609, 780, 1590, 1582, 1605, 781, 1590, 1582, 1605, 780, 
-    1591, 1605, 1581, 781, 1591, 1605, 1581, 781, 1591, 1605, 1605, 780, 
-    1591, 1605, 1610, 780, 1593, 1580, 1605, 780, 1593, 1605, 1605, 781, 
-    1593, 1605, 1605, 780, 1593, 1605, 1609, 780, 1594, 1605, 1605, 780, 
-    1594, 1605, 1610, 780, 1594, 1605, 1609, 780, 1601, 1582, 1605, 781, 
-    1601, 1582, 1605, 780, 1602, 1605, 1581, 780, 1602, 1605, 1605, 780, 
-    1604, 1581, 1605, 780, 1604, 1581, 1610, 780, 1604, 1581, 1609, 781, 
-    1604, 1580, 1580, 780, 1604, 1580, 1580, 780, 1604, 1582, 1605, 781, 
-    1604, 1582, 1605, 780, 1604, 1605, 1581, 781, 1604, 1605, 1581, 781, 
-    1605, 1581, 1580, 781, 1605, 1581, 1605, 780, 1605, 1581, 1610, 781, 
-    1605, 1580, 1581, 781, 1605, 1580, 1605, 781, 1605, 1582, 1580, 781, 
-    1605, 1582, 1605, 781, 1605, 1580, 1582, 781, 1607, 1605, 1580, 781, 
-    1607, 1605, 1605, 781, 1606, 1581, 1605, 780, 1606, 1581, 1609, 780, 
-    1606, 1580, 1605, 781, 1606, 1580, 1605, 780, 1606, 1580, 1609, 780, 
-    1606, 1605, 1610, 780, 1606, 1605, 1609, 780, 1610, 1605, 1605, 781, 
-    1610, 1605, 1605, 780, 1576, 1582, 1610, 780, 1578, 1580, 1610, 780, 
-    1578, 1580, 1609, 780, 1578, 1582, 1610, 780, 1578, 1582, 1609, 780, 
-    1578, 1605, 1610, 780, 1578, 1605, 1609, 780, 1580, 1605, 1610, 780, 
-    1580, 1581, 1609, 780, 1580, 1605, 1609, 780, 1587, 1582, 1609, 780, 
-    1589, 1581, 1610, 780, 1588, 1581, 1610, 780, 1590, 1581, 1610, 780, 
-    1604, 1580, 1610, 780, 1604, 1605, 1610, 780, 1610, 1581, 1610, 780, 
-    1610, 1580, 1610, 780, 1610, 1605, 1610, 780, 1605, 1605, 1610, 780, 
-    1602, 1605, 1610, 780, 1606, 1581, 1610, 781, 1602, 1605, 1581, 781, 
-    1604, 1581, 1605, 780, 1593, 1605, 1610, 780, 1603, 1605, 1610, 781, 
-    1606, 1580, 1581, 780, 1605, 1582, 1610, 781, 1604, 1580, 1605, 780, 
-    1603, 1605, 1605, 780, 1604, 1580, 1605, 780, 1606, 1580, 1581, 780, 
-    1580, 1581, 1610, 780, 1581, 1580, 1610, 780, 1605, 1580, 1610, 780, 
-    1601, 1605, 1610, 780, 1576, 1581, 1610, 781, 1603, 1605, 1605, 781, 
-    1593, 1580, 1605, 781, 1589, 1605, 1605, 780, 1587, 1582, 1610, 780, 
-    1606, 1580, 1610, 779, 1589, 1604, 1746, 779, 1602, 1604, 1746, 1035, 
-    1575, 1604, 1604, 1607, 1035, 1575, 1603, 1576, 1585, 1035, 1605, 1581, 
-    1605, 1583, 1035, 1589, 1604, 1593, 1605, 1035, 1585, 1587, 1608, 1604, 
-    1035, 1593, 1604, 1610, 1607, 1035, 1608, 1587, 1604, 1605, 779, 1589, 
-    1604, 1609, 4619, 1589, 1604, 1609, 32, 1575, 1604, 1604, 1607, 32, 1593, 
-    1604, 1610, 1607, 32, 1608, 1587, 1604, 1605, 2059, 1580, 1604, 32, 1580, 
-    1604, 1575, 1604, 1607, 1035, 1585, 1740, 1575, 1604, 265, 44, 265, 
-    12289, 265, 12290, 265, 58, 265, 59, 265, 33, 265, 63, 265, 12310, 265, 
-    12311, 265, 8230, 265, 8229, 265, 8212, 265, 8211, 265, 95, 265, 95, 265, 
-    40, 265, 41, 265, 123, 265, 125, 265, 12308, 265, 12309, 265, 12304, 265, 
-    12305, 265, 12298, 265, 12299, 265, 12296, 265, 12297, 265, 12300, 265, 
-    12301, 265, 12302, 265, 12303, 265, 91, 265, 93, 258, 8254, 258, 8254, 
-    258, 8254, 258, 8254, 258, 95, 258, 95, 258, 95, 271, 44, 271, 12289, 
-    271, 46, 271, 59, 271, 58, 271, 63, 271, 33, 271, 8212, 271, 40, 271, 41, 
-    271, 123, 271, 125, 271, 12308, 271, 12309, 271, 35, 271, 38, 271, 42, 
-    271, 43, 271, 45, 271, 60, 271, 62, 271, 61, 271, 92, 271, 36, 271, 37, 
-    271, 64, 523, 32, 1611, 526, 1600, 1611, 523, 32, 1612, 523, 32, 1613, 
-    523, 32, 1614, 526, 1600, 1614, 523, 32, 1615, 526, 1600, 1615, 523, 32, 
-    1616, 526, 1600, 1616, 523, 32, 1617, 526, 1600, 1617, 523, 32, 1618, 
-    526, 1600, 1618, 267, 1569, 267, 1570, 268, 1570, 267, 1571, 268, 1571, 
-    267, 1572, 268, 1572, 267, 1573, 268, 1573, 267, 1574, 268, 1574, 269, 
-    1574, 270, 1574, 267, 1575, 268, 1575, 267, 1576, 268, 1576, 269, 1576, 
-    270, 1576, 267, 1577, 268, 1577, 267, 1578, 268, 1578, 269, 1578, 270, 
-    1578, 267, 1579, 268, 1579, 269, 1579, 270, 1579, 267, 1580, 268, 1580, 
-    269, 1580, 270, 1580, 267, 1581, 268, 1581, 269, 1581, 270, 1581, 267, 
-    1582, 268, 1582, 269, 1582, 270, 1582, 267, 1583, 268, 1583, 267, 1584, 
-    268, 1584, 267, 1585, 268, 1585, 267, 1586, 268, 1586, 267, 1587, 268, 
-    1587, 269, 1587, 270, 1587, 267, 1588, 268, 1588, 269, 1588, 270, 1588, 
-    267, 1589, 268, 1589, 269, 1589, 270, 1589, 267, 1590, 268, 1590, 269, 
-    1590, 270, 1590, 267, 1591, 268, 1591, 269, 1591, 270, 1591, 267, 1592, 
-    268, 1592, 269, 1592, 270, 1592, 267, 1593, 268, 1593, 269, 1593, 270, 
-    1593, 267, 1594, 268, 1594, 269, 1594, 270, 1594, 267, 1601, 268, 1601, 
-    269, 1601, 270, 1601, 267, 1602, 268, 1602, 269, 1602, 270, 1602, 267, 
-    1603, 268, 1603, 269, 1603, 270, 1603, 267, 1604, 268, 1604, 269, 1604, 
-    270, 1604, 267, 1605, 268, 1605, 269, 1605, 270, 1605, 267, 1606, 268, 
-    1606, 269, 1606, 270, 1606, 267, 1607, 268, 1607, 269, 1607, 270, 1607, 
-    267, 1608, 268, 1608, 267, 1609, 268, 1609, 267, 1610, 268, 1610, 269, 
-    1610, 270, 1610, 523, 1604, 1570, 524, 1604, 1570, 523, 1604, 1571, 524, 
-    1604, 1571, 523, 1604, 1573, 524, 1604, 1573, 523, 1604, 1575, 524, 1604, 
-    1575, 264, 33, 264, 34, 264, 35, 264, 36, 264, 37, 264, 38, 264, 39, 264, 
-    40, 264, 41, 264, 42, 264, 43, 264, 44, 264, 45, 264, 46, 264, 47, 264, 
-    48, 264, 49, 264, 50, 264, 51, 264, 52, 264, 53, 264, 54, 264, 55, 264, 
-    56, 264, 57, 264, 58, 264, 59, 264, 60, 264, 61, 264, 62, 264, 63, 264, 
-    64, 264, 65, 264, 66, 264, 67, 264, 68, 264, 69, 264, 70, 264, 71, 264, 
-    72, 264, 73, 264, 74, 264, 75, 264, 76, 264, 77, 264, 78, 264, 79, 264, 
-    80, 264, 81, 264, 82, 264, 83, 264, 84, 264, 85, 264, 86, 264, 87, 264, 
-    88, 264, 89, 264, 90, 264, 91, 264, 92, 264, 93, 264, 94, 264, 95, 264, 
-    96, 264, 97, 264, 98, 264, 99, 264, 100, 264, 101, 264, 102, 264, 103, 
-    264, 104, 264, 105, 264, 106, 264, 107, 264, 108, 264, 109, 264, 110, 
-    264, 111, 264, 112, 264, 113, 264, 114, 264, 115, 264, 116, 264, 117, 
-    264, 118, 264, 119, 264, 120, 264, 121, 264, 122, 264, 123, 264, 124, 
-    264, 125, 264, 126, 264, 10629, 264, 10630, 272, 12290, 272, 12300, 272, 
-    12301, 272, 12289, 272, 12539, 272, 12530, 272, 12449, 272, 12451, 272, 
-    12453, 272, 12455, 272, 12457, 272, 12515, 272, 12517, 272, 12519, 272, 
-    12483, 272, 12540, 272, 12450, 272, 12452, 272, 12454, 272, 12456, 272, 
-    12458, 272, 12459, 272, 12461, 272, 12463, 272, 12465, 272, 12467, 272, 
-    12469, 272, 12471, 272, 12473, 272, 12475, 272, 12477, 272, 12479, 272, 
-    12481, 272, 12484, 272, 12486, 272, 12488, 272, 12490, 272, 12491, 272, 
-    12492, 272, 12493, 272, 12494, 272, 12495, 272, 12498, 272, 12501, 272, 
-    12504, 272, 12507, 272, 12510, 272, 12511, 272, 12512, 272, 12513, 272, 
-    12514, 272, 12516, 272, 12518, 272, 12520, 272, 12521, 272, 12522, 272, 
-    12523, 272, 12524, 272, 12525, 272, 12527, 272, 12531, 272, 12441, 272, 
-    12442, 272, 12644, 272, 12593, 272, 12594, 272, 12595, 272, 12596, 272, 
-    12597, 272, 12598, 272, 12599, 272, 12600, 272, 12601, 272, 12602, 272, 
-    12603, 272, 12604, 272, 12605, 272, 12606, 272, 12607, 272, 12608, 272, 
-    12609, 272, 12610, 272, 12611, 272, 12612, 272, 12613, 272, 12614, 272, 
-    12615, 272, 12616, 272, 12617, 272, 12618, 272, 12619, 272, 12620, 272, 
-    12621, 272, 12622, 272, 12623, 272, 12624, 272, 12625, 272, 12626, 272, 
-    12627, 272, 12628, 272, 12629, 272, 12630, 272, 12631, 272, 12632, 272, 
-    12633, 272, 12634, 272, 12635, 272, 12636, 272, 12637, 272, 12638, 272, 
-    12639, 272, 12640, 272, 12641, 272, 12642, 272, 12643, 264, 162, 264, 
-    163, 264, 172, 264, 175, 264, 166, 264, 165, 264, 8361, 272, 9474, 272, 
-    8592, 272, 8593, 272, 8594, 272, 8595, 272, 9632, 272, 9675, 512, 55300, 
-    56473, 55300, 56506, 512, 55300, 56475, 55300, 56506, 512, 55300, 56485, 
-    55300, 56506, 512, 55300, 56625, 55300, 56615, 512, 55300, 56626, 55300, 
-    56615, 512, 55300, 57159, 55300, 57150, 512, 55300, 57159, 55300, 57175, 
-    512, 55301, 56505, 55301, 56506, 512, 55301, 56505, 55301, 56496, 512, 
-    55301, 56505, 55301, 56509, 512, 55301, 56760, 55301, 56751, 512, 55301, 
-    56761, 55301, 56751, 512, 55348, 56663, 55348, 56677, 512, 55348, 56664, 
-    55348, 56677, 512, 55348, 56671, 55348, 56686, 512, 55348, 56671, 55348, 
-    56687, 512, 55348, 56671, 55348, 56688, 512, 55348, 56671, 55348, 56689, 
-    512, 55348, 56671, 55348, 56690, 512, 55348, 56761, 55348, 56677, 512, 
-    55348, 56762, 55348, 56677, 512, 55348, 56763, 55348, 56686, 512, 55348, 
-    56764, 55348, 56686, 512, 55348, 56763, 55348, 56687, 512, 55348, 56764, 
-    55348, 56687, 262, 65, 262, 66, 262, 67, 262, 68, 262, 69, 262, 70, 262, 
-    71, 262, 72, 262, 73, 262, 74, 262, 75, 262, 76, 262, 77, 262, 78, 262, 
-    79, 262, 80, 262, 81, 262, 82, 262, 83, 262, 84, 262, 85, 262, 86, 262, 
-    87, 262, 88, 262, 89, 262, 90, 262, 97, 262, 98, 262, 99, 262, 100, 262, 
-    101, 262, 102, 262, 103, 262, 104, 262, 105, 262, 106, 262, 107, 262, 
-    108, 262, 109, 262, 110, 262, 111, 262, 112, 262, 113, 262, 114, 262, 
-    115, 262, 116, 262, 117, 262, 118, 262, 119, 262, 120, 262, 121, 262, 
-    122, 262, 65, 262, 66, 262, 67, 262, 68, 262, 69, 262, 70, 262, 71, 262, 
-    72, 262, 73, 262, 74, 262, 75, 262, 76, 262, 77, 262, 78, 262, 79, 262, 
-    80, 262, 81, 262, 82, 262, 83, 262, 84, 262, 85, 262, 86, 262, 87, 262, 
-    88, 262, 89, 262, 90, 262, 97, 262, 98, 262, 99, 262, 100, 262, 101, 262, 
-    102, 262, 103, 262, 105, 262, 106, 262, 107, 262, 108, 262, 109, 262, 
-    110, 262, 111, 262, 112, 262, 113, 262, 114, 262, 115, 262, 116, 262, 
-    117, 262, 118, 262, 119, 262, 120, 262, 121, 262, 122, 262, 65, 262, 66, 
-    262, 67, 262, 68, 262, 69, 262, 70, 262, 71, 262, 72, 262, 73, 262, 74, 
-    262, 75, 262, 76, 262, 77, 262, 78, 262, 79, 262, 80, 262, 81, 262, 82, 
-    262, 83, 262, 84, 262, 85, 262, 86, 262, 87, 262, 88, 262, 89, 262, 90, 
-    262, 97, 262, 98, 262, 99, 262, 100, 262, 101, 262, 102, 262, 103, 262, 
-    104, 262, 105, 262, 106, 262, 107, 262, 108, 262, 109, 262, 110, 262, 
-    111, 262, 112, 262, 113, 262, 114, 262, 115, 262, 116, 262, 117, 262, 
-    118, 262, 119, 262, 120, 262, 121, 262, 122, 262, 65, 262, 67, 262, 68, 
-    262, 71, 262, 74, 262, 75, 262, 78, 262, 79, 262, 80, 262, 81, 262, 83, 
-    262, 84, 262, 85, 262, 86, 262, 87, 262, 88, 262, 89, 262, 90, 262, 97, 
-    262, 98, 262, 99, 262, 100, 262, 102, 262, 104, 262, 105, 262, 106, 262, 
-    107, 262, 108, 262, 109, 262, 110, 262, 112, 262, 113, 262, 114, 262, 
-    115, 262, 116, 262, 117, 262, 118, 262, 119, 262, 120, 262, 121, 262, 
-    122, 262, 65, 262, 66, 262, 67, 262, 68, 262, 69, 262, 70, 262, 71, 262, 
-    72, 262, 73, 262, 74, 262, 75, 262, 76, 262, 77, 262, 78, 262, 79, 262, 
-    80, 262, 81, 262, 82, 262, 83, 262, 84, 262, 85, 262, 86, 262, 87, 262, 
-    88, 262, 89, 262, 90, 262, 97, 262, 98, 262, 99, 262, 100, 262, 101, 262, 
-    102, 262, 103, 262, 104, 262, 105, 262, 106, 262, 107, 262, 108, 262, 
-    109, 262, 110, 262, 111, 262, 112, 262, 113, 262, 114, 262, 115, 262, 
-    116, 262, 117, 262, 118, 262, 119, 262, 120, 262, 121, 262, 122, 262, 65, 
-    262, 66, 262, 68, 262, 69, 262, 70, 262, 71, 262, 74, 262, 75, 262, 76, 
-    262, 77, 262, 78, 262, 79, 262, 80, 262, 81, 262, 83, 262, 84, 262, 85, 
-    262, 86, 262, 87, 262, 88, 262, 89, 262, 97, 262, 98, 262, 99, 262, 100, 
-    262, 101, 262, 102, 262, 103, 262, 104, 262, 105, 262, 106, 262, 107, 
-    262, 108, 262, 109, 262, 110, 262, 111, 262, 112, 262, 113, 262, 114, 
-    262, 115, 262, 116, 262, 117, 262, 118, 262, 119, 262, 120, 262, 121, 
-    262, 122, 262, 65, 262, 66, 262, 68, 262, 69, 262, 70, 262, 71, 262, 73, 
-    262, 74, 262, 75, 262, 76, 262, 77, 262, 79, 262, 83, 262, 84, 262, 85, 
-    262, 86, 262, 87, 262, 88, 262, 89, 262, 97, 262, 98, 262, 99, 262, 100, 
-    262, 101, 262, 102, 262, 103, 262, 104, 262, 105, 262, 106, 262, 107, 
-    262, 108, 262, 109, 262, 110, 262, 111, 262, 112, 262, 113, 262, 114, 
-    262, 115, 262, 116, 262, 117, 262, 118, 262, 119, 262, 120, 262, 121, 
-    262, 122, 262, 65, 262, 66, 262, 67, 262, 68, 262, 69, 262, 70, 262, 71, 
-    262, 72, 262, 73, 262, 74, 262, 75, 262, 76, 262, 77, 262, 78, 262, 79, 
-    262, 80, 262, 81, 262, 82, 262, 83, 262, 84, 262, 85, 262, 86, 262, 87, 
-    262, 88, 262, 89, 262, 90, 262, 97, 262, 98, 262, 99, 262, 100, 262, 101, 
-    262, 102, 262, 103, 262, 104, 262, 105, 262, 106, 262, 107, 262, 108, 
-    262, 109, 262, 110, 262, 111, 262, 112, 262, 113, 262, 114, 262, 115, 
-    262, 116, 262, 117, 262, 118, 262, 119, 262, 120, 262, 121, 262, 122, 
-    262, 65, 262, 66, 262, 67, 262, 68, 262, 69, 262, 70, 262, 71, 262, 72, 
-    262, 73, 262, 74, 262, 75, 262, 76, 262, 77, 262, 78, 262, 79, 262, 80, 
-    262, 81, 262, 82, 262, 83, 262, 84, 262, 85, 262, 86, 262, 87, 262, 88, 
-    262, 89, 262, 90, 262, 97, 262, 98, 262, 99, 262, 100, 262, 101, 262, 
-    102, 262, 103, 262, 104, 262, 105, 262, 106, 262, 107, 262, 108, 262, 
-    109, 262, 110, 262, 111, 262, 112, 262, 113, 262, 114, 262, 115, 262, 
-    116, 262, 117, 262, 118, 262, 119, 262, 120, 262, 121, 262, 122, 262, 65, 
-    262, 66, 262, 67, 262, 68, 262, 69, 262, 70, 262, 71, 262, 72, 262, 73, 
-    262, 74, 262, 75, 262, 76, 262, 77, 262, 78, 262, 79, 262, 80, 262, 81, 
-    262, 82, 262, 83, 262, 84, 262, 85, 262, 86, 262, 87, 262, 88, 262, 89, 
-    262, 90, 262, 97, 262, 98, 262, 99, 262, 100, 262, 101, 262, 102, 262, 
-    103, 262, 104, 262, 105, 262, 106, 262, 107, 262, 108, 262, 109, 262, 
-    110, 262, 111, 262, 112, 262, 113, 262, 114, 262, 115, 262, 116, 262, 
-    117, 262, 118, 262, 119, 262, 120, 262, 121, 262, 122, 262, 65, 262, 66, 
-    262, 67, 262, 68, 262, 69, 262, 70, 262, 71, 262, 72, 262, 73, 262, 74, 
-    262, 75, 262, 76, 262, 77, 262, 78, 262, 79, 262, 80, 262, 81, 262, 82, 
-    262, 83, 262, 84, 262, 85, 262, 86, 262, 87, 262, 88, 262, 89, 262, 90, 
-    262, 97, 262, 98, 262, 99, 262, 100, 262, 101, 262, 102, 262, 103, 262, 
-    104, 262, 105, 262, 106, 262, 107, 262, 108, 262, 109, 262, 110, 262, 
-    111, 262, 112, 262, 113, 262, 114, 262, 115, 262, 116, 262, 117, 262, 
-    118, 262, 119, 262, 120, 262, 121, 262, 122, 262, 65, 262, 66, 262, 67, 
-    262, 68, 262, 69, 262, 70, 262, 71, 262, 72, 262, 73, 262, 74, 262, 75, 
-    262, 76, 262, 77, 262, 78, 262, 79, 262, 80, 262, 81, 262, 82, 262, 83, 
-    262, 84, 262, 85, 262, 86, 262, 87, 262, 88, 262, 89, 262, 90, 262, 97, 
-    262, 98, 262, 99, 262, 100, 262, 101, 262, 102, 262, 103, 262, 104, 262, 
-    105, 262, 106, 262, 107, 262, 108, 262, 109, 262, 110, 262, 111, 262, 
-    112, 262, 113, 262, 114, 262, 115, 262, 116, 262, 117, 262, 118, 262, 
-    119, 262, 120, 262, 121, 262, 122, 262, 65, 262, 66, 262, 67, 262, 68, 
-    262, 69, 262, 70, 262, 71, 262, 72, 262, 73, 262, 74, 262, 75, 262, 76, 
-    262, 77, 262, 78, 262, 79, 262, 80, 262, 81, 262, 82, 262, 83, 262, 84, 
-    262, 85, 262, 86, 262, 87, 262, 88, 262, 89, 262, 90, 262, 97, 262, 98, 
-    262, 99, 262, 100, 262, 101, 262, 102, 262, 103, 262, 104, 262, 105, 262, 
-    106, 262, 107, 262, 108, 262, 109, 262, 110, 262, 111, 262, 112, 262, 
-    113, 262, 114, 262, 115, 262, 116, 262, 117, 262, 118, 262, 119, 262, 
-    120, 262, 121, 262, 122, 262, 305, 262, 567, 262, 913, 262, 914, 262, 
-    915, 262, 916, 262, 917, 262, 918, 262, 919, 262, 920, 262, 921, 262, 
-    922, 262, 923, 262, 924, 262, 925, 262, 926, 262, 927, 262, 928, 262, 
-    929, 262, 1012, 262, 931, 262, 932, 262, 933, 262, 934, 262, 935, 262, 
-    936, 262, 937, 262, 8711, 262, 945, 262, 946, 262, 947, 262, 948, 262, 
-    949, 262, 950, 262, 951, 262, 952, 262, 953, 262, 954, 262, 955, 262, 
-    956, 262, 957, 262, 958, 262, 959, 262, 960, 262, 961, 262, 962, 262, 
-    963, 262, 964, 262, 965, 262, 966, 262, 967, 262, 968, 262, 969, 262, 
-    8706, 262, 1013, 262, 977, 262, 1008, 262, 981, 262, 1009, 262, 982, 262, 
-    913, 262, 914, 262, 915, 262, 916, 262, 917, 262, 918, 262, 919, 262, 
-    920, 262, 921, 262, 922, 262, 923, 262, 924, 262, 925, 262, 926, 262, 
-    927, 262, 928, 262, 929, 262, 1012, 262, 931, 262, 932, 262, 933, 262, 
-    934, 262, 935, 262, 936, 262, 937, 262, 8711, 262, 945, 262, 946, 262, 
-    947, 262, 948, 262, 949, 262, 950, 262, 951, 262, 952, 262, 953, 262, 
-    954, 262, 955, 262, 956, 262, 957, 262, 958, 262, 959, 262, 960, 262, 
-    961, 262, 962, 262, 963, 262, 964, 262, 965, 262, 966, 262, 967, 262, 
-    968, 262, 969, 262, 8706, 262, 1013, 262, 977, 262, 1008, 262, 981, 262, 
-    1009, 262, 982, 262, 913, 262, 914, 262, 915, 262, 916, 262, 917, 262, 
-    918, 262, 919, 262, 920, 262, 921, 262, 922, 262, 923, 262, 924, 262, 
-    925, 262, 926, 262, 927, 262, 928, 262, 929, 262, 1012, 262, 931, 262, 
-    932, 262, 933, 262, 934, 262, 935, 262, 936, 262, 937, 262, 8711, 262, 
-    945, 262, 946, 262, 947, 262, 948, 262, 949, 262, 950, 262, 951, 262, 
-    952, 262, 953, 262, 954, 262, 955, 262, 956, 262, 957, 262, 958, 262, 
-    959, 262, 960, 262, 961, 262, 962, 262, 963, 262, 964, 262, 965, 262, 
-    966, 262, 967, 262, 968, 262, 969, 262, 8706, 262, 1013, 262, 977, 262, 
-    1008, 262, 981, 262, 1009, 262, 982, 262, 913, 262, 914, 262, 915, 262, 
-    916, 262, 917, 262, 918, 262, 919, 262, 920, 262, 921, 262, 922, 262, 
-    923, 262, 924, 262, 925, 262, 926, 262, 927, 262, 928, 262, 929, 262, 
-    1012, 262, 931, 262, 932, 262, 933, 262, 934, 262, 935, 262, 936, 262, 
-    937, 262, 8711, 262, 945, 262, 946, 262, 947, 262, 948, 262, 949, 262, 
-    950, 262, 951, 262, 952, 262, 953, 262, 954, 262, 955, 262, 956, 262, 
-    957, 262, 958, 262, 959, 262, 960, 262, 961, 262, 962, 262, 963, 262, 
-    964, 262, 965, 262, 966, 262, 967, 262, 968, 262, 969, 262, 8706, 262, 
-    1013, 262, 977, 262, 1008, 262, 981, 262, 1009, 262, 982, 262, 913, 262, 
-    914, 262, 915, 262, 916, 262, 917, 262, 918, 262, 919, 262, 920, 262, 
-    921, 262, 922, 262, 923, 262, 924, 262, 925, 262, 926, 262, 927, 262, 
-    928, 262, 929, 262, 1012, 262, 931, 262, 932, 262, 933, 262, 934, 262, 
-    935, 262, 936, 262, 937, 262, 8711, 262, 945, 262, 946, 262, 947, 262, 
-    948, 262, 949, 262, 950, 262, 951, 262, 952, 262, 953, 262, 954, 262, 
-    955, 262, 956, 262, 957, 262, 958, 262, 959, 262, 960, 262, 961, 262, 
-    962, 262, 963, 262, 964, 262, 965, 262, 966, 262, 967, 262, 968, 262, 
-    969, 262, 8706, 262, 1013, 262, 977, 262, 1008, 262, 981, 262, 1009, 262, 
-    982, 262, 988, 262, 989, 262, 48, 262, 49, 262, 50, 262, 51, 262, 52, 
-    262, 53, 262, 54, 262, 55, 262, 56, 262, 57, 262, 48, 262, 49, 262, 50, 
-    262, 51, 262, 52, 262, 53, 262, 54, 262, 55, 262, 56, 262, 57, 262, 48, 
-    262, 49, 262, 50, 262, 51, 262, 52, 262, 53, 262, 54, 262, 55, 262, 56, 
-    262, 57, 262, 48, 262, 49, 262, 50, 262, 51, 262, 52, 262, 53, 262, 54, 
-    262, 55, 262, 56, 262, 57, 262, 48, 262, 49, 262, 50, 262, 51, 262, 52, 
-    262, 53, 262, 54, 262, 55, 262, 56, 262, 57, 262, 1575, 262, 1576, 262, 
-    1580, 262, 1583, 262, 1608, 262, 1586, 262, 1581, 262, 1591, 262, 1610, 
-    262, 1603, 262, 1604, 262, 1605, 262, 1606, 262, 1587, 262, 1593, 262, 
-    1601, 262, 1589, 262, 1602, 262, 1585, 262, 1588, 262, 1578, 262, 1579, 
-    262, 1582, 262, 1584, 262, 1590, 262, 1592, 262, 1594, 262, 1646, 262, 
-    1722, 262, 1697, 262, 1647, 262, 1576, 262, 1580, 262, 1607, 262, 1581, 
-    262, 1610, 262, 1603, 262, 1604, 262, 1605, 262, 1606, 262, 1587, 262, 
-    1593, 262, 1601, 262, 1589, 262, 1602, 262, 1588, 262, 1578, 262, 1579, 
-    262, 1582, 262, 1590, 262, 1594, 262, 1580, 262, 1581, 262, 1610, 262, 
-    1604, 262, 1606, 262, 1587, 262, 1593, 262, 1589, 262, 1602, 262, 1588, 
-    262, 1582, 262, 1590, 262, 1594, 262, 1722, 262, 1647, 262, 1576, 262, 
-    1580, 262, 1607, 262, 1581, 262, 1591, 262, 1610, 262, 1603, 262, 1605, 
-    262, 1606, 262, 1587, 262, 1593, 262, 1601, 262, 1589, 262, 1602, 262, 
-    1588, 262, 1578, 262, 1579, 262, 1582, 262, 1590, 262, 1592, 262, 1594, 
-    262, 1646, 262, 1697, 262, 1575, 262, 1576, 262, 1580, 262, 1583, 262, 
-    1607, 262, 1608, 262, 1586, 262, 1581, 262, 1591, 262, 1610, 262, 1604, 
-    262, 1605, 262, 1606, 262, 1587, 262, 1593, 262, 1601, 262, 1589, 262, 
-    1602, 262, 1585, 262, 1588, 262, 1578, 262, 1579, 262, 1582, 262, 1584, 
-    262, 1590, 262, 1592, 262, 1594, 262, 1576, 262, 1580, 262, 1583, 262, 
-    1608, 262, 1586, 262, 1581, 262, 1591, 262, 1610, 262, 1604, 262, 1605, 
-    262, 1606, 262, 1587, 262, 1593, 262, 1601, 262, 1589, 262, 1602, 262, 
-    1585, 262, 1588, 262, 1578, 262, 1579, 262, 1582, 262, 1584, 262, 1590, 
-    262, 1592, 262, 1594, 514, 48, 46, 514, 48, 44, 514, 49, 44, 514, 50, 44, 
-    514, 51, 44, 514, 52, 44, 514, 53, 44, 514, 54, 44, 514, 55, 44, 514, 56, 
-    44, 514, 57, 44, 770, 40, 65, 41, 770, 40, 66, 41, 770, 40, 67, 41, 770, 
-    40, 68, 41, 770, 40, 69, 41, 770, 40, 70, 41, 770, 40, 71, 41, 770, 40, 
-    72, 41, 770, 40, 73, 41, 770, 40, 74, 41, 770, 40, 75, 41, 770, 40, 76, 
-    41, 770, 40, 77, 41, 770, 40, 78, 41, 770, 40, 79, 41, 770, 40, 80, 41, 
-    770, 40, 81, 41, 770, 40, 82, 41, 770, 40, 83, 41, 770, 40, 84, 41, 770, 
-    40, 85, 41, 770, 40, 86, 41, 770, 40, 87, 41, 770, 40, 88, 41, 770, 40, 
-    89, 41, 770, 40, 90, 41, 770, 12308, 83, 12309, 263, 67, 263, 82, 519, 
-    67, 68, 519, 87, 90, 266, 65, 266, 66, 266, 67, 266, 68, 266, 69, 266, 
-    70, 266, 71, 266, 72, 266, 73, 266, 74, 266, 75, 266, 76, 266, 77, 266, 
-    78, 266, 79, 266, 80, 266, 81, 266, 82, 266, 83, 266, 84, 266, 85, 266, 
-    86, 266, 87, 266, 88, 266, 89, 266, 90, 522, 72, 86, 522, 77, 86, 522, 
-    83, 68, 522, 83, 83, 778, 80, 80, 86, 522, 87, 67, 515, 77, 67, 515, 77, 
-    68, 515, 77, 82, 522, 68, 74, 522, 12411, 12363, 522, 12467, 12467, 266, 
-    12469, 266, 25163, 266, 23383, 266, 21452, 266, 12487, 266, 20108, 266, 
-    22810, 266, 35299, 266, 22825, 266, 20132, 266, 26144, 266, 28961, 266, 
-    26009, 266, 21069, 266, 24460, 266, 20877, 266, 26032, 266, 21021, 266, 
-    32066, 266, 29983, 266, 36009, 266, 22768, 266, 21561, 266, 28436, 266, 
-    25237, 266, 25429, 266, 19968, 266, 19977, 266, 36938, 266, 24038, 266, 
-    20013, 266, 21491, 266, 25351, 266, 36208, 266, 25171, 266, 31105, 266, 
-    31354, 266, 21512, 266, 28288, 266, 26377, 266, 26376, 266, 30003, 266, 
-    21106, 266, 21942, 266, 37197, 770, 12308, 26412, 12309, 770, 12308, 
-    19977, 12309, 770, 12308, 20108, 12309, 770, 12308, 23433, 12309, 770, 
-    12308, 28857, 12309, 770, 12308, 25171, 12309, 770, 12308, 30423, 12309, 
-    770, 12308, 21213, 12309, 770, 12308, 25943, 12309, 263, 24471, 263, 
-    21487, 256, 20029, 256, 20024, 256, 20033, 256, 55360, 56610, 256, 20320, 
-    256, 20398, 256, 20411, 256, 20482, 256, 20602, 256, 20633, 256, 20711, 
-    256, 20687, 256, 13470, 256, 55361, 56890, 256, 20813, 256, 20820, 256, 
-    20836, 256, 20855, 256, 55361, 56604, 256, 13497, 256, 20839, 256, 20877, 
-    256, 55361, 56651, 256, 20887, 256, 20900, 256, 20172, 256, 20908, 256, 
-    20917, 256, 55396, 56799, 256, 20981, 256, 20995, 256, 13535, 256, 21051, 
-    256, 21062, 256, 21106, 256, 21111, 256, 13589, 256, 21191, 256, 21193, 
-    256, 21220, 256, 21242, 256, 21253, 256, 21254, 256, 21271, 256, 21321, 
-    256, 21329, 256, 21338, 256, 21363, 256, 21373, 256, 21375, 256, 21375, 
-    256, 21375, 256, 55362, 56876, 256, 28784, 256, 21450, 256, 21471, 256, 
-    55362, 57187, 256, 21483, 256, 21489, 256, 21510, 256, 21662, 256, 21560, 
-    256, 21576, 256, 21608, 256, 21666, 256, 21750, 256, 21776, 256, 21843, 
-    256, 21859, 256, 21892, 256, 21892, 256, 21913, 256, 21931, 256, 21939, 
-    256, 21954, 256, 22294, 256, 22022, 256, 22295, 256, 22097, 256, 22132, 
-    256, 20999, 256, 22766, 256, 22478, 256, 22516, 256, 22541, 256, 22411, 
-    256, 22578, 256, 22577, 256, 22700, 256, 55365, 56548, 256, 22770, 256, 
-    22775, 256, 22790, 256, 22810, 256, 22818, 256, 22882, 256, 55365, 57000, 
-    256, 55365, 57066, 256, 23020, 256, 23067, 256, 23079, 256, 23000, 256, 
-    23142, 256, 14062, 256, 14076, 256, 23304, 256, 23358, 256, 23358, 256, 
-    55366, 56776, 256, 23491, 256, 23512, 256, 23527, 256, 23539, 256, 55366, 
-    57112, 256, 23551, 256, 23558, 256, 24403, 256, 23586, 256, 14209, 256, 
-    23648, 256, 23662, 256, 23744, 256, 23693, 256, 55367, 56804, 256, 23875, 
-    256, 55367, 56806, 256, 23918, 256, 23915, 256, 23932, 256, 24033, 256, 
-    24034, 256, 14383, 256, 24061, 256, 24104, 256, 24125, 256, 24169, 256, 
-    14434, 256, 55368, 56707, 256, 14460, 256, 24240, 256, 24243, 256, 24246, 
-    256, 24266, 256, 55400, 57234, 256, 24318, 256, 55368, 57137, 256, 55368, 
-    57137, 256, 33281, 256, 24354, 256, 24354, 256, 14535, 256, 55372, 57016, 
-    256, 55384, 56794, 256, 24418, 256, 24427, 256, 14563, 256, 24474, 256, 
-    24525, 256, 24535, 256, 24569, 256, 24705, 256, 14650, 256, 14620, 256, 
-    24724, 256, 55369, 57044, 256, 24775, 256, 24904, 256, 24908, 256, 24910, 
-    256, 24908, 256, 24954, 256, 24974, 256, 25010, 256, 24996, 256, 25007, 
-    256, 25054, 256, 25074, 256, 25078, 256, 25104, 256, 25115, 256, 25181, 
-    256, 25265, 256, 25300, 256, 25424, 256, 55370, 57100, 256, 25405, 256, 
-    25340, 256, 25448, 256, 25475, 256, 25572, 256, 55370, 57329, 256, 25634, 
-    256, 25541, 256, 25513, 256, 14894, 256, 25705, 256, 25726, 256, 25757, 
-    256, 25719, 256, 14956, 256, 25935, 256, 25964, 256, 55372, 56330, 256, 
-    26083, 256, 26360, 256, 26185, 256, 15129, 256, 26257, 256, 15112, 256, 
-    15076, 256, 20882, 256, 20885, 256, 26368, 256, 26268, 256, 32941, 256, 
-    17369, 256, 26391, 256, 26395, 256, 26401, 256, 26462, 256, 26451, 256, 
-    55372, 57283, 256, 15177, 256, 26618, 256, 26501, 256, 26706, 256, 26757, 
-    256, 55373, 56429, 256, 26766, 256, 26655, 256, 26900, 256, 15261, 256, 
-    26946, 256, 27043, 256, 27114, 256, 27304, 256, 55373, 56995, 256, 27355, 
-    256, 15384, 256, 27425, 256, 55374, 56487, 256, 27476, 256, 15438, 256, 
-    27506, 256, 27551, 256, 27578, 256, 27579, 256, 55374, 56973, 256, 55367, 
-    56587, 256, 55374, 57082, 256, 27726, 256, 55375, 56508, 256, 27839, 256, 
-    27853, 256, 27751, 256, 27926, 256, 27966, 256, 28023, 256, 27969, 256, 
-    28009, 256, 28024, 256, 28037, 256, 55375, 56606, 256, 27956, 256, 28207, 
-    256, 28270, 256, 15667, 256, 28363, 256, 28359, 256, 55375, 57041, 256, 
-    28153, 256, 28526, 256, 55375, 57182, 256, 55375, 57230, 256, 28614, 256, 
-    28729, 256, 28702, 256, 28699, 256, 15766, 256, 28746, 256, 28797, 256, 
-    28791, 256, 28845, 256, 55361, 56613, 256, 28997, 256, 55376, 56931, 256, 
-    29084, 256, 55376, 57259, 256, 29224, 256, 29237, 256, 29264, 256, 55377, 
-    56840, 256, 29312, 256, 29333, 256, 55377, 57141, 256, 55378, 56340, 256, 
-    29562, 256, 29579, 256, 16044, 256, 29605, 256, 16056, 256, 16056, 256, 
-    29767, 256, 29788, 256, 29809, 256, 29829, 256, 29898, 256, 16155, 256, 
-    29988, 256, 55379, 56374, 256, 30014, 256, 55379, 56466, 256, 30064, 256, 
-    55368, 56735, 256, 30224, 256, 55379, 57249, 256, 55379, 57272, 256, 
-    55380, 56388, 256, 16380, 256, 16392, 256, 30452, 256, 55380, 56563, 256, 
-    55380, 56562, 256, 55380, 56601, 256, 55380, 56627, 256, 30494, 256, 
-    30495, 256, 30495, 256, 30538, 256, 16441, 256, 30603, 256, 16454, 256, 
-    16534, 256, 55381, 56349, 256, 30798, 256, 30860, 256, 30924, 256, 16611, 
-    256, 55381, 56870, 256, 31062, 256, 55381, 56986, 256, 55381, 57029, 256, 
-    31119, 256, 31211, 256, 16687, 256, 31296, 256, 31306, 256, 31311, 256, 
-    55382, 56700, 256, 55382, 56999, 256, 55382, 56999, 256, 31470, 256, 
-    16898, 256, 55382, 57259, 256, 31686, 256, 31689, 256, 16935, 256, 55383, 
-    56448, 256, 31954, 256, 17056, 256, 31976, 256, 31971, 256, 32000, 256, 
-    55383, 57222, 256, 32099, 256, 17153, 256, 32199, 256, 32258, 256, 32325, 
-    256, 17204, 256, 55384, 56872, 256, 55384, 56903, 256, 17241, 256, 55384, 
-    57049, 256, 32634, 256, 55384, 57150, 256, 32661, 256, 32762, 256, 32773, 
-    256, 55385, 56538, 256, 55385, 56611, 256, 32864, 256, 55385, 56744, 256, 
-    32880, 256, 55372, 57183, 256, 17365, 256, 32946, 256, 33027, 256, 17419, 
-    256, 33086, 256, 23221, 256, 55385, 57255, 256, 55385, 57269, 256, 55372, 
-    57235, 256, 55372, 57244, 256, 33281, 256, 33284, 256, 36766, 256, 17515, 
-    256, 33425, 256, 33419, 256, 33437, 256, 21171, 256, 33457, 256, 33459, 
-    256, 33469, 256, 33510, 256, 55386, 57148, 256, 33509, 256, 33565, 256, 
-    33635, 256, 33709, 256, 33571, 256, 33725, 256, 33767, 256, 33879, 256, 
-    33619, 256, 33738, 256, 33740, 256, 33756, 256, 55387, 56374, 256, 55387, 
-    56683, 256, 55387, 56533, 256, 17707, 256, 34033, 256, 34035, 256, 34070, 
-    256, 55388, 57290, 256, 34148, 256, 55387, 57132, 256, 17757, 256, 17761, 
-    256, 55387, 57265, 256, 55388, 56530, 256, 17771, 256, 34384, 256, 34396, 
-    256, 34407, 256, 34409, 256, 34473, 256, 34440, 256, 34574, 256, 34530, 
-    256, 34681, 256, 34600, 256, 34667, 256, 34694, 256, 17879, 256, 34785, 
-    256, 34817, 256, 17913, 256, 34912, 256, 34915, 256, 55389, 56935, 256, 
-    35031, 256, 35038, 256, 17973, 256, 35066, 256, 13499, 256, 55390, 56494, 
-    256, 55390, 56678, 256, 18110, 256, 18119, 256, 35488, 256, 35565, 256, 
-    35722, 256, 35925, 256, 55391, 56488, 256, 36011, 256, 36033, 256, 36123, 
-    256, 36215, 256, 55391, 57135, 256, 55362, 56324, 256, 36299, 256, 36284, 
-    256, 36336, 256, 55362, 56542, 256, 36564, 256, 36664, 256, 55393, 56786, 
-    256, 55393, 56813, 256, 37012, 256, 37105, 256, 37137, 256, 55393, 57134, 
-    256, 37147, 256, 37432, 256, 37591, 256, 37592, 256, 37500, 256, 37881, 
-    256, 37909, 256, 55394, 57338, 256, 38283, 256, 18837, 256, 38327, 256, 
-    55395, 56695, 256, 18918, 256, 38595, 256, 23986, 256, 38691, 256, 55396, 
-    56645, 256, 55396, 56858, 256, 19054, 256, 19062, 256, 38880, 256, 55397, 
-    56330, 256, 19122, 256, 55397, 56470, 256, 38923, 256, 38923, 256, 38953, 
-    256, 55397, 56758, 256, 39138, 256, 19251, 256, 39209, 256, 39335, 256, 
-    39362, 256, 39422, 256, 19406, 256, 55398, 57136, 256, 39698, 256, 40000, 
-    256, 40189, 256, 19662, 256, 19693, 256, 40295, 256, 55400, 56526, 256, 
-    19704, 256, 55400, 56581, 256, 55400, 56846, 256, 55400, 56977, 256, 
-    40635, 256, 19798, 256, 40697, 256, 40702, 256, 40709, 256, 40719, 256, 
-    40726, 256, 40763, 256, 55401, 56832, 
-};
-
-/* index tables for the decomposition data */
-#define DECOMP_SHIFT1 6
-#define DECOMP_SHIFT2 4
-static const unsigned char decomp_index0[] = {
-    0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
-    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 13, 14, 5, 5, 5, 5, 
-    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 15, 16, 5, 5, 5, 5, 17, 18, 
-    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
-    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 19, 20, 
-    5, 5, 5, 5, 5, 21, 22, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
-    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
-    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
-    23, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
-    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
-    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
-    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
-    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
-    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
-    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
-    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
-    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
-    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
-    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
-    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
-    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
-    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
-    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
-    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
-    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
-    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
-    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
-    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
-    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
-    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
-    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
-    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
-    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
-    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
-    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
-    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
-    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
-    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
-    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
-    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
-    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
-    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
-    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
-    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
-    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
-    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
-};
-
-static const unsigned short decomp_index1[] = {
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 
-    14, 0, 0, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 0, 0, 0, 0, 0, 0, 0, 
-    25, 0, 26, 27, 0, 0, 0, 0, 0, 28, 0, 0, 29, 30, 31, 32, 33, 34, 35, 0, 
-    36, 37, 38, 0, 39, 0, 40, 0, 41, 0, 0, 0, 0, 42, 43, 44, 45, 0, 0, 0, 0, 
-    0, 0, 0, 0, 46, 0, 0, 0, 0, 0, 0, 0, 0, 0, 47, 0, 0, 0, 0, 48, 0, 0, 0, 
-    0, 49, 50, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 51, 52, 0, 53, 0, 0, 0, 0, 
-    0, 0, 54, 55, 0, 0, 0, 0, 0, 56, 0, 57, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 58, 59, 0, 0, 0, 60, 0, 0, 61, 0, 0, 0, 0, 0, 0, 0, 62, 0, 0, 0, 
-    0, 0, 0, 0, 63, 0, 0, 0, 0, 0, 0, 0, 64, 0, 0, 0, 0, 0, 0, 0, 0, 65, 0, 
-    0, 0, 0, 0, 66, 0, 0, 0, 0, 0, 0, 0, 67, 0, 68, 0, 0, 69, 0, 0, 0, 70, 
-    71, 72, 73, 74, 75, 76, 77, 0, 0, 0, 0, 0, 0, 78, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 79, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 80, 81, 0, 
-    82, 83, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 84, 85, 86, 87, 88, 89, 0, 90, 91, 92, 0, 0, 0, 0, 
-    93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 
-    109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 
-    123, 124, 125, 126, 127, 128, 129, 130, 0, 131, 132, 133, 134, 0, 0, 0, 
-    0, 0, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 0, 146, 0, 
-    0, 0, 147, 0, 148, 149, 150, 0, 151, 152, 153, 0, 154, 0, 0, 0, 155, 0, 
-    0, 0, 156, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 157, 
-    158, 159, 160, 161, 162, 163, 164, 165, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 166, 0, 
-    0, 0, 0, 0, 0, 167, 0, 0, 0, 0, 0, 168, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 169, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 170, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    171, 0, 0, 0, 0, 0, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 
-    182, 183, 184, 185, 186, 0, 0, 187, 0, 0, 188, 189, 190, 191, 192, 0, 
-    193, 194, 195, 196, 197, 0, 198, 0, 0, 0, 199, 200, 201, 202, 203, 204, 
-    205, 0, 0, 0, 0, 0, 0, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 
-    216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 
-    230, 231, 232, 233, 234, 235, 236, 237, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 238, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 239, 0, 0, 
-    0, 0, 0, 0, 0, 240, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 241, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 242, 243, 244, 245, 246, 247, 
-    248, 249, 250, 251, 252, 253, 254, 255, 256, 257, 258, 259, 260, 261, 
-    262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 0, 0, 272, 273, 274, 
-    275, 276, 277, 278, 279, 280, 281, 282, 283, 0, 284, 285, 286, 287, 288, 
-    289, 290, 291, 292, 293, 294, 295, 296, 297, 298, 299, 300, 301, 302, 
-    303, 304, 305, 306, 0, 307, 308, 309, 310, 311, 312, 313, 314, 0, 0, 315, 
-    0, 316, 0, 317, 318, 319, 320, 321, 322, 323, 324, 325, 326, 327, 328, 
-    329, 330, 331, 332, 333, 334, 335, 336, 337, 338, 339, 340, 341, 342, 
-    343, 344, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 345, 346, 0, 0, 0, 0, 0, 0, 0, 
-    347, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 348, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 349, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 350, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 351, 352, 0, 0, 0, 0, 353, 354, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 355, 356, 357, 358, 359, 360, 361, 362, 363, 364, 
-    365, 366, 367, 368, 369, 370, 371, 372, 373, 374, 375, 376, 377, 378, 
-    379, 380, 381, 382, 383, 384, 385, 386, 387, 388, 389, 390, 391, 392, 
-    393, 394, 395, 396, 397, 398, 399, 400, 401, 402, 403, 404, 405, 406, 
-    407, 408, 409, 410, 411, 412, 413, 414, 415, 416, 417, 418, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 419, 420, 421, 422, 423, 424, 425, 426, 427, 428, 429, 430, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 431, 432, 433, 434, 435, 0, 436, 0, 
-    0, 437, 0, 0, 0, 0, 0, 0, 438, 439, 440, 441, 442, 443, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 444, 445, 
-    446, 447, 448, 449, 450, 451, 452, 453, 454, 455, 456, 457, 458, 459, 
-    460, 461, 462, 463, 464, 465, 466, 467, 468, 469, 470, 471, 472, 473, 
-    474, 475, 476, 477, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-};
-
-static const unsigned short decomp_index2[] = {
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 
-    3, 0, 6, 0, 0, 0, 0, 8, 0, 0, 11, 13, 15, 18, 0, 0, 20, 23, 25, 0, 27, 
-    31, 35, 0, 39, 42, 45, 48, 51, 54, 0, 57, 60, 63, 66, 69, 72, 75, 78, 81, 
-    0, 84, 87, 90, 93, 96, 99, 0, 0, 102, 105, 108, 111, 114, 0, 0, 117, 120, 
-    123, 126, 129, 132, 0, 135, 138, 141, 144, 147, 150, 153, 156, 159, 0, 
-    162, 165, 168, 171, 174, 177, 0, 0, 180, 183, 186, 189, 192, 0, 195, 198, 
-    201, 204, 207, 210, 213, 216, 219, 222, 225, 228, 231, 234, 237, 240, 
-    243, 0, 0, 246, 249, 252, 255, 258, 261, 264, 267, 270, 273, 276, 279, 
-    282, 285, 288, 291, 294, 297, 300, 303, 0, 0, 306, 309, 312, 315, 318, 
-    321, 324, 327, 330, 0, 333, 336, 339, 342, 345, 348, 0, 351, 354, 357, 
-    360, 363, 366, 369, 372, 0, 0, 375, 378, 381, 384, 387, 390, 393, 0, 0, 
-    396, 399, 402, 405, 408, 411, 0, 0, 414, 417, 420, 423, 426, 429, 432, 
-    435, 438, 441, 444, 447, 450, 453, 456, 459, 462, 465, 0, 0, 468, 471, 
-    474, 477, 480, 483, 486, 489, 492, 495, 498, 501, 504, 507, 510, 513, 
-    516, 519, 522, 525, 528, 531, 534, 537, 539, 542, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 545, 548, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 551, 554, 557, 560, 563, 566, 569, 572, 575, 578, 581, 584, 587, 
-    590, 593, 596, 599, 602, 605, 608, 611, 614, 617, 620, 623, 0, 626, 629, 
-    632, 635, 638, 641, 0, 0, 644, 647, 650, 653, 656, 659, 662, 665, 668, 
-    671, 674, 677, 680, 683, 686, 689, 0, 0, 692, 695, 698, 701, 704, 707, 
-    710, 713, 716, 719, 722, 725, 728, 731, 734, 737, 740, 743, 746, 749, 
-    752, 755, 758, 761, 764, 767, 770, 773, 776, 779, 782, 785, 788, 791, 
-    794, 797, 0, 0, 800, 803, 0, 0, 0, 0, 0, 0, 806, 809, 812, 815, 818, 821, 
-    824, 827, 830, 833, 836, 839, 842, 845, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 848, 850, 852, 854, 856, 858, 860, 862, 864, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 866, 869, 872, 875, 878, 881, 0, 0, 884, 886, 888, 
-    890, 892, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 894, 896, 0, 898, 900, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 903, 0, 0, 0, 0, 0, 905, 0, 0, 0, 
-    908, 0, 0, 0, 0, 0, 910, 913, 916, 919, 921, 924, 927, 0, 930, 0, 933, 
-    936, 939, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 942, 945, 948, 951, 954, 957, 960, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 963, 966, 969, 972, 975, 
-    0, 978, 980, 982, 984, 987, 990, 992, 0, 0, 0, 0, 0, 0, 0, 0, 0, 994, 
-    996, 998, 0, 1000, 1002, 0, 0, 0, 1004, 0, 0, 0, 0, 0, 0, 1006, 1009, 0, 
-    1012, 0, 0, 0, 1015, 0, 0, 0, 0, 1018, 1021, 1024, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 1027, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1030, 0, 0, 
-    0, 0, 0, 0, 1033, 1036, 0, 1039, 0, 0, 0, 1042, 0, 0, 0, 0, 1045, 1048, 
-    1051, 0, 0, 0, 0, 0, 0, 0, 1054, 1057, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1060, 
-    1063, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1066, 1069, 1072, 1075, 0, 
-    0, 1078, 1081, 0, 0, 1084, 1087, 1090, 1093, 1096, 1099, 0, 0, 1102, 
-    1105, 1108, 1111, 1114, 1117, 0, 0, 1120, 1123, 1126, 1129, 1132, 1135, 
-    1138, 1141, 1144, 1147, 1150, 1153, 0, 0, 1156, 1159, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 1162, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1165, 1168, 
-    1171, 1174, 1177, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1180, 1183, 
-    1186, 1189, 0, 0, 0, 0, 0, 0, 0, 1192, 0, 1195, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 1198, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 1201, 0, 0, 0, 0, 0, 0, 0, 1204, 0, 0, 1207, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1210, 1213, 1216, 
-    1219, 1222, 1225, 1228, 1231, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1234, 
-    1237, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1240, 1243, 0, 1246, 
-    0, 0, 0, 1249, 0, 0, 1252, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 1255, 1258, 1261, 0, 0, 1264, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1267, 
-    0, 0, 1270, 1273, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1276, 
-    1279, 0, 0, 0, 0, 0, 0, 1282, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 1285, 1288, 1291, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    1294, 0, 0, 0, 0, 0, 0, 0, 1297, 0, 0, 0, 0, 0, 0, 1300, 1303, 0, 1306, 
-    1309, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1312, 1315, 1318, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1321, 0, 1324, 1327, 1330, 0, 0, 0, 0, 
-    1333, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1336, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1339, 1342, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1345, 0, 0, 0, 0, 0, 0, 1347, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 1350, 0, 0, 0, 0, 1353, 0, 0, 0, 0, 1356, 0, 0, 
-    0, 0, 1359, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1362, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 1365, 0, 1368, 1371, 1374, 1377, 1380, 0, 0, 0, 0, 0, 0, 0, 
-    1383, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1386, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 1389, 0, 0, 0, 0, 1392, 0, 0, 0, 0, 1395, 0, 0, 0, 0, 
-    1398, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1401, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 1404, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 1407, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1409, 0, 1412, 0, 1415, 0, 
-    1418, 0, 1421, 0, 0, 0, 1424, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1427, 0, 1430, 0, 0, 1433, 1436, 0, 1439, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    1442, 1444, 1446, 0, 1448, 1450, 1452, 1454, 1456, 1458, 1460, 1462, 
-    1464, 1466, 1468, 0, 1470, 1472, 1474, 1476, 1478, 1480, 1482, 1484, 
-    1486, 1488, 1490, 1492, 1494, 1496, 1498, 1500, 1502, 1504, 0, 1506, 
-    1508, 1510, 1512, 1514, 1516, 1518, 1520, 1522, 1524, 1526, 1528, 1530, 
-    1532, 1534, 1536, 1538, 1540, 1542, 1544, 1546, 1548, 1550, 1552, 1554, 
-    1556, 1558, 1560, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1562, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1564, 1566, 1568, 1570, 
-    1572, 1574, 1576, 1578, 1580, 1582, 1584, 1586, 1588, 1590, 1592, 1594, 
-    1596, 1598, 1600, 1602, 1604, 1606, 1608, 1610, 1612, 1614, 1616, 1618, 
-    1620, 1622, 1624, 1626, 1628, 1630, 1632, 1634, 1636, 1638, 1641, 1644, 
-    1647, 1650, 1653, 1656, 1659, 1662, 1665, 1668, 1671, 1674, 1677, 1680, 
-    1683, 1686, 1689, 1692, 1695, 1698, 1701, 1704, 1707, 1710, 1713, 1716, 
-    1719, 1722, 1725, 1728, 1731, 1734, 1737, 1740, 1743, 1746, 1749, 1752, 
-    1755, 1758, 1761, 1764, 1767, 1770, 1773, 1776, 1779, 1782, 1785, 1788, 
-    1791, 1794, 1797, 1800, 1803, 1806, 1809, 1812, 1815, 1818, 1821, 1824, 
-    1827, 1830, 1833, 1836, 1839, 1842, 1845, 1848, 1851, 1854, 1857, 1860, 
-    1863, 1866, 1869, 1872, 1875, 1878, 1881, 1884, 1887, 1890, 1893, 1896, 
-    1899, 1902, 1905, 1908, 1911, 1914, 1917, 1920, 1923, 1926, 1929, 1932, 
-    1935, 1938, 1941, 1944, 1947, 1950, 1953, 1956, 1959, 1962, 1965, 1968, 
-    1971, 1974, 1977, 1980, 1983, 1986, 1989, 1992, 1995, 1998, 2001, 2004, 
-    2007, 2010, 2013, 2016, 2019, 2022, 2025, 2028, 2031, 2034, 2037, 2040, 
-    2043, 2046, 2049, 2052, 2055, 2058, 2061, 2064, 2067, 2070, 2073, 2076, 
-    2079, 2082, 2085, 2088, 2091, 2094, 2097, 2100, 2103, 0, 0, 0, 0, 2106, 
-    2109, 2112, 2115, 2118, 2121, 2124, 2127, 2130, 2133, 2136, 2139, 2142, 
-    2145, 2148, 2151, 2154, 2157, 2160, 2163, 2166, 2169, 2172, 2175, 2178, 
-    2181, 2184, 2187, 2190, 2193, 2196, 2199, 2202, 2205, 2208, 2211, 2214, 
-    2217, 2220, 2223, 2226, 2229, 2232, 2235, 2238, 2241, 2244, 2247, 2250, 
-    2253, 2256, 2259, 2262, 2265, 2268, 2271, 2274, 2277, 2280, 2283, 2286, 
-    2289, 2292, 2295, 2298, 2301, 2304, 2307, 2310, 2313, 2316, 2319, 2322, 
-    2325, 2328, 2331, 2334, 2337, 2340, 2343, 2346, 2349, 2352, 2355, 2358, 
-    2361, 2364, 2367, 2370, 2373, 0, 0, 0, 0, 0, 0, 2376, 2379, 2382, 2385, 
-    2388, 2391, 2394, 2397, 2400, 2403, 2406, 2409, 2412, 2415, 2418, 2421, 
-    2424, 2427, 2430, 2433, 2436, 2439, 0, 0, 2442, 2445, 2448, 2451, 2454, 
-    2457, 0, 0, 2460, 2463, 2466, 2469, 2472, 2475, 2478, 2481, 2484, 2487, 
-    2490, 2493, 2496, 2499, 2502, 2505, 2508, 2511, 2514, 2517, 2520, 2523, 
-    2526, 2529, 2532, 2535, 2538, 2541, 2544, 2547, 2550, 2553, 2556, 2559, 
-    2562, 2565, 2568, 2571, 0, 0, 2574, 2577, 2580, 2583, 2586, 2589, 0, 0, 
-    2592, 2595, 2598, 2601, 2604, 2607, 2610, 2613, 0, 2616, 0, 2619, 0, 
-    2622, 0, 2625, 2628, 2631, 2634, 2637, 2640, 2643, 2646, 2649, 2652, 
-    2655, 2658, 2661, 2664, 2667, 2670, 2673, 2676, 2679, 2681, 2684, 2686, 
-    2689, 2691, 2694, 2696, 2699, 2701, 2704, 2706, 2709, 0, 0, 2711, 2714, 
-    2717, 2720, 2723, 2726, 2729, 2732, 2735, 2738, 2741, 2744, 2747, 2750, 
-    2753, 2756, 2759, 2762, 2765, 2768, 2771, 2774, 2777, 2780, 2783, 2786, 
-    2789, 2792, 2795, 2798, 2801, 2804, 2807, 2810, 2813, 2816, 2819, 2822, 
-    2825, 2828, 2831, 2834, 2837, 2840, 2843, 2846, 2849, 2852, 2855, 2858, 
-    2861, 2864, 2867, 0, 2870, 2873, 2876, 2879, 2882, 2885, 2887, 2890, 
-    2893, 2895, 2898, 2901, 2904, 2907, 2910, 0, 2913, 2916, 2919, 2922, 
-    2924, 2927, 2929, 2932, 2935, 2938, 2941, 2944, 2947, 2950, 0, 0, 2952, 
-    2955, 2958, 2961, 2964, 2967, 0, 2969, 2972, 2975, 2978, 2981, 2984, 
-    2987, 2989, 2992, 2995, 2998, 3001, 3004, 3007, 3010, 3012, 3015, 3018, 
-    3020, 0, 0, 3022, 3025, 3028, 0, 3031, 3034, 3037, 3040, 3042, 3045, 
-    3047, 3050, 3052, 0, 3055, 3057, 3059, 3061, 3063, 3065, 3067, 3069, 
-    3071, 3073, 3075, 0, 0, 0, 0, 0, 0, 3077, 0, 0, 0, 0, 0, 3079, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 3082, 3084, 3087, 0, 0, 0, 0, 0, 0, 0, 0, 
-    3091, 0, 0, 0, 3093, 3096, 0, 3100, 3103, 0, 0, 0, 0, 3107, 0, 3110, 0, 
-    0, 0, 0, 0, 0, 0, 0, 3113, 3116, 3119, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 3122, 0, 0, 0, 0, 0, 0, 0, 3127, 3129, 3131, 0, 0, 3133, 3135, 
-    3137, 3139, 3141, 3143, 3145, 3147, 3149, 3151, 3153, 3155, 3157, 3159, 
-    3161, 3163, 3165, 3167, 3169, 3171, 3173, 3175, 3177, 3179, 3181, 3183, 
-    3185, 0, 3187, 3189, 3191, 3193, 3195, 3197, 3199, 3201, 3203, 3205, 
-    3207, 3209, 3211, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3213, 0, 0, 0, 0, 0, 
-    0, 0, 3216, 3220, 3224, 3226, 0, 3229, 3233, 3237, 0, 3239, 3242, 3244, 
-    3246, 3248, 3250, 3252, 3254, 3256, 3258, 3260, 0, 3262, 3264, 0, 0, 
-    3267, 3269, 3271, 3273, 3275, 0, 0, 3277, 3280, 3284, 0, 3287, 0, 3289, 
-    0, 3291, 0, 3293, 3295, 3297, 3299, 0, 3301, 3303, 3305, 0, 3307, 3309, 
-    3311, 3313, 3315, 3317, 3319, 0, 3321, 3325, 3327, 3329, 3331, 3333, 0, 
-    0, 0, 0, 3335, 3337, 3339, 3341, 3343, 0, 0, 0, 0, 0, 0, 3345, 3349, 
-    3353, 3358, 3362, 3366, 3370, 3374, 3378, 3382, 3386, 3390, 3394, 3398, 
-    3402, 3406, 3409, 3411, 3414, 3418, 3421, 3423, 3426, 3430, 3435, 3438, 
-    3440, 3443, 3447, 3449, 3451, 3453, 3455, 3457, 3460, 3464, 3467, 3469, 
-    3472, 3476, 3481, 3484, 3486, 3489, 3493, 3495, 3497, 3499, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 3501, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    3505, 3508, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3511, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3514, 3517, 3520, 0, 0, 0, 0, 
-    3523, 0, 0, 0, 0, 3526, 0, 0, 3529, 0, 0, 0, 0, 0, 0, 0, 3532, 0, 3535, 
-    0, 0, 0, 0, 0, 3538, 3541, 0, 3545, 3548, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 3552, 0, 0, 3555, 0, 0, 3558, 0, 3561, 0, 0, 0, 0, 0, 
-    0, 3564, 0, 3567, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3570, 3573, 3576, 3579, 
-    3582, 0, 0, 3585, 3588, 0, 0, 3591, 3594, 0, 0, 0, 0, 0, 0, 3597, 3600, 
-    0, 0, 3603, 3606, 0, 0, 3609, 3612, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 3615, 3618, 3621, 3624, 3627, 3630, 3633, 3636, 0, 0, 
-    0, 0, 0, 0, 3639, 3642, 3645, 3648, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    3651, 3653, 0, 0, 0, 0, 0, 3655, 3657, 3659, 3661, 3663, 3665, 3667, 
-    3669, 3671, 3673, 3676, 3679, 3682, 3685, 3688, 3691, 3694, 3697, 3700, 
-    3703, 3706, 3710, 3714, 3718, 3722, 3726, 3730, 3734, 3738, 3742, 3747, 
-    3752, 3757, 3762, 3767, 3772, 3777, 3782, 3787, 3792, 3797, 3800, 3803, 
-    3806, 3809, 3812, 3815, 3818, 3821, 3824, 3828, 3832, 3836, 3840, 3844, 
-    3848, 3852, 3856, 3860, 3864, 3868, 3872, 3876, 3880, 3884, 3888, 3892, 
-    3896, 3900, 3904, 3908, 3912, 3916, 3920, 3924, 3928, 3932, 3936, 3940, 
-    3944, 3948, 3952, 3956, 3960, 3964, 3968, 3972, 3974, 3976, 3978, 3980, 
-    3982, 3984, 3986, 3988, 3990, 3992, 3994, 3996, 3998, 4000, 4002, 4004, 
-    4006, 4008, 4010, 4012, 4014, 4016, 4018, 4020, 4022, 4024, 4026, 4028, 
-    4030, 4032, 4034, 4036, 4038, 4040, 4042, 4044, 4046, 4048, 4050, 4052, 
-    4054, 4056, 4058, 4060, 4062, 4064, 4066, 4068, 4070, 4072, 4074, 4076, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4078, 0, 0, 0, 0, 0, 
-    0, 0, 4083, 4087, 4090, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 4094, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4097, 
-    4099, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4101, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4103, 0, 0, 0, 4105, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 4107, 4109, 4111, 4113, 4115, 4117, 4119, 4121, 
-    4123, 4125, 4127, 4129, 4131, 4133, 4135, 4137, 4139, 4141, 4143, 4145, 
-    4147, 4149, 4151, 4153, 4155, 4157, 4159, 4161, 4163, 4165, 4167, 4169, 
-    4171, 4173, 4175, 4177, 4179, 4181, 4183, 4185, 4187, 4189, 4191, 4193, 
-    4195, 4197, 4199, 4201, 4203, 4205, 4207, 4209, 4211, 4213, 4215, 4217, 
-    4219, 4221, 4223, 4225, 4227, 4229, 4231, 4233, 4235, 4237, 4239, 4241, 
-    4243, 4245, 4247, 4249, 4251, 4253, 4255, 4257, 4259, 4261, 4263, 4265, 
-    4267, 4269, 4271, 4273, 4275, 4277, 4279, 4281, 4283, 4285, 4287, 4289, 
-    4291, 4293, 4295, 4297, 4299, 4301, 4303, 4305, 4307, 4309, 4311, 4313, 
-    4315, 4317, 4319, 4321, 4323, 4325, 4327, 4329, 4331, 4333, 4335, 4337, 
-    4339, 4341, 4343, 4345, 4347, 4349, 4351, 4353, 4355, 4357, 4359, 4361, 
-    4363, 4365, 4367, 4369, 4371, 4373, 4375, 4377, 4379, 4381, 4383, 4385, 
-    4387, 4389, 4391, 4393, 4395, 4397, 4399, 4401, 4403, 4405, 4407, 4409, 
-    4411, 4413, 4415, 4417, 4419, 4421, 4423, 4425, 4427, 4429, 4431, 4433, 
-    4435, 4437, 4439, 4441, 4443, 4445, 4447, 4449, 4451, 4453, 4455, 4457, 
-    4459, 4461, 4463, 4465, 4467, 4469, 4471, 4473, 4475, 4477, 4479, 4481, 
-    4483, 4485, 4487, 4489, 4491, 4493, 4495, 4497, 4499, 4501, 4503, 4505, 
-    4507, 4509, 4511, 4513, 4515, 4517, 4519, 4521, 4523, 4525, 4527, 4529, 
-    4531, 4533, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4535, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4537, 0, 4539, 4541, 4543, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4545, 0, 4548, 0, 4551, 0, 
-    4554, 0, 4557, 0, 4560, 0, 4563, 0, 4566, 0, 4569, 0, 4572, 0, 4575, 0, 
-    4578, 0, 0, 4581, 0, 4584, 0, 4587, 0, 0, 0, 0, 0, 0, 4590, 4593, 0, 
-    4596, 4599, 0, 4602, 4605, 0, 4608, 4611, 0, 4614, 4617, 0, 0, 0, 0, 0, 
-    0, 4620, 0, 0, 0, 0, 0, 0, 4623, 4626, 0, 4629, 4632, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 4635, 0, 4638, 0, 4641, 0, 4644, 0, 4647, 0, 4650, 0, 
-    4653, 0, 4656, 0, 4659, 0, 4662, 0, 4665, 0, 4668, 0, 0, 4671, 0, 4674, 
-    0, 4677, 0, 0, 0, 0, 0, 0, 4680, 4683, 0, 4686, 4689, 0, 4692, 4695, 0, 
-    4698, 4701, 0, 4704, 4707, 0, 0, 0, 0, 0, 0, 4710, 0, 0, 4713, 4716, 
-    4719, 4722, 0, 0, 0, 4725, 4728, 0, 4731, 4733, 4735, 4737, 4739, 4741, 
-    4743, 4745, 4747, 4749, 4751, 4753, 4755, 4757, 4759, 4761, 4763, 4765, 
-    4767, 4769, 4771, 4773, 4775, 4777, 4779, 4781, 4783, 4785, 4787, 4789, 
-    4791, 4793, 4795, 4797, 4799, 4801, 4803, 4805, 4807, 4809, 4811, 4813, 
-    4815, 4817, 4819, 4821, 4823, 4825, 4827, 4829, 4831, 4833, 4835, 4837, 
-    4839, 4841, 4843, 4845, 4847, 4849, 4851, 4853, 4855, 4857, 4859, 4861, 
-    4863, 4865, 4867, 4869, 4871, 4873, 4875, 4877, 4879, 4881, 4883, 4885, 
-    4887, 4889, 4891, 4893, 4895, 4897, 4899, 4901, 4903, 4905, 4907, 4909, 
-    4911, 4913, 4915, 4917, 0, 0, 0, 4919, 4921, 4923, 4925, 4927, 4929, 
-    4931, 4933, 4935, 4937, 4939, 4941, 4943, 4945, 4947, 4951, 4955, 4959, 
-    4963, 4967, 4971, 4975, 4979, 4983, 4987, 4991, 4995, 4999, 5003, 5008, 
-    5013, 5018, 5023, 5028, 5033, 5038, 5043, 5048, 5053, 5058, 5063, 5068, 
-    5073, 5078, 5086, 0, 5093, 5097, 5101, 5105, 5109, 5113, 5117, 5121, 
-    5125, 5129, 5133, 5137, 5141, 5145, 5149, 5153, 5157, 5161, 5165, 5169, 
-    5173, 5177, 5181, 5185, 5189, 5193, 5197, 5201, 5205, 5209, 5213, 5217, 
-    5221, 5225, 5229, 5233, 5237, 5239, 5241, 5243, 0, 0, 0, 0, 0, 0, 0, 0, 
-    5245, 5249, 5252, 5255, 5258, 5261, 5264, 5267, 5270, 5273, 5276, 5279, 
-    5282, 5285, 5288, 5291, 5294, 5296, 5298, 5300, 5302, 5304, 5306, 5308, 
-    5310, 5312, 5314, 5316, 5318, 5320, 5322, 5325, 5328, 5331, 5334, 5337, 
-    5340, 5343, 5346, 5349, 5352, 5355, 5358, 5361, 5364, 5370, 5375, 0, 
-    5378, 5380, 5382, 5384, 5386, 5388, 5390, 5392, 5394, 5396, 5398, 5400, 
-    5402, 5404, 5406, 5408, 5410, 5412, 5414, 5416, 5418, 5420, 5422, 5424, 
-    5426, 5428, 5430, 5432, 5434, 5436, 5438, 5440, 5442, 5444, 5446, 5448, 
-    5450, 5452, 5454, 5456, 5458, 5460, 5462, 5464, 5466, 5468, 5470, 5472, 
-    5474, 5476, 5479, 5482, 5485, 5488, 5491, 5494, 5497, 5500, 5503, 5506, 
-    5509, 5512, 5515, 5518, 5521, 5524, 5527, 5530, 5533, 5536, 5539, 5542, 
-    5545, 5548, 5552, 5556, 5560, 5563, 5567, 5570, 5574, 5576, 5578, 5580, 
-    5582, 5584, 5586, 5588, 5590, 5592, 5594, 5596, 5598, 5600, 5602, 5604, 
-    5606, 5608, 5610, 5612, 5614, 5616, 5618, 5620, 5622, 5624, 5626, 5628, 
-    5630, 5632, 5634, 5636, 5638, 5640, 5642, 5644, 5646, 5648, 5650, 5652, 
-    5654, 5656, 5658, 5660, 5662, 5664, 5666, 0, 5668, 5673, 5678, 5683, 
-    5687, 5692, 5696, 5700, 5706, 5711, 5715, 5719, 5723, 5728, 5733, 5737, 
-    5741, 5744, 5748, 5753, 5758, 5761, 5767, 5774, 5780, 5784, 5790, 5796, 
-    5801, 5805, 5809, 5813, 5818, 5824, 5829, 5833, 5837, 5841, 5844, 5847, 
-    5850, 5853, 5857, 5861, 5867, 5871, 5876, 5882, 5886, 5889, 5892, 5898, 
-    5903, 5909, 5913, 5919, 5922, 5926, 5930, 5934, 5938, 5942, 5947, 5951, 
-    5954, 5958, 5962, 5966, 5971, 5975, 5979, 5983, 5989, 5994, 5997, 6003, 
-    6006, 6011, 6016, 6020, 6024, 6028, 6033, 6036, 6040, 6045, 6048, 6054, 
-    6058, 6061, 6064, 6067, 6070, 6073, 6076, 6079, 6082, 6085, 6088, 6092, 
-    6096, 6100, 6104, 6108, 6112, 6116, 6120, 6124, 6128, 6132, 6136, 6140, 
-    6144, 6148, 6152, 6155, 6158, 6162, 6165, 6168, 6171, 6175, 6179, 6182, 
-    6185, 6188, 6191, 6194, 6199, 6202, 6205, 6208, 6211, 6214, 6217, 6220, 
-    6223, 6227, 6232, 6235, 6238, 6241, 6244, 6247, 6250, 6253, 6257, 6261, 
-    6265, 6269, 6272, 6275, 6278, 6281, 6284, 6287, 6290, 6293, 6296, 6299, 
-    6303, 6307, 6310, 6314, 6318, 6322, 6325, 6329, 6333, 6338, 6341, 6345, 
-    6349, 6353, 6357, 6363, 6370, 6373, 6376, 6379, 6382, 6385, 6388, 6391, 
-    6394, 6397, 6400, 6403, 6406, 6409, 6412, 6415, 6418, 6421, 6424, 6429, 
-    6432, 6435, 6438, 6443, 6447, 6450, 6453, 6456, 6459, 6462, 6465, 6468, 
-    6471, 6474, 6477, 6481, 6484, 6487, 6491, 6495, 6498, 6503, 6507, 6510, 
-    6513, 6516, 6519, 6523, 6527, 6530, 6533, 6536, 6539, 6542, 6545, 6548, 
-    6551, 6554, 6558, 6562, 6566, 6570, 6574, 6578, 6582, 6586, 6590, 6594, 
-    6598, 6602, 6606, 6610, 6614, 6618, 6622, 6626, 6630, 6634, 6638, 6642, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6646, 6648, 0, 0, 6650, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6652, 6654, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6656, 6658, 6660, 
-    6662, 6664, 6666, 6668, 6670, 6672, 6674, 6676, 6678, 6680, 6682, 6684, 
-    6686, 6688, 6690, 6692, 6694, 6696, 6698, 6700, 6702, 6704, 6706, 6708, 
-    6710, 6712, 6714, 6716, 6718, 6720, 6722, 6724, 6726, 6728, 6730, 6732, 
-    6734, 6736, 6738, 6740, 6742, 6744, 6746, 6748, 6750, 6752, 6754, 6756, 
-    6758, 6760, 6762, 6764, 6766, 6768, 6770, 6772, 6774, 6776, 6778, 6780, 
-    6782, 6784, 6786, 6788, 6790, 6792, 6794, 6796, 6798, 6800, 6802, 6804, 
-    6806, 6808, 6810, 6812, 6814, 6816, 6818, 6820, 6822, 6824, 6826, 6828, 
-    6830, 6832, 6834, 6836, 6838, 6840, 6842, 6844, 6846, 6848, 6850, 6852, 
-    6854, 6856, 6858, 6860, 6862, 6864, 6866, 6868, 6870, 6872, 6874, 6876, 
-    6878, 6880, 6882, 6884, 6886, 6888, 6890, 6892, 6894, 6896, 6898, 6900, 
-    6902, 6904, 6906, 6908, 6910, 6912, 6914, 6916, 6918, 6920, 6922, 6924, 
-    6926, 6928, 6930, 6932, 6934, 6936, 6938, 6940, 6942, 6944, 6946, 6948, 
-    6950, 6952, 6954, 6956, 6958, 6960, 6962, 6964, 6966, 6968, 6970, 6972, 
-    6974, 6976, 6978, 6980, 6982, 6984, 6986, 6988, 6990, 6992, 6994, 6996, 
-    6998, 7000, 7002, 7004, 7006, 7008, 7010, 7012, 7014, 7016, 7018, 7020, 
-    7022, 7024, 7026, 7028, 7030, 7032, 7034, 7036, 7038, 7040, 7042, 7044, 
-    7046, 7048, 7050, 7052, 7054, 7056, 7058, 7060, 7062, 7064, 7066, 7068, 
-    7070, 7072, 7074, 7076, 7078, 7080, 7082, 7084, 7086, 7088, 7090, 7092, 
-    7094, 7096, 7098, 7100, 7102, 7104, 7106, 7108, 7110, 7112, 7114, 7116, 
-    7118, 7120, 7122, 7124, 7126, 7128, 7130, 7132, 7134, 7136, 7138, 7140, 
-    7142, 7144, 7146, 7148, 7150, 7152, 7154, 7156, 7158, 7160, 7162, 7164, 
-    7166, 7168, 7170, 7172, 7174, 7176, 7178, 7180, 7182, 7184, 7186, 7188, 
-    7190, 7192, 7194, 7196, 7198, 7200, 7202, 0, 0, 7204, 0, 7206, 0, 0, 
-    7208, 7210, 7212, 7214, 7216, 7218, 7220, 7222, 7224, 7226, 0, 7228, 0, 
-    7230, 0, 0, 7232, 7234, 0, 0, 0, 7236, 7238, 7240, 7242, 7244, 7246, 
-    7248, 7250, 7252, 7254, 7256, 7258, 7260, 7262, 7264, 7266, 7268, 7270, 
-    7272, 7274, 7276, 7278, 7280, 7282, 7284, 7286, 7288, 7290, 7292, 7294, 
-    7296, 7298, 7300, 7302, 7304, 7306, 7308, 7310, 7312, 7314, 7316, 7318, 
-    7320, 7322, 7324, 7326, 7328, 7330, 7332, 7334, 7336, 7338, 7340, 7342, 
-    7344, 7346, 7348, 7350, 7352, 7354, 7356, 7358, 7360, 7362, 7364, 7366, 
-    7368, 7371, 0, 0, 7373, 7375, 7377, 7379, 7381, 7383, 7385, 7387, 7389, 
-    7391, 7393, 7395, 7397, 7399, 7401, 7403, 7405, 7407, 7409, 7411, 7413, 
-    7415, 7417, 7419, 7421, 7423, 7425, 7427, 7429, 7431, 7433, 7435, 7437, 
-    7439, 7441, 7443, 7445, 7447, 7449, 7451, 7453, 7455, 7457, 7459, 7461, 
-    7463, 7465, 7467, 7469, 7471, 7473, 7475, 7477, 7479, 7481, 7483, 7485, 
-    7487, 7489, 7491, 7493, 7495, 7497, 7499, 7501, 7503, 7505, 7507, 7509, 
-    7511, 7513, 7515, 7517, 7519, 7521, 7523, 7525, 7527, 7529, 7531, 7533, 
-    7535, 7537, 7539, 7541, 7543, 7545, 7547, 7549, 7551, 7553, 7555, 7557, 
-    7559, 7561, 7563, 7566, 7569, 7572, 7574, 7576, 7578, 7581, 7584, 7587, 
-    7589, 0, 0, 0, 0, 0, 0, 7591, 7594, 7597, 7600, 7604, 7608, 7611, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7614, 7617, 7620, 7623, 7626, 0, 0, 0, 0, 
-    0, 7629, 0, 7632, 7635, 7637, 7639, 7641, 7643, 7645, 7647, 7649, 7651, 
-    7653, 7655, 7658, 7661, 7664, 7667, 7670, 7673, 7676, 7679, 7682, 7685, 
-    7688, 7691, 0, 7694, 7697, 7700, 7703, 7706, 0, 7709, 0, 7712, 7715, 0, 
-    7718, 7721, 0, 7724, 7727, 7730, 7733, 7736, 7739, 7742, 7745, 7748, 
-    7751, 7754, 7756, 7758, 7760, 7762, 7764, 7766, 7768, 7770, 7772, 7774, 
-    7776, 7778, 7780, 7782, 7784, 7786, 7788, 7790, 7792, 7794, 7796, 7798, 
-    7800, 7802, 7804, 7806, 7808, 7810, 7812, 7814, 7816, 7818, 7820, 7822, 
-    7824, 7826, 7828, 7830, 7832, 7834, 7836, 7838, 7840, 7842, 7844, 7846, 
-    7848, 7850, 7852, 7854, 7856, 7858, 7860, 7862, 7864, 7866, 7868, 7870, 
-    7872, 7874, 7876, 7878, 7880, 7882, 7884, 7886, 7888, 7890, 7892, 7894, 
-    7896, 7898, 7900, 7902, 7904, 7906, 7908, 7910, 7912, 7914, 7916, 7918, 
-    7920, 7922, 7924, 7926, 7928, 7930, 7932, 7934, 7936, 7938, 7940, 7942, 
-    7944, 7946, 7948, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    7950, 7952, 7954, 7956, 7958, 7960, 7962, 7964, 7966, 7968, 7970, 7972, 
-    7974, 7976, 7978, 7980, 7982, 7984, 7986, 7988, 7990, 7992, 7994, 7996, 
-    7999, 8002, 8005, 8008, 8011, 8014, 8017, 8020, 8023, 8026, 8029, 8032, 
-    8035, 8038, 8041, 8044, 8047, 8050, 8052, 8054, 8056, 8058, 8061, 8064, 
-    8067, 8070, 8073, 8076, 8079, 8082, 8085, 8088, 8091, 8094, 8097, 8100, 
-    8103, 8106, 8109, 8112, 8115, 8118, 8121, 8124, 8127, 8130, 8133, 8136, 
-    8139, 8142, 8145, 8148, 8151, 8154, 8157, 8160, 8163, 8166, 8169, 8172, 
-    8175, 8178, 8181, 8184, 8187, 8190, 8193, 8196, 8199, 8202, 8205, 8208, 
-    8211, 8214, 8217, 8220, 8223, 8226, 8229, 8232, 8235, 8238, 8241, 8244, 
-    8247, 8250, 8253, 8256, 8259, 8262, 8265, 8268, 8271, 8274, 8277, 8280, 
-    8283, 8286, 8289, 8292, 8295, 8298, 8301, 8304, 8307, 8310, 8313, 8316, 
-    8319, 8322, 8325, 8328, 8331, 8334, 8337, 8340, 8344, 8348, 8352, 8356, 
-    8360, 8364, 8367, 8370, 8373, 8376, 8379, 8382, 8385, 8388, 8391, 8394, 
-    8397, 8400, 8403, 8406, 8409, 8412, 8415, 8418, 8421, 8424, 8427, 8430, 
-    8433, 8436, 8439, 8442, 8445, 8448, 8451, 8454, 8457, 8460, 8463, 8466, 
-    8469, 8472, 8475, 8478, 8481, 8484, 8487, 8490, 8493, 8496, 8499, 8502, 
-    8505, 8508, 8511, 8514, 8517, 8520, 8523, 8526, 8529, 8532, 8535, 8538, 
-    8541, 8544, 8547, 8550, 8553, 8556, 8559, 8562, 8565, 8568, 8571, 8574, 
-    8577, 8580, 8583, 8586, 8589, 8592, 8595, 8598, 8601, 8604, 8607, 8610, 
-    8613, 8616, 8619, 8622, 8625, 8628, 8631, 8634, 8637, 8640, 8643, 8646, 
-    8649, 8652, 8655, 8658, 8661, 8664, 8667, 8670, 8673, 8676, 8679, 8682, 
-    8685, 8688, 8691, 8694, 8697, 8700, 8703, 8706, 8709, 8712, 8715, 8718, 
-    8721, 8724, 8727, 8730, 8733, 8736, 8739, 8742, 8745, 8748, 8751, 8754, 
-    8757, 8760, 8763, 8766, 8769, 8772, 8775, 8778, 8781, 8784, 8787, 8790, 
-    8794, 8798, 8802, 8805, 8808, 8811, 8814, 8817, 8820, 8823, 8826, 8829, 
-    8832, 8835, 8838, 8841, 8844, 8847, 8850, 8853, 8856, 8859, 8862, 8865, 
-    8868, 8871, 8874, 8877, 8880, 8883, 8886, 8889, 8892, 8895, 8898, 8901, 
-    8904, 8907, 8910, 8913, 8916, 8919, 8922, 8925, 8928, 8931, 8934, 8937, 
-    8940, 8943, 8946, 8949, 8952, 8955, 8958, 8961, 8964, 8967, 8970, 8973, 
-    8976, 8979, 8982, 8985, 8988, 8991, 8994, 8997, 9000, 9003, 9006, 9009, 
-    9012, 9015, 9018, 0, 0, 9021, 9025, 9029, 9033, 9037, 9041, 9045, 9049, 
-    9053, 9057, 9061, 9065, 9069, 9073, 9077, 9081, 9085, 9089, 9093, 9097, 
-    9101, 9105, 9109, 9113, 9117, 9121, 9125, 9129, 9133, 9137, 9141, 9145, 
-    9149, 9153, 9157, 9161, 9165, 9169, 9173, 9177, 9181, 9185, 9189, 9193, 
-    9197, 9201, 9205, 9209, 9213, 9217, 9221, 9225, 9229, 9233, 9237, 9241, 
-    9245, 9249, 9253, 9257, 9261, 9265, 9269, 9273, 0, 0, 9277, 9281, 9285, 
-    9289, 9293, 9297, 9301, 9305, 9309, 9313, 9317, 9321, 9325, 9329, 9333, 
-    9337, 9341, 9345, 9349, 9353, 9357, 9361, 9365, 9369, 9373, 9377, 9381, 
-    9385, 9389, 9393, 9397, 9401, 9405, 9409, 9413, 9417, 9421, 9425, 9429, 
-    9433, 9437, 9441, 9445, 9449, 9453, 9457, 9461, 9465, 9469, 9473, 9477, 
-    9481, 9485, 9489, 0, 0, 0, 0, 0, 0, 0, 0, 9493, 9497, 9501, 9506, 9511, 
-    9516, 9521, 9526, 9531, 9536, 9540, 9559, 9568, 0, 0, 0, 9573, 9575, 
-    9577, 9579, 9581, 9583, 9585, 9587, 9589, 9591, 0, 0, 0, 0, 0, 0, 9593, 
-    9595, 9597, 9599, 9601, 9603, 9605, 9607, 9609, 9611, 9613, 9615, 9617, 
-    9619, 9621, 9623, 9625, 9627, 9629, 9631, 9633, 0, 0, 9635, 9637, 9639, 
-    9641, 9643, 9645, 9647, 9649, 9651, 9653, 9655, 9657, 0, 9659, 9661, 
-    9663, 9665, 9667, 9669, 9671, 9673, 9675, 9677, 9679, 9681, 9683, 9685, 
-    9687, 9689, 9691, 9693, 9695, 0, 9697, 9699, 9701, 9703, 0, 0, 0, 0, 
-    9705, 9708, 9711, 0, 9714, 0, 9717, 9720, 9723, 9726, 9729, 9732, 9735, 
-    9738, 9741, 9744, 9747, 9749, 9751, 9753, 9755, 9757, 9759, 9761, 9763, 
-    9765, 9767, 9769, 9771, 9773, 9775, 9777, 9779, 9781, 9783, 9785, 9787, 
-    9789, 9791, 9793, 9795, 9797, 9799, 9801, 9803, 9805, 9807, 9809, 9811, 
-    9813, 9815, 9817, 9819, 9821, 9823, 9825, 9827, 9829, 9831, 9833, 9835, 
-    9837, 9839, 9841, 9843, 9845, 9847, 9849, 9851, 9853, 9855, 9857, 9859, 
-    9861, 9863, 9865, 9867, 9869, 9871, 9873, 9875, 9877, 9879, 9881, 9883, 
-    9885, 9887, 9889, 9891, 9893, 9895, 9897, 9899, 9901, 9903, 9905, 9907, 
-    9909, 9911, 9913, 9915, 9917, 9919, 9921, 9923, 9925, 9927, 9929, 9931, 
-    9933, 9935, 9937, 9939, 9941, 9943, 9945, 9947, 9949, 9951, 9953, 9955, 
-    9957, 9959, 9961, 9963, 9965, 9967, 9969, 9971, 9973, 9975, 9977, 9979, 
-    9981, 9984, 9987, 9990, 9993, 9996, 9999, 10002, 0, 0, 0, 0, 10005, 
-    10007, 10009, 10011, 10013, 10015, 10017, 10019, 10021, 10023, 10025, 
-    10027, 10029, 10031, 10033, 10035, 10037, 10039, 10041, 10043, 10045, 
-    10047, 10049, 10051, 10053, 10055, 10057, 10059, 10061, 10063, 10065, 
-    10067, 10069, 10071, 10073, 10075, 10077, 10079, 10081, 10083, 10085, 
-    10087, 10089, 10091, 10093, 10095, 10097, 10099, 10101, 10103, 10105, 
-    10107, 10109, 10111, 10113, 10115, 10117, 10119, 10121, 10123, 10125, 
-    10127, 10129, 10131, 10133, 10135, 10137, 10139, 10141, 10143, 10145, 
-    10147, 10149, 10151, 10153, 10155, 10157, 10159, 10161, 10163, 10165, 
-    10167, 10169, 10171, 10173, 10175, 10177, 10179, 10181, 10183, 10185, 
-    10187, 10189, 10191, 10193, 10195, 10197, 10199, 10201, 10203, 10205, 
-    10207, 10209, 10211, 10213, 10215, 10217, 10219, 10221, 10223, 10225, 
-    10227, 10229, 10231, 10233, 10235, 10237, 10239, 10241, 10243, 10245, 
-    10247, 10249, 10251, 10253, 10255, 10257, 10259, 10261, 10263, 10265, 
-    10267, 10269, 10271, 10273, 10275, 10277, 10279, 10281, 10283, 10285, 
-    10287, 10289, 10291, 10293, 10295, 10297, 10299, 10301, 10303, 10305, 
-    10307, 10309, 10311, 10313, 10315, 10317, 10319, 10321, 10323, 10325, 
-    10327, 10329, 10331, 10333, 10335, 10337, 10339, 10341, 10343, 10345, 
-    10347, 10349, 10351, 10353, 10355, 10357, 10359, 10361, 10363, 10365, 
-    10367, 10369, 10371, 10373, 10375, 10377, 10379, 10381, 10383, 0, 0, 0, 
-    10385, 10387, 10389, 10391, 10393, 10395, 0, 0, 10397, 10399, 10401, 
-    10403, 10405, 10407, 0, 0, 10409, 10411, 10413, 10415, 10417, 10419, 0, 
-    0, 10421, 10423, 10425, 0, 0, 0, 10427, 10429, 10431, 10433, 10435, 
-    10437, 10439, 0, 10441, 10443, 10445, 10447, 10449, 10451, 10453, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 10455, 0, 10460, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 10465, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    10470, 10475, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10480, 10485, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10490, 10495, 0, 10500, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 10505, 10510, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 10515, 10520, 10525, 10530, 10535, 10540, 10545, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10550, 10555, 10560, 
-    10565, 10570, 10575, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10580, 
-    10582, 10584, 10586, 10588, 10590, 10592, 10594, 10596, 10598, 10600, 
-    10602, 10604, 10606, 10608, 10610, 10612, 10614, 10616, 10618, 10620, 
-    10622, 10624, 10626, 10628, 10630, 10632, 10634, 10636, 10638, 10640, 
-    10642, 10644, 10646, 10648, 10650, 10652, 10654, 10656, 10658, 10660, 
-    10662, 10664, 10666, 10668, 10670, 10672, 10674, 10676, 10678, 10680, 
-    10682, 10684, 10686, 10688, 10690, 10692, 10694, 10696, 10698, 10700, 
-    10702, 10704, 10706, 10708, 10710, 10712, 10714, 10716, 10718, 10720, 
-    10722, 10724, 10726, 10728, 10730, 10732, 10734, 10736, 10738, 10740, 
-    10742, 10744, 10746, 10748, 0, 10750, 10752, 10754, 10756, 10758, 10760, 
-    10762, 10764, 10766, 10768, 10770, 10772, 10774, 10776, 10778, 10780, 
-    10782, 10784, 10786, 10788, 10790, 10792, 10794, 10796, 10798, 10800, 
-    10802, 10804, 10806, 10808, 10810, 10812, 10814, 10816, 10818, 10820, 
-    10822, 10824, 10826, 10828, 10830, 10832, 10834, 10836, 10838, 10840, 
-    10842, 10844, 10846, 10848, 10850, 10852, 10854, 10856, 10858, 10860, 
-    10862, 10864, 10866, 10868, 10870, 10872, 10874, 10876, 10878, 10880, 
-    10882, 10884, 10886, 10888, 10890, 0, 10892, 10894, 0, 0, 10896, 0, 0, 
-    10898, 10900, 0, 0, 10902, 10904, 10906, 10908, 0, 10910, 10912, 10914, 
-    10916, 10918, 10920, 10922, 10924, 10926, 10928, 10930, 10932, 0, 10934, 
-    0, 10936, 10938, 10940, 10942, 10944, 10946, 10948, 0, 10950, 10952, 
-    10954, 10956, 10958, 10960, 10962, 10964, 10966, 10968, 10970, 10972, 
-    10974, 10976, 10978, 10980, 10982, 10984, 10986, 10988, 10990, 10992, 
-    10994, 10996, 10998, 11000, 11002, 11004, 11006, 11008, 11010, 11012, 
-    11014, 11016, 11018, 11020, 11022, 11024, 11026, 11028, 11030, 11032, 
-    11034, 11036, 11038, 11040, 11042, 11044, 11046, 11048, 11050, 11052, 
-    11054, 11056, 11058, 11060, 11062, 11064, 11066, 11068, 11070, 11072, 
-    11074, 11076, 11078, 0, 11080, 11082, 11084, 11086, 0, 0, 11088, 11090, 
-    11092, 11094, 11096, 11098, 11100, 11102, 0, 11104, 11106, 11108, 11110, 
-    11112, 11114, 11116, 0, 11118, 11120, 11122, 11124, 11126, 11128, 11130, 
-    11132, 11134, 11136, 11138, 11140, 11142, 11144, 11146, 11148, 11150, 
-    11152, 11154, 11156, 11158, 11160, 11162, 11164, 11166, 11168, 11170, 
-    11172, 0, 11174, 11176, 11178, 11180, 0, 11182, 11184, 11186, 11188, 
-    11190, 0, 11192, 0, 0, 0, 11194, 11196, 11198, 11200, 11202, 11204, 
-    11206, 0, 11208, 11210, 11212, 11214, 11216, 11218, 11220, 11222, 11224, 
-    11226, 11228, 11230, 11232, 11234, 11236, 11238, 11240, 11242, 11244, 
-    11246, 11248, 11250, 11252, 11254, 11256, 11258, 11260, 11262, 11264, 
-    11266, 11268, 11270, 11272, 11274, 11276, 11278, 11280, 11282, 11284, 
-    11286, 11288, 11290, 11292, 11294, 11296, 11298, 11300, 11302, 11304, 
-    11306, 11308, 11310, 11312, 11314, 11316, 11318, 11320, 11322, 11324, 
-    11326, 11328, 11330, 11332, 11334, 11336, 11338, 11340, 11342, 11344, 
-    11346, 11348, 11350, 11352, 11354, 11356, 11358, 11360, 11362, 11364, 
-    11366, 11368, 11370, 11372, 11374, 11376, 11378, 11380, 11382, 11384, 
-    11386, 11388, 11390, 11392, 11394, 11396, 11398, 11400, 11402, 11404, 
-    11406, 11408, 11410, 11412, 11414, 11416, 11418, 11420, 11422, 11424, 
-    11426, 11428, 11430, 11432, 11434, 11436, 11438, 11440, 11442, 11444, 
-    11446, 11448, 11450, 11452, 11454, 11456, 11458, 11460, 11462, 11464, 
-    11466, 11468, 11470, 11472, 11474, 11476, 11478, 11480, 11482, 11484, 
-    11486, 11488, 11490, 11492, 11494, 11496, 11498, 11500, 11502, 11504, 
-    11506, 11508, 11510, 11512, 11514, 11516, 11518, 11520, 11522, 11524, 
-    11526, 11528, 11530, 11532, 11534, 11536, 11538, 11540, 11542, 11544, 
-    11546, 11548, 11550, 11552, 11554, 11556, 11558, 11560, 11562, 11564, 
-    11566, 11568, 11570, 11572, 11574, 11576, 11578, 11580, 11582, 11584, 
-    11586, 11588, 11590, 11592, 11594, 11596, 11598, 11600, 11602, 11604, 
-    11606, 11608, 11610, 11612, 11614, 11616, 11618, 11620, 11622, 11624, 
-    11626, 11628, 11630, 11632, 11634, 11636, 11638, 11640, 11642, 11644, 
-    11646, 11648, 11650, 11652, 11654, 11656, 11658, 11660, 11662, 11664, 
-    11666, 11668, 11670, 11672, 11674, 11676, 11678, 11680, 11682, 11684, 
-    11686, 11688, 11690, 11692, 11694, 11696, 11698, 11700, 11702, 11704, 
-    11706, 11708, 11710, 11712, 11714, 11716, 11718, 11720, 11722, 11724, 
-    11726, 11728, 11730, 11732, 11734, 11736, 11738, 11740, 11742, 11744, 
-    11746, 11748, 11750, 11752, 11754, 11756, 11758, 11760, 11762, 11764, 
-    11766, 11768, 11770, 11772, 11774, 11776, 11778, 11780, 11782, 11784, 
-    11786, 11788, 11790, 11792, 11794, 11796, 11798, 11800, 11802, 11804, 
-    11806, 11808, 11810, 11812, 11814, 11816, 11818, 11820, 11822, 11824, 
-    11826, 11828, 11830, 11832, 11834, 11836, 11838, 11840, 11842, 11844, 
-    11846, 11848, 11850, 11852, 11854, 11856, 11858, 11860, 11862, 11864, 
-    11866, 11868, 11870, 11872, 11874, 11876, 11878, 11880, 11882, 11884, 
-    11886, 0, 0, 11888, 11890, 11892, 11894, 11896, 11898, 11900, 11902, 
-    11904, 11906, 11908, 11910, 11912, 11914, 11916, 11918, 11920, 11922, 
-    11924, 11926, 11928, 11930, 11932, 11934, 11936, 11938, 11940, 11942, 
-    11944, 11946, 11948, 11950, 11952, 11954, 11956, 11958, 11960, 11962, 
-    11964, 11966, 11968, 11970, 11972, 11974, 11976, 11978, 11980, 11982, 
-    11984, 11986, 11988, 11990, 11992, 11994, 11996, 11998, 12000, 12002, 
-    12004, 12006, 12008, 12010, 12012, 12014, 12016, 12018, 12020, 12022, 
-    12024, 12026, 12028, 12030, 12032, 12034, 12036, 12038, 12040, 12042, 
-    12044, 12046, 12048, 12050, 12052, 12054, 12056, 12058, 12060, 12062, 
-    12064, 12066, 12068, 12070, 12072, 12074, 12076, 12078, 12080, 12082, 
-    12084, 12086, 12088, 12090, 12092, 12094, 12096, 12098, 12100, 12102, 
-    12104, 12106, 12108, 12110, 12112, 12114, 12116, 12118, 12120, 12122, 
-    12124, 12126, 12128, 12130, 12132, 12134, 12136, 12138, 12140, 12142, 
-    12144, 12146, 12148, 12150, 12152, 12154, 12156, 12158, 12160, 12162, 
-    12164, 12166, 12168, 12170, 12172, 12174, 12176, 12178, 12180, 12182, 
-    12184, 12186, 12188, 12190, 12192, 12194, 12196, 12198, 12200, 12202, 
-    12204, 12206, 12208, 12210, 12212, 12214, 12216, 12218, 12220, 12222, 
-    12224, 12226, 12228, 12230, 12232, 12234, 12236, 12238, 12240, 12242, 
-    12244, 12246, 12248, 12250, 12252, 12254, 12256, 12258, 12260, 12262, 
-    12264, 12266, 12268, 12270, 12272, 12274, 12276, 12278, 12280, 12282, 
-    12284, 12286, 12288, 12290, 12292, 12294, 12296, 12298, 12300, 12302, 
-    12304, 12306, 12308, 12310, 12312, 12314, 12316, 12318, 12320, 12322, 
-    12324, 12326, 12328, 12330, 12332, 12334, 12336, 12338, 12340, 12342, 
-    12344, 12346, 12348, 12350, 12352, 12354, 12356, 12358, 12360, 12362, 
-    12364, 12366, 12368, 12370, 12372, 12374, 12376, 12378, 12380, 12382, 
-    12384, 12386, 12388, 12390, 12392, 12394, 12396, 12398, 12400, 12402, 
-    12404, 12406, 12408, 12410, 12412, 12414, 12416, 12418, 12420, 12422, 
-    12424, 12426, 12428, 12430, 12432, 12434, 12436, 12438, 12440, 12442, 
-    12444, 12446, 12448, 12450, 12452, 12454, 12456, 12458, 12460, 12462, 
-    12464, 12466, 12468, 12470, 0, 0, 12472, 12474, 12476, 12478, 12480, 
-    12482, 12484, 12486, 12488, 12490, 12492, 12494, 12496, 12498, 12500, 
-    12502, 12504, 12506, 12508, 12510, 12512, 12514, 12516, 12518, 12520, 
-    12522, 12524, 12526, 12528, 12530, 12532, 12534, 12536, 12538, 12540, 
-    12542, 12544, 12546, 12548, 12550, 12552, 12554, 12556, 12558, 12560, 
-    12562, 12564, 12566, 12568, 12570, 12572, 12574, 12576, 12578, 0, 12580, 
-    12582, 12584, 12586, 12588, 12590, 12592, 12594, 12596, 12598, 12600, 
-    12602, 12604, 12606, 12608, 12610, 12612, 12614, 12616, 12618, 12620, 
-    12622, 12624, 12626, 12628, 12630, 12632, 0, 12634, 12636, 0, 12638, 0, 
-    0, 12640, 0, 12642, 12644, 12646, 12648, 12650, 12652, 12654, 12656, 
-    12658, 12660, 0, 12662, 12664, 12666, 12668, 0, 12670, 0, 12672, 0, 0, 0, 
-    0, 0, 0, 12674, 0, 0, 0, 0, 12676, 0, 12678, 0, 12680, 0, 12682, 12684, 
-    12686, 0, 12688, 12690, 0, 12692, 0, 0, 12694, 0, 12696, 0, 12698, 0, 
-    12700, 0, 12702, 0, 12704, 12706, 0, 12708, 0, 0, 12710, 12712, 12714, 
-    12716, 0, 12718, 12720, 12722, 12724, 12726, 12728, 12730, 0, 12732, 
-    12734, 12736, 12738, 0, 12740, 12742, 12744, 12746, 0, 12748, 0, 12750, 
-    12752, 12754, 12756, 12758, 12760, 12762, 12764, 12766, 12768, 0, 12770, 
-    12772, 12774, 12776, 12778, 12780, 12782, 12784, 12786, 12788, 12790, 
-    12792, 12794, 12796, 12798, 12800, 12802, 0, 0, 0, 0, 0, 12804, 12806, 
-    12808, 0, 12810, 12812, 12814, 12816, 12818, 0, 12820, 12822, 12824, 
-    12826, 12828, 12830, 12832, 12834, 12836, 12838, 12840, 12842, 12844, 
-    12846, 12848, 12850, 12852, 0, 0, 0, 0, 12854, 12857, 12860, 12863, 
-    12866, 12869, 12872, 12875, 12878, 12881, 12884, 0, 0, 0, 0, 0, 12887, 
-    12891, 12895, 12899, 12903, 12907, 12911, 12915, 12919, 12923, 12927, 
-    12931, 12935, 12939, 12943, 12947, 12951, 12955, 12959, 12963, 12967, 
-    12971, 12975, 12979, 12983, 12987, 12991, 12995, 12997, 12999, 13002, 0, 
-    13005, 13007, 13009, 13011, 13013, 13015, 13017, 13019, 13021, 13023, 
-    13025, 13027, 13029, 13031, 13033, 13035, 13037, 13039, 13041, 13043, 
-    13045, 13047, 13049, 13051, 13053, 13055, 13057, 13060, 13063, 13066, 
-    13069, 13073, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13076, 13079, 13082, 0, 0, 0, 
-    13085, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13088, 13091, 13094, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13096, 13098, 13100, 13102, 13104, 
-    13106, 13108, 13110, 13112, 13114, 13116, 13118, 13120, 13122, 13124, 
-    13126, 13128, 13130, 13132, 13134, 13136, 13138, 13140, 13142, 13144, 
-    13146, 13148, 13150, 13152, 13154, 13156, 13158, 13160, 13162, 13164, 
-    13166, 13168, 13170, 13172, 13174, 13176, 13178, 13180, 13182, 0, 0, 0, 
-    0, 13184, 13188, 13192, 13196, 13200, 13204, 13208, 13212, 13216, 0, 0, 
-    0, 0, 0, 0, 0, 13220, 13222, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    13224, 13226, 13228, 13230, 13233, 13235, 13237, 13239, 13241, 13243, 
-    13245, 13247, 13249, 13251, 13254, 13256, 13258, 13260, 13262, 13265, 
-    13267, 13269, 13271, 13274, 13276, 13278, 13280, 13282, 13284, 13287, 
-    13289, 13291, 13293, 13295, 13297, 13299, 13301, 13303, 13305, 13307, 
-    13309, 13311, 13313, 13315, 13317, 13319, 13321, 13323, 13325, 13327, 
-    13329, 13331, 13333, 13336, 13338, 13340, 13342, 13345, 13347, 13349, 
-    13351, 13353, 13355, 13357, 13359, 13361, 13363, 13365, 13367, 13369, 
-    13371, 13373, 13375, 13377, 13379, 13381, 13383, 13385, 13387, 13389, 
-    13391, 13393, 13395, 13397, 13399, 13401, 13403, 13405, 13407, 13409, 
-    13412, 13414, 13416, 13418, 13420, 13422, 13424, 13427, 13430, 13432, 
-    13434, 13436, 13438, 13440, 13442, 13444, 13446, 13448, 13450, 13453, 
-    13455, 13457, 13459, 13461, 13464, 13466, 13468, 13470, 13472, 13474, 
-    13476, 13478, 13480, 13482, 13485, 13487, 13490, 13492, 13494, 13496, 
-    13498, 13500, 13502, 13504, 13506, 13508, 13510, 13512, 13515, 13517, 
-    13519, 13521, 13523, 13525, 13528, 13530, 13533, 13536, 13538, 13540, 
-    13542, 13544, 13547, 13550, 13552, 13554, 13556, 13558, 13560, 13562, 
-    13564, 13566, 13568, 13570, 13572, 13575, 13577, 13579, 13581, 13583, 
-    13585, 13587, 13589, 13591, 13593, 13595, 13597, 13599, 13601, 13603, 
-    13605, 13607, 13609, 13611, 13613, 13616, 13618, 13620, 13622, 13624, 
-    13626, 13629, 13631, 13633, 13635, 13637, 13639, 13641, 13643, 13645, 
-    13647, 13649, 13651, 13654, 13656, 13658, 13660, 13662, 13664, 13666, 
-    13668, 13670, 13672, 13674, 13676, 13678, 13680, 13682, 13684, 13686, 
-    13688, 13690, 13693, 13695, 13697, 13699, 13701, 13703, 13706, 13708, 
-    13710, 13712, 13714, 13716, 13718, 13720, 13722, 13725, 13727, 13729, 
-    13731, 13734, 13736, 13738, 13740, 13742, 13744, 13746, 13749, 13752, 
-    13755, 13757, 13760, 13762, 13764, 13766, 13768, 13770, 13772, 13774, 
-    13776, 13778, 13780, 13783, 13785, 13787, 13789, 13791, 13793, 13795, 
-    13798, 13800, 13802, 13805, 13808, 13810, 13812, 13814, 13816, 13818, 
-    13820, 13822, 13824, 13826, 13829, 13831, 13834, 13836, 13839, 13841, 
-    13843, 13845, 13848, 13850, 13852, 13855, 13858, 13860, 13862, 13864, 
-    13866, 13868, 13870, 13872, 13874, 13876, 13878, 13880, 13882, 13884, 
-    13887, 13889, 13892, 13894, 13897, 13899, 13902, 13905, 13908, 13910, 
-    13912, 13914, 13917, 13920, 13923, 13926, 13928, 13930, 13932, 13934, 
-    13936, 13938, 13940, 13942, 13945, 13947, 13949, 13951, 13953, 13956, 
-    13958, 13961, 13964, 13966, 13968, 13970, 13972, 13974, 13976, 13979, 
-    13982, 13985, 13987, 13989, 13992, 13994, 13996, 13998, 14001, 14003, 
-    14005, 14007, 14009, 14011, 14014, 14016, 14018, 14020, 14022, 14024, 
-    14026, 14029, 14032, 14034, 14037, 14039, 14042, 14044, 14046, 14048, 
-    14051, 14054, 14056, 14059, 14061, 14064, 14066, 14068, 14070, 14072, 
-    14074, 14076, 14079, 14082, 14085, 14088, 14090, 14092, 14094, 14096, 
-    14098, 14100, 14102, 14104, 14106, 14108, 14110, 14112, 14115, 14117, 
-    14119, 14121, 14123, 14125, 14127, 14129, 14131, 14133, 14135, 14137, 
-    14139, 14142, 14145, 14148, 14150, 14152, 14154, 14156, 14159, 14161, 
-    14164, 14166, 14168, 14171, 14174, 14176, 14178, 14180, 14182, 14184, 
-    14186, 14188, 14190, 14192, 14194, 14196, 14198, 14200, 14202, 14204, 
-    14206, 14208, 14210, 14212, 14215, 14217, 14219, 14221, 14223, 14225, 
-    14228, 14231, 14233, 14235, 14237, 14239, 14241, 14243, 14246, 14248, 
-    14250, 14252, 14254, 14257, 14260, 14262, 14264, 14266, 14269, 14271, 
-    14273, 14276, 14279, 14281, 14283, 14285, 14288, 14290, 14292, 14294, 
-    14296, 14298, 14300, 14302, 14305, 14307, 14309, 14311, 14314, 14316, 
-    14318, 14320, 14322, 14325, 14328, 14330, 14332, 14334, 14337, 14339, 
-    14342, 14344, 14346, 14348, 14351, 14353, 14355, 14357, 14359, 14361, 
-    14363, 14365, 14368, 14370, 14372, 14374, 14376, 14378, 14380, 14383, 
-    14385, 14388, 14391, 14394, 14396, 14398, 14400, 14402, 14404, 14406, 
-    14408, 14410, 0, 0, 
-};
-
-/* NFC pairs */
-#define COMP_SHIFT1 2
-#define COMP_SHIFT2 1
-static const unsigned short comp_index0[] = {
-    0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 4, 
-    5, 6, 7, 0, 0, 0, 0, 8, 0, 9, 10, 0, 0, 0, 11, 12, 13, 14, 0, 0, 0, 0, 0, 
-    15, 16, 17, 0, 0, 0, 0, 18, 19, 20, 21, 0, 0, 0, 0, 22, 0, 0, 0, 0, 0, 0, 
-    23, 24, 25, 26, 0, 0, 0, 0, 27, 28, 29, 30, 0, 0, 0, 0, 31, 32, 33, 34, 
-    0, 0, 0, 0, 35, 0, 0, 0, 0, 0, 0, 36, 0, 37, 38, 39, 0, 0, 0, 40, 41, 42, 
-    43, 0, 0, 0, 0, 44, 45, 46, 0, 0, 0, 0, 0, 47, 48, 49, 50, 0, 0, 0, 51, 
-    52, 53, 54, 0, 0, 0, 0, 55, 56, 0, 0, 0, 0, 0, 0, 57, 58, 59, 60, 0, 0, 
-    0, 0, 61, 62, 63, 0, 0, 0, 0, 0, 64, 65, 66, 67, 0, 0, 0, 68, 69, 70, 71, 
-    0, 0, 0, 0, 72, 0, 73, 0, 0, 0, 0, 0, 74, 0, 75, 0, 0, 0, 0, 0, 76, 0, 0, 
-    0, 0, 0, 0, 77, 78, 79, 0, 0, 0, 0, 0, 80, 81, 82, 83, 0, 0, 0, 0, 84, 
-    85, 86, 0, 0, 0, 0, 0, 87, 88, 0, 89, 0, 0, 0, 90, 91, 0, 92, 0, 0, 0, 0, 
-    0, 93, 94, 95, 0, 0, 0, 0, 96, 97, 98, 99, 0, 0, 0, 0, 100, 0, 0, 0, 0, 
-    0, 0, 101, 102, 0, 103, 0, 0, 0, 0, 104, 105, 106, 107, 0, 0, 0, 0, 108, 
-    109, 110, 111, 0, 0, 0, 0, 112, 113, 0, 0, 0, 0, 0, 114, 115, 116, 117, 
-    0, 0, 0, 0, 118, 119, 120, 121, 0, 0, 0, 0, 122, 0, 123, 0, 0, 0, 0, 124, 
-    125, 126, 127, 128, 0, 0, 0, 129, 130, 131, 132, 0, 0, 0, 0, 133, 134, 0, 
-    0, 0, 0, 0, 0, 135, 136, 137, 138, 0, 0, 0, 139, 140, 141, 142, 0, 0, 0, 
-    0, 0, 143, 144, 145, 0, 0, 0, 0, 146, 147, 148, 149, 0, 0, 0, 0, 150, 0, 
-    151, 0, 0, 0, 0, 152, 153, 154, 0, 0, 0, 0, 0, 0, 155, 0, 0, 0, 0, 0, 0, 
-    156, 157, 158, 0, 0, 0, 0, 0, 159, 160, 161, 162, 0, 0, 0, 163, 0, 0, 0, 
-    164, 0, 0, 0, 165, 166, 0, 0, 0, 0, 0, 0, 167, 0, 0, 0, 0, 0, 0, 0, 168, 
-    0, 0, 0, 0, 0, 0, 169, 170, 0, 0, 0, 0, 0, 0, 171, 0, 0, 0, 0, 0, 0, 0, 
-    172, 173, 0, 0, 0, 0, 0, 0, 174, 0, 0, 0, 0, 0, 0, 175, 176, 0, 0, 0, 0, 
-    0, 0, 177, 178, 0, 0, 0, 0, 0, 0, 179, 0, 0, 0, 0, 0, 0, 0, 180, 0, 0, 0, 
-    0, 0, 0, 181, 182, 183, 0, 0, 0, 0, 0, 184, 185, 0, 0, 0, 0, 0, 0, 186, 
-    0, 0, 0, 0, 0, 0, 0, 187, 0, 0, 0, 0, 0, 0, 188, 189, 0, 0, 0, 0, 0, 0, 
-    190, 0, 0, 0, 0, 0, 0, 0, 191, 192, 0, 0, 0, 0, 0, 0, 193, 0, 0, 0, 0, 0, 
-    0, 194, 195, 0, 0, 0, 0, 0, 0, 196, 197, 0, 0, 0, 0, 0, 0, 198, 0, 0, 0, 
-    0, 0, 0, 0, 199, 0, 0, 0, 0, 0, 0, 200, 201, 202, 0, 0, 0, 0, 0, 203, 
-    204, 0, 0, 0, 0, 0, 0, 205, 206, 0, 0, 0, 0, 0, 0, 207, 0, 0, 0, 0, 0, 0, 
-    208, 0, 0, 0, 0, 0, 0, 0, 209, 0, 0, 0, 0, 0, 0, 0, 210, 0, 0, 0, 0, 0, 
-    0, 0, 211, 0, 0, 0, 0, 0, 0, 0, 212, 0, 0, 0, 0, 0, 0, 0, 213, 0, 0, 0, 
-    0, 0, 0, 0, 214, 0, 0, 0, 0, 0, 0, 215, 0, 0, 0, 0, 0, 0, 216, 0, 0, 0, 
-    0, 0, 0, 0, 0, 217, 0, 0, 0, 0, 0, 0, 0, 218, 0, 0, 0, 0, 0, 0, 219, 0, 
-    0, 0, 0, 0, 0, 220, 221, 222, 0, 0, 0, 0, 0, 223, 224, 225, 0, 0, 0, 0, 
-    0, 226, 227, 228, 0, 0, 0, 0, 0, 229, 230, 231, 0, 0, 0, 0, 0, 0, 232, 0, 
-    0, 0, 0, 0, 0, 233, 0, 0, 0, 0, 0, 0, 234, 0, 0, 0, 0, 0, 0, 0, 235, 0, 
-    0, 0, 0, 0, 0, 0, 236, 0, 0, 0, 0, 0, 0, 0, 237, 0, 0, 0, 0, 0, 0, 238, 
-    0, 0, 0, 0, 0, 0, 0, 239, 0, 0, 0, 0, 0, 0, 0, 240, 0, 0, 0, 0, 0, 0, 0, 
-    241, 0, 0, 0, 0, 0, 0, 242, 0, 243, 244, 0, 0, 0, 0, 245, 246, 0, 0, 0, 
-    0, 0, 247, 0, 248, 0, 249, 0, 0, 0, 250, 251, 252, 0, 0, 0, 0, 0, 253, 0, 
-    254, 0, 0, 0, 0, 0, 0, 255, 0, 0, 0, 0, 0, 256, 257, 258, 0, 0, 0, 0, 0, 
-    259, 0, 260, 0, 261, 0, 0, 0, 0, 0, 0, 262, 0, 0, 0, 0, 0, 0, 0, 263, 0, 
-    0, 0, 264, 265, 266, 0, 267, 0, 0, 0, 268, 0, 269, 0, 0, 0, 0, 0, 270, 0, 
-    271, 272, 0, 0, 0, 0, 273, 274, 0, 275, 0, 0, 0, 276, 0, 277, 0, 0, 0, 0, 
-    0, 0, 0, 278, 0, 0, 0, 0, 0, 279, 280, 281, 282, 0, 0, 0, 0, 283, 284, 0, 
-    285, 0, 0, 0, 286, 0, 0, 0, 287, 0, 0, 0, 288, 0, 0, 0, 289, 0, 0, 0, 0, 
-    0, 0, 290, 0, 0, 0, 0, 291, 0, 0, 0, 0, 0, 0, 0, 292, 0, 0, 0, 0, 0, 0, 
-    0, 293, 0, 0, 0, 0, 0, 0, 294, 0, 0, 0, 0, 0, 0, 0, 295, 0, 0, 0, 0, 0, 
-    0, 0, 296, 0, 0, 0, 0, 0, 0, 0, 297, 0, 0, 0, 0, 0, 0, 298, 299, 0, 0, 0, 
-    0, 0, 0, 300, 0, 0, 0, 0, 0, 0, 0, 301, 0, 0, 0, 0, 0, 0, 0, 302, 0, 0, 
-    0, 0, 0, 0, 0, 303, 0, 0, 0, 0, 0, 0, 304, 0, 0, 0, 0, 0, 0, 0, 305, 0, 
-    0, 0, 0, 0, 0, 0, 306, 0, 0, 0, 0, 0, 0, 307, 0, 0, 0, 0, 0, 0, 0, 308, 
-    0, 0, 0, 0, 0, 0, 0, 309, 0, 0, 0, 0, 0, 0, 0, 310, 0, 0, 0, 0, 0, 0, 
-    311, 312, 0, 0, 0, 0, 0, 0, 313, 0, 0, 0, 0, 0, 0, 0, 314, 0, 0, 0, 0, 0, 
-    0, 0, 315, 0, 0, 0, 0, 0, 0, 0, 316, 0, 0, 0, 0, 0, 0, 317, 0, 0, 0, 0, 
-    0, 0, 0, 318, 0, 0, 0, 0, 0, 0, 0, 319, 0, 0, 0, 0, 0, 0, 0, 320, 0, 0, 
-    0, 0, 0, 0, 0, 321, 0, 0, 0, 0, 0, 0, 322, 0, 0, 0, 0, 0, 0, 0, 323, 0, 
-    0, 0, 0, 0, 0, 0, 324, 0, 0, 0, 0, 0, 0, 325, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 326, 0, 0, 0, 0, 0, 0, 0, 327, 0, 0, 0, 0, 0, 0, 0, 328, 0, 0, 0, 0, 
-    0, 0, 329, 0, 0, 0, 0, 0, 0, 0, 330, 0, 0, 0, 0, 0, 0, 0, 331, 0, 0, 0, 
-    0, 0, 0, 0, 332, 0, 0, 0, 0, 0, 0, 0, 333, 0, 0, 0, 0, 0, 0, 334, 0, 0, 
-    0, 0, 0, 0, 0, 335, 0, 0, 0, 0, 0, 0, 0, 336, 337, 0, 0, 0, 0, 0, 0, 0, 
-    338, 0, 0, 0, 0, 0, 0, 339, 0, 0, 0, 0, 0, 0, 0, 340, 0, 0, 0, 0, 0, 0, 
-    0, 341, 0, 0, 0, 0, 0, 0, 0, 342, 0, 0, 0, 0, 0, 0, 0, 343, 0, 0, 0, 0, 
-    0, 0, 344, 0, 0, 0, 0, 0, 0, 0, 345, 346, 0, 0, 0, 0, 0, 0, 347, 0, 0, 0, 
-    0, 0, 0, 0, 348, 0, 0, 0, 0, 0, 0, 0, 349, 0, 0, 0, 0, 0, 0, 0, 350, 0, 
-    0, 0, 0, 0, 0, 0, 351, 0, 0, 0, 0, 0, 0, 0, 352, 0, 0, 0, 0, 0, 0, 353, 
-    0, 0, 0, 0, 0, 0, 0, 354, 0, 0, 0, 0, 0, 0, 0, 355, 0, 0, 0, 0, 0, 0, 0, 
-    356, 0, 0, 0, 0, 0, 0, 357, 0, 0, 0, 0, 0, 0, 0, 358, 0, 0, 0, 0, 0, 0, 
-    0, 359, 0, 0, 0, 0, 0, 0, 0, 360, 0, 0, 0, 0, 0, 0, 361, 0, 362, 0, 0, 0, 
-    0, 0, 0, 0, 363, 0, 0, 0, 0, 0, 0, 0, 364, 0, 0, 0, 0, 0, 0, 0, 365, 0, 
-    0, 0, 0, 0, 0, 0, 366, 0, 0, 0, 0, 0, 0, 367, 0, 0, 0, 0, 0, 0, 0, 368, 
-    0, 0, 0, 0, 0, 0, 369, 370, 0, 0, 0, 0, 0, 0, 371, 0, 0, 0, 0, 0, 0, 0, 
-    372, 0, 0, 0, 0, 0, 0, 0, 373, 0, 0, 0, 0, 0, 0, 374, 0, 0, 0, 0, 0, 0, 
-    0, 375, 0, 0, 376, 0, 0, 0, 0, 377, 0, 0, 378, 0, 0, 0, 0, 0, 0, 0, 379, 
-    0, 0, 0, 0, 0, 0, 0, 380, 0, 0, 0, 0, 0, 0, 381, 0, 0, 0, 0, 0, 0, 0, 
-    382, 0, 0, 0, 0, 0, 0, 0, 383, 0, 0, 0, 0, 0, 0, 0, 384, 0, 0, 0, 385, 0, 
-    0, 386, 0, 0, 0, 0, 387, 0, 0, 388, 0, 0, 0, 0, 0, 0, 0, 389, 0, 0, 0, 0, 
-    0, 0, 0, 390, 0, 0, 0, 0, 0, 0, 391, 0, 0, 0, 0, 0, 0, 0, 392, 0, 0, 0, 
-    0, 0, 0, 0, 393, 0, 0, 0, 0, 0, 0, 0, 394, 0, 0, 0, 395, 0, 0, 0, 0, 0, 
-    0, 0, 396, 0, 0, 0, 0, 0, 0, 397, 0, 0, 0, 0, 0, 0, 0, 398, 0, 0, 0, 0, 
-    0, 0, 0, 399, 0, 0, 400, 0, 0, 0, 0, 401, 0, 0, 402, 0, 0, 0, 0, 0, 0, 0, 
-    403, 0, 0, 0, 0, 0, 0, 0, 404, 0, 0, 0, 0, 0, 0, 405, 0, 0, 0, 0, 0, 0, 
-    0, 406, 0, 0, 0, 0, 0, 0, 0, 407, 0, 0, 0, 0, 0, 0, 0, 408, 0, 0, 0, 409, 
-    0, 0, 410, 0, 0, 0, 0, 411, 0, 0, 412, 0, 0, 0, 0, 0, 0, 0, 413, 0, 0, 0, 
-    0, 0, 0, 0, 414, 0, 0, 0, 0, 0, 0, 415, 0, 0, 0, 0, 0, 0, 0, 416, 0, 0, 
-    0, 0, 0, 0, 0, 417, 0, 0, 0, 0, 0, 0, 0, 418, 0, 0, 0, 419, 0, 0, 420, 0, 
-    0, 0, 0, 421, 0, 0, 422, 0, 0, 0, 423, 0, 0, 0, 424, 0, 0, 0, 425, 0, 0, 
-    0, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 0, 0, 428, 0, 0, 0, 0, 0, 0, 429, 0, 
-    0, 0, 0, 0, 0, 0, 430, 0, 0, 0, 0, 0, 0, 0, 431, 0, 0, 432, 0, 0, 0, 0, 
-    433, 0, 0, 434, 0, 0, 0, 435, 0, 0, 0, 436, 0, 0, 0, 437, 0, 0, 0, 438, 
-    0, 0, 0, 439, 0, 0, 440, 0, 0, 0, 0, 0, 0, 0, 441, 0, 0, 0, 0, 0, 0, 0, 
-    442, 0, 0, 0, 0, 0, 0, 0, 443, 0, 0, 0, 0, 0, 0, 444, 0, 0, 0, 0, 0, 0, 
-    0, 445, 0, 0, 0, 0, 0, 0, 0, 446, 0, 0, 0, 447, 0, 0, 0, 448, 0, 0, 0, 
-    449, 0, 0, 450, 0, 0, 0, 0, 0, 0, 0, 451, 0, 0, 0, 0, 0, 0, 0, 452, 0, 0, 
-    0, 0, 0, 0, 0, 453, 0, 0, 0, 0, 0, 0, 454, 0, 0, 0, 0, 0, 0, 0, 455, 0, 
-    0, 0, 0, 0, 0, 0, 456, 0, 0, 0, 0, 0, 0, 0, 457, 0, 0, 0, 0, 0, 0, 458, 
-    0, 0, 0, 0, 0, 0, 0, 459, 0, 0, 0, 0, 0, 0, 0, 460, 0, 0, 0, 461, 0, 0, 
-    0, 462, 0, 0, 0, 0, 0, 0, 463, 0, 0, 0, 0, 0, 0, 0, 464, 0, 0, 0, 465, 0, 
-    0, 0, 466, 0, 0, 0, 0, 0, 0, 467, 0, 0, 0, 0, 0, 0, 0, 468, 0, 0, 0, 0, 
-    0, 0, 0, 469, 0, 0, 0, 0, 0, 0, 0, 470, 0, 0, 0, 0, 0, 0, 471, 0, 0, 0, 
-    0, 0, 0, 0, 472, 0, 0, 0, 0, 0, 0, 0, 473, 0, 0, 0, 0, 0, 0, 0, 474, 0, 
-    0, 0, 0, 0, 0, 475, 0, 0, 0, 0, 0, 0, 0, 476, 0, 0, 0, 0, 0, 0, 0, 477, 
-    0, 0, 0, 0, 0, 0, 0, 478, 0, 0, 0, 0, 0, 0, 479, 0, 0, 0, 0, 0, 0, 0, 
-    480, 0, 0, 0, 0, 0, 0, 0, 481, 0, 0, 0, 0, 0, 0, 0, 482, 0, 0, 0, 0, 0, 
-    0, 483, 0, 0, 0, 0, 0, 0, 0, 484, 0, 0, 0, 0, 0, 0, 0, 485, 0, 0, 0, 0, 
-    0, 0, 0, 486, 0, 0, 0, 0, 0, 0, 487, 0, 0, 0, 0, 0, 0, 0, 488, 0, 0, 0, 
-    0, 0, 0, 0, 489, 0, 0, 0, 0, 0, 0, 0, 490, 0, 0, 0, 0, 0, 0, 491, 0, 0, 
-    0, 0, 0, 0, 0, 492, 0, 0, 0, 0, 0, 0, 0, 493, 0, 0, 0, 0, 0, 0, 0, 494, 
-    0, 0, 0, 0, 0, 0, 495, 0, 0, 0, 0, 0, 0, 0, 496, 0, 0, 0, 0, 0, 0, 0, 
-    497, 0, 0, 0, 0, 0, 0, 0, 498, 0, 0, 0, 0, 0, 0, 499, 0, 0, 0, 0, 0, 0, 
-    0, 500, 0, 0, 0, 0, 0, 0, 0, 501, 0, 0, 0, 0, 0, 0, 0, 502, 0, 0, 0, 0, 
-    0, 0, 503, 0, 0, 0, 0, 0, 0, 0, 504, 0, 0, 0, 0, 0, 0, 0, 505, 0, 0, 0, 
-    0, 0, 0, 0, 506, 0, 0, 0, 0, 0, 0, 507, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    508, 0, 0, 0, 0, 0, 0, 0, 509, 0, 0, 0, 0, 0, 0, 0, 510, 0, 0, 0, 0, 0, 
-    0, 0, 511, 0, 0, 0, 0, 0, 0, 512, 0, 0, 0, 0, 0, 0, 0, 513, 0, 0, 0, 0, 
-    0, 0, 0, 514, 0, 0, 0, 0, 0, 0, 0, 515, 0, 0, 0, 0, 0, 0, 516, 0, 0, 0, 
-    0, 0, 0, 0, 517, 0, 0, 0, 0, 0, 0, 0, 518, 0, 0, 0, 0, 0, 0, 0, 519, 0, 
-    0, 0, 0, 0, 0, 520, 0, 0, 0, 0, 0, 0, 0, 521, 0, 0, 0, 0, 0, 0, 0, 522, 
-    0, 0, 0, 0, 0, 0, 0, 523, 0, 0, 0, 0, 0, 0, 524, 0, 0, 0, 0, 0, 0, 0, 
-    525, 0, 0, 0, 0, 0, 0, 0, 526, 0, 0, 0, 0, 0, 0, 0, 527, 0, 0, 0, 0, 0, 
-    0, 528, 0, 0, 0, 0, 0, 0, 0, 529, 0, 0, 0, 0, 0, 0, 0, 530, 0, 0, 0, 0, 
-    0, 0, 0, 531, 0, 0, 0, 0, 0, 0, 532, 0, 0, 0, 0, 0, 0, 0, 533, 0, 0, 0, 
-    0, 0, 0, 0, 534, 0, 0, 0, 0, 0, 0, 0, 535, 0, 0, 0, 0, 0, 0, 536, 0, 0, 
-    0, 0, 0, 0, 0, 537, 0, 0, 0, 0, 0, 0, 0, 538, 0, 0, 0, 0, 0, 0, 0, 539, 
-    0, 0, 0, 0, 0, 0, 540, 0, 0, 0, 0, 0, 0, 0, 541, 0, 0, 0, 0, 0, 0, 0, 
-    542, 0, 0, 0, 0, 0, 0, 0, 543, 0, 0, 0, 0, 0, 0, 544, 0, 0, 0, 0, 0, 0, 
-    0, 545, 0, 0, 0, 0, 0, 0, 0, 546, 0, 0, 0, 0, 0, 0, 0, 547, 0, 0, 0, 0, 
-    0, 0, 548, 0, 0, 0, 0, 0, 0, 0, 549, 0, 0, 0, 0, 0, 0, 0, 550, 0, 0, 0, 
-    0, 0, 0, 0, 551, 0, 0, 0, 0, 0, 0, 552, 0, 0, 0, 0, 0, 0, 0, 553, 0, 0, 
-    0, 0, 0, 0, 0, 554, 0, 0, 0, 0, 0, 0, 0, 555, 0, 0, 0, 0, 0, 0, 0, 556, 
-    0, 0, 0, 0, 0, 0, 557, 0, 0, 0, 0, 0, 0, 0, 558, 0, 0, 0, 0, 0, 0, 0, 
-    559, 0, 0, 0, 0, 0, 0, 0, 560, 0, 0, 0, 0, 0, 0, 0, 561, 0, 0, 0, 0, 0, 
-    0, 0, 562, 0, 0, 0, 0, 0, 0, 0, 563, 0, 0, 0, 0, 0, 0, 564, 
-};
-
-static const unsigned short comp_index1[] = {
-    0, 0, 0, 0, 0, 1, 0, 0, 2, 0, 0, 0, 0, 0, 0, 3, 0, 4, 5, 6, 7, 8, 9, 10, 
-    0, 11, 12, 0, 13, 0, 0, 0, 0, 0, 0, 14, 15, 0, 0, 0, 0, 16, 0, 0, 0, 0, 
-    0, 17, 18, 0, 19, 0, 20, 0, 0, 0, 0, 21, 0, 0, 0, 22, 0, 23, 0, 0, 24, 0, 
-    25, 26, 0, 27, 0, 28, 29, 30, 31, 32, 33, 34, 0, 35, 0, 36, 37, 38, 0, 0, 
-    0, 0, 0, 39, 0, 0, 0, 40, 41, 42, 43, 0, 44, 0, 0, 0, 0, 45, 0, 0, 0, 0, 
-    0, 46, 0, 47, 0, 48, 0, 0, 49, 0, 50, 0, 51, 0, 0, 52, 53, 54, 55, 56, 
-    57, 58, 0, 59, 0, 0, 60, 61, 0, 0, 0, 62, 0, 0, 0, 0, 0, 63, 64, 0, 0, 
-    65, 0, 66, 0, 0, 67, 0, 0, 0, 0, 0, 68, 0, 0, 0, 0, 69, 0, 0, 70, 0, 71, 
-    72, 0, 73, 0, 74, 0, 0, 75, 0, 0, 0, 0, 76, 0, 0, 77, 78, 0, 79, 0, 80, 
-    0, 0, 81, 0, 82, 83, 0, 84, 0, 0, 0, 0, 0, 85, 86, 87, 88, 89, 90, 91, 0, 
-    92, 0, 0, 93, 0, 0, 0, 94, 0, 0, 95, 0, 0, 0, 96, 0, 0, 97, 0, 98, 99, 0, 
-    100, 0, 101, 0, 0, 102, 0, 103, 104, 0, 105, 0, 106, 0, 0, 107, 0, 108, 
-    0, 0, 0, 109, 0, 110, 0, 0, 111, 0, 112, 113, 0, 114, 0, 0, 0, 0, 0, 115, 
-    116, 117, 118, 119, 120, 121, 0, 122, 123, 0, 124, 125, 0, 0, 0, 126, 0, 
-    0, 127, 0, 0, 128, 129, 0, 130, 131, 0, 0, 0, 0, 0, 132, 0, 0, 0, 133, 
-    134, 135, 136, 137, 0, 0, 0, 138, 0, 0, 139, 140, 0, 141, 0, 142, 0, 0, 
-    143, 0, 0, 0, 0, 144, 0, 145, 146, 147, 148, 149, 150, 151, 0, 152, 153, 
-    0, 154, 0, 0, 155, 0, 0, 0, 0, 156, 157, 0, 0, 0, 0, 0, 158, 159, 0, 160, 
-    0, 161, 162, 0, 0, 0, 163, 0, 164, 0, 0, 165, 0, 166, 167, 0, 168, 0, 
-    169, 170, 171, 172, 173, 174, 175, 0, 176, 0, 177, 178, 179, 0, 0, 0, 0, 
-    0, 180, 0, 0, 0, 181, 182, 183, 184, 0, 185, 186, 0, 0, 0, 0, 0, 187, 0, 
-    188, 0, 189, 0, 0, 190, 0, 191, 0, 192, 193, 0, 194, 195, 196, 197, 198, 
-    199, 200, 0, 201, 0, 0, 202, 203, 0, 0, 0, 204, 0, 0, 0, 205, 0, 0, 0, 0, 
-    0, 206, 0, 0, 0, 0, 207, 0, 0, 208, 0, 209, 0, 0, 210, 0, 211, 0, 0, 0, 
-    0, 212, 0, 0, 213, 0, 214, 215, 0, 216, 0, 217, 0, 0, 218, 219, 0, 0, 0, 
-    0, 0, 0, 220, 221, 0, 222, 0, 223, 0, 0, 224, 0, 225, 226, 0, 227, 0, 0, 
-    0, 0, 0, 228, 229, 230, 231, 232, 233, 234, 0, 235, 0, 0, 236, 0, 0, 0, 
-    237, 0, 0, 238, 0, 0, 0, 239, 0, 0, 240, 0, 241, 242, 0, 243, 0, 244, 0, 
-    0, 245, 0, 0, 0, 0, 0, 246, 247, 0, 248, 0, 249, 0, 0, 250, 0, 251, 0, 0, 
-    0, 252, 0, 253, 0, 0, 254, 0, 255, 256, 0, 257, 0, 258, 259, 260, 261, 
-    262, 263, 264, 0, 265, 266, 0, 267, 268, 0, 0, 0, 269, 0, 0, 270, 0, 0, 
-    0, 0, 0, 0, 271, 272, 0, 273, 274, 0, 0, 0, 275, 0, 276, 0, 0, 0, 277, 
-    278, 279, 280, 281, 0, 0, 0, 282, 0, 0, 283, 284, 0, 285, 0, 286, 0, 0, 
-    287, 0, 0, 0, 0, 288, 0, 0, 0, 0, 0, 289, 0, 290, 0, 0, 0, 0, 291, 292, 
-    0, 0, 293, 0, 0, 0, 0, 294, 295, 0, 0, 0, 0, 0, 0, 296, 0, 297, 0, 0, 0, 
-    0, 298, 0, 0, 299, 300, 0, 0, 301, 0, 0, 302, 0, 0, 0, 0, 0, 0, 303, 304, 
-    0, 0, 305, 0, 0, 306, 0, 307, 308, 0, 0, 0, 0, 0, 309, 310, 0, 0, 0, 0, 
-    0, 0, 311, 0, 312, 0, 0, 313, 0, 0, 0, 0, 0, 314, 315, 0, 0, 316, 0, 0, 
-    0, 0, 317, 318, 0, 0, 0, 0, 0, 0, 319, 0, 320, 0, 0, 0, 0, 321, 0, 0, 
-    322, 323, 0, 0, 324, 0, 0, 325, 0, 0, 0, 0, 0, 0, 326, 327, 0, 0, 328, 0, 
-    0, 329, 0, 330, 331, 0, 0, 0, 0, 0, 332, 333, 0, 0, 0, 0, 0, 0, 334, 0, 
-    335, 0, 0, 336, 0, 0, 0, 0, 0, 337, 338, 0, 0, 339, 0, 0, 340, 341, 0, 0, 
-    342, 0, 0, 343, 0, 0, 0, 0, 0, 0, 344, 0, 0, 345, 0, 0, 346, 0, 0, 0, 0, 
-    0, 347, 0, 0, 348, 0, 0, 349, 0, 0, 350, 0, 0, 0, 351, 0, 0, 0, 0, 0, 0, 
-    352, 0, 353, 0, 0, 354, 0, 0, 0, 0, 0, 0, 355, 0, 0, 0, 356, 357, 0, 0, 
-    358, 0, 0, 0, 359, 0, 0, 360, 361, 0, 0, 362, 0, 0, 0, 363, 0, 0, 364, 
-    365, 0, 0, 366, 0, 0, 0, 367, 0, 0, 368, 369, 0, 0, 370, 0, 0, 0, 371, 0, 
-    0, 0, 372, 0, 0, 0, 373, 0, 0, 0, 0, 0, 0, 374, 0, 0, 375, 0, 0, 376, 0, 
-    0, 377, 0, 0, 0, 0, 0, 0, 378, 0, 0, 379, 0, 0, 380, 0, 0, 0, 0, 0, 381, 
-    0, 382, 0, 383, 384, 0, 0, 0, 0, 0, 0, 385, 386, 0, 0, 0, 0, 0, 0, 387, 
-    0, 0, 0, 388, 0, 0, 389, 0, 0, 390, 0, 0, 0, 0, 391, 0, 392, 393, 0, 0, 
-    0, 394, 0, 0, 0, 395, 0, 0, 396, 0, 0, 0, 0, 0, 0, 397, 0, 0, 0, 398, 0, 
-    399, 400, 0, 0, 0, 401, 0, 0, 0, 402, 0, 0, 403, 0, 0, 404, 0, 0, 0, 0, 
-    0, 0, 405, 0, 0, 406, 0, 0, 0, 0, 407, 0, 408, 0, 0, 0, 0, 409, 0, 0, 
-    410, 0, 0, 0, 0, 411, 0, 0, 412, 0, 0, 0, 413, 0, 0, 414, 0, 0, 0, 0, 0, 
-    0, 415, 416, 0, 417, 418, 0, 0, 0, 419, 0, 0, 420, 0, 0, 0, 0, 421, 0, 0, 
-    422, 0, 0, 423, 0, 0, 0, 424, 0, 425, 426, 0, 0, 0, 427, 0, 0, 0, 0, 0, 
-    0, 428, 429, 0, 0, 0, 0, 0, 0, 430, 0, 0, 431, 0, 0, 0, 0, 432, 0, 433, 
-    0, 0, 0, 0, 434, 0, 435, 0, 0, 0, 0, 0, 0, 436, 437, 0, 0, 438, 0, 0, 
-    439, 0, 440, 441, 0, 0, 0, 442, 0, 0, 443, 0, 444, 445, 0, 446, 447, 0, 
-    0, 448, 0, 0, 0, 449, 0, 450, 451, 0, 0, 0, 452, 0, 0, 0, 0, 0, 453, 0, 
-    454, 455, 0, 456, 457, 0, 0, 0, 0, 0, 0, 458, 0, 0, 459, 0, 460, 461, 0, 
-    0, 0, 462, 0, 0, 463, 0, 464, 465, 0, 466, 467, 0, 0, 468, 0, 0, 0, 469, 
-    0, 470, 471, 0, 0, 0, 472, 0, 0, 0, 0, 0, 473, 0, 474, 475, 0, 476, 477, 
-    0, 0, 0, 0, 0, 0, 478, 0, 0, 479, 0, 0, 480, 0, 0, 0, 0, 0, 481, 0, 0, 
-    482, 0, 0, 0, 483, 0, 0, 484, 0, 0, 485, 0, 0, 0, 0, 0, 0, 486, 0, 0, 
-    487, 488, 0, 489, 0, 0, 490, 0, 0, 0, 0, 0, 0, 491, 0, 0, 492, 0, 0, 493, 
-    0, 0, 0, 494, 0, 0, 495, 0, 0, 0, 0, 0, 0, 496, 0, 0, 0, 497, 0, 0, 0, 
-    498, 499, 0, 0, 0, 500, 0, 0, 0, 0, 0, 501, 502, 0, 503, 0, 0, 0, 504, 0, 
-    0, 0, 505, 0, 0, 506, 507, 0, 0, 0, 0, 0, 508, 0, 0, 0, 509, 510, 0, 0, 
-    0, 0, 0, 511, 0, 0, 0, 512, 513, 0, 514, 0, 0, 0, 0, 515, 0, 0, 516, 0, 
-    0, 517, 0, 0, 0, 0, 0, 0, 518, 0, 0, 519, 0, 0, 520, 0, 0, 521, 0, 0, 0, 
-    0, 0, 0, 522, 0, 0, 523, 0, 0, 524, 0, 0, 525, 0, 0, 0, 0, 0, 0, 526, 0, 
-    0, 0, 527, 0, 0, 528, 0, 0, 529, 0, 0, 530, 0, 0, 0, 531, 0, 0, 0, 0, 0, 
-    0, 532, 533, 534, 0, 0, 0, 0, 0, 535, 536, 0, 0, 0, 0, 0, 537, 0, 0, 538, 
-    0, 0, 539, 0, 0, 0, 0, 0, 0, 540, 0, 541, 0, 0, 0, 0, 0, 542, 543, 0, 0, 
-    0, 0, 0, 544, 0, 0, 545, 0, 0, 546, 0, 0, 0, 0, 0, 0, 547, 0, 0, 548, 0, 
-    0, 549, 0, 0, 550, 0, 0, 0, 0, 551, 0, 0, 0, 0, 0, 552, 553, 0, 0, 0, 0, 
-    0, 554, 0, 0, 555, 0, 0, 556, 0, 0, 0, 0, 0, 0, 557, 0, 0, 558, 0, 0, 
-    559, 0, 0, 560, 0, 0, 0, 0, 561, 0, 0, 562, 0, 0, 0, 0, 0, 0, 563, 0, 0, 
-    564, 0, 0, 565, 0, 0, 0, 0, 0, 566, 567, 0, 0, 0, 0, 0, 568, 0, 0, 569, 
-    0, 0, 570, 0, 0, 0, 0, 0, 0, 571, 0, 0, 572, 0, 0, 573, 0, 0, 574, 0, 0, 
-    0, 0, 575, 0, 0, 0, 0, 0, 576, 577, 0, 0, 0, 0, 0, 578, 0, 0, 579, 0, 0, 
-    580, 0, 0, 0, 0, 0, 0, 581, 0, 0, 582, 0, 0, 583, 0, 0, 584, 0, 0, 0, 0, 
-    585, 0, 0, 0, 0, 0, 586, 587, 0, 0, 0, 0, 0, 588, 0, 0, 0, 0, 589, 0, 
-    590, 0, 0, 0, 0, 591, 0, 592, 0, 0, 0, 0, 593, 0, 0, 594, 0, 0, 0, 0, 0, 
-    0, 595, 0, 0, 596, 0, 0, 597, 0, 0, 0, 0, 0, 598, 599, 0, 0, 0, 0, 0, 
-    600, 0, 0, 0, 0, 601, 0, 602, 0, 0, 0, 0, 603, 0, 604, 0, 0, 0, 0, 605, 
-    0, 0, 0, 0, 0, 606, 0, 0, 607, 0, 0, 608, 0, 0, 609, 0, 0, 0, 0, 0, 0, 
-    610, 0, 0, 611, 0, 0, 612, 0, 0, 0, 0, 613, 0, 614, 0, 0, 0, 0, 615, 0, 
-    0, 0, 0, 0, 616, 0, 0, 617, 0, 0, 618, 0, 0, 619, 0, 0, 0, 0, 0, 0, 620, 
-    0, 0, 621, 0, 0, 622, 0, 0, 623, 0, 0, 0, 0, 0, 0, 624, 0, 0, 625, 0, 0, 
-    626, 0, 0, 0, 0, 627, 0, 628, 0, 0, 0, 0, 0, 0, 629, 0, 0, 630, 0, 0, 0, 
-    0, 631, 0, 632, 0, 0, 0, 0, 0, 633, 0, 0, 634, 0, 0, 635, 0, 0, 636, 0, 
-    0, 0, 0, 0, 0, 637, 0, 0, 638, 0, 0, 639, 0, 0, 640, 0, 0, 0, 0, 0, 0, 
-    641, 0, 0, 642, 0, 0, 643, 0, 0, 644, 0, 0, 0, 0, 0, 0, 645, 0, 0, 646, 
-    0, 0, 647, 0, 0, 648, 0, 0, 0, 0, 0, 0, 649, 0, 0, 650, 0, 0, 651, 0, 0, 
-    652, 0, 0, 0, 0, 0, 0, 653, 0, 0, 654, 0, 0, 655, 0, 0, 656, 0, 0, 0, 0, 
-    0, 0, 657, 0, 0, 658, 0, 0, 659, 0, 0, 660, 0, 0, 0, 0, 0, 0, 661, 0, 0, 
-    662, 0, 0, 663, 0, 0, 664, 0, 0, 0, 0, 0, 0, 665, 0, 0, 666, 0, 0, 667, 
-    0, 0, 668, 0, 0, 0, 0, 0, 0, 669, 0, 0, 670, 0, 0, 671, 0, 0, 672, 0, 0, 
-    0, 0, 0, 0, 673, 0, 0, 0, 674, 0, 0, 675, 0, 0, 676, 0, 0, 677, 0, 0, 0, 
-    0, 0, 0, 678, 0, 0, 679, 0, 0, 680, 0, 0, 681, 0, 0, 0, 0, 0, 0, 682, 0, 
-    0, 683, 0, 0, 684, 0, 0, 685, 0, 0, 0, 0, 0, 0, 686, 0, 0, 687, 0, 0, 
-    688, 0, 0, 689, 0, 0, 0, 0, 0, 0, 690, 0, 0, 691, 0, 0, 692, 0, 0, 693, 
-    0, 0, 0, 0, 0, 0, 694, 0, 0, 695, 0, 0, 696, 0, 0, 697, 0, 0, 0, 0, 0, 0, 
-    698, 0, 0, 699, 0, 0, 700, 0, 0, 701, 0, 0, 0, 0, 0, 0, 702, 0, 0, 703, 
-    0, 0, 704, 0, 0, 705, 0, 0, 0, 0, 0, 0, 706, 0, 0, 707, 0, 0, 708, 0, 0, 
-    709, 0, 0, 0, 0, 0, 0, 710, 0, 0, 711, 0, 0, 712, 0, 0, 713, 0, 0, 0, 0, 
-    0, 0, 714, 0, 0, 715, 0, 0, 716, 0, 0, 717, 0, 0, 0, 0, 0, 0, 718, 0, 0, 
-    719, 0, 0, 720, 0, 0, 721, 0, 0, 0, 722, 0, 0, 0, 0, 0, 0, 723, 0, 0, 
-    724, 0, 0, 725, 0, 0, 726, 0, 0, 0, 727, 0, 0, 0, 728, 729, 0, 0, 730, 0, 
-    0, 0, 0, 0, 0, 731, 
-};
-
-static const unsigned int comp_data[] = {
-    0, 0, 0, 8814, 0, 8800, 0, 8815, 192, 193, 194, 195, 256, 258, 550, 196, 
-    7842, 197, 0, 461, 512, 514, 0, 7840, 0, 7680, 260, 0, 7682, 0, 0, 7684, 
-    7686, 0, 0, 262, 264, 0, 266, 0, 0, 268, 0, 199, 7690, 0, 0, 270, 0, 
-    7692, 0, 7696, 0, 7698, 7694, 0, 200, 201, 202, 7868, 274, 276, 278, 203, 
-    7866, 0, 0, 282, 516, 518, 0, 7864, 0, 552, 280, 7704, 0, 7706, 7710, 0, 
-    0, 500, 284, 0, 7712, 286, 288, 0, 0, 486, 0, 290, 292, 0, 7714, 7718, 0, 
-    542, 0, 7716, 0, 7720, 7722, 0, 204, 205, 206, 296, 298, 300, 304, 207, 
-    7880, 0, 0, 463, 520, 522, 0, 7882, 302, 0, 0, 7724, 308, 0, 0, 7728, 0, 
-    488, 0, 7730, 0, 310, 7732, 0, 0, 313, 0, 317, 0, 7734, 0, 315, 0, 7740, 
-    7738, 0, 0, 7742, 7744, 0, 0, 7746, 504, 323, 0, 209, 7748, 0, 0, 327, 0, 
-    7750, 0, 325, 0, 7754, 7752, 0, 210, 211, 212, 213, 332, 334, 558, 214, 
-    7886, 0, 336, 465, 524, 526, 416, 7884, 490, 0, 0, 7764, 7766, 0, 0, 340, 
-    7768, 0, 0, 344, 528, 530, 0, 7770, 0, 342, 7774, 0, 0, 346, 348, 0, 
-    7776, 0, 0, 352, 0, 7778, 536, 350, 7786, 0, 0, 356, 0, 7788, 538, 354, 
-    0, 7792, 7790, 0, 217, 218, 219, 360, 362, 364, 0, 220, 7910, 366, 368, 
-    467, 532, 534, 431, 7908, 7794, 0, 370, 7798, 0, 7796, 0, 7804, 0, 7806, 
-    7808, 7810, 372, 0, 7814, 7812, 0, 7816, 7818, 7820, 7922, 221, 374, 
-    7928, 562, 0, 7822, 376, 7926, 0, 0, 7924, 0, 377, 7824, 0, 379, 0, 0, 
-    381, 0, 7826, 7828, 0, 224, 225, 226, 227, 257, 259, 551, 228, 7843, 229, 
-    0, 462, 513, 515, 0, 7841, 0, 7681, 261, 0, 7683, 0, 0, 7685, 7687, 0, 0, 
-    263, 265, 0, 267, 0, 0, 269, 0, 231, 7691, 0, 0, 271, 0, 7693, 0, 7697, 
-    0, 7699, 7695, 0, 232, 233, 234, 7869, 275, 277, 279, 235, 7867, 0, 0, 
-    283, 517, 519, 0, 7865, 0, 553, 281, 7705, 0, 7707, 7711, 0, 0, 501, 285, 
-    0, 7713, 287, 289, 0, 0, 487, 0, 291, 293, 0, 7715, 7719, 0, 543, 0, 
-    7717, 0, 7721, 7723, 0, 7830, 0, 236, 237, 238, 297, 299, 301, 0, 239, 
-    7881, 0, 0, 464, 521, 523, 0, 7883, 303, 0, 0, 7725, 309, 0, 0, 496, 0, 
-    7729, 0, 489, 0, 7731, 0, 311, 7733, 0, 0, 314, 0, 318, 0, 7735, 0, 316, 
-    0, 7741, 7739, 0, 0, 7743, 7745, 0, 0, 7747, 505, 324, 0, 241, 7749, 0, 
-    0, 328, 0, 7751, 0, 326, 0, 7755, 7753, 0, 242, 243, 244, 245, 333, 335, 
-    559, 246, 7887, 0, 337, 466, 525, 527, 417, 7885, 491, 0, 0, 7765, 7767, 
-    0, 0, 341, 7769, 0, 0, 345, 529, 531, 0, 7771, 0, 343, 7775, 0, 0, 347, 
-    349, 0, 7777, 0, 0, 353, 0, 7779, 537, 351, 7787, 7831, 0, 357, 0, 7789, 
-    539, 355, 0, 7793, 7791, 0, 249, 250, 251, 361, 363, 365, 0, 252, 7911, 
-    367, 369, 468, 533, 535, 432, 7909, 7795, 0, 371, 7799, 0, 7797, 0, 7805, 
-    0, 7807, 7809, 7811, 373, 0, 7815, 7813, 0, 7832, 0, 7817, 7819, 7821, 
-    7923, 253, 375, 7929, 563, 0, 7823, 255, 7927, 7833, 0, 7925, 0, 378, 
-    7825, 0, 380, 0, 0, 382, 0, 7827, 7829, 0, 8173, 901, 8129, 0, 7846, 
-    7844, 0, 7850, 7848, 0, 478, 0, 0, 506, 0, 508, 482, 0, 0, 7688, 7872, 
-    7870, 0, 7876, 7874, 0, 0, 7726, 7890, 7888, 0, 7894, 7892, 0, 0, 7756, 
-    556, 0, 0, 7758, 554, 0, 0, 510, 475, 471, 469, 0, 0, 473, 7847, 7845, 0, 
-    7851, 7849, 0, 479, 0, 0, 507, 0, 509, 483, 0, 0, 7689, 7873, 7871, 0, 
-    7877, 7875, 0, 0, 7727, 7891, 7889, 0, 7895, 7893, 0, 0, 7757, 557, 0, 0, 
-    7759, 555, 0, 0, 511, 476, 472, 470, 0, 0, 474, 7856, 7854, 0, 7860, 
-    7858, 0, 7857, 7855, 0, 7861, 7859, 0, 7700, 7702, 7701, 7703, 7760, 
-    7762, 7761, 7763, 7780, 0, 7781, 0, 7782, 0, 7783, 0, 0, 7800, 0, 7801, 
-    0, 7802, 0, 7803, 7835, 0, 7900, 7898, 0, 7904, 7902, 0, 0, 7906, 7901, 
-    7899, 0, 7905, 7903, 0, 0, 7907, 7914, 7912, 0, 7918, 7916, 0, 0, 7920, 
-    7915, 7913, 0, 7919, 7917, 0, 0, 7921, 0, 494, 492, 0, 493, 0, 480, 0, 
-    481, 0, 0, 7708, 0, 7709, 560, 0, 561, 0, 0, 495, 8122, 902, 8121, 8120, 
-    7944, 7945, 0, 8124, 8136, 904, 7960, 7961, 8138, 905, 7976, 7977, 0, 
-    8140, 8154, 906, 8153, 8152, 0, 938, 7992, 7993, 8184, 908, 8008, 8009, 
-    0, 8172, 8170, 910, 8169, 8168, 0, 939, 0, 8025, 8186, 911, 8040, 8041, 
-    0, 8188, 0, 8116, 0, 8132, 8048, 940, 8113, 8112, 7936, 7937, 8118, 8115, 
-    8050, 941, 7952, 7953, 8052, 942, 7968, 7969, 8134, 8131, 8054, 943, 
-    8145, 8144, 0, 970, 7984, 7985, 8150, 0, 8056, 972, 8000, 8001, 8164, 
-    8165, 8058, 973, 8161, 8160, 0, 971, 8016, 8017, 8166, 0, 8060, 974, 
-    8032, 8033, 8182, 8179, 8146, 912, 8151, 0, 8162, 944, 8167, 0, 0, 8180, 
-    0, 979, 0, 980, 0, 1031, 0, 1232, 0, 1234, 0, 1027, 1024, 0, 0, 1238, 0, 
-    1025, 0, 1217, 0, 1244, 0, 1246, 1037, 0, 1250, 1049, 0, 1252, 0, 1036, 
-    0, 1254, 1262, 1038, 0, 1264, 1266, 0, 0, 1268, 0, 1272, 0, 1260, 0, 
-    1233, 0, 1235, 0, 1107, 1104, 0, 0, 1239, 0, 1105, 0, 1218, 0, 1245, 0, 
-    1247, 1117, 0, 1251, 1081, 0, 1253, 0, 1116, 0, 1255, 1263, 1118, 0, 
-    1265, 1267, 0, 0, 1269, 0, 1273, 0, 1261, 0, 1111, 1142, 0, 1143, 0, 0, 
-    1242, 0, 1243, 0, 1258, 0, 1259, 1570, 1571, 1573, 0, 0, 1572, 0, 1574, 
-    0, 1730, 0, 1747, 0, 1728, 0, 2345, 0, 2353, 0, 2356, 2507, 2508, 2891, 
-    2888, 2892, 0, 2964, 0, 0, 3018, 3020, 0, 0, 3019, 0, 3144, 0, 3264, 
-    3274, 3271, 3272, 0, 0, 3275, 0, 3402, 3404, 0, 0, 3403, 0, 3546, 3548, 
-    3550, 0, 3549, 4134, 0, 0, 6918, 0, 6920, 0, 6922, 0, 6924, 0, 6926, 0, 
-    6930, 0, 6971, 0, 6973, 0, 6976, 0, 6977, 0, 6979, 7736, 0, 7737, 0, 
-    7772, 0, 7773, 0, 7784, 0, 7785, 0, 7852, 0, 0, 7862, 7853, 0, 0, 7863, 
-    7878, 0, 7879, 0, 7896, 0, 7897, 0, 7938, 7940, 7942, 8064, 7939, 7941, 
-    7943, 8065, 0, 8066, 0, 8067, 0, 8068, 0, 8069, 0, 8070, 0, 8071, 7946, 
-    7948, 7950, 8072, 7947, 7949, 7951, 8073, 0, 8074, 0, 8075, 0, 8076, 0, 
-    8077, 0, 8078, 0, 8079, 7954, 7956, 7955, 7957, 7962, 7964, 7963, 7965, 
-    7970, 7972, 7974, 8080, 7971, 7973, 7975, 8081, 0, 8082, 0, 8083, 0, 
-    8084, 0, 8085, 0, 8086, 0, 8087, 7978, 7980, 7982, 8088, 7979, 7981, 
-    7983, 8089, 0, 8090, 0, 8091, 0, 8092, 0, 8093, 0, 8094, 0, 8095, 7986, 
-    7988, 7990, 0, 7987, 7989, 7991, 0, 7994, 7996, 7998, 0, 7995, 7997, 
-    7999, 0, 8002, 8004, 8003, 8005, 8010, 8012, 8011, 8013, 8018, 8020, 
-    8022, 0, 8019, 8021, 8023, 0, 8027, 8029, 8031, 0, 8034, 8036, 8038, 
-    8096, 8035, 8037, 8039, 8097, 0, 8098, 0, 8099, 0, 8100, 0, 8101, 0, 
-    8102, 0, 8103, 8042, 8044, 8046, 8104, 8043, 8045, 8047, 8105, 0, 8106, 
-    0, 8107, 0, 8108, 0, 8109, 0, 8110, 0, 8111, 0, 8114, 0, 8130, 0, 8178, 
-    0, 8119, 8141, 8142, 8143, 0, 0, 8135, 0, 8183, 8157, 8158, 8159, 0, 0, 
-    8602, 0, 8603, 0, 8622, 0, 8653, 0, 8655, 0, 8654, 0, 8708, 0, 8713, 0, 
-    8716, 0, 8740, 0, 8742, 0, 8769, 0, 8772, 0, 8775, 0, 8777, 0, 8813, 0, 
-    8802, 0, 8816, 0, 8817, 0, 8820, 0, 8821, 0, 8824, 0, 8825, 0, 8832, 0, 
-    8833, 0, 8928, 0, 8929, 0, 8836, 0, 8837, 0, 8840, 0, 8841, 0, 8930, 0, 
-    8931, 0, 8876, 0, 8877, 0, 8878, 0, 8879, 0, 8938, 0, 8939, 0, 8940, 0, 
-    8941, 12436, 0, 12364, 0, 12366, 0, 12368, 0, 12370, 0, 12372, 0, 12374, 
-    0, 12376, 0, 12378, 0, 12380, 0, 12382, 0, 12384, 0, 12386, 0, 12389, 0, 
-    12391, 0, 12393, 0, 12400, 12401, 12403, 12404, 12406, 12407, 12409, 
-    12410, 12412, 12413, 12446, 0, 12532, 0, 12460, 0, 12462, 0, 12464, 0, 
-    12466, 0, 12468, 0, 12470, 0, 12472, 0, 12474, 0, 12476, 0, 12478, 0, 
-    12480, 0, 12482, 0, 12485, 0, 12487, 0, 12489, 0, 12496, 12497, 12499, 
-    12500, 12502, 12503, 12505, 12506, 12508, 12509, 12535, 0, 12536, 0, 
-    12537, 0, 12538, 0, 12542, 0, 69786, 0, 69788, 0, 69803, 0, 0, 69934, 0, 
-    69935, 70475, 70476, 70844, 70843, 70846, 0, 0, 71098, 0, 71099, 
-};
-
index aa297fc..1ff79c9 100644 (file)
 
 #include "hb-unicode.hh"
 
-
-static const struct hb_unicode_range_t _hb_unicode_emoji_Extended_Pictographic_table[] =
+static const uint8_t
+_hb_emoji_u8[448] =
 {
-  {0x00A9, 0x00A9},
-  {0x00AE, 0x00AE},
-  {0x203C, 0x203C},
-  {0x2049, 0x2049},
-  {0x2122, 0x2122},
-  {0x2139, 0x2139},
-  {0x2194, 0x2199},
-  {0x21A9, 0x21AA},
-  {0x231A, 0x231B},
-  {0x2328, 0x2328},
-  {0x2388, 0x2388},
-  {0x23CF, 0x23CF},
-  {0x23E9, 0x23F3},
-  {0x23F8, 0x23FA},
-  {0x24C2, 0x24C2},
-  {0x25AA, 0x25AB},
-  {0x25B6, 0x25B6},
-  {0x25C0, 0x25C0},
-  {0x25FB, 0x25FE},
-  {0x2600, 0x2605},
-  {0x2607, 0x2612},
-  {0x2614, 0x2685},
-  {0x2690, 0x2705},
-  {0x2708, 0x2712},
-  {0x2714, 0x2714},
-  {0x2716, 0x2716},
-  {0x271D, 0x271D},
-  {0x2721, 0x2721},
-  {0x2728, 0x2728},
-  {0x2733, 0x2734},
-  {0x2744, 0x2744},
-  {0x2747, 0x2747},
-  {0x274C, 0x274C},
-  {0x274E, 0x274E},
-  {0x2753, 0x2755},
-  {0x2757, 0x2757},
-  {0x2763, 0x2767},
-  {0x2795, 0x2797},
-  {0x27A1, 0x27A1},
-  {0x27B0, 0x27B0},
-  {0x27BF, 0x27BF},
-  {0x2934, 0x2935},
-  {0x2B05, 0x2B07},
-  {0x2B1B, 0x2B1C},
-  {0x2B50, 0x2B50},
-  {0x2B55, 0x2B55},
-  {0x3030, 0x3030},
-  {0x303D, 0x303D},
-  {0x3297, 0x3297},
-  {0x3299, 0x3299},
-  {0x1F000, 0x1F0FF},
-  {0x1F10D, 0x1F10F},
-  {0x1F12F, 0x1F12F},
-  {0x1F16C, 0x1F171},
-  {0x1F17E, 0x1F17F},
-  {0x1F18E, 0x1F18E},
-  {0x1F191, 0x1F19A},
-  {0x1F1AD, 0x1F1E5},
-  {0x1F201, 0x1F20F},
-  {0x1F21A, 0x1F21A},
-  {0x1F22F, 0x1F22F},
-  {0x1F232, 0x1F23A},
-  {0x1F23C, 0x1F23F},
-  {0x1F249, 0x1F3FA},
-  {0x1F400, 0x1F53D},
-  {0x1F546, 0x1F64F},
-  {0x1F680, 0x1F6FF},
-  {0x1F774, 0x1F77F},
-  {0x1F7D5, 0x1F7FF},
-  {0x1F80C, 0x1F80F},
-  {0x1F848, 0x1F84F},
-  {0x1F85A, 0x1F85F},
-  {0x1F888, 0x1F88F},
-  {0x1F8AE, 0x1F8FF},
-  {0x1F90C, 0x1F93A},
-  {0x1F93C, 0x1F945},
-  {0x1F947, 0x1FFFD},
+    0,  0,  0,  0, 33,  3,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 84,118,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  1,  0,  0,  0,  0,  0,  2,  0,  0,  3,
+    0,  0,  0,  0,  0,  0,  4,  5,  6,  7,  8,  7,  9, 10, 11,  0,
+    0,  0,  0,  0, 12,  0,  0,  0,  0,  0,  0,  0, 13,  0,  0,  0,
+    7,  7,  7, 14, 15, 16, 17, 18, 19, 20,  7,  7,  7,  7,  7, 21,
+    7,  7,  7,  7, 22, 23,  7,  7,  7, 24,  7, 14,  0, 25,  0, 26,
+   27, 28, 29, 14, 30, 31,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,
+    7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7, 22,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,240,  1,  0,  2,  0,  0,
+    0,  0,  0,  4,  0,  0,  0,  0,  0,  0,  0,  0,  0,254,  7,  3,
+    0,  0,  0,  0,  0,  4,  0,  0,  0,  0,  0,  0,  0,  0,  0, 56,
+  159,255,243,255,255,255,255,255,255,255,255,255,255,255,255,255,
+   31,  0,255,255,255,255,255,255, 31,255,  3,  0,  0,  0,  8,  0,
+    0,  0, 24,  0,120,  0,  0,  0,  0,  0, 96,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0, 16,  0, 96,  0,  0,  8,  0,  0,  0,  0,
+  255,255,255,255,255,255,255,127,  0, 96,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,240,  1, 64,  0,  0,254,  3,  0,224,255,255,
+  255,255,255,255, 31,  0,  0,  0,254,127,  0,  0,  0,  0,252,115,
+    0,254,255,255,255,255,255,255,255,255,255,255,255,255,255,  3,
+  255,255,255,255,255,255,255, 31,192,255,255,255,255,255,255,255,
+  255,127,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,240,127,
+    0,  0,224,255,255,255,255,127,  0,112,  0,  0,  0,  0,  0,  0,
+    0,127,  0,124,  0,  0,  0,  0,  0,127,  0,  0,  0,192,255,255,
+    0,240,255,255,255,255,255,243,159,255,255,255,255,255,255,255,
 };
 
+static inline unsigned
+_hb_emoji_b4 (const uint8_t* a, unsigned i)
+{
+  return (a[i>>1]>>((i&1u)<<2))&15u;
+}
+static inline unsigned
+_hb_emoji_b1 (const uint8_t* a, unsigned i)
+{
+  return (a[i>>3]>>((i&7u)<<0))&1u;
+}
+static inline uint_fast8_t
+_hb_emoji_is_Extended_Pictographic (unsigned u)
+{
+  return u<131069u?_hb_emoji_b1(192+_hb_emoji_u8,((_hb_emoji_u8[64+(((_hb_emoji_b4(_hb_emoji_u8,u>>6>>4))<<4)+((u>>6)&15u))])<<6)+((u)&63u)):0;
+}
+
+
 #endif /* HB_UNICODE_EMOJI_TABLE_HH */
 
 /* == End of generated table == */
index 4ac521d..08a4054 100644 (file)
@@ -60,6 +60,7 @@ hb_unicode_combining_class_nil (hb_unicode_funcs_t *ufuncs    HB_UNUSED,
   return HB_UNICODE_COMBINING_CLASS_NOT_REORDERED;
 }
 
+#ifndef HB_DISABLE_DEPRECATED
 static unsigned int
 hb_unicode_eastasian_width_nil (hb_unicode_funcs_t *ufuncs    HB_UNUSED,
                                hb_codepoint_t      unicode   HB_UNUSED,
@@ -67,6 +68,7 @@ hb_unicode_eastasian_width_nil (hb_unicode_funcs_t *ufuncs    HB_UNUSED,
 {
   return 1;
 }
+#endif
 
 static hb_unicode_general_category_t
 hb_unicode_general_category_nil (hb_unicode_funcs_t *ufuncs    HB_UNUSED,
@@ -113,6 +115,7 @@ hb_unicode_decompose_nil (hb_unicode_funcs_t *ufuncs    HB_UNUSED,
 }
 
 
+#ifndef HB_DISABLE_DEPRECATED
 static unsigned int
 hb_unicode_decompose_compatibility_nil (hb_unicode_funcs_t *ufuncs     HB_UNUSED,
                                        hb_codepoint_t      u          HB_UNUSED,
@@ -121,20 +124,23 @@ hb_unicode_decompose_compatibility_nil (hb_unicode_funcs_t *ufuncs     HB_UNUSED
 {
   return 0;
 }
+#endif
 
-
-extern "C" hb_unicode_funcs_t *hb_glib_get_unicode_funcs ();
-extern "C" hb_unicode_funcs_t *hb_icu_get_unicode_funcs ();
-extern "C" hb_unicode_funcs_t *hb_ucdn_get_unicode_funcs ();
+#if !defined(HB_NO_UNICODE_FUNCS) && defined(HAVE_GLIB)
+#include "hb-glib.h"
+#endif
+#if !defined(HB_NO_UNICODE_FUNCS) && defined(HAVE_ICU) && defined(HAVE_ICU_BUILTIN)
+#include "hb-icu.h"
+#endif
 
 hb_unicode_funcs_t *
 hb_unicode_funcs_get_default ()
 {
-#if defined(HAVE_UCDN)
-  return hb_ucdn_get_unicode_funcs ();
-#elif defined(HAVE_GLIB)
+#if !defined(HB_NO_UNICODE_FUNCS) && !defined(HB_NO_UCD)
+  return hb_ucd_get_unicode_funcs ();
+#elif !defined(HB_NO_UNICODE_FUNCS) && defined(HAVE_GLIB)
   return hb_glib_get_unicode_funcs ();
-#elif defined(HAVE_ICU) && defined(HAVE_ICU_BUILTIN)
+#elif !defined(HB_NO_UNICODE_FUNCS) && defined(HAVE_ICU) && defined(HAVE_ICU_BUILTIN)
   return hb_icu_get_unicode_funcs ();
 #else
 #define HB_UNICODE_FUNCS_NIL 1
@@ -144,7 +150,7 @@ hb_unicode_funcs_get_default ()
 
 #if !defined(HB_NO_UNICODE_FUNCS) && defined(HB_UNICODE_FUNCS_NIL)
 #error "Could not find any Unicode functions implementation, you have to provide your own"
-#error "Consider building hb-ucdn.c.  If you absolutely want to build without any, check the code."
+#error "Consider building hb-ucd.cc.  If you absolutely want to build without any, check the code."
 #endif
 
 /**
@@ -264,9 +270,9 @@ hb_unicode_funcs_destroy (hb_unicode_funcs_t *ufuncs)
  **/
 hb_bool_t
 hb_unicode_funcs_set_user_data (hb_unicode_funcs_t *ufuncs,
-                               hb_user_data_key_t *key,
-                               void *              data,
-                               hb_destroy_func_t   destroy,
+                               hb_user_data_key_t *key,
+                               void *              data,
+                               hb_destroy_func_t   destroy,
                                hb_bool_t           replace)
 {
   return hb_object_set_user_data (ufuncs, key, data, destroy, replace);
@@ -285,7 +291,7 @@ hb_unicode_funcs_set_user_data (hb_unicode_funcs_t *ufuncs,
  **/
 void *
 hb_unicode_funcs_get_user_data (hb_unicode_funcs_t *ufuncs,
-                               hb_user_data_key_t *key)
+                               hb_user_data_key_t *key)
 {
   return hb_object_get_user_data (ufuncs, key);
 }
@@ -425,6 +431,7 @@ hb_unicode_decompose (hb_unicode_funcs_t *ufuncs,
   return ufuncs->decompose (ab, a, b);
 }
 
+#ifndef HB_DISABLE_DEPRECATED
 /**
  * hb_unicode_decompose_compatibility:
  * @ufuncs: Unicode functions.
@@ -445,8 +452,10 @@ hb_unicode_decompose_compatibility (hb_unicode_funcs_t *ufuncs,
 {
   return ufuncs->decompose_compatibility (u, decomposed);
 }
+#endif
 
 
+#ifndef HB_NO_OT_SHAPE
 /* See hb-unicode.hh for details. */
 const uint8_t
 _hb_modified_combining_class[256] =
@@ -559,19 +568,19 @@ _hb_modified_combining_class[256] =
   241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254,
   255, /* HB_UNICODE_COMBINING_CLASS_INVALID */
 };
+#endif
 
 
 /*
  * Emoji
  */
+#ifndef HB_NO_EMOJI_SEQUENCES
 
 #include "hb-unicode-emoji-table.hh"
 
 bool
 _hb_unicode_is_emoji_Extended_Pictographic (hb_codepoint_t cp)
 {
-  return hb_bsearch (&cp, _hb_unicode_emoji_Extended_Pictographic_table,
-                    ARRAY_LENGTH (_hb_unicode_emoji_Extended_Pictographic_table),
-                    sizeof (hb_unicode_range_t),
-                    hb_unicode_range_t::cmp);
+  return _hb_emoji_is_Extended_Pictographic (cp);
 }
+#endif
index df0b91f..61b1b0b 100644 (file)
@@ -200,15 +200,15 @@ hb_unicode_funcs_destroy (hb_unicode_funcs_t *ufuncs);
 
 HB_EXTERN hb_bool_t
 hb_unicode_funcs_set_user_data (hb_unicode_funcs_t *ufuncs,
-                               hb_user_data_key_t *key,
-                               void *              data,
-                               hb_destroy_func_t   destroy,
+                               hb_user_data_key_t *key,
+                               void *              data,
+                               hb_destroy_func_t   destroy,
                                hb_bool_t           replace);
 
 
 HB_EXTERN void *
 hb_unicode_funcs_get_user_data (hb_unicode_funcs_t *ufuncs,
-                               hb_user_data_key_t *key);
+                               hb_user_data_key_t *key);
 
 
 HB_EXTERN void
@@ -260,7 +260,7 @@ typedef hb_bool_t                   (*hb_unicode_decompose_func_t)          (hb_unicode_funcs_t *ufuncs,
  * @user_data:
  * @destroy:
  *
- * 
+ *
  *
  * Since: 0.9.2
  **/
@@ -276,7 +276,7 @@ hb_unicode_funcs_set_combining_class_func (hb_unicode_funcs_t *ufuncs,
  * @user_data:
  * @destroy:
  *
- * 
+ *
  *
  * Since: 0.9.2
  **/
@@ -292,7 +292,7 @@ hb_unicode_funcs_set_general_category_func (hb_unicode_funcs_t *ufuncs,
  * @user_data:
  * @destroy:
  *
- * 
+ *
  *
  * Since: 0.9.2
  **/
@@ -308,7 +308,7 @@ hb_unicode_funcs_set_mirroring_func (hb_unicode_funcs_t *ufuncs,
  * @user_data:
  * @destroy:
  *
- * 
+ *
  *
  * Since: 0.9.2
  **/
@@ -324,7 +324,7 @@ hb_unicode_funcs_set_script_func (hb_unicode_funcs_t *ufuncs,
  * @user_data:
  * @destroy:
  *
- * 
+ *
  *
  * Since: 0.9.2
  **/
@@ -340,7 +340,7 @@ hb_unicode_funcs_set_compose_func (hb_unicode_funcs_t *ufuncs,
  * @user_data:
  * @destroy:
  *
- * 
+ *
  *
  * Since: 0.9.2
  **/
index 82ebb10..0c355f1 100644 (file)
@@ -42,19 +42,19 @@ extern HB_INTERNAL const uint8_t _hb_modified_combining_class[256];
 
 #define HB_UNICODE_FUNCS_IMPLEMENT_CALLBACKS \
   HB_UNICODE_FUNC_IMPLEMENT (combining_class) \
-  HB_UNICODE_FUNC_IMPLEMENT (eastasian_width) \
+  HB_IF_NOT_DEPRECATED (HB_UNICODE_FUNC_IMPLEMENT (eastasian_width)) \
   HB_UNICODE_FUNC_IMPLEMENT (general_category) \
   HB_UNICODE_FUNC_IMPLEMENT (mirroring) \
   HB_UNICODE_FUNC_IMPLEMENT (script) \
   HB_UNICODE_FUNC_IMPLEMENT (compose) \
   HB_UNICODE_FUNC_IMPLEMENT (decompose) \
-  HB_UNICODE_FUNC_IMPLEMENT (decompose_compatibility) \
+  HB_IF_NOT_DEPRECATED (HB_UNICODE_FUNC_IMPLEMENT (decompose_compatibility)) \
   /* ^--- Add new callbacks here */
 
 /* Simple callbacks are those taking a hb_codepoint_t and returning a hb_codepoint_t */
 #define HB_UNICODE_FUNCS_IMPLEMENT_CALLBACKS_SIMPLE \
   HB_UNICODE_FUNC_IMPLEMENT (hb_unicode_combining_class_t, combining_class) \
-  HB_UNICODE_FUNC_IMPLEMENT (unsigned int, eastasian_width) \
+  HB_IF_NOT_DEPRECATED (HB_UNICODE_FUNC_IMPLEMENT (unsigned int, eastasian_width)) \
   HB_UNICODE_FUNC_IMPLEMENT (hb_unicode_general_category_t, general_category) \
   HB_UNICODE_FUNC_IMPLEMENT (hb_codepoint_t, mirroring) \
   HB_UNICODE_FUNC_IMPLEMENT (hb_script_t, script) \
@@ -89,7 +89,11 @@ HB_UNICODE_FUNCS_IMPLEMENT_CALLBACKS_SIMPLE
   unsigned int decompose_compatibility (hb_codepoint_t  u,
                                        hb_codepoint_t *decomposed)
   {
+#ifdef HB_DISABLE_DEPRECATED
+    unsigned int ret  = 0;
+#else
     unsigned int ret = func.decompose_compatibility (this, u, decomposed, user_data.decompose_compatibility);
+#endif
     if (ret == 1 && u == decomposed[0]) {
       decomposed[0] = 0;
       return 0;
@@ -101,9 +105,6 @@ HB_UNICODE_FUNCS_IMPLEMENT_CALLBACKS_SIMPLE
   unsigned int
   modified_combining_class (hb_codepoint_t u)
   {
-    /* XXX This hack belongs to the Myanmar shaper. */
-    if (unlikely (u == 0x1037u)) u = 0x103Au;
-
     /* XXX This hack belongs to the USE shaper (for Tai Tham):
      * Reorder SAKOT to ensure it comes after any tone marks. */
     if (unlikely (u == 0x1A60u)) return 254;
@@ -322,11 +323,11 @@ DECLARE_NULL_INSTANCE (hb_unicode_funcs_t);
  *
  * Modify Telugu length marks (ccc=84, ccc=91).
  * These are the only matras in the main Indic scripts range that have
- * a non-zero ccc.  That makes them reorder with the Halant that is
- * ccc=9.  Just zero them, we don't need them in our Indic shaper.
+ * a non-zero ccc.  That makes them reorder with the Halant (ccc=9).
+ * Assign 5 and 6, which are otherwise unassigned.
  */
-#define HB_MODIFIED_COMBINING_CLASS_CCC84 0 /* length mark */
-#define HB_MODIFIED_COMBINING_CLASS_CCC91 0 /* ai length mark */
+#define HB_MODIFIED_COMBINING_CLASS_CCC84 5 /* length mark */
+#define HB_MODIFIED_COMBINING_CLASS_CCC91 6 /* ai length mark */
 
 /* Thai
  *
@@ -391,4 +392,7 @@ HB_INTERNAL bool
 _hb_unicode_is_emoji_Extended_Pictographic (hb_codepoint_t cp);
 
 
+extern "C" HB_INTERNAL hb_unicode_funcs_t *hb_ucd_get_unicode_funcs ();
+
+
 #endif /* HB_UNICODE_HH */
index 31c50df..e93cf7f 100644 (file)
  */
 
 #include "hb.hh"
+
+#ifdef HAVE_UNISCRIBE
+
+#ifdef HB_NO_OT_TAG
+#error "Cannot compile 'uniscribe' shaper with HB_NO_OT_TAG."
+#endif
+
 #include "hb-shaper-impl.hh"
 
 #include <windows.h>
 #include <usp10.h>
 #include <rpc.h>
 
+#ifndef E_NOT_SUFFICIENT_BUFFER
+#define E_NOT_SUFFICIENT_BUFFER HRESULT_FROM_WIN32 (ERROR_INSUFFICIENT_BUFFER)
+#endif
+
 #include "hb-uniscribe.h"
 
 #include "hb-open-file.hh"
  * Functions for using HarfBuzz with the Windows fonts.
  **/
 
-
-static inline uint16_t hb_uint16_swap (const uint16_t v)
-{ return (v >> 8) | (v << 8); }
-static inline uint32_t hb_uint32_swap (const uint32_t v)
-{ return (hb_uint16_swap (v) << 16) | hb_uint16_swap (v >> 16); }
-
-
 typedef HRESULT (WINAPI *SIOT) /*ScriptItemizeOpenType*/(
   const WCHAR *pwcInChars,
   int cInChars,
@@ -234,8 +238,9 @@ struct hb_uniscribe_shaper_funcs_t
   }
 };
 
-
+#if HB_USE_ATEXIT
 static void free_static_uniscribe_shaper_funcs ();
+#endif
 
 static struct hb_uniscribe_shaper_funcs_lazy_loader_t : hb_lazy_loader_t<hb_uniscribe_shaper_funcs_t,
                                                                         hb_uniscribe_shaper_funcs_lazy_loader_t>
@@ -283,7 +288,7 @@ struct active_feature_t {
   OPENTYPE_FEATURE_RECORD rec;
   unsigned int order;
 
-  static int cmp (const void *pa, const void *pb) {
+  HB_INTERNAL static int cmp (const void *pa, const void *pb) {
     const active_feature_t *a = (const active_feature_t *) pa;
     const active_feature_t *b = (const active_feature_t *) pb;
     return a->rec.tagFeature < b->rec.tagFeature ? -1 : a->rec.tagFeature > b->rec.tagFeature ? 1 :
@@ -300,7 +305,7 @@ struct feature_event_t {
   bool start;
   active_feature_t feature;
 
-  static int cmp (const void *pa, const void *pb)
+  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;
@@ -380,8 +385,8 @@ _hb_rename_font (hb_blob_t *blob, wchar_t *new_name)
   static const uint16_t name_IDs[] = { 1, 2, 3, 4, 6 };
 
   unsigned int name_table_length = OT::name::min_size +
-                                   ARRAY_LENGTH (name_IDs) * OT::NameRecord::static_size +
-                                   name_str_len * 2; /* for name data in UTF16BE form */
+                                  ARRAY_LENGTH (name_IDs) * OT::NameRecord::static_size +
+                                  name_str_len * 2; /* for name data in UTF16BE form */
   unsigned int padded_name_table_length = ((name_table_length + 3) & ~3);
   unsigned int name_table_offset = (length + 3) & ~3;
 
@@ -396,18 +401,18 @@ _hb_rename_font (hb_blob_t *blob, wchar_t *new_name)
   memcpy(new_sfnt_data, orig_sfnt_data, length);
 
   OT::name &name = StructAtOffset<OT::name> (new_sfnt_data, name_table_offset);
-  name.format.set (0);
-  name.count.set (ARRAY_LENGTH (name_IDs));
-  name.stringOffset.set (name.get_size ());
+  name.format = 0;
+  name.count = ARRAY_LENGTH (name_IDs);
+  name.stringOffset = name.get_size ();
   for (unsigned int i = 0; i < ARRAY_LENGTH (name_IDs); i++)
   {
     OT::NameRecord &record = name.nameRecordZ[i];
-    record.platformID.set (3);
-    record.encodingID.set (1);
-    record.languageID.set (0x0409u); /* English */
-    record.nameID.set (name_IDs[i]);
-    record.length.set (name_str_len * 2);
-    record.offset.set (0);
+    record.platformID = 3;
+    record.encodingID = 1;
+    record.languageID = 0x0409u; /* English */
+    record.nameID = name_IDs[i];
+    record.length = name_str_len * 2;
+    record.offset = 0;
   }
 
   /* Copy string data from new_name, converting wchar_t to UTF16BE. */
@@ -431,8 +436,8 @@ _hb_rename_font (hb_blob_t *blob, wchar_t *new_name)
     {
       OT::TableRecord &record = const_cast<OT::TableRecord &> (face.get_table (index));
       record.checkSum.set_for_data (&name, padded_name_table_length);
-      record.offset.set (name_table_offset);
-      record.length.set (name_table_length);
+      record.offset = name_table_offset;
+      record.length = name_table_length;
     }
     else if (face_index == 0) /* Fail if first face doesn't have 'name' table. */
     {
@@ -661,7 +666,7 @@ _hb_uniscribe_shape (hb_shape_plan_t    *shape_plan,
 
       if (event->index != last_index)
       {
-        /* Save a snapshot of active features and the range. */
+       /* Save a snapshot of active features and the range. */
        range_record_t *range = range_records.push ();
 
        unsigned int offset = feature_records.length;
@@ -696,9 +701,9 @@ _hb_uniscribe_shape (hb_shape_plan_t    *shape_plan,
       }
       else
       {
-        active_feature_t *feature = active_features.find (&event->feature);
+       active_feature_t *feature = active_features.find (&event->feature);
        if (feature)
-         active_features.remove (feature - active_features.arrayZ ());
+         active_features.remove (feature - active_features.arrayZ);
       }
     }
 
@@ -717,7 +722,7 @@ _hb_uniscribe_shape (hb_shape_plan_t    *shape_plan,
   HB_STMT_START { \
     DEBUG_MSG (UNISCRIBE, nullptr, __VA_ARGS__); \
     return false; \
-  } HB_STMT_END;
+  } HB_STMT_END
 
   HRESULT hr;
 
@@ -728,12 +733,12 @@ retry:
 
 #define ALLOCATE_ARRAY(Type, name, len) \
   Type *name = (Type *) scratch; \
-  { \
+  do { \
     unsigned int _consumed = DIV_CEIL ((len) * sizeof (Type), sizeof (*scratch)); \
     assert (_consumed <= scratch_size); \
     scratch += _consumed; \
     scratch_size -= _consumed; \
-  }
+  } while (0)
 
 #define utf16_index() var1.u32
 
@@ -889,8 +894,8 @@ retry:
                                     &items[i].a,
                                     script_tags[i],
                                     language_tag,
-                                    range_char_counts.arrayZ (),
-                                    range_properties.arrayZ (),
+                                    range_char_counts.arrayZ,
+                                    range_properties.arrayZ,
                                     range_properties.length,
                                     pchars + chars_offset,
                                     item_chars_len,
@@ -930,8 +935,8 @@ retry:
                                     &items[i].a,
                                     script_tags[i],
                                     language_tag,
-                                    range_char_counts.arrayZ (),
-                                    range_properties.arrayZ (),
+                                    range_char_counts.arrayZ,
+                                    range_properties.arrayZ,
                                     range_properties.length,
                                     pchars + chars_offset,
                                     log_clusters + chars_offset,
@@ -967,7 +972,7 @@ retry:
     vis_clusters[i] = (uint32_t) -1;
   for (unsigned int i = 0; i < buffer->len; i++) {
     uint32_t *p = &vis_clusters[log_clusters[buffer->info[i].utf16_index()]];
-    *p = MIN (*p, buffer->info[i].cluster);
+    *p = hb_min (*p, buffer->info[i].cluster);
   }
   for (unsigned int i = 1; i < glyphs_len; i++)
     if (vis_clusters[i] == (uint32_t) -1)
@@ -1019,3 +1024,4 @@ retry:
 }
 
 
+#endif
index 59ec75e..ff5712d 100644 (file)
@@ -235,10 +235,10 @@ struct hb_utf16_xe_t
       hb_codepoint_t h = text[-1];
       if (likely (hb_in_range<hb_codepoint_t> (h, 0xD800u, 0xDBFFu)))
       {
-        /* High-surrogate in h */
-        *unicode = (h << 10) + c - ((0xD800u << 10) - 0x10000u + 0xDC00u);
-        text--;
-        return text;
+       /* High-surrogate in h */
+       *unicode = (h << 10) + c - ((0xD800u << 10) - 0x10000u + 0xDC00u);
+       text--;
+       return text;
       }
     }
 
index 2fd739b..7b150fb 100644 (file)
@@ -38,103 +38,141 @@ struct hb_vector_t
   typedef Type item_t;
   static constexpr unsigned item_size = hb_static_size (Type);
 
-  HB_NO_COPY_ASSIGN_TEMPLATE (hb_vector_t, Type);
   hb_vector_t ()  { init (); }
+  hb_vector_t (const hb_vector_t &o)
+  {
+    init ();
+    alloc (o.length);
+    hb_copy (o, *this);
+  }
+  hb_vector_t (hb_vector_t &&o)
+  {
+    allocated = o.allocated;
+    length = o.length;
+    arrayZ = o.arrayZ;
+    o.init ();
+  }
   ~hb_vector_t () { fini (); }
 
-  unsigned int length;
   private:
   int allocated; /* == -1 means allocation failed. */
-  Type *arrayZ_;
   public:
+  unsigned int length;
+  public:
+  Type *arrayZ;
 
   void init ()
   {
     allocated = length = 0;
-    arrayZ_ = nullptr;
+    arrayZ = nullptr;
   }
 
   void fini ()
   {
-    if (arrayZ_)
-      free (arrayZ_);
+    free (arrayZ);
     init ();
   }
   void fini_deep ()
   {
-    Type *array = arrayZ();
     unsigned int count = length;
     for (unsigned int i = 0; i < count; i++)
-      array[i].fini ();
+      arrayZ[i].fini ();
+    fini ();
+  }
+
+  void reset () { resize (0); }
+
+  hb_vector_t& operator = (const hb_vector_t &o)
+  {
+    reset ();
+    alloc (o.length);
+    hb_copy (o, *this);
+    return *this;
+  }
+  hb_vector_t& operator = (hb_vector_t &&o)
+  {
     fini ();
+    allocated = o.allocated;
+    length = o.length;
+    arrayZ = o.arrayZ;
+    o.init ();
+    return *this;
   }
 
-  const Type * arrayZ () const { return arrayZ_; }
-        Type * arrayZ ()       { return arrayZ_; }
+  hb_bytes_t as_bytes () const
+  { return hb_bytes_t ((const char *) arrayZ, length * item_size); }
+
+  bool operator == (const hb_vector_t &o) const { return as_array () == o.as_array (); }
+  bool operator != (const hb_vector_t &o) const { return !(*this == o); }
+  uint32_t hash () const { return as_array ().hash (); }
 
   Type& operator [] (int i_)
   {
     unsigned int i = (unsigned int) i_;
     if (unlikely (i >= length))
       return Crap (Type);
-    return arrayZ()[i];
+    return arrayZ[i];
   }
   const Type& operator [] (int i_) const
   {
     unsigned int i = (unsigned int) i_;
     if (unlikely (i >= length))
       return Null(Type);
-    return arrayZ()[i];
+    return arrayZ[i];
   }
 
-  explicit_operator bool () const { return length; }
+  Type& tail () { return (*this)[length - 1]; }
+  const Type& tail () const { return (*this)[length - 1]; }
 
-  hb_array_t<Type> as_array ()
-  { return hb_array (arrayZ(), length); }
-  hb_array_t<const Type> as_array () const
-  { return hb_array (arrayZ(), length); }
+  explicit operator bool () const { return length; }
+  unsigned get_size () const { return length * item_size; }
+
+  /* Sink interface. */
+  template <typename T>
+  hb_vector_t& operator << (T&& v) { push (hb_forward<T> (v)); return *this; }
+
+  hb_array_t<      Type> as_array ()       { return hb_array (arrayZ, length); }
+  hb_array_t<const Type> as_array () const { return hb_array (arrayZ, length); }
+
+  /* Iterator. */
+  typedef hb_array_t<const Type>   iter_t;
+  typedef hb_array_t<      Type> writer_t;
+    iter_t   iter () const { return as_array (); }
+  writer_t writer ()       { return as_array (); }
+  operator   iter_t () const { return   iter (); }
+  operator writer_t ()       { return writer (); }
 
   hb_array_t<const Type> sub_array (unsigned int start_offset, unsigned int count) const
-  { return as_array ().sub_array (start_offset, count);}
+  { return as_array ().sub_array (start_offset, count); }
   hb_array_t<const Type> sub_array (unsigned int start_offset, unsigned int *count = nullptr /* IN/OUT */) const
-  { return as_array ().sub_array (start_offset, count);}
+  { return as_array ().sub_array (start_offset, count); }
   hb_array_t<Type> sub_array (unsigned int start_offset, unsigned int count)
-  { return as_array ().sub_array (start_offset, count);}
+  { return as_array ().sub_array (start_offset, count); }
   hb_array_t<Type> sub_array (unsigned int start_offset, unsigned int *count = nullptr /* IN/OUT */)
-  { return as_array ().sub_array (start_offset, count);}
+  { return as_array ().sub_array (start_offset, count); }
 
   hb_sorted_array_t<Type> as_sorted_array ()
-  { return hb_sorted_array (arrayZ(), length); }
+  { return hb_sorted_array (arrayZ, length); }
   hb_sorted_array_t<const Type> as_sorted_array () const
-  { return hb_sorted_array (arrayZ(), length); }
-
-  hb_array_t<const Type> sorted_sub_array (unsigned int start_offset, unsigned int count) const
-  { return as_sorted_array ().sorted_sub_array (start_offset, count);}
-  hb_array_t<const Type> sorted_sub_array (unsigned int start_offset, unsigned int *count = nullptr /* IN/OUT */) const
-  { return as_sorted_array ().sorted_sub_array (start_offset, count);}
-  hb_array_t<Type> sorted_sub_array (unsigned int start_offset, unsigned int count)
-  { return as_sorted_array ().sorted_sub_array (start_offset, count);}
-  hb_array_t<Type> sorted_sub_array (unsigned int start_offset, unsigned int *count = nullptr /* IN/OUT */)
-  { return as_sorted_array ().sorted_sub_array (start_offset, count);}
+  { return hb_sorted_array (arrayZ, length); }
 
-  template <typename T> explicit_operator T * () { return arrayZ(); }
-  template <typename T> explicit_operator const T * () const { return arrayZ(); }
-  operator hb_array_t<Type> ()             { return as_array (); }
-  operator hb_array_t<const Type> () const { return as_array (); }
+  template <typename T> explicit operator T * () { return arrayZ; }
+  template <typename T> explicit operator const T * () const { return arrayZ; }
 
-  Type * operator  + (unsigned int i) { return arrayZ() + i; }
-  const Type * operator  + (unsigned int i) const { return arrayZ() + i; }
+  Type * operator  + (unsigned int i) { return arrayZ + i; }
+  const Type * operator  + (unsigned int i) const { return arrayZ + i; }
 
   Type *push ()
   {
     if (unlikely (!resize (length + 1)))
       return &Crap(Type);
-    return &arrayZ()[length - 1];
+    return &arrayZ[length - 1];
   }
-  Type *push (const Type& v)
+  template <typename T>
+  Type *push (T&& v)
   {
     Type *p = push ();
-    *p = v;
+    *p = hb_forward<T> (v);
     return p;
   }
 
@@ -161,7 +199,7 @@ struct hb_vector_t
       (new_allocated < (unsigned) allocated) ||
       hb_unsigned_mul_overflows (new_allocated, sizeof (Type));
     if (likely (!overflows))
-      new_array = (Type *) realloc (arrayZ_, new_allocated * sizeof (Type));
+      new_array = (Type *) realloc (arrayZ, new_allocated * sizeof (Type));
 
     if (unlikely (!new_array))
     {
@@ -169,7 +207,7 @@ struct hb_vector_t
       return false;
     }
 
-    arrayZ_ = new_array;
+    arrayZ = new_array;
     allocated = new_allocated;
 
     return true;
@@ -182,25 +220,24 @@ struct hb_vector_t
       return false;
 
     if (size > length)
-      memset (arrayZ() + length, 0, (size - length) * sizeof (*arrayZ()));
+      memset (arrayZ + length, 0, (size - length) * sizeof (*arrayZ));
 
     length = size;
     return true;
   }
 
-  void pop ()
+  Type pop ()
   {
-    if (!length) return;
-    length--;
+    if (!length) return Null(Type);
+    return hb_move (arrayZ[--length]); /* Does this move actually work? */
   }
 
   void remove (unsigned int i)
   {
     if (unlikely (i >= length))
       return;
-    Type *array = arrayZ();
-    memmove (static_cast<void *> (&array[i]),
-            static_cast<void *> (&array[i + 1]),
+    memmove (static_cast<void *> (&arrayZ[i]),
+            static_cast<void *> (&arrayZ[i + 1]),
             (length - i - 1) * sizeof (Type));
     length--;
   }
@@ -215,19 +252,17 @@ struct hb_vector_t
   template <typename T>
   Type *find (T v)
   {
-    Type *array = arrayZ();
     for (unsigned int i = 0; i < length; i++)
-      if (array[i] == v)
-       return &array[i];
+      if (arrayZ[i] == v)
+       return &arrayZ[i];
     return nullptr;
   }
   template <typename T>
   const Type *find (T v) const
   {
-    const Type *array = arrayZ();
     for (unsigned int i = 0; i < length; i++)
-      if (array[i] == v)
-       return &array[i];
+      if (arrayZ[i] == v)
+       return &arrayZ[i];
     return nullptr;
   }
 
@@ -242,19 +277,34 @@ struct hb_vector_t
   template <typename T>
   const Type *lsearch (const T &x, const Type *not_found = nullptr) const
   { return as_array ().lsearch (x, not_found); }
+};
+
+template <typename Type>
+struct hb_sorted_vector_t : hb_vector_t<Type>
+{
+  hb_sorted_array_t<      Type> as_array ()       { return hb_sorted_array (this->arrayZ, this->length); }
+  hb_sorted_array_t<const Type> as_array () const { return hb_sorted_array (this->arrayZ, this->length); }
+
+  /* Iterator. */
+  typedef hb_sorted_array_t<const Type> const_iter_t;
+  typedef hb_sorted_array_t<      Type>       iter_t;
+  const_iter_t  iter () const { return as_array (); }
+  const_iter_t citer () const { return as_array (); }
+       iter_t  iter ()       { return as_array (); }
+  operator       iter_t ()       { return iter (); }
+  operator const_iter_t () const { return iter (); }
 
   template <typename T>
   Type *bsearch (const T &x, Type *not_found = nullptr)
-  { return as_sorted_array ().bsearch (x, not_found); }
+  { return as_array ().bsearch (x, not_found); }
   template <typename T>
   const Type *bsearch (const T &x, const Type *not_found = nullptr) const
-  { return as_sorted_array ().bsearch (x, not_found); }
+  { return as_array ().bsearch (x, not_found); }
   template <typename T>
   bool bfind (const T &x, unsigned int *i = nullptr,
-                    hb_bfind_not_found_t not_found = HB_BFIND_NOT_FOUND_DONT_STORE,
-                    unsigned int to_store = (unsigned int) -1) const
-  { return as_sorted_array ().bfind (x, i, not_found, to_store); }
+             hb_bfind_not_found_t not_found = HB_BFIND_NOT_FOUND_DONT_STORE,
+             unsigned int to_store = (unsigned int) -1) const
+  { return as_array ().bfind (x, i, not_found, to_store); }
 };
 
-
 #endif /* HB_VECTOR_HH */
index 783e37b..a564e9f 100644 (file)
@@ -37,10 +37,10 @@ HB_BEGIN_DECLS
 
 
 #define HB_VERSION_MAJOR 2
-#define HB_VERSION_MINOR 4
-#define HB_VERSION_MICRO 0
+#define HB_VERSION_MINOR 6
+#define HB_VERSION_MICRO 4
 
-#define HB_VERSION_STRING "2.4.0"
+#define HB_VERSION_STRING "2.6.4"
 
 #define HB_VERSION_ATLEAST(major,minor,micro) \
        ((major)*10000+(minor)*100+(micro) <= \
index ec24c1a..fcbd330 100644 (file)
--- a/src/hb.hh
+++ b/src/hb.hh
@@ -29,8 +29,9 @@
 #ifndef HB_HH
 #define HB_HH
 
+
 #ifndef HB_NO_PRAGMA_GCC_DIAGNOSTIC
-#if defined(_MSC_VER)
+#ifdef _MSC_VER
 #pragma warning( disable: 4068 ) /* Unknown pragma */
 #endif
 #if defined(__GNUC__) || defined(__clang__)
 #pragma GCC diagnostic error   "-Wcast-align"
 #pragma GCC diagnostic error   "-Wcast-function-type"
 #pragma GCC diagnostic error   "-Wdelete-non-virtual-dtor"
+#pragma GCC diagnostic error   "-Wembedded-directive"
+#pragma GCC diagnostic error   "-Wextra-semi-stmt"
 #pragma GCC diagnostic error   "-Wformat-security"
 #pragma GCC diagnostic error   "-Wimplicit-function-declaration"
 #pragma GCC diagnostic error   "-Winit-self"
+#pragma GCC diagnostic error   "-Winjected-class-name"
 #pragma GCC diagnostic error   "-Wmissing-braces"
 #pragma GCC diagnostic error   "-Wmissing-declarations"
 #pragma GCC diagnostic error   "-Wmissing-prototypes"
 /* Warning.  To be investigated if happens. */
 #ifndef HB_NO_PRAGMA_GCC_DIAGNOSTIC_WARNING
 #pragma GCC diagnostic warning "-Wbuiltin-macro-redefined"
+#pragma GCC diagnostic warning "-Wdeprecated"
+#pragma GCC diagnostic warning "-Wdeprecated-declarations"
 #pragma GCC diagnostic warning "-Wdisabled-optimization"
+#pragma GCC diagnostic warning "-Wdouble-promotion"
 #pragma GCC diagnostic warning "-Wformat=2"
 #pragma GCC diagnostic warning "-Wignored-pragma-optimize"
 #pragma GCC diagnostic warning "-Wlogical-op"
 #pragma GCC diagnostic ignored "-Wpacked" // Erratic impl in clang
 #pragma GCC diagnostic ignored "-Wstrict-aliasing"
 #pragma GCC diagnostic ignored "-Wtype-limits"
+#pragma GCC diagnostic ignored "-Wc++11-compat" // only gcc raises it
 #endif
 
 #endif
 #endif
 
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
+
+#include "hb-config.hh"
+
 
 /*
  * Following added based on what AC_USE_SYSTEM_EXTENSIONS adds to
 #include "hb-aat.h"
 #define HB_AAT_H_IN
 
-#include "hb-aat.h"
-
+#include <limits.h>
 #include <math.h>
 #include <stdlib.h>
 #include <stddef.h>
 #include <string.h>
 #include <assert.h>
-#include <errno.h>
 #include <stdio.h>
 #include <stdarg.h>
 
 #if (defined(_MSC_VER) && _MSC_VER >= 1500) || defined(__MINGW32__)
+#ifdef __MINGW32_VERSION
+#ifndef WIN32_LEAN_AND_MEAN
+#define WIN32_LEAN_AND_MEAN 1
+#endif
+#include <windows.h>
+#else
 #include <intrin.h>
 #endif
+#endif
 
 #define HB_PASTE1(a,b) a##b
 #define HB_PASTE(a,b) HB_PASTE1(a,b)
@@ -199,14 +212,6 @@ extern "C" void  hb_free_impl(void *ptr);
 #define calloc hb_calloc_impl
 #define realloc hb_realloc_impl
 #define free hb_free_impl
-
-#if defined(hb_memalign_impl)
-extern "C" int hb_memalign_impl(void **memptr, size_t alignment, size_t size);
-#define posix_memalign hb_memalign_impl
-#else
-#undef HAVE_POSIX_MEMALIGN
-#endif
-
 #endif
 
 
@@ -214,59 +219,6 @@ extern "C" int hb_memalign_impl(void **memptr, size_t alignment, size_t size);
  * Compiler attributes
  */
 
-/* https://github.com/harfbuzz/harfbuzz/issues/1634 */
-#if __cplusplus < 201103L && !defined(_MSC_VER)
-
-#ifndef nullptr
-#define nullptr NULL
-#endif
-
-#ifndef constexpr
-#define constexpr const
-#endif
-
-#ifndef static_assert
-#define static_assert(e, msg) \
-       HB_UNUSED typedef int HB_PASTE(static_assertion_failed_at_line_, __LINE__) [(e) ? 1 : -1]
-#endif // static_assert
-
-#if defined(__GNUC__)
-#if (__GNUC__ < 4 || (__GNUC__ == 4 && __GNUC_MINOR__ < 8))
-#define thread_local __thread
-#endif
-#else
-#define thread_local
-#endif
-
-template <typename T>
-struct _hb_alignof
-{
-  struct s
-  {
-    char c;
-    T t;
-  };
-  static constexpr size_t value = offsetof (s, t);
-};
-#ifndef alignof
-#define alignof(x) (_hb_alignof<x>::value)
-#endif
-
-/* https://github.com/harfbuzz/harfbuzz/issues/1127 */
-#ifndef explicit_operator
-#define explicit_operator operator
-#endif
-
-#else /* __cplusplus >= 201103L */
-
-/* https://github.com/harfbuzz/harfbuzz/issues/1127 */
-#ifndef explicit_operator
-#define explicit_operator explicit operator
-#endif
-
-#endif /* __cplusplus < 201103L */
-
-
 #if (defined(__GNUC__) || defined(__clang__)) && defined(__OPTIMIZE__)
 #define likely(expr) (__builtin_expect (!!(expr), 1))
 #define unlikely(expr) (__builtin_expect (!!(expr), 0))
@@ -289,7 +241,7 @@ struct _hb_alignof
 #define HB_CONST_FUNC
 #define HB_PRINTF_FUNC(format_idx, arg_idx)
 #endif
-#if defined(__GNUC__) && (__GNUC__ >= 4)
+#if defined(__GNUC__) && (__GNUC__ >= 4) || (__clang__)
 #define HB_UNUSED      __attribute__((unused))
 #elif defined(_MSC_VER) /* https://github.com/harfbuzz/harfbuzz/issues/635 */
 #define HB_UNUSED __pragma(warning(suppress: 4100 4101))
@@ -312,6 +264,13 @@ struct _hb_alignof
 # endif
 #endif
 
+/* https://github.com/harfbuzz/harfbuzz/issues/1651 */
+#if defined(__clang__) && __clang_major__ < 10
+#define static_const static
+#else
+#define static_const static const
+#endif
+
 #if defined(__GNUC__) && (__GNUC__ >= 3)
 #define HB_FUNC __PRETTY_FUNCTION__
 #elif defined(_MSC_VER)
@@ -358,7 +317,8 @@ struct _hb_alignof
 #  define HB_FALLTHROUGH /* FALLTHROUGH */
 #endif
 
-#if defined(__clang__)
+/* https://github.com/harfbuzz/harfbuzz/issues/1852 */
+#if defined(__clang__) && !(defined(_AIX) && (defined(__IBMCPP__) || defined(__ibmxl__)))
 /* Disable certain sanitizer errors. */
 /* https://github.com/harfbuzz/harfbuzz/issues/1247 */
 #define HB_NO_SANITIZE_SIGNED_INTEGER_OVERFLOW __attribute__((no_sanitize("signed-integer-overflow")))
@@ -389,19 +349,35 @@ struct _hb_alignof
 #  if defined(_WIN32_WCE)
      /* Some things not defined on Windows CE. */
 #    define vsnprintf _vsnprintf
-#    define getenv(Name) nullptr
+#    ifndef HB_NO_GETENV
+#      define HB_NO_GETENV
+#    endif
 #    if _WIN32_WCE < 0x800
-#      define setlocale(Category, Locale) "C"
-static int errno = 0; /* Use something better? */
+#      define HB_NO_SETLOCALE
+#      define HB_NO_ERRNO
 #    endif
 #  elif defined(WINAPI_FAMILY) && (WINAPI_FAMILY==WINAPI_FAMILY_PC_APP || WINAPI_FAMILY==WINAPI_FAMILY_PHONE_APP)
-#    define getenv(Name) nullptr
+#    ifndef HB_NO_GETENV
+#      define HB_NO_GETENV
+#    endif
 #  endif
 #  if defined(_MSC_VER) && _MSC_VER < 1900
 #    define snprintf _snprintf
 #  endif
 #endif
 
+#ifdef HB_NO_GETENV
+#define getenv(Name) nullptr
+#endif
+
+#ifndef HB_NO_ERRNO
+#  include <errno.h>
+#else
+static int HB_UNUSED _hb_errno = 0;
+#  undef errno
+#  define errno _hb_errno
+#endif
+
 #if defined(HAVE_ATEXIT) && !defined(HB_USE_ATEXIT)
 /* atexit() is only safe to be called from shared libraries on certain
  * platforms.  Whitelist.
@@ -460,87 +436,13 @@ static_assert ((sizeof (hb_position_t) == 4), "");
 static_assert ((sizeof (hb_mask_t) == 4), "");
 static_assert ((sizeof (hb_var_int_t) == 4), "");
 
-
-#if __cplusplus >= 201103L
-
-/* We only enable these with C++11 or later, since earlier language
- * does not allow structs with constructors in unions, and we need
- * those. */
-
-#define HB_NO_COPY_ASSIGN(TypeName) \
-  TypeName(const TypeName&); \
-  void operator=(const TypeName&)
-#define HB_NO_COPY_ASSIGN_TEMPLATE(TypeName, T) \
-  TypeName(const TypeName<T>&); \
-  void operator=(const TypeName<T>&)
-#define HB_NO_COPY_ASSIGN_TEMPLATE2(TypeName, T1, T2) \
-  TypeName(const TypeName<T1, T2>&); \
-  void operator=(const TypeName<T1, T2>&)
-#define HB_NO_CREATE_COPY_ASSIGN(TypeName) \
-  TypeName(); \
-  TypeName(const TypeName&); \
-  void operator=(const TypeName&)
-#define HB_NO_CREATE_COPY_ASSIGN_TEMPLATE(TypeName, T) \
-  TypeName(); \
-  TypeName(const TypeName<T>&); \
-  void operator=(const TypeName<T>&)
-#define HB_NO_CREATE_COPY_ASSIGN_TEMPLATE2(TypeName, T1, T2) \
-  TypeName(); \
-  TypeName(const TypeName<T1, T2>&); \
-  void operator=(const TypeName<T1, T2>&)
-
-#else /* __cpluspplus >= 201103L */
-
-#define HB_NO_COPY_ASSIGN(TypeName) static_assert (true, "")
-#define HB_NO_COPY_ASSIGN_TEMPLATE(TypeName, T) static_assert (true, "")
-#define HB_NO_COPY_ASSIGN_TEMPLATE2(TypeName, T1, T2) static_assert (true, "")
-#define HB_NO_CREATE_COPY_ASSIGN(TypeName) static_assert (true, "")
-#define HB_NO_CREATE_COPY_ASSIGN_TEMPLATE(TypeName, T) static_assert (true, "")
-#define HB_NO_CREATE_COPY_ASSIGN_TEMPLATE2(TypeName, T1, T2) static_assert (true, "")
-
-#endif /* __cpluspplus >= 201103L */
-
-
-/*
- * Compiler-assisted vectorization parameters.
- */
-
-/*
- * Disable vectorization for now.  To correctly use them, we should
- * use posix_memalign() to allocate in hb_vector_t.  Otherwise, can
- * cause misaligned access.
- *
- * https://bugs.chromium.org/p/chromium/issues/detail?id=860184
- */
-#if !defined(HB_VECTOR_SIZE)
-#  define HB_VECTOR_SIZE 0
-#endif
-
-/* The `vector_size' attribute was introduced in gcc 3.1. */
-#if !defined(HB_VECTOR_SIZE)
-#  if defined( __GNUC__ ) && ( __GNUC__ >= 4 )
-#    define HB_VECTOR_SIZE 128
-#  else
-#    define HB_VECTOR_SIZE 0
-#  endif
-#endif
-static_assert (0 == (HB_VECTOR_SIZE & (HB_VECTOR_SIZE - 1)), "HB_VECTOR_SIZE is not power of 2.");
-static_assert (0 == (HB_VECTOR_SIZE % 64), "HB_VECTOR_SIZE is not multiple of 64.");
-#if HB_VECTOR_SIZE
-typedef uint64_t hb_vector_size_impl_t __attribute__((vector_size (HB_VECTOR_SIZE / 8)));
-#else
-typedef uint64_t hb_vector_size_impl_t;
-#endif
-
-
-/* HB_NDEBUG disables some sanity checks that are very safe to disable and
- * should be disabled in production systems.  If NDEBUG is defined, enable
- * HB_NDEBUG; but if it's desirable that normal assert()s (which are very
- * light-weight) to be enabled, then HB_DEBUG can be defined to disable
- * the costlier checks. */
-#ifdef NDEBUG
-#define HB_NDEBUG 1
-#endif
+#define HB_DELETE_COPY_ASSIGN(TypeName) \
+  TypeName(const TypeName&) = delete; \
+  void operator=(const TypeName&) = delete
+#define HB_DELETE_CREATE_COPY_ASSIGN(TypeName) \
+  TypeName() = delete; \
+  TypeName(const TypeName&) = delete; \
+  void operator=(const TypeName&) = delete
 
 
 /* Flags */
@@ -580,47 +482,112 @@ typedef uint64_t hb_vector_size_impl_t;
 
 
 /* Size signifying variable-sized array */
-#define VAR 1
-
+#ifndef HB_VAR_ARRAY
+#define HB_VAR_ARRAY 1
+#endif
 
-/* fallback for round() */
 static inline double
-_hb_round (double x)
+_hb_roundf (float x)
 {
-  if (x >= 0)
-    return floor (x + 0.5);
-  else
-    return ceil (x - 0.5);
+  return x >= 0 ? floor ((double) x + .5) : ceil ((double) x - .5);
 }
-#if !defined (HAVE_ROUND) && !defined (HAVE_DECL_ROUND)
-#define round(x) _hb_round(x)
+#ifndef HAVE_ROUNDF
+#define roundf(x) _hb_roundf(x)
 #endif
 
+/* Endian swap, used in Windows related backends */
+static inline uint16_t hb_uint16_swap (const uint16_t v)
+{ return (v >> 8) | (v << 8); }
+static inline uint32_t hb_uint32_swap (const uint32_t v)
+{ return (hb_uint16_swap (v) << 16) | hb_uint16_swap (v >> 16); }
 
-/* fallback for posix_memalign() */
-static inline int
-_hb_memalign(void **memptr, size_t alignment, size_t size)
-{
-  if (unlikely (0 != (alignment & (alignment - 1)) ||
-               !alignment ||
-               0 != (alignment & (sizeof (void *) - 1))))
-    return EINVAL;
-
-  char *p = (char *) malloc (size + alignment - 1);
-  if (unlikely (!p))
-    return ENOMEM;
-
-  size_t off = (size_t) p & (alignment - 1);
-  if (off)
-    p += alignment - off;
+/*
+ * Big-endian integers.  Here because fundamental.
+ */
 
-  *memptr = (void *) p;
+template <typename Type, int Bytes> struct BEInt;
 
-  return 0;
-}
-#if !defined(posix_memalign) && !defined(HAVE_POSIX_MEMALIGN)
-#define posix_memalign _hb_memalign
-#endif
+template <typename Type>
+struct BEInt<Type, 1>
+{
+  public:
+  BEInt<Type, 1>& operator = (Type V)
+  {
+    v = V;
+    return *this;
+  }
+  operator Type () const { return v; }
+  private: uint8_t v;
+};
+template <typename Type>
+struct BEInt<Type, 2>
+{
+  public:
+  BEInt<Type, 2>& operator = (Type V)
+  {
+    v[0] = (V >>  8) & 0xFF;
+    v[1] = (V      ) & 0xFF;
+    return *this;
+  }
+  operator Type () const
+  {
+#if ((defined(__GNUC__) && __GNUC__ >= 5) || defined(__clang__)) && \
+    defined(__BYTE_ORDER) && \
+    (__BYTE_ORDER == __LITTLE_ENDIAN || __BYTE_ORDER == __BIG_ENDIAN)
+    /* Spoon-feed the compiler a big-endian integer with alignment 1.
+     * https://github.com/harfbuzz/harfbuzz/pull/1398 */
+    struct __attribute__((packed)) packed_uint16_t { uint16_t v; };
+#if __BYTE_ORDER == __LITTLE_ENDIAN
+    return __builtin_bswap16 (((packed_uint16_t *) this)->v);
+#else /* __BYTE_ORDER == __BIG_ENDIAN */
+    return ((packed_uint16_t *) this)->v;
+#endif
+#endif
+    return (v[0] <<  8)
+        + (v[1]      );
+  }
+  private: uint8_t v[2];
+};
+template <typename Type>
+struct BEInt<Type, 3>
+{
+  public:
+  BEInt<Type, 3>& operator = (Type V)
+  {
+    v[0] = (V >> 16) & 0xFF;
+    v[1] = (V >>  8) & 0xFF;
+    v[2] = (V      ) & 0xFF;
+    return *this;
+  }
+  operator Type () const
+  {
+    return (v[0] << 16)
+        + (v[1] <<  8)
+        + (v[2]      );
+  }
+  private: uint8_t v[3];
+};
+template <typename Type>
+struct BEInt<Type, 4>
+{
+  public:
+  BEInt<Type, 4>& operator = (Type V)
+  {
+    v[0] = (V >> 24) & 0xFF;
+    v[1] = (V >> 16) & 0xFF;
+    v[2] = (V >>  8) & 0xFF;
+    v[3] = (V      ) & 0xFF;
+    return *this;
+  }
+  operator Type () const
+  {
+    return (v[0] << 24)
+        + (v[1] << 16)
+        + (v[2] <<  8)
+        + (v[3]      );
+  }
+  private: uint8_t v[4];
+};
 
 
 /*
@@ -631,28 +598,18 @@ _hb_memalign(void **memptr, size_t alignment, size_t size)
 #define HB_SCRIPT_MYANMAR_ZAWGYI       ((hb_script_t) HB_TAG ('Q','a','a','g'))
 
 
-/* Some really basic things everyone wants. */
-template <typename T> struct hb_remove_const { typedef T value; };
-template <typename T> struct hb_remove_const<const T> { typedef T value; };
-#define hb_remove_const(T) hb_remove_const<T>::value
-template <typename T> struct hb_remove_reference { typedef T value; };
-template <typename T> struct hb_remove_reference<T &> { typedef T value; };
-#define hb_remove_reference(T) hb_remove_reference<T>::value
-template <typename T> struct hb_remove_pointer { typedef T value; };
-template <typename T> struct hb_remove_pointer<T *> { typedef T value; };
-#define hb_remove_pointer(T) hb_remove_pointer<T>::value
-
-
 /* Headers we include for everyone.  Keep topologically sorted by dependency.
  * They express dependency amongst themselves, but no other file should include
  * them directly.*/
-#include "hb-atomic.hh"
+#include "hb-meta.hh"
 #include "hb-mutex.hh"
-#include "hb-null.hh"
-#include "hb-dsalgs.hh"        // Requires: hb-null
-#include "hb-iter.hh"  // Requires: hb-null
-#include "hb-debug.hh" // Requires: hb-atomic hb-dsalgs
-#include "hb-array.hh" // Requires: hb-dsalgs hb-iter hb-null
+#include "hb-number.hh"
+#include "hb-atomic.hh"        // Requires: hb-meta
+#include "hb-null.hh"  // Requires: hb-meta
+#include "hb-algs.hh"  // Requires: hb-meta hb-null hb-number
+#include "hb-iter.hh"  // Requires: hb-algs hb-meta
+#include "hb-debug.hh" // Requires: hb-algs hb-atomic
+#include "hb-array.hh" // Requires: hb-algs hb-iter hb-null
 #include "hb-vector.hh"        // Requires: hb-array hb-null
 #include "hb-object.hh"        // Requires: hb-atomic hb-mutex hb-vector
 
index 490b76e..983cb55 100644 (file)
 
 using namespace OT;
 
+#ifdef HB_NO_OPEN
+#define hb_blob_create_from_file(x)  hb_blob_get_empty ()
+#endif
+
 int
 main (int argc, char **argv)
 {
-  if (argc != 2) {
+  if (argc != 2)
+  {
     fprintf (stderr, "usage: %s font-file.ttf\n", argv[0]);
     exit (1);
   }
@@ -61,7 +66,8 @@ main (int argc, char **argv)
   const OpenTypeFontFile& ot = *sanitized;
 
 
-  switch (ot.get_tag ()) {
+  switch (ot.get_tag ())
+  {
   case OpenTypeFontFile::TrueTypeTag:
     printf ("OpenType font with TrueType outlines\n");
     break;
@@ -87,20 +93,23 @@ main (int argc, char **argv)
 
   int num_fonts = ot.get_face_count ();
   printf ("%d font(s) found in file\n", num_fonts);
-  for (int n_font = 0; n_font < num_fonts; n_font++) {
+  for (int n_font = 0; n_font < num_fonts; n_font++)
+  {
     const OpenTypeFontFace &font = ot.get_face (n_font);
     printf ("Font %d of %d:\n", n_font, num_fonts);
 
     int num_tables = font.get_table_count ();
     printf ("  %d table(s) found in font\n", num_tables);
-    for (int n_table = 0; n_table < num_tables; n_table++) {
+    for (int n_table = 0; n_table < num_tables; n_table++)
+    {
       const OpenTypeTable &table = font.get_table (n_table);
       printf ("  Table %2d of %2d: %.4s (0x%08x+0x%08x)\n", n_table, num_tables,
              (const char *) table.tag,
              (unsigned int) table.offset,
              (unsigned int) table.length);
 
-      switch (table.tag) {
+      switch (table.tag)
+      {
 
       case HB_OT_TAG_GSUB:
       case HB_OT_TAG_GPOS:
@@ -110,10 +119,11 @@ main (int argc, char **argv)
 
        int num_scripts = g.get_script_count ();
        printf ("    %d script(s) found in table\n", num_scripts);
-       for (int n_script = 0; n_script < num_scripts; n_script++) {
+       for (int n_script = 0; n_script < num_scripts; n_script++)
+       {
          const Script &script = g.get_script (n_script);
          printf ("    Script %2d of %2d: %.4s\n", n_script, num_scripts,
-                 (const char *)g.get_script_tag(n_script));
+                 (const char *)g.get_script_tag(n_script));
 
          if (!script.has_default_lang_sys())
            printf ("      No default language system\n");
@@ -136,34 +146,37 @@ main (int argc, char **argv)
 
            int num_features = langsys.get_feature_count ();
            printf ("        %d feature(s) found in language system\n", num_features);
-           for (int n_feature = 0; n_feature < num_features; n_feature++) {
+           for (int n_feature = 0; n_feature < num_features; n_feature++)
+           {
              printf ("        Feature index %2d of %2d: %d\n", n_feature, num_features,
-                     langsys.get_feature_index (n_feature));
+                     langsys.get_feature_index (n_feature));
            }
          }
        }
 
        int num_features = g.get_feature_count ();
        printf ("    %d feature(s) found in table\n", num_features);
-       for (int n_feature = 0; n_feature < num_features; n_feature++) {
+       for (int n_feature = 0; n_feature < num_features; n_feature++)
+       {
          const Feature &feature = g.get_feature (n_feature);
          int num_lookups = feature.get_lookup_count ();
          printf ("    Feature %2d of %2d: %c%c%c%c\n", n_feature, num_features,
-                 HB_UNTAG(g.get_feature_tag(n_feature)));
+                 HB_UNTAG(g.get_feature_tag(n_feature)));
 
          printf ("        %d lookup(s) found in feature\n", num_lookups);
          for (int n_lookup = 0; n_lookup < num_lookups; n_lookup++) {
            printf ("        Lookup index %2d of %2d: %d\n", n_lookup, num_lookups,
-                   feature.get_lookup_index (n_lookup));
+                   feature.get_lookup_index (n_lookup));
          }
        }
 
        int num_lookups = g.get_lookup_count ();
        printf ("    %d lookup(s) found in table\n", num_lookups);
-       for (int n_lookup = 0; n_lookup < num_lookups; n_lookup++) {
+       for (int n_lookup = 0; n_lookup < num_lookups; n_lookup++)
+       {
          const Lookup &lookup = g.get_lookup (n_lookup);
          printf ("    Lookup %2d of %2d: type %d, props 0x%04X\n", n_lookup, num_lookups,
-                 lookup.get_type(), lookup.get_props());
+                 lookup.get_type(), lookup.get_props());
        }
 
        }
diff --git a/src/test-algs.cc b/src/test-algs.cc
new file mode 100644 (file)
index 0000000..f8b8ff6
--- /dev/null
@@ -0,0 +1,95 @@
+/*
+ * Copyright © 2019  Facebook, 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.
+ *
+ * Facebook Author(s): Behdad Esfahbod
+ */
+
+#include "hb.hh"
+#include "hb-algs.hh"
+
+
+static char *
+test_func (int a, char **b)
+{
+  return b ? b[a] : nullptr;
+}
+
+struct A
+{
+  void a () {}
+};
+
+int
+main (int argc, char **argv)
+{
+  int i = 1;
+  auto p = hb_pair (1, i);
+
+  p.second = 2;
+  assert (i == 2);
+
+  const int c = 3;
+  auto pc = hb_pair (1, c);
+  assert (pc.second == 3);
+
+  auto q = p;
+  assert (&q != &p);
+  q.second = 4;
+  assert (i == 4);
+
+  hb_invoke (test_func, 0, nullptr);
+
+  A a;
+  hb_invoke (&A::a, a);
+
+  assert (1 == hb_min (8, 1));
+  assert (8 == hb_max (8, 1));
+
+  int x = 1, y = 2;
+  hb_min (x, 3);
+  hb_min (3, x);
+  hb_min (x, 4 + 3);
+  int &z = hb_min (x, y);
+  z = 3;
+  assert (x == 3);
+
+  hb_pair_t<const int*, int> xp = hb_pair_t<int *, long> (nullptr, 0);
+  xp = hb_pair_t<int *, double> (nullptr, 1);
+  xp = hb_pair_t<const int*, int> (nullptr, 1);
+
+  assert (3 == hb_partial (hb_min, 3) (4));
+  assert (3 == hb_partial<1> (hb_min, 4) (3));
+
+  auto M0 = hb_partial<2> (hb_max, 0);
+  assert (M0 (-2) == 0);
+  assert (M0 (+2) == 2);
+
+  assert (hb_add (2) (5) == 7);
+  assert (hb_add (5) (2) == 7);
+
+  x = 1;
+  assert (++hb_inc (x) == 3);
+  assert (x == 3);
+
+  return 0;
+}
diff --git a/src/test-bimap.cc b/src/test-bimap.cc
new file mode 100644 (file)
index 0000000..1253d0c
--- /dev/null
@@ -0,0 +1,76 @@
+/*
+ * Copyright © 2019  Adobe, 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.
+ *
+ * Adobe Author(s): Michiharu Ariza
+ */
+
+#include "hb.hh"
+#include "hb-bimap.hh"
+
+int
+main (int argc, char **argv)
+{
+  hb_bimap_t   bm;
+
+  assert (bm.is_empty () == true);
+  bm.set (1, 4);
+  bm.set (2, 5);
+  bm.set (3, 6);
+  assert (bm.get_population () == 3);
+  assert (bm.has (1) == true);
+  assert (bm.has (4) == false);
+  assert (bm[2] == 5);
+  assert (bm.backward (6) == 3);
+  bm.del (1);
+  assert (bm.has (1) == false);
+  assert (bm.has (3) == true);
+  bm.clear ();
+  assert (bm.get_population () == 0);
+
+  hb_inc_bimap_t  ibm;
+
+  assert (ibm.add (13) == 0);
+  assert (ibm.add (8) == 1);
+  assert (ibm.add (10) == 2);
+  assert (ibm.add (8) == 1);
+  assert (ibm.add (7) == 3);
+  assert (ibm.get_population () == 4);
+  assert (ibm[7] == 3);
+
+  ibm.sort ();
+  assert (ibm.get_population () == 4);
+  assert (ibm[7] == 0);
+  assert (ibm[13] == 3);
+
+  ibm.identity (3);
+  assert (ibm.get_population () == 3);
+  assert (ibm[0] == 0);
+  assert (ibm[1] == 1);
+  assert (ibm[2] == 2);
+  assert (ibm.backward (0) == 0);
+  assert (ibm.backward (1) == 1);
+  assert (ibm.backward (2) == 2);
+  assert (ibm.has (4) == false);
+
+  return 0;
+}
index a91f4f7..6393f0b 100644 (file)
 
 #include <stdio.h>
 
+#ifdef HB_NO_OPEN
+#define hb_blob_create_from_file(x)  hb_blob_get_empty ()
+#endif
+
 int
 main (int argc, char **argv)
 {
+  bool ret = true;
+
+#ifndef HB_NO_BUFFER_SERIALIZE
+
   if (argc != 2) {
     fprintf (stderr, "usage: %s font-file\n", argv[0]);
     exit (1);
@@ -59,7 +67,6 @@ main (int argc, char **argv)
   hb_buffer_t *buf;
   buf = hb_buffer_create ();
 
-  bool ret = true;
   char line[BUFSIZ], out[BUFSIZ];
   while (fgets (line, sizeof(line), stdin) != nullptr)
   {
@@ -85,5 +92,7 @@ main (int argc, char **argv)
 
   hb_font_destroy (font);
 
+#endif
+
   return !ret;
 }
similarity index 86%
rename from src/test-size-params.cc
rename to src/test-gpos-size-params.cc
index 12eec61..ad10ed4 100644 (file)
 
 #include <stdio.h>
 
+#ifdef HB_NO_OPEN
+#define hb_blob_create_from_file(x)  hb_blob_get_empty ()
+#endif
+
 int
 main (int argc, char **argv)
 {
@@ -45,10 +49,15 @@ main (int argc, char **argv)
   hb_blob_destroy (blob);
   blob = nullptr;
 
-  unsigned int p[5];
-  bool ret = hb_ot_layout_get_size_params (face, p, p+1, (p+2), p+3, p+4);
+  bool ret = true;
 
+#ifndef HB_NO_LAYOUT_FEATURE_PARAMS
+  unsigned int p[5];
+  ret = hb_ot_layout_get_size_params (face, p, p+1, (p+2), p+3, p+4);
   printf ("%g %u %u %g %g\n", p[0]/10., p[1], p[2], p[3]/10., p[4]/10.);
+#endif
+
+  hb_face_destroy (face);
 
   return !ret;
 }
similarity index 96%
rename from src/test-would-substitute.cc
rename to src/test-gsub-would-substitute.cc
index 268f7db..7ad9e08 100644 (file)
 #include "hb-ft.h"
 #endif
 
+#ifdef HB_NO_OPEN
+#define hb_blob_create_from_file(x)  hb_blob_get_empty ()
+#endif
+
 int
 main (int argc, char **argv)
 {
index 05430b0..9c83171 100644 (file)
 
 #include "hb-array.hh"
 #include "hb-set.hh"
+#include "hb-ot-layout-common.hh"
 
 
 template <typename T>
-struct array_iter_t : hb_iter_t<array_iter_t<T>, T>, hb_iter_mixin_t<array_iter_t<T>, T>
+struct array_iter_t : hb_iter_with_fallback_t<array_iter_t<T>, T&>
 {
   array_iter_t (hb_array_t<T> arr_) : arr (arr_) {}
 
-  typedef T __item_type__;
+  typedef T& __item_t__;
+  static constexpr bool is_random_access_iterator = true;
   T& __item_at__ (unsigned i) const { return arr[i]; }
   void __forward__ (unsigned n) { arr += n; }
   void __rewind__ (unsigned n) { arr -= n; }
   unsigned __len__ () const { return arr.length; }
-  bool __random_access__ () const { return true; }
+  bool operator != (const array_iter_t& o) { return arr != o.arr; }
 
   private:
   hb_array_t<T> arr;
@@ -55,12 +57,63 @@ struct some_array_t
   typedef array_iter_t<T> iter_t;
   array_iter_t<T> iter () { return array_iter_t<T> (arr); }
   operator array_iter_t<T> () { return iter (); }
-  operator hb_iter_t<array_iter_t<T> > () { return iter (); }
+  operator hb_iter_t<array_iter_t<T>> () { return iter (); }
 
   private:
   hb_array_t<T> arr;
 };
 
+
+template <typename Iter,
+         hb_requires (hb_is_iterator (Iter))>
+static void
+test_iterator_non_default_constructable (Iter it)
+{
+  /* Iterate over a copy of it. */
+  for (auto c = it.iter (); c; c++)
+    *c;
+
+  /* Same. */
+  for (auto c = +it; c; c++)
+    *c;
+
+  /* Range-based for over a copy. */
+  for (auto _ : +it)
+    (void) _;
+
+  it += it.len ();
+  it = it + 10;
+  it = 10 + it;
+
+  assert (*it == it[0]);
+
+  static_assert (true || it.is_random_access_iterator, "");
+  static_assert (true || it.is_sorted_iterator, "");
+}
+
+template <typename Iter,
+         hb_requires (hb_is_iterator (Iter))>
+static void
+test_iterator (Iter it)
+{
+  Iter default_constructed;
+  assert (!default_constructed);
+
+  test_iterator_non_default_constructable (it);
+}
+
+template <typename Iterable,
+         hb_requires (hb_is_iterable (Iterable))>
+static void
+test_iterable (const Iterable &lst = Null(Iterable))
+{
+  for (auto _ : lst)
+    (void) _;
+
+  // Test that can take iterator from.
+  test_iterator (lst.iter ());
+}
+
 int
 main (int argc, char **argv)
 {
@@ -72,13 +125,162 @@ main (int argc, char **argv)
   array_iter_t<const int> s2 (v); /* Implicit conversion from vector. */
   array_iter_t<int> t (dst);
 
+  static_assert (array_iter_t<int>::is_random_access_iterator, "");
+
   some_array_t<const int> a (src);
 
   s2 = s;
 
+  hb_iter (src);
+  hb_iter (src, 2);
+
   hb_fill (t, 42);
-  hb_copy (t, s);
- // hb_copy (t, a.iter ());
+  hb_copy (s, t);
+  hb_copy (a.iter (), t);
+
+  test_iterable (v);
+  hb_set_t st;
+  st << 1 << 15 << 43;
+  test_iterable (st);
+  hb_sorted_array_t<int> sa;
+  (void) static_cast<hb_iter_t<hb_sorted_array_t<int>, hb_sorted_array_t<int>::item_t>&> (sa);
+  (void) static_cast<hb_iter_t<hb_sorted_array_t<int>, hb_sorted_array_t<int>::__item_t__>&> (sa);
+  (void) static_cast<hb_iter_t<hb_sorted_array_t<int>, int&>&>(sa);
+  (void) static_cast<hb_iter_t<hb_sorted_array_t<int>>&>(sa);
+  (void) static_cast<hb_iter_t<hb_array_t<int>, int&>&> (sa);
+  test_iterable (sa);
+
+  test_iterable<hb_array_t<int>> ();
+  test_iterable<hb_sorted_array_t<const int>> ();
+  test_iterable<hb_vector_t<float>> ();
+  test_iterable<hb_set_t> ();
+  test_iterable<OT::Coverage> ();
+
+  test_iterator (hb_zip (st, v));
+  test_iterator_non_default_constructable (hb_enumerate (st));
+  test_iterator_non_default_constructable (hb_enumerate (st, -5));
+  test_iterator_non_default_constructable (hb_enumerate (hb_iter (st)));
+  test_iterator_non_default_constructable (hb_enumerate (hb_iter (st) + 1));
+  test_iterator_non_default_constructable (hb_iter (st) | hb_filter ());
+  test_iterator_non_default_constructable (hb_iter (st) | hb_map (hb_lidentity));
+
+  assert (true == hb_all (st));
+  assert (false == hb_all (st, 42u));
+  assert (true == hb_any (st));
+  assert (false == hb_any (st, 14u));
+  assert (true == hb_any (st, 14u, [] (unsigned _) { return _ - 1u; }));
+  assert (true == hb_any (st, [] (unsigned _) { return _ == 15u; }));
+  assert (true == hb_any (st, 15u));
+  assert (false == hb_none (st));
+  assert (false == hb_none (st, 15u));
+  assert (true == hb_none (st, 17u));
+
+  hb_array_t<hb_vector_t<int>> pa;
+  pa->as_array ();
+
+  hb_map_t m;
+
+  hb_iter (st);
+  hb_iter (&st);
+
+  + hb_iter (src)
+  | hb_map (m)
+  | hb_map (&m)
+  | hb_filter ()
+  | hb_filter (st)
+  | hb_filter (&st)
+  | hb_filter (hb_bool)
+  | hb_filter (hb_bool, hb_identity)
+  | hb_sink (st)
+  ;
+
+  + hb_iter (src)
+  | hb_sink (hb_array (dst))
+  ;
+
+  + hb_iter (src)
+  | hb_apply (&st)
+  ;
+
+  + hb_iter (src)
+  | hb_map ([] (int i) { return 1; })
+  | hb_reduce ([=] (int acc, int value) { return acc; }, 2)
+  ;
+
+  using map_pair_t = hb_item_type<hb_map_t>;
+  + hb_iter (m)
+  | hb_map ([] (map_pair_t p) { return p.first * p.second; })
+  ;
+
+  m.keys ();
+  using map_key_t = decltype (*m.keys());
+  + hb_iter (m.keys ())
+  | hb_filter ([] (map_key_t k) { return k < 42; })
+  | hb_drain
+  ;
+
+  m.values ();
+  using map_value_t = decltype (*m.values());
+  + hb_iter (m.values ())
+  | hb_filter ([] (map_value_t k) { return k < 42; })
+  | hb_drain
+  ;
+
+  unsigned int temp1 = 10;
+  unsigned int temp2 = 0;
+  hb_map_t *result =
+  + hb_iter (src)
+  | hb_map ([&] (int i) -> hb_set_t *
+           {
+             hb_set_t *set = hb_set_create ();
+             for (unsigned int i = 0; i < temp1; ++i)
+               hb_set_add (set, i);
+             temp1++;
+             return set;
+           })
+  | hb_reduce ([&] (hb_map_t *acc, hb_set_t *value) -> hb_map_t *
+              {
+                hb_map_set (acc, temp2++, hb_set_get_population (value));
+                /* This is not a memory managed language, take care! */
+                hb_set_destroy (value);
+                return acc;
+              }, hb_map_create ())
+  ;
+  /* The result should be something like 0->10, 1->11, ..., 9->19 */
+  assert (hb_map_get (result, 9) == 19);
+
+  unsigned int temp3 = 0;
+  + hb_iter(src)
+  | hb_map([&] (int i) { return ++temp3; })
+  | hb_reduce([&] (float acc, int value) { return acc + value; }, 0)
+  ;
+  hb_map_destroy (result);
+
+  + hb_iter (src)
+  | hb_drain
+  ;
+
+  t << 1;
+  long vl;
+  s >> vl;
+
+  hb_iota ();
+  hb_iota (3);
+  hb_iota (3, 2);
+  assert ((&vl) + 1 == *++hb_iota (&vl, hb_inc));
+  hb_range ();
+  hb_repeat (7u);
+  hb_repeat (nullptr);
+  hb_repeat (vl) | hb_chop (3);
+  assert (hb_len (hb_range (10) | hb_take (3)) == 3);
+  assert (hb_range (9).len () == 9);
+  assert (hb_range (2, 9).len () == 7);
+  assert (hb_range (2, 9, 3).len () == 3);
+  assert (hb_range (2, 8, 3).len () == 2);
+  assert (hb_range (2, 7, 3).len () == 2);
+  assert (hb_range (-2, -9, -3).len () == 3);
+  assert (hb_range (-2, -8, -3).len () == 2);
+  assert (hb_range (-2, -7, -3).len () == 2);
 
   return 0;
 }
diff --git a/src/test-meta.cc b/src/test-meta.cc
new file mode 100644 (file)
index 0000000..0b6e02c
--- /dev/null
@@ -0,0 +1,128 @@
+/*
+ * Copyright © 2019  Facebook, 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.
+ *
+ * Facebook Author(s): Behdad Esfahbod
+ */
+
+#include "hb.hh"
+#include "hb-meta.hh"
+
+#include <type_traits>
+
+int
+main (int argc, char **argv)
+{
+  static_assert (hb_is_convertible (void, void), "");
+  static_assert (hb_is_convertible (void, const void), "");
+  static_assert (hb_is_convertible (const void, void), "");
+
+  static_assert (hb_is_convertible (int,  int), "");
+  static_assert (hb_is_convertible (char, int), "");
+  static_assert (hb_is_convertible (long, int), "");
+
+  static_assert (hb_is_convertible (int, int), "");
+
+  static_assert (hb_is_convertible (const int, int), "");
+  static_assert (hb_is_convertible (int, const int), "");
+  static_assert (hb_is_convertible (const int, const int), "");
+
+  static_assert (hb_is_convertible (int&, int), "");
+  static_assert (!hb_is_convertible (int, int&), "");
+
+  static_assert (hb_is_convertible (int, const int&), "");
+  static_assert (!hb_is_convertible (const int, int&), "");
+  static_assert (hb_is_convertible (const int, const int&), "");
+  static_assert (hb_is_convertible (int&, const int), "");
+  static_assert (hb_is_convertible (const int&, int), "");
+  static_assert (hb_is_convertible (const int&, const int), "");
+  static_assert (hb_is_convertible (const int&, const int), "");
+
+  struct X {};
+  struct Y : X {};
+
+  static_assert (hb_is_convertible (const X &, const X), "");
+  static_assert (hb_is_convertible (X &, const X), "");
+  static_assert (hb_is_convertible (X &, const X &), "");
+  static_assert (hb_is_convertible (X, const X &), "");
+  static_assert (hb_is_convertible (const X, const X &), "");
+  static_assert (!hb_is_convertible (const X, X &), "");
+  static_assert (!hb_is_convertible (X, X &), "");
+  static_assert (hb_is_convertible (X &, X &), "");
+
+  static_assert (hb_is_convertible (int&, long), "");
+  static_assert (!hb_is_convertible (int&, long&), "");
+
+  static_assert (hb_is_convertible (int *, int *), "");
+  static_assert (hb_is_convertible (int *, const int *), "");
+  static_assert (!hb_is_convertible (const int *, int *), "");
+  static_assert (!hb_is_convertible (int *, long *), "");
+  static_assert (hb_is_convertible (int *, void *), "");
+  static_assert (!hb_is_convertible (void *, int *), "");
+
+  static_assert (hb_is_base_of (void, void), "");
+  static_assert (hb_is_base_of (void, int), "");
+  static_assert (!hb_is_base_of (int, void), "");
+
+  static_assert (hb_is_base_of (int, int), "");
+  static_assert (hb_is_base_of (const int, int), "");
+  static_assert (hb_is_base_of (int, const int), "");
+
+  static_assert (hb_is_base_of (X, X), "");
+  static_assert (hb_is_base_of (X, Y), "");
+  static_assert (hb_is_base_of (const X, Y), "");
+  static_assert (hb_is_base_of (X, const Y), "");
+  static_assert (!hb_is_base_of (Y, X), "");
+
+  static_assert (hb_is_constructible (int), "");
+  static_assert (hb_is_constructible (int, int), "");
+  static_assert (hb_is_constructible (int, char), "");
+  static_assert (hb_is_constructible (int, long), "");
+  static_assert (!hb_is_constructible (int, X), "");
+  static_assert (!hb_is_constructible (int, int, int), "");
+  static_assert (hb_is_constructible (X), "");
+  static_assert (!hb_is_constructible (X, int), "");
+  static_assert (hb_is_constructible (X, X), "");
+  static_assert (!hb_is_constructible (X, X, X), "");
+  static_assert (hb_is_constructible (X, Y), "");
+  static_assert (!hb_is_constructible (Y, X), "");
+
+  static_assert (hb_is_trivially_default_constructible (X), "");
+  static_assert (hb_is_trivially_default_constructible (Y), "");
+  static_assert (hb_is_trivially_copy_constructible (X), "");
+  static_assert (hb_is_trivially_copy_constructible (Y), "");
+  static_assert (hb_is_trivially_move_constructible (X), "");
+  static_assert (hb_is_trivially_move_constructible (Y), "");
+  static_assert (hb_is_trivially_destructible (Y), "");
+
+  static_assert (hb_is_trivially_copyable (int), "");
+  static_assert (hb_is_trivially_copyable (X), "");
+  static_assert (hb_is_trivially_copyable (Y), "");
+
+  static_assert (hb_is_trivial (int), "");
+  static_assert (hb_is_trivial (X), "");
+  static_assert (hb_is_trivial (Y), "");
+
+  /* TODO Add more meaningful tests. */
+
+  return 0;
+}
diff --git a/src/test-number.cc b/src/test-number.cc
new file mode 100644 (file)
index 0000000..3591b13
--- /dev/null
@@ -0,0 +1,253 @@
+/*
+ * Copyright © 2019  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.
+ *
+ */
+
+#include "hb.hh"
+#include "hb-number.hh"
+#include "hb-number-parser.hh"
+
+
+int
+main (int argc, char **argv)
+{
+  {
+    const char str[] = "123";
+    const char *pp = str;
+    const char *end = str + 3;
+
+    int pv;
+    assert (hb_parse_int (&pp, end, &pv));
+    assert (pv == 123);
+    assert (pp - str == 3);
+    assert (end - pp == 0);
+    assert (!*end);
+  }
+
+  {
+    const char str[] = "123";
+    const char *pp = str;
+    const char *end = str + strlen (str);
+
+    unsigned int pv;
+    assert (hb_parse_uint (&pp, end, &pv));
+    assert (pv == 123);
+    assert (pp - str == 3);
+    assert (end - pp == 0);
+    assert (!*end);
+  }
+
+  {
+    const char str[] = "12F";
+    const char *pp = str;
+    const char *end = str + 3;
+
+    unsigned int pv;
+    assert (hb_parse_uint (&pp, end, &pv, true, 16));
+    assert (pv == 0x12F);
+    assert (pp - str == 3);
+    assert (end - pp == 0);
+    assert (!*end);
+  }
+
+  {
+    const char str[] = "12Fq";
+    const char *pp = str;
+    const char *end = str + 4;
+
+    unsigned int pv;
+    assert (!hb_parse_uint (&pp, end, &pv, true, 16));
+    assert (hb_parse_uint (&pp, end, &pv, false, 16));
+    assert (pv == 0x12F);
+    assert (pp - str == 3);
+    assert (end - pp == 1);
+    assert (!*end);
+  }
+
+  {
+    const char str[] = "-123";
+    const char *pp = str;
+    const char *end = str + 4;
+
+    int pv;
+    assert (hb_parse_int (&pp, end, &pv));
+    assert (pv == -123);
+    assert (pp - str == 4);
+    assert (end - pp == 0);
+    assert (!*end);
+  }
+
+  {
+    const char str[] = "123";
+    const char *pp = str;
+    assert (ARRAY_LENGTH (str) == 4);
+    const char *end = str + ARRAY_LENGTH (str);
+
+    unsigned int pv;
+    assert (hb_parse_uint (&pp, end, &pv));
+    assert (pv == 123);
+    assert (pp - str == 3);
+    assert (end - pp == 1);
+  }
+
+  {
+    const char str[] = "123\0";
+    const char *pp = str;
+    assert (ARRAY_LENGTH (str) == 5);
+    const char *end = str + ARRAY_LENGTH (str);
+
+    unsigned int pv;
+    assert (hb_parse_uint (&pp, end, &pv));
+    assert (pv == 123);
+    assert (pp - str == 3);
+    assert (end - pp == 2);
+  }
+
+  {
+    const char str[] = "123V";
+    const char *pp = str;
+    assert (ARRAY_LENGTH (str) == 5);
+    const char *end = str + ARRAY_LENGTH (str);
+
+    unsigned int pv;
+    assert (hb_parse_uint (&pp, end, &pv));
+    assert (pv == 123);
+    assert (pp - str == 3);
+    assert (end - pp == 2);
+  }
+
+  {
+    const char str[] = ".123";
+    const char *pp = str;
+    const char *end = str + ARRAY_LENGTH (str);
+
+    double pv;
+    assert (hb_parse_double (&pp, end, &pv));
+    assert ((int) roundf (pv * 1000.) == 123);
+    assert (pp - str == 4);
+    assert (end - pp == 1);
+
+    /* Test strtod_rl even if libc's strtod_l is used */
+    char *pend;
+    assert ((int) roundf (strtod_rl (str, &pend) * 1000.) == 123);
+    assert (pend - str == 4);
+  }
+
+  {
+    const char str[] = "0.123";
+    const char *pp = str;
+    const char *end = str + ARRAY_LENGTH (str) - 1;
+
+    double pv;
+    assert (hb_parse_double (&pp, end, &pv));
+    assert ((int) roundf (pv * 1000.) == 123);
+    assert (pp - str == 5);
+    assert (end - pp == 0);
+
+    char *pend;
+    assert ((int) roundf (strtod_rl (str, &pend) * 1000.) == 123);
+    assert (pend - str == 5);
+  }
+
+  {
+    const char str[] = "0.123e0";
+    const char *pp = str;
+    const char *end = str + ARRAY_LENGTH (str) - 1;
+
+    double pv;
+    assert (hb_parse_double (&pp, end, &pv));
+    assert ((int) roundf (pv * 1000.) == 123);
+    assert (pp - str == 7);
+    assert (end - pp == 0);
+
+    char *pend;
+    assert ((int) roundf (strtod_rl (str, &pend) * 1000.) == 123);
+    assert (pend - str == 7);
+  }
+
+  {
+    const char str[] = "123e-3";
+    const char *pp = str;
+    const char *end = str + ARRAY_LENGTH (str) - 1;
+
+    double pv;
+    assert (hb_parse_double (&pp, end, &pv));
+    assert ((int) roundf (pv * 1000.) == 123);
+    assert (pp - str == 6);
+    assert (end - pp == 0);
+
+    char *pend;
+    assert ((int) roundf (strtod_rl (str, &pend) * 1000.) == 123);
+    assert (pend - str == 6);
+  }
+
+  {
+    const char str[] = ".000123e+3";
+    const char *pp = str;
+    const char *end = str + ARRAY_LENGTH (str) - 1;
+
+    double pv;
+    assert (hb_parse_double (&pp, end, &pv));
+    assert ((int) roundf (pv * 1000.) == 123);
+    assert (pp - str == 10);
+    assert (end - pp == 0);
+
+    char *pend;
+    assert ((int) roundf (strtod_rl (str, &pend) * 1000.) == 123);
+    assert (pend - str == 10);
+  }
+
+  {
+    const char str[] = "-.000000123e6";
+    const char *pp = str;
+    const char *end = str + ARRAY_LENGTH (str) - 1;
+
+    double pv;
+    assert (hb_parse_double (&pp, end, &pv));
+    assert ((int) roundf (pv * 1000.) == -123);
+    assert (pp - str == 13);
+    assert (end - pp == 0);
+
+    char *pend;
+    assert ((int) roundf (strtod_rl (str, &pend) * 1000.) == -123);
+    assert (pend - str == 13);
+  }
+
+  {
+    const char str[] = "-1.23E-1";
+    const char *pp = str;
+    const char *end = str + ARRAY_LENGTH (str) - 1;
+
+    double pv;
+    assert (hb_parse_double (&pp, end, &pv));
+    assert ((int) roundf (pv * 1000.) == -123);
+    assert (pp - str == 8);
+    assert (end - pp == 0);
+
+    char *pend;
+    assert ((int) roundf (strtod_rl (str, &pend) * 1000.) == -123);
+    assert (pend - str == 8);
+  }
+
+  return 0;
+}
index 4050a66..88924b4 100644 (file)
  * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
  */
 
-#include "hb.h"
+#include "hb.hh"
+
+#include <cairo.h>
+
+#ifdef HB_NO_OPEN
+#define hb_blob_create_from_file(x)  hb_blob_get_empty ()
+#endif
+
+#if !defined(HB_NO_COLOR) && defined(CAIRO_HAS_SVG_SURFACE)
+
 #include "hb-ot.h"
 
 #include "hb-ft.h"
@@ -32,7 +41,6 @@
 #include FT_FREETYPE_H
 #include FT_GLYPH_H
 
-#include <cairo.h>
 #include <cairo-ft.h>
 #include <cairo-svg.h>
 
@@ -133,7 +141,7 @@ layered_glyph_dump (hb_face_t *face, cairo_font_face_t *cairo_face, unsigned int
   unsigned glyph_count = hb_face_get_glyph_count (face);
   for (hb_codepoint_t gid = 0; gid < glyph_count; ++gid)
   {
-    unsigned int num_layers = hb_ot_color_glyph_get_layers (face, gid, 0, NULL, NULL);
+    unsigned int num_layers = hb_ot_color_glyph_get_layers (face, gid, 0, nullptr, nullptr);
     if (!num_layers)
       continue;
 
@@ -169,7 +177,7 @@ layered_glyph_dump (hb_face_t *face, cairo_font_face_t *cairo_face, unsigned int
       unsigned int palette_count = hb_ot_color_palette_get_count (face);
       for (unsigned int palette = 0; palette < palette_count; palette++)
       {
-       unsigned int num_colors = hb_ot_color_palette_get_colors (face, palette, 0, NULL, NULL);
+       unsigned int num_colors = hb_ot_color_palette_get_colors (face, palette, 0, nullptr, nullptr);
        if (!num_colors)
          continue;
 
@@ -271,14 +279,14 @@ main (int argc, char **argv)
 
 
   FILE *font_name_file = fopen ("out/.dumped_font_name", "r");
-  if (font_name_file != NULL)
+  if (font_name_file != nullptr)
   {
     fprintf (stderr, "Purge or move ./out folder in order to run a new dump\n");
     exit (1);
   }
 
   font_name_file = fopen ("out/.dumped_font_name", "w");
-  if (font_name_file == NULL)
+  if (font_name_file == nullptr)
   {
     fprintf (stderr, "./out is not accessible as a folder, create it please\n");
     exit (1);
@@ -322,8 +330,8 @@ main (int argc, char **argv)
 
     // disabled when color font as cairo rendering of NotoColorEmoji is soooo slow
     if (!hb_ot_color_has_layers (face) &&
-        !hb_ot_color_has_png (face) &&
-        !hb_ot_color_has_svg (face))
+       !hb_ot_color_has_png (face) &&
+       !hb_ot_color_has_svg (face))
       dump_glyphs (cairo_face, upem, num_glyphs, face_index);
 
     hb_font_destroy (font);
@@ -334,3 +342,7 @@ main (int argc, char **argv)
 
   return 0;
 }
+
+#else
+int main (int argc, char **argv) { return 0; }
+#endif
diff --git a/src/test-ot-meta.cc b/src/test-ot-meta.cc
new file mode 100644 (file)
index 0000000..1045007
--- /dev/null
@@ -0,0 +1,70 @@
+/*
+ * Copyright © 2019  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.
+ */
+
+#include "hb.hh"
+#include "hb-ot.h"
+
+#include <stdlib.h>
+#include <stdio.h>
+
+#ifdef HB_NO_OPEN
+#define hb_blob_create_from_file(x)  hb_blob_get_empty ()
+#endif
+
+int
+main (int argc, char **argv)
+{
+  if (argc != 2) {
+    fprintf (stderr, "usage: %s font-file\n", argv[0]);
+    exit (1);
+  }
+
+  hb_blob_t *blob = hb_blob_create_from_file (argv[1]);
+  hb_face_t *face = hb_face_create (blob, 0 /* first face */);
+  hb_blob_destroy (blob);
+  blob = nullptr;
+
+  unsigned int count = 0;
+
+#ifndef HB_NO_META
+  count = hb_ot_meta_get_entry_tags (face, 0, nullptr, nullptr);
+
+  hb_ot_meta_tag_t *tags = (hb_ot_meta_tag_t *)
+                          malloc (sizeof (hb_ot_meta_tag_t) * count);
+  hb_ot_meta_get_entry_tags (face, 0, &count, tags);
+  for (unsigned i = 0; i < count; ++i)
+  {
+    hb_blob_t *entry = hb_ot_meta_reference_entry (face, tags[i]);
+    printf ("%c%c%c%c, size: %d: %.*s\n",
+           HB_UNTAG (tags[i]), hb_blob_get_length (entry),
+           hb_blob_get_length (entry), hb_blob_get_data (entry, nullptr));
+    hb_blob_destroy (entry);
+  }
+  free (tags);
+#endif
+
+  hb_face_destroy (face);
+
+  return !count;
+}
similarity index 93%
rename from src/test-name-table.cc
rename to src/test-ot-name.cc
index 518e4eb..4a484c6 100644 (file)
 #include <stdlib.h>
 #include <stdio.h>
 
+#ifdef HB_NO_OPEN
+#define hb_blob_create_from_file(x)  hb_blob_get_empty ()
+#endif
+
 int
 main (int argc, char **argv)
 {
@@ -43,7 +47,9 @@ main (int argc, char **argv)
   hb_blob_destroy (blob);
   blob = nullptr;
 
-  unsigned int count;
+  unsigned int count = 0;
+
+#ifndef HB_NO_NAME
   const hb_ot_name_entry_t *entries = hb_ot_name_list_names (face, &count);
 
   for (unsigned int i = 0; i < count; i++)
@@ -62,6 +68,7 @@ main (int argc, char **argv)
 
     printf ("%s\n", buf);
   }
+#endif
 
   hb_face_destroy (face);
 
index 0eef8c2..33cac6b 100644 (file)
@@ -33,9 +33,9 @@ test (hb_codepoint_t cp, unsigned int bit)
   if (OT::_hb_ot_os2_get_unicode_range_bit (cp) != bit)
   {
     fprintf (stderr, "got incorrect bit (%d) for cp 0x%X. Should have been %d.",
-             OT::_hb_ot_os2_get_unicode_range_bit (cp),
-             cp,
-             bit);
+            OT::_hb_ot_os2_get_unicode_range_bit (cp),
+            cp,
+            bit);
     abort();
   }
 }
index f0eace8..65b469f 100644 (file)
 #include "hb-ft.h"
 #endif
 
+#ifdef HB_NO_OPEN
+#define hb_blob_create_from_file(x)  hb_blob_get_empty ()
+#endif
+
 int
 main (int argc, char **argv)
 {
index d16a571..e3bbce9 100644 (file)
@@ -93,6 +93,7 @@ subdir = test
 ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
 am__aclocal_m4_deps = $(top_srcdir)/m4/ax_check_link_flag.m4 \
        $(top_srcdir)/m4/ax_code_coverage.m4 \
+       $(top_srcdir)/m4/ax_cxx_compile_stdcxx.m4 \
        $(top_srcdir)/m4/ax_pthread.m4 $(top_srcdir)/m4/gtk-doc.m4 \
        $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \
        $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \
@@ -235,6 +236,8 @@ FREETYPE_CFLAGS = @FREETYPE_CFLAGS@
 FREETYPE_DEPS = @FREETYPE_DEPS@
 FREETYPE_LIBS = @FREETYPE_LIBS@
 GCOV = @GCOV@
+GDI_CFLAGS = @GDI_CFLAGS@
+GDI_LIBS = @GDI_LIBS@
 GENHTML = @GENHTML@
 GIT = @GIT@
 GLIB_CFLAGS = @GLIB_CFLAGS@
@@ -253,6 +256,7 @@ GTKDOC_DEPS_CFLAGS = @GTKDOC_DEPS_CFLAGS@
 GTKDOC_DEPS_LIBS = @GTKDOC_DEPS_LIBS@
 GTKDOC_MKPDF = @GTKDOC_MKPDF@
 GTKDOC_REBASE = @GTKDOC_REBASE@
+HAVE_CXX11 = @HAVE_CXX11@
 HB_LIBTOOL_VERSION_INFO = @HB_LIBTOOL_VERSION_INFO@
 HB_VERSION = @HB_VERSION@
 HB_VERSION_MAJOR = @HB_VERSION_MAJOR@
index 67d66e1..9d4084b 100644 (file)
@@ -42,6 +42,7 @@ TEST_PROGS = \
        test-shape \
        test-subset \
        test-subset-cmap \
+       test-subset-drop-tables \
        test-subset-glyf \
        test-subset-hdmx \
        test-subset-hmtx \
@@ -52,10 +53,12 @@ TEST_PROGS = \
        test-subset-cff2 \
        test-unicode \
        test-version \
+       test-subset-nameids \
        $(NULL)
 
 test_subset_LDADD = $(LDADD) $(top_builddir)/src/libharfbuzz-subset.la
 test_subset_cmap_LDADD = $(LDADD) $(top_builddir)/src/libharfbuzz-subset.la
+test_subset_drop_tables_LDADD = $(LDADD) $(top_builddir)/src/libharfbuzz-subset.la
 test_subset_glyf_LDADD = $(LDADD) $(top_builddir)/src/libharfbuzz-subset.la
 test_subset_hdmx_LDADD = $(LDADD) $(top_builddir)/src/libharfbuzz-subset.la
 test_subset_hmtx_LDADD = $(LDADD) $(top_builddir)/src/libharfbuzz-subset.la
@@ -64,6 +67,7 @@ test_subset_post_LDADD = $(LDADD) $(top_builddir)/src/libharfbuzz-subset.la
 test_subset_vmtx_LDADD = $(LDADD) $(top_builddir)/src/libharfbuzz-subset.la
 test_subset_cff1_LDADD = $(LDADD) $(top_builddir)/src/libharfbuzz-subset.la
 test_subset_cff2_LDADD = $(LDADD) $(top_builddir)/src/libharfbuzz-subset.la
+test_subset_nameids_LDADD = $(LDADD) $(top_builddir)/src/libharfbuzz-subset.la
 
 test_unicode_CPPFLAGS = \
        $(AM_CPPFLAGS) \
@@ -80,8 +84,11 @@ TEST_PROGS += \
        test-ot-color \
        test-ot-ligature-carets \
        test-ot-name \
+       test-ot-meta \
+       test-ot-metrics \
        test-ot-tag \
        test-ot-extents-cff \
+       test-ot-metrics-tt-var \
        $(NULL)
 
 
index 5f6f922..9a3158a 100644 (file)
@@ -113,6 +113,7 @@ subdir = test/api
 ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
 am__aclocal_m4_deps = $(top_srcdir)/m4/ax_check_link_flag.m4 \
        $(top_srcdir)/m4/ax_code_coverage.m4 \
+       $(top_srcdir)/m4/ax_cxx_compile_stdcxx.m4 \
        $(top_srcdir)/m4/ax_pthread.m4 $(top_srcdir)/m4/gtk-doc.m4 \
        $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \
        $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \
@@ -138,6 +139,7 @@ am__EXEEXT_1 =
 @HAVE_GLIB_TRUE@       test-ot-face$(EXEEXT) test-set$(EXEEXT) \
 @HAVE_GLIB_TRUE@       test-shape$(EXEEXT) test-subset$(EXEEXT) \
 @HAVE_GLIB_TRUE@       test-subset-cmap$(EXEEXT) \
+@HAVE_GLIB_TRUE@       test-subset-drop-tables$(EXEEXT) \
 @HAVE_GLIB_TRUE@       test-subset-glyf$(EXEEXT) \
 @HAVE_GLIB_TRUE@       test-subset-hdmx$(EXEEXT) \
 @HAVE_GLIB_TRUE@       test-subset-hmtx$(EXEEXT) \
@@ -147,13 +149,16 @@ am__EXEEXT_1 =
 @HAVE_GLIB_TRUE@       test-subset-cff1$(EXEEXT) \
 @HAVE_GLIB_TRUE@       test-subset-cff2$(EXEEXT) \
 @HAVE_GLIB_TRUE@       test-unicode$(EXEEXT) test-version$(EXEEXT) \
-@HAVE_GLIB_TRUE@       $(am__EXEEXT_1) test-ot-color$(EXEEXT) \
+@HAVE_GLIB_TRUE@       test-subset-nameids$(EXEEXT) $(am__EXEEXT_1) \
+@HAVE_GLIB_TRUE@       test-ot-color$(EXEEXT) \
 @HAVE_GLIB_TRUE@       test-ot-ligature-carets$(EXEEXT) \
-@HAVE_GLIB_TRUE@       test-ot-name$(EXEEXT) test-ot-tag$(EXEEXT) \
-@HAVE_GLIB_TRUE@       test-ot-extents-cff$(EXEEXT) $(am__EXEEXT_1) \
-@HAVE_GLIB_TRUE@       $(am__EXEEXT_2) $(am__EXEEXT_3) \
-@HAVE_GLIB_TRUE@       test-c$(EXEEXT) test-cplusplus$(EXEEXT) \
-@HAVE_GLIB_TRUE@       $(am__EXEEXT_1)
+@HAVE_GLIB_TRUE@       test-ot-name$(EXEEXT) test-ot-meta$(EXEEXT) \
+@HAVE_GLIB_TRUE@       test-ot-metrics$(EXEEXT) test-ot-tag$(EXEEXT) \
+@HAVE_GLIB_TRUE@       test-ot-extents-cff$(EXEEXT) \
+@HAVE_GLIB_TRUE@       test-ot-metrics-tt-var$(EXEEXT) \
+@HAVE_GLIB_TRUE@       $(am__EXEEXT_1) $(am__EXEEXT_2) \
+@HAVE_GLIB_TRUE@       $(am__EXEEXT_3) test-c$(EXEEXT) \
+@HAVE_GLIB_TRUE@       test-cplusplus$(EXEEXT) $(am__EXEEXT_1)
 PROGRAMS = $(noinst_PROGRAMS)
 test_aat_layout_SOURCES = test-aat-layout.c
 test_aat_layout_OBJECTS = test-aat-layout.$(OBJEXT)
@@ -266,6 +271,24 @@ test_ot_math_OBJECTS = test_ot_math-test-ot-math.$(OBJEXT)
 @HAVE_FREETYPE_TRUE@@HAVE_GLIB_TRUE@test_ot_math_DEPENDENCIES =  \
 @HAVE_FREETYPE_TRUE@@HAVE_GLIB_TRUE@   $(am__DEPENDENCIES_2) \
 @HAVE_FREETYPE_TRUE@@HAVE_GLIB_TRUE@   $(am__DEPENDENCIES_1)
+test_ot_meta_SOURCES = test-ot-meta.c
+test_ot_meta_OBJECTS = test-ot-meta.$(OBJEXT)
+test_ot_meta_LDADD = $(LDADD)
+@HAVE_GLIB_TRUE@test_ot_meta_DEPENDENCIES =  \
+@HAVE_GLIB_TRUE@       $(top_builddir)/src/libharfbuzz.la \
+@HAVE_GLIB_TRUE@       $(am__DEPENDENCIES_1)
+test_ot_metrics_SOURCES = test-ot-metrics.c
+test_ot_metrics_OBJECTS = test-ot-metrics.$(OBJEXT)
+test_ot_metrics_LDADD = $(LDADD)
+@HAVE_GLIB_TRUE@test_ot_metrics_DEPENDENCIES =  \
+@HAVE_GLIB_TRUE@       $(top_builddir)/src/libharfbuzz.la \
+@HAVE_GLIB_TRUE@       $(am__DEPENDENCIES_1)
+test_ot_metrics_tt_var_SOURCES = test-ot-metrics-tt-var.c
+test_ot_metrics_tt_var_OBJECTS = test-ot-metrics-tt-var.$(OBJEXT)
+test_ot_metrics_tt_var_LDADD = $(LDADD)
+@HAVE_GLIB_TRUE@test_ot_metrics_tt_var_DEPENDENCIES =  \
+@HAVE_GLIB_TRUE@       $(top_builddir)/src/libharfbuzz.la \
+@HAVE_GLIB_TRUE@       $(am__DEPENDENCIES_1)
 test_ot_name_SOURCES = test-ot-name.c
 test_ot_name_OBJECTS = test-ot-name.$(OBJEXT)
 test_ot_name_LDADD = $(LDADD)
@@ -306,6 +329,11 @@ test_subset_cmap_SOURCES = test-subset-cmap.c
 test_subset_cmap_OBJECTS = test-subset-cmap.$(OBJEXT)
 @HAVE_GLIB_TRUE@test_subset_cmap_DEPENDENCIES = $(am__DEPENDENCIES_2) \
 @HAVE_GLIB_TRUE@       $(top_builddir)/src/libharfbuzz-subset.la
+test_subset_drop_tables_SOURCES = test-subset-drop-tables.c
+test_subset_drop_tables_OBJECTS = test-subset-drop-tables.$(OBJEXT)
+@HAVE_GLIB_TRUE@test_subset_drop_tables_DEPENDENCIES =  \
+@HAVE_GLIB_TRUE@       $(am__DEPENDENCIES_2) \
+@HAVE_GLIB_TRUE@       $(top_builddir)/src/libharfbuzz-subset.la
 test_subset_glyf_SOURCES = test-subset-glyf.c
 test_subset_glyf_OBJECTS = test-subset-glyf.$(OBJEXT)
 @HAVE_GLIB_TRUE@test_subset_glyf_DEPENDENCIES = $(am__DEPENDENCIES_2) \
@@ -318,6 +346,11 @@ test_subset_hmtx_SOURCES = test-subset-hmtx.c
 test_subset_hmtx_OBJECTS = test-subset-hmtx.$(OBJEXT)
 @HAVE_GLIB_TRUE@test_subset_hmtx_DEPENDENCIES = $(am__DEPENDENCIES_2) \
 @HAVE_GLIB_TRUE@       $(top_builddir)/src/libharfbuzz-subset.la
+test_subset_nameids_SOURCES = test-subset-nameids.c
+test_subset_nameids_OBJECTS = test-subset-nameids.$(OBJEXT)
+@HAVE_GLIB_TRUE@test_subset_nameids_DEPENDENCIES =  \
+@HAVE_GLIB_TRUE@       $(am__DEPENDENCIES_2) \
+@HAVE_GLIB_TRUE@       $(top_builddir)/src/libharfbuzz-subset.la
 test_subset_os2_SOURCES = test-subset-os2.c
 test_subset_os2_OBJECTS = test-subset-os2.$(OBJEXT)
 @HAVE_GLIB_TRUE@test_subset_os2_DEPENDENCIES = $(am__DEPENDENCIES_2) \
@@ -366,15 +399,19 @@ am__depfiles_remade = ./$(DEPDIR)/test-aat-layout.Po \
        ./$(DEPDIR)/test-ot-color.Po \
        ./$(DEPDIR)/test-ot-extents-cff.Po ./$(DEPDIR)/test-ot-face.Po \
        ./$(DEPDIR)/test-ot-ligature-carets.Po \
-       ./$(DEPDIR)/test-ot-name.Po ./$(DEPDIR)/test-ot-tag.Po \
-       ./$(DEPDIR)/test-set.Po ./$(DEPDIR)/test-shape.Po \
-       ./$(DEPDIR)/test-subset-cff1.Po \
+       ./$(DEPDIR)/test-ot-meta.Po \
+       ./$(DEPDIR)/test-ot-metrics-tt-var.Po \
+       ./$(DEPDIR)/test-ot-metrics.Po ./$(DEPDIR)/test-ot-name.Po \
+       ./$(DEPDIR)/test-ot-tag.Po ./$(DEPDIR)/test-set.Po \
+       ./$(DEPDIR)/test-shape.Po ./$(DEPDIR)/test-subset-cff1.Po \
        ./$(DEPDIR)/test-subset-cff2.Po \
        ./$(DEPDIR)/test-subset-cmap.Po \
+       ./$(DEPDIR)/test-subset-drop-tables.Po \
        ./$(DEPDIR)/test-subset-glyf.Po \
        ./$(DEPDIR)/test-subset-hdmx.Po \
-       ./$(DEPDIR)/test-subset-hmtx.Po ./$(DEPDIR)/test-subset-os2.Po \
-       ./$(DEPDIR)/test-subset-post.Po \
+       ./$(DEPDIR)/test-subset-hmtx.Po \
+       ./$(DEPDIR)/test-subset-nameids.Po \
+       ./$(DEPDIR)/test-subset-os2.Po ./$(DEPDIR)/test-subset-post.Po \
        ./$(DEPDIR)/test-subset-vmtx.Po ./$(DEPDIR)/test-subset.Po \
        ./$(DEPDIR)/test-version.Po ./$(DEPDIR)/test_c-test-c.Po \
        ./$(DEPDIR)/test_cplusplus-test-cplusplus.Po \
@@ -420,23 +457,27 @@ SOURCES = test-aat-layout.c test-baseline.c test-blob.c test-buffer.c \
        $(test_cplusplus_SOURCES) test-font.c test-map.c \
        test-multithread.c test-object.c test-ot-color.c \
        test-ot-extents-cff.c test-ot-face.c test-ot-ligature-carets.c \
-       test-ot-math.c test-ot-name.c test-ot-tag.c test-set.c \
-       test-shape.c test-subset.c test-subset-cff1.c \
-       test-subset-cff2.c test-subset-cmap.c test-subset-glyf.c \
-       test-subset-hdmx.c test-subset-hmtx.c test-subset-os2.c \
-       test-subset-post.c test-subset-vmtx.c test-unicode.c \
-       test-version.c
+       test-ot-math.c test-ot-meta.c test-ot-metrics.c \
+       test-ot-metrics-tt-var.c test-ot-name.c test-ot-tag.c \
+       test-set.c test-shape.c test-subset.c test-subset-cff1.c \
+       test-subset-cff2.c test-subset-cmap.c \
+       test-subset-drop-tables.c test-subset-glyf.c \
+       test-subset-hdmx.c test-subset-hmtx.c test-subset-nameids.c \
+       test-subset-os2.c test-subset-post.c test-subset-vmtx.c \
+       test-unicode.c test-version.c
 DIST_SOURCES = test-aat-layout.c test-baseline.c test-blob.c \
        test-buffer.c test-c.c test-collect-unicodes.c test-common.c \
        $(am__test_cplusplus_SOURCES_DIST) test-font.c test-map.c \
        test-multithread.c test-object.c test-ot-color.c \
        test-ot-extents-cff.c test-ot-face.c test-ot-ligature-carets.c \
-       test-ot-math.c test-ot-name.c test-ot-tag.c test-set.c \
-       test-shape.c test-subset.c test-subset-cff1.c \
-       test-subset-cff2.c test-subset-cmap.c test-subset-glyf.c \
-       test-subset-hdmx.c test-subset-hmtx.c test-subset-os2.c \
-       test-subset-post.c test-subset-vmtx.c test-unicode.c \
-       test-version.c
+       test-ot-math.c test-ot-meta.c test-ot-metrics.c \
+       test-ot-metrics-tt-var.c test-ot-name.c test-ot-tag.c \
+       test-set.c test-shape.c test-subset.c test-subset-cff1.c \
+       test-subset-cff2.c test-subset-cmap.c \
+       test-subset-drop-tables.c test-subset-glyf.c \
+       test-subset-hdmx.c test-subset-hmtx.c test-subset-nameids.c \
+       test-subset-os2.c test-subset-post.c test-subset-vmtx.c \
+       test-unicode.c test-version.c
 am__can_run_installinfo = \
   case $$AM_UPDATE_INFO_DIR in \
     n|no|NO) false;; \
@@ -717,6 +758,8 @@ FREETYPE_CFLAGS = @FREETYPE_CFLAGS@
 FREETYPE_DEPS = @FREETYPE_DEPS@
 FREETYPE_LIBS = @FREETYPE_LIBS@
 GCOV = @GCOV@
+GDI_CFLAGS = @GDI_CFLAGS@
+GDI_LIBS = @GDI_LIBS@
 GENHTML = @GENHTML@
 GIT = @GIT@
 GLIB_CFLAGS = @GLIB_CFLAGS@
@@ -735,6 +778,7 @@ GTKDOC_DEPS_CFLAGS = @GTKDOC_DEPS_CFLAGS@
 GTKDOC_DEPS_LIBS = @GTKDOC_DEPS_LIBS@
 GTKDOC_MKPDF = @GTKDOC_MKPDF@
 GTKDOC_REBASE = @GTKDOC_REBASE@
+HAVE_CXX11 = @HAVE_CXX11@
 HB_LIBTOOL_VERSION_INFO = @HB_LIBTOOL_VERSION_INFO@
 HB_VERSION = @HB_VERSION@
 HB_VERSION_MAJOR = @HB_VERSION_MAJOR@
@@ -868,17 +912,20 @@ LINK = $(CXXLINK)
 @HAVE_GLIB_TRUE@       test-buffer test-collect-unicodes test-common \
 @HAVE_GLIB_TRUE@       test-font test-map test-object test-ot-face \
 @HAVE_GLIB_TRUE@       test-set test-shape test-subset \
-@HAVE_GLIB_TRUE@       test-subset-cmap test-subset-glyf \
-@HAVE_GLIB_TRUE@       test-subset-hdmx test-subset-hmtx \
-@HAVE_GLIB_TRUE@       test-subset-os2 test-subset-post \
-@HAVE_GLIB_TRUE@       test-subset-vmtx test-subset-cff1 \
-@HAVE_GLIB_TRUE@       test-subset-cff2 test-unicode test-version \
-@HAVE_GLIB_TRUE@       $(NULL) test-ot-color test-ot-ligature-carets \
-@HAVE_GLIB_TRUE@       test-ot-name test-ot-tag test-ot-extents-cff \
-@HAVE_GLIB_TRUE@       $(NULL) $(am__append_4) $(am__append_5) test-c \
-@HAVE_GLIB_TRUE@       test-cplusplus $(NULL)
+@HAVE_GLIB_TRUE@       test-subset-cmap test-subset-drop-tables \
+@HAVE_GLIB_TRUE@       test-subset-glyf test-subset-hdmx \
+@HAVE_GLIB_TRUE@       test-subset-hmtx test-subset-os2 \
+@HAVE_GLIB_TRUE@       test-subset-post test-subset-vmtx \
+@HAVE_GLIB_TRUE@       test-subset-cff1 test-subset-cff2 test-unicode \
+@HAVE_GLIB_TRUE@       test-version test-subset-nameids $(NULL) \
+@HAVE_GLIB_TRUE@       test-ot-color test-ot-ligature-carets \
+@HAVE_GLIB_TRUE@       test-ot-name test-ot-meta test-ot-metrics \
+@HAVE_GLIB_TRUE@       test-ot-tag test-ot-extents-cff \
+@HAVE_GLIB_TRUE@       test-ot-metrics-tt-var $(NULL) $(am__append_4) \
+@HAVE_GLIB_TRUE@       $(am__append_5) test-c test-cplusplus $(NULL)
 @HAVE_GLIB_TRUE@test_subset_LDADD = $(LDADD) $(top_builddir)/src/libharfbuzz-subset.la
 @HAVE_GLIB_TRUE@test_subset_cmap_LDADD = $(LDADD) $(top_builddir)/src/libharfbuzz-subset.la
+@HAVE_GLIB_TRUE@test_subset_drop_tables_LDADD = $(LDADD) $(top_builddir)/src/libharfbuzz-subset.la
 @HAVE_GLIB_TRUE@test_subset_glyf_LDADD = $(LDADD) $(top_builddir)/src/libharfbuzz-subset.la
 @HAVE_GLIB_TRUE@test_subset_hdmx_LDADD = $(LDADD) $(top_builddir)/src/libharfbuzz-subset.la
 @HAVE_GLIB_TRUE@test_subset_hmtx_LDADD = $(LDADD) $(top_builddir)/src/libharfbuzz-subset.la
@@ -887,6 +934,7 @@ LINK = $(CXXLINK)
 @HAVE_GLIB_TRUE@test_subset_vmtx_LDADD = $(LDADD) $(top_builddir)/src/libharfbuzz-subset.la
 @HAVE_GLIB_TRUE@test_subset_cff1_LDADD = $(LDADD) $(top_builddir)/src/libharfbuzz-subset.la
 @HAVE_GLIB_TRUE@test_subset_cff2_LDADD = $(LDADD) $(top_builddir)/src/libharfbuzz-subset.la
+@HAVE_GLIB_TRUE@test_subset_nameids_LDADD = $(LDADD) $(top_builddir)/src/libharfbuzz-subset.la
 @HAVE_GLIB_TRUE@test_unicode_CPPFLAGS = $(AM_CPPFLAGS) $(GLIB_CFLAGS) \
 @HAVE_GLIB_TRUE@       $(NULL) $(am__append_2)
 @HAVE_GLIB_TRUE@test_unicode_LDADD = $(LDADD) $(am__append_3)
@@ -1048,6 +1096,18 @@ test-ot-math$(EXEEXT): $(test_ot_math_OBJECTS) $(test_ot_math_DEPENDENCIES) $(EX
        @rm -f test-ot-math$(EXEEXT)
        $(AM_V_CCLD)$(LINK) $(test_ot_math_OBJECTS) $(test_ot_math_LDADD) $(LIBS)
 
+test-ot-meta$(EXEEXT): $(test_ot_meta_OBJECTS) $(test_ot_meta_DEPENDENCIES) $(EXTRA_test_ot_meta_DEPENDENCIES) 
+       @rm -f test-ot-meta$(EXEEXT)
+       $(AM_V_CCLD)$(LINK) $(test_ot_meta_OBJECTS) $(test_ot_meta_LDADD) $(LIBS)
+
+test-ot-metrics$(EXEEXT): $(test_ot_metrics_OBJECTS) $(test_ot_metrics_DEPENDENCIES) $(EXTRA_test_ot_metrics_DEPENDENCIES) 
+       @rm -f test-ot-metrics$(EXEEXT)
+       $(AM_V_CCLD)$(LINK) $(test_ot_metrics_OBJECTS) $(test_ot_metrics_LDADD) $(LIBS)
+
+test-ot-metrics-tt-var$(EXEEXT): $(test_ot_metrics_tt_var_OBJECTS) $(test_ot_metrics_tt_var_DEPENDENCIES) $(EXTRA_test_ot_metrics_tt_var_DEPENDENCIES) 
+       @rm -f test-ot-metrics-tt-var$(EXEEXT)
+       $(AM_V_CCLD)$(LINK) $(test_ot_metrics_tt_var_OBJECTS) $(test_ot_metrics_tt_var_LDADD) $(LIBS)
+
 test-ot-name$(EXEEXT): $(test_ot_name_OBJECTS) $(test_ot_name_DEPENDENCIES) $(EXTRA_test_ot_name_DEPENDENCIES) 
        @rm -f test-ot-name$(EXEEXT)
        $(AM_V_CCLD)$(LINK) $(test_ot_name_OBJECTS) $(test_ot_name_LDADD) $(LIBS)
@@ -1080,6 +1140,10 @@ test-subset-cmap$(EXEEXT): $(test_subset_cmap_OBJECTS) $(test_subset_cmap_DEPEND
        @rm -f test-subset-cmap$(EXEEXT)
        $(AM_V_CCLD)$(LINK) $(test_subset_cmap_OBJECTS) $(test_subset_cmap_LDADD) $(LIBS)
 
+test-subset-drop-tables$(EXEEXT): $(test_subset_drop_tables_OBJECTS) $(test_subset_drop_tables_DEPENDENCIES) $(EXTRA_test_subset_drop_tables_DEPENDENCIES) 
+       @rm -f test-subset-drop-tables$(EXEEXT)
+       $(AM_V_CCLD)$(LINK) $(test_subset_drop_tables_OBJECTS) $(test_subset_drop_tables_LDADD) $(LIBS)
+
 test-subset-glyf$(EXEEXT): $(test_subset_glyf_OBJECTS) $(test_subset_glyf_DEPENDENCIES) $(EXTRA_test_subset_glyf_DEPENDENCIES) 
        @rm -f test-subset-glyf$(EXEEXT)
        $(AM_V_CCLD)$(LINK) $(test_subset_glyf_OBJECTS) $(test_subset_glyf_LDADD) $(LIBS)
@@ -1092,6 +1156,10 @@ test-subset-hmtx$(EXEEXT): $(test_subset_hmtx_OBJECTS) $(test_subset_hmtx_DEPEND
        @rm -f test-subset-hmtx$(EXEEXT)
        $(AM_V_CCLD)$(LINK) $(test_subset_hmtx_OBJECTS) $(test_subset_hmtx_LDADD) $(LIBS)
 
+test-subset-nameids$(EXEEXT): $(test_subset_nameids_OBJECTS) $(test_subset_nameids_DEPENDENCIES) $(EXTRA_test_subset_nameids_DEPENDENCIES) 
+       @rm -f test-subset-nameids$(EXEEXT)
+       $(AM_V_CCLD)$(LINK) $(test_subset_nameids_OBJECTS) $(test_subset_nameids_LDADD) $(LIBS)
+
 test-subset-os2$(EXEEXT): $(test_subset_os2_OBJECTS) $(test_subset_os2_DEPENDENCIES) $(EXTRA_test_subset_os2_DEPENDENCIES) 
        @rm -f test-subset-os2$(EXEEXT)
        $(AM_V_CCLD)$(LINK) $(test_subset_os2_OBJECTS) $(test_subset_os2_LDADD) $(LIBS)
@@ -1131,6 +1199,9 @@ distclean-compile:
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test-ot-extents-cff.Po@am__quote@ # am--include-marker
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test-ot-face.Po@am__quote@ # am--include-marker
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test-ot-ligature-carets.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test-ot-meta.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test-ot-metrics-tt-var.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test-ot-metrics.Po@am__quote@ # am--include-marker
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test-ot-name.Po@am__quote@ # am--include-marker
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test-ot-tag.Po@am__quote@ # am--include-marker
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test-set.Po@am__quote@ # am--include-marker
@@ -1138,9 +1209,11 @@ distclean-compile:
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test-subset-cff1.Po@am__quote@ # am--include-marker
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test-subset-cff2.Po@am__quote@ # am--include-marker
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test-subset-cmap.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test-subset-drop-tables.Po@am__quote@ # am--include-marker
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test-subset-glyf.Po@am__quote@ # am--include-marker
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test-subset-hdmx.Po@am__quote@ # am--include-marker
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test-subset-hmtx.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test-subset-nameids.Po@am__quote@ # am--include-marker
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test-subset-os2.Po@am__quote@ # am--include-marker
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test-subset-post.Po@am__quote@ # am--include-marker
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test-subset-vmtx.Po@am__quote@ # am--include-marker
@@ -1567,6 +1640,13 @@ test-subset-cmap.log: test-subset-cmap$(EXEEXT)
        --log-file $$b.log --trs-file $$b.trs \
        $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \
        "$$tst" $(AM_TESTS_FD_REDIRECT)
+test-subset-drop-tables.log: test-subset-drop-tables$(EXEEXT)
+       @p='test-subset-drop-tables$(EXEEXT)'; \
+       b='test-subset-drop-tables'; \
+       $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \
+       --log-file $$b.log --trs-file $$b.trs \
+       $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \
+       "$$tst" $(AM_TESTS_FD_REDIRECT)
 test-subset-glyf.log: test-subset-glyf$(EXEEXT)
        @p='test-subset-glyf$(EXEEXT)'; \
        b='test-subset-glyf'; \
@@ -1637,6 +1717,13 @@ test-version.log: test-version$(EXEEXT)
        --log-file $$b.log --trs-file $$b.trs \
        $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \
        "$$tst" $(AM_TESTS_FD_REDIRECT)
+test-subset-nameids.log: test-subset-nameids$(EXEEXT)
+       @p='test-subset-nameids$(EXEEXT)'; \
+       b='test-subset-nameids'; \
+       $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \
+       --log-file $$b.log --trs-file $$b.trs \
+       $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \
+       "$$tst" $(AM_TESTS_FD_REDIRECT)
 test-ot-color.log: test-ot-color$(EXEEXT)
        @p='test-ot-color$(EXEEXT)'; \
        b='test-ot-color'; \
@@ -1658,6 +1745,20 @@ test-ot-name.log: test-ot-name$(EXEEXT)
        --log-file $$b.log --trs-file $$b.trs \
        $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \
        "$$tst" $(AM_TESTS_FD_REDIRECT)
+test-ot-meta.log: test-ot-meta$(EXEEXT)
+       @p='test-ot-meta$(EXEEXT)'; \
+       b='test-ot-meta'; \
+       $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \
+       --log-file $$b.log --trs-file $$b.trs \
+       $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \
+       "$$tst" $(AM_TESTS_FD_REDIRECT)
+test-ot-metrics.log: test-ot-metrics$(EXEEXT)
+       @p='test-ot-metrics$(EXEEXT)'; \
+       b='test-ot-metrics'; \
+       $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \
+       --log-file $$b.log --trs-file $$b.trs \
+       $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \
+       "$$tst" $(AM_TESTS_FD_REDIRECT)
 test-ot-tag.log: test-ot-tag$(EXEEXT)
        @p='test-ot-tag$(EXEEXT)'; \
        b='test-ot-tag'; \
@@ -1672,6 +1773,13 @@ test-ot-extents-cff.log: test-ot-extents-cff$(EXEEXT)
        --log-file $$b.log --trs-file $$b.trs \
        $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \
        "$$tst" $(AM_TESTS_FD_REDIRECT)
+test-ot-metrics-tt-var.log: test-ot-metrics-tt-var$(EXEEXT)
+       @p='test-ot-metrics-tt-var$(EXEEXT)'; \
+       b='test-ot-metrics-tt-var'; \
+       $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \
+       --log-file $$b.log --trs-file $$b.trs \
+       $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \
+       "$$tst" $(AM_TESTS_FD_REDIRECT)
 test-multithread.log: test-multithread$(EXEEXT)
        @p='test-multithread$(EXEEXT)'; \
        b='test-multithread'; \
@@ -1809,6 +1917,9 @@ distclean: distclean-am
        -rm -f ./$(DEPDIR)/test-ot-extents-cff.Po
        -rm -f ./$(DEPDIR)/test-ot-face.Po
        -rm -f ./$(DEPDIR)/test-ot-ligature-carets.Po
+       -rm -f ./$(DEPDIR)/test-ot-meta.Po
+       -rm -f ./$(DEPDIR)/test-ot-metrics-tt-var.Po
+       -rm -f ./$(DEPDIR)/test-ot-metrics.Po
        -rm -f ./$(DEPDIR)/test-ot-name.Po
        -rm -f ./$(DEPDIR)/test-ot-tag.Po
        -rm -f ./$(DEPDIR)/test-set.Po
@@ -1816,9 +1927,11 @@ distclean: distclean-am
        -rm -f ./$(DEPDIR)/test-subset-cff1.Po
        -rm -f ./$(DEPDIR)/test-subset-cff2.Po
        -rm -f ./$(DEPDIR)/test-subset-cmap.Po
+       -rm -f ./$(DEPDIR)/test-subset-drop-tables.Po
        -rm -f ./$(DEPDIR)/test-subset-glyf.Po
        -rm -f ./$(DEPDIR)/test-subset-hdmx.Po
        -rm -f ./$(DEPDIR)/test-subset-hmtx.Po
+       -rm -f ./$(DEPDIR)/test-subset-nameids.Po
        -rm -f ./$(DEPDIR)/test-subset-os2.Po
        -rm -f ./$(DEPDIR)/test-subset-post.Po
        -rm -f ./$(DEPDIR)/test-subset-vmtx.Po
@@ -1887,6 +2000,9 @@ maintainer-clean: maintainer-clean-am
        -rm -f ./$(DEPDIR)/test-ot-extents-cff.Po
        -rm -f ./$(DEPDIR)/test-ot-face.Po
        -rm -f ./$(DEPDIR)/test-ot-ligature-carets.Po
+       -rm -f ./$(DEPDIR)/test-ot-meta.Po
+       -rm -f ./$(DEPDIR)/test-ot-metrics-tt-var.Po
+       -rm -f ./$(DEPDIR)/test-ot-metrics.Po
        -rm -f ./$(DEPDIR)/test-ot-name.Po
        -rm -f ./$(DEPDIR)/test-ot-tag.Po
        -rm -f ./$(DEPDIR)/test-set.Po
@@ -1894,9 +2010,11 @@ maintainer-clean: maintainer-clean-am
        -rm -f ./$(DEPDIR)/test-subset-cff1.Po
        -rm -f ./$(DEPDIR)/test-subset-cff2.Po
        -rm -f ./$(DEPDIR)/test-subset-cmap.Po
+       -rm -f ./$(DEPDIR)/test-subset-drop-tables.Po
        -rm -f ./$(DEPDIR)/test-subset-glyf.Po
        -rm -f ./$(DEPDIR)/test-subset-hdmx.Po
        -rm -f ./$(DEPDIR)/test-subset-hmtx.Po
+       -rm -f ./$(DEPDIR)/test-subset-nameids.Po
        -rm -f ./$(DEPDIR)/test-subset-os2.Po
        -rm -f ./$(DEPDIR)/test-subset-post.Po
        -rm -f ./$(DEPDIR)/test-subset-vmtx.Po
index 3a71f53..7860f2f 100644 (file)
Binary files a/test/api/fonts/Roboto-Regular.D7,D8,D9,DA,DE.ttf and b/test/api/fonts/Roboto-Regular.D7,D8,D9,DA,DE.ttf differ
diff --git a/test/api/fonts/Roboto-Regular.a.retaingids.ttf b/test/api/fonts/Roboto-Regular.a.retaingids.ttf
new file mode 100644 (file)
index 0000000..183b148
Binary files /dev/null and b/test/api/fonts/Roboto-Regular.a.retaingids.ttf differ
index 9d791f7..705ec69 100644 (file)
Binary files a/test/api/fonts/Roboto-Regular.abc.ttf and b/test/api/fonts/Roboto-Regular.abc.ttf differ
index 6ac1b33..5a5e68e 100644 (file)
Binary files a/test/api/fonts/Roboto-Regular.ac.ttf and b/test/api/fonts/Roboto-Regular.ac.ttf differ
index 906bdbe..fa2a0e4 100644 (file)
Binary files a/test/api/fonts/SourceHanSans-Regular.41,4C2E.retaingids.otf and b/test/api/fonts/SourceHanSans-Regular.41,4C2E.retaingids.otf differ
diff --git a/test/api/fonts/SourceSansVariable-Roman-nohvar-41,C1.ttf b/test/api/fonts/SourceSansVariable-Roman-nohvar-41,C1.ttf
new file mode 100644 (file)
index 0000000..dc237e7
Binary files /dev/null and b/test/api/fonts/SourceSansVariable-Roman-nohvar-41,C1.ttf differ
diff --git a/test/api/fonts/SourceSansVariable-Roman.anchor.ttf b/test/api/fonts/SourceSansVariable-Roman.anchor.ttf
new file mode 100644 (file)
index 0000000..4e8dc9d
Binary files /dev/null and b/test/api/fonts/SourceSansVariable-Roman.anchor.ttf differ
diff --git a/test/api/fonts/SourceSansVariable-Roman.modcomp.ttf b/test/api/fonts/SourceSansVariable-Roman.modcomp.ttf
new file mode 100644 (file)
index 0000000..c75041f
Binary files /dev/null and b/test/api/fonts/SourceSansVariable-Roman.modcomp.ttf differ
diff --git a/test/api/fonts/SourceSerifVariable-Roman-VVAR.abc.ttf b/test/api/fonts/SourceSerifVariable-Roman-VVAR.abc.ttf
new file mode 100644 (file)
index 0000000..7d94abc
Binary files /dev/null and b/test/api/fonts/SourceSerifVariable-Roman-VVAR.abc.ttf differ
diff --git a/test/api/fonts/TestCFF2VF.otf b/test/api/fonts/TestCFF2VF.otf
new file mode 100644 (file)
index 0000000..a9e48e3
Binary files /dev/null and b/test/api/fonts/TestCFF2VF.otf differ
diff --git a/test/api/fonts/cmunrm.otf b/test/api/fonts/cmunrm.otf
new file mode 100644 (file)
index 0000000..b449df0
Binary files /dev/null and b/test/api/fonts/cmunrm.otf differ
diff --git a/test/api/fonts/meta.ttf b/test/api/fonts/meta.ttf
new file mode 100644 (file)
index 0000000..414d7e6
Binary files /dev/null and b/test/api/fonts/meta.ttf differ
diff --git a/test/api/fonts/nameID.dup.expected.ttf b/test/api/fonts/nameID.dup.expected.ttf
new file mode 100644 (file)
index 0000000..e9e7ff5
Binary files /dev/null and b/test/api/fonts/nameID.dup.expected.ttf differ
diff --git a/test/api/fonts/nameID.dup.origin.ttf b/test/api/fonts/nameID.dup.origin.ttf
new file mode 100644 (file)
index 0000000..aad75d4
Binary files /dev/null and b/test/api/fonts/nameID.dup.origin.ttf differ
diff --git a/test/api/fonts/nameID.expected.ttf b/test/api/fonts/nameID.expected.ttf
new file mode 100644 (file)
index 0000000..00aecc0
Binary files /dev/null and b/test/api/fonts/nameID.expected.ttf differ
diff --git a/test/api/fonts/nameID.origin.ttf b/test/api/fonts/nameID.origin.ttf
new file mode 100644 (file)
index 0000000..aec973a
Binary files /dev/null and b/test/api/fonts/nameID.origin.ttf differ
index 3e759a8..99f567a 100644 (file)
@@ -65,9 +65,18 @@ hb_subset_test_create_input_from_glyphs (const hb_set_t *glyphs)
   return input;
 }
 
+static inline hb_subset_input_t *
+hb_subset_test_create_input_from_nameids (const hb_set_t *name_ids)
+{
+  hb_subset_input_t *input = hb_subset_input_create_or_fail ();
+  hb_set_t * input_name_ids  = hb_subset_input_nameid_set (input);
+  hb_set_set (input_name_ids, name_ids);
+  return input;
+}
+
 static inline hb_face_t *
 hb_subset_test_create_subset (hb_face_t *source,
-                              hb_subset_input_t *input)
+                             hb_subset_input_t *input)
 {
   hb_face_t *subset = hb_subset (source, input);
   g_assert (subset);
@@ -78,13 +87,13 @@ hb_subset_test_create_subset (hb_face_t *source,
 
 static inline void
 hb_subset_test_check (hb_face_t *expected,
-                      hb_face_t *actual,
-                      hb_tag_t   table)
+                     hb_face_t *actual,
+                     hb_tag_t   table)
 {
   hb_blob_t *expected_blob, *actual_blob;
-  //fprintf(stderr, "comparing %c%c%c%c ", HB_UNTAG(table));
   expected_blob = hb_face_reference_table (expected, table);
   actual_blob = hb_face_reference_table (actual, table);
+  fprintf(stderr, "comparing %c%c%c%c, expected %d bytes, actual %d bytes\n", HB_UNTAG(table), hb_blob_get_length(expected_blob), hb_blob_get_length (actual_blob));
   hb_test_assert_blobs_equal (expected_blob, actual_blob);
   hb_blob_destroy (expected_blob);
   hb_blob_destroy (actual_blob);
index 872f45c..b866e44 100644 (file)
@@ -173,6 +173,16 @@ static inline void hb_test_assert_blobs_equal (hb_blob_t *expected_blob, hb_blob
   const char *raw_expected = hb_blob_get_data (expected_blob, &expected_length);
   const char *raw_actual = hb_blob_get_data (actual_blob, &actual_length);
   g_assert_cmpint(expected_length, ==, actual_length);
+  if (memcmp (raw_expected, raw_actual, expected_length) != 0)
+  {
+    for (unsigned int i = 0; i < expected_length; i++)
+    {
+      int expected = *(raw_expected + i);
+      int actual = *(raw_actual + i);
+      if (expected != actual) fprintf(stderr, "+%u %02x != %02x\n", i, expected, actual);
+      else fprintf(stderr, "+%u %02x\n", i, expected);
+    }
+  }
   g_assert_cmpint(0, ==, memcmp(raw_expected, raw_actual, expected_length));
 }
 
index 1384556..d9dd8a3 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright © 2018  Google, Inc.
+ * Copyright © 2018  Ebrahim Byagowi
  *
  *  This is part of HarfBuzz, a text shaping library.
  *
index a120e14..982c683 100644 (file)
@@ -34,14 +34,12 @@ test_ot_layout_base (void)
   hb_face_t *face = hb_test_open_font_file ("fonts/base.ttf");
   hb_font_t *font = hb_font_create (face);
 
-#if 0
   hb_position_t position;
-  g_assert (hb_ot_layout_get_baseline (font, HB_OT_LAYOUT_BASELINE_ICFB, HB_DIRECTION_TTB,
+  g_assert (hb_ot_layout_get_baseline (font, HB_OT_LAYOUT_BASELINE_TAG_IDEO_FACE_BOTTOM_OR_LEFT, HB_DIRECTION_TTB,
                                       HB_TAG ('h','a','n','i'),
                                       HB_TAG ('E','N','G',' '),
                                       &position));
   g_assert_cmpint (46, ==, position);
-#endif
 
   hb_font_destroy (font);
   hb_face_destroy (face);
index 64ab3db..228f0f3 100644 (file)
@@ -208,7 +208,7 @@ test_buffer_contents (fixture_t *fixture, gconstpointer user_data)
       if (buffer_type == BUFFER_UTF16)
        cluster++;
       else if (buffer_type == BUFFER_UTF8)
-        cluster += 3;
+       cluster += 3;
     }
     g_assert_cmphex (glyphs[i].codepoint, ==, utf32[1+i]);
     g_assert_cmphex (glyphs[i].cluster,   ==, cluster);
index 50965a9..8a857e1 100644 (file)
@@ -50,6 +50,27 @@ test_collect_unicodes_format4 (void)
 }
 
 static void
+test_collect_unicodes_format12_notdef (void)
+{
+  hb_face_t *face = hb_test_open_font_file ("fonts/cmunrm.otf");
+  hb_set_t *codepoints = hb_set_create();
+  hb_codepoint_t cp;
+
+  hb_face_collect_unicodes (face, codepoints);
+
+  cp = HB_SET_VALUE_INVALID;
+  g_assert (hb_set_next (codepoints, &cp));
+  g_assert_cmpuint (0x20, ==, cp);
+  g_assert (hb_set_next (codepoints, &cp));
+  g_assert_cmpuint (0x21, ==, cp);
+  g_assert (hb_set_next (codepoints, &cp));
+  g_assert_cmpuint (0x22, ==, cp);
+
+  hb_set_destroy (codepoints);
+  hb_face_destroy (face);
+}
+
+static void
 test_collect_unicodes_format12 (void)
 {
   hb_face_t *face = hb_test_open_font_file ("fonts/Roboto-Regular.abc.format12.ttf");
@@ -101,6 +122,7 @@ main (int argc, char **argv)
   hb_test_add (test_collect_unicodes);
   hb_test_add (test_collect_unicodes_format4);
   hb_test_add (test_collect_unicodes_format12);
+  hb_test_add (test_collect_unicodes_format12_notdef);
 
   return hb_test_run();
 }
index 6690194..c6738b4 100644 (file)
@@ -146,9 +146,6 @@ _test_font_nil_funcs (hb_font_t *font)
   glyph = 3;
   g_assert (!hb_font_get_glyph (font, 17, 2, &glyph));
   g_assert_cmpint (glyph, ==, 0);
-
-  x = hb_font_get_glyph_h_kerning (font, 17, 19);
-  g_assert_cmpint (x, ==, 0);
 }
 
 static void
index 093615e..5154621 100644 (file)
@@ -345,7 +345,7 @@ test_object (void)
       if (!obj)
        continue;
       if (obj == o->get_empty ())
-        continue; /* Tested already */
+       continue; /* Tested already */
 
       g_assert (obj == o->reference (obj));
       o->destroy (obj);
index c0cbd77..c2bbad2 100644 (file)
@@ -210,7 +210,7 @@ static void
 test_hb_ot_color_palette_get_colors_v0 (void)
 {
   unsigned int num_colors = hb_ot_color_palette_get_colors (cpal_v0, 0, 0, NULL, NULL);
-  hb_color_t *colors = (hb_color_t*) alloca (num_colors * sizeof (hb_color_t));
+  hb_color_t *colors = (hb_color_t*) malloc (num_colors * sizeof (hb_color_t));
   size_t colors_size = num_colors * sizeof(*colors);
   g_assert_cmpint (num_colors, ==, 2);
 
@@ -252,6 +252,8 @@ test_hb_ot_color_palette_get_colors_v0 (void)
   g_assert_cmpint (num_colors, ==, 0);
   assert_color_rgba (colors, 0, 0x44, 0x44, 0x44, 0x44);  /* untouched */
   assert_color_rgba (colors, 1, 0x44, 0x44, 0x44, 0x44);  /* untouched */
+       
+  free (colors);
 }
 
 
@@ -426,9 +428,9 @@ test_hb_ot_color_png (void)
   g_assert (strncmp (data + 1, "PNG", 3) == 0);
   hb_font_get_glyph_extents (sbix_font, 1, &extents);
   g_assert_cmpint (extents.x_bearing, ==, 0);
-  g_assert_cmpint (extents.y_bearing, ==, 0);
+  g_assert_cmpint (extents.y_bearing, ==, 800);
   g_assert_cmpint (extents.width, ==, 800);
-  g_assert_cmpint (extents.height, ==, 800);
+  g_assert_cmpint (extents.height, ==, -800);
   hb_blob_destroy (blob);
   hb_font_destroy (sbix_font);
 
index 49b8799..7109e30 100644 (file)
@@ -146,8 +146,8 @@ test_extents_cff2 (void)
 
   g_assert_cmpint (extents.x_bearing, ==, 38);
   g_assert_cmpint (extents.y_bearing, ==, 493);
-  g_assert_cmpint (extents.width, ==, 481);
-  g_assert_cmpint (extents.height, ==, -508);
+  g_assert_cmpint (extents.width, ==, 480);
+  g_assert_cmpint (extents.height, ==, -507);
 
   hb_font_destroy (font);
 }
@@ -168,22 +168,53 @@ test_extents_cff2_vsindex (void)
   hb_bool_t result = hb_font_get_glyph_extents (font, 1, &extents);
   g_assert (result);
 
-  g_assert_cmpint (extents.x_bearing, ==, 11);
-  g_assert_cmpint (extents.y_bearing, ==, 656);
-  g_assert_cmpint (extents.width, ==, 653);
-  g_assert_cmpint (extents.height, ==, -656);
+  g_assert_cmpint (extents.x_bearing, ==, 12);
+  g_assert_cmpint (extents.y_bearing, ==, 655);
+  g_assert_cmpint (extents.width, ==, 652);
+  g_assert_cmpint (extents.height, ==, -655);
 
   result = hb_font_get_glyph_extents (font, 2, &extents);
   g_assert (result);
 
-  g_assert_cmpint (extents.x_bearing, ==, 7);
+  g_assert_cmpint (extents.x_bearing, ==, 8);
   g_assert_cmpint (extents.y_bearing, ==, 669);
-  g_assert_cmpint (extents.width, ==, 650);
+  g_assert_cmpint (extents.width, ==, 649);
   g_assert_cmpint (extents.height, ==, -669);
 
   hb_font_destroy (font);
 }
 
+static void
+test_extents_cff2_vsindex_named_instance (void)
+{
+  hb_face_t *face = hb_test_open_font_file ("fonts/AdobeVFPrototype_vsindex.otf");
+  g_assert (face);
+  hb_font_t *font = hb_font_create (face);
+  hb_face_destroy (face);
+  g_assert (font);
+  hb_ot_font_set_funcs (font);
+
+  hb_font_set_var_named_instance (font, 6); // 6 (BlackMediumContrast): 900, 50
+  hb_glyph_extents_t  extents;
+  hb_bool_t result = hb_font_get_glyph_extents (font, 1, &extents);
+  g_assert (result);
+
+  g_assert_cmpint (extents.x_bearing, ==, 13);
+  g_assert_cmpint (extents.y_bearing, ==, 652);
+  g_assert_cmpint (extents.width, ==, 653);
+  g_assert_cmpint (extents.height, ==, -652);
+
+  result = hb_font_get_glyph_extents (font, 2, &extents);
+  g_assert (result);
+
+  g_assert_cmpint (extents.x_bearing, ==, 6);
+  g_assert_cmpint (extents.y_bearing, ==, 675);
+  g_assert_cmpint (extents.width, ==, 647);
+  g_assert_cmpint (extents.height, ==, -675);
+
+  hb_font_destroy (font);
+}
+
 int
 main (int argc, char **argv)
 {
@@ -194,6 +225,7 @@ main (int argc, char **argv)
   hb_test_add (test_extents_cff1_seac);
   hb_test_add (test_extents_cff2);
   hb_test_add (test_extents_cff2_vsindex);
+  hb_test_add (test_extents_cff2_vsindex_named_instance);
 
   return hb_test_run ();
 }
index 9ebcb4e..44a9116 100644 (file)
@@ -74,6 +74,8 @@ test_face (hb_face_t *face,
   hb_ot_color_has_png (face);
   hb_blob_destroy (hb_ot_color_glyph_reference_png (font, cp));
 
+  hb_ot_layout_get_baseline (font, HB_OT_LAYOUT_BASELINE_TAG_HANGING, HB_DIRECTION_RTL, HB_SCRIPT_HANGUL, HB_TAG_NONE, NULL);
+
   hb_ot_layout_has_glyph_classes (face);
   hb_ot_layout_has_substitution (face);
   hb_ot_layout_has_positioning (face);
@@ -88,6 +90,14 @@ test_face (hb_face_t *face,
   hb_ot_math_get_min_connector_overlap (font, HB_DIRECTION_RTL);
   hb_ot_math_get_glyph_assembly (font, cp, HB_DIRECTION_BTT, 0, NULL, NULL, NULL);
 
+  hb_ot_meta_get_entry_tags (face, 0, NULL, NULL);
+  hb_blob_destroy (hb_ot_meta_reference_entry (face, HB_OT_META_TAG_DESIGN_LANGUAGES));
+
+  hb_ot_metrics_get_position (font, HB_OT_METRICS_TAG_HORIZONTAL_ASCENDER, NULL);
+  hb_ot_metrics_get_variation (font, HB_OT_METRICS_TAG_UNDERLINE_OFFSET);
+  hb_ot_metrics_get_x_variation (font, HB_OT_METRICS_TAG_STRIKEOUT_OFFSET);
+  hb_ot_metrics_get_y_variation (font, HB_OT_METRICS_TAG_SUPERSCRIPT_EM_X_OFFSET);
+
   len = sizeof (buf);
   hb_ot_name_list_names (face, NULL);
   hb_ot_name_get_utf8 (face, cp, NULL, &len, buf);
@@ -111,7 +121,7 @@ test_ot_face_empty (void)
 }
 
 static void
-test_ot_var_axis_on_zero_named_instance ()
+test_ot_var_axis_on_zero_named_instance (void)
 {
   hb_face_t *face = hb_test_open_font_file ("fonts/Zycon.ttf");
   g_assert (hb_ot_var_get_axis_count (face));
index 7f50015..73b1a25 100644 (file)
@@ -457,41 +457,41 @@ test_get_glyph_variants (void)
 
   g_assert(hb_font_get_glyph_from_name (hb_font, "arrowleft", -1, &glyph));
   g_assert_cmpint(hb_ot_math_get_glyph_variants (hb_font,
-                                                 glyph,
-                                                 HB_DIRECTION_BTT,
-                                                 0,
-                                                 NULL,
-                                                 NULL), ==, 0);
+                                                glyph,
+                                                HB_DIRECTION_BTT,
+                                                0,
+                                                NULL,
+                                                NULL), ==, 0);
   g_assert_cmpint(hb_ot_math_get_glyph_variants (hb_font,
-                                                 glyph,
-                                                 HB_DIRECTION_RTL,
-                                                 0,
-                                                 NULL,
-                                                 NULL), ==, 3);
+                                                glyph,
+                                                HB_DIRECTION_RTL,
+                                                0,
+                                                NULL,
+                                                NULL), ==, 3);
 
   g_assert(hb_font_get_glyph_from_name (hb_font, "arrowup", -1, &glyph));
   g_assert_cmpint(hb_ot_math_get_glyph_variants (hb_font,
-                                                 glyph,
-                                                 HB_DIRECTION_BTT,
-                                                 0,
-                                                 NULL,
-                                                 NULL), ==, 4);
+                                                glyph,
+                                                HB_DIRECTION_BTT,
+                                                0,
+                                                NULL,
+                                                NULL), ==, 4);
   g_assert_cmpint(hb_ot_math_get_glyph_variants (hb_font,
-                                                 glyph,
-                                                 HB_DIRECTION_RTL,
-                                                 0,
-                                                 NULL,
-                                                 NULL), ==, 0);
+                                                glyph,
+                                                HB_DIRECTION_RTL,
+                                                0,
+                                                NULL,
+                                                NULL), ==, 0);
 
   g_assert(hb_font_get_glyph_from_name (hb_font, "arrowleft", -1, &glyph));
   do {
     count = variantsSize;
     hb_ot_math_get_glyph_variants (hb_font,
-                                   glyph,
-                                   HB_DIRECTION_RTL,
-                                   offset,
-                                   &count,
-                                   variants);
+                                  glyph,
+                                  HB_DIRECTION_RTL,
+                                  offset,
+                                  &count,
+                                  variants);
     offset += count;
   } while (count == variantsSize);
   g_assert_cmpint(offset, ==, 3);
@@ -510,11 +510,11 @@ test_get_glyph_variants (void)
   do {
     count = variantsSize;
     hb_ot_math_get_glyph_variants (hb_font,
-                                   glyph,
-                                   HB_DIRECTION_BTT,
-                                   offset,
-                                   &count,
-                                   variants);
+                                  glyph,
+                                  HB_DIRECTION_BTT,
+                                  offset,
+                                  &count,
+                                  variants);
     offset += count;
   } while (count == variantsSize);
   g_assert_cmpint(offset, ==, 4);
@@ -581,46 +581,46 @@ test_get_glyph_assembly (void)
 
   g_assert(hb_font_get_glyph_from_name (hb_font, "arrowright", -1, &glyph));
   g_assert_cmpint(hb_ot_math_get_glyph_assembly (hb_font,
-                                                 glyph,
-                                                 HB_DIRECTION_BTT,
-                                                 0,
-                                                 NULL,
-                                                 NULL,
-                                                 NULL), ==, 0);
+                                                glyph,
+                                                HB_DIRECTION_BTT,
+                                                0,
+                                                NULL,
+                                                NULL,
+                                                NULL), ==, 0);
   g_assert_cmpint(hb_ot_math_get_glyph_assembly (hb_font,
-                                                 glyph,
-                                                 HB_DIRECTION_RTL,
-                                                 0,
-                                                 NULL,
-                                                 NULL,
-                                                 NULL), ==, 3);
+                                                glyph,
+                                                HB_DIRECTION_RTL,
+                                                0,
+                                                NULL,
+                                                NULL,
+                                                NULL), ==, 3);
 
   g_assert(hb_font_get_glyph_from_name (hb_font, "arrowdown", -1, &glyph));
   g_assert_cmpint(hb_ot_math_get_glyph_assembly (hb_font,
-                                                 glyph,
-                                                 HB_DIRECTION_BTT,
-                                                 0,
-                                                 NULL,
-                                                 NULL,
-                                                 NULL), ==, 5);
+                                                glyph,
+                                                HB_DIRECTION_BTT,
+                                                0,
+                                                NULL,
+                                                NULL,
+                                                NULL), ==, 5);
   g_assert_cmpint(hb_ot_math_get_glyph_assembly (hb_font,
-                                                 glyph,
-                                                 HB_DIRECTION_RTL,
-                                                 0,
-                                                 NULL,
-                                                 NULL,
-                                                 NULL), ==, 0);
+                                                glyph,
+                                                HB_DIRECTION_RTL,
+                                                0,
+                                                NULL,
+                                                NULL,
+                                                NULL), ==, 0);
 
   g_assert(hb_font_get_glyph_from_name (hb_font, "arrowright", -1, &glyph));
   do {
     count = partsSize;
     hb_ot_math_get_glyph_assembly (hb_font,
-                                   glyph,
-                                   HB_DIRECTION_RTL,
-                                   offset,
-                                   &count,
-                                   parts,
-                                   NULL);
+                                  glyph,
+                                  HB_DIRECTION_RTL,
+                                  offset,
+                                  &count,
+                                  parts,
+                                  NULL);
     offset += count;
   } while (count == partsSize);
   g_assert_cmpint(offset, ==, 3);
@@ -629,31 +629,31 @@ test_get_glyph_assembly (void)
   g_assert_cmpint(parts[0].start_connector_length, ==, 800);
   g_assert_cmpint(parts[0].end_connector_length, ==, 384);
   g_assert_cmpint(parts[0].full_advance, ==, 2000);
-  g_assert(!(parts[0].flags & HB_MATH_GLYPH_PART_FLAG_EXTENDER));
+  g_assert(!(parts[0].flags & HB_OT_MATH_GLYPH_PART_FLAG_EXTENDER));
   g_assert(hb_font_get_glyph_from_name (hb_font, "horizontal", -1, &glyph));
   g_assert_cmpint(parts[1].glyph, ==, glyph);
   g_assert_cmpint(parts[1].start_connector_length, ==, 524);
   g_assert_cmpint(parts[1].end_connector_length, ==, 800);
   g_assert_cmpint(parts[1].full_advance, ==, 2000);
-  g_assert(parts[1].flags & HB_MATH_GLYPH_PART_FLAG_EXTENDER);
+  g_assert(parts[1].flags & HB_OT_MATH_GLYPH_PART_FLAG_EXTENDER);
   g_assert(hb_font_get_glyph_from_name (hb_font, "right", -1, &glyph));
   g_assert_cmpint(parts[2].glyph, ==, glyph);
   g_assert_cmpint(parts[2].start_connector_length, ==, 316);
   g_assert_cmpint(parts[2].end_connector_length, ==, 454);
   g_assert_cmpint(parts[2].full_advance, ==, 2000);
-  g_assert(!(parts[2].flags & HB_MATH_GLYPH_PART_FLAG_EXTENDER));
+  g_assert(!(parts[2].flags & HB_OT_MATH_GLYPH_PART_FLAG_EXTENDER));
 
   g_assert(hb_font_get_glyph_from_name (hb_font, "arrowdown", -1, &glyph));
   offset = 0;
   do {
     count = partsSize;
     hb_ot_math_get_glyph_assembly (hb_font,
-                                   glyph,
-                                   HB_DIRECTION_BTT,
-                                   offset,
-                                   &count,
-                                   parts,
-                                   NULL);
+                                  glyph,
+                                  HB_DIRECTION_BTT,
+                                  offset,
+                                  &count,
+                                  parts,
+                                  NULL);
     offset += count;
   } while (count == partsSize);
   g_assert_cmpint(offset, ==, 5);
@@ -662,20 +662,20 @@ test_get_glyph_assembly (void)
   g_assert_cmpint(parts[0].start_connector_length, ==, 365);
   g_assert_cmpint(parts[0].end_connector_length, ==, 158);
   g_assert_cmpint(parts[0].full_advance, ==, 1000);
-  g_assert(!(parts[0].flags & HB_MATH_GLYPH_PART_FLAG_EXTENDER));
+  g_assert(!(parts[0].flags & HB_OT_MATH_GLYPH_PART_FLAG_EXTENDER));
   g_assert(hb_font_get_glyph_from_name (hb_font, "vertical", -1, &glyph));
   g_assert_cmpint(parts[1].glyph, ==, glyph);
   g_assert_cmpint(parts[1].glyph, ==, glyph);
   g_assert_cmpint(parts[1].start_connector_length, ==, 227);
   g_assert_cmpint(parts[1].end_connector_length, ==, 365);
   g_assert_cmpint(parts[1].full_advance, ==, 1000);
-  g_assert(parts[1].flags & HB_MATH_GLYPH_PART_FLAG_EXTENDER);
+  g_assert(parts[1].flags & HB_OT_MATH_GLYPH_PART_FLAG_EXTENDER);
   g_assert(hb_font_get_glyph_from_name (hb_font, "center", -1, &glyph));
   g_assert_cmpint(parts[2].glyph, ==, glyph);
   g_assert_cmpint(parts[2].start_connector_length, ==, 54);
   g_assert_cmpint(parts[2].end_connector_length, ==, 158);
   g_assert_cmpint(parts[2].full_advance, ==, 1000);
-  g_assert(!(parts[2].flags & HB_MATH_GLYPH_PART_FLAG_EXTENDER));
+  g_assert(!(parts[2].flags & HB_OT_MATH_GLYPH_PART_FLAG_EXTENDER));
   g_assert(hb_font_get_glyph_from_name (hb_font, "vertical", -1, &glyph));
   g_assert_cmpint(parts[3].glyph, ==, glyph);
   g_assert_cmpint(parts[3].glyph, ==, glyph);
@@ -683,13 +683,13 @@ test_get_glyph_assembly (void)
   g_assert_cmpint(parts[3].start_connector_length, ==, 400);
   g_assert_cmpint(parts[3].end_connector_length, ==, 296);
   g_assert_cmpint(parts[3].full_advance, ==, 1000);
-  g_assert(parts[1].flags & HB_MATH_GLYPH_PART_FLAG_EXTENDER);
+  g_assert(parts[1].flags & HB_OT_MATH_GLYPH_PART_FLAG_EXTENDER);
   g_assert(hb_font_get_glyph_from_name (hb_font, "top", -1, &glyph));
   g_assert_cmpint(parts[4].glyph, ==, glyph);
   g_assert_cmpint(parts[4].start_connector_length, ==, 123);
   g_assert_cmpint(parts[4].end_connector_length, ==, 192);
   g_assert_cmpint(parts[4].full_advance, ==, 1000);
-  g_assert(!(parts[4].flags & HB_MATH_GLYPH_PART_FLAG_EXTENDER));
+  g_assert(!(parts[4].flags & HB_OT_MATH_GLYPH_PART_FLAG_EXTENDER));
 
   closeFont();
 
diff --git a/test/api/test-ot-meta.c b/test/api/test-ot-meta.c
new file mode 100644 (file)
index 0000000..573c8c6
--- /dev/null
@@ -0,0 +1,84 @@
+/*
+ * Copyright © 2019  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.
+ */
+
+#include "hb-test.h"
+
+#include <hb-ot.h>
+
+/* Unit tests for hb-ot-meta.h */
+
+static void
+test_ot_meta_get_entries (void)
+{
+  hb_face_t *face = hb_test_open_font_file ("fonts/meta.ttf");
+  hb_ot_meta_tag_t entries[2];
+
+  unsigned int entries_count = 2;
+  g_assert_cmpint (hb_ot_meta_get_entry_tags (face, 0, &entries_count, entries), ==, 5);
+  g_assert_cmpint (entries_count, ==, 2);
+  g_assert_cmpint (entries[0], ==, HB_TAG ('a','p','p','l'));
+  g_assert_cmpint (entries[1], ==, HB_TAG ('b','i','l','d'));
+
+  entries_count = 1;
+  g_assert_cmpint (hb_ot_meta_get_entry_tags (face, 2, &entries_count, entries), ==, 5);
+  g_assert_cmpint (entries_count, ==, 1);
+  g_assert_cmpint (entries[0], ==, HB_TAG ('d','l','n','g'));
+
+  entries_count = 2;
+  g_assert_cmpint (hb_ot_meta_get_entry_tags (face, 4, &entries_count, entries), ==, 5);
+  g_assert_cmpint (entries_count, ==, 1);
+  g_assert_cmpint (entries[0], ==, HB_TAG ('s','l','n','g'));
+
+  hb_face_destroy (face);
+}
+
+static void
+test_ot_meta_reference_entry (void)
+{
+  hb_face_t *face = hb_test_open_font_file ("fonts/meta.ttf");
+  hb_blob_t *dlng = hb_ot_meta_reference_entry (face, HB_OT_META_TAG_DESIGN_LANGUAGES);
+  g_assert_cmpint (hb_blob_get_length (dlng), ==, 8);
+  g_assert_cmpmem (hb_blob_get_data (dlng, NULL), 8, "ar,de,fa", 8);
+  hb_blob_destroy (dlng);
+  hb_blob_t *fslf = hb_ot_meta_reference_entry (face, (hb_ot_meta_tag_t) HB_TAG ('f','s','l','f'));
+  g_assert_cmpint (hb_blob_get_length (fslf), ==, 12);
+  hb_blob_destroy (fslf);
+  hb_blob_t *nacl = hb_ot_meta_reference_entry (face, (hb_ot_meta_tag_t) HB_TAG ('n','a','c','l'));
+  g_assert_cmpint (hb_blob_get_length (nacl), ==, 0);
+  hb_blob_destroy (nacl);
+  hb_blob_t *slng = hb_ot_meta_reference_entry (face, HB_OT_META_TAG_SUPPORTED_LANGUAGES);
+  g_assert_cmpint (hb_blob_get_length (slng), ==, 11);
+  g_assert_cmpmem (hb_blob_get_data (slng, NULL), 11, "ar,de,en,fa", 11);
+  hb_blob_destroy (slng);
+  hb_face_destroy (face);
+}
+
+int
+main (int argc, char **argv)
+{
+  hb_test_init (&argc, &argv);
+  hb_test_add (test_ot_meta_get_entries);
+  hb_test_add (test_ot_meta_reference_entry);
+  return hb_test_run ();
+}
diff --git a/test/api/test-ot-metrics-tt-var.c b/test/api/test-ot-metrics-tt-var.c
new file mode 100644 (file)
index 0000000..2305a95
--- /dev/null
@@ -0,0 +1,250 @@
+/*
+ * Copyright © 2019 Adobe 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.
+ *
+ * Adobe Author(s): Michiharu Ariza
+ */
+
+#include "hb-test.h"
+#include <hb-ot.h>
+
+/* Unit tests for glyph advance widths and extents of TrueType variable fonts */
+
+static void
+test_extents_tt_var (void)
+{
+  hb_face_t *face = hb_test_open_font_file ("fonts/SourceSansVariable-Roman-nohvar-41,C1.ttf");
+  g_assert (face);
+  hb_font_t *font = hb_font_create (face);
+  hb_face_destroy (face);
+  g_assert (font);
+  hb_ot_font_set_funcs (font);
+
+  hb_glyph_extents_t  extents;
+  hb_bool_t result = hb_font_get_glyph_extents (font, 2, &extents);
+  g_assert (result);
+
+  g_assert_cmpint (extents.x_bearing, ==, 10);
+  g_assert_cmpint (extents.y_bearing, ==, 846);
+  g_assert_cmpint (extents.width, ==, 500);
+  g_assert_cmpint (extents.height, ==, -846);
+
+  float coords[1] = { 500.0f };
+  hb_font_set_var_coords_design (font, coords, 1);
+  result = hb_font_get_glyph_extents (font, 2, &extents);
+  g_assert (result);
+
+  g_assert_cmpint (extents.x_bearing, ==, 0);
+  g_assert_cmpint (extents.y_bearing, ==, 874);
+  g_assert_cmpint (extents.width, ==, 551);
+  g_assert_cmpint (extents.height, ==, -874);
+
+  hb_font_destroy (font);
+}
+
+static void
+test_advance_tt_var_nohvar (void)
+{
+  hb_face_t *face = hb_test_open_font_file ("fonts/SourceSansVariable-Roman-nohvar-41,C1.ttf");
+  g_assert (face);
+  hb_font_t *font = hb_font_create (face);
+  hb_face_destroy (face);
+  g_assert (font);
+  hb_ot_font_set_funcs (font);
+
+  hb_position_t x, y;
+  hb_font_get_glyph_advance_for_direction(font, 2, HB_DIRECTION_LTR, &x, &y);
+
+  g_assert_cmpint (x, ==, 520);
+  g_assert_cmpint (y, ==, 0);
+
+  hb_font_get_glyph_advance_for_direction(font, 2, HB_DIRECTION_TTB, &x, &y);
+
+  g_assert_cmpint (x, ==, 0);
+  g_assert_cmpint (y, ==, -1000);
+
+  float coords[1] = { 500.0f };
+  hb_font_set_var_coords_design (font, coords, 1);
+  hb_font_get_glyph_advance_for_direction(font, 2, HB_DIRECTION_LTR, &x, &y);
+
+  g_assert_cmpint (x, ==, 551);
+  g_assert_cmpint (y, ==, 0);
+
+  hb_font_get_glyph_advance_for_direction(font, 2, HB_DIRECTION_TTB, &x, &y);
+
+  g_assert_cmpint (x, ==, 0);
+  g_assert_cmpint (y, ==, -1000);
+
+  hb_font_destroy (font);
+}
+
+static void
+test_advance_tt_var_hvarvvar (void)
+{
+  hb_face_t *face = hb_test_open_font_file ("fonts/SourceSerifVariable-Roman-VVAR.abc.ttf");
+  g_assert (face);
+  hb_font_t *font = hb_font_create (face);
+  hb_face_destroy (face);
+  g_assert (font);
+  hb_ot_font_set_funcs (font);
+
+  hb_position_t x, y;
+  hb_font_get_glyph_advance_for_direction(font, 1, HB_DIRECTION_LTR, &x, &y);
+
+  g_assert_cmpint (x, ==, 508);
+  g_assert_cmpint (y, ==, 0);
+
+  hb_font_get_glyph_advance_for_direction(font, 1, HB_DIRECTION_TTB, &x, &y);
+
+  g_assert_cmpint (x, ==, 0);
+  g_assert_cmpint (y, ==, -1000);
+
+  float coords[1] = { 700.0f };
+  hb_font_set_var_coords_design (font, coords, 1);
+  hb_font_get_glyph_advance_for_direction(font, 1, HB_DIRECTION_LTR, &x, &y);
+
+  g_assert_cmpint (x, ==, 531);
+  g_assert_cmpint (y, ==, 0);
+
+  hb_font_get_glyph_advance_for_direction(font, 1, HB_DIRECTION_TTB, &x, &y);
+
+  g_assert_cmpint (x, ==, 0);
+  g_assert_cmpint (y, ==, -1012);
+
+  hb_font_destroy (font);
+}
+
+static void
+test_advance_tt_var_anchor (void)
+{
+  hb_face_t *face = hb_test_open_font_file ("fonts/SourceSansVariable-Roman.anchor.ttf");
+  g_assert (face);
+  hb_font_t *font = hb_font_create (face);
+  hb_face_destroy (face);
+  g_assert (font);
+  hb_ot_font_set_funcs (font);
+
+  hb_glyph_extents_t  extents;
+  hb_bool_t result = hb_font_get_glyph_extents (font, 2, &extents);
+  g_assert (result);
+
+  g_assert_cmpint (extents.x_bearing, ==, 56);
+  g_assert_cmpint (extents.y_bearing, ==, 672);
+  g_assert_cmpint (extents.width, ==, 556);
+  g_assert_cmpint (extents.height, ==, -684);
+
+  float coords[1] = { 500.0f };
+  hb_font_set_var_coords_design (font, coords, 1);
+  result = hb_font_get_glyph_extents (font, 2, &extents);
+  g_assert (result);
+
+  g_assert_cmpint (extents.x_bearing, ==, 50);
+  g_assert_cmpint (extents.y_bearing, ==, 667);
+  g_assert_cmpint (extents.width, ==, 593);
+  g_assert_cmpint (extents.height, ==, -679);
+
+  hb_font_destroy (font);
+}
+
+static void
+test_extents_tt_var_comp (void)
+{
+  hb_face_t *face = hb_test_open_font_file ("fonts/SourceSansVariable-Roman.modcomp.ttf");
+  g_assert (face);
+  hb_font_t *font = hb_font_create (face);
+  hb_face_destroy (face);
+  g_assert (font);
+  hb_ot_font_set_funcs (font);
+
+  hb_glyph_extents_t  extents;
+  float coords[1] = { 800.0f };
+  hb_font_set_var_coords_design (font, coords, 1);
+
+  hb_bool_t result;
+  result = hb_font_get_glyph_extents (font, 2, &extents);      /* Ccedilla, cedilla y-scaled by 0.8, with unscaled component offset */
+  g_assert (result);
+
+  g_assert_cmpint (extents.x_bearing, ==, 19);
+  g_assert_cmpint (extents.y_bearing, ==, 663);
+  g_assert_cmpint (extents.width, ==, 519);
+  g_assert_cmpint (extents.height, ==, -895);
+
+  result = hb_font_get_glyph_extents (font, 3, &extents);      /* Cacute, acute y-scaled by 0.8, with unscaled component offset (default) */
+  g_assert (result);
+
+  g_assert_cmpint (extents.x_bearing, ==, 19);
+  g_assert_cmpint (extents.y_bearing, ==, 909);
+  g_assert_cmpint (extents.width, ==, 519);
+  g_assert_cmpint (extents.height, ==, -921);
+
+  result = hb_font_get_glyph_extents (font, 4, &extents);      /* Ccaron, caron y-scaled by 0.8, with scaled component offset */
+  g_assert (result);
+
+  g_assert_cmpint (extents.x_bearing, ==, 19);
+  g_assert_cmpint (extents.y_bearing, ==, 866);
+  g_assert_cmpint (extents.width, ==, 519);
+  g_assert_cmpint (extents.height, ==, -878);
+
+  hb_font_destroy (font);
+}
+
+static void
+test_advance_tt_var_comp_v (void)
+{
+  hb_face_t *face = hb_test_open_font_file ("fonts/SourceSansVariable-Roman.modcomp.ttf");
+  g_assert (face);
+  hb_font_t *font = hb_font_create (face);
+  hb_face_destroy (face);
+  g_assert (font);
+  hb_ot_font_set_funcs (font);
+
+  float coords[1] = { 800.0f };
+  hb_font_set_var_coords_design (font, coords, 1);
+
+  hb_position_t x, y;
+  hb_font_get_glyph_advance_for_direction(font, 2, HB_DIRECTION_TTB, &x, &y);  /* No VVAR; 'C' in composite Ccedilla determines metrics */
+
+  g_assert_cmpint (x, ==, 0);
+  g_assert_cmpint (y, ==, -991);
+
+  hb_font_get_glyph_origin_for_direction(font, 2, HB_DIRECTION_TTB, &x, &y);
+
+  g_assert_cmpint (x, ==, 292);
+  g_assert_cmpint (y, ==, 1013);
+
+  hb_font_destroy (font);
+}
+
+int
+main (int argc, char **argv)
+{
+  hb_test_init (&argc, &argv);
+
+  hb_test_add (test_extents_tt_var);
+  hb_test_add (test_advance_tt_var_nohvar);
+  hb_test_add (test_advance_tt_var_hvarvvar);
+  hb_test_add (test_advance_tt_var_anchor);
+  hb_test_add (test_extents_tt_var_comp);
+  hb_test_add (test_advance_tt_var_comp_v);
+
+  return hb_test_run ();
+}
diff --git a/test/api/test-ot-metrics.c b/test/api/test-ot-metrics.c
new file mode 100644 (file)
index 0000000..34f9196
--- /dev/null
@@ -0,0 +1,78 @@
+/*
+ * 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.
+ */
+
+#include "hb-test.h"
+
+#include <hb-ot.h>
+
+#include <math.h>
+
+/* Unit tests for hb-ot-metrics.h */
+
+static void
+test_ot_metrics_get_no_var (void)
+{
+  hb_face_t *face = hb_test_open_font_file ("fonts/cpal-v0.ttf");
+  hb_font_t *font = hb_font_create (face);
+  hb_position_t value;
+  g_assert (hb_ot_metrics_get_position (font, HB_OT_METRICS_TAG_HORIZONTAL_ASCENDER, &value));
+  g_assert_cmpint (value, ==, 1000);
+  g_assert_cmpint (hb_ot_metrics_get_x_variation (font, HB_OT_METRICS_TAG_HORIZONTAL_ASCENDER), ==, 0);
+  g_assert_cmpint (hb_ot_metrics_get_y_variation (font, HB_OT_METRICS_TAG_HORIZONTAL_ASCENDER), ==, 0);
+  g_assert_cmpint (hb_ot_metrics_get_x_variation (font, HB_OT_METRICS_TAG_X_HEIGHT), ==, 0);
+  // g_assert_cmpint ((int) hb_ot_metrics_get_variation (font, HB_OT_METRICS_TAG_HORIZONTAL_ASCENDER), ==, 0);
+  hb_font_destroy (font);
+  hb_face_destroy (face);
+}
+
+static void
+test_ot_metrics_get_var (void)
+{
+  hb_face_t *face = hb_test_open_font_file ("fonts/TestCFF2VF.otf");
+  hb_font_t *font = hb_font_create (face);
+  hb_position_t value;
+  g_assert (hb_ot_metrics_get_position (font, HB_OT_METRICS_TAG_X_HEIGHT, &value));
+  g_assert_cmpint (value, ==, 486);
+  g_assert_cmpint (hb_ot_metrics_get_x_variation (font, HB_OT_METRICS_TAG_HORIZONTAL_ASCENDER), ==, 0);
+  g_assert_cmpint (hb_ot_metrics_get_y_variation (font, HB_OT_METRICS_TAG_HORIZONTAL_ASCENDER), ==, 0);
+  g_assert_cmpint (hb_ot_metrics_get_x_variation (font, HB_OT_METRICS_TAG_X_HEIGHT), ==, 0);
+  float coords[] = {100.f};
+  hb_font_set_var_coords_design (font, coords, 1);
+  g_assert (hb_ot_metrics_get_position (font, HB_OT_METRICS_TAG_X_HEIGHT, &value));
+  g_assert_cmpint (value, ==,  478);
+  g_assert_cmpint (hb_ot_metrics_get_x_variation (font, HB_OT_METRICS_TAG_HORIZONTAL_ASCENDER), ==, 0);
+  g_assert_cmpint (hb_ot_metrics_get_y_variation (font, HB_OT_METRICS_TAG_HORIZONTAL_ASCENDER), ==, 0);
+  g_assert_cmpint (hb_ot_metrics_get_x_variation (font, HB_OT_METRICS_TAG_X_HEIGHT), ==, -8);
+  hb_font_destroy (font);
+  hb_face_destroy (face);
+}
+
+int
+main (int argc, char **argv)
+{
+  hb_test_init (&argc, &argv);
+  hb_test_add (test_ot_metrics_get_no_var);
+  hb_test_add (test_ot_metrics_get_var);
+  return hb_test_run ();
+}
index 60231af..958fd6b 100644 (file)
@@ -190,7 +190,6 @@ test_ot_tag_script_indic (void)
   test_indic_tags ("ory3", "ory2", "orya", HB_SCRIPT_ORIYA);
   test_indic_tags ("tml3", "tml2", "taml", HB_SCRIPT_TAMIL);
   test_indic_tags ("tel3", "tel2", "telu", HB_SCRIPT_TELUGU);
-  test_indic_tags ("mym3", "mym2", "mymr", HB_SCRIPT_MYANMAR);
 }
 
 
@@ -281,6 +280,8 @@ test_ot_tag_language (void)
   g_assert_cmphex (HB_TAG_CHAR4 ("dflt"), ==, HB_OT_TAG_DEFAULT_LANGUAGE);
   test_language_two_way ("dflt", NULL);
 
+  test_language_two_way ("ALT", "alt");
+
   test_language_two_way ("ARA", "ar");
 
   test_language_two_way ("AZE", "az");
@@ -350,10 +351,8 @@ test_ot_tag_language (void)
   test_tag_from_language ("ZHH", "yue-Hant");
   test_tag_from_language ("ZHS", "yue-Hans");
 
-  test_tag_from_language ("ZHS", "zh"); /* Chinese */
-  test_tag_from_language ("ZHS", "zh-xx");
-
-  test_language_two_way ("ABC", "x-hbotabc");
+  test_language_two_way ("ABC", "abc");
+  test_language_two_way ("ABCD", "x-hbotabcd");
   test_tag_from_language ("ABC", "asdf-asdf-wer-x-hbotabc-zxc");
   test_tag_from_language ("ABC", "asdf-asdf-wer-x-hbotabc");
   test_tag_from_language ("ABCD", "asdf-asdf-wer-x-hbotabcd");
@@ -503,6 +502,7 @@ test_ot_tag_full (void)
   test_tags (HB_SCRIPT_INVALID, "x-hbsc5678-hbot1234", HB_OT_MAX_TAGS_PER_SCRIPT, HB_OT_MAX_TAGS_PER_LANGUAGE, 1, 1, "5678", "1234");
   test_tags (HB_SCRIPT_MALAYALAM, "ml", HB_OT_MAX_TAGS_PER_SCRIPT, HB_OT_MAX_TAGS_PER_LANGUAGE, 3, 2, "mlm3", "mlm2", "mlym", "MAL", "MLR");
   test_tags (HB_SCRIPT_MALAYALAM, "ml", 1, 1, 1, 1, "mlm3", "MAL");
+  test_tags (HB_SCRIPT_MYANMAR, "und", HB_OT_MAX_TAGS_PER_SCRIPT, 0, 2, 0, "mym2", "mymr");
   test_tags (HB_SCRIPT_INVALID, "xyz", HB_OT_MAX_TAGS_PER_SCRIPT, HB_OT_MAX_TAGS_PER_LANGUAGE, 0, 1, "XYZ");
   test_tags (HB_SCRIPT_INVALID, "xy", HB_OT_MAX_TAGS_PER_SCRIPT, HB_OT_MAX_TAGS_PER_LANGUAGE, 0, 0);
 }
index 146cf0f..fd7acec 100644 (file)
@@ -67,45 +67,16 @@ glyph_func (hb_font_t *font HB_UNUSED, void *font_data HB_UNUSED,
   return FALSE;
 }
 
-static hb_position_t
-glyph_h_kerning_func (hb_font_t *font HB_UNUSED, void *font_data HB_UNUSED,
-                     hb_codepoint_t left, hb_codepoint_t right,
-                     void *user_data HB_UNUSED)
-{
-  if (left == 1 && right == 2)
-    return -2;
-
-  return 0;
-}
-
 static const char TesT[] = "TesT";
 
 static void
-test_shape (void)
+test_font (hb_font_t *font)
 {
-  hb_blob_t *blob;
-  hb_face_t *face;
-  hb_font_funcs_t *ffuncs;
-  hb_font_t *font;
   hb_buffer_t *buffer;
   unsigned int len;
   hb_glyph_info_t *glyphs;
   hb_glyph_position_t *positions;
 
-  blob = hb_blob_create (test_data, sizeof (test_data), HB_MEMORY_MODE_READONLY, NULL, NULL);
-  face = hb_face_create (blob, 0);
-  hb_blob_destroy (blob);
-  font = hb_font_create (face);
-  hb_face_destroy (face);
-  hb_font_set_scale (font, 10, 10);
-
-  ffuncs = hb_font_funcs_create ();
-  hb_font_funcs_set_glyph_h_advance_func (ffuncs, glyph_h_advance_func, NULL, NULL);
-  hb_font_funcs_set_nominal_glyph_func (ffuncs, glyph_func, malloc (10), free);
-  hb_font_funcs_set_glyph_h_kerning_func (ffuncs, glyph_h_kerning_func, NULL, NULL);
-  hb_font_set_funcs (font, ffuncs, NULL, NULL);
-  hb_font_funcs_destroy (ffuncs);
-
   buffer =  hb_buffer_create ();
   hb_buffer_set_direction (buffer, HB_DIRECTION_LTR);
   hb_buffer_add_utf8 (buffer, TesT, 4, 0, 4);
@@ -118,8 +89,8 @@ test_shape (void)
 
   {
     const hb_codepoint_t output_glyphs[] = {1, 2, 3, 1};
-    const hb_position_t output_x_advances[] = {9, 5, 5, 10};
-    const hb_position_t output_x_offsets[] = {0, -1, 0, 0};
+    const hb_position_t output_x_advances[] = {10, 6, 5, 10};
+    const hb_position_t output_x_offsets[] = {0, 0, 0, 0};
     unsigned int i;
     g_assert_cmpint (len, ==, 4);
     for (i = 0; i < len; i++) {
@@ -135,6 +106,35 @@ test_shape (void)
   }
 
   hb_buffer_destroy (buffer);
+}
+
+static void
+test_shape (void)
+{
+  hb_blob_t *blob;
+  hb_face_t *face;
+  hb_font_funcs_t *ffuncs;
+  hb_font_t *font, *sub_font;
+
+  blob = hb_blob_create (test_data, sizeof (test_data), HB_MEMORY_MODE_READONLY, NULL, NULL);
+  face = hb_face_create (blob, 0);
+  hb_blob_destroy (blob);
+  font = hb_font_create (face);
+  hb_face_destroy (face);
+  hb_font_set_scale (font, 10, 10);
+
+  ffuncs = hb_font_funcs_create ();
+  hb_font_funcs_set_glyph_h_advance_func (ffuncs, glyph_h_advance_func, NULL, NULL);
+  hb_font_funcs_set_nominal_glyph_func (ffuncs, glyph_func, malloc (10), free);
+  hb_font_set_funcs (font, ffuncs, NULL, NULL);
+  hb_font_funcs_destroy (ffuncs);
+
+  test_font (font);
+
+  sub_font = hb_font_create_sub_font (font);
+  test_font (sub_font);
+
+  hb_font_destroy (sub_font);
   hb_font_destroy (font);
 }
 
diff --git a/test/api/test-subset-drop-tables.c b/test/api/test-subset-drop-tables.c
new file mode 100644 (file)
index 0000000..e234080
--- /dev/null
@@ -0,0 +1,71 @@
+/*
+ * Copyright © 2019  Google, Inc.
+ *
+ *  This is part of HarfBuzz, a text shaping library.
+ *
+ * Permission is hereby granted, without written agreement and without
+ * license or royalty fees, to use, copy, modify, and distribute this
+ * software and its documentation for any purpose, provided that the
+ * above copyright notice and the following two paragraphs appear in
+ * all copies of this software.
+ *
+ * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
+ * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
+ * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
+ * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+ * DAMAGE.
+ *
+ * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
+ * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS
+ * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
+ * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
+ *
+ * Google Author(s): Garret Rieger
+ */
+
+#include "hb-test.h"
+#include "hb-subset-test.h"
+
+/* Unit tests for hb-subset.cc drop tables functionality */
+
+static void
+test_subset_drop_tables (void)
+{
+  hb_face_t *face = hb_test_open_font_file ("fonts/Roboto-Regular.abc.ttf");
+
+  hb_set_t *codepoints = hb_set_create();
+  hb_set_add (codepoints, 97);
+  hb_set_add (codepoints, 99);
+  hb_subset_input_t *input = hb_subset_test_create_input (codepoints);
+  hb_set_add (hb_subset_input_drop_tables_set (input), HB_TAG ('h', 'd', 'm', 'x'));
+  hb_set_add (hb_subset_input_drop_tables_set (input), HB_TAG ('h', 'm', 't', 'x'));
+  hb_set_destroy (codepoints);
+
+  hb_face_t* subset = hb_subset (face, input);
+
+  hb_blob_t *hdmx = hb_face_reference_table (subset, HB_TAG ('h', 'd', 'm', 'x'));
+  hb_blob_t *hmtx = hb_face_reference_table (subset, HB_TAG ('h', 'm', 't', 'x'));
+  hb_blob_t *cmap = hb_face_reference_table (subset, HB_TAG ('c', 'm', 'a', 'p'));
+  g_assert (!hb_blob_get_length (hdmx));
+  g_assert (!hb_blob_get_length (hmtx));
+  g_assert ( hb_blob_get_length (cmap));
+  hb_blob_destroy (hdmx);
+  hb_blob_destroy (hmtx);
+  hb_blob_destroy (cmap);
+
+  hb_face_destroy (subset);
+  hb_subset_input_destroy (input);
+  hb_face_destroy (face);
+}
+
+
+int
+main (int argc, char **argv)
+{
+  hb_test_init (&argc, &argv);
+
+  hb_test_add (test_subset_drop_tables);
+
+  return hb_test_run();
+}
index 4671156..2b330ce 100644 (file)
@@ -70,9 +70,9 @@ test_subset_glyf (void)
   face_abc_subset = hb_subset_test_create_subset (face_abc, hb_subset_test_create_input (codepoints));
   hb_set_destroy (codepoints);
 
-  hb_subset_test_check (face_ac, face_abc_subset, HB_TAG ('g','l','y','f'));
-  hb_subset_test_check (face_ac, face_abc_subset, HB_TAG ('l','o','c', 'a'));
   check_maxp_num_glyphs(face_abc_subset, 3, true);
+  hb_subset_test_check (face_ac, face_abc_subset, HB_TAG ('l','o','c', 'a'));
+  hb_subset_test_check (face_ac, face_abc_subset, HB_TAG ('g','l','y','f'));
 
   hb_face_destroy (face_abc_subset);
   hb_face_destroy (face_abc);
@@ -137,7 +137,9 @@ test_subset_glyf_with_gsub (void)
 
   input = hb_subset_test_create_input (codepoints);
   hb_set_destroy (codepoints);
-  hb_subset_input_set_drop_layout (input, false);
+  hb_set_del (hb_subset_input_drop_tables_set (input), HB_TAG('G', 'S', 'U', 'B'));
+  hb_set_del (hb_subset_input_drop_tables_set (input), HB_TAG('G', 'P', 'O', 'S'));
+  hb_set_del (hb_subset_input_drop_tables_set (input), HB_TAG('G', 'D', 'E', 'F'));
 
   face_subset = hb_subset_test_create_subset (face_fil, input);
 
@@ -164,7 +166,9 @@ test_subset_glyf_without_gsub (void)
 
   input = hb_subset_test_create_input (codepoints);
   hb_set_destroy (codepoints);
-  hb_subset_input_set_drop_layout (input, true);
+  hb_set_add (hb_subset_input_drop_tables_set (input), HB_TAG('G', 'S', 'U', 'B'));
+  hb_set_add (hb_subset_input_drop_tables_set (input), HB_TAG('G', 'P', 'O', 'S'));
+  hb_set_add (hb_subset_input_drop_tables_set (input), HB_TAG('G', 'D', 'E', 'F'));
 
   face_subset = hb_subset_test_create_subset (face_fil, input);
 
@@ -190,9 +194,9 @@ test_subset_glyf_noop (void)
   face_abc_subset = hb_subset_test_create_subset (face_abc, hb_subset_test_create_input (codepoints));
   hb_set_destroy (codepoints);
 
-  hb_subset_test_check (face_abc, face_abc_subset, HB_TAG ('g','l','y','f'));
-  hb_subset_test_check (face_abc, face_abc_subset, HB_TAG ('l','o','c', 'a'));
   check_maxp_num_glyphs(face_abc_subset, 4, true);
+  hb_subset_test_check (face_abc, face_abc_subset, HB_TAG ('l','o','c', 'a'));
+  hb_subset_test_check (face_abc, face_abc_subset, HB_TAG ('g','l','y','f'));
 
   hb_face_destroy (face_abc_subset);
   hb_face_destroy (face_abc);
@@ -214,9 +218,9 @@ test_subset_glyf_strip_hints_simple (void)
   face_abc_subset = hb_subset_test_create_subset (face_abc, input);
   hb_set_destroy (codepoints);
 
+  check_maxp_num_glyphs(face_abc_subset, 3, false);
   hb_subset_test_check (face_ac, face_abc_subset, HB_TAG ('l','o','c', 'a'));
   hb_subset_test_check (face_ac, face_abc_subset, HB_TAG ('g','l','y','f'));
-  check_maxp_num_glyphs(face_abc_subset, 3, false);
 
   hb_face_destroy (face_abc_subset);
   hb_face_destroy (face_abc);
@@ -239,9 +243,9 @@ test_subset_glyf_strip_hints_composite (void)
   face_generated_subset = hb_subset_test_create_subset (face_components, input);
   hb_set_destroy (codepoints);
 
-  hb_subset_test_check (face_subset, face_generated_subset, HB_TAG ('g','l','y','f'));
-  hb_subset_test_check (face_subset, face_generated_subset, HB_TAG ('l','o','c', 'a'));
   check_maxp_num_glyphs(face_generated_subset, 4, false);
+  hb_subset_test_check (face_subset, face_generated_subset, HB_TAG ('l','o','c', 'a'));
+  hb_subset_test_check (face_subset, face_generated_subset, HB_TAG ('g','l','y','f'));
 
   hb_face_destroy (face_generated_subset);
   hb_face_destroy (face_subset);
@@ -296,15 +300,39 @@ test_subset_glyf_retain_gids (void)
   face_abc_subset = hb_subset_test_create_subset (face_abc, input);
   hb_set_destroy (codepoints);
 
-  hb_subset_test_check (face_ac, face_abc_subset, HB_TAG ('g','l','y','f'));
-  hb_subset_test_check (face_ac, face_abc_subset, HB_TAG ('l','o','c', 'a'));
   check_maxp_num_glyphs(face_abc_subset, 4, true);
+  hb_subset_test_check (face_ac, face_abc_subset, HB_TAG ('l','o','c', 'a'));
+  hb_subset_test_check (face_ac, face_abc_subset, HB_TAG ('g','l','y','f'));
 
   hb_face_destroy (face_abc_subset);
   hb_face_destroy (face_abc);
   hb_face_destroy (face_ac);
 }
 
+static void
+test_subset_glyf_retain_gids_truncates (void)
+{
+  hb_face_t *face_abc = hb_test_open_font_file ("fonts/Roboto-Regular.abc.ttf");
+  hb_face_t *face_a = hb_test_open_font_file ("fonts/Roboto-Regular.a.retaingids.ttf");
+
+  hb_set_t *codepoints = hb_set_create();
+  hb_face_t *face_abc_subset;
+  hb_set_add (codepoints, 97);
+
+  hb_subset_input_t *input = hb_subset_test_create_input (codepoints);
+  hb_subset_input_set_retain_gids (input, true);
+  face_abc_subset = hb_subset_test_create_subset (face_abc, input);
+  hb_set_destroy (codepoints);
+
+  check_maxp_num_glyphs(face_abc_subset, 2, true);
+  hb_subset_test_check (face_a, face_abc_subset, HB_TAG ('l','o','c', 'a'));
+  hb_subset_test_check (face_a, face_abc_subset, HB_TAG ('g','l','y','f'));
+
+  hb_face_destroy (face_abc_subset);
+  hb_face_destroy (face_abc);
+  hb_face_destroy (face_a);
+}
+
 // TODO(grieger): test for long loca generation.
 
 int
@@ -322,6 +350,7 @@ main (int argc, char **argv)
   hb_test_add (test_subset_glyf_with_gsub);
   hb_test_add (test_subset_glyf_without_gsub);
   hb_test_add (test_subset_glyf_retain_gids);
+  hb_test_add (test_subset_glyf_retain_gids_truncates);
 
   return hb_test_run();
 }
index 44e579a..7178833 100644 (file)
@@ -92,28 +92,6 @@ test_subset_hdmx_invalid (void)
 }
 
 static void
-test_subset_hdmx_fails_sanitize (void)
-{
-  hb_face_t *face = hb_test_open_font_file ("../fuzzing/fonts/clusterfuzz-testcase-minimized-hb-subset-fuzzer-5609911946838016");
-
-  hb_subset_input_t *input = hb_subset_input_create_or_fail ();
-  hb_set_t *codepoints = hb_subset_input_unicode_set (input);
-  hb_face_t *subset;
-
-  hb_set_add (codepoints, 'a');
-  hb_set_add (codepoints, 'b');
-  hb_set_add (codepoints, 'c');
-
-  subset = hb_subset (face, input);
-  g_assert (subset);
-  g_assert (subset == hb_face_get_empty ());
-
-  hb_subset_input_destroy (input);
-  hb_face_destroy (subset);
-  hb_face_destroy (face);
-}
-
-static void
 test_subset_hdmx_noop (void)
 {
   hb_face_t *face_abc = hb_test_open_font_file ("fonts/Roboto-Regular.abc.ttf");
@@ -140,7 +118,6 @@ main (int argc, char **argv)
   hb_test_add (test_subset_hdmx_simple_subset);
   hb_test_add (test_subset_hdmx_multiple_device_records);
   hb_test_add (test_subset_hdmx_invalid);
-  hb_test_add (test_subset_hdmx_fails_sanitize);
   hb_test_add (test_subset_hdmx_noop);
 
   return hb_test_run();
diff --git a/test/api/test-subset-nameids.c b/test/api/test-subset-nameids.c
new file mode 100644 (file)
index 0000000..b58a86c
--- /dev/null
@@ -0,0 +1,79 @@
+/*
+ * Copyright © 2018  Google, Inc.
+ *
+ *  This is part of HarfBuzz, a text shaping library.
+ *
+ * Permission is hereby granted, without written agreement and without
+ * license or royalty fees, to use, copy, modify, and distribute this
+ * software and its documentation for any purpose, provided that the
+ * above copyright notice and the following two paragraphs appear in
+ * all copies of this software.
+ *
+ * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
+ * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
+ * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
+ * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+ * DAMAGE.
+ *
+ * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
+ * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS
+ * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
+ * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
+ *
+ * Google Author(s): Garret Rieger
+ */
+
+#include "hb-test.h"
+#include "hb-subset-test.h"
+
+static void
+test_subset_nameids (void)
+{
+  hb_face_t *face_origin = hb_test_open_font_file ("fonts/nameID.origin.ttf");
+  hb_face_t *face_expected = hb_test_open_font_file ("fonts/nameID.expected.ttf");
+
+  hb_set_t *name_ids = hb_set_create();
+  hb_face_t *face_subset;
+  hb_set_add (name_ids, 0);
+  hb_set_add (name_ids, 9);
+  face_subset = hb_subset_test_create_subset (face_origin, hb_subset_test_create_input_from_nameids (name_ids));
+  hb_set_destroy (name_ids);
+
+  hb_subset_test_check (face_expected, face_subset, HB_TAG ('n','a','m','e'));
+
+  hb_face_destroy (face_subset);
+  hb_face_destroy (face_origin);
+  hb_face_destroy (face_expected);
+}
+
+static void
+test_subset_nameids_with_dup_strs (void)
+{
+  hb_face_t *face_origin = hb_test_open_font_file ("fonts/nameID.dup.origin.ttf");
+  hb_face_t *face_expected = hb_test_open_font_file ("fonts/nameID.dup.expected.ttf");
+
+  hb_set_t *name_ids = hb_set_create();
+  hb_face_t *face_subset;
+  hb_set_add (name_ids, 1);
+  hb_set_add (name_ids, 3);
+  face_subset = hb_subset_test_create_subset (face_origin, hb_subset_test_create_input_from_nameids (name_ids));
+  hb_set_destroy (name_ids);
+
+  hb_subset_test_check (face_expected, face_subset, HB_TAG ('n','a','m','e'));
+
+  hb_face_destroy (face_subset);
+  hb_face_destroy (face_origin);
+  hb_face_destroy (face_expected);
+}
+
+int
+main (int argc, char **argv)
+{
+  hb_test_init (&argc, &argv);
+
+  hb_test_add (test_subset_nameids);
+  hb_test_add (test_subset_nameids_with_dup_strs);
+
+  return hb_test_run();
+}
index 6195bb2..71a471d 100644 (file)
@@ -62,8 +62,8 @@ static void free_up (void *p)
 
 static hb_script_t
 simple_get_script (hb_unicode_funcs_t *ufuncs,
-                   hb_codepoint_t      codepoint,
-                   void               *user_data)
+                  hb_codepoint_t      codepoint,
+                  void               *user_data)
 {
   data_t *data = (data_t *) user_data;
 
@@ -79,8 +79,8 @@ simple_get_script (hb_unicode_funcs_t *ufuncs,
 
 static hb_script_t
 a_is_for_arabic_get_script (hb_unicode_funcs_t *ufuncs,
-                            hb_codepoint_t      codepoint,
-                            void               *user_data)
+                           hb_codepoint_t      codepoint,
+                           void               *user_data)
 {
   data_t *data = (data_t *) user_data;
 
@@ -157,6 +157,27 @@ static const test_pair_t combining_class_tests_more[] =
   /* Unicode-6.0 character additions */
   {   0x135D, 230 },
 
+  /* Unicode-6.1 character additions */
+  {   0xA674, 230 },
+
+  /* Unicode-7.0 character additions */
+  {   0x1AB0, 230 },
+
+  /* Unicode-8.0 character additions */
+  {   0xA69E, 230 },
+
+  /* Unicode-9.0 character additions */
+  {  0x1E000, 230 },
+
+  /* Unicode-10.0 character additions */
+  {   0x1DF6, 232 },
+
+  /* Unicode-11.0 character additions */
+  {   0x07FD, 220 },
+
+  /* Unicode-12.0 character additions */
+  {   0x0EBA,   9 },
+
   { 0x111111, 0 }
 };
 
@@ -204,6 +225,36 @@ static const test_pair_t general_category_tests_more[] =
   /* Unicode-6.0 character additions */
   {   0x0620, HB_UNICODE_GENERAL_CATEGORY_OTHER_LETTER },
 
+  /* Unicode-6.1 character additions */
+  {   0x058F, HB_UNICODE_GENERAL_CATEGORY_CURRENCY_SYMBOL },
+
+  /* Unicode-6.2 character additions */
+  {   0x20BA, HB_UNICODE_GENERAL_CATEGORY_CURRENCY_SYMBOL },
+
+  /* Unicode-6.3 character additions */
+  {   0x061C, HB_UNICODE_GENERAL_CATEGORY_FORMAT },
+
+  /* Unicode-7.0 character additions */
+  {   0x058D, HB_UNICODE_GENERAL_CATEGORY_OTHER_SYMBOL },
+
+  /* Unicode-8.0 character additions */
+  {   0x08E3, HB_UNICODE_GENERAL_CATEGORY_NON_SPACING_MARK },
+
+  /* Unicode-9.0 character additions */
+  {   0x08D4, HB_UNICODE_GENERAL_CATEGORY_NON_SPACING_MARK },
+
+  /* Unicode-10.0 character additions */
+  {   0x09FD, HB_UNICODE_GENERAL_CATEGORY_OTHER_PUNCTUATION },
+
+  /* Unicode-11.0 character additions */
+  {   0x0560, HB_UNICODE_GENERAL_CATEGORY_LOWERCASE_LETTER },
+
+  /* Unicode-12.0 character additions */
+  {   0x0C77, HB_UNICODE_GENERAL_CATEGORY_OTHER_PUNCTUATION },
+
+  /* Unicode-12.1 character additions */
+  {   0x32FF, HB_UNICODE_GENERAL_CATEGORY_OTHER_SYMBOL },
+
   { 0x111111, HB_UNICODE_GENERAL_CATEGORY_UNASSIGNED }
 };
 
@@ -242,7 +293,12 @@ static const test_pair_t mirroring_tests[] =
 };
 static const test_pair_t mirroring_tests_more[] =
 {
-  /* No new mirroring characters have been encoded in recent Unicode versions. */
+  /* Unicode-6.1 character additions */
+  {   0x27CB, 0x27CD },
+
+  /* Unicode-11.0 character additions */
+  {   0x2BFE, 0x221F },
+
   { 0x111111, 0x111111 }
 };
 
@@ -342,8 +398,10 @@ static const test_pair_t script_tests_more[] =
   /* Unicode-5.2 additions */
   {  0x10B00, HB_SCRIPT_AVESTAN },
   {   0xA6A0, HB_SCRIPT_BAMUM },
+  {   0x1400, HB_SCRIPT_CANADIAN_ABORIGINAL },
   {  0x13000, HB_SCRIPT_EGYPTIAN_HIEROGLYPHS },
   {  0x10840, HB_SCRIPT_IMPERIAL_ARAMAIC },
+  {   0x1CED, HB_SCRIPT_INHERITED },
   {  0x10B60, HB_SCRIPT_INSCRIPTIONAL_PAHLAVI },
   {  0x10B40, HB_SCRIPT_INSCRIPTIONAL_PARTHIAN },
   {   0xA980, HB_SCRIPT_JAVANESE },
@@ -361,9 +419,85 @@ static const test_pair_t script_tests_more[] =
   {  0x11000, HB_SCRIPT_BRAHMI },
   {   0x0840, HB_SCRIPT_MANDAIC },
 
-  /* Unicode-5.2 character additions */
-  {   0x1CED, HB_SCRIPT_INHERITED },
-  {   0x1400, HB_SCRIPT_CANADIAN_ABORIGINAL },
+  /* Unicode-6.1 additions */
+  {  0x10980, HB_SCRIPT_MEROITIC_HIEROGLYPHS },
+  {  0x109A0, HB_SCRIPT_MEROITIC_CURSIVE },
+  {  0x110D0, HB_SCRIPT_SORA_SOMPENG },
+  {  0x11100, HB_SCRIPT_CHAKMA },
+  {  0x11180, HB_SCRIPT_SHARADA },
+  {  0x11680, HB_SCRIPT_TAKRI },
+  {  0x16F00, HB_SCRIPT_MIAO },
+
+  /* Unicode-6.2 additions */
+  {   0x20BA, HB_SCRIPT_COMMON },
+
+  /* Unicode-6.3 additions */
+  {   0x2066, HB_SCRIPT_COMMON },
+
+  /* Unicode-7.0 additions */
+  {   0x10350, HB_SCRIPT_OLD_PERMIC },
+  {   0x10500, HB_SCRIPT_ELBASAN },
+  {   0x10530, HB_SCRIPT_CAUCASIAN_ALBANIAN },
+  {   0x10600, HB_SCRIPT_LINEAR_A },
+  {   0x10860, HB_SCRIPT_PALMYRENE },
+  {   0x10880, HB_SCRIPT_NABATAEAN },
+  {   0x10A80, HB_SCRIPT_OLD_NORTH_ARABIAN },
+  {   0x10AC0, HB_SCRIPT_MANICHAEAN },
+  {   0x10B80, HB_SCRIPT_PSALTER_PAHLAVI },
+  {   0x11150, HB_SCRIPT_MAHAJANI },
+  {   0x11200, HB_SCRIPT_KHOJKI },
+  {   0x112B0, HB_SCRIPT_KHUDAWADI },
+  {   0x11300, HB_SCRIPT_GRANTHA },
+  {   0x11480, HB_SCRIPT_TIRHUTA },
+  {   0x11580, HB_SCRIPT_SIDDHAM },
+  {   0x11600, HB_SCRIPT_MODI },
+  {   0x118A0, HB_SCRIPT_WARANG_CITI },
+  {   0x11AC0, HB_SCRIPT_PAU_CIN_HAU },
+  {   0x16A40, HB_SCRIPT_MRO },
+  {   0x16AD0, HB_SCRIPT_BASSA_VAH },
+  {   0x16B00, HB_SCRIPT_PAHAWH_HMONG },
+  {   0x1BC00, HB_SCRIPT_DUPLOYAN },
+  {   0x1E800, HB_SCRIPT_MENDE_KIKAKUI },
+
+  /* Unicode-8.0 additions */
+  {   0x108E0, HB_SCRIPT_HATRAN },
+  {   0x10C80, HB_SCRIPT_OLD_HUNGARIAN },
+  {   0x11280, HB_SCRIPT_MULTANI },
+  {   0x11700, HB_SCRIPT_AHOM },
+  {   0x14400, HB_SCRIPT_ANATOLIAN_HIEROGLYPHS },
+  {   0x1D800, HB_SCRIPT_SIGNWRITING },
+
+  /* Unicode-9.0 additions */
+  {   0x104B0, HB_SCRIPT_OSAGE },
+  {   0x11400, HB_SCRIPT_NEWA },
+  {   0x11C00, HB_SCRIPT_BHAIKSUKI },
+  {   0x11C70, HB_SCRIPT_MARCHEN },
+  {   0x17000, HB_SCRIPT_TANGUT },
+  {   0x1E900, HB_SCRIPT_ADLAM },
+
+  /* Unicode-10.0 additions */
+  {   0x11A00, HB_SCRIPT_ZANABAZAR_SQUARE },
+  {   0x11A50, HB_SCRIPT_SOYOMBO },
+  {   0x11D00, HB_SCRIPT_MASARAM_GONDI },
+  {   0x1B170, HB_SCRIPT_NUSHU },
+
+  /* Unicode-11.0 additions */
+  {   0x10D00, HB_SCRIPT_HANIFI_ROHINGYA },
+  {   0x10F00, HB_SCRIPT_OLD_SOGDIAN },
+  {   0x10F30, HB_SCRIPT_SOGDIAN },
+  {   0x11800, HB_SCRIPT_DOGRA },
+  {   0x11D60, HB_SCRIPT_GUNJALA_GONDI },
+  {   0x11EE0, HB_SCRIPT_MAKASAR },
+  {   0x16E40, HB_SCRIPT_MEDEFAIDRIN },
+
+  /* Unicode-12.0 additions */
+  {   0x10FE0, HB_SCRIPT_ELYMAIC },
+  {   0x119A0, HB_SCRIPT_NANDINAGARI },
+  {   0x1E100, HB_SCRIPT_NYIAKENG_PUACHUE_HMONG },
+  {   0x1E2C0, HB_SCRIPT_WANCHO },
+
+  /* Unicode-12.1 additions */
+  {   0x32FF, HB_SCRIPT_COMMON },
 
   { 0x111111, HB_SCRIPT_UNKNOWN }
 };
@@ -413,7 +547,7 @@ static const property_t properties[] =
 #undef PROPERTY
 
 static void
-test_unicode_properties (gconstpointer user_data)
+test_unicode_properties (gconstpointer user_data, hb_bool_t lenient)
 {
   hb_unicode_funcs_t *uf = (hb_unicode_funcs_t *) user_data;
   unsigned int i, j;
@@ -437,16 +571,30 @@ test_unicode_properties (gconstpointer user_data)
     tests = p->tests_more;
     for (j = 0; j < p->num_tests_more; j++) {
       g_test_message ("Test %s more #%d: U+%04X", p->name, j, tests[j].unicode);
-      if (p->getter (uf, tests[j].unicode) != tests[j].value) {
-       g_test_message ("Soft fail: Received %x, expected %x", p->getter (uf, tests[j].unicode), tests[j].value);
-        failed = TRUE;
+      if (lenient) {
+       if (p->getter (uf, tests[j].unicode) != tests[j].value) {
+         g_test_message ("Soft fail: Received %x, expected %x", p->getter (uf, tests[j].unicode), tests[j].value);
+         failed = TRUE;
+       }
       }
+      else
+       g_assert_cmphex (p->getter (uf, tests[j].unicode), ==, tests[j].value);
     }
   }
 
   if (failed)
     g_test_message ("Some property tests failed.  You probably have an old version of one of the libraries used.");
 }
+static void
+test_unicode_properties_lenient (gconstpointer user_data)
+{
+  test_unicode_properties (user_data, TRUE);
+}
+static void
+test_unicode_properties_strict (gconstpointer user_data)
+{
+  test_unicode_properties (user_data, FALSE);
+}
 
 static hb_codepoint_t
 default_value (hb_codepoint_t _default_value, hb_codepoint_t unicode)
@@ -529,7 +677,7 @@ test_unicode_chainup (void)
 
   g_assert (!hb_unicode_funcs_is_immutable (uf2));
   hb_unicode_funcs_make_immutable (uf2);
-  test_unicode_properties (uf2);
+  test_unicode_properties_strict (uf2);
 
   hb_unicode_funcs_destroy (uf2);
 
@@ -603,7 +751,7 @@ test_unicode_subclassing_nil (data_fixture_t *f, gconstpointer user_data HB_UNUS
   hb_unicode_funcs_destroy (uf);
 
   hb_unicode_funcs_set_script_func (aa, a_is_for_arabic_get_script,
-                                    &f->data[1], free_up);
+                                   &f->data[1], free_up);
 
   g_assert_cmphex (hb_unicode_script (aa, 'a'), ==, HB_SCRIPT_ARABIC);
   g_assert_cmphex (hb_unicode_script (aa, 'b'), ==, HB_SCRIPT_UNKNOWN);
@@ -622,7 +770,7 @@ test_unicode_subclassing_default (data_fixture_t *f, gconstpointer user_data HB_
   aa = hb_unicode_funcs_create (uf);
 
   hb_unicode_funcs_set_script_func (aa, a_is_for_arabic_get_script,
-                                    &f->data[1], free_up);
+                                   &f->data[1], free_up);
 
   g_assert_cmphex (hb_unicode_script (aa, 'a'), ==, HB_SCRIPT_ARABIC);
   g_assert_cmphex (hb_unicode_script (aa, 'b'), ==, HB_SCRIPT_LATIN);
@@ -640,7 +788,7 @@ test_unicode_subclassing_deep (data_fixture_t *f, gconstpointer user_data HB_UNU
   uf = hb_unicode_funcs_create (NULL);
 
   hb_unicode_funcs_set_script_func (uf, simple_get_script,
-                                    &f->data[0], free_up);
+                                   &f->data[0], free_up);
 
   aa = hb_unicode_funcs_create (uf);
 
@@ -650,7 +798,7 @@ test_unicode_subclassing_deep (data_fixture_t *f, gconstpointer user_data HB_UNU
   g_assert (!f->data[0].freed);
 
   hb_unicode_funcs_set_script_func (aa, a_is_for_arabic_get_script,
-                                    &f->data[1], free_up);
+                                   &f->data[1], free_up);
 
   g_assert_cmphex (hb_unicode_script (aa, 'a'), ==, HB_SCRIPT_ARABIC);
   g_assert_cmphex (hb_unicode_script (aa, 'b'), ==, HB_SCRIPT_LATIN);
@@ -755,6 +903,10 @@ test_unicode_normalization (gconstpointer user_data)
   g_assert (hb_unicode_compose (uf, 0xCE20, 0x11B8, &ab) && ab == 0xCE31);
   g_assert (hb_unicode_compose (uf, 0x110E, 0x1173, &ab) && ab == 0xCE20);
 
+  g_assert (!hb_unicode_compose (uf, 0xAC00, 0x11A7, &ab));
+  g_assert (hb_unicode_compose (uf, 0xAC00, 0x11A8, &ab) && ab == 0xAC01);
+  g_assert (!hb_unicode_compose (uf, 0xAC01, 0x11A8, &ab));
+
 
   /* Test decompose() */
 
@@ -796,16 +948,16 @@ main (int argc, char **argv)
   hb_test_add (test_unicode_properties_nil);
   hb_test_add (test_unicode_properties_empty);
 
-  hb_test_add_data_flavor (hb_unicode_funcs_get_default (),          "default", test_unicode_properties);
+  hb_test_add_data_flavor (hb_unicode_funcs_get_default (),          "default", test_unicode_properties_strict);
   hb_test_add_data_flavor (hb_unicode_funcs_get_default (),          "default", test_unicode_normalization);
   hb_test_add_data_flavor ((gconstpointer) script_roundtrip_default, "default", test_unicode_script_roundtrip);
 #ifdef HAVE_GLIB
-  hb_test_add_data_flavor (hb_glib_get_unicode_funcs (),             "glib",    test_unicode_properties);
+  hb_test_add_data_flavor (hb_glib_get_unicode_funcs (),             "glib",    test_unicode_properties_lenient);
   hb_test_add_data_flavor (hb_glib_get_unicode_funcs (),             "glib",    test_unicode_normalization);
   hb_test_add_data_flavor ((gconstpointer) script_roundtrip_glib,    "glib",    test_unicode_script_roundtrip);
 #endif
 #ifdef HAVE_ICU
-  hb_test_add_data_flavor (hb_icu_get_unicode_funcs (),              "icu",     test_unicode_properties);
+  hb_test_add_data_flavor (hb_icu_get_unicode_funcs (),              "icu",     test_unicode_properties_lenient);
   hb_test_add_data_flavor (hb_icu_get_unicode_funcs (),              "icu",     test_unicode_normalization);
   hb_test_add_data_flavor ((gconstpointer) script_roundtrip_icu,     "icu",     test_unicode_script_roundtrip);
 #endif
index a77df70..5bd2d7e 100644 (file)
@@ -55,8 +55,8 @@ hb_subset_fuzzer_CPPFLAGS = $(AM_CPPFLAGS)
 hb_subset_fuzzer_DEPENDENCIES = $(top_builddir)/src/libharfbuzz-subset.la
 
 check:
-       EXEEXT="$(EXEEXT)" srcdir="$(srcdir)" builddir="$(builddir)" $(srcdir)/run-shape-fuzzer-tests.py
-       EXEEXT="$(EXEEXT)" srcdir="$(srcdir)" builddir="$(builddir)" $(srcdir)/run-subset-fuzzer-tests.py
+       EXEEXT="$(EXEEXT)" srcdir="$(srcdir)" builddir="$(builddir)" LIBTOOL="$(LIBTOOL)" $(srcdir)/run-shape-fuzzer-tests.py
+       EXEEXT="$(EXEEXT)" srcdir="$(srcdir)" builddir="$(builddir)" LIBTOOL="$(LIBTOOL)" $(srcdir)/run-subset-fuzzer-tests.py
 check-valgrind:
        $(AM_V_at)RUN_VALGRIND=1 $(MAKE) $(AM_MAKEFLGS) check
 
index 6ecd679..d4e7ba3 100644 (file)
@@ -95,6 +95,7 @@ subdir = test/fuzzing
 ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
 am__aclocal_m4_deps = $(top_srcdir)/m4/ax_check_link_flag.m4 \
        $(top_srcdir)/m4/ax_code_coverage.m4 \
+       $(top_srcdir)/m4/ax_cxx_compile_stdcxx.m4 \
        $(top_srcdir)/m4/ax_pthread.m4 $(top_srcdir)/m4/gtk-doc.m4 \
        $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \
        $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \
@@ -253,6 +254,8 @@ FREETYPE_CFLAGS = @FREETYPE_CFLAGS@
 FREETYPE_DEPS = @FREETYPE_DEPS@
 FREETYPE_LIBS = @FREETYPE_LIBS@
 GCOV = @GCOV@
+GDI_CFLAGS = @GDI_CFLAGS@
+GDI_LIBS = @GDI_LIBS@
 GENHTML = @GENHTML@
 GIT = @GIT@
 GLIB_CFLAGS = @GLIB_CFLAGS@
@@ -271,6 +274,7 @@ GTKDOC_DEPS_CFLAGS = @GTKDOC_DEPS_CFLAGS@
 GTKDOC_DEPS_LIBS = @GTKDOC_DEPS_LIBS@
 GTKDOC_MKPDF = @GTKDOC_MKPDF@
 GTKDOC_REBASE = @GTKDOC_REBASE@
+HAVE_CXX11 = @HAVE_CXX11@
 HB_LIBTOOL_VERSION_INFO = @HB_LIBTOOL_VERSION_INFO@
 HB_VERSION = @HB_VERSION@
 HB_VERSION_MAJOR = @HB_VERSION_MAJOR@
@@ -803,8 +807,8 @@ $(top_builddir)/src/libharfbuzz.la: lib
 $(top_builddir)/src/libharfbuzz-subset.la: libs
 
 check:
-       EXEEXT="$(EXEEXT)" srcdir="$(srcdir)" builddir="$(builddir)" $(srcdir)/run-shape-fuzzer-tests.py
-       EXEEXT="$(EXEEXT)" srcdir="$(srcdir)" builddir="$(builddir)" $(srcdir)/run-subset-fuzzer-tests.py
+       EXEEXT="$(EXEEXT)" srcdir="$(srcdir)" builddir="$(builddir)" LIBTOOL="$(LIBTOOL)" $(srcdir)/run-shape-fuzzer-tests.py
+       EXEEXT="$(EXEEXT)" srcdir="$(srcdir)" builddir="$(builddir)" LIBTOOL="$(LIBTOOL)" $(srcdir)/run-subset-fuzzer-tests.py
 check-valgrind:
        $(AM_V_at)RUN_VALGRIND=1 $(MAKE) $(AM_MAKEFLGS) check
 
diff --git a/test/fuzzing/fonts/clusterfuzz-testcase-hb-subset-fuzzer-5717414645334016 b/test/fuzzing/fonts/clusterfuzz-testcase-hb-subset-fuzzer-5717414645334016
new file mode 100644 (file)
index 0000000..9cde3b9
Binary files /dev/null and b/test/fuzzing/fonts/clusterfuzz-testcase-hb-subset-fuzzer-5717414645334016 differ
diff --git a/test/fuzzing/fonts/clusterfuzz-testcase-minimized-harfbuzz_fuzzer-5093685255077888 b/test/fuzzing/fonts/clusterfuzz-testcase-minimized-harfbuzz_fuzzer-5093685255077888
new file mode 100644 (file)
index 0000000..e65025e
Binary files /dev/null and b/test/fuzzing/fonts/clusterfuzz-testcase-minimized-harfbuzz_fuzzer-5093685255077888 differ
diff --git a/test/fuzzing/fonts/clusterfuzz-testcase-minimized-harfbuzz_fuzzer-5702671124791296 b/test/fuzzing/fonts/clusterfuzz-testcase-minimized-harfbuzz_fuzzer-5702671124791296
new file mode 100644 (file)
index 0000000..9ecc7f1
Binary files /dev/null and b/test/fuzzing/fonts/clusterfuzz-testcase-minimized-harfbuzz_fuzzer-5702671124791296 differ
diff --git a/test/fuzzing/fonts/clusterfuzz-testcase-minimized-harfbuzz_fuzzer-6252118652092416 b/test/fuzzing/fonts/clusterfuzz-testcase-minimized-harfbuzz_fuzzer-6252118652092416
new file mode 100644 (file)
index 0000000..e2dd6a3
Binary files /dev/null and b/test/fuzzing/fonts/clusterfuzz-testcase-minimized-harfbuzz_fuzzer-6252118652092416 differ
diff --git a/test/fuzzing/fonts/clusterfuzz-testcase-minimized-hb-subset-fuzzer-5077547978588160 b/test/fuzzing/fonts/clusterfuzz-testcase-minimized-hb-subset-fuzzer-5077547978588160
new file mode 100644 (file)
index 0000000..37bb009
Binary files /dev/null and b/test/fuzzing/fonts/clusterfuzz-testcase-minimized-hb-subset-fuzzer-5077547978588160 differ
diff --git a/test/fuzzing/fonts/clusterfuzz-testcase-minimized-hb-subset-fuzzer-5634197349203968 b/test/fuzzing/fonts/clusterfuzz-testcase-minimized-hb-subset-fuzzer-5634197349203968
new file mode 100644 (file)
index 0000000..39e8bd9
Binary files /dev/null and b/test/fuzzing/fonts/clusterfuzz-testcase-minimized-hb-subset-fuzzer-5634197349203968 differ
diff --git a/test/fuzzing/fonts/clusterfuzz-testcase-minimized-hb-subset-fuzzer-5643107869917184 b/test/fuzzing/fonts/clusterfuzz-testcase-minimized-hb-subset-fuzzer-5643107869917184
new file mode 100644 (file)
index 0000000..b11bd87
Binary files /dev/null and b/test/fuzzing/fonts/clusterfuzz-testcase-minimized-hb-subset-fuzzer-5643107869917184 differ
diff --git a/test/fuzzing/fonts/clusterfuzz-testcase-minimized-hb-subset-fuzzer-5659903036751872 b/test/fuzzing/fonts/clusterfuzz-testcase-minimized-hb-subset-fuzzer-5659903036751872
new file mode 100644 (file)
index 0000000..51ab2fe
Binary files /dev/null and b/test/fuzzing/fonts/clusterfuzz-testcase-minimized-hb-subset-fuzzer-5659903036751872 differ
diff --git a/test/fuzzing/fonts/clusterfuzz-testcase-minimized-hb-subset-fuzzer-5667673584697344 b/test/fuzzing/fonts/clusterfuzz-testcase-minimized-hb-subset-fuzzer-5667673584697344
new file mode 100644 (file)
index 0000000..e08ab56
Binary files /dev/null and b/test/fuzzing/fonts/clusterfuzz-testcase-minimized-hb-subset-fuzzer-5667673584697344 differ
diff --git a/test/fuzzing/fonts/clusterfuzz-testcase-minimized-hb-subset-fuzzer-5675720390475776 b/test/fuzzing/fonts/clusterfuzz-testcase-minimized-hb-subset-fuzzer-5675720390475776
new file mode 100644 (file)
index 0000000..3881fbe
Binary files /dev/null and b/test/fuzzing/fonts/clusterfuzz-testcase-minimized-hb-subset-fuzzer-5675720390475776 differ
diff --git a/test/fuzzing/fonts/clusterfuzz-testcase-minimized-hb-subset-fuzzer-5676773460672512 b/test/fuzzing/fonts/clusterfuzz-testcase-minimized-hb-subset-fuzzer-5676773460672512
new file mode 100644 (file)
index 0000000..4fc920b
Binary files /dev/null and b/test/fuzzing/fonts/clusterfuzz-testcase-minimized-hb-subset-fuzzer-5676773460672512 differ
diff --git a/test/fuzzing/fonts/clusterfuzz-testcase-minimized-hb-subset-fuzzer-5677906231033856 b/test/fuzzing/fonts/clusterfuzz-testcase-minimized-hb-subset-fuzzer-5677906231033856
new file mode 100644 (file)
index 0000000..72147f6
Binary files /dev/null and b/test/fuzzing/fonts/clusterfuzz-testcase-minimized-hb-subset-fuzzer-5677906231033856 differ
diff --git a/test/fuzzing/fonts/clusterfuzz-testcase-minimized-hb-subset-fuzzer-5680398559870976 b/test/fuzzing/fonts/clusterfuzz-testcase-minimized-hb-subset-fuzzer-5680398559870976
new file mode 100644 (file)
index 0000000..5c7b6b5
Binary files /dev/null and b/test/fuzzing/fonts/clusterfuzz-testcase-minimized-hb-subset-fuzzer-5680398559870976 differ
diff --git a/test/fuzzing/fonts/clusterfuzz-testcase-minimized-hb-subset-fuzzer-5696825891225600 b/test/fuzzing/fonts/clusterfuzz-testcase-minimized-hb-subset-fuzzer-5696825891225600
new file mode 100644 (file)
index 0000000..30515a4
Binary files /dev/null and b/test/fuzzing/fonts/clusterfuzz-testcase-minimized-hb-subset-fuzzer-5696825891225600 differ
diff --git a/test/fuzzing/fonts/clusterfuzz-testcase-minimized-hb-subset-fuzzer-5716947896893440 b/test/fuzzing/fonts/clusterfuzz-testcase-minimized-hb-subset-fuzzer-5716947896893440
new file mode 100644 (file)
index 0000000..6391320
Binary files /dev/null and b/test/fuzzing/fonts/clusterfuzz-testcase-minimized-hb-subset-fuzzer-5716947896893440 differ
diff --git a/test/fuzzing/fonts/clusterfuzz-testcase-minimized-hb-subset-fuzzer-5721073428987904 b/test/fuzzing/fonts/clusterfuzz-testcase-minimized-hb-subset-fuzzer-5721073428987904
new file mode 100644 (file)
index 0000000..683ef99
Binary files /dev/null and b/test/fuzzing/fonts/clusterfuzz-testcase-minimized-hb-subset-fuzzer-5721073428987904 differ
diff --git a/test/fuzzing/fonts/clusterfuzz-testcase-minimized-hb-subset-fuzzer-5728664968232960 b/test/fuzzing/fonts/clusterfuzz-testcase-minimized-hb-subset-fuzzer-5728664968232960
new file mode 100644 (file)
index 0000000..e099413
Binary files /dev/null and b/test/fuzzing/fonts/clusterfuzz-testcase-minimized-hb-subset-fuzzer-5728664968232960 differ
diff --git a/test/fuzzing/fonts/clusterfuzz-testcase-minimized-hb-subset-fuzzer-5738978499624960 b/test/fuzzing/fonts/clusterfuzz-testcase-minimized-hb-subset-fuzzer-5738978499624960
new file mode 100644 (file)
index 0000000..0264a15
Binary files /dev/null and b/test/fuzzing/fonts/clusterfuzz-testcase-minimized-hb-subset-fuzzer-5738978499624960 differ
diff --git a/test/fuzzing/fonts/clusterfuzz-testcase-minimized-hb-subset-fuzzer-5754526379802624 b/test/fuzzing/fonts/clusterfuzz-testcase-minimized-hb-subset-fuzzer-5754526379802624
new file mode 100644 (file)
index 0000000..3a7cc9d
Binary files /dev/null and b/test/fuzzing/fonts/clusterfuzz-testcase-minimized-hb-subset-fuzzer-5754526379802624 differ
diff --git a/test/fuzzing/fonts/clusterfuzz-testcase-minimized-hb-subset-fuzzer-5761434614497280 b/test/fuzzing/fonts/clusterfuzz-testcase-minimized-hb-subset-fuzzer-5761434614497280
new file mode 100644 (file)
index 0000000..0060ade
Binary files /dev/null and b/test/fuzzing/fonts/clusterfuzz-testcase-minimized-hb-subset-fuzzer-5761434614497280 differ
diff --git a/test/fuzzing/fonts/clusterfuzz-testcase-minimized-hb-subset-fuzzer-5763024094232576 b/test/fuzzing/fonts/clusterfuzz-testcase-minimized-hb-subset-fuzzer-5763024094232576
new file mode 100644 (file)
index 0000000..da1b718
Binary files /dev/null and b/test/fuzzing/fonts/clusterfuzz-testcase-minimized-hb-subset-fuzzer-5763024094232576 differ
diff --git a/test/fuzzing/fonts/clusterfuzz-testcase-minimized-hb-subset-fuzzer-5923632099885056 b/test/fuzzing/fonts/clusterfuzz-testcase-minimized-hb-subset-fuzzer-5923632099885056
new file mode 100644 (file)
index 0000000..0a3c6df
Binary files /dev/null and b/test/fuzzing/fonts/clusterfuzz-testcase-minimized-hb-subset-fuzzer-5923632099885056 differ
index 5723db9..64a6b12 100644 (file)
@@ -10,7 +10,7 @@
 extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size)
 {
   hb_blob_t *blob = hb_blob_create ((const char *)data, size,
-                                   HB_MEMORY_MODE_READONLY, NULL, NULL);
+                                   HB_MEMORY_MODE_READONLY, nullptr, nullptr);
   hb_face_t *face = hb_face_create (blob, 0);
   hb_font_t *font = hb_font_create (face);
   hb_ot_font_set_funcs (font);
@@ -21,7 +21,7 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size)
     hb_buffer_t *buffer = hb_buffer_create ();
     hb_buffer_add_utf8 (buffer, text, -1, 0, -1);
     hb_buffer_guess_segment_properties (buffer);
-    hb_shape (font, buffer, NULL, 0);
+    hb_shape (font, buffer, nullptr, 0);
     hb_buffer_destroy (buffer);
   }
 
@@ -34,7 +34,7 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size)
   hb_buffer_t *buffer = hb_buffer_create ();
   hb_buffer_add_utf32 (buffer, text32, sizeof (text32) / sizeof (text32[0]), 0, -1);
   hb_buffer_guess_segment_properties (buffer);
-  hb_shape (font, buffer, NULL, 0);
+  hb_shape (font, buffer, nullptr, 0);
   hb_buffer_destroy (buffer);
 
   /* Misc calls on face. */
index 56ffd22..428765e 100644 (file)
@@ -3,6 +3,7 @@
 #include <stdlib.h>
 #include <stdio.h>
 #include <string.h>
+#include <assert.h>
 
 #include "hb-subset.h"
 
@@ -16,16 +17,35 @@ trySubset (hb_face_t *face,
 {
   hb_subset_input_t *input = hb_subset_input_create_or_fail ();
   hb_subset_input_set_drop_hints (input, drop_hints);
-  hb_subset_input_set_drop_layout (input, drop_layout);
   hb_subset_input_set_retain_gids (input, retain_gids);
   hb_set_t *codepoints = hb_subset_input_unicode_set (input);
 
+  if (!drop_layout)
+  {
+    hb_set_del (hb_subset_input_drop_tables_set (input), HB_TAG ('G', 'S', 'U', 'B'));
+    hb_set_del (hb_subset_input_drop_tables_set (input), HB_TAG ('G', 'P', 'O', 'S'));
+    hb_set_del (hb_subset_input_drop_tables_set (input), HB_TAG ('G', 'D', 'E', 'F'));
+  }
+
   for (int i = 0; i < text_length; i++)
   {
     hb_set_add (codepoints, text[i]);
   }
 
   hb_face_t *result = hb_subset (face, input);
+  {
+    hb_blob_t *blob = hb_face_reference_blob (result);
+    unsigned int length;
+    const char *data = hb_blob_get_data (blob, &length);
+
+    // Something not optimizable just to access all the blob data
+    unsigned int bytes_count = 0;
+    for (unsigned int i = 0; i < length; ++i)
+      if (data[i]) ++bytes_count;
+    assert (bytes_count || !length);
+
+    hb_blob_destroy (blob);
+  }
   hb_face_destroy (result);
 
   hb_subset_input_destroy (input);
@@ -47,7 +67,7 @@ trySubset (hb_face_t *face,
 extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size)
 {
   hb_blob_t *blob = hb_blob_create ((const char *)data, size,
-                                   HB_MEMORY_MODE_READONLY, NULL, NULL);
+                                   HB_MEMORY_MODE_READONLY, nullptr, nullptr);
   hb_face_t *face = hb_face_create (blob, 0);
 
   /* Just test this API here quickly. */
index f15247c..5318f64 100644 (file)
@@ -4,8 +4,10 @@
 #include <stdlib.h>
 #include <assert.h>
 
-int main(int argc, char **argv) {
+int main (int argc, char **argv)
+{
   hb_blob_t *blob = hb_blob_create_from_file (argv[1]);
+
   unsigned int len;
   const char *font_data = hb_blob_get_data (blob, &len);
   if (len == 0)
@@ -14,10 +16,13 @@ int main(int argc, char **argv) {
     exit (1);
   }
 
-  for (int i = 1; i < argc; i++) {
+  for (int i = 1; i < argc; i++)
+  {
     printf ("%s\n", argv[i]);
-    LLVMFuzzerTestOneInput((const uint8_t *) font_data, len);
+    LLVMFuzzerTestOneInput ((const uint8_t *) font_data, len);
   }
 
   hb_blob_destroy (blob);
+
+  return 0;
 }
index e3d180f..94fc877 100755 (executable)
@@ -5,41 +5,47 @@ from __future__ import print_function, division, absolute_import
 import sys, os, subprocess, tempfile, threading
 
 
-def which(program):
+def which (program):
        # https://stackoverflow.com/a/377028
-       def is_exe(fpath):
-               return os.path.isfile(fpath) and os.access(fpath, os.X_OK)
+       def is_exe (fpath):
+               return os.path.isfile (fpath) and os.access (fpath, os.X_OK)
 
-       fpath, _ = os.path.split(program)
+       fpath, _ = os.path.split (program)
        if fpath:
-               if is_exe(program):
+               if is_exe (program):
                        return program
        else:
-               for path in os.environ["PATH"].split(os.pathsep):
-                       exe_file = os.path.join(path, program)
-                       if is_exe(exe_file):
+               for path in os.environ["PATH"].split (os.pathsep):
+                       exe_file = os.path.join (path, program)
+                       if is_exe (exe_file):
                                return exe_file
 
        return None
 
 
-def cmd(command):
+def cmd (command):
        # https://stackoverflow.com/a/4408409
        # https://stackoverflow.com/a/10012262
-       with tempfile.TemporaryFile() as tempf:
+       with tempfile.TemporaryFile () as tempf:
                p = subprocess.Popen (command, stderr=tempf)
                is_killed = {'value': False}
 
-               def timeout(p, is_killed):
+               def timeout (p, is_killed):
                        is_killed['value'] = True
-                       p.kill()
-               timer = threading.Timer (2, timeout, [p, is_killed])
+                       p.kill ()
+               timeout_seconds = int (os.environ.get ("HB_TEST_SHAPE_FUZZER_TIMEOUT", "2"))
+               timer = threading.Timer (timeout_seconds, timeout, [p, is_killed])
 
                try:
                        timer.start()
                        p.wait ()
                        tempf.seek (0)
-                       text = tempf.read().decode ("utf-8").strip ()
+                       text = tempf.read ()
+
+                       #TODO: Detect debug mode with a better way
+                       is_debug_mode = b"SANITIZE" in text
+
+                       text = "" if is_debug_mode else text.decode ("utf-8").strip ()
                        returncode = p.returncode
                finally:
                        timer.cancel()
@@ -67,33 +73,36 @@ please provide it as the first argument to the tool""")
 print ('hb_shape_fuzzer:', hb_shape_fuzzer)
 fails = 0
 
+libtool = os.environ.get ('LIBTOOL')
 valgrind = None
-if os.environ.get('RUN_VALGRIND', ''):
+if os.environ.get ('RUN_VALGRIND', ''):
        valgrind = which ('valgrind')
+       if valgrind is None:
+               print ("""Valgrind requested but not found.""")
+               sys.exit (1)
+       if libtool is None:
+               print ("""Valgrind support is currently autotools only and needs libtool but not found.""")
+
 
 parent_path = os.path.join (srcdir, "fonts")
 for file in os.listdir (parent_path):
-       path = os.path.join(parent_path, file)
+       path = os.path.join (parent_path, file)
+
+       if valgrind:
+               text, returncode = cmd (libtool.split(' ') + ['--mode=execute', valgrind + ' --leak-check=full --error-exitcode=1', '--', hb_shape_fuzzer, path])
+       else:
+               text, returncode = cmd ([hb_shape_fuzzer, path])
+               if 'error' in text:
+                       returncode = 1
 
-       text, returncode = cmd ([hb_shape_fuzzer, path])
-       if text.strip ():
+       if (not valgrind or returncode) and text.strip ():
                print (text)
 
-       failed = False
-       if returncode != 0 or 'error' in text:
+       if returncode != 0:
                print ('failure on %s' % file)
-               failed = True
-
-       if valgrind:
-               text, returncode = cmd ([valgrind, '--error-exitcode=1', hb_shape_fuzzer, path])
-               if returncode:
-                       print (text)
-                       print ('failure on %s' % file)
-                       failed = True
-
-       if failed:
                fails = fails + 1
 
+
 if fails:
        print ("%i shape fuzzer related tests failed." % fails)
        sys.exit (1)
index 7392a92..f290e6e 100755 (executable)
@@ -2,7 +2,60 @@
 
 from __future__ import print_function, division, absolute_import
 
-import sys, os, subprocess
+import sys, os, subprocess, tempfile, threading
+
+
+def which(program):
+       # https://stackoverflow.com/a/377028
+       def is_exe(fpath):
+               return os.path.isfile(fpath) and os.access(fpath, os.X_OK)
+
+       fpath, _ = os.path.split(program)
+       if fpath:
+               if is_exe(program):
+                       return program
+       else:
+               for path in os.environ["PATH"].split(os.pathsep):
+                       exe_file = os.path.join(path, program)
+                       if is_exe(exe_file):
+                               return exe_file
+
+       return None
+
+
+def cmd(command):
+       # https://stackoverflow.com/a/4408409
+       # https://stackoverflow.com/a/10012262
+       with tempfile.TemporaryFile() as tempf:
+               p = subprocess.Popen (command, stderr=tempf)
+               is_killed = {'value': False}
+
+               def timeout(p, is_killed):
+                       is_killed['value'] = True
+                       p.kill()
+               timeout_seconds = int (os.environ.get ("HB_TEST_SUBSET_FUZZER_TIMEOUT", "8"))
+               timer = threading.Timer (timeout_seconds, timeout, [p, is_killed])
+
+               try:
+                       timer.start()
+                       p.wait ()
+                       tempf.seek (0)
+                       text = tempf.read ()
+
+                       #TODO: Detect debug mode with a better way
+                       is_debug_mode = b"SANITIZE" in text
+
+                       text = "" if is_debug_mode else text.decode ("utf-8").strip ()
+                       returncode = p.returncode
+               finally:
+                       timer.cancel()
+
+               if is_killed['value']:
+                       text = 'error: timeout, ' + text
+                       returncode = 1
+
+               return text, returncode
+
 
 srcdir = os.environ.get ("srcdir", ".")
 EXEEXT = os.environ.get ("EXEEXT", "")
@@ -20,25 +73,42 @@ please provide it as the first argument to the tool""")
 print ('hb_subset_fuzzer:', hb_subset_fuzzer)
 fails = 0
 
+libtool = os.environ.get('LIBTOOL')
+valgrind = None
+if os.environ.get('RUN_VALGRIND', ''):
+       valgrind = which ('valgrind')
+       if valgrind is None:
+               print ("""Valgrind requested but not found.""")
+               sys.exit (1)
+       if libtool is None:
+               print ("""Valgrind support is currently autotools only and needs libtool but not found.""")
+
+
 def run_dir (parent_path):
        global fails
        for file in os.listdir (parent_path):
                path = os.path.join(parent_path, file)
+               # TODO: Run on all the fonts not just subset related ones
+               if "subset" not in path: continue
 
                print ("running subset fuzzer against %s" % path)
-               p = subprocess.Popen ([hb_subset_fuzzer, path])
+               if valgrind:
+                       text, returncode = cmd (libtool.split(' ') + ['--mode=execute', valgrind + ' --leak-check=full --show-leak-kinds=all --error-exitcode=1', '--', hb_subset_fuzzer, path])
+               else:
+                       text, returncode = cmd ([hb_subset_fuzzer, path])
+                       if 'error' in text:
+                               returncode = 1
 
-               if p.wait () != 0:
-                       print ("failed for %s" % path)
-                       fails = fails + 1
+               if (not valgrind or returncode) and text.strip ():
+                       print (text)
 
-               if p.wait () != 0:
+               if returncode != 0:
                        print ("failed for %s" % path)
                        fails = fails + 1
 
+
 run_dir (os.path.join (srcdir, "..", "subset", "data", "fonts"))
-# TODO running these tests very slow tests.  Fix and re-enable
-#run_dir (os.path.join (srcdir, "fonts"))
+run_dir (os.path.join (srcdir, "fonts"))
 
 if fails:
         print ("%i subset fuzzer related tests failed." % fails)
index 0e0237a..fb952e1 100644 (file)
@@ -93,6 +93,7 @@ subdir = test/shaping
 ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
 am__aclocal_m4_deps = $(top_srcdir)/m4/ax_check_link_flag.m4 \
        $(top_srcdir)/m4/ax_code_coverage.m4 \
+       $(top_srcdir)/m4/ax_cxx_compile_stdcxx.m4 \
        $(top_srcdir)/m4/ax_pthread.m4 $(top_srcdir)/m4/gtk-doc.m4 \
        $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \
        $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \
@@ -235,6 +236,8 @@ FREETYPE_CFLAGS = @FREETYPE_CFLAGS@
 FREETYPE_DEPS = @FREETYPE_DEPS@
 FREETYPE_LIBS = @FREETYPE_LIBS@
 GCOV = @GCOV@
+GDI_CFLAGS = @GDI_CFLAGS@
+GDI_LIBS = @GDI_LIBS@
 GENHTML = @GENHTML@
 GIT = @GIT@
 GLIB_CFLAGS = @GLIB_CFLAGS@
@@ -253,6 +256,7 @@ GTKDOC_DEPS_CFLAGS = @GTKDOC_DEPS_CFLAGS@
 GTKDOC_DEPS_LIBS = @GTKDOC_DEPS_LIBS@
 GTKDOC_MKPDF = @GTKDOC_MKPDF@
 GTKDOC_REBASE = @GTKDOC_REBASE@
+HAVE_CXX11 = @HAVE_CXX11@
 HB_LIBTOOL_VERSION_INFO = @HB_LIBTOOL_VERSION_INFO@
 HB_VERSION = @HB_VERSION@
 HB_VERSION_MAJOR = @HB_VERSION_MAJOR@
index 1170e86..8a1562c 100644 (file)
@@ -93,6 +93,7 @@ subdir = test/shaping/data
 ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
 am__aclocal_m4_deps = $(top_srcdir)/m4/ax_check_link_flag.m4 \
        $(top_srcdir)/m4/ax_code_coverage.m4 \
+       $(top_srcdir)/m4/ax_cxx_compile_stdcxx.m4 \
        $(top_srcdir)/m4/ax_pthread.m4 $(top_srcdir)/m4/gtk-doc.m4 \
        $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \
        $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \
@@ -235,6 +236,8 @@ FREETYPE_CFLAGS = @FREETYPE_CFLAGS@
 FREETYPE_DEPS = @FREETYPE_DEPS@
 FREETYPE_LIBS = @FREETYPE_LIBS@
 GCOV = @GCOV@
+GDI_CFLAGS = @GDI_CFLAGS@
+GDI_LIBS = @GDI_LIBS@
 GENHTML = @GENHTML@
 GIT = @GIT@
 GLIB_CFLAGS = @GLIB_CFLAGS@
@@ -253,6 +256,7 @@ GTKDOC_DEPS_CFLAGS = @GTKDOC_DEPS_CFLAGS@
 GTKDOC_DEPS_LIBS = @GTKDOC_DEPS_LIBS@
 GTKDOC_MKPDF = @GTKDOC_MKPDF@
 GTKDOC_REBASE = @GTKDOC_REBASE@
+HAVE_CXX11 = @HAVE_CXX11@
 HB_LIBTOOL_VERSION_INFO = @HB_LIBTOOL_VERSION_INFO@
 HB_VERSION = @HB_VERSION@
 HB_VERSION_MAJOR = @HB_VERSION_MAJOR@
index 3e94bb3..3b0ab1f 100644 (file)
@@ -194,6 +194,7 @@ subdir = test/shaping/data/aots
 ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
 am__aclocal_m4_deps = $(top_srcdir)/m4/ax_check_link_flag.m4 \
        $(top_srcdir)/m4/ax_code_coverage.m4 \
+       $(top_srcdir)/m4/ax_cxx_compile_stdcxx.m4 \
        $(top_srcdir)/m4/ax_pthread.m4 $(top_srcdir)/m4/gtk-doc.m4 \
        $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \
        $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \
@@ -479,6 +480,8 @@ FREETYPE_CFLAGS = @FREETYPE_CFLAGS@
 FREETYPE_DEPS = @FREETYPE_DEPS@
 FREETYPE_LIBS = @FREETYPE_LIBS@
 GCOV = @GCOV@
+GDI_CFLAGS = @GDI_CFLAGS@
+GDI_LIBS = @GDI_LIBS@
 GENHTML = @GENHTML@
 GIT = @GIT@
 GLIB_CFLAGS = @GLIB_CFLAGS@
@@ -497,6 +500,7 @@ GTKDOC_DEPS_CFLAGS = @GTKDOC_DEPS_CFLAGS@
 GTKDOC_DEPS_LIBS = @GTKDOC_DEPS_LIBS@
 GTKDOC_MKPDF = @GTKDOC_MKPDF@
 GTKDOC_REBASE = @GTKDOC_REBASE@
+HAVE_CXX11 = @HAVE_CXX11@
 HB_LIBTOOL_VERSION_INFO = @HB_LIBTOOL_VERSION_INFO@
 HB_VERSION = @HB_VERSION@
 HB_VERSION_MAJOR = @HB_VERSION_MAJOR@
index eb50742..86d887e 100644 (file)
@@ -112,9 +112,9 @@ TESTS = tests/aat-trak.tests tests/aat-morx.tests \
        tests/mark-attachment.tests tests/mark-filtering-sets.tests \
        tests/mongolian-variation-selector.tests \
        tests/myanmar-syllable.tests tests/myanmar-zawgyi.tests \
-       tests/none-directional.tests tests/rand.tests \
-       tests/spaces.tests tests/simple.tests tests/sinhala.tests \
-       tests/tibetan-contractions-1.tests \
+       tests/none-directional.tests tests/positioning-features.tests \
+       tests/rand.tests tests/spaces.tests tests/simple.tests \
+       tests/sinhala.tests tests/tibetan-contractions-1.tests \
        tests/tibetan-contractions-2.tests tests/tibetan-vowels.tests \
        tests/use.tests tests/use-indic3.tests tests/use-marchen.tests \
        tests/use-syllable.tests tests/variations-rvrn.tests \
@@ -124,6 +124,7 @@ subdir = test/shaping/data/in-house
 ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
 am__aclocal_m4_deps = $(top_srcdir)/m4/ax_check_link_flag.m4 \
        $(top_srcdir)/m4/ax_code_coverage.m4 \
+       $(top_srcdir)/m4/ax_cxx_compile_stdcxx.m4 \
        $(top_srcdir)/m4/ax_pthread.m4 $(top_srcdir)/m4/gtk-doc.m4 \
        $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \
        $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \
@@ -409,6 +410,8 @@ FREETYPE_CFLAGS = @FREETYPE_CFLAGS@
 FREETYPE_DEPS = @FREETYPE_DEPS@
 FREETYPE_LIBS = @FREETYPE_LIBS@
 GCOV = @GCOV@
+GDI_CFLAGS = @GDI_CFLAGS@
+GDI_LIBS = @GDI_LIBS@
 GENHTML = @GENHTML@
 GIT = @GIT@
 GLIB_CFLAGS = @GLIB_CFLAGS@
@@ -427,6 +430,7 @@ GTKDOC_DEPS_CFLAGS = @GTKDOC_DEPS_CFLAGS@
 GTKDOC_DEPS_LIBS = @GTKDOC_DEPS_LIBS@
 GTKDOC_MKPDF = @GTKDOC_MKPDF@
 GTKDOC_REBASE = @GTKDOC_REBASE@
+HAVE_CXX11 = @HAVE_CXX11@
 HB_LIBTOOL_VERSION_INFO = @HB_LIBTOOL_VERSION_INFO@
 HB_VERSION = @HB_VERSION@
 HB_VERSION_MAJOR = @HB_VERSION_MAJOR@
index 0e9a3a2..bf14a98 100644 (file)
@@ -41,6 +41,7 @@ TESTS = \
        tests/myanmar-syllable.tests \
        tests/myanmar-zawgyi.tests \
        tests/none-directional.tests \
+       tests/positioning-features.tests \
        tests/rand.tests \
        tests/spaces.tests \
        tests/simple.tests \
diff --git a/test/shaping/data/in-house/fonts/3cc01fede4debd4b7794ccb1b16cdb9987ea7571.ttf b/test/shaping/data/in-house/fonts/3cc01fede4debd4b7794ccb1b16cdb9987ea7571.ttf
new file mode 100644 (file)
index 0000000..945d698
Binary files /dev/null and b/test/shaping/data/in-house/fonts/3cc01fede4debd4b7794ccb1b16cdb9987ea7571.ttf differ
diff --git a/test/shaping/data/in-house/fonts/53a91c20e33a596f2be17fb68b382d6b7eb85d5c.ttf b/test/shaping/data/in-house/fonts/53a91c20e33a596f2be17fb68b382d6b7eb85d5c.ttf
new file mode 100644 (file)
index 0000000..f3d52e5
Binary files /dev/null and b/test/shaping/data/in-house/fonts/53a91c20e33a596f2be17fb68b382d6b7eb85d5c.ttf differ
diff --git a/test/shaping/data/in-house/fonts/ea3f63620511b2097200d23774ffef197e829e69.ttf b/test/shaping/data/in-house/fonts/ea3f63620511b2097200d23774ffef197e829e69.ttf
new file mode 100644 (file)
index 0000000..31d4e50
Binary files /dev/null and b/test/shaping/data/in-house/fonts/ea3f63620511b2097200d23774ffef197e829e69.ttf differ
diff --git a/test/shaping/data/in-house/fonts/f79eb71df4e4c9c273b67b89a06e5ff9e3c1f834.ttf b/test/shaping/data/in-house/fonts/f79eb71df4e4c9c273b67b89a06e5ff9e3c1f834.ttf
new file mode 100644 (file)
index 0000000..be48fd0
Binary files /dev/null and b/test/shaping/data/in-house/fonts/f79eb71df4e4c9c273b67b89a06e5ff9e3c1f834.ttf differ
diff --git a/test/shaping/data/in-house/fonts/fcbaa518d3cce441ed37ae3b1fed6a19e9b54efd.ttf b/test/shaping/data/in-house/fonts/fcbaa518d3cce441ed37ae3b1fed6a19e9b54efd.ttf
new file mode 100644 (file)
index 0000000..b1a8a33
Binary files /dev/null and b/test/shaping/data/in-house/fonts/fcbaa518d3cce441ed37ae3b1fed6a19e9b54efd.ttf differ
index 4bbe729..6da3ba8 100644 (file)
@@ -1,11 +1,11 @@
 ../fonts/TRAK.ttf::U+0041,U+0042,U+0043:[A.alt=0+1000|B=1+1000|C.alt=2+1000]
 ../fonts/TRAK.ttf:--font-ptem=.5:U+0041,U+0042,U+0043:[A.alt=0@100,0+1200|B=1@100,0+1200|C.alt=2@100,0+1200]
 ../fonts/TRAK.ttf:--font-ptem=1:U+0041,U+0042,U+0043:[A.alt=0@100,0+1200|B=1@100,0+1200|C.alt=2@100,0+1200]
-../fonts/TRAK.ttf:--font-ptem=2:U+0041,U+0042,U+0043:[A.alt=0@93,0+1187|B=1@93,0+1187|C.alt=2@93,0+1187]
-../fonts/TRAK.ttf:--font-ptem=9:U+0041,U+0042,U+0043:[A.alt=0+1000|B=1+1000|C.alt=2+1000]
-../fonts/TRAK.ttf:--font-ptem=24:U+0041,U+0042,U+0043:[A.alt=0@-12,0+976|B=1@-12,0+976|C.alt=2@-12,0+976]
-../fonts/TRAK.ttf:--font-ptem=72:U+0041,U+0042,U+0043:[A.alt=0@-50,0+900|B=1@-50,0+900|C.alt=2@-50,0+900]
-../fonts/TRAK.ttf:--font-ptem=144:U+0041,U+0042,U+0043:[A.alt=0@-107,0+786|B=1@-107,0+786|C.alt=2@-107,0+786]
-../fonts/TRAK.ttf:--font-ptem=144:U+0041,U+0042,U+0043:[A.alt=0@-107,0+786|B=1@-107,0+786|C.alt=2@-107,0+786]
+../fonts/TRAK.ttf:--font-ptem=2:U+0041,U+0042,U+0043:[A.alt=0@100,0+1200|B=1@100,0+1200|C.alt=2@100,0+1200]
+../fonts/TRAK.ttf:--font-ptem=9:U+0041,U+0042,U+0043:[A.alt=0@30,0+1060|B=1@30,0+1060|C.alt=2@30,0+1060]
+../fonts/TRAK.ttf:--font-ptem=24:U+0041,U+0042,U+0043:[A.alt=0@-7,0+986|B=1@-7,0+986|C.alt=2@-7,0+986]
+../fonts/TRAK.ttf:--font-ptem=72:U+0041,U+0042,U+0043:[A.alt=0@-35,0+929|B=1@-35,0+929|C.alt=2@-35,0+929]
+../fonts/TRAK.ttf:--font-ptem=144:U+0041,U+0042,U+0043:[A.alt=0@-78,0+843|B=1@-78,0+843|C.alt=2@-78,0+843]
+../fonts/TRAK.ttf:--font-ptem=144:U+0041,U+0042,U+0043:[A.alt=0@-78,0+843|B=1@-78,0+843|C.alt=2@-78,0+843]
 ../fonts/TRAK.ttf:--font-ptem=144 --features=-trak:U+0041,U+0042,U+0043:[A.alt=0+1000|B=1+1000|C.alt=2+1000]
-../fonts/TRAK.ttf:--font-ptem=144 --features=-trak[1;3]:U+0041,U+0042,U+0043,U+0041,U+0042,U+0043:[A.alt=0@-107,0+786|B=1+1000|C.alt=2+1000|A.alt=3@-107,0+786|B=4@-107,0+786|C.alt=5@-107,0+786]
+../fonts/TRAK.ttf:--font-ptem=144 --features=-trak[1;3]:U+0041,U+0042,U+0043,U+0041,U+0042,U+0043:[A.alt=0@-78,0+843|B=1+1000|C.alt=2+1000|A.alt=3@-78,0+843|B=4@-78,0+843|C.alt=5@-78,0+843]
index b325d78..bf0005c 100644 (file)
@@ -1 +1,2 @@
 ../fonts/ee39587d13b2afa5499cc79e45780aa79293bbd4.ttf:--font-funcs=ot --show-extents:U+1F42F:[gid1=0+2963<0,2179,2963,-2789>]
+../fonts/fcbaa518d3cce441ed37ae3b1fed6a19e9b54efd.ttf:--font-funcs=ot --show-extents:U+1F600:[gid4=0+2550<0,1898,2555,-2405>]
index db4a31d..434e0a5 100644 (file)
@@ -13,7 +13,7 @@
 /System/Library/Fonts/GeezaPro.ttc@f43ee7151c2e9f1dddfbc26cfc148609eb5c5820:--font-funcs ot:U+0631,U+0628:[u0628.beh=1+1415|u0631.reh=0@-202,0+700]
 /System/Library/Fonts/GeezaPro.ttc@f43ee7151c2e9f1dddfbc26cfc148609eb5c5820:--font-funcs ot:U+0628,U+064F:[u064f.damma=0@250,-250+250|u0628.beh=0@-250,0+1165]
 /System/Library/Fonts/SFNSDisplay.ttf@92787c30716672737e9059bc367c15d04fbc1ced:--font-funcs ot:U+0054,U+0065,U+0020,U+0041,U+0056,U+0020,U+0054,U+0072,U+0020,U+0056,U+0061,U+0020,U+0072,U+0054,U+0020,U+0065,U+0054,U+0020,U+0054,U+0064:[gid225=0+1105|gid584=1@-105,0+979|gid3=2+490|gid4=3+1227|gid265=4@-65,0+1227|gid3=5+490|gid225=6+1130|gid728=7@-80,0+569|gid3=8+490|gid265=9+1227|gid505=10@-65,0+997|gid3=11+490|gid728=12+609|gid225=13@-40,0+1170|gid3=14+490|gid584=15+1004|gid225=16@-80,0+1130|gid3=17+490|gid225=18+1105|gid576=19@-105,0+1068]
-/System/Library/Fonts/SFNSDisplay.ttf@92787c30716672737e9059bc367c15d04fbc1ced:--font-ptem 9 --font-funcs ot:U+0054,U+0065,U+0020,U+0041,U+0056,U+0020,U+0054,U+0072,U+0020,U+0056,U+0061,U+0020,U+0072,U+0054,U+0020,U+0065,U+0054,U+0020,U+0054,U+0064:[gid225=0@46,0+1197|gid584=1@-59,0+1071|gid3=2@46,0+582|gid4=3@46,0+1319|gid265=4@-19,0+1319|gid3=5@46,0+582|gid225=6@46,0+1222|gid728=7@-34,0+661|gid3=8@46,0+582|gid265=9@46,0+1319|gid505=10@-19,0+1089|gid3=11@46,0+582|gid728=12@46,0+701|gid225=13@6,0+1262|gid3=14@46,0+582|gid584=15@46,0+1096|gid225=16@-34,0+1222|gid3=17@46,0+582|gid225=18@46,0+1197|gid576=19@-59,0+1160]
+/System/Library/Fonts/SFNSDisplay.ttf@92787c30716672737e9059bc367c15d04fbc1ced:--font-ptem 9 --font-funcs ot:U+0054,U+0065,U+0020,U+0041,U+0056,U+0020,U+0054,U+0072,U+0020,U+0056,U+0061,U+0020,U+0072,U+0054,U+0020,U+0065,U+0054,U+0020,U+0054,U+0064:[gid225=0@65,0+1235|gid584=1@-40,0+1109|gid3=2@65,0+620|gid4=3@65,0+1357|gid265=4+1357|gid3=5@65,0+620|gid225=6@65,0+1260|gid728=7@-15,0+699|gid3=8@65,0+620|gid265=9@65,0+1357|gid505=10+1127|gid3=11@65,0+620|gid728=12@65,0+739|gid225=13@25,0+1300|gid3=14@65,0+620|gid584=15@65,0+1134|gid225=16@-15,0+1260|gid3=17@65,0+620|gid225=18@65,0+1235|gid576=19@-40,0+1198]
 /System/Library/Fonts/Apple Color Emoji.ttc@d2fe8a134483aa48a43a9d1e4b7204d37a4abdf5:--remove-default-ignorables --font-funcs ot:U+1F468,U+200D,U+1F469,U+200D,U+1F467,U+200D,U+1F466:[u1F46A.MWGB=0+800]
 /Library/Fonts/Zapfino.ttf@9ee799ffb09516ead6b0cf6f2ca807276e150748:--font-funcs ot:U+005A,U+0061,U+0070,U+0066,U+0069,U+006E,U+005A,U+0061,U+0070,U+0066,U+0069,U+006E,U+005A,U+0061,U+0070,U+0066,U+0069,U+006E,U+005A,U+0061,U+0070,U+0066,U+0069,U+006E,U+005A,U+0061,U+0070,U+0066,U+0069,U+006E,U+005A,U+0061,U+0070,U+0066,U+0069,U+006E,U+005A,U+0061,U+0070,U+0066,U+0069,U+006E,U+005A,U+0061,U+0070,U+0066,U+0069,U+006E,U+005A,U+0061,U+0070,U+0066,U+0069,U+006E,U+005A,U+0061,U+0070,U+0066,U+0069,U+006E,U+005A,U+0061,U+0070,U+0066,U+0069,U+006E,U+005A,U+0061,U+0070,U+0066,U+0069,U+006E,U+006F:[Z=0+416|a=1@-21,0+264|p_f=2+433|i=4+181|n=5+261|Z=6+416|a=7@-21,0+264|p_f=8+433|i=10+181|n=11+261|Z=12+416|a=13@-21,0+264|p_f=14+433|i=16+181|n=17+261|Z=18+416|a=19@-21,0+264|p_f=20+433|i=22+181|n=23+261|Z=24+416|a=25@-21,0+264|p_f=26+433|i=28+181|n=29+261|Z=30+416|a=31@-21,0+264|p_f=32+433|i=34+181|n=35+261|Z=36+416|a=37@-21,0+264|p_f=38+433|i=40+181|n=41+261|Z=42+416|a=43@-21,0+264|p_f=44+433|i=46+181|n=47+261|Z=48+416|a=49@-21,0+264|p_f=50+433|i=52+181|n=53+261|Z=54+416|a=55@-21,0+264|p_f=56+433|i=58+181|n=59+261|Z=60+416|a=61@-21,0+264|p_f=62+433|i=64+181|n=65+261|Z_a_p_f_i_n_o=66+2333]
 
@@ -32,7 +32,7 @@
 /System/Library/Fonts/GeezaPro.ttc@ab26ea45dcaa5e1c5a958e42af10e10d330e7334:--font-funcs ot:U+0631,U+0628:[u0628.beh=1+1415|u0631.reh=0@-202,0+700]
 /System/Library/Fonts/GeezaPro.ttc@ab26ea45dcaa5e1c5a958e42af10e10d330e7334:--font-funcs ot:U+0628,U+064F:[u064f.damma=0@250,-250+250|u0628.beh=0@-250,0+1165]
 /System/Library/Fonts/SFNSDisplay.ttf@c8948f464ff822a5f9bbf2e12d0e4e32268815aa:--font-funcs ot:U+0054,U+0065,U+0020,U+0041,U+0056,U+0020,U+0054,U+0072,U+0020,U+0056,U+0061,U+0020,U+0072,U+0054,U+0020,U+0065,U+0054,U+0020,U+0054,U+0064:[gid282=0+1055|gid658=1@-135,0+914|gid3=2+420|gid4=3+1227|gid332=4@-65,0+1227|gid3=5+420|gid282=6+1075|gid813=7@-115,0+516|gid3=8+420|gid332=9+1217|gid572=10@-75,0+953|gid3=11+420|gid813=12+546|gid282=13@-85,0+1105|gid3=14+420|gid658=15+914|gid282=16@-135,0+1055|gid3=17+420|gid282=18+1055|gid649=19@-135,0+999]
-/System/Library/Fonts/SFNSDisplay.ttf@c8948f464ff822a5f9bbf2e12d0e4e32268815aa:--font-ptem 9 --font-funcs ot:U+0054,U+0065,U+0020,U+0041,U+0056,U+0020,U+0054,U+0072,U+0020,U+0056,U+0061,U+0020,U+0072,U+0054,U+0020,U+0065,U+0054,U+0020,U+0054,U+0064:[gid282=0@46,0+1147|gid658=1@-89,0+1006|gid3=2@46,0+512|gid4=3@46,0+1319|gid332=4@-19,0+1319|gid3=5@46,0+512|gid282=6@46,0+1167|gid813=7@-69,0+608|gid3=8@46,0+512|gid332=9@46,0+1309|gid572=10@-29,0+1045|gid3=11@46,0+512|gid813=12@46,0+638|gid282=13@-39,0+1197|gid3=14@46,0+512|gid658=15@46,0+1006|gid282=16@-89,0+1147|gid3=17@46,0+512|gid282=18@46,0+1147|gid649=19@-89,0+1091]
+/System/Library/Fonts/SFNSDisplay.ttf@c8948f464ff822a5f9bbf2e12d0e4e32268815aa:--font-ptem 9 --font-funcs ot:U+0054,U+0065,U+0020,U+0041,U+0056,U+0020,U+0054,U+0072,U+0020,U+0056,U+0061,U+0020,U+0072,U+0054,U+0020,U+0065,U+0054,U+0020,U+0054,U+0064:[gid282=0@65,0+1185|gid658=1@-70,0+1044|gid3=2@65,0+550|gid4=3@65,0+1357|gid332=4+1357|gid3=5@65,0+550|gid282=6@65,0+1205|gid813=7@-50,0+646|gid3=8@65,0+550|gid332=9@65,0+1347|gid572=10@-10,0+1083|gid3=11@65,0+550|gid813=12@65,0+676|gid282=13@-20,0+1235|gid3=14@65,0+550|gid658=15@65,0+1044|gid282=16@-70,0+1185|gid3=17@65,0+550|gid282=18@65,0+1185|gid649=19@-70,0+1129]
 /System/Library/Fonts/Apple Color Emoji.ttc@2e09b1f3d42c3821cc6c4ac5b6ce16237ab0d496:--remove-default-ignorables --font-funcs ot:U+1F468,U+200D,U+1F469,U+200D,U+1F467,U+200D,U+1F466:[u1F46A.MWGB=0+800]
 /Library/Fonts/Zapfino.ttf@99a1e15163c3e9567d5b1019c45e9254dae63b08:--font-funcs ot:U+005A,U+0061,U+0070,U+0066,U+0069,U+006E,U+005A,U+0061,U+0070,U+0066,U+0069,U+006E,U+005A,U+0061,U+0070,U+0066,U+0069,U+006E,U+005A,U+0061,U+0070,U+0066,U+0069,U+006E,U+005A,U+0061,U+0070,U+0066,U+0069,U+006E,U+005A,U+0061,U+0070,U+0066,U+0069,U+006E,U+005A,U+0061,U+0070,U+0066,U+0069,U+006E,U+005A,U+0061,U+0070,U+0066,U+0069,U+006E,U+005A,U+0061,U+0070,U+0066,U+0069,U+006E,U+005A,U+0061,U+0070,U+0066,U+0069,U+006E,U+005A,U+0061,U+0070,U+0066,U+0069,U+006E,U+005A,U+0061,U+0070,U+0066,U+0069,U+006E,U+006F:[Z=0+416|a=1@-21,0+264|p_f=2+433|i=4+181|n=5+261|Z=6+416|a=7@-21,0+264|p_f=8+433|i=10+181|n=11+261|Z=12+416|a=13@-21,0+264|p_f=14+433|i=16+181|n=17+261|Z=18+416|a=19@-21,0+264|p_f=20+433|i=22+181|n=23+261|Z=24+416|a=25@-21,0+264|p_f=26+433|i=28+181|n=29+261|Z=30+416|a=31@-21,0+264|p_f=32+433|i=34+181|n=35+261|Z=36+416|a=37@-21,0+264|p_f=38+433|i=40+181|n=41+261|Z=42+416|a=43@-21,0+264|p_f=44+433|i=46+181|n=47+261|Z=48+416|a=49@-21,0+264|p_f=50+433|i=52+181|n=53+261|Z=54+416|a=55@-21,0+264|p_f=56+433|i=58+181|n=59+261|Z=60+416|a=61@-21,0+264|p_f=62+433|i=64+181|n=65+261|Z_a_p_f_i_n_o=66+2333]
 
@@ -51,6 +51,6 @@
 /System/Library/Fonts/GeezaPro.ttc@ab26ea45dcaa5e1c5a958e42af10e10d330e7334:--font-funcs ot:U+0631,U+0628:[u0628.beh=1+1415|u0631.reh=0@-202,0+700]
 /System/Library/Fonts/GeezaPro.ttc@ab26ea45dcaa5e1c5a958e42af10e10d330e7334:--font-funcs ot:U+0628,U+064F:[u064f.damma=0@250,-250+250|u0628.beh=0@-250,0+1165]
 /System/Library/Fonts/SFNSDisplay.ttf@6e9677c443f6583228a63fd147663cfc635924d9:--font-funcs ot:U+0054,U+0065,U+0020,U+0041,U+0056,U+0020,U+0054,U+0072,U+0020,U+0056,U+0061,U+0020,U+0072,U+0054,U+0020,U+0065,U+0054,U+0020,U+0054,U+0064:[gid283=0+1055|gid659=1@-135,0+914|gid3=2+420|gid4=3+1227|gid333=4@-65,0+1227|gid3=5+420|gid283=6+1075|gid815=7@-115,0+516|gid3=8+420|gid333=9+1217|gid573=10@-75,0+953|gid3=11+420|gid815=12+546|gid283=13@-85,0+1105|gid3=14+420|gid659=15+914|gid283=16@-135,0+1055|gid3=17+420|gid283=18+1055|gid650=19@-135,0+999]
-/System/Library/Fonts/SFNSDisplay.ttf@6e9677c443f6583228a63fd147663cfc635924d9:--font-ptem 9 --font-funcs ot:U+0054,U+0065,U+0020,U+0041,U+0056,U+0020,U+0054,U+0072,U+0020,U+0056,U+0061,U+0020,U+0072,U+0054,U+0020,U+0065,U+0054,U+0020,U+0054,U+0064:[gid283=0@46,0+1147|gid659=1@-89,0+1006|gid3=2@46,0+512|gid4=3@46,0+1319|gid333=4@-19,0+1319|gid3=5@46,0+512|gid283=6@46,0+1167|gid815=7@-69,0+608|gid3=8@46,0+512|gid333=9@46,0+1309|gid573=10@-29,0+1045|gid3=11@46,0+512|gid815=12@46,0+638|gid283=13@-39,0+1197|gid3=14@46,0+512|gid659=15@46,0+1006|gid283=16@-89,0+1147|gid3=17@46,0+512|gid283=18@46,0+1147|gid650=19@-89,0+1091]
+/System/Library/Fonts/SFNSDisplay.ttf@6e9677c443f6583228a63fd147663cfc635924d9:--font-ptem 9 --font-funcs ot:U+0054,U+0065,U+0020,U+0041,U+0056,U+0020,U+0054,U+0072,U+0020,U+0056,U+0061,U+0020,U+0072,U+0054,U+0020,U+0065,U+0054,U+0020,U+0054,U+0064:[gid283=0@65,0+1185|gid659=1@-70,0+1044|gid3=2@65,0+550|gid4=3@65,0+1357|gid333=4+1357|gid3=5@65,0+550|gid283=6@65,0+1205|gid815=7@-50,0+646|gid3=8@65,0+550|gid333=9@65,0+1347|gid573=10@-10,0+1083|gid3=11@65,0+550|gid815=12@65,0+676|gid283=13@-20,0+1235|gid3=14@65,0+550|gid659=15@65,0+1044|gid283=16@-70,0+1185|gid3=17@65,0+550|gid283=18@65,0+1185|gid650=19@-70,0+1129]
 /System/Library/Fonts/Apple Color Emoji.ttc@60f77161021b1b87e99c3690e1a9b56341cf8792:--remove-default-ignorables --font-funcs ot:U+1F468,U+200D,U+1F469,U+200D,U+1F467,U+200D,U+1F466:[u1F46A.MWGB=0+800]
 /Library/Fonts/Zapfino.ttf@99a1e15163c3e9567d5b1019c45e9254dae63b08:--font-funcs ot:U+005A,U+0061,U+0070,U+0066,U+0069,U+006E,U+005A,U+0061,U+0070,U+0066,U+0069,U+006E,U+005A,U+0061,U+0070,U+0066,U+0069,U+006E,U+005A,U+0061,U+0070,U+0066,U+0069,U+006E,U+005A,U+0061,U+0070,U+0066,U+0069,U+006E,U+005A,U+0061,U+0070,U+0066,U+0069,U+006E,U+005A,U+0061,U+0070,U+0066,U+0069,U+006E,U+005A,U+0061,U+0070,U+0066,U+0069,U+006E,U+005A,U+0061,U+0070,U+0066,U+0069,U+006E,U+005A,U+0061,U+0070,U+0066,U+0069,U+006E,U+005A,U+0061,U+0070,U+0066,U+0069,U+006E,U+005A,U+0061,U+0070,U+0066,U+0069,U+006E,U+006F:[Z=0+416|a=1@-21,0+264|p_f=2+433|i=4+181|n=5+261|Z=6+416|a=7@-21,0+264|p_f=8+433|i=10+181|n=11+261|Z=12+416|a=13@-21,0+264|p_f=14+433|i=16+181|n=17+261|Z=18+416|a=19@-21,0+264|p_f=20+433|i=22+181|n=23+261|Z=24+416|a=25@-21,0+264|p_f=26+433|i=28+181|n=29+261|Z=30+416|a=31@-21,0+264|p_f=32+433|i=34+181|n=35+261|Z=36+416|a=37@-21,0+264|p_f=38+433|i=40+181|n=41+261|Z=42+416|a=43@-21,0+264|p_f=44+433|i=46+181|n=47+261|Z=48+416|a=49@-21,0+264|p_f=50+433|i=52+181|n=53+261|Z=54+416|a=55@-21,0+264|p_f=56+433|i=58+181|n=59+261|Z=60+416|a=61@-21,0+264|p_f=62+433|i=64+181|n=65+261|Z_a_p_f_i_n_o=66+2333]
diff --git a/test/shaping/data/in-house/tests/positioning-features.tests b/test/shaping/data/in-house/tests/positioning-features.tests
new file mode 100644 (file)
index 0000000..8cab9d8
--- /dev/null
@@ -0,0 +1,3 @@
+../fonts/53a91c20e33a596f2be17fb68b382d6b7eb85d5c.ttf::U+0041,U+0056:[A=0+625|V=1+675]
+../fonts/f79eb71df4e4c9c273b67b89a06e5ff9e3c1f834.ttf::U+006D,U+0315:[m=0+945|uni0315=0@32,-178+0]
+../fonts/ea3f63620511b2097200d23774ffef197e829e69.ttf::U+0079,U+0325:[y=0+565|uni0325=0@-422,-240+0]
index 6a247ed..9056008 100644 (file)
@@ -10,3 +10,7 @@
 ../fonts/28f497629c04ceb15546c9a70e0730125ed6698d.ttf::U+11013,U+11044,U+11046:[brm_KA=0+754|brm_vowelOO=0@-647,0+0|brm_virama=0@-524,0+0]
 ../fonts/28f497629c04ceb15546c9a70e0730125ed6698d.ttf::U+11013,U+1103C:[brm_KA=0+754|brm_vowelU=0@-403,0+0]
 ../fonts/86cdd983c4e4c4d7f27dd405d6ceb7d4b9ed3d35.ttf::U+111C8,U+111C9,U+111C9:[u111C8=0+500|u111C9=0@-500,0+0|u111C9=0@-500,0+0]
+../fonts/3cc01fede4debd4b7794ccb1b16cdb9987ea7571.ttf::U+1A3D,U+1A5A,U+1A63:[uni1A3D=0+250|uni1A5A=0+0|uni1A63=0+250]
+../fonts/3cc01fede4debd4b7794ccb1b16cdb9987ea7571.ttf::U+1A3D,U+1A60,U+1A3D,U+1A63,U+1A60,U+1A3D,U+1A59:[uni1A3D=0+250|uni1A60=0+0|uni1A3D=2+250|uni1A63=2+250|uni1A60=2+0|uni1A3D=5+250|uni1A59=5+0]
+../fonts/3cc01fede4debd4b7794ccb1b16cdb9987ea7571.ttf::U+1A3D,U+1A60,U+1A3D,U+1A63,U+1A60,U+1A3D,U+1A5A:[uni1A3D=0+250|uni1A60=0+0|uni1A3D=2+250|uni1A63=2+250|uni1A60=2+0|uni1A3D=5+250|uni25CC=5+250|uni1A5A=5+0]
+../fonts/3cc01fede4debd4b7794ccb1b16cdb9987ea7571.ttf::U+1A3D,U+1A60,U+1A3D,U+1A63,U+1A60,U+1A3D,U+1A60:[uni1A3D=0+250|uni1A60=0+0|uni1A3D=2+250|uni1A63=2+250|uni1A60=2+0|uni1A3D=5+250|uni1A60=5+0]
index 6bf15ce..9f4c011 100644 (file)
@@ -118,6 +118,7 @@ subdir = test/shaping/data/text-rendering-tests
 ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
 am__aclocal_m4_deps = $(top_srcdir)/m4/ax_check_link_flag.m4 \
        $(top_srcdir)/m4/ax_code_coverage.m4 \
+       $(top_srcdir)/m4/ax_cxx_compile_stdcxx.m4 \
        $(top_srcdir)/m4/ax_pthread.m4 $(top_srcdir)/m4/gtk-doc.m4 \
        $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \
        $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \
@@ -403,6 +404,8 @@ FREETYPE_CFLAGS = @FREETYPE_CFLAGS@
 FREETYPE_DEPS = @FREETYPE_DEPS@
 FREETYPE_LIBS = @FREETYPE_LIBS@
 GCOV = @GCOV@
+GDI_CFLAGS = @GDI_CFLAGS@
+GDI_LIBS = @GDI_LIBS@
 GENHTML = @GENHTML@
 GIT = @GIT@
 GLIB_CFLAGS = @GLIB_CFLAGS@
@@ -421,6 +424,7 @@ GTKDOC_DEPS_CFLAGS = @GTKDOC_DEPS_CFLAGS@
 GTKDOC_DEPS_LIBS = @GTKDOC_DEPS_LIBS@
 GTKDOC_MKPDF = @GTKDOC_MKPDF@
 GTKDOC_REBASE = @GTKDOC_REBASE@
+HAVE_CXX11 = @HAVE_CXX11@
 HB_LIBTOOL_VERSION_INFO = @HB_LIBTOOL_VERSION_INFO@
 HB_VERSION = @HB_VERSION@
 HB_VERSION_MAJOR = @HB_VERSION_MAJOR@
index 4ab74f0..7f24354 100755 (executable)
@@ -2,6 +2,17 @@
 
 dir=`mktemp -d`
 
+if which sha1sum 2>/dev/null >/dev/null; then
+       SHA1SUM=sha1sum
+elif which shasum 2>/dev/null >/dev/null; then
+       SHA1SUM='shasum -a 1'
+elif which digest 2>/dev/null >/dev/null; then
+       SHA1SUM='digest -a sha1'
+else
+       echo "'sha1sum' not found"
+       exit 2
+fi
+
 out=/dev/stdout
 if test "x$1" == 'x-o'; then
        shift
@@ -90,7 +101,7 @@ if ! test "x$glyphs" = "x$glyphs_subset"; then
        glyphs=$glyphs_subset
 fi
 
-sha1sum=`sha1sum "$dir/font.subset.ttf" | cut -d' ' -f1`
+sha1sum=`$SHA1SUM "$dir/font.subset.ttf" | cut -d' ' -f1`
 subset="data/in-house/fonts/$sha1sum.ttf"
 mv "$dir/font.subset.ttf" "$subset"
 
index 1673cfb..da4b3d4 100644 (file)
@@ -6,7 +6,8 @@ CLEANFILES =
 SUBDIRS = data
 
 # Convenience targets:
-lib:
+lib: libs # Always build subsetter lib in this subdir
+libs:
        @$(MAKE) $(AM_MAKEFLAGS) -C $(top_builddir)/src libs
 
 EXTRA_DIST += \
index 16f5c00..c661983 100644 (file)
@@ -93,6 +93,7 @@ subdir = test/subset
 ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
 am__aclocal_m4_deps = $(top_srcdir)/m4/ax_check_link_flag.m4 \
        $(top_srcdir)/m4/ax_code_coverage.m4 \
+       $(top_srcdir)/m4/ax_cxx_compile_stdcxx.m4 \
        $(top_srcdir)/m4/ax_pthread.m4 $(top_srcdir)/m4/gtk-doc.m4 \
        $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \
        $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \
@@ -235,6 +236,8 @@ FREETYPE_CFLAGS = @FREETYPE_CFLAGS@
 FREETYPE_DEPS = @FREETYPE_DEPS@
 FREETYPE_LIBS = @FREETYPE_LIBS@
 GCOV = @GCOV@
+GDI_CFLAGS = @GDI_CFLAGS@
+GDI_LIBS = @GDI_LIBS@
 GENHTML = @GENHTML@
 GIT = @GIT@
 GLIB_CFLAGS = @GLIB_CFLAGS@
@@ -253,6 +256,7 @@ GTKDOC_DEPS_CFLAGS = @GTKDOC_DEPS_CFLAGS@
 GTKDOC_DEPS_LIBS = @GTKDOC_DEPS_LIBS@
 GTKDOC_MKPDF = @GTKDOC_MKPDF@
 GTKDOC_REBASE = @GTKDOC_REBASE@
+HAVE_CXX11 = @HAVE_CXX11@
 HB_LIBTOOL_VERSION_INFO = @HB_LIBTOOL_VERSION_INFO@
 HB_VERSION = @HB_VERSION@
 HB_VERSION_MAJOR = @HB_VERSION_MAJOR@
@@ -693,7 +697,8 @@ uninstall-am:
 
 
 # Convenience targets:
-lib:
+lib: libs # Always build subsetter lib in this subdir
+libs:
        @$(MAKE) $(AM_MAKEFLAGS) -C $(top_builddir)/src libs
 
 -include $(top_srcdir)/git.mk
index 0677120..4508fcd 100644 (file)
@@ -9,7 +9,15 @@ EXTRA_DIST += \
        $(TESTS) \
        expected/basics \
        expected/full-font \
+       expected/cff-full-font \
        expected/japanese \
+       expected/cff-japanese \
+       expected/layout \
+       expected/layout.gpos \
+       expected/layout.gpos2 \
+       expected/layout.gpos3 \
+       expected/layout.gsub6 \
+       expected/cmap14 \
        fonts \
        profiles \
        $(NULL)
index 3ca3360..17a079f 100644 (file)
@@ -89,13 +89,18 @@ PRE_UNINSTALL = :
 POST_UNINSTALL = :
 build_triplet = @build@
 host_triplet = @host@
-TESTS = tests/basics.tests tests/full-font.tests tests/japanese.tests \
-       $(am__EXEEXT_1)
+TESTS = tests/basics.tests tests/full-font.tests \
+       tests/cff-full-font.tests tests/japanese.tests \
+       tests/cff-japanese.tests tests/layout.tests \
+       tests/layout.gpos.tests tests/layout.gpos2.tests \
+       tests/layout.gpos3.tests tests/layout.gsub6.tests \
+       tests/cmap14.tests $(am__EXEEXT_1)
 XFAIL_TESTS = $(am__EXEEXT_1)
 subdir = test/subset/data
 ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
 am__aclocal_m4_deps = $(top_srcdir)/m4/ax_check_link_flag.m4 \
        $(top_srcdir)/m4/ax_code_coverage.m4 \
+       $(top_srcdir)/m4/ax_cxx_compile_stdcxx.m4 \
        $(top_srcdir)/m4/ax_pthread.m4 $(top_srcdir)/m4/gtk-doc.m4 \
        $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \
        $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \
@@ -440,6 +445,8 @@ FREETYPE_CFLAGS = @FREETYPE_CFLAGS@
 FREETYPE_DEPS = @FREETYPE_DEPS@
 FREETYPE_LIBS = @FREETYPE_LIBS@
 GCOV = @GCOV@
+GDI_CFLAGS = @GDI_CFLAGS@
+GDI_LIBS = @GDI_LIBS@
 GENHTML = @GENHTML@
 GIT = @GIT@
 GLIB_CFLAGS = @GLIB_CFLAGS@
@@ -458,6 +465,7 @@ GTKDOC_DEPS_CFLAGS = @GTKDOC_DEPS_CFLAGS@
 GTKDOC_DEPS_LIBS = @GTKDOC_DEPS_LIBS@
 GTKDOC_MKPDF = @GTKDOC_MKPDF@
 GTKDOC_REBASE = @GTKDOC_REBASE@
+HAVE_CXX11 = @HAVE_CXX11@
 HB_LIBTOOL_VERSION_INFO = @HB_LIBTOOL_VERSION_INFO@
 HB_VERSION = @HB_VERSION@
 HB_VERSION_MAJOR = @HB_VERSION_MAJOR@
@@ -579,7 +587,10 @@ top_builddir = @top_builddir@
 top_srcdir = @top_srcdir@
 NULL = 
 EXTRA_DIST = $(TESTS) expected/basics expected/full-font \
-       expected/japanese fonts profiles $(NULL)
+       expected/cff-full-font expected/japanese expected/cff-japanese \
+       expected/layout expected/layout.gpos expected/layout.gpos2 \
+       expected/layout.gpos3 expected/layout.gsub6 expected/cmap14 \
+       fonts profiles $(NULL)
 CLEANFILES = 
 SUBDIRS = 
 TEST_EXTENSIONS = .tests
index dd1bcfe..5b93f27 100644 (file)
@@ -1,7 +1,15 @@
 TESTS = \
        tests/basics.tests \
        tests/full-font.tests \
+       tests/cff-full-font.tests \
        tests/japanese.tests \
+       tests/cff-japanese.tests \
+       tests/layout.tests \
+       tests/layout.gpos.tests \
+       tests/layout.gpos2.tests \
+       tests/layout.gpos3.tests \
+       tests/layout.gsub6.tests \
+       tests/cmap14.tests \
        $(NULL)
 
 XFAIL_TESTS = \
diff --git a/test/subset/data/expected/basics/Comfortaa-Regular-new.default.61,62,63.ttf b/test/subset/data/expected/basics/Comfortaa-Regular-new.default.61,62,63.ttf
new file mode 100644 (file)
index 0000000..efe5bcb
Binary files /dev/null and b/test/subset/data/expected/basics/Comfortaa-Regular-new.default.61,62,63.ttf differ
diff --git a/test/subset/data/expected/basics/Comfortaa-Regular-new.default.61,63.ttf b/test/subset/data/expected/basics/Comfortaa-Regular-new.default.61,63.ttf
new file mode 100644 (file)
index 0000000..8e12241
Binary files /dev/null and b/test/subset/data/expected/basics/Comfortaa-Regular-new.default.61,63.ttf differ
diff --git a/test/subset/data/expected/basics/Comfortaa-Regular-new.default.61.ttf b/test/subset/data/expected/basics/Comfortaa-Regular-new.default.61.ttf
new file mode 100644 (file)
index 0000000..bd802a5
Binary files /dev/null and b/test/subset/data/expected/basics/Comfortaa-Regular-new.default.61.ttf differ
diff --git a/test/subset/data/expected/basics/Comfortaa-Regular-new.default.62.ttf b/test/subset/data/expected/basics/Comfortaa-Regular-new.default.62.ttf
new file mode 100644 (file)
index 0000000..9fbebb5
Binary files /dev/null and b/test/subset/data/expected/basics/Comfortaa-Regular-new.default.62.ttf differ
diff --git a/test/subset/data/expected/basics/Comfortaa-Regular-new.default.63.ttf b/test/subset/data/expected/basics/Comfortaa-Regular-new.default.63.ttf
new file mode 100644 (file)
index 0000000..7391741
Binary files /dev/null and b/test/subset/data/expected/basics/Comfortaa-Regular-new.default.63.ttf differ
diff --git a/test/subset/data/expected/basics/Comfortaa-Regular-new.default.retain-all-codepoint.ttf b/test/subset/data/expected/basics/Comfortaa-Regular-new.default.retain-all-codepoint.ttf
new file mode 100644 (file)
index 0000000..5de8d89
Binary files /dev/null and b/test/subset/data/expected/basics/Comfortaa-Regular-new.default.retain-all-codepoint.ttf differ
diff --git a/test/subset/data/expected/basics/Comfortaa-Regular-new.drop-hints-retain-gids.61,62,63.ttf b/test/subset/data/expected/basics/Comfortaa-Regular-new.drop-hints-retain-gids.61,62,63.ttf
new file mode 100644 (file)
index 0000000..05d83d8
Binary files /dev/null and b/test/subset/data/expected/basics/Comfortaa-Regular-new.drop-hints-retain-gids.61,62,63.ttf differ
diff --git a/test/subset/data/expected/basics/Comfortaa-Regular-new.drop-hints-retain-gids.61,63.ttf b/test/subset/data/expected/basics/Comfortaa-Regular-new.drop-hints-retain-gids.61,63.ttf
new file mode 100644 (file)
index 0000000..f47887e
Binary files /dev/null and b/test/subset/data/expected/basics/Comfortaa-Regular-new.drop-hints-retain-gids.61,63.ttf differ
diff --git a/test/subset/data/expected/basics/Comfortaa-Regular-new.drop-hints-retain-gids.61.ttf b/test/subset/data/expected/basics/Comfortaa-Regular-new.drop-hints-retain-gids.61.ttf
new file mode 100644 (file)
index 0000000..bfa9267
Binary files /dev/null and b/test/subset/data/expected/basics/Comfortaa-Regular-new.drop-hints-retain-gids.61.ttf differ
diff --git a/test/subset/data/expected/basics/Comfortaa-Regular-new.drop-hints-retain-gids.62.ttf b/test/subset/data/expected/basics/Comfortaa-Regular-new.drop-hints-retain-gids.62.ttf
new file mode 100644 (file)
index 0000000..8c12158
Binary files /dev/null and b/test/subset/data/expected/basics/Comfortaa-Regular-new.drop-hints-retain-gids.62.ttf differ
diff --git a/test/subset/data/expected/basics/Comfortaa-Regular-new.drop-hints-retain-gids.63.ttf b/test/subset/data/expected/basics/Comfortaa-Regular-new.drop-hints-retain-gids.63.ttf
new file mode 100644 (file)
index 0000000..6a47c39
Binary files /dev/null and b/test/subset/data/expected/basics/Comfortaa-Regular-new.drop-hints-retain-gids.63.ttf differ
diff --git a/test/subset/data/expected/basics/Comfortaa-Regular-new.drop-hints-retain-gids.retain-all-codepoint.ttf b/test/subset/data/expected/basics/Comfortaa-Regular-new.drop-hints-retain-gids.retain-all-codepoint.ttf
new file mode 100644 (file)
index 0000000..e3c0727
Binary files /dev/null and b/test/subset/data/expected/basics/Comfortaa-Regular-new.drop-hints-retain-gids.retain-all-codepoint.ttf differ
diff --git a/test/subset/data/expected/basics/Comfortaa-Regular-new.drop-hints.61,62,63.ttf b/test/subset/data/expected/basics/Comfortaa-Regular-new.drop-hints.61,62,63.ttf
new file mode 100644 (file)
index 0000000..36a4b9a
Binary files /dev/null and b/test/subset/data/expected/basics/Comfortaa-Regular-new.drop-hints.61,62,63.ttf differ
diff --git a/test/subset/data/expected/basics/Comfortaa-Regular-new.drop-hints.61,63.ttf b/test/subset/data/expected/basics/Comfortaa-Regular-new.drop-hints.61,63.ttf
new file mode 100644 (file)
index 0000000..251794c
Binary files /dev/null and b/test/subset/data/expected/basics/Comfortaa-Regular-new.drop-hints.61,63.ttf differ
diff --git a/test/subset/data/expected/basics/Comfortaa-Regular-new.drop-hints.61.ttf b/test/subset/data/expected/basics/Comfortaa-Regular-new.drop-hints.61.ttf
new file mode 100644 (file)
index 0000000..9e65c83
Binary files /dev/null and b/test/subset/data/expected/basics/Comfortaa-Regular-new.drop-hints.61.ttf differ
diff --git a/test/subset/data/expected/basics/Comfortaa-Regular-new.drop-hints.62.ttf b/test/subset/data/expected/basics/Comfortaa-Regular-new.drop-hints.62.ttf
new file mode 100644 (file)
index 0000000..ada1649
Binary files /dev/null and b/test/subset/data/expected/basics/Comfortaa-Regular-new.drop-hints.62.ttf differ
diff --git a/test/subset/data/expected/basics/Comfortaa-Regular-new.drop-hints.63.ttf b/test/subset/data/expected/basics/Comfortaa-Regular-new.drop-hints.63.ttf
new file mode 100644 (file)
index 0000000..6b0dc6c
Binary files /dev/null and b/test/subset/data/expected/basics/Comfortaa-Regular-new.drop-hints.63.ttf differ
diff --git a/test/subset/data/expected/basics/Comfortaa-Regular-new.drop-hints.retain-all-codepoint.ttf b/test/subset/data/expected/basics/Comfortaa-Regular-new.drop-hints.retain-all-codepoint.ttf
new file mode 100644 (file)
index 0000000..6425ecf
Binary files /dev/null and b/test/subset/data/expected/basics/Comfortaa-Regular-new.drop-hints.retain-all-codepoint.ttf differ
diff --git a/test/subset/data/expected/basics/Comfortaa-Regular-new.name-ids.61,62,63.ttf b/test/subset/data/expected/basics/Comfortaa-Regular-new.name-ids.61,62,63.ttf
new file mode 100644 (file)
index 0000000..90e49be
Binary files /dev/null and b/test/subset/data/expected/basics/Comfortaa-Regular-new.name-ids.61,62,63.ttf differ
diff --git a/test/subset/data/expected/basics/Comfortaa-Regular-new.name-ids.61,63.ttf b/test/subset/data/expected/basics/Comfortaa-Regular-new.name-ids.61,63.ttf
new file mode 100644 (file)
index 0000000..5277d15
Binary files /dev/null and b/test/subset/data/expected/basics/Comfortaa-Regular-new.name-ids.61,63.ttf differ
diff --git a/test/subset/data/expected/basics/Comfortaa-Regular-new.name-ids.61.ttf b/test/subset/data/expected/basics/Comfortaa-Regular-new.name-ids.61.ttf
new file mode 100644 (file)
index 0000000..de06660
Binary files /dev/null and b/test/subset/data/expected/basics/Comfortaa-Regular-new.name-ids.61.ttf differ
diff --git a/test/subset/data/expected/basics/Comfortaa-Regular-new.name-ids.62.ttf b/test/subset/data/expected/basics/Comfortaa-Regular-new.name-ids.62.ttf
new file mode 100644 (file)
index 0000000..effad7b
Binary files /dev/null and b/test/subset/data/expected/basics/Comfortaa-Regular-new.name-ids.62.ttf differ
diff --git a/test/subset/data/expected/basics/Comfortaa-Regular-new.name-ids.63.ttf b/test/subset/data/expected/basics/Comfortaa-Regular-new.name-ids.63.ttf
new file mode 100644 (file)
index 0000000..21c8205
Binary files /dev/null and b/test/subset/data/expected/basics/Comfortaa-Regular-new.name-ids.63.ttf differ
diff --git a/test/subset/data/expected/basics/Comfortaa-Regular-new.name-ids.retain-all-codepoint.ttf b/test/subset/data/expected/basics/Comfortaa-Regular-new.name-ids.retain-all-codepoint.ttf
new file mode 100644 (file)
index 0000000..fbb8c33
Binary files /dev/null and b/test/subset/data/expected/basics/Comfortaa-Regular-new.name-ids.retain-all-codepoint.ttf differ
diff --git a/test/subset/data/expected/basics/Comfortaa-Regular-new.retain-gids.61,62,63.ttf b/test/subset/data/expected/basics/Comfortaa-Regular-new.retain-gids.61,62,63.ttf
new file mode 100644 (file)
index 0000000..3c0f4cd
Binary files /dev/null and b/test/subset/data/expected/basics/Comfortaa-Regular-new.retain-gids.61,62,63.ttf differ
diff --git a/test/subset/data/expected/basics/Comfortaa-Regular-new.retain-gids.61,63.ttf b/test/subset/data/expected/basics/Comfortaa-Regular-new.retain-gids.61,63.ttf
new file mode 100644 (file)
index 0000000..a5ce9e0
Binary files /dev/null and b/test/subset/data/expected/basics/Comfortaa-Regular-new.retain-gids.61,63.ttf differ
diff --git a/test/subset/data/expected/basics/Comfortaa-Regular-new.retain-gids.61.ttf b/test/subset/data/expected/basics/Comfortaa-Regular-new.retain-gids.61.ttf
new file mode 100644 (file)
index 0000000..1b84335
Binary files /dev/null and b/test/subset/data/expected/basics/Comfortaa-Regular-new.retain-gids.61.ttf differ
diff --git a/test/subset/data/expected/basics/Comfortaa-Regular-new.retain-gids.62.ttf b/test/subset/data/expected/basics/Comfortaa-Regular-new.retain-gids.62.ttf
new file mode 100644 (file)
index 0000000..97eaa26
Binary files /dev/null and b/test/subset/data/expected/basics/Comfortaa-Regular-new.retain-gids.62.ttf differ
diff --git a/test/subset/data/expected/basics/Comfortaa-Regular-new.retain-gids.63.ttf b/test/subset/data/expected/basics/Comfortaa-Regular-new.retain-gids.63.ttf
new file mode 100644 (file)
index 0000000..f42edb7
Binary files /dev/null and b/test/subset/data/expected/basics/Comfortaa-Regular-new.retain-gids.63.ttf differ
diff --git a/test/subset/data/expected/basics/Comfortaa-Regular-new.retain-gids.retain-all-codepoint.ttf b/test/subset/data/expected/basics/Comfortaa-Regular-new.retain-gids.retain-all-codepoint.ttf
new file mode 100644 (file)
index 0000000..cc2805a
Binary files /dev/null and b/test/subset/data/expected/basics/Comfortaa-Regular-new.retain-gids.retain-all-codepoint.ttf differ
diff --git a/test/subset/data/expected/basics/Roboto-Regular.abc.default.retain-all-codepoint.ttf b/test/subset/data/expected/basics/Roboto-Regular.abc.default.retain-all-codepoint.ttf
new file mode 100644 (file)
index 0000000..12d9208
Binary files /dev/null and b/test/subset/data/expected/basics/Roboto-Regular.abc.default.retain-all-codepoint.ttf differ
index 1a0d5bd..128eae0 100644 (file)
Binary files a/test/subset/data/expected/basics/Roboto-Regular.abc.drop-hints-retain-gids.61.ttf and b/test/subset/data/expected/basics/Roboto-Regular.abc.drop-hints-retain-gids.61.ttf differ
index 257184b..2d2b65b 100644 (file)
Binary files a/test/subset/data/expected/basics/Roboto-Regular.abc.drop-hints-retain-gids.62.ttf and b/test/subset/data/expected/basics/Roboto-Regular.abc.drop-hints-retain-gids.62.ttf differ
diff --git a/test/subset/data/expected/basics/Roboto-Regular.abc.drop-hints-retain-gids.retain-all-codepoint.ttf b/test/subset/data/expected/basics/Roboto-Regular.abc.drop-hints-retain-gids.retain-all-codepoint.ttf
new file mode 100644 (file)
index 0000000..52dc474
Binary files /dev/null and b/test/subset/data/expected/basics/Roboto-Regular.abc.drop-hints-retain-gids.retain-all-codepoint.ttf differ
diff --git a/test/subset/data/expected/basics/Roboto-Regular.abc.drop-hints.retain-all-codepoint.ttf b/test/subset/data/expected/basics/Roboto-Regular.abc.drop-hints.retain-all-codepoint.ttf
new file mode 100644 (file)
index 0000000..52dc474
Binary files /dev/null and b/test/subset/data/expected/basics/Roboto-Regular.abc.drop-hints.retain-all-codepoint.ttf differ
diff --git a/test/subset/data/expected/basics/Roboto-Regular.abc.name-ids.61,62,63.ttf b/test/subset/data/expected/basics/Roboto-Regular.abc.name-ids.61,62,63.ttf
new file mode 100644 (file)
index 0000000..12d9208
Binary files /dev/null and b/test/subset/data/expected/basics/Roboto-Regular.abc.name-ids.61,62,63.ttf differ
diff --git a/test/subset/data/expected/basics/Roboto-Regular.abc.name-ids.61,63.ttf b/test/subset/data/expected/basics/Roboto-Regular.abc.name-ids.61,63.ttf
new file mode 100644 (file)
index 0000000..1af233f
Binary files /dev/null and b/test/subset/data/expected/basics/Roboto-Regular.abc.name-ids.61,63.ttf differ
diff --git a/test/subset/data/expected/basics/Roboto-Regular.abc.name-ids.61.ttf b/test/subset/data/expected/basics/Roboto-Regular.abc.name-ids.61.ttf
new file mode 100644 (file)
index 0000000..a699eea
Binary files /dev/null and b/test/subset/data/expected/basics/Roboto-Regular.abc.name-ids.61.ttf differ
diff --git a/test/subset/data/expected/basics/Roboto-Regular.abc.name-ids.62.ttf b/test/subset/data/expected/basics/Roboto-Regular.abc.name-ids.62.ttf
new file mode 100644 (file)
index 0000000..52706dc
Binary files /dev/null and b/test/subset/data/expected/basics/Roboto-Regular.abc.name-ids.62.ttf differ
diff --git a/test/subset/data/expected/basics/Roboto-Regular.abc.name-ids.63.ttf b/test/subset/data/expected/basics/Roboto-Regular.abc.name-ids.63.ttf
new file mode 100644 (file)
index 0000000..3de7c77
Binary files /dev/null and b/test/subset/data/expected/basics/Roboto-Regular.abc.name-ids.63.ttf differ
diff --git a/test/subset/data/expected/basics/Roboto-Regular.abc.name-ids.retain-all-codepoint.ttf b/test/subset/data/expected/basics/Roboto-Regular.abc.name-ids.retain-all-codepoint.ttf
new file mode 100644 (file)
index 0000000..12d9208
Binary files /dev/null and b/test/subset/data/expected/basics/Roboto-Regular.abc.name-ids.retain-all-codepoint.ttf differ
index d3a67ea..a699eea 100644 (file)
Binary files a/test/subset/data/expected/basics/Roboto-Regular.abc.retain-gids.61.ttf and b/test/subset/data/expected/basics/Roboto-Regular.abc.retain-gids.61.ttf differ
index 4ff6e33..eb84f9c 100644 (file)
Binary files a/test/subset/data/expected/basics/Roboto-Regular.abc.retain-gids.62.ttf and b/test/subset/data/expected/basics/Roboto-Regular.abc.retain-gids.62.ttf differ
diff --git a/test/subset/data/expected/basics/Roboto-Regular.abc.retain-gids.retain-all-codepoint.ttf b/test/subset/data/expected/basics/Roboto-Regular.abc.retain-gids.retain-all-codepoint.ttf
new file mode 100644 (file)
index 0000000..12d9208
Binary files /dev/null and b/test/subset/data/expected/basics/Roboto-Regular.abc.retain-gids.retain-all-codepoint.ttf differ
diff --git a/test/subset/data/expected/cff-full-font/SourceSansPro-Regular.default.1FC,21,41,20,62,63.otf b/test/subset/data/expected/cff-full-font/SourceSansPro-Regular.default.1FC,21,41,20,62,63.otf
new file mode 100644 (file)
index 0000000..f0ea3ca
Binary files /dev/null and b/test/subset/data/expected/cff-full-font/SourceSansPro-Regular.default.1FC,21,41,20,62,63.otf differ
diff --git a/test/subset/data/expected/cff-full-font/SourceSansPro-Regular.default.61,62,63.otf b/test/subset/data/expected/cff-full-font/SourceSansPro-Regular.default.61,62,63.otf
new file mode 100644 (file)
index 0000000..7ea55a2
Binary files /dev/null and b/test/subset/data/expected/cff-full-font/SourceSansPro-Regular.default.61,62,63.otf differ
diff --git a/test/subset/data/expected/cff-full-font/SourceSansPro-Regular.default.D7,D8,D9,DA,DE.otf b/test/subset/data/expected/cff-full-font/SourceSansPro-Regular.default.D7,D8,D9,DA,DE.otf
new file mode 100644 (file)
index 0000000..07b9aa2
Binary files /dev/null and b/test/subset/data/expected/cff-full-font/SourceSansPro-Regular.default.D7,D8,D9,DA,DE.otf differ
diff --git a/test/subset/data/expected/cff-full-font/SourceSansPro-Regular.desubroutinize-retain-gids.1FC,21,41,20,62,63.otf b/test/subset/data/expected/cff-full-font/SourceSansPro-Regular.desubroutinize-retain-gids.1FC,21,41,20,62,63.otf
new file mode 100644 (file)
index 0000000..2811017
Binary files /dev/null and b/test/subset/data/expected/cff-full-font/SourceSansPro-Regular.desubroutinize-retain-gids.1FC,21,41,20,62,63.otf differ
diff --git a/test/subset/data/expected/cff-full-font/SourceSansPro-Regular.desubroutinize-retain-gids.61,62,63.otf b/test/subset/data/expected/cff-full-font/SourceSansPro-Regular.desubroutinize-retain-gids.61,62,63.otf
new file mode 100644 (file)
index 0000000..98bbf38
Binary files /dev/null and b/test/subset/data/expected/cff-full-font/SourceSansPro-Regular.desubroutinize-retain-gids.61,62,63.otf differ
diff --git a/test/subset/data/expected/cff-full-font/SourceSansPro-Regular.desubroutinize-retain-gids.D7,D8,D9,DA,DE.otf b/test/subset/data/expected/cff-full-font/SourceSansPro-Regular.desubroutinize-retain-gids.D7,D8,D9,DA,DE.otf
new file mode 100644 (file)
index 0000000..2d88e57
Binary files /dev/null and b/test/subset/data/expected/cff-full-font/SourceSansPro-Regular.desubroutinize-retain-gids.D7,D8,D9,DA,DE.otf differ
diff --git a/test/subset/data/expected/cff-full-font/SourceSansPro-Regular.desubroutinize.1FC,21,41,20,62,63.otf b/test/subset/data/expected/cff-full-font/SourceSansPro-Regular.desubroutinize.1FC,21,41,20,62,63.otf
new file mode 100644 (file)
index 0000000..cf0fbf6
Binary files /dev/null and b/test/subset/data/expected/cff-full-font/SourceSansPro-Regular.desubroutinize.1FC,21,41,20,62,63.otf differ
diff --git a/test/subset/data/expected/cff-full-font/SourceSansPro-Regular.desubroutinize.61,62,63.otf b/test/subset/data/expected/cff-full-font/SourceSansPro-Regular.desubroutinize.61,62,63.otf
new file mode 100644 (file)
index 0000000..8ab8294
Binary files /dev/null and b/test/subset/data/expected/cff-full-font/SourceSansPro-Regular.desubroutinize.61,62,63.otf differ
diff --git a/test/subset/data/expected/cff-full-font/SourceSansPro-Regular.desubroutinize.D7,D8,D9,DA,DE.otf b/test/subset/data/expected/cff-full-font/SourceSansPro-Regular.desubroutinize.D7,D8,D9,DA,DE.otf
new file mode 100644 (file)
index 0000000..de475e6
Binary files /dev/null and b/test/subset/data/expected/cff-full-font/SourceSansPro-Regular.desubroutinize.D7,D8,D9,DA,DE.otf differ
diff --git a/test/subset/data/expected/cff-full-font/SourceSansPro-Regular.drop-hints-desubroutinize-retain-gids.1FC,21,41,20,62,63.otf b/test/subset/data/expected/cff-full-font/SourceSansPro-Regular.drop-hints-desubroutinize-retain-gids.1FC,21,41,20,62,63.otf
new file mode 100644 (file)
index 0000000..e5775fd
Binary files /dev/null and b/test/subset/data/expected/cff-full-font/SourceSansPro-Regular.drop-hints-desubroutinize-retain-gids.1FC,21,41,20,62,63.otf differ
diff --git a/test/subset/data/expected/cff-full-font/SourceSansPro-Regular.drop-hints-desubroutinize-retain-gids.61,62,63.otf b/test/subset/data/expected/cff-full-font/SourceSansPro-Regular.drop-hints-desubroutinize-retain-gids.61,62,63.otf
new file mode 100644 (file)
index 0000000..572ea74
Binary files /dev/null and b/test/subset/data/expected/cff-full-font/SourceSansPro-Regular.drop-hints-desubroutinize-retain-gids.61,62,63.otf differ
diff --git a/test/subset/data/expected/cff-full-font/SourceSansPro-Regular.drop-hints-desubroutinize-retain-gids.D7,D8,D9,DA,DE.otf b/test/subset/data/expected/cff-full-font/SourceSansPro-Regular.drop-hints-desubroutinize-retain-gids.D7,D8,D9,DA,DE.otf
new file mode 100644 (file)
index 0000000..376f658
Binary files /dev/null and b/test/subset/data/expected/cff-full-font/SourceSansPro-Regular.drop-hints-desubroutinize-retain-gids.D7,D8,D9,DA,DE.otf differ
diff --git a/test/subset/data/expected/cff-full-font/SourceSansPro-Regular.drop-hints-desubroutinize.1FC,21,41,20,62,63.otf b/test/subset/data/expected/cff-full-font/SourceSansPro-Regular.drop-hints-desubroutinize.1FC,21,41,20,62,63.otf
new file mode 100644 (file)
index 0000000..cf3228d
Binary files /dev/null and b/test/subset/data/expected/cff-full-font/SourceSansPro-Regular.drop-hints-desubroutinize.1FC,21,41,20,62,63.otf differ
diff --git a/test/subset/data/expected/cff-full-font/SourceSansPro-Regular.drop-hints-desubroutinize.61,62,63.otf b/test/subset/data/expected/cff-full-font/SourceSansPro-Regular.drop-hints-desubroutinize.61,62,63.otf
new file mode 100644 (file)
index 0000000..1bafff1
Binary files /dev/null and b/test/subset/data/expected/cff-full-font/SourceSansPro-Regular.drop-hints-desubroutinize.61,62,63.otf differ
diff --git a/test/subset/data/expected/cff-full-font/SourceSansPro-Regular.drop-hints-desubroutinize.D7,D8,D9,DA,DE.otf b/test/subset/data/expected/cff-full-font/SourceSansPro-Regular.drop-hints-desubroutinize.D7,D8,D9,DA,DE.otf
new file mode 100644 (file)
index 0000000..34303e7
Binary files /dev/null and b/test/subset/data/expected/cff-full-font/SourceSansPro-Regular.drop-hints-desubroutinize.D7,D8,D9,DA,DE.otf differ
diff --git a/test/subset/data/expected/cff-full-font/SourceSansPro-Regular.drop-hints-retain-gids.1FC,21,41,20,62,63.otf b/test/subset/data/expected/cff-full-font/SourceSansPro-Regular.drop-hints-retain-gids.1FC,21,41,20,62,63.otf
new file mode 100644 (file)
index 0000000..e23e37f
Binary files /dev/null and b/test/subset/data/expected/cff-full-font/SourceSansPro-Regular.drop-hints-retain-gids.1FC,21,41,20,62,63.otf differ
diff --git a/test/subset/data/expected/cff-full-font/SourceSansPro-Regular.drop-hints-retain-gids.61,62,63.otf b/test/subset/data/expected/cff-full-font/SourceSansPro-Regular.drop-hints-retain-gids.61,62,63.otf
new file mode 100644 (file)
index 0000000..b5a565e
Binary files /dev/null and b/test/subset/data/expected/cff-full-font/SourceSansPro-Regular.drop-hints-retain-gids.61,62,63.otf differ
diff --git a/test/subset/data/expected/cff-full-font/SourceSansPro-Regular.drop-hints-retain-gids.D7,D8,D9,DA,DE.otf b/test/subset/data/expected/cff-full-font/SourceSansPro-Regular.drop-hints-retain-gids.D7,D8,D9,DA,DE.otf
new file mode 100644 (file)
index 0000000..6045b4c
Binary files /dev/null and b/test/subset/data/expected/cff-full-font/SourceSansPro-Regular.drop-hints-retain-gids.D7,D8,D9,DA,DE.otf differ
diff --git a/test/subset/data/expected/cff-full-font/SourceSansPro-Regular.drop-hints.1FC,21,41,20,62,63.otf b/test/subset/data/expected/cff-full-font/SourceSansPro-Regular.drop-hints.1FC,21,41,20,62,63.otf
new file mode 100644 (file)
index 0000000..112dec7
Binary files /dev/null and b/test/subset/data/expected/cff-full-font/SourceSansPro-Regular.drop-hints.1FC,21,41,20,62,63.otf differ
diff --git a/test/subset/data/expected/cff-full-font/SourceSansPro-Regular.drop-hints.61,62,63.otf b/test/subset/data/expected/cff-full-font/SourceSansPro-Regular.drop-hints.61,62,63.otf
new file mode 100644 (file)
index 0000000..929c4e2
Binary files /dev/null and b/test/subset/data/expected/cff-full-font/SourceSansPro-Regular.drop-hints.61,62,63.otf differ
diff --git a/test/subset/data/expected/cff-full-font/SourceSansPro-Regular.drop-hints.D7,D8,D9,DA,DE.otf b/test/subset/data/expected/cff-full-font/SourceSansPro-Regular.drop-hints.D7,D8,D9,DA,DE.otf
new file mode 100644 (file)
index 0000000..939a565
Binary files /dev/null and b/test/subset/data/expected/cff-full-font/SourceSansPro-Regular.drop-hints.D7,D8,D9,DA,DE.otf differ
diff --git a/test/subset/data/expected/cff-full-font/SourceSansPro-Regular.retain-gids.1FC,21,41,20,62,63.otf b/test/subset/data/expected/cff-full-font/SourceSansPro-Regular.retain-gids.1FC,21,41,20,62,63.otf
new file mode 100644 (file)
index 0000000..e1613ac
Binary files /dev/null and b/test/subset/data/expected/cff-full-font/SourceSansPro-Regular.retain-gids.1FC,21,41,20,62,63.otf differ
diff --git a/test/subset/data/expected/cff-full-font/SourceSansPro-Regular.retain-gids.61,62,63.otf b/test/subset/data/expected/cff-full-font/SourceSansPro-Regular.retain-gids.61,62,63.otf
new file mode 100644 (file)
index 0000000..479c5e0
Binary files /dev/null and b/test/subset/data/expected/cff-full-font/SourceSansPro-Regular.retain-gids.61,62,63.otf differ
diff --git a/test/subset/data/expected/cff-full-font/SourceSansPro-Regular.retain-gids.D7,D8,D9,DA,DE.otf b/test/subset/data/expected/cff-full-font/SourceSansPro-Regular.retain-gids.D7,D8,D9,DA,DE.otf
new file mode 100644 (file)
index 0000000..95149dc
Binary files /dev/null and b/test/subset/data/expected/cff-full-font/SourceSansPro-Regular.retain-gids.D7,D8,D9,DA,DE.otf differ
diff --git a/test/subset/data/expected/cff-japanese/SourceHanSans-Regular_subset.default.3042,3044,3046,3048,304A,304B.otf b/test/subset/data/expected/cff-japanese/SourceHanSans-Regular_subset.default.3042,3044,3046,3048,304A,304B.otf
new file mode 100644 (file)
index 0000000..6065be4
Binary files /dev/null and b/test/subset/data/expected/cff-japanese/SourceHanSans-Regular_subset.default.3042,3044,3046,3048,304A,304B.otf differ
diff --git a/test/subset/data/expected/cff-japanese/SourceHanSans-Regular_subset.default.3042,3044,3046,73E0,5EA6,8F38.otf b/test/subset/data/expected/cff-japanese/SourceHanSans-Regular_subset.default.3042,3044,3046,73E0,5EA6,8F38.otf
new file mode 100644 (file)
index 0000000..cee7584
Binary files /dev/null and b/test/subset/data/expected/cff-japanese/SourceHanSans-Regular_subset.default.3042,3044,3046,73E0,5EA6,8F38.otf differ
diff --git a/test/subset/data/expected/cff-japanese/SourceHanSans-Regular_subset.default.61,63,65,6B.otf b/test/subset/data/expected/cff-japanese/SourceHanSans-Regular_subset.default.61,63,65,6B.otf
new file mode 100644 (file)
index 0000000..0f13fa5
Binary files /dev/null and b/test/subset/data/expected/cff-japanese/SourceHanSans-Regular_subset.default.61,63,65,6B.otf differ
diff --git a/test/subset/data/expected/cff-japanese/SourceHanSans-Regular_subset.default.660E,6975,73E0,5EA6,8F38,6E05.otf b/test/subset/data/expected/cff-japanese/SourceHanSans-Regular_subset.default.660E,6975,73E0,5EA6,8F38,6E05.otf
new file mode 100644 (file)
index 0000000..6db56f4
Binary files /dev/null and b/test/subset/data/expected/cff-japanese/SourceHanSans-Regular_subset.default.660E,6975,73E0,5EA6,8F38,6E05.otf differ
diff --git a/test/subset/data/expected/cff-japanese/SourceHanSans-Regular_subset.default.660E.otf b/test/subset/data/expected/cff-japanese/SourceHanSans-Regular_subset.default.660E.otf
new file mode 100644 (file)
index 0000000..1b216cc
Binary files /dev/null and b/test/subset/data/expected/cff-japanese/SourceHanSans-Regular_subset.default.660E.otf differ
diff --git a/test/subset/data/expected/cff-japanese/SourceHanSans-Regular_subset.desubroutinize-retain-gids.3042,3044,3046,3048,304A,304B.otf b/test/subset/data/expected/cff-japanese/SourceHanSans-Regular_subset.desubroutinize-retain-gids.3042,3044,3046,3048,304A,304B.otf
new file mode 100644 (file)
index 0000000..690fe90
Binary files /dev/null and b/test/subset/data/expected/cff-japanese/SourceHanSans-Regular_subset.desubroutinize-retain-gids.3042,3044,3046,3048,304A,304B.otf differ
diff --git a/test/subset/data/expected/cff-japanese/SourceHanSans-Regular_subset.desubroutinize-retain-gids.3042,3044,3046,73E0,5EA6,8F38.otf b/test/subset/data/expected/cff-japanese/SourceHanSans-Regular_subset.desubroutinize-retain-gids.3042,3044,3046,73E0,5EA6,8F38.otf
new file mode 100644 (file)
index 0000000..f1f0cb1
Binary files /dev/null and b/test/subset/data/expected/cff-japanese/SourceHanSans-Regular_subset.desubroutinize-retain-gids.3042,3044,3046,73E0,5EA6,8F38.otf differ
diff --git a/test/subset/data/expected/cff-japanese/SourceHanSans-Regular_subset.desubroutinize-retain-gids.61,63,65,6B.otf b/test/subset/data/expected/cff-japanese/SourceHanSans-Regular_subset.desubroutinize-retain-gids.61,63,65,6B.otf
new file mode 100644 (file)
index 0000000..b353d43
Binary files /dev/null and b/test/subset/data/expected/cff-japanese/SourceHanSans-Regular_subset.desubroutinize-retain-gids.61,63,65,6B.otf differ
diff --git a/test/subset/data/expected/cff-japanese/SourceHanSans-Regular_subset.desubroutinize-retain-gids.660E,6975,73E0,5EA6,8F38,6E05.otf b/test/subset/data/expected/cff-japanese/SourceHanSans-Regular_subset.desubroutinize-retain-gids.660E,6975,73E0,5EA6,8F38,6E05.otf
new file mode 100644 (file)
index 0000000..7d96667
Binary files /dev/null and b/test/subset/data/expected/cff-japanese/SourceHanSans-Regular_subset.desubroutinize-retain-gids.660E,6975,73E0,5EA6,8F38,6E05.otf differ
diff --git a/test/subset/data/expected/cff-japanese/SourceHanSans-Regular_subset.desubroutinize-retain-gids.660E.otf b/test/subset/data/expected/cff-japanese/SourceHanSans-Regular_subset.desubroutinize-retain-gids.660E.otf
new file mode 100644 (file)
index 0000000..afd9c33
Binary files /dev/null and b/test/subset/data/expected/cff-japanese/SourceHanSans-Regular_subset.desubroutinize-retain-gids.660E.otf differ
diff --git a/test/subset/data/expected/cff-japanese/SourceHanSans-Regular_subset.desubroutinize.3042,3044,3046,3048,304A,304B.otf b/test/subset/data/expected/cff-japanese/SourceHanSans-Regular_subset.desubroutinize.3042,3044,3046,3048,304A,304B.otf
new file mode 100644 (file)
index 0000000..1a47c85
Binary files /dev/null and b/test/subset/data/expected/cff-japanese/SourceHanSans-Regular_subset.desubroutinize.3042,3044,3046,3048,304A,304B.otf differ
diff --git a/test/subset/data/expected/cff-japanese/SourceHanSans-Regular_subset.desubroutinize.3042,3044,3046,73E0,5EA6,8F38.otf b/test/subset/data/expected/cff-japanese/SourceHanSans-Regular_subset.desubroutinize.3042,3044,3046,73E0,5EA6,8F38.otf
new file mode 100644 (file)
index 0000000..b69448b
Binary files /dev/null and b/test/subset/data/expected/cff-japanese/SourceHanSans-Regular_subset.desubroutinize.3042,3044,3046,73E0,5EA6,8F38.otf differ
diff --git a/test/subset/data/expected/cff-japanese/SourceHanSans-Regular_subset.desubroutinize.61,63,65,6B.otf b/test/subset/data/expected/cff-japanese/SourceHanSans-Regular_subset.desubroutinize.61,63,65,6B.otf
new file mode 100644 (file)
index 0000000..3682a0d
Binary files /dev/null and b/test/subset/data/expected/cff-japanese/SourceHanSans-Regular_subset.desubroutinize.61,63,65,6B.otf differ
diff --git a/test/subset/data/expected/cff-japanese/SourceHanSans-Regular_subset.desubroutinize.660E,6975,73E0,5EA6,8F38,6E05.otf b/test/subset/data/expected/cff-japanese/SourceHanSans-Regular_subset.desubroutinize.660E,6975,73E0,5EA6,8F38,6E05.otf
new file mode 100644 (file)
index 0000000..6f98c8f
Binary files /dev/null and b/test/subset/data/expected/cff-japanese/SourceHanSans-Regular_subset.desubroutinize.660E,6975,73E0,5EA6,8F38,6E05.otf differ
diff --git a/test/subset/data/expected/cff-japanese/SourceHanSans-Regular_subset.desubroutinize.660E.otf b/test/subset/data/expected/cff-japanese/SourceHanSans-Regular_subset.desubroutinize.660E.otf
new file mode 100644 (file)
index 0000000..1497979
Binary files /dev/null and b/test/subset/data/expected/cff-japanese/SourceHanSans-Regular_subset.desubroutinize.660E.otf differ
diff --git a/test/subset/data/expected/cff-japanese/SourceHanSans-Regular_subset.drop-hints-desubroutinize-retain-gids.3042,3044,3046,3048,304A,304B.otf b/test/subset/data/expected/cff-japanese/SourceHanSans-Regular_subset.drop-hints-desubroutinize-retain-gids.3042,3044,3046,3048,304A,304B.otf
new file mode 100644 (file)
index 0000000..c728315
Binary files /dev/null and b/test/subset/data/expected/cff-japanese/SourceHanSans-Regular_subset.drop-hints-desubroutinize-retain-gids.3042,3044,3046,3048,304A,304B.otf differ
diff --git a/test/subset/data/expected/cff-japanese/SourceHanSans-Regular_subset.drop-hints-desubroutinize-retain-gids.3042,3044,3046,73E0,5EA6,8F38.otf b/test/subset/data/expected/cff-japanese/SourceHanSans-Regular_subset.drop-hints-desubroutinize-retain-gids.3042,3044,3046,73E0,5EA6,8F38.otf
new file mode 100644 (file)
index 0000000..9a0e726
Binary files /dev/null and b/test/subset/data/expected/cff-japanese/SourceHanSans-Regular_subset.drop-hints-desubroutinize-retain-gids.3042,3044,3046,73E0,5EA6,8F38.otf differ
diff --git a/test/subset/data/expected/cff-japanese/SourceHanSans-Regular_subset.drop-hints-desubroutinize-retain-gids.61,63,65,6B.otf b/test/subset/data/expected/cff-japanese/SourceHanSans-Regular_subset.drop-hints-desubroutinize-retain-gids.61,63,65,6B.otf
new file mode 100644 (file)
index 0000000..513d47e
Binary files /dev/null and b/test/subset/data/expected/cff-japanese/SourceHanSans-Regular_subset.drop-hints-desubroutinize-retain-gids.61,63,65,6B.otf differ
diff --git a/test/subset/data/expected/cff-japanese/SourceHanSans-Regular_subset.drop-hints-desubroutinize-retain-gids.660E,6975,73E0,5EA6,8F38,6E05.otf b/test/subset/data/expected/cff-japanese/SourceHanSans-Regular_subset.drop-hints-desubroutinize-retain-gids.660E,6975,73E0,5EA6,8F38,6E05.otf
new file mode 100644 (file)
index 0000000..b10526d
Binary files /dev/null and b/test/subset/data/expected/cff-japanese/SourceHanSans-Regular_subset.drop-hints-desubroutinize-retain-gids.660E,6975,73E0,5EA6,8F38,6E05.otf differ
diff --git a/test/subset/data/expected/cff-japanese/SourceHanSans-Regular_subset.drop-hints-desubroutinize-retain-gids.660E.otf b/test/subset/data/expected/cff-japanese/SourceHanSans-Regular_subset.drop-hints-desubroutinize-retain-gids.660E.otf
new file mode 100644 (file)
index 0000000..2684381
Binary files /dev/null and b/test/subset/data/expected/cff-japanese/SourceHanSans-Regular_subset.drop-hints-desubroutinize-retain-gids.660E.otf differ
diff --git a/test/subset/data/expected/cff-japanese/SourceHanSans-Regular_subset.drop-hints-desubroutinize.3042,3044,3046,3048,304A,304B.otf b/test/subset/data/expected/cff-japanese/SourceHanSans-Regular_subset.drop-hints-desubroutinize.3042,3044,3046,3048,304A,304B.otf
new file mode 100644 (file)
index 0000000..68a254e
Binary files /dev/null and b/test/subset/data/expected/cff-japanese/SourceHanSans-Regular_subset.drop-hints-desubroutinize.3042,3044,3046,3048,304A,304B.otf differ
diff --git a/test/subset/data/expected/cff-japanese/SourceHanSans-Regular_subset.drop-hints-desubroutinize.3042,3044,3046,73E0,5EA6,8F38.otf b/test/subset/data/expected/cff-japanese/SourceHanSans-Regular_subset.drop-hints-desubroutinize.3042,3044,3046,73E0,5EA6,8F38.otf
new file mode 100644 (file)
index 0000000..b900d92
Binary files /dev/null and b/test/subset/data/expected/cff-japanese/SourceHanSans-Regular_subset.drop-hints-desubroutinize.3042,3044,3046,73E0,5EA6,8F38.otf differ
diff --git a/test/subset/data/expected/cff-japanese/SourceHanSans-Regular_subset.drop-hints-desubroutinize.61,63,65,6B.otf b/test/subset/data/expected/cff-japanese/SourceHanSans-Regular_subset.drop-hints-desubroutinize.61,63,65,6B.otf
new file mode 100644 (file)
index 0000000..6b7cc2e
Binary files /dev/null and b/test/subset/data/expected/cff-japanese/SourceHanSans-Regular_subset.drop-hints-desubroutinize.61,63,65,6B.otf differ
diff --git a/test/subset/data/expected/cff-japanese/SourceHanSans-Regular_subset.drop-hints-desubroutinize.660E,6975,73E0,5EA6,8F38,6E05.otf b/test/subset/data/expected/cff-japanese/SourceHanSans-Regular_subset.drop-hints-desubroutinize.660E,6975,73E0,5EA6,8F38,6E05.otf
new file mode 100644 (file)
index 0000000..69b6b2e
Binary files /dev/null and b/test/subset/data/expected/cff-japanese/SourceHanSans-Regular_subset.drop-hints-desubroutinize.660E,6975,73E0,5EA6,8F38,6E05.otf differ
diff --git a/test/subset/data/expected/cff-japanese/SourceHanSans-Regular_subset.drop-hints-desubroutinize.660E.otf b/test/subset/data/expected/cff-japanese/SourceHanSans-Regular_subset.drop-hints-desubroutinize.660E.otf
new file mode 100644 (file)
index 0000000..460bace
Binary files /dev/null and b/test/subset/data/expected/cff-japanese/SourceHanSans-Regular_subset.drop-hints-desubroutinize.660E.otf differ
diff --git a/test/subset/data/expected/cff-japanese/SourceHanSans-Regular_subset.drop-hints-retain-gids.3042,3044,3046,3048,304A,304B.otf b/test/subset/data/expected/cff-japanese/SourceHanSans-Regular_subset.drop-hints-retain-gids.3042,3044,3046,3048,304A,304B.otf
new file mode 100644 (file)
index 0000000..ecdd5d6
Binary files /dev/null and b/test/subset/data/expected/cff-japanese/SourceHanSans-Regular_subset.drop-hints-retain-gids.3042,3044,3046,3048,304A,304B.otf differ
diff --git a/test/subset/data/expected/cff-japanese/SourceHanSans-Regular_subset.drop-hints-retain-gids.3042,3044,3046,73E0,5EA6,8F38.otf b/test/subset/data/expected/cff-japanese/SourceHanSans-Regular_subset.drop-hints-retain-gids.3042,3044,3046,73E0,5EA6,8F38.otf
new file mode 100644 (file)
index 0000000..77b1f95
Binary files /dev/null and b/test/subset/data/expected/cff-japanese/SourceHanSans-Regular_subset.drop-hints-retain-gids.3042,3044,3046,73E0,5EA6,8F38.otf differ
diff --git a/test/subset/data/expected/cff-japanese/SourceHanSans-Regular_subset.drop-hints-retain-gids.61,63,65,6B.otf b/test/subset/data/expected/cff-japanese/SourceHanSans-Regular_subset.drop-hints-retain-gids.61,63,65,6B.otf
new file mode 100644 (file)
index 0000000..8a1bc96
Binary files /dev/null and b/test/subset/data/expected/cff-japanese/SourceHanSans-Regular_subset.drop-hints-retain-gids.61,63,65,6B.otf differ
diff --git a/test/subset/data/expected/cff-japanese/SourceHanSans-Regular_subset.drop-hints-retain-gids.660E,6975,73E0,5EA6,8F38,6E05.otf b/test/subset/data/expected/cff-japanese/SourceHanSans-Regular_subset.drop-hints-retain-gids.660E,6975,73E0,5EA6,8F38,6E05.otf
new file mode 100644 (file)
index 0000000..7d943fd
Binary files /dev/null and b/test/subset/data/expected/cff-japanese/SourceHanSans-Regular_subset.drop-hints-retain-gids.660E,6975,73E0,5EA6,8F38,6E05.otf differ
diff --git a/test/subset/data/expected/cff-japanese/SourceHanSans-Regular_subset.drop-hints-retain-gids.660E.otf b/test/subset/data/expected/cff-japanese/SourceHanSans-Regular_subset.drop-hints-retain-gids.660E.otf
new file mode 100644 (file)
index 0000000..eb01e55
Binary files /dev/null and b/test/subset/data/expected/cff-japanese/SourceHanSans-Regular_subset.drop-hints-retain-gids.660E.otf differ
diff --git a/test/subset/data/expected/cff-japanese/SourceHanSans-Regular_subset.drop-hints.3042,3044,3046,3048,304A,304B.otf b/test/subset/data/expected/cff-japanese/SourceHanSans-Regular_subset.drop-hints.3042,3044,3046,3048,304A,304B.otf
new file mode 100644 (file)
index 0000000..19c8ed8
Binary files /dev/null and b/test/subset/data/expected/cff-japanese/SourceHanSans-Regular_subset.drop-hints.3042,3044,3046,3048,304A,304B.otf differ
diff --git a/test/subset/data/expected/cff-japanese/SourceHanSans-Regular_subset.drop-hints.3042,3044,3046,73E0,5EA6,8F38.otf b/test/subset/data/expected/cff-japanese/SourceHanSans-Regular_subset.drop-hints.3042,3044,3046,73E0,5EA6,8F38.otf
new file mode 100644 (file)
index 0000000..5c7ac1a
Binary files /dev/null and b/test/subset/data/expected/cff-japanese/SourceHanSans-Regular_subset.drop-hints.3042,3044,3046,73E0,5EA6,8F38.otf differ
diff --git a/test/subset/data/expected/cff-japanese/SourceHanSans-Regular_subset.drop-hints.61,63,65,6B.otf b/test/subset/data/expected/cff-japanese/SourceHanSans-Regular_subset.drop-hints.61,63,65,6B.otf
new file mode 100644 (file)
index 0000000..abac3dd
Binary files /dev/null and b/test/subset/data/expected/cff-japanese/SourceHanSans-Regular_subset.drop-hints.61,63,65,6B.otf differ
diff --git a/test/subset/data/expected/cff-japanese/SourceHanSans-Regular_subset.drop-hints.660E,6975,73E0,5EA6,8F38,6E05.otf b/test/subset/data/expected/cff-japanese/SourceHanSans-Regular_subset.drop-hints.660E,6975,73E0,5EA6,8F38,6E05.otf
new file mode 100644 (file)
index 0000000..e593d6d
Binary files /dev/null and b/test/subset/data/expected/cff-japanese/SourceHanSans-Regular_subset.drop-hints.660E,6975,73E0,5EA6,8F38,6E05.otf differ
diff --git a/test/subset/data/expected/cff-japanese/SourceHanSans-Regular_subset.drop-hints.660E.otf b/test/subset/data/expected/cff-japanese/SourceHanSans-Regular_subset.drop-hints.660E.otf
new file mode 100644 (file)
index 0000000..e586904
Binary files /dev/null and b/test/subset/data/expected/cff-japanese/SourceHanSans-Regular_subset.drop-hints.660E.otf differ
diff --git a/test/subset/data/expected/cff-japanese/SourceHanSans-Regular_subset.retain-gids.3042,3044,3046,3048,304A,304B.otf b/test/subset/data/expected/cff-japanese/SourceHanSans-Regular_subset.retain-gids.3042,3044,3046,3048,304A,304B.otf
new file mode 100644 (file)
index 0000000..75f1613
Binary files /dev/null and b/test/subset/data/expected/cff-japanese/SourceHanSans-Regular_subset.retain-gids.3042,3044,3046,3048,304A,304B.otf differ
diff --git a/test/subset/data/expected/cff-japanese/SourceHanSans-Regular_subset.retain-gids.3042,3044,3046,73E0,5EA6,8F38.otf b/test/subset/data/expected/cff-japanese/SourceHanSans-Regular_subset.retain-gids.3042,3044,3046,73E0,5EA6,8F38.otf
new file mode 100644 (file)
index 0000000..6f3794c
Binary files /dev/null and b/test/subset/data/expected/cff-japanese/SourceHanSans-Regular_subset.retain-gids.3042,3044,3046,73E0,5EA6,8F38.otf differ
diff --git a/test/subset/data/expected/cff-japanese/SourceHanSans-Regular_subset.retain-gids.61,63,65,6B.otf b/test/subset/data/expected/cff-japanese/SourceHanSans-Regular_subset.retain-gids.61,63,65,6B.otf
new file mode 100644 (file)
index 0000000..7c5f648
Binary files /dev/null and b/test/subset/data/expected/cff-japanese/SourceHanSans-Regular_subset.retain-gids.61,63,65,6B.otf differ
diff --git a/test/subset/data/expected/cff-japanese/SourceHanSans-Regular_subset.retain-gids.660E,6975,73E0,5EA6,8F38,6E05.otf b/test/subset/data/expected/cff-japanese/SourceHanSans-Regular_subset.retain-gids.660E,6975,73E0,5EA6,8F38,6E05.otf
new file mode 100644 (file)
index 0000000..2dcd75b
Binary files /dev/null and b/test/subset/data/expected/cff-japanese/SourceHanSans-Regular_subset.retain-gids.660E,6975,73E0,5EA6,8F38,6E05.otf differ
diff --git a/test/subset/data/expected/cff-japanese/SourceHanSans-Regular_subset.retain-gids.660E.otf b/test/subset/data/expected/cff-japanese/SourceHanSans-Regular_subset.retain-gids.660E.otf
new file mode 100644 (file)
index 0000000..a5d40d0
Binary files /dev/null and b/test/subset/data/expected/cff-japanese/SourceHanSans-Regular_subset.retain-gids.660E.otf differ
diff --git a/test/subset/data/expected/cmap14/cmap14_font1.default.4E00,4E02,4E03.otf b/test/subset/data/expected/cmap14/cmap14_font1.default.4E00,4E02,4E03.otf
new file mode 100644 (file)
index 0000000..fb41408
Binary files /dev/null and b/test/subset/data/expected/cmap14/cmap14_font1.default.4E00,4E02,4E03.otf differ
diff --git a/test/subset/data/expected/cmap14/cmap14_font1.default.4E00,4E03.otf b/test/subset/data/expected/cmap14/cmap14_font1.default.4E00,4E03.otf
new file mode 100644 (file)
index 0000000..e50256d
Binary files /dev/null and b/test/subset/data/expected/cmap14/cmap14_font1.default.4E00,4E03.otf differ
diff --git a/test/subset/data/expected/cmap14/cmap14_font1.default.4E00,4E05,4E07.otf b/test/subset/data/expected/cmap14/cmap14_font1.default.4E00,4E05,4E07.otf
new file mode 100644 (file)
index 0000000..24f3871
Binary files /dev/null and b/test/subset/data/expected/cmap14/cmap14_font1.default.4E00,4E05,4E07.otf differ
diff --git a/test/subset/data/expected/cmap14/cmap14_font1.default.4E02,4E03,4E08.otf b/test/subset/data/expected/cmap14/cmap14_font1.default.4E02,4E03,4E08.otf
new file mode 100644 (file)
index 0000000..38672ba
Binary files /dev/null and b/test/subset/data/expected/cmap14/cmap14_font1.default.4E02,4E03,4E08.otf differ
diff --git a/test/subset/data/expected/cmap14/cmap14_font1.default.4E02.otf b/test/subset/data/expected/cmap14/cmap14_font1.default.4E02.otf
new file mode 100644 (file)
index 0000000..c5f898e
Binary files /dev/null and b/test/subset/data/expected/cmap14/cmap14_font1.default.4E02.otf differ
diff --git a/test/subset/data/expected/cmap14/cmap14_font1.default.4E03.otf b/test/subset/data/expected/cmap14/cmap14_font1.default.4E03.otf
new file mode 100644 (file)
index 0000000..03cae07
Binary files /dev/null and b/test/subset/data/expected/cmap14/cmap14_font1.default.4E03.otf differ
diff --git a/test/subset/data/expected/cmap14/cmap14_font1.default.4E05,4E07,4E08,4E09.otf b/test/subset/data/expected/cmap14/cmap14_font1.default.4E05,4E07,4E08,4E09.otf
new file mode 100644 (file)
index 0000000..2506a41
Binary files /dev/null and b/test/subset/data/expected/cmap14/cmap14_font1.default.4E05,4E07,4E08,4E09.otf differ
diff --git a/test/subset/data/expected/cmap14/cmap14_font1.default.4E08,4E09.otf b/test/subset/data/expected/cmap14/cmap14_font1.default.4E08,4E09.otf
new file mode 100644 (file)
index 0000000..e8ebeb4
Binary files /dev/null and b/test/subset/data/expected/cmap14/cmap14_font1.default.4E08,4E09.otf differ
diff --git a/test/subset/data/expected/cmap14/cmap14_font1.default.4E08.otf b/test/subset/data/expected/cmap14/cmap14_font1.default.4E08.otf
new file mode 100644 (file)
index 0000000..910cc0f
Binary files /dev/null and b/test/subset/data/expected/cmap14/cmap14_font1.default.4E08.otf differ
diff --git a/test/subset/data/expected/cmap14/cmap14_font1.default.retain-all-codepoint.otf b/test/subset/data/expected/cmap14/cmap14_font1.default.retain-all-codepoint.otf
new file mode 100644 (file)
index 0000000..d7d6972
Binary files /dev/null and b/test/subset/data/expected/cmap14/cmap14_font1.default.retain-all-codepoint.otf differ
diff --git a/test/subset/data/expected/cmap14/cmap14_font1.drop-hints-retain-gids.4E00,4E02,4E03.otf b/test/subset/data/expected/cmap14/cmap14_font1.drop-hints-retain-gids.4E00,4E02,4E03.otf
new file mode 100644 (file)
index 0000000..a1c001c
Binary files /dev/null and b/test/subset/data/expected/cmap14/cmap14_font1.drop-hints-retain-gids.4E00,4E02,4E03.otf differ
diff --git a/test/subset/data/expected/cmap14/cmap14_font1.drop-hints-retain-gids.4E00,4E03.otf b/test/subset/data/expected/cmap14/cmap14_font1.drop-hints-retain-gids.4E00,4E03.otf
new file mode 100644 (file)
index 0000000..5b41802
Binary files /dev/null and b/test/subset/data/expected/cmap14/cmap14_font1.drop-hints-retain-gids.4E00,4E03.otf differ
diff --git a/test/subset/data/expected/cmap14/cmap14_font1.drop-hints-retain-gids.4E00,4E05,4E07.otf b/test/subset/data/expected/cmap14/cmap14_font1.drop-hints-retain-gids.4E00,4E05,4E07.otf
new file mode 100644 (file)
index 0000000..b88e288
Binary files /dev/null and b/test/subset/data/expected/cmap14/cmap14_font1.drop-hints-retain-gids.4E00,4E05,4E07.otf differ
diff --git a/test/subset/data/expected/cmap14/cmap14_font1.drop-hints-retain-gids.4E02,4E03,4E08.otf b/test/subset/data/expected/cmap14/cmap14_font1.drop-hints-retain-gids.4E02,4E03,4E08.otf
new file mode 100644 (file)
index 0000000..6d95272
Binary files /dev/null and b/test/subset/data/expected/cmap14/cmap14_font1.drop-hints-retain-gids.4E02,4E03,4E08.otf differ
diff --git a/test/subset/data/expected/cmap14/cmap14_font1.drop-hints-retain-gids.4E02.otf b/test/subset/data/expected/cmap14/cmap14_font1.drop-hints-retain-gids.4E02.otf
new file mode 100644 (file)
index 0000000..251568f
Binary files /dev/null and b/test/subset/data/expected/cmap14/cmap14_font1.drop-hints-retain-gids.4E02.otf differ
diff --git a/test/subset/data/expected/cmap14/cmap14_font1.drop-hints-retain-gids.4E03.otf b/test/subset/data/expected/cmap14/cmap14_font1.drop-hints-retain-gids.4E03.otf
new file mode 100644 (file)
index 0000000..2b1d7a7
Binary files /dev/null and b/test/subset/data/expected/cmap14/cmap14_font1.drop-hints-retain-gids.4E03.otf differ
diff --git a/test/subset/data/expected/cmap14/cmap14_font1.drop-hints-retain-gids.4E05,4E07,4E08,4E09.otf b/test/subset/data/expected/cmap14/cmap14_font1.drop-hints-retain-gids.4E05,4E07,4E08,4E09.otf
new file mode 100644 (file)
index 0000000..dce7f14
Binary files /dev/null and b/test/subset/data/expected/cmap14/cmap14_font1.drop-hints-retain-gids.4E05,4E07,4E08,4E09.otf differ
diff --git a/test/subset/data/expected/cmap14/cmap14_font1.drop-hints-retain-gids.4E08,4E09.otf b/test/subset/data/expected/cmap14/cmap14_font1.drop-hints-retain-gids.4E08,4E09.otf
new file mode 100644 (file)
index 0000000..e1e2245
Binary files /dev/null and b/test/subset/data/expected/cmap14/cmap14_font1.drop-hints-retain-gids.4E08,4E09.otf differ
diff --git a/test/subset/data/expected/cmap14/cmap14_font1.drop-hints-retain-gids.4E08.otf b/test/subset/data/expected/cmap14/cmap14_font1.drop-hints-retain-gids.4E08.otf
new file mode 100644 (file)
index 0000000..f72cdc9
Binary files /dev/null and b/test/subset/data/expected/cmap14/cmap14_font1.drop-hints-retain-gids.4E08.otf differ
diff --git a/test/subset/data/expected/cmap14/cmap14_font1.drop-hints-retain-gids.retain-all-codepoint.otf b/test/subset/data/expected/cmap14/cmap14_font1.drop-hints-retain-gids.retain-all-codepoint.otf
new file mode 100644 (file)
index 0000000..4efa2e2
Binary files /dev/null and b/test/subset/data/expected/cmap14/cmap14_font1.drop-hints-retain-gids.retain-all-codepoint.otf differ
diff --git a/test/subset/data/expected/cmap14/cmap14_font1.drop-hints.4E00,4E02,4E03.otf b/test/subset/data/expected/cmap14/cmap14_font1.drop-hints.4E00,4E02,4E03.otf
new file mode 100644 (file)
index 0000000..a440b96
Binary files /dev/null and b/test/subset/data/expected/cmap14/cmap14_font1.drop-hints.4E00,4E02,4E03.otf differ
diff --git a/test/subset/data/expected/cmap14/cmap14_font1.drop-hints.4E00,4E03.otf b/test/subset/data/expected/cmap14/cmap14_font1.drop-hints.4E00,4E03.otf
new file mode 100644 (file)
index 0000000..c503e38
Binary files /dev/null and b/test/subset/data/expected/cmap14/cmap14_font1.drop-hints.4E00,4E03.otf differ
diff --git a/test/subset/data/expected/cmap14/cmap14_font1.drop-hints.4E00,4E05,4E07.otf b/test/subset/data/expected/cmap14/cmap14_font1.drop-hints.4E00,4E05,4E07.otf
new file mode 100644 (file)
index 0000000..d36d155
Binary files /dev/null and b/test/subset/data/expected/cmap14/cmap14_font1.drop-hints.4E00,4E05,4E07.otf differ
diff --git a/test/subset/data/expected/cmap14/cmap14_font1.drop-hints.4E02,4E03,4E08.otf b/test/subset/data/expected/cmap14/cmap14_font1.drop-hints.4E02,4E03,4E08.otf
new file mode 100644 (file)
index 0000000..34a8469
Binary files /dev/null and b/test/subset/data/expected/cmap14/cmap14_font1.drop-hints.4E02,4E03,4E08.otf differ
diff --git a/test/subset/data/expected/cmap14/cmap14_font1.drop-hints.4E02.otf b/test/subset/data/expected/cmap14/cmap14_font1.drop-hints.4E02.otf
new file mode 100644 (file)
index 0000000..d695329
Binary files /dev/null and b/test/subset/data/expected/cmap14/cmap14_font1.drop-hints.4E02.otf differ
diff --git a/test/subset/data/expected/cmap14/cmap14_font1.drop-hints.4E03.otf b/test/subset/data/expected/cmap14/cmap14_font1.drop-hints.4E03.otf
new file mode 100644 (file)
index 0000000..1c4d2b5
Binary files /dev/null and b/test/subset/data/expected/cmap14/cmap14_font1.drop-hints.4E03.otf differ
diff --git a/test/subset/data/expected/cmap14/cmap14_font1.drop-hints.4E05,4E07,4E08,4E09.otf b/test/subset/data/expected/cmap14/cmap14_font1.drop-hints.4E05,4E07,4E08,4E09.otf
new file mode 100644 (file)
index 0000000..e5981f0
Binary files /dev/null and b/test/subset/data/expected/cmap14/cmap14_font1.drop-hints.4E05,4E07,4E08,4E09.otf differ
diff --git a/test/subset/data/expected/cmap14/cmap14_font1.drop-hints.4E08,4E09.otf b/test/subset/data/expected/cmap14/cmap14_font1.drop-hints.4E08,4E09.otf
new file mode 100644 (file)
index 0000000..4b76f1c
Binary files /dev/null and b/test/subset/data/expected/cmap14/cmap14_font1.drop-hints.4E08,4E09.otf differ
diff --git a/test/subset/data/expected/cmap14/cmap14_font1.drop-hints.4E08.otf b/test/subset/data/expected/cmap14/cmap14_font1.drop-hints.4E08.otf
new file mode 100644 (file)
index 0000000..cf60215
Binary files /dev/null and b/test/subset/data/expected/cmap14/cmap14_font1.drop-hints.4E08.otf differ
diff --git a/test/subset/data/expected/cmap14/cmap14_font1.drop-hints.retain-all-codepoint.otf b/test/subset/data/expected/cmap14/cmap14_font1.drop-hints.retain-all-codepoint.otf
new file mode 100644 (file)
index 0000000..bf353ed
Binary files /dev/null and b/test/subset/data/expected/cmap14/cmap14_font1.drop-hints.retain-all-codepoint.otf differ
diff --git a/test/subset/data/expected/cmap14/cmap14_font1.name-ids.4E00,4E02,4E03.otf b/test/subset/data/expected/cmap14/cmap14_font1.name-ids.4E00,4E02,4E03.otf
new file mode 100644 (file)
index 0000000..a7b67bf
Binary files /dev/null and b/test/subset/data/expected/cmap14/cmap14_font1.name-ids.4E00,4E02,4E03.otf differ
diff --git a/test/subset/data/expected/cmap14/cmap14_font1.name-ids.4E00,4E03.otf b/test/subset/data/expected/cmap14/cmap14_font1.name-ids.4E00,4E03.otf
new file mode 100644 (file)
index 0000000..7c6805d
Binary files /dev/null and b/test/subset/data/expected/cmap14/cmap14_font1.name-ids.4E00,4E03.otf differ
diff --git a/test/subset/data/expected/cmap14/cmap14_font1.name-ids.4E00,4E05,4E07.otf b/test/subset/data/expected/cmap14/cmap14_font1.name-ids.4E00,4E05,4E07.otf
new file mode 100644 (file)
index 0000000..b1876b6
Binary files /dev/null and b/test/subset/data/expected/cmap14/cmap14_font1.name-ids.4E00,4E05,4E07.otf differ
diff --git a/test/subset/data/expected/cmap14/cmap14_font1.name-ids.4E02,4E03,4E08.otf b/test/subset/data/expected/cmap14/cmap14_font1.name-ids.4E02,4E03,4E08.otf
new file mode 100644 (file)
index 0000000..b07778f
Binary files /dev/null and b/test/subset/data/expected/cmap14/cmap14_font1.name-ids.4E02,4E03,4E08.otf differ
diff --git a/test/subset/data/expected/cmap14/cmap14_font1.name-ids.4E02.otf b/test/subset/data/expected/cmap14/cmap14_font1.name-ids.4E02.otf
new file mode 100644 (file)
index 0000000..fb77632
Binary files /dev/null and b/test/subset/data/expected/cmap14/cmap14_font1.name-ids.4E02.otf differ
diff --git a/test/subset/data/expected/cmap14/cmap14_font1.name-ids.4E03.otf b/test/subset/data/expected/cmap14/cmap14_font1.name-ids.4E03.otf
new file mode 100644 (file)
index 0000000..4ec322c
Binary files /dev/null and b/test/subset/data/expected/cmap14/cmap14_font1.name-ids.4E03.otf differ
diff --git a/test/subset/data/expected/cmap14/cmap14_font1.name-ids.4E05,4E07,4E08,4E09.otf b/test/subset/data/expected/cmap14/cmap14_font1.name-ids.4E05,4E07,4E08,4E09.otf
new file mode 100644 (file)
index 0000000..ec20755
Binary files /dev/null and b/test/subset/data/expected/cmap14/cmap14_font1.name-ids.4E05,4E07,4E08,4E09.otf differ
diff --git a/test/subset/data/expected/cmap14/cmap14_font1.name-ids.4E08,4E09.otf b/test/subset/data/expected/cmap14/cmap14_font1.name-ids.4E08,4E09.otf
new file mode 100644 (file)
index 0000000..bf2c086
Binary files /dev/null and b/test/subset/data/expected/cmap14/cmap14_font1.name-ids.4E08,4E09.otf differ
diff --git a/test/subset/data/expected/cmap14/cmap14_font1.name-ids.4E08.otf b/test/subset/data/expected/cmap14/cmap14_font1.name-ids.4E08.otf
new file mode 100644 (file)
index 0000000..0a3721e
Binary files /dev/null and b/test/subset/data/expected/cmap14/cmap14_font1.name-ids.4E08.otf differ
diff --git a/test/subset/data/expected/cmap14/cmap14_font1.name-ids.retain-all-codepoint.otf b/test/subset/data/expected/cmap14/cmap14_font1.name-ids.retain-all-codepoint.otf
new file mode 100644 (file)
index 0000000..eaaa56d
Binary files /dev/null and b/test/subset/data/expected/cmap14/cmap14_font1.name-ids.retain-all-codepoint.otf differ
diff --git a/test/subset/data/expected/cmap14/cmap14_font1.retain-gids.4E00,4E02,4E03.otf b/test/subset/data/expected/cmap14/cmap14_font1.retain-gids.4E00,4E02,4E03.otf
new file mode 100644 (file)
index 0000000..5c5ce5c
Binary files /dev/null and b/test/subset/data/expected/cmap14/cmap14_font1.retain-gids.4E00,4E02,4E03.otf differ
diff --git a/test/subset/data/expected/cmap14/cmap14_font1.retain-gids.4E00,4E03.otf b/test/subset/data/expected/cmap14/cmap14_font1.retain-gids.4E00,4E03.otf
new file mode 100644 (file)
index 0000000..3b87f54
Binary files /dev/null and b/test/subset/data/expected/cmap14/cmap14_font1.retain-gids.4E00,4E03.otf differ
diff --git a/test/subset/data/expected/cmap14/cmap14_font1.retain-gids.4E00,4E05,4E07.otf b/test/subset/data/expected/cmap14/cmap14_font1.retain-gids.4E00,4E05,4E07.otf
new file mode 100644 (file)
index 0000000..e06a24d
Binary files /dev/null and b/test/subset/data/expected/cmap14/cmap14_font1.retain-gids.4E00,4E05,4E07.otf differ
diff --git a/test/subset/data/expected/cmap14/cmap14_font1.retain-gids.4E02,4E03,4E08.otf b/test/subset/data/expected/cmap14/cmap14_font1.retain-gids.4E02,4E03,4E08.otf
new file mode 100644 (file)
index 0000000..aabdc5e
Binary files /dev/null and b/test/subset/data/expected/cmap14/cmap14_font1.retain-gids.4E02,4E03,4E08.otf differ
diff --git a/test/subset/data/expected/cmap14/cmap14_font1.retain-gids.4E02.otf b/test/subset/data/expected/cmap14/cmap14_font1.retain-gids.4E02.otf
new file mode 100644 (file)
index 0000000..4183c9f
Binary files /dev/null and b/test/subset/data/expected/cmap14/cmap14_font1.retain-gids.4E02.otf differ
diff --git a/test/subset/data/expected/cmap14/cmap14_font1.retain-gids.4E03.otf b/test/subset/data/expected/cmap14/cmap14_font1.retain-gids.4E03.otf
new file mode 100644 (file)
index 0000000..66ef901
Binary files /dev/null and b/test/subset/data/expected/cmap14/cmap14_font1.retain-gids.4E03.otf differ
diff --git a/test/subset/data/expected/cmap14/cmap14_font1.retain-gids.4E05,4E07,4E08,4E09.otf b/test/subset/data/expected/cmap14/cmap14_font1.retain-gids.4E05,4E07,4E08,4E09.otf
new file mode 100644 (file)
index 0000000..4bee46f
Binary files /dev/null and b/test/subset/data/expected/cmap14/cmap14_font1.retain-gids.4E05,4E07,4E08,4E09.otf differ
diff --git a/test/subset/data/expected/cmap14/cmap14_font1.retain-gids.4E08,4E09.otf b/test/subset/data/expected/cmap14/cmap14_font1.retain-gids.4E08,4E09.otf
new file mode 100644 (file)
index 0000000..6e8baa9
Binary files /dev/null and b/test/subset/data/expected/cmap14/cmap14_font1.retain-gids.4E08,4E09.otf differ
diff --git a/test/subset/data/expected/cmap14/cmap14_font1.retain-gids.4E08.otf b/test/subset/data/expected/cmap14/cmap14_font1.retain-gids.4E08.otf
new file mode 100644 (file)
index 0000000..f6191da
Binary files /dev/null and b/test/subset/data/expected/cmap14/cmap14_font1.retain-gids.4E08.otf differ
diff --git a/test/subset/data/expected/cmap14/cmap14_font1.retain-gids.retain-all-codepoint.otf b/test/subset/data/expected/cmap14/cmap14_font1.retain-gids.retain-all-codepoint.otf
new file mode 100644 (file)
index 0000000..bf2746b
Binary files /dev/null and b/test/subset/data/expected/cmap14/cmap14_font1.retain-gids.retain-all-codepoint.otf differ
index 93efe65..e8b7b37 100644 (file)
Binary files a/test/subset/data/expected/full-font/Roboto-Regular.default.1FC,21,41,20,62,63.ttf and b/test/subset/data/expected/full-font/Roboto-Regular.default.1FC,21,41,20,62,63.ttf differ
index d4d26d7..912e1fb 100644 (file)
Binary files a/test/subset/data/expected/full-font/Roboto-Regular.default.61,62,63.ttf and b/test/subset/data/expected/full-font/Roboto-Regular.default.61,62,63.ttf differ
index 7e271f2..6f19df6 100644 (file)
Binary files a/test/subset/data/expected/full-font/Roboto-Regular.default.D7,D8,D9,DA,DE.ttf and b/test/subset/data/expected/full-font/Roboto-Regular.default.D7,D8,D9,DA,DE.ttf differ
index 99b91bd..9ea42ab 100644 (file)
Binary files a/test/subset/data/expected/full-font/Roboto-Regular.drop-hints.1FC,21,41,20,62,63.ttf and b/test/subset/data/expected/full-font/Roboto-Regular.drop-hints.1FC,21,41,20,62,63.ttf differ
index eb94906..4d12593 100644 (file)
Binary files a/test/subset/data/expected/full-font/Roboto-Regular.drop-hints.61,62,63.ttf and b/test/subset/data/expected/full-font/Roboto-Regular.drop-hints.61,62,63.ttf differ
index ff361ba..281b475 100644 (file)
Binary files a/test/subset/data/expected/full-font/Roboto-Regular.drop-hints.D7,D8,D9,DA,DE.ttf and b/test/subset/data/expected/full-font/Roboto-Regular.drop-hints.D7,D8,D9,DA,DE.ttf differ
index 3398999..6770dac 100644 (file)
Binary files a/test/subset/data/expected/japanese/Mplus1p-Regular.default.3042,3044,3046,3048,304A,304B.ttf and b/test/subset/data/expected/japanese/Mplus1p-Regular.default.3042,3044,3046,3048,304A,304B.ttf differ
index 66b98a6..0c66219 100644 (file)
Binary files a/test/subset/data/expected/japanese/Mplus1p-Regular.default.3042,3044,3046,73E0,5EA6,8F38.ttf and b/test/subset/data/expected/japanese/Mplus1p-Regular.default.3042,3044,3046,73E0,5EA6,8F38.ttf differ
index 22d1bb3..4a5a6f8 100644 (file)
Binary files a/test/subset/data/expected/japanese/Mplus1p-Regular.default.61,63,65,6B.ttf and b/test/subset/data/expected/japanese/Mplus1p-Regular.default.61,63,65,6B.ttf differ
index 2804359..465ce34 100644 (file)
Binary files a/test/subset/data/expected/japanese/Mplus1p-Regular.default.660E,6975,73E0,5EA6,8F38,6E05.ttf and b/test/subset/data/expected/japanese/Mplus1p-Regular.default.660E,6975,73E0,5EA6,8F38,6E05.ttf differ
index 333ca51..28f3c37 100644 (file)
Binary files a/test/subset/data/expected/japanese/Mplus1p-Regular.default.660E.ttf and b/test/subset/data/expected/japanese/Mplus1p-Regular.default.660E.ttf differ
index c84b20c..1bebda7 100644 (file)
Binary files a/test/subset/data/expected/japanese/Mplus1p-Regular.drop-hints.3042,3044,3046,3048,304A,304B.ttf and b/test/subset/data/expected/japanese/Mplus1p-Regular.drop-hints.3042,3044,3046,3048,304A,304B.ttf differ
index e757b9e..a43998d 100644 (file)
Binary files a/test/subset/data/expected/japanese/Mplus1p-Regular.drop-hints.3042,3044,3046,73E0,5EA6,8F38.ttf and b/test/subset/data/expected/japanese/Mplus1p-Regular.drop-hints.3042,3044,3046,73E0,5EA6,8F38.ttf differ
index e869ff1..34c7788 100644 (file)
Binary files a/test/subset/data/expected/japanese/Mplus1p-Regular.drop-hints.61,63,65,6B.ttf and b/test/subset/data/expected/japanese/Mplus1p-Regular.drop-hints.61,63,65,6B.ttf differ
index ed4ed4c..92ec10b 100644 (file)
Binary files a/test/subset/data/expected/japanese/Mplus1p-Regular.drop-hints.660E,6975,73E0,5EA6,8F38,6E05.ttf and b/test/subset/data/expected/japanese/Mplus1p-Regular.drop-hints.660E,6975,73E0,5EA6,8F38,6E05.ttf differ
index cb50238..b9bb539 100644 (file)
Binary files a/test/subset/data/expected/japanese/Mplus1p-Regular.drop-hints.660E.ttf and b/test/subset/data/expected/japanese/Mplus1p-Regular.drop-hints.660E.ttf differ
diff --git a/test/subset/data/expected/layout.gpos/gpos1_2_font.keep-layout-retain-gids.41,43.otf b/test/subset/data/expected/layout.gpos/gpos1_2_font.keep-layout-retain-gids.41,43.otf
new file mode 100644 (file)
index 0000000..6b2879f
Binary files /dev/null and b/test/subset/data/expected/layout.gpos/gpos1_2_font.keep-layout-retain-gids.41,43.otf differ
diff --git a/test/subset/data/expected/layout.gpos/gpos1_2_font.keep-layout-retain-gids.41,46.otf b/test/subset/data/expected/layout.gpos/gpos1_2_font.keep-layout-retain-gids.41,46.otf
new file mode 100644 (file)
index 0000000..eebb3e1
Binary files /dev/null and b/test/subset/data/expected/layout.gpos/gpos1_2_font.keep-layout-retain-gids.41,46.otf differ
diff --git a/test/subset/data/expected/layout.gpos/gpos1_2_font.keep-layout-retain-gids.43,46.otf b/test/subset/data/expected/layout.gpos/gpos1_2_font.keep-layout-retain-gids.43,46.otf
new file mode 100644 (file)
index 0000000..c271bde
Binary files /dev/null and b/test/subset/data/expected/layout.gpos/gpos1_2_font.keep-layout-retain-gids.43,46.otf differ
diff --git a/test/subset/data/expected/layout.gpos/gpos1_2_font.keep-layout-retain-gids.retain-all-codepoint.otf b/test/subset/data/expected/layout.gpos/gpos1_2_font.keep-layout-retain-gids.retain-all-codepoint.otf
new file mode 100644 (file)
index 0000000..2d6962b
Binary files /dev/null and b/test/subset/data/expected/layout.gpos/gpos1_2_font.keep-layout-retain-gids.retain-all-codepoint.otf differ
diff --git a/test/subset/data/expected/layout.gpos2/gpos2_1_font7.keep-layout-retain-gids.21,23,25.otf b/test/subset/data/expected/layout.gpos2/gpos2_1_font7.keep-layout-retain-gids.21,23,25.otf
new file mode 100644 (file)
index 0000000..49039fe
Binary files /dev/null and b/test/subset/data/expected/layout.gpos2/gpos2_1_font7.keep-layout-retain-gids.21,23,25.otf differ
diff --git a/test/subset/data/expected/layout.gpos2/gpos2_1_font7.keep-layout-retain-gids.21,23.otf b/test/subset/data/expected/layout.gpos2/gpos2_1_font7.keep-layout-retain-gids.21,23.otf
new file mode 100644 (file)
index 0000000..68cb0ec
Binary files /dev/null and b/test/subset/data/expected/layout.gpos2/gpos2_1_font7.keep-layout-retain-gids.21,23.otf differ
diff --git a/test/subset/data/expected/layout.gpos2/gpos2_1_font7.keep-layout-retain-gids.retain-all-codepoint.otf b/test/subset/data/expected/layout.gpos2/gpos2_1_font7.keep-layout-retain-gids.retain-all-codepoint.otf
new file mode 100644 (file)
index 0000000..8f18b89
Binary files /dev/null and b/test/subset/data/expected/layout.gpos2/gpos2_1_font7.keep-layout-retain-gids.retain-all-codepoint.otf differ
diff --git a/test/subset/data/expected/layout.gpos2/gpos2_1_font7.keep-layout.21,23,25.otf b/test/subset/data/expected/layout.gpos2/gpos2_1_font7.keep-layout.21,23,25.otf
new file mode 100644 (file)
index 0000000..47fea1a
Binary files /dev/null and b/test/subset/data/expected/layout.gpos2/gpos2_1_font7.keep-layout.21,23,25.otf differ
diff --git a/test/subset/data/expected/layout.gpos2/gpos2_1_font7.keep-layout.21,23.otf b/test/subset/data/expected/layout.gpos2/gpos2_1_font7.keep-layout.21,23.otf
new file mode 100644 (file)
index 0000000..99e813f
Binary files /dev/null and b/test/subset/data/expected/layout.gpos2/gpos2_1_font7.keep-layout.21,23.otf differ
diff --git a/test/subset/data/expected/layout.gpos2/gpos2_1_font7.keep-layout.retain-all-codepoint.otf b/test/subset/data/expected/layout.gpos2/gpos2_1_font7.keep-layout.retain-all-codepoint.otf
new file mode 100644 (file)
index 0000000..8f18b89
Binary files /dev/null and b/test/subset/data/expected/layout.gpos2/gpos2_1_font7.keep-layout.retain-all-codepoint.otf differ
diff --git a/test/subset/data/expected/layout.gpos2/gpos2_2_font5.keep-layout-retain-gids.21,23,25.otf b/test/subset/data/expected/layout.gpos2/gpos2_2_font5.keep-layout-retain-gids.21,23,25.otf
new file mode 100644 (file)
index 0000000..b34a49f
Binary files /dev/null and b/test/subset/data/expected/layout.gpos2/gpos2_2_font5.keep-layout-retain-gids.21,23,25.otf differ
diff --git a/test/subset/data/expected/layout.gpos2/gpos2_2_font5.keep-layout-retain-gids.21,23.otf b/test/subset/data/expected/layout.gpos2/gpos2_2_font5.keep-layout-retain-gids.21,23.otf
new file mode 100644 (file)
index 0000000..2ad1d29
Binary files /dev/null and b/test/subset/data/expected/layout.gpos2/gpos2_2_font5.keep-layout-retain-gids.21,23.otf differ
diff --git a/test/subset/data/expected/layout.gpos2/gpos2_2_font5.keep-layout-retain-gids.retain-all-codepoint.otf b/test/subset/data/expected/layout.gpos2/gpos2_2_font5.keep-layout-retain-gids.retain-all-codepoint.otf
new file mode 100644 (file)
index 0000000..88e6046
Binary files /dev/null and b/test/subset/data/expected/layout.gpos2/gpos2_2_font5.keep-layout-retain-gids.retain-all-codepoint.otf differ
diff --git a/test/subset/data/expected/layout.gpos2/gpos2_2_font5.keep-layout.21,23,25.otf b/test/subset/data/expected/layout.gpos2/gpos2_2_font5.keep-layout.21,23,25.otf
new file mode 100644 (file)
index 0000000..195c8dc
Binary files /dev/null and b/test/subset/data/expected/layout.gpos2/gpos2_2_font5.keep-layout.21,23,25.otf differ
diff --git a/test/subset/data/expected/layout.gpos2/gpos2_2_font5.keep-layout.21,23.otf b/test/subset/data/expected/layout.gpos2/gpos2_2_font5.keep-layout.21,23.otf
new file mode 100644 (file)
index 0000000..d10d362
Binary files /dev/null and b/test/subset/data/expected/layout.gpos2/gpos2_2_font5.keep-layout.21,23.otf differ
diff --git a/test/subset/data/expected/layout.gpos2/gpos2_2_font5.keep-layout.retain-all-codepoint.otf b/test/subset/data/expected/layout.gpos2/gpos2_2_font5.keep-layout.retain-all-codepoint.otf
new file mode 100644 (file)
index 0000000..88e6046
Binary files /dev/null and b/test/subset/data/expected/layout.gpos2/gpos2_2_font5.keep-layout.retain-all-codepoint.otf differ
diff --git a/test/subset/data/expected/layout.gpos3/gpos3_font3.keep-layout-retain-gids.28,29.otf b/test/subset/data/expected/layout.gpos3/gpos3_font3.keep-layout-retain-gids.28,29.otf
new file mode 100644 (file)
index 0000000..17aa6d8
Binary files /dev/null and b/test/subset/data/expected/layout.gpos3/gpos3_font3.keep-layout-retain-gids.28,29.otf differ
diff --git a/test/subset/data/expected/layout.gpos3/gpos3_font3.keep-layout-retain-gids.28,2B.otf b/test/subset/data/expected/layout.gpos3/gpos3_font3.keep-layout-retain-gids.28,2B.otf
new file mode 100644 (file)
index 0000000..9e6f2eb
Binary files /dev/null and b/test/subset/data/expected/layout.gpos3/gpos3_font3.keep-layout-retain-gids.28,2B.otf differ
diff --git a/test/subset/data/expected/layout.gpos3/gpos3_font3.keep-layout-retain-gids.29,2B.otf b/test/subset/data/expected/layout.gpos3/gpos3_font3.keep-layout-retain-gids.29,2B.otf
new file mode 100644 (file)
index 0000000..0187ed7
Binary files /dev/null and b/test/subset/data/expected/layout.gpos3/gpos3_font3.keep-layout-retain-gids.29,2B.otf differ
diff --git a/test/subset/data/expected/layout.gpos3/gpos3_font3.keep-layout-retain-gids.retain-all-codepoint.otf b/test/subset/data/expected/layout.gpos3/gpos3_font3.keep-layout-retain-gids.retain-all-codepoint.otf
new file mode 100644 (file)
index 0000000..d9b5dfb
Binary files /dev/null and b/test/subset/data/expected/layout.gpos3/gpos3_font3.keep-layout-retain-gids.retain-all-codepoint.otf differ
diff --git a/test/subset/data/expected/layout.gpos3/gpos3_font3.keep-layout.28,29.otf b/test/subset/data/expected/layout.gpos3/gpos3_font3.keep-layout.28,29.otf
new file mode 100644 (file)
index 0000000..f3ca19a
Binary files /dev/null and b/test/subset/data/expected/layout.gpos3/gpos3_font3.keep-layout.28,29.otf differ
diff --git a/test/subset/data/expected/layout.gpos3/gpos3_font3.keep-layout.28,2B.otf b/test/subset/data/expected/layout.gpos3/gpos3_font3.keep-layout.28,2B.otf
new file mode 100644 (file)
index 0000000..2a8114a
Binary files /dev/null and b/test/subset/data/expected/layout.gpos3/gpos3_font3.keep-layout.28,2B.otf differ
diff --git a/test/subset/data/expected/layout.gpos3/gpos3_font3.keep-layout.29,2B.otf b/test/subset/data/expected/layout.gpos3/gpos3_font3.keep-layout.29,2B.otf
new file mode 100644 (file)
index 0000000..1426d50
Binary files /dev/null and b/test/subset/data/expected/layout.gpos3/gpos3_font3.keep-layout.29,2B.otf differ
diff --git a/test/subset/data/expected/layout.gpos3/gpos3_font3.keep-layout.retain-all-codepoint.otf b/test/subset/data/expected/layout.gpos3/gpos3_font3.keep-layout.retain-all-codepoint.otf
new file mode 100644 (file)
index 0000000..d9b5dfb
Binary files /dev/null and b/test/subset/data/expected/layout.gpos3/gpos3_font3.keep-layout.retain-all-codepoint.otf differ
diff --git a/test/subset/data/expected/layout.gsub6/gsub_chaining1_multiple_subrules_f1.keep-layout-retain-gids.30,31,32,33.otf b/test/subset/data/expected/layout.gsub6/gsub_chaining1_multiple_subrules_f1.keep-layout-retain-gids.30,31,32,33.otf
new file mode 100644 (file)
index 0000000..e10d863
Binary files /dev/null and b/test/subset/data/expected/layout.gsub6/gsub_chaining1_multiple_subrules_f1.keep-layout-retain-gids.30,31,32,33.otf differ
diff --git a/test/subset/data/expected/layout.gsub6/gsub_chaining1_multiple_subrules_f1.keep-layout-retain-gids.retain-all-codepoint.otf b/test/subset/data/expected/layout.gsub6/gsub_chaining1_multiple_subrules_f1.keep-layout-retain-gids.retain-all-codepoint.otf
new file mode 100644 (file)
index 0000000..1f90754
Binary files /dev/null and b/test/subset/data/expected/layout.gsub6/gsub_chaining1_multiple_subrules_f1.keep-layout-retain-gids.retain-all-codepoint.otf differ
diff --git a/test/subset/data/expected/layout.gsub6/gsub_chaining1_multiple_subrules_f1.keep-layout.30,31,32,33.otf b/test/subset/data/expected/layout.gsub6/gsub_chaining1_multiple_subrules_f1.keep-layout.30,31,32,33.otf
new file mode 100644 (file)
index 0000000..bdaa805
Binary files /dev/null and b/test/subset/data/expected/layout.gsub6/gsub_chaining1_multiple_subrules_f1.keep-layout.30,31,32,33.otf differ
diff --git a/test/subset/data/expected/layout.gsub6/gsub_chaining1_multiple_subrules_f1.keep-layout.retain-all-codepoint.otf b/test/subset/data/expected/layout.gsub6/gsub_chaining1_multiple_subrules_f1.keep-layout.retain-all-codepoint.otf
new file mode 100644 (file)
index 0000000..1f90754
Binary files /dev/null and b/test/subset/data/expected/layout.gsub6/gsub_chaining1_multiple_subrules_f1.keep-layout.retain-all-codepoint.otf differ
diff --git a/test/subset/data/expected/layout.gsub6/gsub_chaining2_multiple_subrules_f1.keep-layout-retain-gids.30,31,32,33.otf b/test/subset/data/expected/layout.gsub6/gsub_chaining2_multiple_subrules_f1.keep-layout-retain-gids.30,31,32,33.otf
new file mode 100644 (file)
index 0000000..856249e
Binary files /dev/null and b/test/subset/data/expected/layout.gsub6/gsub_chaining2_multiple_subrules_f1.keep-layout-retain-gids.30,31,32,33.otf differ
diff --git a/test/subset/data/expected/layout.gsub6/gsub_chaining2_multiple_subrules_f1.keep-layout-retain-gids.retain-all-codepoint.otf b/test/subset/data/expected/layout.gsub6/gsub_chaining2_multiple_subrules_f1.keep-layout-retain-gids.retain-all-codepoint.otf
new file mode 100644 (file)
index 0000000..e764393
Binary files /dev/null and b/test/subset/data/expected/layout.gsub6/gsub_chaining2_multiple_subrules_f1.keep-layout-retain-gids.retain-all-codepoint.otf differ
diff --git a/test/subset/data/expected/layout.gsub6/gsub_chaining2_multiple_subrules_f1.keep-layout.30,31,32,33.otf b/test/subset/data/expected/layout.gsub6/gsub_chaining2_multiple_subrules_f1.keep-layout.30,31,32,33.otf
new file mode 100644 (file)
index 0000000..a53b114
Binary files /dev/null and b/test/subset/data/expected/layout.gsub6/gsub_chaining2_multiple_subrules_f1.keep-layout.30,31,32,33.otf differ
diff --git a/test/subset/data/expected/layout.gsub6/gsub_chaining2_multiple_subrules_f1.keep-layout.retain-all-codepoint.otf b/test/subset/data/expected/layout.gsub6/gsub_chaining2_multiple_subrules_f1.keep-layout.retain-all-codepoint.otf
new file mode 100644 (file)
index 0000000..e764393
Binary files /dev/null and b/test/subset/data/expected/layout.gsub6/gsub_chaining2_multiple_subrules_f1.keep-layout.retain-all-codepoint.otf differ
diff --git a/test/subset/data/expected/layout.gsub6/gsub_chaining3_simple_f2.keep-layout-retain-gids.30,31,32,33.otf b/test/subset/data/expected/layout.gsub6/gsub_chaining3_simple_f2.keep-layout-retain-gids.30,31,32,33.otf
new file mode 100644 (file)
index 0000000..2d08eb0
Binary files /dev/null and b/test/subset/data/expected/layout.gsub6/gsub_chaining3_simple_f2.keep-layout-retain-gids.30,31,32,33.otf differ
diff --git a/test/subset/data/expected/layout.gsub6/gsub_chaining3_simple_f2.keep-layout-retain-gids.retain-all-codepoint.otf b/test/subset/data/expected/layout.gsub6/gsub_chaining3_simple_f2.keep-layout-retain-gids.retain-all-codepoint.otf
new file mode 100644 (file)
index 0000000..737f85a
Binary files /dev/null and b/test/subset/data/expected/layout.gsub6/gsub_chaining3_simple_f2.keep-layout-retain-gids.retain-all-codepoint.otf differ
diff --git a/test/subset/data/expected/layout.gsub6/gsub_chaining3_simple_f2.keep-layout.30,31,32,33.otf b/test/subset/data/expected/layout.gsub6/gsub_chaining3_simple_f2.keep-layout.30,31,32,33.otf
new file mode 100644 (file)
index 0000000..fbd9a44
Binary files /dev/null and b/test/subset/data/expected/layout.gsub6/gsub_chaining3_simple_f2.keep-layout.30,31,32,33.otf differ
diff --git a/test/subset/data/expected/layout.gsub6/gsub_chaining3_simple_f2.keep-layout.retain-all-codepoint.otf b/test/subset/data/expected/layout.gsub6/gsub_chaining3_simple_f2.keep-layout.retain-all-codepoint.otf
new file mode 100644 (file)
index 0000000..737f85a
Binary files /dev/null and b/test/subset/data/expected/layout.gsub6/gsub_chaining3_simple_f2.keep-layout.retain-all-codepoint.otf differ
diff --git a/test/subset/data/expected/layout/Roboto-Regular.smallcaps.keep-layout-retain-gids.41,42,43.ttf b/test/subset/data/expected/layout/Roboto-Regular.smallcaps.keep-layout-retain-gids.41,42,43.ttf
new file mode 100644 (file)
index 0000000..aa007ba
Binary files /dev/null and b/test/subset/data/expected/layout/Roboto-Regular.smallcaps.keep-layout-retain-gids.41,42,43.ttf differ
diff --git a/test/subset/data/expected/layout/Roboto-Regular.smallcaps.keep-layout-retain-gids.41,43.ttf b/test/subset/data/expected/layout/Roboto-Regular.smallcaps.keep-layout-retain-gids.41,43.ttf
new file mode 100644 (file)
index 0000000..f3be30c
Binary files /dev/null and b/test/subset/data/expected/layout/Roboto-Regular.smallcaps.keep-layout-retain-gids.41,43.ttf differ
diff --git a/test/subset/data/expected/layout/Roboto-Regular.smallcaps.keep-layout-retain-gids.41.ttf b/test/subset/data/expected/layout/Roboto-Regular.smallcaps.keep-layout-retain-gids.41.ttf
new file mode 100644 (file)
index 0000000..44c329e
Binary files /dev/null and b/test/subset/data/expected/layout/Roboto-Regular.smallcaps.keep-layout-retain-gids.41.ttf differ
diff --git a/test/subset/data/expected/layout/Roboto-Regular.smallcaps.keep-layout-retain-gids.43.ttf b/test/subset/data/expected/layout/Roboto-Regular.smallcaps.keep-layout-retain-gids.43.ttf
new file mode 100644 (file)
index 0000000..b0a1ea3
Binary files /dev/null and b/test/subset/data/expected/layout/Roboto-Regular.smallcaps.keep-layout-retain-gids.43.ttf differ
diff --git a/test/subset/data/expected/layout/Roboto-Regular.smallcaps.keep-layout-retain-gids.CA,CB.ttf b/test/subset/data/expected/layout/Roboto-Regular.smallcaps.keep-layout-retain-gids.CA,CB.ttf
new file mode 100644 (file)
index 0000000..16ad9d5
Binary files /dev/null and b/test/subset/data/expected/layout/Roboto-Regular.smallcaps.keep-layout-retain-gids.CA,CB.ttf differ
diff --git a/test/subset/data/expected/layout/Roboto-Regular.smallcaps.keep-layout.41,42,43.ttf b/test/subset/data/expected/layout/Roboto-Regular.smallcaps.keep-layout.41,42,43.ttf
new file mode 100644 (file)
index 0000000..d0d9d5a
Binary files /dev/null and b/test/subset/data/expected/layout/Roboto-Regular.smallcaps.keep-layout.41,42,43.ttf differ
diff --git a/test/subset/data/expected/layout/Roboto-Regular.smallcaps.keep-layout.41,43.ttf b/test/subset/data/expected/layout/Roboto-Regular.smallcaps.keep-layout.41,43.ttf
new file mode 100644 (file)
index 0000000..f4d881f
Binary files /dev/null and b/test/subset/data/expected/layout/Roboto-Regular.smallcaps.keep-layout.41,43.ttf differ
diff --git a/test/subset/data/expected/layout/Roboto-Regular.smallcaps.keep-layout.41.ttf b/test/subset/data/expected/layout/Roboto-Regular.smallcaps.keep-layout.41.ttf
new file mode 100644 (file)
index 0000000..9e6dd28
Binary files /dev/null and b/test/subset/data/expected/layout/Roboto-Regular.smallcaps.keep-layout.41.ttf differ
diff --git a/test/subset/data/expected/layout/Roboto-Regular.smallcaps.keep-layout.43.ttf b/test/subset/data/expected/layout/Roboto-Regular.smallcaps.keep-layout.43.ttf
new file mode 100644 (file)
index 0000000..50260c5
Binary files /dev/null and b/test/subset/data/expected/layout/Roboto-Regular.smallcaps.keep-layout.43.ttf differ
diff --git a/test/subset/data/expected/layout/Roboto-Regular.smallcaps.keep-layout.CA,CB.ttf b/test/subset/data/expected/layout/Roboto-Regular.smallcaps.keep-layout.CA,CB.ttf
new file mode 100644 (file)
index 0000000..22d5b61
Binary files /dev/null and b/test/subset/data/expected/layout/Roboto-Regular.smallcaps.keep-layout.CA,CB.ttf differ
diff --git a/test/subset/data/fonts/Comfortaa-Regular-new.ttf b/test/subset/data/fonts/Comfortaa-Regular-new.ttf
new file mode 100644 (file)
index 0000000..4965fbe
Binary files /dev/null and b/test/subset/data/fonts/Comfortaa-Regular-new.ttf differ
diff --git a/test/subset/data/fonts/Roboto-Regular.smallcaps.ttf b/test/subset/data/fonts/Roboto-Regular.smallcaps.ttf
new file mode 100644 (file)
index 0000000..fc58299
Binary files /dev/null and b/test/subset/data/fonts/Roboto-Regular.smallcaps.ttf differ
diff --git a/test/subset/data/fonts/SourceHanSans-Regular.otf b/test/subset/data/fonts/SourceHanSans-Regular.otf
deleted file mode 100755 (executable)
index dd807db..0000000
Binary files a/test/subset/data/fonts/SourceHanSans-Regular.otf and /dev/null differ
diff --git a/test/subset/data/fonts/SourceHanSans-Regular_subset.otf b/test/subset/data/fonts/SourceHanSans-Regular_subset.otf
new file mode 100644 (file)
index 0000000..06af9b3
Binary files /dev/null and b/test/subset/data/fonts/SourceHanSans-Regular_subset.otf differ
diff --git a/test/subset/data/fonts/cmap14_font1.otf b/test/subset/data/fonts/cmap14_font1.otf
new file mode 100644 (file)
index 0000000..a4283c6
Binary files /dev/null and b/test/subset/data/fonts/cmap14_font1.otf differ
diff --git a/test/subset/data/fonts/gpos1_2_font.otf b/test/subset/data/fonts/gpos1_2_font.otf
new file mode 100644 (file)
index 0000000..28331f2
Binary files /dev/null and b/test/subset/data/fonts/gpos1_2_font.otf differ
diff --git a/test/subset/data/fonts/gpos2_1_font7.otf b/test/subset/data/fonts/gpos2_1_font7.otf
new file mode 100644 (file)
index 0000000..22b54ea
Binary files /dev/null and b/test/subset/data/fonts/gpos2_1_font7.otf differ
diff --git a/test/subset/data/fonts/gpos2_2_font5.otf b/test/subset/data/fonts/gpos2_2_font5.otf
new file mode 100644 (file)
index 0000000..63af3bc
Binary files /dev/null and b/test/subset/data/fonts/gpos2_2_font5.otf differ
diff --git a/test/subset/data/fonts/gpos3_font3.otf b/test/subset/data/fonts/gpos3_font3.otf
new file mode 100644 (file)
index 0000000..69c74a3
Binary files /dev/null and b/test/subset/data/fonts/gpos3_font3.otf differ
diff --git a/test/subset/data/fonts/gsub_chaining1_multiple_subrules_f1.otf b/test/subset/data/fonts/gsub_chaining1_multiple_subrules_f1.otf
new file mode 100644 (file)
index 0000000..74b9945
Binary files /dev/null and b/test/subset/data/fonts/gsub_chaining1_multiple_subrules_f1.otf differ
diff --git a/test/subset/data/fonts/gsub_chaining2_multiple_subrules_f1.otf b/test/subset/data/fonts/gsub_chaining2_multiple_subrules_f1.otf
new file mode 100644 (file)
index 0000000..a3a1846
Binary files /dev/null and b/test/subset/data/fonts/gsub_chaining2_multiple_subrules_f1.otf differ
diff --git a/test/subset/data/fonts/gsub_chaining3_simple_f2.otf b/test/subset/data/fonts/gsub_chaining3_simple_f2.otf
new file mode 100644 (file)
index 0000000..bc9ed9a
Binary files /dev/null and b/test/subset/data/fonts/gsub_chaining3_simple_f2.otf differ
diff --git a/test/subset/data/profiles/keep-layout-retain-gids.txt b/test/subset/data/profiles/keep-layout-retain-gids.txt
new file mode 100644 (file)
index 0000000..f4787ad
--- /dev/null
@@ -0,0 +1,2 @@
+--drop-tables-=GSUB,GPOS
+--retain-gids
diff --git a/test/subset/data/profiles/keep-layout.txt b/test/subset/data/profiles/keep-layout.txt
new file mode 100644 (file)
index 0000000..56da0ff
--- /dev/null
@@ -0,0 +1 @@
+--drop-tables-=GSUB,GPOS
diff --git a/test/subset/data/profiles/name-ids.txt b/test/subset/data/profiles/name-ids.txt
new file mode 100644 (file)
index 0000000..db42c09
--- /dev/null
@@ -0,0 +1 @@
+--name-IDs=0,1,2
index 4fc3f4e..772f33c 100644 (file)
@@ -1,11 +1,13 @@
 FONTS:
 Roboto-Regular.abc.ttf
+Comfortaa-Regular-new.ttf
 
 PROFILES:
 default.txt
 drop-hints.txt
 drop-hints-retain-gids.txt
 retain-gids.txt
+name-ids.txt
 
 SUBSETS:
 abc
@@ -13,3 +15,4 @@ b
 c
 ac
 a
+*
diff --git a/test/subset/data/tests/cff-full-font.tests b/test/subset/data/tests/cff-full-font.tests
new file mode 100644 (file)
index 0000000..e55f21e
--- /dev/null
@@ -0,0 +1,18 @@
+FONTS:
+SourceSansPro-Regular.otf
+
+PROFILES:
+default.txt
+drop-hints.txt
+drop-hints-retain-gids.txt
+retain-gids.txt
+desubroutinize.txt
+desubroutinize-retain-gids.txt
+drop-hints-desubroutinize.txt
+drop-hints-desubroutinize-retain-gids.txt
+
+SUBSETS:
+abc
+Ǽ!A bc
+×ØÙÚÞ
+
diff --git a/test/subset/data/tests/cff-japanese.tests b/test/subset/data/tests/cff-japanese.tests
new file mode 100644 (file)
index 0000000..d69396f
--- /dev/null
@@ -0,0 +1,22 @@
+FONTS:
+SourceHanSans-Regular_subset.otf
+
+PROFILES:
+default.txt
+drop-hints.txt
+drop-hints-retain-gids.txt
+retain-gids.txt
+desubroutinize.txt
+desubroutinize-retain-gids.txt
+drop-hints-desubroutinize.txt
+drop-hints-desubroutinize-retain-gids.txt
+
+SUBSETS:
+明
+acek
+明極珠度輸清
+あいうえおか
+あいう珠度輸
+
+
+
diff --git a/test/subset/data/tests/cmap14.tests b/test/subset/data/tests/cmap14.tests
new file mode 100644 (file)
index 0000000..6575870
--- /dev/null
@@ -0,0 +1,21 @@
+FONTS:
+cmap14_font1.otf
+
+PROFILES:
+default.txt
+drop-hints.txt
+drop-hints-retain-gids.txt
+retain-gids.txt
+name-ids.txt
+
+SUBSETS:
+一丂七
+丂
+七
+一七
+一丅万
+丅万丈三
+丈
+丈三
+丂七丈
+*
diff --git a/test/subset/data/tests/layout.gpos.tests b/test/subset/data/tests/layout.gpos.tests
new file mode 100644 (file)
index 0000000..2d0f936
--- /dev/null
@@ -0,0 +1,11 @@
+FONTS:
+gpos1_2_font.otf
+
+PROFILES:
+keep-layout-retain-gids.txt
+
+SUBSETS:
+AC
+CF
+AF
+*
diff --git a/test/subset/data/tests/layout.gpos2.tests b/test/subset/data/tests/layout.gpos2.tests
new file mode 100644 (file)
index 0000000..94fe78a
--- /dev/null
@@ -0,0 +1,12 @@
+FONTS:
+gpos2_1_font7.otf
+gpos2_2_font5.otf
+
+PROFILES:
+keep-layout.txt
+keep-layout-retain-gids.txt
+
+SUBSETS:
+!#
+!#%
+*
diff --git a/test/subset/data/tests/layout.gpos3.tests b/test/subset/data/tests/layout.gpos3.tests
new file mode 100644 (file)
index 0000000..409272f
--- /dev/null
@@ -0,0 +1,12 @@
+FONTS:
+gpos3_font3.otf
+
+PROFILES:
+keep-layout.txt
+keep-layout-retain-gids.txt
+
+SUBSETS:
+()
+(+
+)+
+*
diff --git a/test/subset/data/tests/layout.gsub6.tests b/test/subset/data/tests/layout.gsub6.tests
new file mode 100644 (file)
index 0000000..47399b8
--- /dev/null
@@ -0,0 +1,12 @@
+FONTS:
+gsub_chaining1_multiple_subrules_f1.otf
+gsub_chaining2_multiple_subrules_f1.otf
+gsub_chaining3_simple_f2.otf
+
+PROFILES:
+keep-layout.txt
+keep-layout-retain-gids.txt
+
+SUBSETS:
+0123
+*
diff --git a/test/subset/data/tests/layout.tests b/test/subset/data/tests/layout.tests
new file mode 100644 (file)
index 0000000..dd1c26e
--- /dev/null
@@ -0,0 +1,13 @@
+FONTS:
+Roboto-Regular.smallcaps.ttf
+
+PROFILES:
+keep-layout.txt
+keep-layout-retain-gids.txt
+
+SUBSETS:
+ABC
+AC
+C
+A
+ÊË
index fb4684c..5d221e6 100755 (executable)
@@ -1,6 +1,6 @@
 #!/usr/bin/env python
 
-# Runs a subsetting test suite. Compares the results of subsetting via harfbuz
+# Runs a subsetting test suite. Compares the results of subsetting via harfbuzz
 # to subsetting via fonttools.
 
 from __future__ import print_function, division, absolute_import
@@ -16,27 +16,27 @@ import tempfile
 from subset_test_suite import SubsetTestSuite
 
 # https://stackoverflow.com/a/377028
-def which(program):
-       def is_exe(fpath):
-               return os.path.isfile(fpath) and os.access(fpath, os.X_OK)
+def which (program):
+       def is_exe (fpath):
+               return os.path.isfile (fpath) and os.access (fpath, os.X_OK)
 
-       fpath, _ = os.path.split(program)
+       fpath, _ = os.path.split (program)
        if fpath:
-               if is_exe(program):
+               if is_exe (program):
                        return program
        else:
-               for path in os.environ["PATH"].split(os.pathsep):
-                       exe_file = os.path.join(path, program)
-                       if is_exe(exe_file):
+               for path in os.environ["PATH"].split (os.pathsep):
+                       exe_file = os.path.join (path, program)
+                       if is_exe (exe_file):
                                return exe_file
 
        return None
 
-ttx = which ("ttx")
+fonttools = which ("fonttools")
 ots_sanitize = which ("ots-sanitize")
 
-if not ttx:
-       print("TTX is not present, skipping test.")
+if not fonttools:
+       print ("fonttools is not present, skipping test.")
        sys.exit (77)
 
 def cmd(command):
@@ -50,7 +50,7 @@ def read_binary (file_path):
        with open (file_path, 'rb') as f:
                return f.read ()
 
-def fail_test(test, cli_args, message):
+def fail_test (test, cli_args, message):
        print ('ERROR: %s' % message)
        print ('Test State:')
        print ('  test.font_path    %s' % os.path.abspath (test.font_path))
@@ -61,12 +61,13 @@ def fail_test(test, cli_args, message):
        print ('  expected_file     %s' % os.path.abspath (expected_file))
        return 1
 
-def run_test(test, should_check_ots):
-       out_file = os.path.join(tempfile.mkdtemp (), test.get_font_name () + '-subset' + test.get_font_extension ())
+def run_test (test, should_check_ots):
+       out_file = os.path.join (tempfile.mkdtemp (), test.get_font_name () + '-subset' + test.get_font_extension ())
        cli_args = [hb_subset,
                    "--font-file=" + test.font_path,
                    "--output-file=" + out_file,
-                   "--unicodes=%s" % test.unicodes ()]
+                   "--unicodes=%s" % test.unicodes (),
+                   "--drop-tables+=DSIG,GPOS,GSUB,GDEF,gvar,avar,MVAR,HVAR"]
        cli_args.extend (test.get_profile_flags ())
        print (' '.join (cli_args))
        _, return_code = cmd (cli_args)
@@ -75,11 +76,11 @@ def run_test(test, should_check_ots):
                return fail_test (test, cli_args, "%s returned %d" % (' '.join (cli_args), return_code))
 
        expected_ttx, return_code = run_ttx (os.path.join (test_suite.get_output_directory (),
-                                           test.get_font_name ()))
+                                            test.get_font_name ()))
        if return_code:
                return fail_test (test, cli_args, "ttx (expected) returned %d" % (return_code))
 
-       actual_ttx, return_code = run_ttx(out_file)
+       actual_ttx, return_code = run_ttx (out_file)
        if return_code:
                return fail_test (test, cli_args, "ttx (actual) returned %d" % (return_code))
 
@@ -91,7 +92,7 @@ def run_test(test, should_check_ots):
                for line in unified_diff (expected_ttx.splitlines (1), actual_ttx.splitlines (1)):
                        sys.stdout.write (line)
                sys.stdout.flush ()
-               return fail_test(test, cli_args, 'ttx for expected and actual does not match.')
+               return fail_test (test, cli_args, 'ttx for expected and actual does not match.')
 
        if should_check_ots:
                print ("Checking output with ots-sanitize.")
@@ -101,8 +102,8 @@ def run_test(test, should_check_ots):
        return 0
 
 def run_ttx (file):
-       print ("ttx %s" % file)
-       return cmd([ttx, "-q", "-o-", file])
+       print ("fonttools ttx %s" % file)
+       return cmd ([fonttools, "ttx", "-q", "-o-", file])
 
 def strip_check_sum (ttx_string):
        return re.sub ('checkSumAdjustment value=["]0x([0-9a-fA-F])+["]',
@@ -123,7 +124,7 @@ def check_ots (path):
        return True
 
 args = sys.argv[1:]
-if not args or sys.argv[1].find('hb-subset') == -1 or not os.path.exists (sys.argv[1]):
+if not args or sys.argv[1].find ('hb-subset') == -1 or not os.path.exists (sys.argv[1]):
        print ("First argument does not seem to point to usable hb-subset.")
        sys.exit (1)
 hb_subset, args = args[0], args[1:]
@@ -138,7 +139,7 @@ fails = 0
 for path in args:
        with io.open (path, mode="r", encoding="utf-8") as f:
                print ("Running tests in " + path)
-               test_suite = SubsetTestSuite (path, f.read())
+               test_suite = SubsetTestSuite (path, f.read ())
                for test in test_suite.tests ():
                        fails += run_test (test, has_ots)
 
index ad438ee..47664d0 100644 (file)
@@ -12,7 +12,10 @@ class Test:
                self.subset = subset
 
        def unicodes(self):
-               return ",".join("%X" % ord(c) for (i, c) in enumerate(self.subset))
+               if self.subset == '*':
+                       return self.subset[0]
+               else:
+                       return ",".join("%X" % ord(c) for (i, c) in enumerate(self.subset))
 
        def get_profile_flags(self):
                with io.open(self.profile_path, mode="r", encoding="utf-8") as f:
@@ -23,7 +26,12 @@ class Test:
                font_base_name_parts = os.path.splitext(font_base_name)
                profile_name = os.path.splitext(os.path.basename(self.profile_path))[0]
 
-               return "%s.%s.%s%s" % (font_base_name_parts[0],
+               if self.unicodes() == "*":
+                       return "%s.%s.retain-all-codepoint%s" % (font_base_name_parts[0],
+                                      profile_name,
+                                      font_base_name_parts[1])
+               else:
+                       return "%s.%s.%s%s" % (font_base_name_parts[0],
                                       profile_name,
                                       self.unicodes(),
                                       font_base_name_parts[1])
@@ -39,9 +47,9 @@ class SubsetTestSuite:
 
        def __init__(self, test_path, definition):
                self.test_path = test_path
-               self.fonts = set()
-               self.profiles = set()
-               self.subsets = set()
+               self.fonts = []
+               self.profiles = []
+               self.subsets = []
                self._parse(definition)
 
        def get_output_directory(self):
@@ -87,6 +95,6 @@ class SubsetTestSuite:
                        if line in destinations:
                                current_destination = destinations[line]
                        elif current_destination is not None:
-                               current_destination.add(line)
+                               current_destination.append(line)
                        else:
                                raise Exception("Failed to parse test suite file.")
index e24a6f3..5298e77 100644 (file)
@@ -50,8 +50,9 @@ bin_PROGRAMS += hb-shape
 
 hb_subset_SOURCES = $(HB_SUBSET_CLI_sources)
 hb_subset_LDADD = \
-       $(LDADD) \
-       $(top_builddir)/src/libharfbuzz-subset.la
+       $(top_builddir)/src/libharfbuzz-subset.la \
+       $(LDADD)
+
 bin_PROGRAMS += hb-subset
 
 hb_ot_shape_closure_SOURCES = $(HB_OT_SHAPE_CLOSURE_sources)
index 40f116f..d8f7b32 100644 (file)
@@ -97,6 +97,7 @@ subdir = util
 ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
 am__aclocal_m4_deps = $(top_srcdir)/m4/ax_check_link_flag.m4 \
        $(top_srcdir)/m4/ax_code_coverage.m4 \
+       $(top_srcdir)/m4/ax_cxx_compile_stdcxx.m4 \
        $(top_srcdir)/m4/ax_pthread.m4 $(top_srcdir)/m4/gtk-doc.m4 \
        $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \
        $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \
@@ -138,16 +139,18 @@ hb_shape_LDADD = $(LDADD)
 hb_shape_DEPENDENCIES = $(top_builddir)/src/libharfbuzz.la \
        $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \
        $(am__DEPENDENCIES_1)
-am__hb_subset_SOURCES_DIST = hb-subset.cc options.cc options.hh \
-       main-font-text.hh
-am__objects_4 = hb-subset.$(OBJEXT) options.$(OBJEXT) $(am__objects_1)
+am__hb_subset_SOURCES_DIST = hb-subset.cc options.cc options-subset.cc \
+       options.hh main-font-text.hh
+am__objects_4 = hb-subset.$(OBJEXT) options.$(OBJEXT) \
+       options-subset.$(OBJEXT) $(am__objects_1)
 @HAVE_GLIB_TRUE@am_hb_subset_OBJECTS = $(am__objects_4)
 hb_subset_OBJECTS = $(am_hb_subset_OBJECTS)
 am__DEPENDENCIES_2 = $(top_builddir)/src/libharfbuzz.la \
        $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \
        $(am__DEPENDENCIES_1)
-@HAVE_GLIB_TRUE@hb_subset_DEPENDENCIES = $(am__DEPENDENCIES_2) \
-@HAVE_GLIB_TRUE@       $(top_builddir)/src/libharfbuzz-subset.la
+@HAVE_GLIB_TRUE@hb_subset_DEPENDENCIES =  \
+@HAVE_GLIB_TRUE@       $(top_builddir)/src/libharfbuzz-subset.la \
+@HAVE_GLIB_TRUE@       $(am__DEPENDENCIES_2)
 am__hb_view_SOURCES_DIST = hb-view.cc options.cc options.hh \
        main-font-text.hh shape-consumer.hh ansi-print.cc \
        ansi-print.hh helper-cairo.cc helper-cairo.hh \
@@ -182,7 +185,8 @@ am__depfiles_remade = ./$(DEPDIR)/ansi-print.Po \
        ./$(DEPDIR)/hb-ot-shape-closure.Po ./$(DEPDIR)/hb-shape.Po \
        ./$(DEPDIR)/hb-subset.Po ./$(DEPDIR)/hb-view.Po \
        ./$(DEPDIR)/helper-cairo-ansi.Po ./$(DEPDIR)/helper-cairo.Po \
-       ./$(DEPDIR)/options.Po ./$(DEPDIR)/view-cairo.Po
+       ./$(DEPDIR)/options-subset.Po ./$(DEPDIR)/options.Po \
+       ./$(DEPDIR)/view-cairo.Po
 am__mv = mv -f
 CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
        $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS)
@@ -301,6 +305,8 @@ FREETYPE_CFLAGS = @FREETYPE_CFLAGS@
 FREETYPE_DEPS = @FREETYPE_DEPS@
 FREETYPE_LIBS = @FREETYPE_LIBS@
 GCOV = @GCOV@
+GDI_CFLAGS = @GDI_CFLAGS@
+GDI_LIBS = @GDI_LIBS@
 GENHTML = @GENHTML@
 GIT = @GIT@
 GLIB_CFLAGS = @GLIB_CFLAGS@
@@ -319,6 +325,7 @@ GTKDOC_DEPS_CFLAGS = @GTKDOC_DEPS_CFLAGS@
 GTKDOC_DEPS_LIBS = @GTKDOC_DEPS_LIBS@
 GTKDOC_MKPDF = @GTKDOC_MKPDF@
 GTKDOC_REBASE = @GTKDOC_REBASE@
+HAVE_CXX11 = @HAVE_CXX11@
 HB_LIBTOOL_VERSION_INFO = @HB_LIBTOOL_VERSION_INFO@
 HB_VERSION = @HB_VERSION@
 HB_VERSION_MAJOR = @HB_VERSION_MAJOR@
@@ -477,6 +484,7 @@ HB_OT_SHAPE_CLOSURE_sources = \
 HB_SUBSET_CLI_sources = \
        hb-subset.cc \
        options.cc \
+       options-subset.cc \
        options.hh \
        main-font-text.hh \
        $(NULL)
@@ -507,8 +515,8 @@ LDADD = \
 @HAVE_GLIB_TRUE@hb_shape_SOURCES = $(HB_SHAPE_sources)
 @HAVE_GLIB_TRUE@hb_subset_SOURCES = $(HB_SUBSET_CLI_sources)
 @HAVE_GLIB_TRUE@hb_subset_LDADD = \
-@HAVE_GLIB_TRUE@       $(LDADD) \
-@HAVE_GLIB_TRUE@       $(top_builddir)/src/libharfbuzz-subset.la
+@HAVE_GLIB_TRUE@       $(top_builddir)/src/libharfbuzz-subset.la \
+@HAVE_GLIB_TRUE@       $(LDADD)
 
 @HAVE_GLIB_TRUE@hb_ot_shape_closure_SOURCES = $(HB_OT_SHAPE_CLOSURE_sources)
 all: all-am
@@ -640,6 +648,7 @@ distclean-compile:
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/hb-view.Po@am__quote@ # am--include-marker
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/helper-cairo-ansi.Po@am__quote@ # am--include-marker
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/helper-cairo.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/options-subset.Po@am__quote@ # am--include-marker
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/options.Po@am__quote@ # am--include-marker
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/view-cairo.Po@am__quote@ # am--include-marker
 
@@ -813,6 +822,7 @@ distclean: distclean-am
        -rm -f ./$(DEPDIR)/hb-view.Po
        -rm -f ./$(DEPDIR)/helper-cairo-ansi.Po
        -rm -f ./$(DEPDIR)/helper-cairo.Po
+       -rm -f ./$(DEPDIR)/options-subset.Po
        -rm -f ./$(DEPDIR)/options.Po
        -rm -f ./$(DEPDIR)/view-cairo.Po
        -rm -f Makefile
@@ -867,6 +877,7 @@ maintainer-clean: maintainer-clean-am
        -rm -f ./$(DEPDIR)/hb-view.Po
        -rm -f ./$(DEPDIR)/helper-cairo-ansi.Po
        -rm -f ./$(DEPDIR)/helper-cairo.Po
+       -rm -f ./$(DEPDIR)/options-subset.Po
        -rm -f ./$(DEPDIR)/options.Po
        -rm -f ./$(DEPDIR)/view-cairo.Po
        -rm -f Makefile
index 6c815d2..bcf85f5 100644 (file)
@@ -32,6 +32,7 @@ HB_OT_SHAPE_CLOSURE_sources = \
 HB_SUBSET_CLI_sources = \
        hb-subset.cc \
        options.cc \
+       options-subset.cc \
        options.hh \
        main-font-text.hh \
        $(NULL)
index 49a0477..58df0a6 100644 (file)
@@ -133,7 +133,7 @@ struct image_t
        for (unsigned int col = 0; col < w; col++)
          *q++ = *p++;
       else {
-        unsigned int limit = width - x;
+       unsigned int limit = width - x;
        for (unsigned int col = 0; col < limit; col++)
          *q++ = *p++;
        p--;
@@ -171,17 +171,17 @@ struct biimage_t
     int freq[8] = {0};
     for (unsigned int y = 0; y < height; y++)
       for (unsigned int x = 0; x < width; x++) {
-        color_t c = image (x, y);
-        freq[c.to_ansi ()]++;
+       color_t c = image (x, y);
+       freq[c.to_ansi ()]++;
       }
     bg = 0;
     for (unsigned int i = 1; i < 8; i++)
       if (freq[bg] < freq[i])
-        bg = i;
+       bg = i;
     fg = 0;
     for (unsigned int i = 1; i < 8; i++)
       if (i != bg && freq[fg] < freq[i])
-        fg = i;
+       fg = i;
     if (fg == bg || freq[fg] == 0) {
       fg = bg;
       unicolor = true;
@@ -202,7 +202,7 @@ struct biimage_t
     int dd = diff.dot (diff);
     for (unsigned int y = 0; y < height; y++)
       for (unsigned int x = 0; x < width; x++) {
-        int d = diff.dot (image (x, y).diff (bgc));
+       int d = diff.dot (image (x, y).diff (bgc));
        (*this)(x, y) = d < 0 ? 0 : d > dd ? 255 : lround (d * 255. / dd);
       }
   }
@@ -287,13 +287,13 @@ block_best (const biimage_t &bi, bool *inverse)
       unsigned int s;
       s = row_sum[i] + total_i - row_sum_i[i];
       if (s < best_s) {
-        best_s = s;
+       best_s = s;
        best_i = i;
        best_inv = false;
       }
       s = row_sum_i[i] + total - row_sum[i];
       if (s < best_s) {
-        best_s = s;
+       best_s = s;
        best_i = i;
        best_inv = true;
       }
@@ -319,13 +319,13 @@ block_best (const biimage_t &bi, bool *inverse)
       unsigned int s;
       s = col_sum[i] + total_i - col_sum_i[i];
       if (s < best_s) {
-        best_s = s;
+       best_s = s;
        best_i = i;
        best_inv = true;
       }
       s = col_sum_i[i] + total - col_sum[i];
       if (s < best_s) {
-        best_s = s;
+       best_s = s;
        best_i = i;
        best_inv = false;
       }
@@ -396,15 +396,15 @@ ansi_print_image_rgb24 (const uint32_t *data,
       image.copy_sub_image (cell, col * CELL_W, row * CELL_H, CELL_W, CELL_H);
       bi.set (cell);
       if (bi.unicolor) {
-        if (last_bg != bi.bg) {
+       if (last_bg != bi.bg) {
          printf ("%c[%dm", ESC_E, 40 + bi.bg);
          last_bg = bi.bg;
        }
        printf (" ");
       } else {
-        /* Figure out the closest character to the biimage */
+       /* Figure out the closest character to the biimage */
        bool inverse = false;
-        const char *c = block_best (bi, &inverse);
+       const char *c = block_best (bi, &inverse);
        if (inverse) {
          if (last_bg != bi.fg || last_fg != bi.bg) {
            printf ("%c[%d;%dm", ESC_E, 30 + bi.bg, 40 + bi.fg);
index 77ca201..33f531b 100644 (file)
@@ -39,7 +39,7 @@ struct shape_closure_consumer_t : option_group_t
     add_options (parser);
   }
 
-  void add_options (struct option_parser_t *parser)
+  void add_options (struct option_parser_t *parser) override
   {
     GOptionEntry entries[] =
     {
index 3ae3fa1..bab5cba 100644 (file)
@@ -181,7 +181,7 @@ main (int argc, char **argv)
       fflush (stdout);
 
       if (ret)
-        break;
+       break;
     }
     return ret;
   }
index 33e584b..008e4e6 100644 (file)
@@ -40,19 +40,26 @@ struct subset_consumer_t
       : failed (false), options (parser), subset_options (parser), font (nullptr), input (nullptr) {}
 
   void init (hb_buffer_t  *buffer_,
-             const font_options_t *font_opts)
+            const font_options_t *font_opts)
   {
     font = hb_font_reference (font_opts->get_font ());
-    input = hb_subset_input_create_or_fail ();
+    input = hb_subset_input_reference (subset_options.input);
   }
 
   void consume_line (const char   *text,
-                     unsigned int  text_len,
-                     const char   *text_before,
-                     const char   *text_after)
+                    unsigned int  text_len,
+                    const char   *text_before,
+                    const char   *text_after)
   {
     // TODO(Q1) does this only get called with at least 1 codepoint?
     hb_set_t *codepoints = hb_subset_input_unicode_set (input);
+    if (0 == strcmp (text, "*"))
+    {
+      hb_face_t *face = hb_font_get_face (font);
+      hb_face_collect_unicodes (face, codepoints);
+      return;
+    }
+
     gchar *c = (gchar *)text;
     do {
       gunichar cp = g_utf8_get_char(c);
@@ -81,7 +88,7 @@ struct subset_consumer_t
     }
     if ((unsigned int) bytes_written != data_length) {
       fprintf(stderr, "Expected %u bytes written, got %d\n", data_length,
-              bytes_written);
+             bytes_written);
       return false;
     }
     return true;
@@ -89,11 +96,6 @@ struct subset_consumer_t
 
   void finish (const font_options_t *font_opts)
   {
-    hb_subset_input_set_drop_layout (input, !subset_options.keep_layout);
-    hb_subset_input_set_drop_hints (input, subset_options.drop_hints);
-    hb_subset_input_set_retain_gids (input, subset_options.retain_gids);
-    hb_subset_input_set_desubroutinize (input, subset_options.desubroutinize);
-
     hb_face_t *face = hb_font_get_face (font);
 
     hb_face_t *new_face = hb_subset (face, input);
index 50f9eb4..cbda493 100644 (file)
@@ -71,7 +71,7 @@ helper_cairo_surface_write_to_ansi_stream (cairo_surface_t    *surface,
     unsigned int i;
     for (i = 0; i < width; i++)
       if (data[i] != bg_color)
-        break;
+       break;
     if (i < width)
       break;
     data += stride / 4;
@@ -86,7 +86,7 @@ helper_cairo_surface_write_to_ansi_stream (cairo_surface_t    *surface,
     unsigned int i;
     for (i = 0; i < width; i++)
       if (row[i] != bg_color)
-        break;
+       break;
     if (i < width)
       break;
     height--;
index b4f94a9..42cce71 100644 (file)
@@ -97,7 +97,7 @@ helper_cairo_create_scaled_font (const font_options_t *font_opts)
 
     if (FT_New_Memory_Face (ft_library,
                            (const FT_Byte *) blob_data,
-                            blob_length,
+                           blob_length,
                            font_opts->face_index,
                            &ft_face))
       fail (false, "FT_New_Memory_Face fail");
diff --git a/util/options-subset.cc b/util/options-subset.cc
new file mode 100644 (file)
index 0000000..35fa05e
--- /dev/null
@@ -0,0 +1,144 @@
+/*
+ * Copyright © 2019  Google, Inc.
+ *
+ *  This is part of HarfBuzz, a text shaping library.
+ *
+ * Permission is hereby granted, without written agreement and without
+ * license or royalty fees, to use, copy, modify, and distribute this
+ * software and its documentation for any purpose, provided that the
+ * above copyright notice and the following two paragraphs appear in
+ * all copies of this software.
+ *
+ * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
+ * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
+ * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
+ * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+ * DAMAGE.
+ *
+ * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
+ * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS
+ * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
+ * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
+ *
+ * Google Author(s): Garret Rieger
+ */
+
+#include "options.hh"
+
+#include "hb-subset-input.hh"
+
+static gboolean
+parse_nameids (const char *name,
+              const char *arg,
+              gpointer    data,
+              GError    **error G_GNUC_UNUSED)
+{
+  subset_options_t *subset_opts = (subset_options_t *) data;
+  hb_set_t *name_ids = subset_opts->input->name_ids;
+
+  char last_name_char = name[strlen (name) - 1];
+
+  if (last_name_char != '+' && last_name_char != '-')
+    hb_set_clear (name_ids);
+
+  if (0 == strcmp (arg, "*"))
+  {
+    if (last_name_char == '-')
+      hb_set_del_range (name_ids, 0, 0x7FFF);
+    else
+      hb_set_add_range (name_ids, 0, 0x7FFF);
+    return true;
+  }
+
+  char *s = (char *) arg;
+  char *p;
+
+  while (s && *s)
+  {
+    while (*s && strchr (", ", *s))
+      s++;
+    if (!*s)
+      break;
+
+    errno = 0;
+    hb_codepoint_t u = strtoul (s, &p, 10);
+    if (errno || s == p)
+    {
+      hb_set_destroy (name_ids);
+      g_set_error (error, G_OPTION_ERROR, G_OPTION_ERROR_BAD_VALUE,
+                  "Failed parsing nameID values at: '%s'", s);
+      return false;
+    }
+
+    if (last_name_char != '-')
+    {
+      hb_set_add (name_ids, u);
+    } else {
+      hb_set_del (name_ids, u);
+    }
+
+    s = p;
+  }
+
+  return true;
+}
+
+static gboolean
+parse_drop_tables (const char *name,
+                  const char *arg,
+                  gpointer    data,
+                  GError    **error G_GNUC_UNUSED)
+{
+  subset_options_t *subset_opts = (subset_options_t *) data;
+  hb_set_t *drop_tables = subset_opts->input->drop_tables;
+
+  char last_name_char = name[strlen (name) - 1];
+
+  if (last_name_char != '+' && last_name_char != '-')
+    hb_set_clear (drop_tables);
+
+  char *s = strtok((char *) arg, ", ");
+  while (s)
+  {
+    if (strlen (s) > 4) // Table tags are at most 4 bytes.
+    {
+      g_set_error (error, G_OPTION_ERROR, G_OPTION_ERROR_BAD_VALUE,
+                  "Failed parsing table tag values at: '%s'", s);
+      return false;
+    }
+
+    hb_tag_t tag = hb_tag_from_string (s, strlen (s));
+
+    if (last_name_char != '-')
+      hb_set_add (drop_tables, tag);
+    else
+      hb_set_del (drop_tables, tag);
+
+    s = strtok(nullptr, ", ");
+  }
+
+  return true;
+}
+
+void
+subset_options_t::add_options (option_parser_t *parser)
+{
+  GOptionEntry entries[] =
+  {
+    {"no-hinting", 0, 0, G_OPTION_ARG_NONE,  &this->input->drop_hints,   "Whether to drop hints",   nullptr},
+    {"retain-gids", 0, 0, G_OPTION_ARG_NONE,  &this->input->retain_gids,   "If set don't renumber glyph ids in the subset.",   nullptr},
+    {"desubroutinize", 0, 0, G_OPTION_ARG_NONE,  &this->input->desubroutinize,   "Remove CFF/CFF2 use of subroutines",   nullptr},
+    {"name-IDs", 0, 0, G_OPTION_ARG_CALLBACK,  (gpointer) &parse_nameids,  "Subset specified nameids", "list of int numbers"},
+    {"drop-tables", 0, 0, G_OPTION_ARG_CALLBACK,  (gpointer) &parse_drop_tables,  "Drop the specified tables.", "list of string table tags."},
+    {"drop-tables+", 0, 0, G_OPTION_ARG_CALLBACK,  (gpointer) &parse_drop_tables,  "Drop the specified tables.", "list of string table tags."},
+    {"drop-tables-", 0, 0, G_OPTION_ARG_CALLBACK,  (gpointer) &parse_drop_tables,  "Drop the specified tables.", "list of string table tags."},
+
+    {nullptr}
+  };
+  parser->add_group (entries,
+        "subset",
+        "Subset options:",
+        "Options subsetting",
+        this);
+}
index c5a4f0f..43ff90a 100644 (file)
@@ -31,6 +31,8 @@
 #endif
 #include <hb-ot.h>
 
+#define DELIMITERS "<+>{},;&#\\xXuUnNiI\n\t\v\f\r "
+
 static struct supported_font_funcs_t {
        char name[4];
        void (*func) (hb_font_t *);
@@ -194,8 +196,8 @@ parse_shapers (const char *name G_GNUC_UNUSED,
     bool found = false;
     for (const char **hb_shaper = hb_shape_list_shapers (); *hb_shaper; hb_shaper++) {
       if (strcmp (*shaper, *hb_shaper) == 0) {
-        found = true;
-        break;
+       found = true;
+       break;
       }
     }
     if (!found) {
@@ -226,9 +228,9 @@ list_shapers (const char *name G_GNUC_UNUSED,
 
 static gboolean
 parse_features (const char *name G_GNUC_UNUSED,
-               const char *arg,
-               gpointer    data,
-               GError    **error G_GNUC_UNUSED)
+               const char *arg,
+               gpointer    data,
+               GError    **error G_GNUC_UNUSED)
 {
   shape_options_t *shape_opts = (shape_options_t *) data;
   char *s = (char *) arg;
@@ -269,9 +271,9 @@ parse_features (const char *name G_GNUC_UNUSED,
 
 static gboolean
 parse_variations (const char *name G_GNUC_UNUSED,
-               const char *arg,
-               gpointer    data,
-               GError    **error G_GNUC_UNUSED)
+                 const char *arg,
+                 gpointer    data,
+                 GError    **error G_GNUC_UNUSED)
 {
   font_options_t *font_opts = (font_options_t *) data;
   char *s = (char *) arg;
@@ -333,9 +335,9 @@ parse_text (const char *name G_GNUC_UNUSED,
 
 static gboolean
 parse_unicodes (const char *name G_GNUC_UNUSED,
-               const char *arg,
-               gpointer    data,
-               GError    **error G_GNUC_UNUSED)
+               const char *arg,
+               gpointer    data,
+               GError    **error G_GNUC_UNUSED)
 {
   text_options_t *text_opts = (text_options_t *) data;
 
@@ -347,28 +349,37 @@ parse_unicodes (const char *name G_GNUC_UNUSED,
   }
 
   GString *gs = g_string_new (nullptr);
-  char *s = (char *) arg;
-  char *p;
-
-  while (s && *s)
+  if (0 == strcmp (arg, "*"))
+  {
+    g_string_append_c (gs, '*');
+  }
+  else
   {
-    while (*s && strchr ("<+>{},;&#\\xXuUnNiI\n\t\v\f\r ", *s))
-      s++;
-    if (!*s)
-      break;
 
-    errno = 0;
-    hb_codepoint_t u = strtoul (s, &p, 16);
-    if (errno || s == p)
+    char *s = (char *) arg;
+    char *p;
+
+    while (s && *s)
     {
-      g_set_error (error, G_OPTION_ERROR, G_OPTION_ERROR_BAD_VALUE,
-                  "Failed parsing Unicode values at: '%s'", s);
-      return false;
-    }
+      while (*s && strchr (DELIMITERS, *s))
+       s++;
+      if (!*s)
+       break;
 
-    g_string_append_unichar (gs, u);
+      errno = 0;
+      hb_codepoint_t u = strtoul (s, &p, 16);
+      if (errno || s == p)
+      {
+       g_string_free (gs, TRUE);
+       g_set_error (error, G_OPTION_ERROR, G_OPTION_ERROR_BAD_VALUE,
+                  "Failed parsing Unicode values at: '%s'", s);
+       return false;
+      }
 
-    s = p;
+      g_string_append_unichar (gs, u);
+
+      s = p;
+    }
   }
 
   text_opts->text_len = gs->len;
@@ -705,7 +716,7 @@ font_options_t::get_font () const
       GString *s = g_string_new (nullptr);
       for (unsigned int i = 0; i < ARRAY_LENGTH (supported_font_funcs); i++)
       {
-        if (i)
+       if (i)
          g_string_append_c (s, '/');
        g_string_append (s, supported_font_funcs[i].name);
       }
@@ -866,9 +877,9 @@ format_options_t::add_options (option_parser_t *parser)
   parser->add_group (entries,
                     "output-syntax",
                     "Output syntax:\n"
-         "    text: [<glyph name or index>=<glyph cluster index within input>@<horizontal displacement>,<vertical displacement>+<horizontal advance>,<vertical advance>|...]\n"
-         "    json: [{\"g\": <glyph name or index>, \"ax\": <horizontal advance>, \"ay\": <vertical advance>, \"dx\": <horizontal displacement>, \"dy\": <vertical displacement>, \"cl\": <glyph cluster index within input>}, ...]\n"
-         "\nOutput syntax options:",
+        "    text: [<glyph name or index>=<glyph cluster index within input>@<horizontal displacement>,<vertical displacement>+<horizontal advance>,<vertical advance>|...]\n"
+        "    json: [{\"g\": <glyph name or index>, \"ax\": <horizontal advance>, \"ay\": <vertical advance>, \"dx\": <horizontal displacement>, \"dy\": <vertical displacement>, \"cl\": <glyph cluster index within input>}, ...]\n"
+        "\nOutput syntax options:",
                     "Options for the syntax of the output",
                     this);
 }
@@ -970,22 +981,3 @@ format_options_t::serialize_buffer_of_glyphs (hb_buffer_t  *buffer,
   serialize_glyphs (buffer, font, output_format, format_flags, gs);
   g_string_append_c (gs, '\n');
 }
-
-void
-subset_options_t::add_options (option_parser_t *parser)
-{
-  GOptionEntry entries[] =
-  {
-    {"layout", 0, 0, G_OPTION_ARG_NONE,  &this->keep_layout,   "Keep OpenType Layout tables",   nullptr},
-    {"no-hinting", 0, 0, G_OPTION_ARG_NONE,  &this->drop_hints,   "Whether to drop hints",   nullptr},
-    {"retain-gids", 0, 0, G_OPTION_ARG_NONE,  &this->retain_gids,   "If set don't renumber glyph ids in the subset.",   nullptr},
-    {"desubroutinize", 0, 0, G_OPTION_ARG_NONE,  &this->desubroutinize,   "Remove CFF/CFF2 use of subroutines",   nullptr},
-
-    {nullptr}
-  };
-  parser->add_group (entries,
-         "subset",
-         "Subset options:",
-         "Options subsetting",
-         this);
-}
index 84139f5..9e22b40 100644 (file)
@@ -28,6 +28,7 @@
 #define OPTIONS_HH
 
 #include "hb.hh"
+#include "hb-subset.h"
 
 #include <stdlib.h>
 #include <stddef.h>
@@ -128,13 +129,13 @@ struct view_options_t : option_group_t
 
     add_options (parser);
   }
-  virtual ~view_options_t ()
+  ~view_options_t () override
   {
     g_free (fore);
     g_free (back);
   }
 
-  void add_options (option_parser_t *parser);
+  void add_options (option_parser_t *parser) override;
 
   hb_bool_t annotate;
   char *fore;
@@ -164,7 +165,7 @@ struct shape_options_t : option_group_t
 
     add_options (parser);
   }
-  virtual ~shape_options_t ()
+  ~shape_options_t () override
   {
     g_free (direction);
     g_free (language);
@@ -173,7 +174,7 @@ struct shape_options_t : option_group_t
     g_strfreev (shapers);
   }
 
-  void add_options (option_parser_t *parser);
+  void add_options (option_parser_t *parser) override;
 
   void setup_buffer (hb_buffer_t *buffer)
   {
@@ -241,7 +242,7 @@ struct shape_options_t : option_group_t
     if (!hb_shape_full (font, buffer, features, num_features, shapers))
     {
       if (error)
-        *error = "all shapers failed.";
+       *error = "all shapers failed.";
       goto fail;
     }
 
@@ -340,7 +341,7 @@ struct shape_options_t : option_group_t
       /* Shape segment corresponding to glyphs start..end. */
       if (end == num_glyphs)
       {
-        if (forward)
+       if (forward)
          text_end = num_chars;
        else
          text_start = 0;
@@ -371,9 +372,9 @@ struct shape_options_t : option_group_t
       /* TODO: Add pre/post context text. */
       hb_buffer_flags_t flags = hb_buffer_get_flags (fragment);
       if (0 < text_start)
-        flags = (hb_buffer_flags_t) (flags & ~HB_BUFFER_FLAG_BOT);
+       flags = (hb_buffer_flags_t) (flags & ~HB_BUFFER_FLAG_BOT);
       if (text_end < num_chars)
-        flags = (hb_buffer_flags_t) (flags & ~HB_BUFFER_FLAG_EOT);
+       flags = (hb_buffer_flags_t) (flags & ~HB_BUFFER_FLAG_EOT);
       hb_buffer_set_flags (fragment, flags);
 
       hb_buffer_append (fragment, text_buffer, text_start, text_end);
@@ -470,7 +471,7 @@ struct font_options_t : option_group_t
 
     add_options (parser);
   }
-  virtual ~font_options_t ()
+  ~font_options_t () override
   {
     g_free (font_file);
     free (variations);
@@ -478,7 +479,7 @@ struct font_options_t : option_group_t
     hb_font_destroy (font);
   }
 
-  void add_options (option_parser_t *parser);
+  void add_options (option_parser_t *parser) override;
 
   hb_font_t *get_font () const;
 
@@ -520,7 +521,7 @@ struct text_options_t : option_group_t
 
     add_options (parser);
   }
-  virtual ~text_options_t ()
+  ~text_options_t () override
   {
     g_free (text_before);
     g_free (text_after);
@@ -532,9 +533,9 @@ struct text_options_t : option_group_t
       fclose (fp);
   }
 
-  void add_options (option_parser_t *parser);
+  void add_options (option_parser_t *parser) override;
 
-  void post_parse (GError **error G_GNUC_UNUSED) {
+  void post_parse (GError **error G_GNUC_UNUSED) override {
     if (text && text_file)
       g_set_error (error,
                   G_OPTION_ERROR, G_OPTION_ERROR_BAD_VALUE,
@@ -571,7 +572,7 @@ struct output_options_t : option_group_t
 
     add_options (parser);
   }
-  virtual ~output_options_t ()
+  ~output_options_t () override
   {
     g_free (output_file);
     g_free (output_format);
@@ -579,9 +580,9 @@ struct output_options_t : option_group_t
       fclose (fp);
   }
 
-  void add_options (option_parser_t *parser);
+  void add_options (option_parser_t *parser) override;
 
-  void post_parse (GError **error G_GNUC_UNUSED)
+  void post_parse (GError **error G_GNUC_UNUSED) override
   {
     if (output_format)
       explicit_output_format = true;
@@ -626,7 +627,7 @@ struct format_options_t : option_group_t
     add_options (parser);
   }
 
-  void add_options (option_parser_t *parser);
+  void add_options (option_parser_t *parser) override;
 
   void serialize_unicode (hb_buffer_t  *buffer,
                          GString      *gs);
@@ -673,20 +674,18 @@ struct subset_options_t : option_group_t
 {
   subset_options_t (option_parser_t *parser)
   {
-    keep_layout = false;
-    drop_hints = false;
-    retain_gids = false;
-    desubroutinize = false;
-
+    input = hb_subset_input_create_or_fail ();
     add_options (parser);
   }
 
-  void add_options (option_parser_t *parser);
+  ~subset_options_t () override
+  {
+    hb_subset_input_destroy (input);
+  }
+
+  void add_options (option_parser_t *parser) override;
 
-  hb_bool_t keep_layout;
-  hb_bool_t drop_hints;
-  hb_bool_t retain_gids;
-  hb_bool_t desubroutinize;
+  hb_subset_input_t *input;
 };
 
 /* fallback implementation for scalbn()/scalbnf() for pre-2013 MSVC */