diff options
author | Allan Sandfeld Jensen <allan.jensen@qt.io> | 2018-05-15 10:20:33 +0200 |
---|---|---|
committer | Allan Sandfeld Jensen <allan.jensen@qt.io> | 2018-05-15 10:28:57 +0000 |
commit | d17ea114e5ef69ad5d5d7413280a13e6428098aa (patch) | |
tree | 2c01a75df69f30d27b1432467cfe7c1467a498da /chromium/third_party/harfbuzz-ng | |
parent | 8c5c43c7b138c9b4b0bf56d946e61d3bbc111bec (diff) | |
download | qtwebengine-chromium-d17ea114e5ef69ad5d5d7413280a13e6428098aa.tar.gz |
BASELINE: Update Chromium to 67.0.3396.47
Change-Id: Idcb1341782e417561a2473eeecc82642dafda5b7
Reviewed-by: Michal Klocek <michal.klocek@qt.io>
Diffstat (limited to 'chromium/third_party/harfbuzz-ng')
276 files changed, 30179 insertions, 1215 deletions
diff --git a/chromium/third_party/harfbuzz-ng/BUILD.gn b/chromium/third_party/harfbuzz-ng/BUILD.gn index d1dafdec3ac..c8bd9c6f9d3 100644 --- a/chromium/third_party/harfbuzz-ng/BUILD.gn +++ b/chromium/third_party/harfbuzz-ng/BUILD.gn @@ -20,7 +20,7 @@ if (use_system_harfbuzz) { } } else { config("harfbuzz_config") { - include_dirs = [ "src" ] + include_dirs = [ "src/src" ] } config("harfbuzz_warnings") { @@ -45,121 +45,130 @@ if (use_system_harfbuzz) { visibility = [ "//third_party:freetype_harfbuzz" ] sources = [ - "src/hb-atomic-private.hh", - "src/hb-blob.cc", - "src/hb-blob.h", - "src/hb-buffer-deserialize-json.hh", - "src/hb-buffer-deserialize-text.hh", - "src/hb-buffer-private.hh", - "src/hb-buffer-serialize.cc", - "src/hb-buffer.cc", - "src/hb-buffer.h", - "src/hb-cache-private.hh", - "src/hb-common.cc", - "src/hb-common.h", - "src/hb-debug.hh", - "src/hb-deprecated.h", - "src/hb-dsalgs.hh", - "src/hb-face-private.hh", - "src/hb-face.cc", - "src/hb-face.h", - "src/hb-font-private.hh", - "src/hb-font.cc", - "src/hb-font.h", - "src/hb-ft.cc", - "src/hb-ft.h", - "src/hb-icu.cc", - "src/hb-icu.h", - "src/hb-mutex-private.hh", - "src/hb-object-private.hh", - "src/hb-open-file-private.hh", - "src/hb-open-type-private.hh", - "src/hb-ot-font.cc", - "src/hb-ot-font.h", - "src/hb-ot-head-table.hh", - "src/hb-ot-hhea-table.hh", - "src/hb-ot-hmtx-table.hh", - "src/hb-ot-kern-table.hh", - "src/hb-ot-layout-common-private.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-private.hh", - "src/hb-ot-layout-private.hh", - "src/hb-ot-layout.cc", - "src/hb-ot-layout.h", - "src/hb-ot-map-private.hh", - "src/hb-ot-map.cc", - "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-name-table.hh", - "src/hb-ot-post-macroman.hh", - "src/hb-ot-shape-complex-arabic-fallback.hh", - "src/hb-ot-shape-complex-arabic-private.hh", - "src/hb-ot-shape-complex-arabic-table.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-private.hh", - "src/hb-ot-shape-complex-indic-table.cc", - "src/hb-ot-shape-complex-indic.cc", - "src/hb-ot-shape-complex-khmer-machine.hh", - "src/hb-ot-shape-complex-khmer-private.hh", - "src/hb-ot-shape-complex-khmer.cc", - "src/hb-ot-shape-complex-myanmar-machine.hh", - "src/hb-ot-shape-complex-myanmar-private.hh", - "src/hb-ot-shape-complex-myanmar.cc", - "src/hb-ot-shape-complex-private.hh", - "src/hb-ot-shape-complex-thai.cc", - "src/hb-ot-shape-complex-tibetan.cc", - "src/hb-ot-shape-complex-use-machine.hh", - "src/hb-ot-shape-complex-use-private.hh", - "src/hb-ot-shape-complex-use-table.cc", - "src/hb-ot-shape-complex-use.cc", - "src/hb-ot-shape-fallback-private.hh", - "src/hb-ot-shape-fallback.cc", - "src/hb-ot-shape-normalize-private.hh", - "src/hb-ot-shape-normalize.cc", - "src/hb-ot-shape-private.hh", - "src/hb-ot-shape.cc", - "src/hb-ot-shape.h", - "src/hb-ot-tag.cc", - "src/hb-ot-tag.h", - "src/hb-ot-var-avar-table.hh", - "src/hb-ot-var-fvar-table.hh", - "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.h", - "src/hb-private.hh", - "src/hb-set-digest-private.hh", - "src/hb-set-private.hh", - "src/hb-set.cc", - "src/hb-set.h", - "src/hb-shape-plan-private.hh", - "src/hb-shape-plan.cc", - "src/hb-shape-plan.h", - "src/hb-shape.cc", - "src/hb-shape.h", - "src/hb-shaper-impl-private.hh", - "src/hb-shaper-list.hh", - "src/hb-shaper-private.hh", - "src/hb-shaper.cc", - "src/hb-string-array.hh", - "src/hb-subset-plan.h", - "src/hb-subset.h", - "src/hb-unicode-private.hh", - "src/hb-unicode.cc", - "src/hb-unicode.h", - "src/hb-utf-private.hh", - "src/hb-version.h", - "src/hb-warning.cc", - "src/hb.h", + "src/src/hb-atomic-private.hh", + "src/src/hb-blob.cc", + "src/src/hb-blob.h", + "src/src/hb-buffer-deserialize-json.hh", + "src/src/hb-buffer-deserialize-text.hh", + "src/src/hb-buffer-private.hh", + "src/src/hb-buffer-serialize.cc", + "src/src/hb-buffer.cc", + "src/src/hb-buffer.h", + "src/src/hb-cache-private.hh", + "src/src/hb-common.cc", + "src/src/hb-common.h", + "src/src/hb-debug.hh", + "src/src/hb-deprecated.h", + "src/src/hb-dsalgs.hh", + "src/src/hb-face-private.hh", + "src/src/hb-face.cc", + "src/src/hb-face.h", + "src/src/hb-font-private.hh", + "src/src/hb-font.cc", + "src/src/hb-font.h", + "src/src/hb-ft.cc", + "src/src/hb-ft.h", + "src/src/hb-icu.cc", + "src/src/hb-icu.h", + "src/src/hb-mutex-private.hh", + "src/src/hb-object-private.hh", + "src/src/hb-open-file-private.hh", + "src/src/hb-open-type-private.hh", + "src/src/hb-ot-color-cbdt-table.hh", + "src/src/hb-ot-color-colr-table.hh", + "src/src/hb-ot-color-cpal-table.hh", + "src/src/hb-ot-font.cc", + "src/src/hb-ot-font.h", + "src/src/hb-ot-hdmx-table.hh", + "src/src/hb-ot-head-table.hh", + "src/src/hb-ot-hhea-table.hh", + "src/src/hb-ot-hmtx-table.hh", + "src/src/hb-ot-kern-table.hh", + "src/src/hb-ot-layout-base-table.hh", + "src/src/hb-ot-layout-base-table.hh", + "src/src/hb-ot-layout-common-private.hh", + "src/src/hb-ot-layout-gdef-table.hh", + "src/src/hb-ot-layout-gpos-table.hh", + "src/src/hb-ot-layout-gsub-table.hh", + "src/src/hb-ot-layout-gsubgpos-private.hh", + "src/src/hb-ot-layout-private.hh", + "src/src/hb-ot-layout.cc", + "src/src/hb-ot-layout.h", + "src/src/hb-ot-map-private.hh", + "src/src/hb-ot-map.cc", + "src/src/hb-ot-math-table.hh", + "src/src/hb-ot-math.cc", + "src/src/hb-ot-math.h", + "src/src/hb-ot-maxp-table.hh", + "src/src/hb-ot-name-table.hh", + "src/src/hb-ot-os2-unicode-ranges.hh", + "src/src/hb-ot-post-macroman.hh", + "src/src/hb-ot-shape-complex-arabic-fallback.hh", + "src/src/hb-ot-shape-complex-arabic-private.hh", + "src/src/hb-ot-shape-complex-arabic-table.hh", + "src/src/hb-ot-shape-complex-arabic.cc", + "src/src/hb-ot-shape-complex-default.cc", + "src/src/hb-ot-shape-complex-hangul.cc", + "src/src/hb-ot-shape-complex-hebrew.cc", + "src/src/hb-ot-shape-complex-indic-machine.hh", + "src/src/hb-ot-shape-complex-indic-private.hh", + "src/src/hb-ot-shape-complex-indic-table.cc", + "src/src/hb-ot-shape-complex-indic.cc", + "src/src/hb-ot-shape-complex-khmer-machine.hh", + "src/src/hb-ot-shape-complex-khmer-private.hh", + "src/src/hb-ot-shape-complex-khmer.cc", + "src/src/hb-ot-shape-complex-myanmar-machine.hh", + "src/src/hb-ot-shape-complex-myanmar-private.hh", + "src/src/hb-ot-shape-complex-myanmar.cc", + "src/src/hb-ot-shape-complex-private.hh", + "src/src/hb-ot-shape-complex-thai.cc", + "src/src/hb-ot-shape-complex-tibetan.cc", + "src/src/hb-ot-shape-complex-use-machine.hh", + "src/src/hb-ot-shape-complex-use-private.hh", + "src/src/hb-ot-shape-complex-use-table.cc", + "src/src/hb-ot-shape-complex-use.cc", + "src/src/hb-ot-shape-fallback-private.hh", + "src/src/hb-ot-shape-fallback.cc", + "src/src/hb-ot-shape-normalize-private.hh", + "src/src/hb-ot-shape-normalize.cc", + "src/src/hb-ot-shape-private.hh", + "src/src/hb-ot-shape.cc", + "src/src/hb-ot-shape.h", + "src/src/hb-ot-tag.cc", + "src/src/hb-ot-tag.h", + "src/src/hb-ot-var-avar-table.hh", + "src/src/hb-ot-var-fvar-table.hh", + "src/src/hb-ot-var-hvar-table.hh", + "src/src/hb-ot-var-mvar-table.hh", + "src/src/hb-ot-var.cc", + "src/src/hb-ot-var.h", + "src/src/hb-ot.h", + "src/src/hb-private.hh", + "src/src/hb-set-digest-private.hh", + "src/src/hb-set-private.hh", + "src/src/hb-set.cc", + "src/src/hb-set.h", + "src/src/hb-shape-plan-private.hh", + "src/src/hb-shape-plan.cc", + "src/src/hb-shape-plan.h", + "src/src/hb-shape.cc", + "src/src/hb-shape.h", + "src/src/hb-shaper-impl-private.hh", + "src/src/hb-shaper-list.hh", + "src/src/hb-shaper-private.hh", + "src/src/hb-shaper.cc", + "src/src/hb-string-array.hh", + "src/src/hb-subset-glyf.hh", + "src/src/hb-subset-plan.h", + "src/src/hb-subset-private.hh", + "src/src/hb-subset.h", + "src/src/hb-unicode-private.hh", + "src/src/hb-unicode.cc", + "src/src/hb-unicode.h", + "src/src/hb-utf-private.hh", + "src/src/hb-version.h", + "src/src/hb-warning.cc", + "src/src/hb.h", ] defines = [ @@ -199,8 +208,8 @@ if (use_system_harfbuzz) { if (is_mac) { sources += [ - "src/hb-coretext.cc", - "src/hb-coretext.h", + "src/src/hb-coretext.cc", + "src/src/hb-coretext.h", ] defines += [ "HAVE_CORETEXT" ] libs = [ @@ -213,8 +222,8 @@ if (use_system_harfbuzz) { if (use_glib) { configs += [ "//build/config/linux:glib" ] sources += [ - "src/hb-glib.cc", - "src/hb-glib.h", + "src/src/hb-glib.cc", + "src/src/hb-glib.h", ] } } diff --git a/chromium/third_party/harfbuzz-ng/README b/chromium/third_party/harfbuzz-ng/README deleted file mode 100644 index 69a1bdd9ff3..00000000000 --- a/chromium/third_party/harfbuzz-ng/README +++ /dev/null @@ -1,12 +0,0 @@ -[![Build Status](https://travis-ci.org/behdad/harfbuzz.svg)](https://travis-ci.org/behdad/harfbuzz) -[![Build Status](https://ci.appveyor.com/api/projects/status/4oaq58ns2h0m2soa?svg=true)](https://ci.appveyor.com/project/behdad/harfbuzz) -[![Coverage Status](https://img.shields.io/coveralls/behdad/harfbuzz.svg)](https://coveralls.io/r/behdad/harfbuzz) -[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 the file COPYING. diff --git a/chromium/third_party/harfbuzz-ng/README.chromium b/chromium/third_party/harfbuzz-ng/README.chromium index a6b334433ad..98165ba858d 100644 --- a/chromium/third_party/harfbuzz-ng/README.chromium +++ b/chromium/third_party/harfbuzz-ng/README.chromium @@ -1,47 +1,51 @@ Name: harfbuzz-ng Short Name: harfbuzz-ng URL: http://harfbuzz.org -Version: 1.7.5 + 0c66043a..0bff6991 -Date: 20180219 +Version: 1.7.6 +Date: 20180319 +Revision: 957e7756634a4fdf1654041e20e883cf964ecac9 Security Critical: yes License: MIT -License File: COPYING +License File: src/COPYING Description: This is harfbuzz-ng, a new implementation of harfbuzz with a different API from the old one. -This copy of harfbuzz is usually updated by downloading the release tarball from -http://www.freedesktop.org/software/harfbuzz/release/ , removing files in src, -copying *.h *.hh *.cc (except for hb-uniscribe* and hb-directwrite.* and -hb-fallback-shape.cc) from the tarball's src folder over to src, then checking -for removed or added files and update our build recipes in BUILD.gn and -harfbuzz.gyp accordingly, update the NEWS file from HarfBuzz' release notes, and -bump the version numbers in README.chromium. +This copy of harfbuzz is updated by putting the new commit hash matching one in +https://chromium.googlesource.com/external/github.com/harfbuzz/harfbuzz/ to the +top level DEPS file. When upgrading, check whether files have been added or +removed in upstream and whether the BUILD.gn file needs to be updated to reflect +that. -Currently the following files from HarfBuzz are unused and not copied: - dump-indic-data.cc - dump-khmer-data.cc - dump-myanmar-data.cc - dump-use-data.cc - hb-aat-layout-common-private.hh - hb-aat-layout-kerx-table.hh - hb-aat-layout-morx-table.hh - hb-aat-layout-private.hh - hb-aat-layout.cc - hb-directwrite.cc - hb-directwrite.h - hb-fallback-shape.cc - hb-subset-glyf.cc - hb-subset-glyf.hh - hb-subset-input.cc - hb-subset-plan.cc - hb-subset-private.hh - hb-subset.cc - hb-uniscribe.cc - hb-uniscribe.h +Chromium-local cherry picks or patches can be done by pushing new branches to +refs/heads/chromium/ of [1]. The set of HarfBuzz OWNERS has write rights to this +part of the tree. We suggest to follow a pattern of naming branches needed for +Chromium revisions by the chromium milestone number. For example, if a +cherry-pick is needed for M65, push to "refs/heads/chromium/m65" and reference +the new commit in DEPS. Take a look at +https://chromium-review.googlesource.com/c/chromium/src/+/937502 for an example. -Cherry-pick 0c66043a..0bff6991 to test hb_set optimizations and page size -change. - -Patch hb-ot-shape.cc to not include any aat headers yet.
\ No newline at end of file +Currently we are intentionally not building the following files from HarfBuzz. + dump-indic-data.cc + dump-khmer-data.cc + dump-myanmar-data.cc + dump-use-data.cc + hb-aat-layout-ankr-table.hh + hb-aat-layout-common-private.hh + hb-aat-layout-kerx-table.hh + hb-aat-layout-morx-table.hh + hb-aat-layout-private.hh + hb-aat-layout-trak-table.hh + hb-aat-layout.cc + hb-directwrite.cc + hb-directwrite.h + hb-fallback-shape.cc + hb-ot-color.cc + hb-subset-glyf.cc + hb-subset-input.cc + hb-subset-plan.cc + hb-subset.cc + hb-uniscribe.cc + hb-uniscribe.h + test-unicode-ranges.cc diff --git a/chromium/third_party/harfbuzz-ng/src/.ci/deploy-docs.sh b/chromium/third_party/harfbuzz-ng/src/.ci/deploy-docs.sh new file mode 100755 index 00000000000..a8a85233195 --- /dev/null +++ b/chromium/third_party/harfbuzz-ng/src/.ci/deploy-docs.sh @@ -0,0 +1,36 @@ +#!/bin/bash + +set -x +set -o errexit -o nounset + +if test "x$TRAVIS_SECURE_ENV_VARS" != xtrue; then exit; fi + +BRANCH="$TRAVIS_BRANCH" +if test "x$BRANCH" != xmaster; then exit; fi + +TAG="$(git describe --exact-match --match "[0-9]*" HEAD 2>/dev/null || true)" + +DOCSDIR=build-docs +REVISION=$(git rev-parse --short HEAD) + +rm -rf $DOCSDIR || exit +mkdir $DOCSDIR +cd $DOCSDIR + +cp ../docs/html/* . +#cp ../docs/CNAME . + +git init +git config user.name "Travis CI" +git config user.email "travis@harfbuzz.org" +set +x +echo "git remote add upstream \"https://\$GH_TOKEN@github.com/harfbuzz/harfbuzz.github.io.git\"" +git remote add upstream "https://$GH_TOKEN@github.com/harfbuzz/harfbuzz.github.io.git" +set -x +git fetch upstream +git reset upstream/master + +touch . +git add -A . +git commit -m "Rebuild docs for https://github.com/harfbuzz/harfbuzz/commit/$REVISION" +git push -q upstream HEAD:master diff --git a/chromium/third_party/harfbuzz-ng/src/.ci/fail.sh b/chromium/third_party/harfbuzz-ng/src/.ci/fail.sh new file mode 100755 index 00000000000..4e0069e3f8a --- /dev/null +++ b/chromium/third_party/harfbuzz-ng/src/.ci/fail.sh @@ -0,0 +1,18 @@ +#!/bin/bash + +for f in $(find . -name '*.log' -not -name 'config.log'); do + last=$(tail -1 $f) + if [[ $last = FAIL* ]]; then + echo '====' $f '====' + cat $f + elif [[ $last = PASS* ]]; then + # Do nothing. + true + else + # Travis Linux images has an old automake that does not match the + # patterns above, so in case of doubt just print the file. + cat $f + fi +done + +exit 1 diff --git a/chromium/third_party/harfbuzz-ng/src/.ci/run-coveralls.sh b/chromium/third_party/harfbuzz-ng/src/.ci/run-coveralls.sh new file mode 100755 index 00000000000..8d1ceb5e25a --- /dev/null +++ b/chromium/third_party/harfbuzz-ng/src/.ci/run-coveralls.sh @@ -0,0 +1,14 @@ +#!/bin/bash + +set -x +set -o errexit -o nounset + +if test x"$TRAVIS_REPO_SLUG" != x"harfbuzz/harfbuzz"; then exit; fi + +pip install --user nose +pip install --user cpp-coveralls +export PATH=$HOME/.local/bin:$PATH + +rm -f src/.libs/NONE.gcov +touch src/NONE +coveralls -e docs diff --git a/chromium/third_party/harfbuzz-ng/src/.ci/trigger-coverity.sh b/chromium/third_party/harfbuzz-ng/src/.ci/trigger-coverity.sh new file mode 100644 index 00000000000..19852bd1187 --- /dev/null +++ b/chromium/third_party/harfbuzz-ng/src/.ci/trigger-coverity.sh @@ -0,0 +1,11 @@ +#!/bin/bash + +set -x +set -o errexit -o nounset + +if test x"$TRAVIS_EVENT_TYPE" != x"cron"; then exit; fi +if test x"$TRAVIS_BRANCH" != x"master"; then exit; fi + +git fetch --unshallow +git remote add upstream "https://$GH_TOKEN@github.com/harfbuzz/harfbuzz.git" +git push -q upstream master:coverity_scan diff --git a/chromium/third_party/harfbuzz-ng/src/.circleci/config.yml b/chromium/third_party/harfbuzz-ng/src/.circleci/config.yml new file mode 100644 index 00000000000..8ef10586132 --- /dev/null +++ b/chromium/third_party/harfbuzz-ng/src/.circleci/config.yml @@ -0,0 +1,191 @@ +version: 2 + +jobs: + + distcheck: + docker: + - image: ubuntu:17.10 + steps: + - checkout + - run: apt update && apt install -y ninja-build binutils libtool autoconf automake make cmake gcc g++ pkg-config ragel gtk-doc-tools libfreetype6-dev libglib2.0-dev libcairo2-dev libicu-dev libgraphite2-dev python python-pip + - run: pip install fonttools + - run: ./autogen.sh + - run: make + - run: make distcheck || .ci/fail.sh + - run: rm -rf harfbuzz-* + - run: make distdir && cd harfbuzz-* && cmake -DHB_CHECK=ON -Bbuild -H. -GNinja && ninja -Cbuild && CTEST_OUTPUT_ON_FAILURE=1 ninja -Cbuild test && ninja -Cbuild install + + alpine-O3: + docker: + - image: alpine + steps: + - checkout + - run: apk update && apk add ragel make pkgconfig libtool autoconf automake gettext gcc g++ glib-dev freetype-dev cairo-dev + # C??FLAGS are not needed for a regular build + - run: CFLAGS="-O3" CXXFLAGS="-O3" ./autogen.sh + - run: make + - run: make check || .ci/fail.sh + + archlinux-debug-O0-py3: + docker: + - image: base/devel + steps: + - checkout + - run: pacman --noconfirm -Syu freetype2 cairo icu gettext gobject-introspection gcc gcc-libs glib2 graphite pkg-config ragel python python-pip + - run: pip install fonttools + # C??FLAGS are not needed for a regular build + - run: CFLAGS="-O0" CXXFLAGS="-O0" CPPFLAGS="-DHB_DEBUG" ./autogen.sh --with-freetype --with-glib --with-gobject --with-cairo --with-icu --with-graphite2 + - run: make + - run: make check || .ci/fail.sh + + clang-O3-O0: + docker: + - image: multiarch/crossbuild + steps: + - checkout + - run: apt update && apt install -y ragel libfreetype6-dev libglib2.0-dev libcairo2-dev libicu-dev libgraphite2-dev python python-pip + - run: pip install fonttools + - run: wget http://download.savannah.gnu.org/releases/freetype/freetype-2.9.tar.bz2 && tar xf freetype-2.9.tar.bz2 && cd freetype-2.9 && ./autogen.sh && ./configure && make -j4 && cd .. + - run: CFLAGS="-O3" CXXFLAGS="-O3" CC=clang CXX=clang++ ./autogen.sh --with-freetype --with-glib --with-cairo --with-icu --with-graphite2 + - run: make + - run: LD_LIBRARY_PATH="$PWD/freetype-2.9/objs/.libs" make check || .ci/fail.sh + - run: CFLAGS="-O0" CXXFLAGS="-O0" CC=clang CXX=clang++ ./autogen.sh --with-freetype --with-glib --with-cairo --with-icu --with-graphite2 + - run: make + - run: LD_LIBRARY_PATH="$PWD/freetype-2.9/objs/.libs" make check || .ci/fail.sh + + fedora-outoftreebuild: + docker: + - image: fedora + steps: + - checkout + - run: dnf install -y pkg-config ragel gcc gcc-c++ automake autoconf libtool make which glib2-devel freetype-devel cairo-devel libicu-devel gobject-introspection-devel graphite2-devel redhat-rpm-config python || true + - run: NOCONFIGURE=1 ./autogen.sh --with-freetype --with-glib --with-gobject --with-cairo --with-icu --with-graphite2 + - run: mkdir build && cd build && ../configure && make && (make check || ../.ci/fail.sh) + + cmake-gcc: + docker: + - image: ubuntu:17.10 + steps: + - checkout + - run: apt update && apt install -y ninja-build binutils cmake gcc g++ pkg-config ragel gtk-doc-tools libfreetype6-dev libglib2.0-dev libcairo2-dev libicu-dev libgraphite2-dev python python-pip + - run: pip install fonttools + - run: cmake -DHB_CHECK=ON -Bbuild -H. -GNinja + - run: ninja -Cbuild + - run: CTEST_OUTPUT_ON_FAILURE=1 ninja -Cbuild test + - run: ninja -Cbuild install + + cmake-oracledeveloperstudio: + docker: + - image: fedora + steps: + - checkout + - run: dnf install -y gcc ragel cmake make which glib2-devel freetype-devel cairo-devel libicu-devel graphite2-devel wget tar bzip2 python || true + - run: wget http://$ODSUSER:$ODSPASS@behdad.org/harfbuzz-private/OracleDeveloperStudio12.6-linux-x86-bin.tar.bz2 && tar xf OracleDeveloperStudio12.6-linux-x86-bin.tar.bz2 --owner root --group root --no-same-owner + - run: CC=/root/project/OracleDeveloperStudio12.6-linux-x86-bin/developerstudio12.6/bin/suncc CXX=/root/project/OracleDeveloperStudio12.6-linux-x86-bin/developerstudio12.6/bin/sunCC cmake -DHB_HAVE_GRAPHITE2=ON -DHB_BUILTIN_UCDN=ON -DHB_HAVE_GLIB=ON -DHB_HAVE_ICU=ON -DHB_HAVE_FREETYPE=ON -Bbuild -H. + - run: make -Cbuild + - run: CTEST_OUTPUT_ON_FAILURE=1 make -Cbuild test + - run: make -Cbuild install + + crosscompile-notest-djgpp: + docker: + - image: quay.io/ebraminio/djgpp + steps: + - checkout + - run: apt update && apt install -y ragel pkg-config libtool autoconf + - run: CFLAGS="-Wno-attributes" CXXFLAGS="-Wno-attributes" ./autogen.sh --prefix=/usr/local/djgpp --host=i586-pc-msdosdjgpp + - run: make + + crosscompile-notest-freebsd9: + docker: + - image: donbowman/freebsd-cross-build + steps: + - checkout + - run: apt update && apt install -y pkg-config ragel + - run: ./autogen.sh --prefix=/freebsd --host=x86_64-pc-freebsd9 + - run: make + + crosscompile-notest-psvita: + docker: + - image: dockcross/base + steps: + - checkout + - run: apt update && apt install ragel + - run: git clone https://github.com/vitasdk/vdpm && cd vdpm && ./bootstrap-vitasdk.sh + - run: ./autogen.sh --prefix=/usr/local/vitasdk/arm-vita-eabi --host=arm-vita-eabi + - run: make + + crosscompile-cmake-notest-android-arm: + docker: + - image: dockcross/android-arm + steps: + - checkout + - run: apt update && apt install ragel + - run: cmake -Bbuild -H. -GNinja + - run: ninja -Cbuild + + crosscompile-cmake-notest-browser-asmjs: + docker: + - image: dockcross/browser-asmjs + steps: + - checkout + - run: apt update && apt install ragel + - run: cmake -Bbuild -H. -GNinja + - run: ninja -Cbuild + + crosscompile-cmake-notest-linux-arm64: + docker: + - image: dockcross/linux-arm64 + steps: + - checkout + - run: apt update && apt install ragel + - run: cmake -Bbuild -H. -GNinja + - run: ninja -Cbuild + + crosscompile-cmake-notest-linux-mips: + docker: + - image: dockcross/linux-mips + steps: + - checkout + - run: apt update && apt install ragel + - run: cmake -Bbuild -H. -GNinja + - run: ninja -Cbuild + + crosscompile-cmake-notest-windows-x64: + docker: + - image: dockcross/windows-x64 + steps: + - checkout + - run: apt update && apt install ragel + - run: cmake -Bbuild -H. -GNinja + - run: ninja -Cbuild + +workflows: + version: 2 + build: + jobs: + # both autotools and cmake + - distcheck + + # autotools based builds + - alpine-O3 + - archlinux-debug-O0-py3 + - clang-O3-O0 + - fedora-outoftreebuild + + # cmake based builds + - cmake-gcc + - cmake-oracledeveloperstudio + + # crosscompiles + # they can't be test thus are without tests + ## autotools + - crosscompile-notest-djgpp + - crosscompile-notest-freebsd9 + - crosscompile-notest-psvita + + ## cmake + - crosscompile-cmake-notest-android-arm + - crosscompile-cmake-notest-browser-asmjs + - crosscompile-cmake-notest-linux-arm64 + - crosscompile-cmake-notest-linux-mips + - crosscompile-cmake-notest-windows-x64 diff --git a/chromium/third_party/harfbuzz-ng/src/.editorconfig b/chromium/third_party/harfbuzz-ng/src/.editorconfig new file mode 100644 index 00000000000..708188ad889 --- /dev/null +++ b/chromium/third_party/harfbuzz-ng/src/.editorconfig @@ -0,0 +1,18 @@ +root = true + +[*] +charset = utf-8 +trim_trailing_whitespace = true +end_of_line = lf +insert_final_newline = true + +[*.{c,cc,h,hh}] +indent_size = 2 +indent_style = space +tab_width = 8 + +[*.{py,sh}] +indent_style = tab + +[{CMakeLists.txt,*.cmake}] +indent_size = 2 diff --git a/chromium/third_party/harfbuzz-ng/src/.travis.yml b/chromium/third_party/harfbuzz-ng/src/.travis.yml new file mode 100644 index 00000000000..69b09c183fb --- /dev/null +++ b/chromium/third_party/harfbuzz-ng/src/.travis.yml @@ -0,0 +1,89 @@ +# Build Configuration for Travis +dist: trusty + +language: cpp + +env: + global: + - CPPFLAGS="" + - CFLAGS="-Werror -Werror=unused -Werror=unused-function" + - CXXFLAGS="-Werror -Werror=unused -Werror=unused-function -Wno-deprecated-register" # glib uses register and clang raises a warning + - CONFIGURE_OPTS="--with-freetype --with-glib --with-gobject --with-cairo --with-icu --with-graphite2" + - NOCONFIGURE=1 + # COVERITY_SCAN_TOKEN + - secure: "MRJtVu/fQoWNwMAamvIJBCX/1SMvEuEUk/ljAif/y2/3syyWgxFGp17UGnDILdoZYyCqTM+jQciY2P0nVqbjjOAUlML4QOAalqw8kPp8iTsnHUe+KOMVrOVP6p6qAQxk1im1O41cCMkmVKvk+NXe/on5euz6LGF2laHZaOAMoes=" + +matrix: + include: + - os: linux + compiler: gcc + script: + # Remove these two lines when Travis updated its distro + - wget http://download.savannah.gnu.org/releases/freetype/freetype-2.9.tar.bz2 && tar xf freetype-2.9.tar.bz2 && cd freetype-2.9 && ./autogen.sh && ./configure && make -j4 && cd .. + - export LD_LIBRARY_PATH="$PWD/freetype-2.9/objs/.libs" + + - ./autogen.sh + - ./configure $CONFIGURE_OPTS --enable-gtk-doc --enable-code-coverage + - make + - make check || .ci/fail.sh + - rm -rf freetype-2.9 + after_success: + - bash .ci/run-coveralls.sh # for coveralls.io code coverage tracking + - bash .ci/deploy-docs.sh + - bash .ci/trigger-coverity.sh + + - os: linux + compiler: clang + script: + # Remove these two lines when Travis updated its distro + - wget http://download.savannah.gnu.org/releases/freetype/freetype-2.9.tar.bz2 && tar xf freetype-2.9.tar.bz2 && cd freetype-2.9 && ./autogen.sh && ./configure && make -j4 && cd .. + - export LD_LIBRARY_PATH="$PWD/freetype-2.9/objs/.libs" + + - ./autogen.sh + - ./configure $CONFIGURE_OPTS + - make + - make check || .ci/fail.sh + + - os: osx + compiler: clang + install: + # https://github.com/harfbuzz/harfbuzz/issues/345 + - export CXXFLAGS="$CXXFLAGS -Wno-deprecated-declarations" + - brew update; + # Workaround Travis/brew bug + - brew uninstall libtool && brew install libtool + - brew install ragel freetype glib gobject-introspection cairo icu4c graphite2 + - brew link --force icu4c # icu4c is keg-only + script: + - ./autogen.sh + - ./configure $CONFIGURE_OPTS --with-coretext + - make + - make check || .ci/fail.sh + +notifications: + irc: "irc.freenode.org#harfbuzz" + email: harfbuzz-bots-chatter@googlegroups.com + +addons: + apt: + packages: + - pkg-config # for autogen.sh + - ragel + - lcov + - gtk-doc-tools + - libfreetype6-dev # for font function + - libglib2.0-dev # for font functions / tests / utils + - libcairo2-dev # for utils + - libicu-dev # for extra unicode functions + - libgraphite2-dev # for extra shapers + #- libgirepository1.0-dev # for gobject-introspection + + coverity_scan: + project: + name: behdad/harfbuzz + version: 1.0 + description: HarfBuzz OpenType text shaping engine + notification_email: harfbuzz-bots-chatter@googlegroups.com + build_command_prepend: ./autogen.sh --with-freetype --with-glib --with-gobject --with-cairo --with-icu --with-graphite2 + build_command: make + branch_pattern: coverity_scan diff --git a/chromium/third_party/harfbuzz-ng/src/AUTHORS b/chromium/third_party/harfbuzz-ng/src/AUTHORS new file mode 100644 index 00000000000..81cdc4cf37f --- /dev/null +++ b/chromium/third_party/harfbuzz-ng/src/AUTHORS @@ -0,0 +1,9 @@ +Behdad Esfahbod +Simon Hausmann +Martin Hosken +Jonathan Kew +Lars Knoll +Werner Lemberg +Roozbeh Pournader +Owen Taylor +David Turner diff --git a/chromium/third_party/harfbuzz-ng/src/BUILD.md b/chromium/third_party/harfbuzz-ng/src/BUILD.md new file mode 100644 index 00000000000..8a6b5695a06 --- /dev/null +++ b/chromium/third_party/harfbuzz-ng/src/BUILD.md @@ -0,0 +1,50 @@ +On Linux, install the development packages for FreeType, +Cairo, and GLib. For example, on Ubuntu / Debian, you would do: + + sudo apt-get install gcc g++ libfreetype6-dev libglib2.0-dev libcairo2-dev + +whereas on Fedora, RHEL, CentOS, and other Red Hat based systems you would do: + + sudo yum install gcc gcc-c++ freetype-devel glib2-devel cairo-devel + +on Windows, consider using [vcpkg](https://github.com/Microsoft/vcpkg), +provided by Microsoft, for building HarfBuzz and other open-source libraries +but if you need to build harfbuzz from source, put ragel binary on your +PATH and follow appveyor CI's cmake +[build steps](https://github.com/harfbuzz/harfbuzz/blob/master/appveyor.yml). + +on macOS, using MacPorts: + + sudo port install freetype glib2 cairo + +or using Homebrew: + + brew install freetype glib cairo + +If you are using a tarball, you can now proceed to running configure and make +as with any other standard package. That should leave you with a shared +library in `src/`, and a few utility programs including `hb-view` and `hb-shape` +under `util/`. + +If you are bootstraping from git, you need a few more tools before you can +run `autogen.sh` for the first time. Namely, `pkg-config` and `ragel`. + +Again, on Ubuntu / Debian: + + sudo apt-get install autoconf automake libtool pkg-config ragel gtk-doc-tools + +and on Fedora, RHEL, CentOS: + + sudo yum install autoconf automake libtool pkgconfig ragel gtk-doc + +on the Mac, using MacPorts: + + sudo port install autoconf automake libtool pkgconfig ragel gtk-doc + +or using Homebrew: + + brew install autoconf automake libtool pkgconfig ragel gtk-doc + +To build the Python bindings, you also need: + + brew install pygobject3 diff --git a/chromium/third_party/harfbuzz-ng/src/CMakeLists.txt b/chromium/third_party/harfbuzz-ng/src/CMakeLists.txt new file mode 100644 index 00000000000..85709b2e522 --- /dev/null +++ b/chromium/third_party/harfbuzz-ng/src/CMakeLists.txt @@ -0,0 +1,867 @@ +cmake_minimum_required(VERSION 2.8.0) +project(harfbuzz) + +enable_testing() + +## Limit framework build to Xcode generator +if (BUILD_FRAMEWORK) + # for a framework build on macOS, use: + # cmake -DBUILD_FRAMEWORK=ON -Bbuild -H. -GXcode && cmake --build build + if (NOT "${CMAKE_GENERATOR}" STREQUAL "Xcode") + message(FATAL_ERROR + "You should use Xcode generator with BUILD_FRAMEWORK enabled") + endif () + set (CMAKE_OSX_ARCHITECTURES "$(ARCHS_STANDARD_32_64_BIT)") + set (CMAKE_MACOSX_RPATH ON) + set (BUILD_SHARED_LIBS ON) +endif () + + +## Disallow in-source builds, as CMake generated make files can collide with autotools ones +if (NOT MSVC AND "${PROJECT_BINARY_DIR}" STREQUAL "${PROJECT_SOURCE_DIR}") + message(FATAL_ERROR + " +In-source builds are not permitted! Make a separate folder for" + " building, e.g.," + " + mkdir build; cd build; cmake .." + " +Before that, remove the files created by this failed run with" + " + rm -rf CMakeCache.txt CMakeFiles") +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) + option(HB_HAVE_CORETEXT "Enable CoreText shaper backend on macOS" ON) + set (CMAKE_MACOSX_RPATH ON) +endif () +if (WIN32) + option(HB_HAVE_UNISCRIBE "Enable Uniscribe shaper backend 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) +if (HB_BUILD_UTILS) + set (HB_HAVE_GLIB ON) + set (HB_HAVE_FREETYPE ON) +endif () + +option(HB_HAVE_GOBJECT "Enable GObject Bindings" OFF) +if (HB_HAVE_GOBJECT) + set (HB_HAVE_GLIB ON) +endif () + +option(HB_HAVE_INTROSPECTION "Enable building introspection (.gir/.typelib) files" OFF) +if (HB_HAVE_INTROSPECTION) + set (HB_HAVE_GOBJECT ON) + set (HB_HAVE_GLIB ON) +endif () + +option(HB_CHECK OFF "Do a configuration suitable for testing (shared library and enable all options)") +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) + #set (HB_HAVE_INTROSPECTION ON) + set (HB_HAVE_FREETYPE ON) + set (HB_HAVE_GRAPHITE2 ON) + if (WIN32) + set (HB_HAVE_UNISCRIBE ON) + set (HB_HAVE_DIRECTWRITE ON) + elseif (APPLE) + set (HB_HAVE_CORETEXT ON) + endif () +endif () + +include_directories(AFTER + ${PROJECT_SOURCE_DIR}/src + ${PROJECT_BINARY_DIR}/src +) + +add_definitions(-DHAVE_OT) +add_definitions(-DHAVE_FALLBACK) + +# We need PYTHON_EXECUTABLE to be set for running the tests... +include (FindPythonInterp) + +## Functions and headers +include (CheckFunctionExists) +include (CheckIncludeFile) +macro (check_funcs) # Similar to AC_CHECK_FUNCS of autotools + foreach (func_name ${ARGN}) + string(TOUPPER ${func_name} definiton_to_add) + check_function_exists(${func_name} HAVE_${definiton_to_add}) + if (${HAVE_${definiton_to_add}}) + add_definitions(-DHAVE_${definiton_to_add}) + endif () + endforeach () +endmacro () +if (UNIX) + list(APPEND CMAKE_REQUIRED_LIBRARIES m) +endif () +check_funcs(atexit mprotect sysconf getpagesize mmap isatty newlocale strtod_l round) +check_include_file(unistd.h HAVE_UNISTD_H) +if (${HAVE_UNISTD_H}) + add_definitions(-DHAVE_UNISTD_H) +endif () +check_include_file(sys/mman.h HAVE_SYS_MMAN_H) +if (${HAVE_SYS_MMAN_H}) + add_definitions(-DHAVE_SYS_MMAN_H) +endif () +check_include_file(xlocale.h HAVE_XLOCALE_H) +if (${HAVE_XLOCALE_H}) + add_definitions(-DHAVE_XLOCALE_H) +endif () +check_include_file(stdbool.h HAVE_STDBOOL_H) +if (${HAVE_STDBOOL_H}) + add_definitions(-DHAVE_STDBOOL_H) +endif () + + +if (MSVC) + add_definitions(-wd4244 -wd4267 -D_CRT_SECURE_NO_WARNINGS -D_CRT_NONSTDC_NO_WARNINGS) +endif () + + +## Detect if we are running inside a distribution or regular repository folder +# if (EXISTS "${PROJECT_SOURCE_DIR}/ChangeLog") +# # perhaps we are on dist directory +# set (IN_HB_DIST TRUE) +# #set (HB_VERSION_H "${PROJECT_SOURCE_DIR}/src/hb-version.h") +# 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}) + set (${variable} ${listVar} PARENT_SCOPE) +endfunction () + +# http://stackoverflow.com/a/27630120 +function (add_prefix_to_list var prefix) + set (listVar "") + foreach (f ${${var}}) + list(APPEND listVar "${prefix}${f}") + endforeach () + set (${var} "${listVar}" PARENT_SCOPE) +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_OT_sources ${SRCSOURCES}) +add_prefix_to_list(HB_OT_sources "${PROJECT_SOURCE_DIR}/src/") +extract_make_variable(HB_OT_headers ${SRCSOURCES}) +add_prefix_to_list(HB_OT_headers "${PROJECT_SOURCE_DIR}/src/") + +extract_make_variable(HB_SUBSET_sources ${SRCSOURCES}) +add_prefix_to_list(HB_SUBSET_sources "${PROJECT_SOURCE_DIR}/src/") + +extract_make_variable(HB_SUBSET_headers ${SRCSOURCES}) +add_prefix_to_list(HB_SUBSET_headers "${PROJECT_SOURCE_DIR}/src/") + +extract_make_variable(HB_BASE_RAGEL_GENERATED_sources ${SRCSOURCES}) +extract_make_variable(HB_OT_RAGEL_GENERATED_sources ${SRCSOURCES}) +#if (IN_HB_DIST) + add_prefix_to_list(HB_BASE_RAGEL_GENERATED_sources "${PROJECT_SOURCE_DIR}/src/") + add_prefix_to_list(HB_OT_RAGEL_GENERATED_sources "${PROJECT_SOURCE_DIR}/src/") +#else () +# add_prefix_to_list(HB_BASE_RAGEL_GENERATED_sources "${PROJECT_BINARY_DIR}/src/") +# add_prefix_to_list(HB_OT_RAGEL_GENERATED_sources "${PROJECT_BINARY_DIR}/src/") +#endif () + +extract_make_variable(HB_VIEW_sources ${UTILSOURCES}) +add_prefix_to_list(HB_VIEW_sources "${PROJECT_SOURCE_DIR}/util/") +extract_make_variable(HB_SHAPE_sources ${UTILSOURCES}) +add_prefix_to_list(HB_SHAPE_sources "${PROJECT_SOURCE_DIR}/util/") +extract_make_variable(HB_SUBSET_CLI_sources ${UTILSOURCES}) +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}) +set (HB_VERSION ${CMAKE_MATCH_1}) +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} ${HB_OT_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} + ${HB_OT_sources} + ${HB_OT_RAGEL_GENERATED_sources} +) + +set (subset_project_sources + ${HB_SUBSET_sources} +) + +set (project_extra_sources) + +set (project_headers + #${HB_VERSION_H} + + ${HB_BASE_headers} + ${HB_OT_headers} +) + +set (subset_project_headers + ${HB_SUBSET_headers} +) + + +## Find and include needed header folders and libraries +if (HB_HAVE_FREETYPE) + include (FindFreetype) + if (NOT FREETYPE_FOUND) + message(FATAL_ERROR "HB_HAVE_FREETYPE was set, but we failed to find it. Maybe add a CMAKE_PREFIX_PATH= to your Freetype2 install prefix") + endif () + + list(APPEND THIRD_PARTY_LIBS ${FREETYPE_LIBRARIES}) + 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 + set (CMAKE_REQUIRED_INCLUDES ${CMAKE_REQUIRED_INCLUDES} ${FREETYPE_INCLUDE_DIRS}) + set (CMAKE_REQUIRED_LIBRARIES ${CMAKE_REQUIRED_LIBRARIES} ${FREETYPE_LIBRARIES}) + + check_funcs(FT_Get_Var_Blend_Coordinates FT_Set_Var_Blend_Coordinates FT_Done_MM_Var) +endif () + +if (HB_HAVE_GRAPHITE2) + add_definitions(-DHAVE_GRAPHITE2) + + find_path(GRAPHITE2_INCLUDE_DIR graphite2/Font.h) + find_library(GRAPHITE2_LIBRARY 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}) + + 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) + + # https://github.com/WebKit/webkit/blob/master/Source/cmake/FindGLIB.cmake + find_package(PkgConfig) + pkg_check_modules(PC_GLIB QUIET glib-2.0) + + find_library(GLIB_LIBRARIES NAMES glib-2.0 HINTS ${PC_GLIB_LIBDIR} ${PC_GLIB_LIBRARY_DIRS}) + find_path(GLIBCONFIG_INCLUDE_DIR NAMES glibconfig.h HINTS ${PC_LIBDIR} ${PC_LIBRARY_DIRS} ${PC_GLIB_INCLUDEDIR} ${PC_GLIB_INCLUDE_DIRS} PATH_SUFFIXES glib-2.0/include) + find_path(GLIB_INCLUDE_DIR NAMES glib.h HINTS ${PC_GLIB_INCLUDEDIR} ${PC_GLIB_INCLUDE_DIRS} PATH_SUFFIXES glib-2.0) + + 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}) + + mark_as_advanced(GLIB_LIBRARIES GLIBCONFIG_INCLUDE_DIR GLIB_INCLUDE_DIR) +endif () + +if (HB_HAVE_ICU) + add_definitions(-DHAVE_ICU) + + # https://github.com/WebKit/webkit/blob/master/Source/cmake/FindICU.cmake + find_package(PkgConfig) + pkg_check_modules(PC_ICU QUIET icu-uc) + + find_path(ICU_INCLUDE_DIR NAMES unicode/utypes.h HINTS ${PC_ICU_INCLUDE_DIRS} ${PC_ICU_INCLUDEDIR}) + find_library(ICU_LIBRARY NAMES libicuuc cygicuuc cygicuuc32 icuuc HINTS ${PC_ICU_LIBRARY_DIRS} ${PC_ICU_LIBDIR}) + + 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}) + + mark_as_advanced(ICU_INCLUDE_DIR ICU_LIBRARY) +endif () + +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) + + find_library(APPLICATION_SERVICES_FRAMEWORK ApplicationServices) + if (APPLICATION_SERVICES_FRAMEWORK) + list(APPEND THIRD_PARTY_LIBS ${APPLICATION_SERVICES_FRAMEWORK}) + endif (APPLICATION_SERVICES_FRAMEWORK) + + mark_as_advanced(APPLICATION_SERVICES_FRAMEWORK) +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 () + +if (HB_HAVE_GOBJECT) + include (FindPerl) + + # Use the hints from glib-2.0.pc to find glib-mkenums + find_package(PkgConfig) + pkg_check_modules(PC_GLIB QUIET glib-2.0) + find_program(GLIB_MKENUMS glib-mkenums + HINTS ${PC_glib_mkenums} + ) + set (GLIB_MKENUMS_CMD) + + if (WIN32 AND NOT MINGW) + # In Visual Studio builds, shebang lines are not supported + # in the standard cmd.exe shell that we use, so we need to + # first determine whether glib-mkenums is a Python or PERL + # script + execute_process(COMMAND "${PYTHON_EXECUTABLE}" "${GLIB_MKENUMS}" --version + RESULT_VARIABLE GLIB_MKENUMS_PYTHON + OUTPUT_QUIET ERROR_QUIET + ) + if (GLIB_MKENUMS_PYTHON EQUAL 0) + message("${GLIB_MKENUMS} is a Python script.") + set (GLIB_MKENUMS_CMD "${PYTHON_EXECUTABLE}" "${GLIB_MKENUMS}") + else () + execute_process(COMMAND "${PERL_EXECUTABLE}" "${GLIB_MKENUMS}" --version + RESULT_VARIABLE GLIB_MKENUMS_PERL + OUTPUT_QUIET ERROR_QUIET + ) + if (GLIB_MKENUMS_PERL EQUAL 0) + message("${GLIB_MKENUMS} is a PERL script.") + set (GLIB_MKENUMS_CMD "${PERL_EXECUTABLE}" "${GLIB_MKENUMS}") + endif () + if (NOT GLIB_MKENUMS_PERL EQUAL 0 AND NOT GLIB_MKENUMS_PYTHON EQUAL 0) + message(FATAL_ERROR "Unable to determine type of glib-mkenums script") + endif () + endif () + else () + set (GLIB_MKENUMS_CMD "${GLIB_MKENUMS}") + endif () + if (NOT GLIB_MKENUMS_CMD) + message(FATAL_ERROR "HB_HAVE_GOBJECT was set, but we failed to find glib-mkenums, which is required") + endif () + + pkg_check_modules(PC_GOBJECT QUIET gobject-2.0) + + find_library(GOBJECT_LIBRARIES NAMES gobject-2.0 HINTS ${PC_GLIB_LIBDIR} ${PC_GLIB_LIBRARY_DIRS}) + find_path(GOBJECT_INCLUDE_DIR NAMES glib-object.h HINTS ${PC_GLIB_INCLUDEDIR} ${PC_GLIB_INCLUDE_DIRS} PATH_SUFFIXES glib-2.0) + + include_directories(${GOBJECTCONFIG_INCLUDE_DIR} ${GOBJECT_INCLUDE_DIR}) + mark_as_advanced(GOBJECT_LIBRARIES GOBJECT_INCLUDE_DIR) + + list(APPEND hb_gobject_sources ${PROJECT_SOURCE_DIR}/src/hb-gobject-structs.cc) + list(APPEND hb_gobject_gen_sources + ${CMAKE_CURRENT_BINARY_DIR}/src/hb-gobject-enums.cc + ) + list(APPEND hb_gobject_structs_headers + ${PROJECT_SOURCE_DIR}/src/hb-gobject-structs.h + ) + list(APPEND hb_gobject_headers + ${PROJECT_SOURCE_DIR}/src/hb-gobject.h + ${hb_gobject_structs_headers} + ) + list(APPEND hb_gobject_gen_headers + ${CMAKE_CURRENT_BINARY_DIR}/src/hb-gobject-enums.h + ) + + add_custom_command( + OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/src/hb-gobject-enums.h + COMMAND ${GLIB_MKENUMS_CMD} + --template=${PROJECT_SOURCE_DIR}/src/hb-gobject-enums.h.tmpl + --identifier-prefix hb_ + --symbol-prefix hb_gobject + ${hb_gobject_structs_headers} + ${project_headers} + > ${CMAKE_CURRENT_BINARY_DIR}/src/hb-gobject-enums.h.tmp + COMMAND "${CMAKE_COMMAND}" + "-DENUM_INPUT_SRC=${CMAKE_CURRENT_BINARY_DIR}/src/hb-gobject-enums.h.tmp" + "-DENUM_OUTPUT_SRC=${CMAKE_CURRENT_BINARY_DIR}/src/hb-gobject-enums.h" + -P ${PROJECT_SOURCE_DIR}/replace-enum-strings.cmake + DEPENDS ${PROJECT_SOURCE_DIR}/src/hb-gobject-enums.h.tmpl + ${hb_gobject_header} + ${project_headers} + ) + + add_custom_command( + OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/src/hb-gobject-enums.cc + COMMAND ${GLIB_MKENUMS_CMD} + --template=${PROJECT_SOURCE_DIR}/src/hb-gobject-enums.cc.tmpl + --identifier-prefix hb_ + --symbol-prefix hb_gobject + ${hb_gobject_header} + ${project_headers} + > ${CMAKE_CURRENT_BINARY_DIR}/src/hb-gobject-enums.cc.tmp + COMMAND "${CMAKE_COMMAND}" + "-DENUM_INPUT_SRC=${CMAKE_CURRENT_BINARY_DIR}/src/hb-gobject-enums.cc.tmp" + "-DENUM_OUTPUT_SRC=${CMAKE_CURRENT_BINARY_DIR}/src/hb-gobject-enums.cc" + -P ${PROJECT_SOURCE_DIR}/replace-enum-strings.cmake + DEPENDS ${PROJECT_SOURCE_DIR}/src/hb-gobject-enums.cc.tmpl + ${CMAKE_CURRENT_BINARY_DIR}/src/hb-gobject-enums.h + ${hb_gobject_header} + ${project_headers} + ) +endif () + + +## Atomic ops availability detection +file(WRITE "${PROJECT_BINARY_DIR}/try_compile_intel_atomic_primitives.c" +" void memory_barrier (void) { __sync_synchronize (); } + int atomic_add (int *i) { return __sync_fetch_and_add (i, 1); } + int mutex_trylock (int *m) { return __sync_lock_test_and_set (m, 1); } + void mutex_unlock (int *m) { __sync_lock_release (m); } + int main () { return 0; } +") +try_compile(HB_HAVE_INTEL_ATOMIC_PRIMITIVES + ${PROJECT_BINARY_DIR}/try_compile_intel_atomic_primitives + ${PROJECT_BINARY_DIR}/try_compile_intel_atomic_primitives.c) +if (HB_HAVE_INTEL_ATOMIC_PRIMITIVES) + add_definitions(-DHAVE_INTEL_ATOMIC_PRIMITIVES) +endif () + +file(WRITE "${PROJECT_BINARY_DIR}/try_compile_solaris_atomic_ops.c" +" #include <atomic.h> + /* This requires Solaris Studio 12.2 or newer: */ + #include <mbarrier.h> + void memory_barrier (void) { __machine_rw_barrier (); } + int atomic_add (volatile unsigned *i) { return atomic_add_int_nv (i, 1); } + void *atomic_ptr_cmpxchg (volatile void **target, void *cmp, void *newval) { return atomic_cas_ptr (target, cmp, newval); } + int main () { return 0; } +") +try_compile(HB_HAVE_SOLARIS_ATOMIC_OPS + ${PROJECT_BINARY_DIR}/try_compile_solaris_atomic_ops + ${PROJECT_BINARY_DIR}/try_compile_solaris_atomic_ops.c) +if (HB_HAVE_SOLARIS_ATOMIC_OPS) + add_definitions(-DHAVE_SOLARIS_ATOMIC_OPS) +endif () + + +## Define harfbuzz library +add_library(harfbuzz ${project_sources} ${project_extra_sources} ${project_headers}) +set_target_properties(harfbuzz PROPERTIES + VISIBILITY_INLINES_HIDDEN TRUE) +target_link_libraries(harfbuzz ${THIRD_PARTY_LIBS}) + +## Define harfbuzz-subset library +add_library(harfbuzz-subset ${subset_project_sources} ${subset_project_headers}) +add_dependencies(harfbuzz-subset harfbuzz) +set_target_properties(harfbuzz-subset PROPERTIES + VISIBILITY_INLINES_HIDDEN TRUE) +target_link_libraries(harfbuzz-subset harfbuzz ${THIRD_PARTY_LIBS}) + +if (UNIX OR MINGW) + # Make symbols link locally + include(CheckCXXCompilerFlag) + check_cxx_compiler_flag(-Bsymbolic-functions CXX_SUPPORTS_FLAG_BSYMB_FUNCS) + if(CXX_SUPPORTS_FLAG_BSYMB_FUNCS) + link_libraries(-Bsymbolic-functions) + endif() + + if (CMAKE_CXX_COMPILER_ID STREQUAL "Clang" OR CMAKE_CXX_COMPILER_ID STREQUAL "GNU") + # Make sure we don't link to libstdc++ + set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fno-rtti -fno-exceptions") + set (CMAKE_CXX_IMPLICIT_LINK_LIBRARIES "m") # libm + set (CMAKE_CXX_IMPLICIT_LINK_DIRECTORIES "") + set_target_properties(harfbuzz PROPERTIES LINKER_LANGUAGE C) + set_target_properties(harfbuzz-subset PROPERTIES LINKER_LANGUAGE C) + + # No threadsafe statics as we do it ourselves + set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fno-threadsafe-statics") + endif () +endif () + +## Define harfbuzz-gobject library +if (HB_HAVE_GOBJECT) + add_library(harfbuzz-gobject + ${hb_gobject_sources} + ${hb_gobject_gen_sources} + ${hb_gobject_headers} + ${hb_gobject_gen_headers} + ) + set_target_properties(harfbuzz-gobject PROPERTIES + VISIBILITY_INLINES_HIDDEN TRUE) + include_directories(BEFORE ${CMAKE_CURRENT_BINARY_DIR}/src) + add_dependencies(harfbuzz-gobject harfbuzz) + target_link_libraries(harfbuzz-gobject harfbuzz ${GOBJECT_LIBRARIES} ${THIRD_PARTY_LIBS}) +endif () + +if (BUILD_SHARED_LIBS AND WIN32 AND NOT MINGW) + add_definitions("-DHB_EXTERN=__declspec(dllexport) extern") +endif () + +# On Windows, g-ir-scanner requires a DLL build in order for it to work +if (WIN32) + if (NOT BUILD_SHARED_LIBS) + message("Building introspection files on Windows requires BUILD_SHARED_LIBS to be enabled.") + set (HB_HAVE_INTROSPECTION OFF) + endif () +endif () + +if (HB_HAVE_INTROSPECTION) + + find_package(PkgConfig) + pkg_check_modules(PC_GI QUIET gobject-introspection-1.0) + + find_program(G_IR_SCANNER g-ir-scanner + HINTS ${PC_g_ir_scanner} + ) + + find_program(G_IR_COMPILER g-ir-compiler + HINTS ${PC_g_ir_compiler} + ) + + if (WIN32 AND NOT MINGW) + # Note that since we already enable HB_HAVE_GOBJECT + # we would already have PYTHON_EXECUTABLE handy + set (G_IR_SCANNER_CMD "${PYTHON_EXECUTABLE}" "${G_IR_SCANNER}") + else () + set (G_IR_SCANNER_CMD "${G_IR_SCANNER}") + endif () + + # We need to account for the varying output directories + # when we build using Visual Studio projects + if ("${CMAKE_GENERATOR}" MATCHES "Visual Studio*") + set (hb_libpath "${CMAKE_CURRENT_BINARY_DIR}/$<CONFIGURATION>") + else () + set (hb_libpath "$<TARGET_FILE_DIR:harfbuzz-gobject>") + endif () + + # Get the CFlags that we used to build HarfBuzz/HarfBuzz-GObject + set (hb_defines_cflags "") + foreach (hb_cflag ${hb_cflags}) + list(APPEND hb_defines_cflags "-D${hb_cflag}") + endforeach (hb_cflag) + + # Get the other dependent libraries we used to build HarfBuzz/HarfBuzz-GObject + set (extra_libs "") + foreach (extra_lib ${THIRD_PARTY_LIBS}) + # We don't want the .lib extension here... + string(REPLACE ".lib" "" extra_lib_stripped "${extra_lib}") + list(APPEND extra_libs "--extra-library=${extra_lib_stripped}") + endforeach () + + set (introspected_sources) + foreach (f + ${project_headers} + ${project_sources} + ${hb_gobject_gen_sources} + ${hb_gobject_gen_headers} + ${hb_gobject_sources} + ${hb_gobject_headers} + ) + if (WIN32) + # Nasty issue: We need to make drive letters lower case, + # otherwise g-ir-scanner won't like it and give us a bunch + # of invalid items and unresolved types... + STRING(SUBSTRING "${f}" 0 1 drive) + STRING(SUBSTRING "${f}" 1 -1 path) + if (drive MATCHES "[A-Z]") + STRING(TOLOWER ${drive} drive_lower) + list(APPEND introspected_sources "${drive_lower}${path}") + else () + list(APPEND introspected_sources "${f}") + endif () + else () + list(APPEND introspected_sources "${f}") + endif () + endforeach () + + file(REMOVE ${CMAKE_CURRENT_BINARY_DIR}/src/hb_gir_list) + foreach (s ${introspected_sources}) + file(APPEND ${CMAKE_CURRENT_BINARY_DIR}/src/hb_gir_list "${s}\n") + endforeach () + + # Finally, build the introspection files... + add_custom_command( + TARGET harfbuzz-gobject + POST_BUILD + COMMAND ${G_IR_SCANNER_CMD} + --warn-all --no-libtool --verbose + -n hb + --namespace=HarfBuzz + --nsversion=0.0 + --identifier-prefix=hb_ + --include GObject-2.0 + --pkg-export=harfbuzz + --cflags-begin + -I${PROJECT_SOURCE_DIR}/src + -I${PROJECT_BINARY_DIR}/src + ${hb_includedir_cflags} + ${hb_defines_cflags} + -DHB_H + -DHB_H_IN + -DHB_OT_H + -DHB_OT_H_IN + -DHB_GOBJECT_H + -DHB_GOBJECT_H_IN + -DHB_EXTERN= + --cflags-end + --library=harfbuzz-gobject + --library=harfbuzz + -L${hb_libpath} + ${extra_libs} + --filelist ${CMAKE_CURRENT_BINARY_DIR}/src/hb_gir_list + -o ${hb_libpath}/HarfBuzz-0.0.gir + DEPENDS harfbuzz-gobject harfbuzz ${CMAKE_CURRENT_BINARY_DIR}/src/hb_gir_list + ) + + add_custom_command( + TARGET harfbuzz-gobject + POST_BUILD + COMMAND "${G_IR_COMPILER}" + --verbose --debug + --includedir ${CMAKE_CURRENT_BINARY_DIR} + ${hb_libpath}/HarfBuzz-0.0.gir + -o ${hb_libpath}/HarfBuzz-0.0.typelib + DEPENDS ${hb_libpath}/HarfBuzz-0.0.gir harfbuzz-gobject + ) +endif () + + +## Additional framework build configs +if (BUILD_FRAMEWORK) + set (CMAKE_MACOSX_RPATH ON) + set_target_properties(harfbuzz PROPERTIES + FRAMEWORK TRUE + PUBLIC_HEADER "${project_headers}" + XCODE_ATTRIBUTE_INSTALL_PATH "@rpath" + ) + set (MACOSX_FRAMEWORK_IDENTIFIER "harfbuzz") + set (MACOSX_FRAMEWORK_SHORT_VERSION_STRING "${HB_VERSION}") + set (MACOSX_FRAMEWORK_BUNDLE_VERSION "${HB_VERSION}") +endif () + + +## Additional harfbuzz build artifacts +if (HB_BUILD_UTILS) + # https://github.com/WebKit/webkit/blob/master/Source/cmake/FindCairo.cmake + find_package(PkgConfig) + pkg_check_modules(PC_CAIRO QUIET cairo) + + find_path(CAIRO_INCLUDE_DIRS NAMES cairo.h HINTS ${PC_CAIRO_INCLUDEDIR} ${PC_CAIRO_INCLUDE_DIRS} PATH_SUFFIXES cairo) + find_library(CAIRO_LIBRARIESNAMES cairo HINTS ${PC_CAIRO_LIBDIR} ${PC_CAIRO_LIBRARY_DIRS}) + + add_definitions("-DPACKAGE_NAME=\"HarfBuzz\"") + add_definitions("-DPACKAGE_VERSION=\"${HB_VERSION}\"") + include_directories(${CAIRO_INCLUDE_DIRS}) + + add_executable(hb-view ${HB_VIEW_sources}) + target_link_libraries(hb-view harfbuzz ${CAIRO_LIBRARIESNAMES}) + + add_executable(hb-shape ${HB_SHAPE_sources}) + target_link_libraries(hb-shape harfbuzz) + + add_executable(hb-subset ${HB_SUBSET_CLI_sources}) + target_link_libraries(hb-subset harfbuzz harfbuzz-subset) + + add_executable(hb-ot-shape-closure ${HB_OT_SHAPE_CLOSURE_sources}) + target_link_libraries(hb-ot-shape-closure harfbuzz) + + mark_as_advanced(CAIRO_INCLUDE_DIRS CAIRO_LIBRARIESNAMES) +endif () + + +## Install +include (GNUInstallDirs) + +if (NOT SKIP_INSTALL_HEADERS AND NOT SKIP_INSTALL_ALL) + install(FILES ${project_headers} DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/harfbuzz) + if (HB_HAVE_GOBJECT) + install(FILES ${hb_gobject_headers} ${hb_gobject_gen_headers} DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/harfbuzz) + endif () +endif () + +if (NOT SKIP_INSTALL_LIBRARIES AND NOT SKIP_INSTALL_ALL) + install(TARGETS harfbuzz + ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} + LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} + FRAMEWORK DESTINATION Library/Frameworks + ) + if (HB_BUILD_UTILS) + install(TARGETS hb-view + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} + ) + install(TARGETS hb-subset + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} + ) + + install(TARGETS hb-shape + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} + ) + + install(TARGETS hb-ot-shape-closure + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} + ) + endif () + if (HB_HAVE_GOBJECT) + install(TARGETS harfbuzz-gobject + ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} + LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} + ) + if (HB_HAVE_INTROSPECTION) + if ("${CMAKE_GENERATOR}" MATCHES "Visual Studio*") + set (hb_libpath "${CMAKE_CURRENT_BINARY_DIR}/$<CONFIGURATION>") + else () + set (hb_libpath "$<TARGET_FILE_DIR:harfbuzz-gobject>") + endif () + + install(FILES "${hb_libpath}/HarfBuzz-0.0.gir" + DESTINATION ${CMAKE_INSTALL_DATAROOTDIR}/gir-1.0 + ) + + install(FILES "${hb_libpath}/HarfBuzz-0.0.typelib" + DESTINATION ${CMAKE_INSTALL_LIBDIR}/girepository-1.0 + ) + endif () + endif () +endif () + +if (UNIX AND CMAKE_GENERATOR STREQUAL "Ninja") + if (CMAKE_CXX_COMPILER_ID STREQUAL "Clang") + set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fcolor-diagnostics") + set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fcolor-diagnostics") + endif () + if (CMAKE_CXX_COMPILER_ID STREQUAL "GNU") + set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fdiagnostics-color") + set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fdiagnostics-color") + endif () +endif () + + +## src/ executables +foreach (prog main test test-would-substitute test-size-params test-buffer-serialize hb-ot-tag test-unicode-ranges) + 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 + set (prog_name test-test) + endif () + 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") + +## Tests +if (UNIX OR MINGW) + if (BUILD_SHARED_LIBS) + # generate harfbuzz.def after build completion + string(REPLACE ";" " " space_separated_headers "${project_headers}") + add_custom_command(TARGET harfbuzz POST_BUILD + COMMAND ${CMAKE_COMMAND} -E env "headers=${space_separated_headers}" python ${PROJECT_SOURCE_DIR}/src/gen-def.py ${PROJECT_BINARY_DIR}/harfbuzz.def + WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}/src) + + add_test(NAME check-static-inits.sh + COMMAND ${PROJECT_SOURCE_DIR}/src/check-static-inits.sh + WORKING_DIRECTORY ${PROJECT_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/harfbuzz.dir/src # ugly hack + ) + add_test(NAME check-libstdc++.sh COMMAND ${PROJECT_SOURCE_DIR}/src/check-libstdc++.sh) + add_test(NAME check-symbols.sh COMMAND ${PROJECT_SOURCE_DIR}/src/check-symbols.sh) + + set_tests_properties( + check-static-inits.sh check-libstdc++.sh check-symbols.sh + PROPERTIES + ENVIRONMENT "libs=.;srcdir=${PROJECT_SOURCE_DIR}/src" + SKIP_RETURN_CODE 77) + endif () + + add_test(NAME check-c-linkage-decls.sh COMMAND ./check-c-linkage-decls.sh) + add_test(NAME check-header-guards.sh COMMAND ./check-header-guards.sh) + add_test(NAME check-externs.sh COMMAND ./check-externs.sh) + add_test(NAME check-includes.sh COMMAND ./check-includes.sh) + set_tests_properties( + check-c-linkage-decls.sh check-header-guards.sh check-externs.sh check-includes.sh + PROPERTIES + WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}/src + SKIP_RETURN_CODE 77) +endif () + +# Needs to come last so that variables defined above are passed to +# subdirectories. +add_subdirectory(test) diff --git a/chromium/third_party/harfbuzz-ng/COPYING b/chromium/third_party/harfbuzz-ng/src/COPYING index 9d1056f40b1..9d1056f40b1 100644 --- a/chromium/third_party/harfbuzz-ng/COPYING +++ b/chromium/third_party/harfbuzz-ng/src/COPYING diff --git a/chromium/third_party/harfbuzz-ng/src/Makefile.am b/chromium/third_party/harfbuzz-ng/src/Makefile.am new file mode 100644 index 00000000000..fde5256422b --- /dev/null +++ b/chromium/third_party/harfbuzz-ng/src/Makefile.am @@ -0,0 +1,85 @@ +# Process this file with automake to produce Makefile.in + +NULL = + +ACLOCAL_AMFLAGS = -I m4 + +SUBDIRS = src util test docs + +EXTRA_DIST = \ + autogen.sh \ + harfbuzz.doap \ + README.python \ + BUILD.md \ + RELEASING.md \ + CMakeLists.txt \ + replace-enum-strings.cmake \ + $(NULL) + +MAINTAINERCLEANFILES = \ + $(GITIGNORE_MAINTAINERCLEANFILES_TOPLEVEL) \ + $(GITIGNORE_MAINTAINERCLEANFILES_M4_LIBTOOL) \ + $(GITIGNORE_MAINTAINERCLEANFILES_MAKEFILE_IN) \ + $(srcdir)/INSTALL \ + $(srcdir)/ChangeLog \ + $(srcdir)/gtk-doc.make \ + $(srcdir)/m4/gtk-doc.m4 \ + $(NULL) + + +# +# ChangeLog generation +# +CHANGELOG_RANGE = +ChangeLog: $(srcdir)/ChangeLog +$(srcdir)/ChangeLog: + $(AM_V_GEN) if test -d "$(top_srcdir)/.git"; then \ + (GIT_DIR=$(top_srcdir)/.git \ + $(GIT) log $(CHANGELOG_RANGE) --stat) | fmt --split-only > $@.tmp \ + && mv -f $@.tmp "$(srcdir)/ChangeLog" \ + || ($(RM) $@.tmp; \ + echo Failed to generate ChangeLog, your ChangeLog may be outdated >&2; \ + (test -f $@ || echo git-log is required to generate this file >> "$(srcdir)/$@")); \ + else \ + test -f $@ || \ + (echo A git checkout and git-log is required to generate ChangeLog >&2 && \ + echo A git checkout and git-log is required to generate this file >> "$(srcdir)/$@"); \ + fi +.PHONY: ChangeLog $(srcdir)/ChangeLog + + +# +# Release engineering +# + +DISTCHECK_CONFIGURE_FLAGS = \ + --enable-gtk-doc \ + --disable-doc-cross-references \ + --with-gobject \ + --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 + +dist-hook: dist-clear-sticky-bits +# Clean up any sticky bits we may inherit from parent dir +dist-clear-sticky-bits: + chmod -R a-s $(distdir) + + +tar_file = $(PACKAGE_TARNAME)-$(VERSION).tar.bz2 +sha256_file = $(tar_file).sha256 +gpg_file = $(sha256_file).asc +$(sha256_file): $(tar_file) + sha256sum $^ > $@ +$(gpg_file): $(sha256_file) + @echo "Please enter your GPG password to sign the checksum." + gpg --armor --sign $^ + +release-files: $(tar_file) $(sha256_file) $(gpg_file) + + +-include $(top_srcdir)/git.mk diff --git a/chromium/third_party/harfbuzz-ng/NEWS b/chromium/third_party/harfbuzz-ng/src/NEWS index dfd8b101300..fe09ab160f0 100644 --- a/chromium/third_party/harfbuzz-ng/NEWS +++ b/chromium/third_party/harfbuzz-ng/src/NEWS @@ -1,3 +1,18 @@ +Overview of changes leading to 1.7.6 +Wednesday, March 7, 2018 +==================================== + +- Fix to hb_set_t binary operations. Ouch. +- New experimental harfbuzz-subset library. All of hb-subset.h + is experimental right now and API WILL change. + +- New API: +hb_blob_copy_writable_or_fail() +HB_OT_TAG_BASE +hb_set_previous() +hb_set_previous_range() + + Overview of changes leading to 1.7.5 Tuesday, January 30, 2018 ==================================== @@ -69,7 +84,7 @@ Monday, October 23nd, 2017 - Yesterday's release had a bad crasher; don't use it. That's what happens when one works on Sunday... - https://github.com/behdad/harfbuzz/issues/578 + https://github.com/harfbuzz/harfbuzz/issues/578 - Build fixes for FreeBSD and Chrome Android. @@ -78,7 +93,7 @@ Sunday, October 22nd, 2017 ==================================== - Don't skip over COMBINING GRAPHEME JOINER when ligating, etc. - To be refined: https://github.com/behdad/harfbuzz/issues/554 + To be refined: https://github.com/harfbuzz/harfbuzz/issues/554 - Faster hb_set_t implementation. - Don't use deprecated ICU API. - Fix undefined-behavior in Myanmar shaper, introduced in 1.6.0 @@ -479,7 +494,7 @@ Tuesday, February 23, 2016 - CoreText: Drastically speed up font initialization. - CoreText: Fix tiny leak. - Group ZWJ/ZWNJ with previous syllable under cluster-level=0. - https://github.com/behdad/harfbuzz/issues/217 + https://github.com/harfbuzz/harfbuzz/issues/217 - Add test/shaping/README.md about how to add tests to the suite. @@ -495,8 +510,8 @@ Friday, February 19, 2016 - Allow GPOS cursive connection on marks, and fix the interaction with mark attachment. This work resulted in some changes to how mark attachments work. See: - https://github.com/behdad/harfbuzz/issues/211 - https://github.com/behdad/harfbuzz/commit/86c68c7a2c971efe8e35b1f1bd99401dc8b688d2 + https://github.com/harfbuzz/harfbuzz/issues/211 + https://github.com/harfbuzz/harfbuzz/commit/86c68c7a2c971efe8e35b1f1bd99401dc8b688d2 - Graphite2 shaper: improved negative advance handling (eg. Nastaliq). - Add nmake-based build system for Windows. - Minor speedup. @@ -537,7 +552,7 @@ Wednesday, November 26, 2015 ==================================== - Fix badly-broken fallback shaper that affected terminology. - https://github.com/behdad/harfbuzz/issues/187 + https://github.com/harfbuzz/harfbuzz/issues/187 - Fix y_scaling in Graphite shaper. - API changes: * An unset glyph_h_origin() function in font-funcs now (sensibly) @@ -559,11 +574,11 @@ Wednesday, November 18, 2015 ==================================== - Implement 'stch' stretch feature for Syriac Abbreviation Mark. - https://github.com/behdad/harfbuzz/issues/141 + https://github.com/harfbuzz/harfbuzz/issues/141 - Disable use of decompose_compatibility() callback. - Implement "shaping" of various Unicode space characters, even if the font does not support them. - https://github.com/behdad/harfbuzz/issues/153 + https://github.com/harfbuzz/harfbuzz/issues/153 - If font does not support U+2011 NO-BREAK HYPHEN, fallback to U+2010 HYPHEN. - Changes resulting from libFuzzer continuous fuzzing: @@ -586,7 +601,7 @@ Thursday, October 15, 2015 - Revert default load-flags of fonts created using hb_ft_font_create() back to FT_LOAD_DEFAULT|FT_LOAD_NO_HINTING. This was changed in last release (1.0.5), but caused major issues, so revert. - https://github.com/behdad/harfbuzz/issues/143 + https://github.com/harfbuzz/harfbuzz/issues/143 Overview of changes leading to 1.0.5 @@ -594,7 +609,7 @@ Tuesday, October 13, 2015 ==================================== - Fix multiple memory access bugs discovered using libFuzzer. - https://github.com/behdad/harfbuzz/issues/139 + https://github.com/harfbuzz/harfbuzz/issues/139 Everyone should upgrade to this version as soon as possible. We now have continuous fuzzing set up, to avoid issues like these creeping in again. @@ -865,7 +880,7 @@ Wednesday, July 16, 2014 U+FFFD REPLACEMENT CHARACTER now. - With all changes in this release, the buffer will contain fully valid Unicode after hb_buffer_add_utf8/16/32 no matter how - broken the input is. This can be overriden though. See below. + broken the input is. This can be overridden though. See below. - Fix Mongolian Variation Selectors for fonts without GDEF. - Fix minor invalid buffer access. - Accept zh-Hant and zh-Hans language tags. hb_ot_tag_to_language() diff --git a/chromium/third_party/harfbuzz-ng/src/README b/chromium/third_party/harfbuzz-ng/src/README new file mode 100644 index 00000000000..6e2132237fa --- /dev/null +++ b/chromium/third_party/harfbuzz-ng/src/README @@ -0,0 +1,16 @@ +[![Build Status](https://travis-ci.org/harfbuzz/harfbuzz.svg)](https://travis-ci.org/harfbuzz/harfbuzz) +[![Build status](https://ci.appveyor.com/api/projects/status/0t0flrxpstj9lb9w?svg=true)](https://ci.appveyor.com/project/harfbuzz/harfbuzz) +[![CircleCI](https://circleci.com/gh/harfbuzz/harfbuzz.svg?style=svg)](https://circleci.com/gh/harfbuzz/harfbuzz) +[![Coverity](https://img.shields.io/coverity/scan/5450.svg)](https://scan.coverity.com/projects/behdad-harfbuzz) +[![Coverage Status](https://img.shields.io/coveralls/harfbuzz/harfbuzz.svg)](https://coveralls.io/r/harfbuzz/harfbuzz) +[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 the file COPYING. + +Documentation: https://harfbuzz.github.io diff --git a/chromium/third_party/harfbuzz-ng/src/README.md b/chromium/third_party/harfbuzz-ng/src/README.md new file mode 120000 index 00000000000..100b93820ad --- /dev/null +++ b/chromium/third_party/harfbuzz-ng/src/README.md @@ -0,0 +1 @@ +README
\ No newline at end of file diff --git a/chromium/third_party/harfbuzz-ng/src/README.python b/chromium/third_party/harfbuzz-ng/src/README.python new file mode 100644 index 00000000000..cd312649dbc --- /dev/null +++ b/chromium/third_party/harfbuzz-ng/src/README.python @@ -0,0 +1,30 @@ +To enable HarfBuzz bindings for Python among other languages, make sure +you have latest version of gobject-introspection available. On Ubuntu, +you can install that this way: + + sudo apt-get install libgirepository1.0-dev + +And then run autogen.sh (if building from git), and then: + + ./configure --with-gobject --enable-introspection + +Make sure that gobject-introspection is enabled then in the final report. + +Compile and install. + +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. + +Make sure you have pygobject installed. Then check that the following +import works in your Python interpretter: + + from gi.repository import HarfBuzz + +If it does, you are ready to call HarfBuzz from Python! Congratulations. +See 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/chromium/third_party/harfbuzz-ng/src/RELEASING.md b/chromium/third_party/harfbuzz-ng/src/RELEASING.md new file mode 100644 index 00000000000..dedcca8f9e9 --- /dev/null +++ b/chromium/third_party/harfbuzz-ng/src/RELEASING.md @@ -0,0 +1,99 @@ +HarfBuzz release walk-through checklist: + +1. Open gitk and review changes since last release. + + * `git diff $(git describe | sed 's/-.*//').. src/*.h` prints all public API + changes. + + Document them in NEWS. All API and API semantic changes should be clearly + marked as API additions, API changes, or API deletions. Document + deprecations. + + If there's a backward-incompatible API change (including deletions for API + used anywhere), that's a release blocker. Do NOT release. + +2. Based on severity of changes, decide whether it's a minor or micro release + number bump, + +3. Make sure you have correct date and new version at the top of NEWS file, + +4. Bump version in configure.ac line 3, + +5. Do "make distcheck", if it passes, you get a tarball. + Otherwise, fix things and commit them separately before making release, + +6. "make release-files". Enter your GPG password. This creates a sha256 hash + and signs it. + +7. Now that you have release files built, commit NEWS and configure.ac changes. + The commit message is simply the release number. Eg. "1.4.7" + +8. Tag the release and sign it: Eg. "git tag -s 1.4.7 -m 1.4.7". Enter your + GPG password again. + +9. 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 (available below) to configure harfbuzz with mingw in a subdirector (eg. winbuild/), + + c. make + + d. Back in the parent directory, run `./UPDATE.sh` (available below) to build win32 bundle. + +10. 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 2895619 Jul 18 11:34 harfbuzz-1.4.7-win32.zip +``` + +11. While doing that, quickly double-check the size of the .tar.bz2 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. + +12. Push the commit and tag out: "git push --follow-tags". Make sure it's + pushed both to freedesktop repo and github. + +13. 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/chromium/third_party/harfbuzz-ng/src/THANKS b/chromium/third_party/harfbuzz-ng/src/THANKS new file mode 100644 index 00000000000..940cfde5c39 --- /dev/null +++ b/chromium/third_party/harfbuzz-ng/src/THANKS @@ -0,0 +1,7 @@ +Bradley Grainger +Khaled Hosny +Kenichi Ishibashi +Ryan Lortie +Jeff Muizelaar +suzuki toshiya +Philip Withnall diff --git a/chromium/third_party/harfbuzz-ng/src/TODO b/chromium/third_party/harfbuzz-ng/src/TODO new file mode 100644 index 00000000000..53ffbe9d00a --- /dev/null +++ b/chromium/third_party/harfbuzz-ng/src/TODO @@ -0,0 +1,42 @@ +General fixes: +============= + +- Implement 'rand' feature. + + +API issues: +=========== + +- API to accept a list of languages? + +- Remove hb_ot_shape_glyphs_closure()? + + +API additions +============= + +- Language to/from script. + +- blob_from_file? + +- Add hb-cairo glue + +- Add sanitize API (and a cached version, that saves result on blob user-data) + +- BCP 47 language handling / API (language_matches?) + +- Add hb_font_create_unscaled()? + +- Add query / enumeration API for aalt-like features? + +- SFNT api? get_num_faces? + +- Add segmentation API + +- Add hb-fribidi glue? + + +hb-view / hb-shape enhancements: +=============================== + +- Add --width, --height, --auto-size, --ink-box, --align, etc? diff --git a/chromium/third_party/harfbuzz-ng/src/appveyor.yml b/chromium/third_party/harfbuzz-ng/src/appveyor.yml new file mode 100644 index 00000000000..b68572062e5 --- /dev/null +++ b/chromium/third_party/harfbuzz-ng/src/appveyor.yml @@ -0,0 +1,62 @@ +platform: x64 + +environment: + matrix: + - compiler: msvc + generator: Visual Studio 14 + platform: Win32 + configuration: Debug + triplet: x86-windows + - compiler: msvc + generator: Visual Studio 14 Win64 + platform: x64 + configuration: Debug + triplet: x64-windows + + - compiler: msvc + generator: Visual Studio 14 ARM + platform: ARM + configuration: Debug + + + - compiler: msys2 + MINGW_PREFIX: /mingw64 + MINGW_CHOST: x86_64-w64-mingw32 + MSYS2_ARCH: x86_64 + - compiler: msys2 + MINGW_PREFIX: /mingw32 + MINGW_CHOST: i686-w64-mingw32 + MSYS2_ARCH: i686 + +install: + - C:\msys64\usr\bin\bash -lc "pacman --noconfirm -S mingw-w64-x86_64-ragel" + +build_script: + - 'if "%compiler%"=="msvc" if not "%platform%"=="ARM" vcpkg install glib:%triplet% freetype:%triplet% cairo:%triplet%' + - 'if "%compiler%"=="msvc" md build' + - 'if "%compiler%"=="msvc" cd build' + - 'if "%compiler%"=="msvc" set PATH=%PATH%;C:\Program Files (x86)\MSBuild\14.0\Bin;c:\msys64\mingw64\bin' # msys2 is added just for having "ragel" on PATH + + - 'if "%compiler%"=="msvc" if "%platform%"=="ARM" cmake -DHB_HAVE_UNISCRIBE=ON -DHB_HAVE_DIRECTWRITE=ON -G "%generator%" ../' + - 'if "%compiler%"=="msvc" if not "%platform%"=="ARM" cmake -DHB_HAVE_UNISCRIBE=ON -DHB_HAVE_DIRECTWRITE=ON -DHB_HAVE_GLIB=ON -DHB_HAVE_FREETYPE=ON -DHB_BUILD_UTILS=ON -G "%generator%" -DCMAKE_TOOLCHAIN_FILE=c:/tools/vcpkg/scripts/buildsystems/vcpkg.cmake ../' + + - 'if "%compiler%"=="msvc" msbuild harfbuzz.sln /p:Configuration=%configuration% /p:Platform=%platform%' + - 'if "%compiler%"=="msvc" if not "%platform%"=="ARM" ctest --output-on-failure -C %configuration%' + + - 'if "%compiler%"=="msys2" C:\msys64\usr\bin\bash -lc "pacman --noconfirm -S mingw-w64-$MSYS2_ARCH-{freetype,cairo,icu,gettext,gobject-introspection,gcc,gcc-libs,glib2,graphite2,pkg-config,python2}"' + - 'if "%compiler%"=="msys2" C:\msys64\usr\bin\bash -lc "curl https://sourceforge.net/p/mingw-w64/mingw-w64/ci/master/tree/mingw-w64-headers/include/dwrite_1.h?format=raw > %MINGW_PREFIX%/%MINGW_CHOST%/include/dwrite_1.h"' + - 'if "%compiler%"=="msys2" C:\msys64\usr\bin\bash -lc "cd $APPVEYOR_BUILD_FOLDER; PATH=$PATH:/mingw64/bin:/mingw32/bin; ./autogen.sh --with-uniscribe --with-freetype --with-glib --with-gobject --with-cairo --with-icu --with-graphite2 --with-directwrite --build=%MINGW_CHOST% --host=%MINGW_CHOST% --prefix=%MINGW_PREFIX%; make; make check || .ci/fail.sh"' + +cache: + - c:\tools\vcpkg\installed\ + +notifications: + - provider: Email + to: + - harfbuzz-bots-chatter@googlegroups.com + on_build_success: false + on_build_failure: true + on_build_status_changed: true + +# disable automatic tests +test: off diff --git a/chromium/third_party/harfbuzz-ng/src/autogen.sh b/chromium/third_party/harfbuzz-ng/src/autogen.sh new file mode 100755 index 00000000000..fd5c1983c73 --- /dev/null +++ b/chromium/third_party/harfbuzz-ng/src/autogen.sh @@ -0,0 +1,48 @@ +#!/bin/sh +# Run this to generate all the initial makefiles, etc. + +test -n "$srcdir" || srcdir=`dirname "$0"` +test -n "$srcdir" || srcdir=. + +olddir=`pwd` +cd $srcdir + +#echo -n "checking for ragel... " +#which ragel || { +# echo "You need to install ragel... See http://www.complang.org/ragel/" +# exit 1 +#} + +echo -n "checking for pkg-config... " +which pkg-config || { + echo "*** No pkg-config found, please install it ***" + exit 1 +} + +echo -n "checking for libtoolize... " +which glibtoolize || which libtoolize || { + echo "*** No libtoolize (libtool) found, please install it ***" + exit 1 +} +echo -n "checking for gtkdocize... " +if which gtkdocize ; then + gtkdocize --copy || exit 1 +else + echo "*** No gtkdocize (gtk-doc) found, skipping documentation ***" + echo "EXTRA_DIST = " > gtk-doc.make +fi + +echo -n "checking for autoreconf... " +which autoreconf || { + echo "*** No autoreconf (autoconf) found, please install it ***" + exit 1 +} + +echo "running autoreconf --force --install --verbose" +autoreconf --force --install --verbose || exit $? + +cd $olddir +test -n "$NOCONFIGURE" || { + echo "running configure $@" + "$srcdir/configure" "$@" +} diff --git a/chromium/third_party/harfbuzz-ng/src/configure.ac b/chromium/third_party/harfbuzz-ng/src/configure.ac new file mode 100644 index 00000000000..9e3bf0817cf --- /dev/null +++ b/chromium/third_party/harfbuzz-ng/src/configure.ac @@ -0,0 +1,549 @@ +AC_PREREQ([2.64]) +AC_INIT([HarfBuzz], + [1.7.6], + [https://github.com/harfbuzz/harfbuzz/issues/new], + [harfbuzz], + [http://harfbuzz.org/]) + +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_SILENT_RULES([yes]) +AX_CODE_COVERAGE + +# Initialize libtool +m4_ifdef([AM_PROG_AR], [AM_PROG_AR]) +LT_PREREQ([2.2]) +LT_INIT([disable-static]) + +# Check for programs +AC_USE_SYSTEM_EXTENSIONS +AC_PROG_CC +AC_PROG_CC_C99 +AM_PROG_CC_C_O +AC_PROG_CXX +dnl AX_CXX_COMPILE_STDCXX(11, noext, optional) +AC_SYS_LARGEFILE +PKG_PROG_PKG_CONFIG([0.20]) +AM_MISSING_PROG([RAGEL], [ragel]) +AM_MISSING_PROG([GIT], [git]) + +# Version +m4_define(hb_version_triplet,m4_split(AC_PACKAGE_VERSION,[[.]])) +m4_define(hb_version_major,m4_argn(1,hb_version_triplet)) +m4_define(hb_version_minor,m4_argn(2,hb_version_triplet)) +m4_define(hb_version_micro,m4_argn(3,hb_version_triplet)) +HB_VERSION_MAJOR=hb_version_major +HB_VERSION_MINOR=hb_version_minor +HB_VERSION_MICRO=hb_version_micro +HB_VERSION=AC_PACKAGE_VERSION +AC_SUBST(HB_VERSION_MAJOR) +AC_SUBST(HB_VERSION_MINOR) +AC_SUBST(HB_VERSION_MICRO) +AC_SUBST(HB_VERSION) + +# Libtool version +m4_define([hb_version_int], + m4_eval(hb_version_major*10000 + hb_version_minor*100 + hb_version_micro)) +m4_if(m4_eval(hb_version_minor % 2), [1], + dnl for unstable releases + [m4_define([hb_libtool_revision], 0)], + dnl for stable releases + [m4_define([hb_libtool_revision], hb_version_micro)]) +m4_define([hb_libtool_age], + m4_eval(hb_version_int - hb_libtool_revision)) +m4_define([hb_libtool_current], + m4_eval(hb_libtool_age)) +HB_LIBTOOL_VERSION_INFO=hb_libtool_current:hb_libtool_revision:hb_libtool_age +AC_SUBST(HB_LIBTOOL_VERSION_INFO) + +AC_ARG_WITH([libstdc++], + [AS_HELP_STRING([--with-libstdc++=@<:@yes/no@:>@], + [Allow linking with libstdc++ @<:@default=no@:>@])], + [with_libstdcxx=$withval], + [with_libstdcxx=no]) +AM_CONDITIONAL(WITH_LIBSTDCXX, [test "x$with_libstdcxx" = "xyes"]) + +# Documentation +have_gtk_doc=false +m4_ifdef([GTK_DOC_CHECK], [ +GTK_DOC_CHECK([1.15],[--flavour no-tmpl]) + if test "x$enable_gtk_doc" = xyes; then + have_gtk_doc=true + fi +], [ + AM_CONDITIONAL([ENABLE_GTK_DOC], false) +]) + +# Functions, and headers + +AC_CHECK_FUNCS(atexit mprotect sysconf getpagesize mmap isatty newlocale strtod_l) + +save_libs="$LIBS" +LIBS="$LIBS -lm" +AC_CHECK_FUNCS([round], ,[AC_CHECK_DECLS([round], , ,[#include <math.h>])]) +LIBS="$save_libs" + +AC_CHECK_HEADERS(unistd.h sys/mman.h xlocale.h stdbool.h) + +# Compiler flags +AC_CANONICAL_HOST +AC_CHECK_ALIGNOF([struct{char;}]) +if test "x$GCC" = "xyes"; then + + # Make symbols link locally + AX_CHECK_LINK_FLAG([[-Bsymbolic-functions]], [LDFLAGS="$LDFLAGS -Bsymbolic-functions"]) + + # Assorted warnings + CXXFLAGS="$CXXFLAGS -Wcast-align" + + case "$host" in + *-*-mingw*) + ;; + *) + # Hide inline methods + CXXFLAGS="$CXXFLAGS -fvisibility-inlines-hidden" + ;; + esac + + case "$host" in + arm-*-*) + if test "x$ac_cv_alignof_struct_char__" != x1; then + # Request byte alignment + CXXFLAGS="$CXXFLAGS -mstructure-size-boundary=8" + fi + ;; + esac +fi + +AM_CONDITIONAL(HAVE_GCC, test "x$GCC" = "xyes") + +hb_os_win32=no +AC_MSG_CHECKING([for native Win32]) +case "$host" in + *-*-mingw*) + hb_os_win32=yes + ;; +esac +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 +if $have_pthread; then + AC_DEFINE(HAVE_PTHREAD, 1, [Have POSIX threads]) +fi +AM_CONDITIONAL(HAVE_PTHREAD, $have_pthread) + +dnl ========================================================================== + +have_ot=true +if $have_ot; then + AC_DEFINE(HAVE_OT, 1, [Have native OpenType Layout backend]) +fi +AM_CONDITIONAL(HAVE_OT, $have_ot) + +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@:>@])],, + [with_glib=auto]) +have_glib=false +GLIB_DEPS="glib-2.0 >= 2.19.1" +AC_SUBST(GLIB_DEPS) +if test "x$with_glib" = "xyes" -o "x$with_glib" = "xauto"; then + PKG_CHECK_MODULES(GLIB, $GLIB_DEPS, have_glib=true, :) +fi +if test "x$with_glib" = "xyes" -a "x$have_glib" != "xtrue"; then + AC_MSG_ERROR([glib support requested but glib-2.0 not found]) +fi +if $have_glib; then + AC_DEFINE(HAVE_GLIB, 1, [Have glib2 library]) +fi +AM_CONDITIONAL(HAVE_GLIB, $have_glib) + +dnl =========================================================================== + +AC_ARG_WITH(gobject, + [AS_HELP_STRING([--with-gobject=@<:@yes/no/auto@:>@], + [Use gobject @<:@default=no@:>@])],, + [with_gobject=no]) +have_gobject=false +if test "x$with_gobject" = "xyes" -o "x$with_gobject" = "xauto"; then + PKG_CHECK_MODULES(GOBJECT, gobject-2.0 glib-2.0, have_gobject=true, :) +fi +if test "x$with_gobject" = "xyes" -a "x$have_gobject" != "xtrue"; then + AC_MSG_ERROR([gobject support requested but gobject-2.0 / glib-2.0 not found]) +fi +if $have_gobject; then + AC_DEFINE(HAVE_GOBJECT, 1, [Have gobject2 library]) + GLIB_MKENUMS=`$PKG_CONFIG --variable=glib_mkenums glib-2.0` + AC_SUBST(GLIB_MKENUMS) +fi +AM_CONDITIONAL(HAVE_GOBJECT, $have_gobject) +AC_SUBST(have_gobject) + +dnl =========================================================================== + + +dnl =========================================================================== +# Gobject-Introspection +have_introspection=false +m4_ifdef([GOBJECT_INTROSPECTION_CHECK], [ + if $have_gobject; then + GOBJECT_INTROSPECTION_CHECK([1.34.0]) + if test "x$found_introspection" = xyes; then + have_introspection=true + fi + else + AM_CONDITIONAL([HAVE_INTROSPECTION], false) + fi +], [ + AM_CONDITIONAL([HAVE_INTROSPECTION], false) +]) + +dnl ========================================================================== + +AC_ARG_WITH(cairo, + [AS_HELP_STRING([--with-cairo=@<:@yes/no/auto@:>@], + [Use cairo @<:@default=auto@:>@])],, + [with_cairo=auto]) +have_cairo=false +if test "x$with_cairo" = "xyes" -o "x$with_cairo" = "xauto"; then + PKG_CHECK_MODULES(CAIRO, cairo >= 1.8.0, have_cairo=true, :) +fi +if test "x$with_cairo" = "xyes" -a "x$have_cairo" != "xtrue"; then + AC_MSG_ERROR([cairo support requested but not found]) +fi +if $have_cairo; then + AC_DEFINE(HAVE_CAIRO, 1, [Have cairo graphics library]) +fi +AM_CONDITIONAL(HAVE_CAIRO, $have_cairo) + +have_cairo_ft=false +if $have_cairo; then + PKG_CHECK_MODULES(CAIRO_FT, cairo-ft, have_cairo_ft=true, :) +fi +if $have_cairo_ft; then + AC_DEFINE(HAVE_CAIRO_FT, 1, [Have cairo-ft support in cairo graphics library]) +fi +AM_CONDITIONAL(HAVE_CAIRO_FT, $have_cairo_ft) + +dnl ========================================================================== + +AC_ARG_WITH(fontconfig, + [AS_HELP_STRING([--with-fontconfig=@<:@yes/no/auto@:>@], + [Use fontconfig @<:@default=auto@:>@])],, + [with_fontconfig=auto]) +have_fontconfig=false +if test "x$with_fontconfig" = "xyes" -o "x$with_fontconfig" = "xauto"; then + PKG_CHECK_MODULES(FONTCONFIG, fontconfig, have_fontconfig=true, :) +fi +if test "x$with_fontconfig" = "xyes" -a "x$have_fontconfig" != "xtrue"; then + AC_MSG_ERROR([fontconfig support requested but not found]) +fi +if $have_fontconfig; then + AC_DEFINE(HAVE_FONTCONFIG, 1, [Have fontconfig library]) +fi +AM_CONDITIONAL(HAVE_FONTCONFIG, $have_fontconfig) + +dnl ========================================================================== + +AC_ARG_WITH(icu, + [AS_HELP_STRING([--with-icu=@<:@yes/no/builtin/auto@:>@], + [Use ICU @<:@default=auto@:>@])],, + [with_icu=auto]) +have_icu=false +if test "x$with_icu" = "xyes" -o "x$with_icu" = "xbuiltin" -o "x$with_icu" = "xauto"; then + PKG_CHECK_MODULES(ICU, icu-uc, have_icu=true, :) + + dnl Fallback to icu-config if ICU pkg-config files could not be found + if test "$have_icu" != "true"; then + AC_CHECK_TOOL(ICU_CONFIG, icu-config, no) + AC_MSG_CHECKING([for ICU by using icu-config fallback]) + if test "$ICU_CONFIG" != "no" && "$ICU_CONFIG" --version >/dev/null; then + have_icu=true + # We don't use --cflags as this gives us a lot of things that we don't + # necessarily want, like debugging and optimization flags + # See man (1) icu-config for more info. + ICU_CFLAGS=`$ICU_CONFIG --cppflags` + ICU_LIBS=`$ICU_CONFIG --ldflags-searchpath --ldflags-libsonly` + AC_SUBST(ICU_CFLAGS) + AC_SUBST(ICU_LIBS) + AC_MSG_RESULT([yes]) + else + AC_MSG_RESULT([no]) + fi + fi +fi +if test \( "x$with_icu" = "xyes" -o "x$with_icu" = "xbuiltin" \) -a "x$have_icu" != "xtrue"; then + AC_MSG_ERROR([icu support requested but icu-uc not found]) +fi + +if $have_icu; then + CXXFLAGS="$CXXFLAGS `$PKG_CONFIG --variable=CXXFLAGS icu-uc`" + AC_DEFINE(HAVE_ICU, 1, [Have ICU library]) + if test "x$with_icu" = "xbuiltin"; then + AC_DEFINE(HAVE_ICU_BUILTIN, 1, [Use hb-icu Unicode callbacks]) + fi +fi +AM_CONDITIONAL(HAVE_ICU, $have_icu) +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@:>@])],, + [with_graphite2=no]) +have_graphite2=false +GRAPHITE2_DEPS="graphite2" +AC_SUBST(GRAPHITE2_DEPS) +if test "x$with_graphite2" = "xyes" -o "x$with_graphite2" = "xauto"; then + PKG_CHECK_MODULES(GRAPHITE2, $GRAPHITE2_DEPS, have_graphite2=true, :) + if test "x$have_graphite2" != "xtrue"; then + # If pkg-config is not available, graphite2 can still be there + ac_save_CFLAGS="$CFLAGS" + ac_save_CPPFLAGS="$CPPFLAGS" + CFLAGS="$CFLAGS $GRAPHITE2_CFLAGS" + CPPFLAGS="$CPPFLAGS $GRAPHITE2_CFLAGS" + AC_CHECK_HEADER(graphite2/Segment.h, have_graphite2=true, :) + CPPFLAGS="$ac_save_CPPFLAGS" + CFLAGS="$ac_save_CFLAGS" + fi +fi +if test "x$with_graphite2" = "xyes" -a "x$have_graphite2" != "xtrue"; then + AC_MSG_ERROR([graphite2 support requested but libgraphite2 not found]) +fi +if $have_graphite2; then + AC_DEFINE(HAVE_GRAPHITE2, 1, [Have Graphite2 library]) +fi +AM_CONDITIONAL(HAVE_GRAPHITE2, $have_graphite2) + +dnl ========================================================================== + +AC_ARG_WITH(freetype, + [AS_HELP_STRING([--with-freetype=@<:@yes/no/auto@:>@], + [Use the FreeType library @<:@default=auto@:>@])],, + [with_freetype=auto]) +have_freetype=false +FREETYPE_DEPS="freetype2 >= 12.0.6" +AC_SUBST(FREETYPE_DEPS) +if test "x$with_freetype" = "xyes" -o "x$with_freetype" = "xauto"; then + # See freetype/docs/VERSION.DLL; 12.0.6 means freetype-2.4.2 + PKG_CHECK_MODULES(FREETYPE, $FREETYPE_DEPS, have_freetype=true, :) +fi +if test "x$with_freetype" = "xyes" -a "x$have_freetype" != "xtrue"; then + AC_MSG_ERROR([FreeType support requested but libfreetype2 not found]) +fi +if $have_freetype; then + AC_DEFINE(HAVE_FREETYPE, 1, [Have FreeType 2 library]) + save_libs=$LIBS + LIBS="$LIBS $FREETYPE_LIBS" + AC_CHECK_FUNCS(FT_Get_Var_Blend_Coordinates FT_Set_Var_Blend_Coordinates FT_Done_MM_Var) + LIBS=$save_libs +fi +AM_CONDITIONAL(HAVE_FREETYPE, $have_freetype) + +dnl =========================================================================== + +AC_ARG_WITH(uniscribe, + [AS_HELP_STRING([--with-uniscribe=@<:@yes/no/auto@:>@], + [Use the Uniscribe library @<:@default=no@:>@])],, + [with_uniscribe=no]) +have_uniscribe=false +if test "x$with_uniscribe" = "xyes" -o "x$with_uniscribe" = "xauto"; then + AC_CHECK_HEADERS(usp10.h windows.h, have_uniscribe=true) +fi +if test "x$with_uniscribe" = "xyes" -a "x$have_uniscribe" != "xtrue"; then + AC_MSG_ERROR([uniscribe support requested but not found]) +fi +if $have_uniscribe; then + UNISCRIBE_CFLAGS= + UNISCRIBE_LIBS="-lusp10 -lgdi32 -lrpcrt4" + AC_SUBST(UNISCRIBE_CFLAGS) + AC_SUBST(UNISCRIBE_LIBS) + AC_DEFINE(HAVE_UNISCRIBE, 1, [Have Uniscribe library]) +fi +AM_CONDITIONAL(HAVE_UNISCRIBE, $have_uniscribe) + +dnl =========================================================================== + +AC_ARG_WITH(directwrite, + [AS_HELP_STRING([--with-directwrite=@<:@yes/no/auto@:>@], + [Use the DirectWrite library (experimental) @<:@default=no@:>@])],, + [with_directwrite=no]) +have_directwrite=false +AC_LANG_PUSH([C++]) +if test "x$with_directwrite" = "xyes" -o "x$with_directwrite" = "xauto"; then + AC_CHECK_HEADERS(dwrite.h, have_directwrite=true) +fi +AC_LANG_POP([C++]) +if test "x$with_directwrite" = "xyes" -a "x$have_directwrite" != "xtrue"; then + AC_MSG_ERROR([directwrite support requested but not found]) +fi +if $have_directwrite; then + DIRECTWRITE_CXXFLAGS= + DIRECTWRITE_LIBS="-ldwrite" + AC_SUBST(DIRECTWRITE_CXXFLAGS) + AC_SUBST(DIRECTWRITE_LIBS) + AC_DEFINE(HAVE_DIRECTWRITE, 1, [Have DirectWrite library]) +fi +AM_CONDITIONAL(HAVE_DIRECTWRITE, $have_directwrite) + +dnl =========================================================================== + +AC_ARG_WITH(coretext, + [AS_HELP_STRING([--with-coretext=@<:@yes/no/auto@:>@], + [Use CoreText @<:@default=no@:>@])],, + [with_coretext=no]) +have_coretext=false +if test "x$with_coretext" = "xyes" -o "x$with_coretext" = "xauto"; then + AC_CHECK_TYPE(CTFontRef, have_coretext=true,, [#include <ApplicationServices/ApplicationServices.h>]) + + if $have_coretext; then + CORETEXT_CFLAGS= + CORETEXT_LIBS="-framework ApplicationServices" + AC_SUBST(CORETEXT_CFLAGS) + AC_SUBST(CORETEXT_LIBS) + else + # On iOS CoreText and CoreGraphics are stand-alone frameworks + if test "x$have_coretext" != "xtrue"; then + # Check for a different symbol to avoid getting cached result. + AC_CHECK_TYPE(CTRunRef, have_coretext=true,, [#include <CoreText/CoreText.h>]) + fi + + if $have_coretext; then + CORETEXT_CFLAGS= + CORETEXT_LIBS="-framework CoreText -framework CoreGraphics -framework CoreFoundation" + AC_SUBST(CORETEXT_CFLAGS) + AC_SUBST(CORETEXT_LIBS) + fi + fi +fi +if test "x$with_coretext" = "xyes" -a "x$have_coretext" != "xtrue"; then + AC_MSG_ERROR([CoreText support requested but libcoretext not found]) +fi +if $have_coretext; then + AC_DEFINE(HAVE_CORETEXT, 1, [Have Core Text backend]) +fi +AM_CONDITIONAL(HAVE_CORETEXT, $have_coretext) + +dnl =========================================================================== + +AC_CACHE_CHECK([for Intel atomic primitives], hb_cv_have_intel_atomic_primitives, [ + hb_cv_have_intel_atomic_primitives=false + AC_TRY_LINK([ + void memory_barrier (void) { __sync_synchronize (); } + int atomic_add (int *i) { return __sync_fetch_and_add (i, 1); } + int mutex_trylock (int *m) { return __sync_lock_test_and_set (m, 1); } + void mutex_unlock (int *m) { __sync_lock_release (m); } + ], [], hb_cv_have_intel_atomic_primitives=true + ) +]) +if $hb_cv_have_intel_atomic_primitives; then + AC_DEFINE(HAVE_INTEL_ATOMIC_PRIMITIVES, 1, [Have Intel __sync_* atomic primitives]) +fi + +dnl =========================================================================== + +AC_CACHE_CHECK([for Solaris atomic operations], hb_cv_have_solaris_atomic_ops, [ + hb_cv_have_solaris_atomic_ops=false + AC_TRY_LINK([ + #include <atomic.h> + /* This requires Solaris Studio 12.2 or newer: */ + #include <mbarrier.h> + void memory_barrier (void) { __machine_rw_barrier (); } + int atomic_add (volatile unsigned *i) { return atomic_add_int_nv (i, 1); } + void *atomic_ptr_cmpxchg (volatile void **target, void *cmp, void *newval) { return atomic_cas_ptr (target, cmp, newval); } + ], [], hb_cv_have_solaris_atomic_ops=true + ) +]) +if $hb_cv_have_solaris_atomic_ops; then + AC_DEFINE(HAVE_SOLARIS_ATOMIC_OPS, 1, [Have Solaris __machine_*_barrier and atomic_* operations]) +fi + +if test "$os_win32" = no && ! $have_pthread; then + AC_CHECK_HEADERS(sched.h) + AC_SEARCH_LIBS(sched_yield,rt,AC_DEFINE(HAVE_SCHED_YIELD, 1, [Have sched_yield])) +fi + +dnl =========================================================================== + +AC_CONFIG_FILES([ +Makefile +src/Makefile +src/hb-version.h +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/in-house/Makefile +test/shaping/data/text-rendering-tests/Makefile +test/subset/Makefile +test/subset/data/Makefile +docs/Makefile +docs/version.xml +]) + +AC_OUTPUT + +AC_MSG_NOTICE([ + +Build configuration: + +Unicode callbacks (you want at least one): + Builtin (UCDN): ${have_ucdn} + Glib: ${have_glib} + ICU: ${have_icu} + +Font callbacks (the more the merrier): + FreeType: ${have_freetype} + +Tools used for command-line utilities: + Cairo: ${have_cairo} + Fontconfig: ${have_fontconfig} + +Additional shapers (the more the merrier): + Graphite2: ${have_graphite2} + +Platform shapers (not normally needed): + CoreText: ${have_coretext} + Uniscribe: ${have_uniscribe} + DirectWrite: ${have_directwrite} + +Other features: + Documentation: ${enable_gtk_doc} + GObject bindings: ${have_gobject} + Introspection: ${have_introspection} +]) diff --git a/chromium/third_party/harfbuzz-ng/src/docs/HarfBuzz.png b/chromium/third_party/harfbuzz-ng/src/docs/HarfBuzz.png Binary files differnew file mode 100644 index 00000000000..771d955d01f --- /dev/null +++ b/chromium/third_party/harfbuzz-ng/src/docs/HarfBuzz.png diff --git a/chromium/third_party/harfbuzz-ng/src/docs/HarfBuzz.svg b/chromium/third_party/harfbuzz-ng/src/docs/HarfBuzz.svg new file mode 100644 index 00000000000..4e2df254146 --- /dev/null +++ b/chromium/third_party/harfbuzz-ng/src/docs/HarfBuzz.svg @@ -0,0 +1,277 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<!-- Created with Inkscape (http://www.inkscape.org/) --> + +<svg + xmlns:dc="http://purl.org/dc/elements/1.1/" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns="http://www.w3.org/2000/svg" + xmlns:xlink="http://www.w3.org/1999/xlink" + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" + version="1.1" + id="svg2" + width="682.66669" + height="682.66669" + viewBox="0 0 682.66669 682.66669" + sodipodi:docname="harfbuzz2.svg" + inkscape:version="0.92.2 5c3e80d, 2017-08-06" + inkscape:export-filename="harfbuzz2.png" + inkscape:export-xdpi="72" + inkscape:export-ydpi="72"> + <metadata + id="metadata8"> + <rdf:RDF> + <cc:Work + rdf:about=""> + <dc:format>image/svg+xml</dc:format> + <dc:type + rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> + <dc:title /> + </cc:Work> + </rdf:RDF> + </metadata> + <defs + id="defs6"> + <g + id="g50"> + <symbol + id="glyph0-0" + overflow="visible" + style="overflow:visible"> + <path + id="path26" + d="M 32,0 V -192 H 224 V 0 Z M 48,-16 H 208 V -176 H 48 Z m 0,0" + style="stroke:none" + inkscape:connector-curvature="0" /> + </symbol> + <symbol + id="glyph0-1" + overflow="visible" + style="overflow:visible"> + <path + id="path29" + d="m 52.5,-64.875 c -0.08594,2.25 -0.9375,6.335938 -2.5625,12.25 -1.625,5.917969 -3.75,12.375 -6.375,19.375 -2.625,7 -4.9375,12.292969 -6.9375,15.875 -2,3.585938 -4.1875,6.3125 -6.5625,8.1875 -2.375,1.875 -6.210938,3.585938 -11.5,5.125 -5.292969,1.542969 -9.542969,2.585938 -12.75,3.125 -3.210938,0.542969 -5.230469,0.8125 -6.0625,0.8125 -0.832031,-0.082031 -1.332031,-0.414062 -1.5,-1 -0.164062,-0.582031 0.085938,-1.332031 0.75,-2.25 0.9179688,-1.414062 3.226562,-3.269531 6.9375,-5.5625 3.707031,-2.289062 8.019531,-5.164062 12.9375,-8.625 4.914062,-3.457031 8.414062,-6.476562 10.5,-9.0625 2.082031,-2.582031 4.4375,-6.457031 7.0625,-11.625 2.625,-5.164062 5,-10.375 7.125,-15.625 2.125,-5.25 3.644531,-8.832031 4.5625,-10.75 0.914062,-1.914062 1.914062,-2.832031 3,-2.75 0.914062,0.167969 1.375,1 1.375,2.5 z M 41.75,-117.75 c 0,-1.83203 1.5625,-5.8125 4.6875,-11.9375 3.125,-6.125 5.144531,-9.1875 6.0625,-9.1875 1.832031,-0.75 4.5,0.64844 8,4.1875 3.5,3.54297 5.375,6.3125 5.625,8.3125 0,2.66797 -1.460938,6.5 -4.375,11.5 -2.917969,5 -5.042969,7.5 -6.375,7.5 -0.5,-0.25 -2.230469,-1.35156 -5.1875,-3.3125 -2.960938,-1.95703 -5.148438,-3.4375 -6.5625,-4.4375 -1.25,-0.83203 -1.875,-1.70703 -1.875,-2.625 z m 0,0" + style="stroke:none" + inkscape:connector-curvature="0" /> + </symbol> + <symbol + id="glyph0-2" + overflow="visible" + style="overflow:visible"> + <path + id="path32" + d="m 19.75,-47.125 c -0.167969,3.167969 -0.5,6.023438 -1,8.5625 -0.5,2.542969 -1.167969,4.710938 -2,6.5 -0.835938,1.792969 -1.898438,3.125 -3.1875,4 -1.292969,0.875 -2.855469,1.1875 -4.6875,0.9375 0.082031,-6.5 0.769531,-15.5625 2.0625,-27.1875 1.289062,-11.625 3.226562,-24.476562 5.8125,-38.5625 1.332031,-4.082031 4.039062,-11.28906 8.125,-21.625 0.414062,-1 0.851562,-1.41406 1.3125,-1.25 0.457031,0.16797 0.6875,0.58594 0.6875,1.25 -0.25,5.08594 -1.292969,14.792969 -3.125,29.125 -1.835938,14.335938 -2.960938,24.167969 -3.375,29.5 -0.417969,5.335938 -0.625,8.25 -0.625,8.75 z m 0,0" + style="stroke:none" + inkscape:connector-curvature="0" /> + </symbol> + <symbol + id="glyph0-3" + overflow="visible" + style="overflow:visible"> + <path + id="path35" + d="m -10.875,-27.25 c 1.667969,-7.164062 3.5625,-12.457031 5.6875,-15.875 2.125,-3.414062 3.855469,-5.289062 5.1875,-5.625 v 5.5 c 0,7 1.875,11.875 5.625,14.625 2.25,1.5 4.5,2 6.75,1.5 2.25,-0.5 3.976562,-1.664062 5.1875,-3.5 1.207031,-1.832031 2.226562,-3.976562 3.0625,-6.4375 0.832031,-2.457031 1.625,-3.6875 2.375,-3.6875 0.914062,0 1.289062,0.875 1.125,2.625 -0.08594,3 -1.023438,7.875 -2.8125,14.625 C 19.519531,-16.75 17.082031,-11.207031 14,-6.875 10.914062,-2.539062 7.164062,-0.25 2.75,0 c -4.5,-0.164062 -8,-2.707031 -10.5,-7.625 -2.25,-4.832031 -3.289062,-11.082031 -3.125,-18.75 z m 6.625,111.5 c 0,-1.835938 1.5625,-5.8125 4.6875,-11.9375 3.125,-6.125 5.144531,-9.1875 6.0625,-9.1875 1.832031,-0.75 4.5,0.644531 8,4.1875 3.5,3.539062 5.375,6.3125 5.625,8.3125 0,2.664062 -1.460938,6.5 -4.375,11.5 -2.917969,5 -5.042969,7.5 -6.375,7.5 C 8.875,94.375 7.144531,93.269531 4.1875,91.3125 1.226562,89.351562 -0.957031,87.875 -2.375,86.875 -3.625,86.039062 -4.25,85.164062 -4.25,84.25 Z m 0,0" + style="stroke:none" + inkscape:connector-curvature="0" /> + </symbol> + <symbol + id="glyph0-4" + overflow="visible" + style="overflow:visible"> + <path + id="path38" + d="" + style="stroke:none" + inkscape:connector-curvature="0" /> + </symbol> + <symbol + id="glyph0-5" + overflow="visible" + style="overflow:visible"> + <path + id="path41" + d="m 118.5,-33 c 15.33203,-3.914062 27.375,-8.289062 36.125,-13.125 7.5,-4.082031 11.25,-7.5 11.25,-10.25 0,-0.832031 -0.5625,-1.894531 -1.6875,-3.1875 -1.125,-1.289062 -1.9375,-1.9375 -2.4375,-1.9375 -0.83594,0 -2.02344,0.148438 -3.5625,0.4375 -1.54297,0.292969 -2.64844,0.4375 -3.3125,0.4375 -2.91797,0 -4.98047,-0.769531 -6.1875,-2.3125 -1.21094,-1.539062 -1.8125,-3.601562 -1.8125,-6.1875 0,-1.5 2.16406,-6.539062 6.5,-15.125 1.66406,-3.414062 3.0625,-5.8125 4.1875,-7.1875 1.125,-1.375 2.76953,-2.0625 4.9375,-2.0625 3.58203,0 6.91406,1.9375 10,5.8125 3.08203,3.875 4.625,8.855469 4.625,14.9375 0,6 -0.8125,11.4375 -2.4375,16.3125 -1.625,4.875 -4.14844,9.605469 -7.5625,14.1875 -3.41797,4.585938 -7.83594,9.042969 -13.25,13.375 -8.08594,6.085938 -17.625,11.230469 -28.625,15.4375 -11,4.210938 -23.83594,7.5 -38.5,9.875 C 72.082031,-1.1875 58.082031,0 44.75,0 37.082031,0 30.082031,-0.375 23.75,-1.125 17.414062,-1.875 12.582031,-3.289062 9.25,-5.375 3.082031,-8.789062 0.25,-14.5 0.75,-22.5 c 0.332031,-4.082031 0.832031,-8.4375 1.5,-13.0625 0.664062,-4.625 1.351562,-8.3125 2.0625,-11.0625 0.707031,-2.75 1.5625,-4.125 2.5625,-4.125 0.832031,0 1.332031,1.75 1.5,5.25 0.164062,3.5 0.6875,6.0625 1.5625,7.6875 0.875,1.625 2.207031,3 4,4.125 1.789062,1.125 4.6875,2.210938 8.6875,3.25 4,1.042969 8.6875,1.855469 14.0625,2.4375 5.375,0.585938 12.519531,0.875 21.4375,0.875 12.414062,0 23.019531,-0.4375 31.8125,-1.3125 C 98.726562,-29.3125 108.25,-30.832031 118.5,-33 Z m -38.75,-86.75 c 0,-1.83203 1.5625,-5.8125 4.6875,-11.9375 3.125,-6.125 5.144531,-9.1875 6.0625,-9.1875 1.832031,-0.75 4.5,0.64844 8,4.1875 3.5,3.54297 5.375,6.3125 5.625,8.3125 0,2.66797 -1.46094,6.5 -4.375,11.5 -2.917969,5 -5.042969,7.5 -6.375,7.5 -0.5,-0.25 -2.230469,-1.35156 -5.1875,-3.3125 -2.960938,-1.95703 -5.148438,-3.4375 -6.5625,-4.4375 -1.25,-0.83203 -1.875,-1.70703 -1.875,-2.625 z m 0,0" + style="stroke:none" + inkscape:connector-curvature="0" /> + </symbol> + <symbol + id="glyph0-6" + overflow="visible" + style="overflow:visible"> + <path + id="path44" + d="m 78,-56.875 c -1.335938,2.25 -2.25,3.875 -2.75,4.875 -1.417969,2.335938 -2.875,4.210938 -4.375,5.625 -1.75,1.75 -4.042969,3.292969 -6.875,4.625 -6.085938,2.917969 -10.460938,5.75 -13.125,8.5 -1.75,1.75 -3.792969,4.960938 -6.125,9.625 -4.25,8.585938 -8.417969,14.292969 -12.5,17.125 -4.085938,2.917969 -11.417969,5 -22,6.25 C 9.414062,-0.0820312 8.414062,0 7.25,0 H 4.375 c -1.5,0 -2.25,-0.164062 -2.25,-0.5 0,-1.914062 2.539062,-4.5 7.625,-7.75 4,-2.414062 7,-4.207031 9,-5.375 6,-3.414062 10.414062,-6.125 13.25,-8.125 4,-2.914062 6.625,-5.75 7.875,-8.5 4.164062,-8.5 7.625,-14.414062 10.375,-17.75 3.082031,-3.664062 6.625,-6.5 10.625,-8.5 C 67.289062,-60.082031 71,-62.207031 72,-62.875 l 10,2.375 z m 0,0" + style="stroke:none" + inkscape:connector-curvature="0" /> + </symbol> + <symbol + id="glyph0-7" + overflow="visible" + style="overflow:visible"> + <path + id="path47" + d="m 13,-17.625 c -1,1.75 -2.0625,3.480469 -3.1875,5.1875 C 8.6875,-10.726562 7.539062,-9.082031 6.375,-7.5 5.207031,-5.914062 4.0625,-4.476562 2.9375,-3.1875 1.8125,-1.894531 0.832031,-0.832031 0,0 c -0.5,-2.582031 -0.832031,-5.125 -1,-7.625 -0.164062,-2.5 0.167969,-5.039062 1,-7.625 1.25,-0.75 2.207031,-1.414062 2.875,-2 1.664062,-1.5 5.375,-6.582031 11.125,-15.25 -0.667969,-0.664062 -2.585938,-1.601562 -5.75,-2.8125 -3.167969,-1.207031 -6.167969,-1.894531 -9,-2.0625 -2.582031,-0.164062 -4.726562,0.3125 -6.4375,1.4375 -1.707031,1.125 -3.25,2.710938 -4.625,4.75 -1.375,2.042969 -2.5625,2.980469 -3.5625,2.8125 -0.332031,-0.164062 -0.375,-0.851562 -0.125,-2.0625 0.25,-1.207031 0.625,-2.394531 1.125,-3.5625 2.085938,-4.832031 4.480469,-8.4375 7.1875,-10.8125 2.710938,-2.375 5.9375,-3.5625 9.6875,-3.5625 2.75,0 6.164062,0.667969 10.25,2 2.582031,0.917969 4.789062,1.375 6.625,1.375 3.832031,0 7.625,-1.375 11.375,-4.125 0.832031,0 1.125,0.542969 0.875,1.625 -0.25,1.085938 -0.605469,2.355469 -1.0625,3.8125 -0.460938,1.460938 -0.773438,2.4375 -0.9375,2.9375 -0.835938,2.585938 -1.5,4.085938 -2,4.5 -0.5,0.417969 -1.960938,1.5 -4.375,3.25 -1.335938,1 -2.480469,2.148438 -3.4375,3.4375 -0.960938,1.292969 -1.9375,2.835938 -2.9375,4.625 -1,1.792969 -2.292969,4.230469 -3.875,7.3125 z m 0,0" + style="stroke:none" + inkscape:connector-curvature="0" /> + </symbol> + </g> + <g + id="g184"> + <symbol + id="glyph0-0-3" + overflow="visible" + style="overflow:visible"> + <path + id="path163" + d="" + style="stroke:none" + inkscape:connector-curvature="0" /> + </symbol> + <symbol + id="glyph0-1-6" + overflow="visible" + style="overflow:visible"> + <path + id="path166" + d="m 79.625,-103.25 c -3.585938,22 -6.8125,38.417969 -9.6875,49.25 -2.875,10.835938 -5.480469,19.105469 -7.8125,24.8125 -2.335938,5.710938 -4.898438,10.0625 -7.6875,13.0625 -2.792969,3 -7.917969,5.855469 -15.375,8.5625 -7.460938,2.710938 -13.6875,4.605469 -18.6875,5.6875 -5,1.085938 -8.125,1.667969 -9.375,1.75 C 9.75,-0.207031 8.957031,-0.4375 8.625,-0.8125 8.289062,-1.1875 8.582031,-2.082031 9.5,-3.5 c 1.582031,-2.25 4.894531,-5.332031 9.9375,-9.25 5.039062,-3.914062 11,-8.789062 17.875,-14.625 6.875,-5.832031 12.019531,-10.976562 15.4375,-15.4375 3.414062,-4.457031 6.4375,-10.539062 9.0625,-18.25 C 64.4375,-68.769531 67,-76.832031 69.5,-85.25 c 2.5,-8.414062 4.3125,-14.125 5.4375,-17.125 1.125,-3 2.269531,-4.45703 3.4375,-4.375 1.332031,0.25 1.75,1.41797 1.25,3.5 z m 8.875,-68.625 c 0.664062,2.41797 0.644531,4.91797 -0.0625,7.5 -0.710938,2.58594 -2.023438,5.29297 -3.9375,8.125 -1.167969,1.91797 -2.398438,3.64844 -3.6875,5.1875 -1.292969,1.54297 -2.648438,3.02344 -4.0625,4.4375 -0.417969,0.5 -1.085938,1.125 -2,1.875 -0.917969,0.75 -1.875,1.46094 -2.875,2.125 -1,0.66797 -1.960938,1.14844 -2.875,1.4375 -0.917969,0.29297 -1.585938,0.1875 -2,-0.3125 -3,-2.41406 -5.960938,-4.875 -8.875,-7.375 -2.917969,-2.5 -6.125,-4.83203 -9.625,-7 -0.585938,-0.41406 -0.855469,-0.8125 -0.8125,-1.1875 0.03906,-0.375 0.269531,-0.9375 0.6875,-1.6875 l 20,-30.5 c 0.582031,-0.83203 1.164062,-1.22656 1.75,-1.1875 0.582031,0.043 1.207031,0.27344 1.875,0.6875 1.75,1 3.5,2.125 5.25,3.375 1.75,1.25 3.375,2.60547 4.875,4.0625 1.5,1.46094 2.8125,3.04297 3.9375,4.75 1.125,1.71094 1.9375,3.60547 2.4375,5.6875 z m 0,0" + style="stroke:none" + inkscape:connector-curvature="0" /> + </symbol> + <symbol + id="glyph0-2-7" + overflow="visible" + style="overflow:visible"> + <path + id="path169" + d="m 29.625,-70.625 c -0.667969,8.335938 -2.542969,15.417969 -5.625,21.25 -3.085938,5.835938 -6.585938,8.75 -10.5,8.75 0,-3.164062 1.019531,-13 3.0625,-29.5 2.039062,-16.5 3.582031,-28.3125 4.625,-35.4375 1.039062,-7.125 2.226562,-14.6875 3.5625,-22.6875 1.332031,-8 2.625,-14.45703 3.875,-19.375 1.414062,-4.08203 2.9375,-8.20703 4.5625,-12.375 1.625,-4.16406 3.3125,-8.28906 5.0625,-12.375 1.164062,-1.83203 1.914062,-1.53906 2.25,0.875 -2.085938,13.83594 -4,28.1875 -5.75,43.0625 -1.75,14.875 -2.9375,25.52344 -3.5625,31.9375 -0.625,6.417969 -0.9375,10.167969 -0.9375,11.25 -0.417969,6.835938 -0.625,11.710938 -0.625,14.625 z m 0,0" + style="stroke:none" + inkscape:connector-curvature="0" /> + </symbol> + <symbol + id="glyph0-3-5" + overflow="visible" + style="overflow:visible"> + <path + id="path172" + d="m -16.125,-40.625 c 1.25,-5.332031 2.625,-10 4.125,-14 1.5,-4 2.960938,-7.3125 4.375,-9.9375 1.417969,-2.625 2.792969,-4.644531 4.125,-6.0625 1.335938,-1.414062 2.5,-2.25 3.5,-2.5 v 8.25 c 0,10.5 2.789062,17.835938 8.375,22 3.414062,2.25 6.8125,3 10.1875,2.25 3.375,-0.75 5.957031,-2.5 7.75,-5.25 1.789062,-2.75 3.3125,-5.976562 4.5625,-9.6875 1.25,-3.707031 2.457031,-5.5625 3.625,-5.5625 1.332031,0 1.875,1.335938 1.625,4 -0.08594,4.5 -1.480469,11.8125 -4.1875,21.9375 -2.710938,10.125 -6.375,18.4375 -11,24.9375 -4.625,6.5 -10.230469,9.917969 -16.8125,10.25 -6.75,-0.25 -12,-4.039062 -15.75,-11.375 -3.414062,-7.25 -4.914062,-16.625 -4.5,-28.125 z M 28.5,82.125 c 0.664062,2.414062 0.644531,4.914062 -0.0625,7.5 -0.710938,2.582031 -2.023438,5.289062 -3.9375,8.125 -1.167969,1.914062 -2.398438,3.64453 -3.6875,5.1875 -1.292969,1.53906 -2.648438,3.01953 -4.0625,4.4375 -0.417969,0.5 -1.085938,1.125 -2,1.875 -0.917969,0.75 -1.875,1.45703 -2.875,2.125 -1,0.66406 -1.960938,1.14453 -2.875,1.4375 C 8.082031,113.10156 7.414062,113 7,112.5 c -3,-2.41797 -5.960938,-4.875 -8.875,-7.375 -2.914062,-2.5 -6.125,-4.83594 -9.625,-7 -0.582031,-0.417969 -0.851562,-0.8125 -0.8125,-1.1875 0.04297,-0.375 0.273438,-0.9375 0.6875,-1.6875 l 20,-30.5 c 0.582031,-0.835938 1.164062,-1.230469 1.75,-1.1875 0.582031,0.03906 1.207031,0.269531 1.875,0.6875 1.75,1 3.5,2.125 5.25,3.375 1.75,1.25 3.375,2.601562 4.875,4.0625 1.5,1.457031 2.8125,3.039062 3.9375,4.75 1.125,1.707031 1.9375,3.601562 2.4375,5.6875 z m 0,0" + style="stroke:none" + inkscape:connector-curvature="0" /> + </symbol> + <symbol + id="glyph0-4-3" + overflow="visible" + style="overflow:visible"> + <path + id="path175" + d="" + style="stroke:none" + inkscape:connector-curvature="0" /> + </symbol> + <symbol + id="glyph0-5-5" + overflow="visible" + style="overflow:visible"> + <path + id="path178" + d="M 72.125,0.125 C 58.039062,0.0390625 47.164062,-0.582031 39.5,-1.75 26.164062,-3.832031 16.664062,-7.832031 11,-13.75 5.914062,-18.332031 3.375,-24.582031 3.375,-32.5 c 0,-3.082031 0.289062,-7.5 0.875,-13.25 0.582031,-5.75 1.375,-11.5 2.375,-17.25 0.414062,-2.414062 0.789062,-4.582031 1.125,-6.5 0.25,-1.332031 0.582031,-2.414062 1,-3.25 0.414062,-0.832031 0.875,-1.3125 1.375,-1.4375 0.5,-0.125 0.976562,0.210938 1.4375,1 0.457031,0.792969 0.894531,2.148438 1.3125,4.0625 0.332031,2.085938 0.789062,4.25 1.375,6.5 1.332031,5.417969 4.957031,9.460938 10.875,12.125 15,6.417969 37.914062,9.75 68.75,10 12.75,-0.164062 24.58203,-0.625 35.5,-1.375 11.16406,-0.832031 23.75,-2.789062 37.75,-5.875 14,-3.082031 25.14453,-6.457031 33.4375,-10.125 8.28906,-3.664062 15.35156,-7.625 21.1875,-11.875 4.58203,-3.332031 6.875,-6.539062 6.875,-9.625 0,-1.25 -1.1875,-2.726562 -3.5625,-4.4375 -2.375,-1.707031 -3.9375,-2.5625 -4.6875,-2.5625 -1.41797,0.667969 -3.08594,1.1875 -5,1.5625 -1.91797,0.375 -3.66797,0.480469 -5.25,0.3125 -4.41797,-0.5 -7.71094,-1.875 -9.875,-4.125 -2.16797,-2.25 -3.25,-5.289062 -3.25,-9.125 0,-2.41406 3.20703,-10 9.625,-22.75 2.58203,-5.16406 4.85156,-8.76953 6.8125,-10.8125 1.95703,-2.03906 4.64453,-3.0625 8.0625,-3.0625 5.41406,0 10.4375,2.91797 15.0625,8.75 4.625,5.83594 6.9375,13.29297 6.9375,22.375 0,9 -1.21094,16.792969 -3.625,23.375 -3,9 -7.08594,17.335938 -12.25,25 -6.5,9.25 -13.625,16.5625 -21.375,21.9375 -7.75,5.375 -15.58594,9.648438 -23.5,12.8125 -7.08594,3.5 -16.23047,6.773438 -27.4375,9.8125 -11.21094,3.042969 -24.8125,5.523438 -40.8125,7.4375 -15.835938,1.917969 -29.960938,2.9140625 -42.375,3 z m 82.375,-172 c 0.66406,2.41797 0.64453,4.91797 -0.0625,7.5 -0.71094,2.58594 -2.02344,5.29297 -3.9375,8.125 -1.16797,1.91797 -2.39844,3.64844 -3.6875,5.1875 -1.29297,1.54297 -2.64844,3.02344 -4.0625,4.4375 -0.41797,0.5 -1.08594,1.125 -2,1.875 -0.91797,0.75 -1.875,1.46094 -2.875,2.125 -1,0.66797 -1.96094,1.14844 -2.875,1.4375 -0.91797,0.29297 -1.58594,0.1875 -2,-0.3125 -3,-2.41406 -5.96094,-4.875 -8.875,-7.375 -2.91797,-2.5 -6.125,-4.83203 -9.625,-7 -0.58594,-0.41406 -0.85547,-0.8125 -0.8125,-1.1875 0.0391,-0.375 0.26953,-0.9375 0.6875,-1.6875 l 20,-30.5 c 0.58203,-0.83203 1.16406,-1.22656 1.75,-1.1875 0.58203,0.043 1.20703,0.27344 1.875,0.6875 1.75,1 3.5,2.125 5.25,3.375 1.75,1.25 3.375,2.60547 4.875,4.0625 1.5,1.46094 2.8125,3.04297 3.9375,4.75 1.125,1.71094 1.9375,3.60547 2.4375,5.6875 z m 0,0" + style="stroke:none" + inkscape:connector-curvature="0" /> + </symbol> + <symbol + id="glyph0-6-6" + overflow="visible" + style="overflow:visible"> + <path + id="path181" + d="m 115,-102.5 c -1.83594,3.25 -3.75,6.523438 -5.75,9.8125 -2,3.292969 -4.23047,6.398438 -6.6875,9.3125 -2.46094,2.917969 -5.167969,5.5625 -8.125,7.9375 -2.960938,2.375 -6.3125,4.273438 -10.0625,5.6875 -3.085938,1.25 -5.710938,2.648438 -7.875,4.1875 -2.167969,1.542969 -3.960938,3.1875 -5.375,4.9375 -2.167969,2.335938 -4.042969,5.5625 -5.625,9.6875 -1.585938,4.125 -3.230469,8.480469 -4.9375,13.0625 -1.710938,4.585938 -3.585938,9.0625 -5.625,13.4375 -2.042969,4.375 -4.605469,7.980469 -7.6875,10.8125 C 43,-9.125 36.707031,-6.082031 28.375,-4.5 L 5.5,-0.625 C 4.832031,-0.539062 4.019531,-0.476562 3.0625,-0.4375 2.101562,-0.394531 1.414062,-0.414062 1,-0.5 -0.914062,-1.082031 -1.5,-2.351562 -0.75,-4.3125 0,-6.269531 1.957031,-8.25 5.125,-10.25 c 6.414062,-4.25 11.539062,-7.6875 15.375,-10.3125 3.832031,-2.625 6.957031,-4.769531 9.375,-6.4375 2.414062,-1.664062 4.351562,-3.039062 5.8125,-4.125 1.457031,-1.082031 3.019531,-2.289062 4.6875,-3.625 6.75,-5.082031 11.414062,-10.414062 14,-16 1.5,-2.914062 2.875,-5.75 4.125,-8.5 1.25,-2.75 2.5625,-5.457031 3.9375,-8.125 1.375,-2.664062 2.851562,-5.3125 4.4375,-7.9375 1.582031,-2.625 3.414062,-5.269531 5.5,-7.9375 2.164062,-2.664062 5.082031,-5.269531 8.75,-7.8125 3.664062,-2.539062 8.082031,-5.0625 13.25,-7.5625 0.582031,-0.25 1.539062,-0.8125 2.875,-1.6875 1.332031,-0.875 2.95703,-2.26953 4.875,-4.1875 1.91406,-1.91406 4.10156,-4.51953 6.5625,-7.8125 2.45703,-3.28906 5.0625,-7.47656 7.8125,-12.5625 -1,-1 -3.875,-2.375 -8.625,-4.125 -4.75,-1.83203 -9.25,-2.875 -13.5,-3.125 -3.917969,-0.25 -7.148438,0.46094 -9.6875,2.125 -2.542969,1.66797 -4.855469,4.04297 -6.9375,7.125 -2.085938,3.08594 -3.875,4.5 -5.375,4.25 -0.5,-0.25 -0.585938,-1.28906 -0.25,-3.125 0.414062,-1.83203 1,-3.625 1.75,-5.375 3.164062,-7.25 6.75,-12.625 10.75,-16.125 4.082031,-3.58203 8.957031,-5.375 14.625,-5.375 4.08203,0 9.20703,1 15.375,3 3.83203,1.33594 7.125,2 9.875,2 5.75,0 11.45703,-2.03906 17.125,-6.125 1.25,0 1.6875,0.8125 1.3125,2.4375 -0.375,1.625 -0.9375,3.52344 -1.6875,5.6875 -0.66797,2.16797 -1.125,3.625 -1.375,4.375 -1.25,3.91797 -2.25,6.21094 -3,6.875 -0.75,0.58594 -2.91797,2.16797 -6.5,4.75 -2,1.5 -3.73047,3.23047 -5.1875,5.1875 -1.46094,1.96094 -2.9375,4.27344 -4.4375,6.9375 -1.5,2.66797 -3.41797,6.33594 -5.75,11 z m 0,0" + style="stroke:none" + inkscape:connector-curvature="0" /> + </symbol> + </g> + </defs> + <sodipodi:namedview + pagecolor="#ffffff" + bordercolor="#666666" + borderopacity="1" + objecttolerance="10" + gridtolerance="10" + guidetolerance="10" + inkscape:pageopacity="0" + inkscape:pageshadow="2" + inkscape:window-width="2560" + inkscape:window-height="1471" + id="namedview4" + showgrid="false" + inkscape:zoom="0.59454973" + inkscape:cx="-165.7731" + inkscape:cy="361.75575" + inkscape:window-x="0" + inkscape:window-y="55" + inkscape:window-maximized="1" + inkscape:current-layer="svg2" /> + <path + id="path871" + d="m 205.59223,196.11402 c -5.97657,36.66667 -11.35417,64.02995 -16.14583,82.08333 -4.79167,18.0599 -9.13412,31.84245 -13.02084,41.35417 -3.89323,9.51823 -8.16406,16.77083 -12.8125,21.77083 -4.65495,5 -13.19661,9.75912 -25.625,14.27083 -12.43489,4.51823 -22.8125,7.67579 -31.14583,9.47917 -8.333331,1.8099 -13.541664,2.77995 -15.624997,2.91667 -2.083334,-0.13672 -3.404949,-0.52084 -3.958334,-1.14584 -0.559896,-0.625 -0.07161,-2.11588 1.458334,-4.47916 2.636718,-3.75 8.157551,-8.88672 16.562497,-15.41667 8.39844,-6.52344 18.33333,-14.64844 29.79167,-24.375 11.45833,-9.72005 20.03255,-18.29427 25.72916,-25.72916 5.69011,-7.42839 10.72917,-17.56511 15.10417,-30.41667 4.375,-12.84505 8.64583,-26.28255 12.8125,-40.3125 4.16667,-14.02343 7.1875,-23.54166 9.0625,-28.54166 1.875,-5 3.78255,-7.42839 5.72916,-7.29167 2.22006,0.41667 2.91667,2.36328 2.08334,5.83333 z M 220.38389,81.739028 c 1.10677,4.02995 1.07422,8.196616 -0.10416,12.5 -1.1849,4.309899 -3.3724,8.821612 -6.5625,13.541662 -1.94662,3.19662 -3.9974,6.08074 -6.14584,8.64584 -2.15494,2.57161 -4.41406,5.03906 -6.77083,7.39583 -0.69661,0.83333 -1.8099,1.875 -3.33333,3.125 -1.52995,1.25 -3.125,2.4349 -4.79167,3.54167 -1.66666,1.11328 -3.26823,1.91406 -4.79166,2.39583 -1.52995,0.48828 -2.64323,0.3125 -3.33334,-0.52083 -5,-4.02344 -9.93489,-8.125 -14.79166,-12.29167 -4.86329,-4.16667 -10.20834,-8.05338 -16.04167,-11.66667 -0.97656,-0.6901 -1.42578,-1.35416 -1.35417,-1.97916 0.0651,-0.625 0.44922,-1.5625 1.14584,-2.8125 l 33.33333,-50.833334 c 0.97005,-1.386717 1.9401,-2.044267 2.91667,-1.979167 0.97005,0.07167 2.01171,0.455734 3.125,1.145834 2.91666,1.666666 5.83333,3.541666 8.74999,5.624999 2.91667,2.083334 5.625,4.34245 8.125,6.770833 2.5,2.4349 4.6875,5.071617 6.5625,7.916667 1.875,2.851566 3.22917,6.009116 4.0625,9.479166 z m 0,0" + style="fill:#000000;fill-opacity:1;stroke:none;stroke-width:1.66666663" + inkscape:connector-curvature="0" /> + <path + inkscape:connector-curvature="0" + style="fill:#000000;fill-opacity:1;stroke:none;stroke-width:1.66666663" + d="m 256.21722,250.48902 c -1.11328,13.89323 -4.23828,25.69662 -9.375,35.41667 -5.14323,9.72656 -10.97656,14.58333 -17.5,14.58333 0,-5.27344 1.69922,-21.66667 5.10417,-49.16667 3.39843,-27.49999 5.97005,-47.18749 7.70833,-59.06249 1.73177,-11.875 3.71094,-24.47917 5.9375,-37.8125 2.22005,-13.33333 4.375,-24.09505 6.45833,-32.29167 2.35677,-6.80338 4.89583,-13.67838 7.60417,-20.625 2.70833,-6.940096 5.52083,-13.815095 8.4375,-20.624995 1.9401,-3.053383 3.1901,-2.5651 3.75,1.458333 -3.47657,23.059902 -6.66667,46.979162 -9.58334,71.770832 -2.91666,24.79166 -4.89583,42.53906 -5.9375,53.22916 -1.04166,10.69662 -1.5625,16.94662 -1.5625,18.75 -0.69661,11.39323 -1.04166,19.51823 -1.04166,24.375 z m 0,0" + id="path875" /> + <path + id="path945" + d="m 229.34222,300.48902 c 2.08333,-8.88672 4.375,-16.66667 6.875,-23.33333 2.5,-6.66667 4.9349,-12.1875 7.29167,-16.5625 2.36328,-4.375 4.65495,-7.74089 6.875,-10.10417 2.22656,-2.35677 4.16666,-3.75 5.83333,-4.16667 v 13.75 c 0,17.5 4.64844,29.72657 13.95833,36.66667 5.69011,3.75 11.35417,5 16.97917,3.75 5.625,-1.25 9.92838,-4.16667 12.91666,-8.75 2.98177,-4.58333 5.52084,-9.96094 7.60417,-16.14583 2.08333,-6.17839 4.09505,-9.27084 6.04167,-9.27084 2.22005,0 3.125,2.22657 2.70833,6.66667 -0.14323,7.5 -2.46745,19.6875 -6.97917,36.5625 -4.51823,16.875 -10.625,30.72916 -18.33333,41.5625 -7.70833,10.83333 -17.05078,16.52995 -28.02083,17.08333 -11.25,-0.41667 -20,-6.73177 -26.25,-18.95833 -5.6901,-12.08334 -8.1901,-27.70833 -7.5,-46.875 z" + style="fill:#000000;fill-opacity:1;stroke:none;stroke-width:1.66666663" + inkscape:connector-curvature="0" /> + <path + id="path943" + d="m 286.78334,583.03989 c 1.10677,4.02343 1.07422,8.1901 -0.10416,12.5 -1.1849,4.30338 -3.3724,8.8151 -6.5625,13.54167 -1.94662,3.1901 -3.9974,6.07421 -6.14584,8.64583 -2.15495,2.5651 -4.41406,5.03255 -6.77083,7.39583 -0.69662,0.83334 -1.8099,1.875 -3.33333,3.125 -1.52995,1.25 -3.125,2.42839 -4.79167,3.54167 -1.66667,1.10677 -3.26823,1.90755 -4.79167,2.39583 -1.52994,0.48177 -2.64323,0.3125 -3.33333,-0.52083 -5,-4.02995 -9.9349,-8.125 -14.79167,-12.29167 -4.85677,-4.16666 -10.20833,-8.0599 -16.04166,-11.66666 -0.97005,-0.69662 -1.41927,-1.35417 -1.35417,-1.97917 0.0716,-0.625 0.45573,-1.5625 1.14583,-2.8125 l 33.33334,-50.83333 c 0.97005,-1.39323 1.9401,-2.05078 2.91666,-1.97917 0.97006,0.0652 2.01172,0.44922 3.125,1.14584 2.91667,1.66666 5.83334,3.54166 8.75,5.625 2.91667,2.08333 5.625,4.33593 8.125,6.77083 2.5,2.42838 4.6875,5.0651 6.5625,7.91667 1.875,2.84505 3.22917,6.00259 4.0625,9.47916 z" + style="fill:#000000;fill-opacity:1;stroke:none;stroke-width:1.66666663" + inkscape:connector-curvature="0" /> + <path + id="path879" + d="M 303.71722,505.07234" + style="fill:#000000;fill-opacity:1;stroke:none;stroke-width:1.66666663" + inkscape:connector-curvature="0" /> + <path + inkscape:connector-curvature="0" + id="path925" + d="m 168.42167,500.82557 c -23.47656,-0.14323 -41.60156,-1.17838 -54.375,-3.125 -22.226562,-3.47005 -38.059894,-10.13671 -47.499997,-20 -8.476563,-7.63671 -12.708333,-18.05338 -12.708333,-31.24999 0,-5.13672 0.48177,-12.5 1.458333,-22.08334 0.970052,-9.58333 2.291667,-19.16666 3.958333,-28.75 0.690104,-4.02343 1.315104,-7.63671 1.875,-10.83333 0.416667,-2.22005 0.970052,-4.02344 1.666667,-5.41667 0.690103,-1.38671 1.458333,-2.1875 2.291666,-2.39583 0.833334,-0.20833 1.627604,0.35156 2.395834,1.66667 0.761718,1.32161 1.490885,3.58073 2.187499,6.77083 0.553385,3.47656 1.315104,7.08333 2.291667,10.83333 2.220052,9.02995 8.261718,15.76823 18.124999,20.20834 25.000002,10.69661 63.190102,16.25 114.583332,16.66666 21.25,-0.27343 40.97005,-1.04166 59.16666,-2.29166 18.60677,-1.38672 39.58333,-4.64844 62.91667,-9.79167 23.33333,-5.13672 41.90754,-10.76172 55.72916,-16.875 13.8151,-6.10677 25.58593,-12.70833 35.3125,-19.79167 7.63671,-5.55338 11.45833,-10.89843 11.45833,-16.04166 0,-2.08333 -1.97917,-4.54427 -5.9375,-7.39583 -3.95833,-2.84506 -6.5625,-4.27084 -7.8125,-4.27084 -2.36328,1.11328 -5.14323,1.97917 -8.33333,2.60417 -3.19662,0.625 -6.11328,0.80078 -8.75,0.52083 -7.36328,-0.83333 -12.85157,-3.125 -16.45833,-6.875 -3.61329,-3.75 -5.41667,-8.8151 -5.41667,-15.20833 0,-4.02343 5.34505,-16.66667 16.04167,-37.91667 4.30338,-8.60676 8.08593,-14.61588 11.35416,-18.02083 3.26172,-3.39843 7.74089,-5.10416 13.4375,-5.10416 9.02343,0 17.39583,4.86328 25.10417,14.58333 7.70833,9.72656 11.5625,22.15495 11.5625,37.29166 0,15 -2.01824,27.98828 -6.04167,38.95834 -5,14.99999 -11.8099,28.89322 -20.41667,41.66666 -10.83333,15.41667 -22.70833,27.60417 -35.62499,36.5625 -12.91667,8.95833 -25.97657,16.08073 -39.16667,21.35416 -11.8099,5.83334 -27.05078,11.28907 -45.72916,16.35417 -18.6849,5.07162 -41.35417,9.20573 -68.02083,12.39583 -26.39323,3.19662 -49.9349,4.85677 -70.625,5 z" + style="fill:#000000;fill-opacity:1;stroke:none;stroke-width:1.66666663" /> + <path + inkscape:connector-curvature="0" + id="path923" + d="m 430.22191,133.16177 c 1.10676,4.02995 1.07421,8.19662 -0.10417,12.5 -1.1849,4.3099 -3.3724,8.82162 -6.5625,13.54167 -1.94661,3.19661 -3.9974,6.08073 -6.14583,8.64583 -2.15495,2.57162 -4.41407,5.03907 -6.77083,7.39583 -0.69662,0.83334 -1.8099,1.875 -3.33334,3.125 -1.52995,1.25 -3.125,2.4349 -4.79166,3.54167 -1.66667,1.11328 -3.26824,1.91407 -4.79167,2.39583 -1.52995,0.48829 -2.64323,0.3125 -3.33333,-0.52083 -5,-4.02343 -9.9349,-8.125 -14.79167,-12.29167 -4.86328,-4.16666 -10.20833,-8.05338 -16.04167,-11.66666 -0.97656,-0.6901 -1.42578,-1.35417 -1.35416,-1.97917 0.0652,-0.625 0.44921,-1.5625 1.14583,-2.8125 l 33.33333,-50.83333 c 0.97005,-1.38672 1.9401,-2.04427 2.91667,-1.97917 0.97005,0.0717 2.01172,0.45574 3.125,1.14584 2.91667,1.66666 5.83333,3.54166 8.75,5.625 2.91667,2.08333 5.625,4.34245 8.125,6.77083 2.5,2.4349 4.6875,5.07162 6.5625,7.91667 1.875,2.85156 3.22916,6.00911 4.0625,9.47916 z" + style="fill:#000000;fill-opacity:1;stroke:none;stroke-width:1.66666663" /> + <path + inkscape:connector-curvature="0" + id="path883" + d="M 305.71333,214.15892" + style="fill:#000000;fill-opacity:1;stroke:none;stroke-width:1.66666663" /> + <path + id="path887" + d="m 599.12998,319.78391 c -3.0599,5.41667 -6.25,10.8724 -9.58333,16.35417 -3.33334,5.48828 -7.05079,10.66406 -11.14584,15.52083 -4.10156,4.86328 -8.61328,9.27084 -13.54166,13.22917 -4.9349,3.95833 -10.52084,7.12239 -16.77084,9.47916 -5.14323,2.08334 -9.51823,4.41407 -13.125,6.97917 -3.61328,2.57162 -6.60156,5.3125 -8.95833,8.22917 -3.61328,3.89323 -6.73828,9.27083 -9.375,16.14583 -2.64323,6.875 -5.38411,14.13411 -8.22916,21.77083 -2.85157,7.64323 -5.97657,15.10417 -9.375,22.39583 -3.40495,7.29167 -7.67579,13.30079 -12.8125,18.02084 -7.08334,7.5 -17.57162,12.57161 -31.45834,15.20833 l -38.12499,6.45833 c -1.11329,0.14323 -2.46745,0.2474 -4.0625,0.3125 -1.60157,0.0716 -2.7474,0.0391 -3.4375,-0.10416 -3.19011,-0.97005 -4.16667,-3.08594 -2.91667,-6.35417 1.25,-3.26172 4.51172,-6.5625 9.79167,-9.89583 10.6901,-7.08334 19.23177,-12.8125 25.625,-17.1875 6.38671,-4.375 11.59505,-7.94922 15.62499,-10.72917 4.02344,-2.77343 7.25261,-5.0651 9.6875,-6.875 2.42839,-1.80338 5.03256,-3.8151 7.8125,-6.04166 11.25,-8.47006 19.02344,-17.35677 23.33334,-26.66667 2.5,-4.85677 4.79166,-9.58333 6.875,-14.16667 2.08333,-4.58333 4.27083,-9.09505 6.5625,-13.54166 2.29166,-4.44011 4.7526,-8.85417 7.39583,-13.22917 2.63672,-4.375 5.6901,-8.78255 9.16667,-13.22916 3.60677,-4.44011 8.47005,-8.78256 14.58333,-13.02084 6.10677,-4.23177 13.47005,-8.4375 22.08333,-12.60416 0.97005,-0.41667 2.5651,-1.35417 4.79167,-2.8125 2.22005,-1.45834 4.92838,-3.78255 8.125,-6.97917 3.1901,-3.1901 6.83593,-7.53255 10.9375,-13.02083 4.09505,-5.48177 8.4375,-12.46094 13.02083,-20.9375 -1.66667,-1.66667 -6.45833,-3.95833 -14.375,-6.875 -7.91667,-3.05338 -15.41667,-4.79167 -22.5,-5.20833 -6.52995,-0.41667 -11.91406,0.76823 -16.14583,3.54166 -4.23828,2.77995 -8.09245,6.73829 -11.5625,11.875 -3.47657,5.14323 -6.45833,7.5 -8.95833,7.08333 -0.83334,-0.41666 -0.97657,-2.14843 -0.41667,-5.20833 0.6901,-3.05338 1.66667,-6.04166 2.91667,-8.95833 5.27343,-12.08333 11.24999,-21.04167 17.91666,-26.875 6.80339,-5.97005 14.92839,-8.95833 24.375,-8.95833 6.80338,0 15.34505,1.66666 25.625,5 6.38672,2.22656 11.875,3.33333 16.45833,3.33333 9.58333,0 19.09505,-3.39843 28.54167,-10.20833 2.08333,0 2.8125,1.35416 2.1875,4.0625 -0.625,2.70833 -1.5625,5.8724 -2.8125,9.47916 -1.11329,3.61329 -1.875,6.04167 -2.29167,7.29167 -2.08333,6.52995 -3.75,10.35157 -5,11.45833 -1.25,0.97657 -4.86328,3.61329 -10.83333,7.91667 -3.33334,2.5 -6.21745,5.38411 -8.64584,8.64583 -2.43489,3.26823 -4.89583,7.1224 -7.39583,11.5625 -2.5,4.44662 -5.69661,10.5599 -9.58333,18.33333 z m 0,0" + style="fill:#000000;fill-opacity:1;stroke:none;stroke-width:1.66666663" + inkscape:connector-curvature="0" /> + <use + style="fill:#000000;fill-opacity:1" + id="use62" + y="291" + x="119.25" + xlink:href="#glyph0-4" + width="100%" + height="100%" + transform="matrix(1.3333333,0,0,1.3333333,72.589732,-189.32751)" /> + <use + style="fill:#000000;fill-opacity:1" + id="use196" + y="391" + x="168.375" + xlink:href="#glyph0-4-3" + width="100%" + height="100%" + transform="matrix(1.3333333,0,0,1.3333333,-861.41828,-631.73483)" /> +</svg> diff --git a/chromium/third_party/harfbuzz-ng/src/docs/Makefile.am b/chromium/third_party/harfbuzz-ng/src/docs/Makefile.am new file mode 100644 index 00000000000..a9935385b9a --- /dev/null +++ b/chromium/third_party/harfbuzz-ng/src/docs/Makefile.am @@ -0,0 +1,123 @@ +# Process this file with automake to produce Makefile.in + +# We require automake 1.6 at least. +AUTOMAKE_OPTIONS = 1.6 + +# This is a blank Makefile.am for using gtk-doc. +# Copy this to your project's API docs directory and modify the variables to +# suit your project. See the GTK+ Makefiles in gtk+/docs/reference for examples +# of using the various options. + +# The name of the module, e.g. 'glib'. +DOC_MODULE=harfbuzz + +# Uncomment for versioned docs and specify the version of the module, e.g. '2'. +#DOC_MODULE_VERSION=$(HB_VERSION_MAJOR) + +# The top-level SGML file. You can change this if you want to. +DOC_MAIN_SGML_FILE=$(DOC_MODULE)-docs.xml + +# Directories containing the source code. +# gtk-doc will search all .c and .h files beneath these paths +# for inline comments documenting functions and macros. +# e.g. DOC_SOURCE_DIR=$(top_srcdir)/gtk $(top_srcdir)/gdk +DOC_SOURCE_DIR=$(top_srcdir)/src $(top_builddir)/src + +# Extra options to pass to gtkdoc-scangobj. Not normally needed. +SCANGOBJ_OPTIONS= + +# Extra options to supply to gtkdoc-scan. +# e.g. SCAN_OPTIONS=--deprecated-guards="GTK_DISABLE_DEPRECATED" +SCAN_OPTIONS=--rebuild-types --deprecated-guards="HB_DISABLE_DEPRECATED" \ + --ignore-decorators="HB_EXTERN" + +# 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@^.*/@@'` +if HAVE_GOBJECT +else +IGNORE_HFILES+=hb-gobject.h hb-gobject-enums.h hb-gobject-structs.h +endif + +# Extra options to supply to gtkdoc-mkdb. +# e.g. MKDB_OPTIONS=--xml-mode --output-format=xml +MKDB_OPTIONS=--source-suffixes=h,cc --xml-mode --output-format=xml --ignore-files="$(IGNORE_HFILES)" + +# Extra options to supply to gtkdoc-mktmpl +# e.g. MKTMPL_OPTIONS=--only-section-tmpl +MKTMPL_OPTIONS= + +# Extra options to supply to gtkdoc-mkhtml +MKHTML_OPTIONS= + +# Extra options to supply to gtkdoc-fixref. Not normally needed. +# e.g. FIXXREF_OPTIONS=--extra-dir=../gdk-pixbuf/html --extra-dir=../gdk/html +FIXXREF_OPTIONS= + +# Used for dependencies. The docs will be rebuilt if any of these change. +# e.g. HFILE_GLOB=$(top_srcdir)/gtk/*.h +# e.g. CFILE_GLOB=$(top_srcdir)/gtk/*.c +HFILE_GLOB=$(top_srcdir)/src/hb.h $(top_srcdir)/src/hb-*.h +CFILE_GLOB=$(top_srcdir)/src/hb-*.cc + +# Extra header to include when scanning, which are not under DOC_SOURCE_DIR +# e.g. EXTRA_HFILES=$(top_srcdir}/contrib/extra.h +EXTRA_HFILES=$(top_builddir)/src/hb-version.h + +# Images to copy into HTML directory. +# e.g. HTML_IMAGES=$(top_srcdir)/gtk/stock-icons/stock_about_24.png +HTML_IMAGES= \ + HarfBuzz.png \ + HarfBuzz.svg + +# Extra SGML files that are included by $(DOC_MAIN_SGML_FILE). +# e.g. content_files=running.sgml building.sgml changes-2.0.sgml +content_files= \ + usermanual-buffers-language-script-and-direction.xml \ + usermanual-clusters.xml \ + usermanual-fonts-and-faces.xml \ + usermanual-glyph-information.xml \ + usermanual-hello-harfbuzz.xml \ + usermanual-install-harfbuzz.xml \ + usermanual-opentype-features.xml \ + usermanual-what-is-harfbuzz.xml \ + version.xml + +# SGML files where gtk-doc abbrevations (#GtkWidget) are expanded +# These files must be listed here *and* in content_files +# e.g. expand_content_files=running.sgml +expand_content_files= + +# CFLAGS and LDFLAGS for compiling gtkdoc-scangobj with your library. +# Only needed if you are using gtkdoc-scangobj to dynamically query widget +# signals and properties. +# e.g. GTKDOC_CFLAGS=-I$(top_srcdir) -I$(top_builddir) $(GTK_DEBUG_FLAGS) +# e.g. GTKDOC_LIBS=$(top_builddir)/gtk/$(gtktargetlib) +GTKDOC_CFLAGS= +GTKDOC_LIBS=$(top_builddir)/src/libharfbuzz.la +if HAVE_GOBJECT +GTKDOC_LIBS+=$(top_builddir)/src/libharfbuzz-gobject.la +endif + +# This includes the standard gtk-doc make rules, copied by gtkdocize. +include $(top_srcdir)/gtk-doc.make + +# Other files to distribute +# e.g. EXTRA_DIST += version.xml.in +EXTRA_DIST += version.xml.in + +# Files not to distribute +# for --rebuild-types in $(SCAN_OPTIONS), e.g. $(DOC_MODULE).types +# for --rebuild-sections in $(SCAN_OPTIONS) e.g. $(DOC_MODULE)-sections.txt +#DISTCLEANFILES += + +# Comment this out if you don't want 'make check' to test you doc status +# and run some sanity checks +if ENABLE_GTK_DOC +TESTS_ENVIRONMENT = cd $(srcdir) && \ + DOC_MODULE=$(DOC_MODULE) DOC_MAIN_SGML_FILE=$(DOC_MAIN_SGML_FILE) \ + SRCDIR=$(abs_srcdir) BUILDDIR=$(abs_builddir) +#TESTS = $(GTKDOC_CHECK) +endif + +-include $(top_srcdir)/git.mk diff --git a/chromium/third_party/harfbuzz-ng/src/docs/harfbuzz-docs.xml b/chromium/third_party/harfbuzz-ng/src/docs/harfbuzz-docs.xml new file mode 100644 index 00000000000..9452a92af58 --- /dev/null +++ b/chromium/third_party/harfbuzz-ng/src/docs/harfbuzz-docs.xml @@ -0,0 +1,210 @@ +<?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"> +]> +<book id="index"> + <bookinfo> + <title>HarfBuzz Manual</title> + <abstract> + <title>HarfBuzz</title> + <graphic fileref="HarfBuzz.png" format="PNG" align="center"/> + <para> + HarfBuzz is an <ulink url="http://www.microsoft.com/typography/otspec/">OpenType</ulink> + text shaping engine. + </para> + <para> + The current HarfBuzz codebase, formerly known as harfbuzz-ng, is + versioned 1.x.x and is stable and under active maintenance. This is + what is used in latest versions of Firefox, GNOME, ChromeOS, Chrome, + LibreOffice, XeTeX, Android, and KDE, among other places. The canonical + source tree is available + <ulink url="http://cgit.freedesktop.org/harfbuzz/">here</ulink>. + Also available on + <ulink url="https://github.com/harfbuzz/harfbuzz">github</ulink>. + See <xref linkend="download" endterm="download.title"/> for release tarballs. + </para> + <para> + The old HarfBuzz codebase, these days known as harfbuzz-old, was + derived from <ulink url="http://freetype.org/">FreeType</ulink>, + <ulink url="http://pango.org/">Pango</ulink>, and + <ulink url="http://qt-project.org/">Qt</ulink> and is available + <ulink url="http://cgit.freedesktop.org/harfbuzz.old/">here</ulink>. + It is not actively developed or maintained, and is extremely buggy. All + users are encouraged to switch over to the new HarfBuzz as soon as + possible. There are no release tarballs of old HarfBuzz whatsoever. + </para> + </abstract> + </bookinfo> + + <part> + <title>User's manual</title> + <xi:include href="usermanual-what-is-harfbuzz.xml"/> + <xi:include href="usermanual-install-harfbuzz.xml"/> + <xi:include href="usermanual-hello-harfbuzz.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"/> + </part> + + <part> + <partinfo> + <releaseinfo> + This document is for HarfBuzz &version;. + <!--The latest version of this documentation can be found on-line at + <ulink role="online-location" url="http://[SERVER]/libharfbuzz/index.html">http://[SERVER]/libharfbuzz/</ulink>.--> + </releaseinfo> + </partinfo> + <title>Reference manual</title> + <chapter> + <title>HarfBuzz API</title> + <xi:include href="xml/hb.xml"/> + <xi:include href="xml/hb-common.xml"/> + <xi:include href="xml/hb-unicode.xml"/> + <xi:include href="xml/hb-buffer.xml"/> + <xi:include href="xml/hb-blob.xml"/> + <xi:include href="xml/hb-face.xml"/> + <xi:include href="xml/hb-font.xml"/> + <xi:include href="xml/hb-shape.xml"/> + + <xi:include href="xml/hb-version.xml"/> + <xi:include href="xml/hb-deprecated.xml"/> + + <xi:include href="xml/hb-set.xml"/> + + <xi:include href="xml/hb-ot.xml"/> + <xi:include href="xml/hb-ot-layout.xml"/> + <xi:include href="xml/hb-ot-tag.xml"/> + <xi:include href="xml/hb-ot-font.xml"/> + <xi:include href="xml/hb-ot-shape.xml"/> + <xi:include href="xml/hb-ot-math.xml"/> + + <xi:include href="xml/hb-shape-plan.xml"/> + + <xi:include href="xml/hb-glib.xml"/> + <xi:include href="xml/hb-icu.xml"/> + + <xi:include href="xml/hb-ft.xml"/> + + <xi:include href="xml/hb-graphite2.xml"/> + <xi:include href="xml/hb-uniscribe.xml"/> + <xi:include href="xml/hb-coretext.xml"/> + + <xi:include href="xml/hb-gobject.xml"/> + + </chapter> + <chapter id="object-tree"> + <title>Object Hierarchy</title> + <xi:include href="xml/tree_index.sgml"/> + </chapter> + <index id="api-index-full"> + <title>API Index</title> + <xi:include href="xml/api-index-full.xml"><xi:fallback /></xi:include> + </index> + <index id="api-index-0-9-2" role="0.9.2"> + <title>Index of new symbols in 0.9.2</title> + <xi:include href="xml/api-index-0.9.2.xml"><xi:fallback /></xi:include> + </index> + <index id="api-index-0-9-5" role="0.9.5"> + <title>Index of new symbols in 0.9.5</title> + <xi:include href="xml/api-index-0.9.5.xml"><xi:fallback /></xi:include> + </index> + <index id="api-index-0-9-7" role="0.9.7"> + <title>Index of new symbols in 0.9.7</title> + <xi:include href="xml/api-index-0.9.7.xml"><xi:fallback /></xi:include> + </index> + <index id="api-index-0-9-8" role="0.9.8"> + <title>Index of new symbols in 0.9.8</title> + <xi:include href="xml/api-index-0.9.8.xml"><xi:fallback /></xi:include> + </index> + <index id="api-index-0-9-10" role="0.9.10"> + <title>Index of new symbols in 0.9.10</title> + <xi:include href="xml/api-index-0.9.10.xml"><xi:fallback /></xi:include> + </index> + <index id="api-index-0-9-11" role="0.9.11"> + <title>Index of new symbols in 0.9.11</title> + <xi:include href="xml/api-index-0.9.11.xml"><xi:fallback /></xi:include> + </index> + <index id="api-index-0-9-20" role="0.9.20"> + <title>Index of new symbols in 0.9.20</title> + <xi:include href="xml/api-index-0.9.20.xml"><xi:fallback /></xi:include> + </index> + <index id="api-index-0-9-22" role="0.9.22"> + <title>Index of new symbols in 0.9.22</title> + <xi:include href="xml/api-index-0.9.22.xml"><xi:fallback /></xi:include> + </index> + <index id="api-index-0-9-28" role="0.9.28"> + <title>Index of new symbols in 0.9.28</title> + <xi:include href="xml/api-index-0.9.28.xml"><xi:fallback /></xi:include> + </index> + <index id="api-index-0-9-30" role="0.9.30"> + <title>Index of new symbols in 0.9.30</title> + <xi:include href="xml/api-index-0.9.30.xml"><xi:fallback /></xi:include> + </index> + <index id="api-index-0-9-31" role="0.9.31"> + <title>Index of new symbols in 0.9.31</title> + <xi:include href="xml/api-index-0.9.31.xml"><xi:fallback /></xi:include> + </index> + <index id="api-index-0-9-38" role="0.9.38"> + <title>Index of new symbols in 0.9.38</title> + <xi:include href="xml/api-index-0.9.38.xml"><xi:fallback /></xi:include> + </index> + <index id="api-index-0-9-39" role="0.9.39"> + <title>Index of new symbols in 0.9.39</title> + <xi:include href="xml/api-index-0.9.39.xml"><xi:fallback /></xi:include> + </index> + <index id="api-index-0-9-41" role="0.9.41"> + <title>Index of new symbols in 0.9.41</title> + <xi:include href="xml/api-index-0.9.41.xml"><xi:fallback /></xi:include> + </index> + <index id="api-index-0-9-42" role="0.9.42"> + <title>Index of new symbols in 0.9.42</title> + <xi:include href="xml/api-index-0.9.42.xml"><xi:fallback /></xi:include> + </index> + <index id="api-index-1-0-5" role="1.0.5"> + <title>Index of new symbols in 1.0.5</title> + <xi:include href="xml/api-index-1.0.5.xml"><xi:fallback /></xi:include> + </index> + <index id="api-index-1-1-2" role="1.1.2"> + <title>Index of new symbols in 1.1.2</title> + <xi:include href="xml/api-index-1.1.2.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 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-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-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-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-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-6-0" role="1.6.0"> + <title>Index of new symbols in 1.6.0</title> + <xi:include href="xml/api-index-1.6.0.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> + + <xi:include href="xml/annotation-glossary.xml"><xi:fallback /></xi:include> + </part> +</book> diff --git a/chromium/third_party/harfbuzz-ng/src/docs/harfbuzz-overrides.txt b/chromium/third_party/harfbuzz-ng/src/docs/harfbuzz-overrides.txt new file mode 100644 index 00000000000..e69de29bb2d --- /dev/null +++ b/chromium/third_party/harfbuzz-ng/src/docs/harfbuzz-overrides.txt diff --git a/chromium/third_party/harfbuzz-ng/src/docs/harfbuzz-sections.txt b/chromium/third_party/harfbuzz-ng/src/docs/harfbuzz-sections.txt new file mode 100644 index 00000000000..91faa0b7590 --- /dev/null +++ b/chromium/third_party/harfbuzz-ng/src/docs/harfbuzz-sections.txt @@ -0,0 +1,627 @@ +<SECTION> +<FILE>hb</FILE> +<SUBSECTION Private> +HB_H_IN +HB_EXTERN +</SECTION> + +<SECTION> +<FILE>hb-blob</FILE> +hb_blob_create +hb_blob_create_sub_blob +hb_blob_copy_writable_or_fail +hb_blob_destroy +hb_blob_get_data +hb_blob_get_data_writable +hb_blob_get_empty +hb_blob_get_length +hb_blob_get_user_data +hb_blob_is_immutable +hb_blob_make_immutable +hb_blob_reference +hb_blob_set_user_data +hb_blob_t +hb_memory_mode_t +</SECTION> + +<SECTION> +<FILE>hb-buffer</FILE> +HB_SEGMENT_PROPERTIES_DEFAULT +HB_BUFFER_REPLACEMENT_CODEPOINT_DEFAULT +hb_buffer_create +hb_buffer_reference +hb_buffer_get_empty +hb_buffer_destroy +hb_buffer_reset +hb_buffer_clear_contents +hb_buffer_pre_allocate +hb_buffer_allocation_successful +hb_buffer_add +hb_buffer_add_codepoints +hb_buffer_add_utf32 +hb_buffer_add_utf16 +hb_buffer_add_utf8 +hb_buffer_add_latin1 +hb_buffer_append +hb_buffer_set_content_type +hb_buffer_get_content_type +hb_buffer_set_direction +hb_buffer_get_direction +hb_buffer_set_script +hb_buffer_get_script +hb_buffer_set_language +hb_buffer_get_language +hb_buffer_set_flags +hb_buffer_get_flags +hb_buffer_set_cluster_level +hb_buffer_get_cluster_level +hb_buffer_set_length +hb_buffer_get_length +hb_buffer_set_segment_properties +hb_buffer_get_segment_properties +hb_buffer_guess_segment_properties +hb_buffer_set_unicode_funcs +hb_buffer_get_unicode_funcs +hb_buffer_set_user_data +hb_buffer_get_user_data +hb_buffer_get_glyph_infos +hb_buffer_get_glyph_positions +hb_buffer_set_replacement_codepoint +hb_buffer_get_replacement_codepoint +hb_buffer_normalize_glyphs +hb_buffer_reverse +hb_buffer_reverse_range +hb_buffer_reverse_clusters +hb_buffer_serialize_glyphs +hb_buffer_deserialize_glyphs +hb_buffer_serialize_format_from_string +hb_buffer_serialize_format_to_string +hb_buffer_serialize_list_formats +hb_segment_properties_equal +hb_segment_properties_hash +hb_buffer_diff +hb_buffer_set_message_func +hb_buffer_t +hb_glyph_info_get_glyph_flags +hb_glyph_info_t +hb_glyph_flags_t +hb_glyph_position_t +hb_buffer_content_type_t +hb_buffer_flags_t +hb_buffer_cluster_level_t +hb_segment_properties_t +hb_buffer_serialize_format_t +hb_buffer_serialize_flags_t +hb_buffer_diff_flags_t +hb_buffer_message_func_t +</SECTION> + +<SECTION> +<FILE>hb-common</FILE> +hb_tag_from_string +hb_tag_to_string +hb_direction_from_string +hb_direction_to_string +hb_script_from_iso15924_tag +hb_script_from_string +hb_script_to_iso15924_tag +hb_script_get_horizontal_direction +hb_language_from_string +hb_language_to_string +hb_language_get_default +hb_bool_t +hb_codepoint_t +hb_destroy_func_t +hb_direction_t +hb_language_t +hb_mask_t +hb_position_t +hb_tag_t +hb_script_t +hb_user_data_key_t +hb_var_int_t +HB_TAG +HB_TAG_NONE +HB_TAG_MAX +HB_TAG_MAX_SIGNED +HB_UNTAG +HB_DIRECTION_REVERSE +HB_DIRECTION_IS_BACKWARD +HB_DIRECTION_IS_FORWARD +HB_DIRECTION_IS_HORIZONTAL +HB_DIRECTION_IS_VALID +HB_DIRECTION_IS_VERTICAL +HB_LANGUAGE_INVALID +<SUBSECTION Private> +HB_BEGIN_DECLS +HB_END_DECLS +int16_t +int32_t +int64_t +int8_t +uint16_t +uint32_t +uint64_t +uint8_t +</SECTION> + +<SECTION> +<FILE>hb-deprecated</FILE> +HB_BUFFER_FLAGS_DEFAULT +HB_BUFFER_SERIALIZE_FLAGS_DEFAULT +HB_SCRIPT_CANADIAN_ABORIGINAL +hb_font_funcs_set_glyph_func +hb_font_get_glyph_func_t +hb_set_invert +</SECTION> + +<SECTION> +<FILE>hb-coretext</FILE> +HB_CORETEXT_TAG_KERX +HB_CORETEXT_TAG_MORT +HB_CORETEXT_TAG_MORX +hb_coretext_face_create +hb_coretext_font_create +hb_coretext_face_get_cg_font +hb_coretext_font_get_ct_font +</SECTION> + +<SECTION> +<FILE>hb-face</FILE> +hb_face_create +hb_face_create_for_tables +hb_face_destroy +hb_face_get_empty +hb_face_get_table_tags +hb_face_get_glyph_count +hb_face_get_index +hb_face_get_upem +hb_face_get_user_data +hb_face_is_immutable +hb_face_make_immutable +hb_face_reference +hb_face_reference_blob +hb_face_reference_table +hb_face_set_glyph_count +hb_face_set_index +hb_face_set_upem +hb_face_set_user_data +hb_face_t +</SECTION> + +<SECTION> +<FILE>hb-font</FILE> +hb_font_add_glyph_origin_for_direction +hb_font_create +hb_font_create_sub_font +hb_font_destroy +hb_font_funcs_create +hb_font_funcs_destroy +hb_font_funcs_get_empty +hb_font_funcs_get_user_data +hb_font_funcs_is_immutable +hb_font_funcs_make_immutable +hb_font_funcs_reference +hb_font_funcs_set_glyph_contour_point_func +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_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 +hb_font_funcs_set_glyph_v_kerning_func +hb_font_funcs_set_glyph_v_origin_func +hb_font_funcs_set_nominal_glyph_func +hb_font_funcs_set_user_data +hb_font_funcs_set_variation_glyph_func +hb_font_funcs_t +hb_font_get_empty +hb_font_get_face +hb_font_get_glyph +hb_font_get_glyph_advance_for_direction +hb_font_get_glyph_advance_func_t +hb_font_get_glyph_contour_point +hb_font_get_glyph_contour_point_for_origin +hb_font_get_glyph_contour_point_func_t +hb_font_get_glyph_extents +hb_font_get_glyph_extents_for_origin +hb_font_get_glyph_extents_func_t +hb_font_get_glyph_from_name +hb_font_get_glyph_from_name_func_t +hb_font_get_glyph_h_advance +hb_font_get_glyph_h_advance_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 +hb_font_get_glyph_origin_func_t +hb_font_get_glyph_v_advance +hb_font_get_glyph_v_advance_func_t +hb_font_get_glyph_v_kerning +hb_font_get_glyph_v_kerning_func_t +hb_font_get_glyph_v_origin +hb_font_get_glyph_v_origin_func_t +hb_font_get_nominal_glyph +hb_font_get_nominal_glyph_func_t +hb_font_get_parent +hb_font_get_ppem +hb_font_get_ptem +hb_font_get_scale +hb_font_get_user_data +hb_font_get_variation_glyph +hb_font_get_variation_glyph_func_t +hb_font_get_var_coords_normalized +hb_font_glyph_from_string +hb_font_glyph_to_string +hb_font_is_immutable +hb_font_make_immutable +hb_font_reference +hb_font_set_face +hb_font_set_funcs +hb_font_set_funcs_data +hb_font_set_parent +hb_font_set_ppem +hb_font_set_ptem +hb_font_set_scale +hb_font_set_user_data +hb_variation_t +hb_variation_from_string +hb_variation_to_string +hb_font_set_variations +hb_font_set_var_coords_design +hb_font_set_var_coords_normalized +hb_font_subtract_glyph_origin_for_direction +hb_font_t +hb_reference_table_func_t +hb_font_funcs_set_font_h_extents_func +hb_font_funcs_set_font_v_extents_func +hb_font_get_extents_for_direction +hb_font_get_font_extents_func_t +hb_font_get_font_h_extents_func_t +hb_font_get_font_v_extents_func_t +hb_font_get_h_extents +hb_font_get_v_extents +</SECTION> + +<SECTION> +<FILE>hb-ft</FILE> +hb_ft_face_create +hb_ft_face_create_cached +hb_ft_face_create_referenced +hb_ft_font_create +hb_ft_font_create_referenced +hb_ft_font_changed +hb_ft_font_get_face +hb_ft_font_set_load_flags +hb_ft_font_get_load_flags +hb_ft_font_set_funcs +</SECTION> + +<SECTION> +<FILE>hb-glib</FILE> +hb_glib_get_unicode_funcs +hb_glib_script_from_script +hb_glib_script_to_script +hb_glib_blob_create +</SECTION> + +<SECTION> +<FILE>hb-gobject</FILE> +HB_GOBJECT_TYPE_BLOB +HB_GOBJECT_TYPE_BUFFER +HB_GOBJECT_TYPE_BUFFER_CONTENT_TYPE +HB_GOBJECT_TYPE_BUFFER_DIFF_FLAGS +HB_GOBJECT_TYPE_BUFFER_FLAGS +HB_GOBJECT_TYPE_BUFFER_SERIALIZE_FLAGS +HB_GOBJECT_TYPE_BUFFER_SERIALIZE_FORMAT +HB_GOBJECT_TYPE_DIRECTION +HB_GOBJECT_TYPE_FACE +HB_GOBJECT_TYPE_FONT +HB_GOBJECT_TYPE_FONT_FUNCS +HB_GOBJECT_TYPE_GLYPH_FLAGS +HB_GOBJECT_TYPE_MEMORY_MODE +HB_GOBJECT_TYPE_OT_LAYOUT_GLYPH_CLASS +HB_GOBJECT_TYPE_OT_MATH_CONSTANT +HB_GOBJECT_TYPE_OT_MATH_GLYPH_PART +HB_GOBJECT_TYPE_OT_MATH_GLYPH_PART_FLAGS +HB_GOBJECT_TYPE_OT_MATH_GLYPH_VARIANT +HB_GOBJECT_TYPE_OT_MATH_KERN +HB_GOBJECT_TYPE_SCRIPT +HB_GOBJECT_TYPE_SHAPE_PLAN +HB_GOBJECT_TYPE_UNICODE_COMBINING_CLASS +HB_GOBJECT_TYPE_UNICODE_FUNCS +HB_GOBJECT_TYPE_UNICODE_GENERAL_CATEGORY +HB_GOBJECT_TYPE_BUFFER_CLUSTER_LEVEL +HB_GOBJECT_TYPE_FEATURE +HB_GOBJECT_TYPE_GLYPH_INFO +HB_GOBJECT_TYPE_GLYPH_POSITION +HB_GOBJECT_TYPE_SEGMENT_PROPERTIES +HB_GOBJECT_TYPE_SET +HB_GOBJECT_TYPE_USER_DATA_KEY +hb_gobject_blob_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_font_funcs_get_type +hb_gobject_font_get_type +hb_gobject_glyph_flags_get_type +hb_gobject_memory_mode_get_type +hb_gobject_ot_layout_glyph_class_get_type +hb_gobject_ot_math_constant_get_type +hb_gobject_ot_math_glyph_part_get_type +hb_gobject_ot_math_glyph_part_flags_get_type +hb_gobject_ot_math_glyph_variant_get_type +hb_gobject_ot_math_kern_get_type +hb_gobject_script_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_buffer_cluster_level_get_type +hb_gobject_feature_get_type +hb_gobject_glyph_info_get_type +hb_gobject_glyph_position_get_type +hb_gobject_segment_properties_get_type +hb_gobject_set_get_type +hb_gobject_user_data_key_get_type +<SUBSECTION Private> +HB_GOBJECT_H_IN +</SECTION> + +<SECTION> +<FILE>hb-gobject</FILE> + +</SECTION> + +<SECTION> +<FILE>hb-graphite2</FILE> +HB_GRAPHITE2_TAG_SILF +hb_graphite2_face_get_gr_face +hb_graphite2_font_get_gr_font +</SECTION> + +<SECTION> +<FILE>hb-icu</FILE> +hb_icu_get_unicode_funcs +hb_icu_script_from_script +hb_icu_script_to_script +</SECTION> + +<SECTION> +<FILE>hb-ot</FILE> +<SUBSECTION Private> +HB_OT_H_IN +</SECTION> + +<SECTION> +<FILE>hb-ot-font</FILE> +hb_ot_font_set_funcs +</SECTION> + +<SECTION> +<FILE>hb-ot-shape</FILE> +hb_ot_shape_glyphs_closure +</SECTION> + +<SECTION> +<FILE>hb-ot-layout</FILE> +HB_OT_LAYOUT_DEFAULT_LANGUAGE_INDEX +HB_OT_LAYOUT_NO_FEATURE_INDEX +HB_OT_LAYOUT_NO_SCRIPT_INDEX +HB_OT_LAYOUT_NO_VARIATIONS_INDEX +HB_OT_TAG_GDEF +HB_OT_TAG_GPOS +HB_OT_TAG_GSUB +HB_OT_TAG_JSTF +hb_ot_layout_collect_lookups +hb_ot_layout_feature_get_lookups +hb_ot_layout_feature_with_variations_get_lookups +hb_ot_layout_get_attach_points +hb_ot_layout_get_glyph_class +hb_ot_layout_get_glyphs_in_class +hb_ot_layout_get_ligature_carets +hb_ot_layout_get_size_params +hb_ot_layout_glyph_class_t +hb_ot_layout_glyph_sequence_func_t +hb_ot_layout_has_glyph_classes +hb_ot_layout_has_positioning +hb_ot_layout_has_substitution +hb_ot_layout_language_find_feature +hb_ot_layout_language_get_feature_indexes +hb_ot_layout_language_get_feature_tags +hb_ot_layout_language_get_required_feature +hb_ot_layout_lookup_collect_glyphs +hb_ot_layout_lookup_substitute_closure +hb_ot_layout_lookup_would_substitute +hb_ot_layout_script_find_language +hb_ot_layout_script_get_language_tags +hb_ot_layout_table_choose_script +hb_ot_layout_table_find_feature_variations +hb_ot_layout_table_find_script +hb_ot_layout_table_get_feature_tags +hb_ot_layout_table_get_script_tags +hb_ot_layout_table_get_lookup_count +hb_ot_shape_plan_collect_lookups +hb_ot_layout_language_get_required_feature_index +<SUBSECTION Private> +Xhb_ot_layout_lookup_enumerate_sequences +Xhb_ot_layout_lookup_position +Xhb_ot_layout_lookup_substitute +</SECTION> + +<SECTION> +<FILE>hb-ot-var</FILE> +HB_OT_TAG_VAR_AXIS_ITALIC +HB_OT_TAG_VAR_AXIS_OPTICAL_SIZE +HB_OT_TAG_VAR_AXIS_SLANT +HB_OT_TAG_VAR_AXIS_WEIGHT +HB_OT_TAG_VAR_AXIS_WIDTH +HB_OT_VAR_NO_AXIS_INDEX +hb_ot_var_axis_t +hb_ot_var_has_data +hb_ot_var_find_axis +hb_ot_var_get_axis_count +hb_ot_var_get_axes +hb_ot_var_normalize_variations +hb_ot_var_normalize_coords +</SECTION> + +<SECTION> +<FILE>hb-ot-math</FILE> +HB_OT_TAG_MATH +HB_OT_MATH_SCRIPT +hb_ot_math_constant_t +hb_ot_math_kern_t +hb_ot_math_glyph_variant_t +hb_ot_math_glyph_part_flags_t +hb_ot_math_glyph_part_t +hb_ot_math_has_data +hb_ot_math_get_constant +hb_ot_math_get_glyph_italics_correction +hb_ot_math_get_glyph_top_accent_attachment +hb_ot_math_get_glyph_kerning +hb_ot_math_is_glyph_extended_shape +hb_ot_math_get_glyph_variants +hb_ot_math_get_min_connector_overlap +hb_ot_math_get_glyph_assembly +</SECTION> + +<SECTION> +<FILE>hb-ot-tag</FILE> +HB_OT_TAG_DEFAULT_LANGUAGE +HB_OT_TAG_DEFAULT_SCRIPT +hb_ot_tag_from_language +hb_ot_tag_to_language +hb_ot_tag_to_script +hb_ot_tags_from_script +</SECTION> + +<SECTION> +<FILE>hb-set</FILE> +HB_SET_VALUE_INVALID +hb_set_add +hb_set_add_range +hb_set_allocation_successful +hb_set_clear +hb_set_create +hb_set_del +hb_set_del_range +hb_set_destroy +hb_set_get_empty +hb_set_get_max +hb_set_get_min +hb_set_get_population +hb_set_get_user_data +hb_set_has +hb_set_intersect +hb_set_is_empty +hb_set_is_equal +hb_set_next +hb_set_previous +hb_set_next_range +hb_set_previous_range +hb_set_reference +hb_set_set +hb_set_set_user_data +hb_set_subtract +hb_set_symmetric_difference +hb_set_t +hb_set_union +</SECTION> + +<SECTION> +<FILE>hb-shape</FILE> +hb_feature_t +hb_feature_from_string +hb_feature_to_string +hb_shape +hb_shape_full +hb_shape_list_shapers +</SECTION> + +<SECTION> +<FILE>hb-shape-plan</FILE> +hb_shape_plan_create +hb_shape_plan_create_cached +hb_shape_plan_create2 +hb_shape_plan_create_cached2 +hb_shape_plan_destroy +hb_shape_plan_execute +hb_shape_plan_get_empty +hb_shape_plan_get_shaper +hb_shape_plan_get_user_data +hb_shape_plan_reference +hb_shape_plan_set_user_data +hb_shape_plan_t +</SECTION> + +<SECTION> +<FILE>hb-unicode</FILE> +HB_UNICODE_MAX_DECOMPOSITION_LEN +hb_unicode_combining_class +hb_unicode_combining_class_func_t +hb_unicode_combining_class_t +hb_unicode_compose +hb_unicode_compose_func_t +hb_unicode_decompose +hb_unicode_decompose_compatibility +hb_unicode_decompose_func_t +hb_unicode_eastasian_width +hb_unicode_funcs_create +hb_unicode_funcs_destroy +hb_unicode_funcs_get_default +hb_unicode_funcs_get_empty +hb_unicode_funcs_get_parent +hb_unicode_funcs_get_user_data +hb_unicode_funcs_is_immutable +hb_unicode_funcs_make_immutable +hb_unicode_funcs_reference +hb_unicode_funcs_set_combining_class_func +hb_unicode_funcs_set_compose_func +hb_unicode_funcs_set_decompose_compatibility_func +hb_unicode_funcs_set_decompose_func +hb_unicode_funcs_set_eastasian_width_func +hb_unicode_funcs_set_general_category_func +hb_unicode_funcs_set_mirroring_func +hb_unicode_funcs_set_script_func +hb_unicode_funcs_set_user_data +hb_unicode_funcs_t +hb_unicode_general_category +hb_unicode_general_category_func_t +hb_unicode_general_category_t +hb_unicode_mirroring +hb_unicode_mirroring_func_t +hb_unicode_script +hb_unicode_script_func_t +</SECTION> + +<SECTION> +<FILE>hb-uniscribe</FILE> +hb_uniscribe_font_get_hfont +hb_uniscribe_font_get_logfontw +<SUBSECTION Private> +hb_directwrite_shape_experimental_width +</SECTION> + +<SECTION> +<FILE>hb-version</FILE> +HB_VERSION_ATLEAST +HB_VERSION_MAJOR +HB_VERSION_MICRO +HB_VERSION_MINOR +HB_VERSION_STRING +hb_version +hb_version_atleast +hb_version_string +</SECTION> diff --git a/chromium/third_party/harfbuzz-ng/src/docs/usermanual-buffers-language-script-and-direction.xml b/chromium/third_party/harfbuzz-ng/src/docs/usermanual-buffers-language-script-and-direction.xml new file mode 100644 index 00000000000..9eddb71a9cb --- /dev/null +++ b/chromium/third_party/harfbuzz-ng/src/docs/usermanual-buffers-language-script-and-direction.xml @@ -0,0 +1,77 @@ +<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 + 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. + </para> + <section id="creating-and-destroying-buffers"> + <title>Creating and destroying buffers</title> + <para> + As we saw in our initial example, a buffer is created and + initialized with <literal>hb_buffer_create()</literal>. 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 that it creates (such as + buffers), so you don't have to. When you have finished working on + a buffer, you can call <literal>hb_buffer_destroy()</literal>: + </para> + <programlisting language="C"> + hb_buffer_t *buffer = hb_buffer_create(); + ... + hb_buffer_destroy(buffer); +</programlisting> + <para> + This will destroy the object and free its associated memory - + unless some other part of the program holds a reference to this + buffer. If you acquire a HarfBuzz buffer from another subsystem + and want to ensure that it is not garbage collected by someone + 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> + <para> + And then decrease it once you're done with it: + </para> + <programlisting language="C"> + hb_buffer_destroy(buffer); +} +</programlisting> + <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 + throw away the string in the buffer but keep the options, you can + instead call <literal>hb_buffer_clear_contents(buffer)</literal>. + </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) + </para> + </section> + <section id="setting-buffer-properties"> + <title>Setting buffer properties</title> + <para> + </para> + </section> + <section id="what-about-the-other-scripts"> + <title>What about the other scripts?</title> + <para> + </para> + </section> + <section id="customizing-unicode-functions"> + <title>Customizing Unicode functions</title> + <para> + </para> + </section> +</chapter>
\ No newline at end of file diff --git a/chromium/third_party/harfbuzz-ng/src/docs/usermanual-clusters.xml b/chromium/third_party/harfbuzz-ng/src/docs/usermanual-clusters.xml new file mode 100644 index 00000000000..608371b00d7 --- /dev/null +++ b/chromium/third_party/harfbuzz-ng/src/docs/usermanual-clusters.xml @@ -0,0 +1,304 @@ +<chapter id="clusters"> +<sect1 id="clusters"> + <title>Clusters</title> + <para> + In shaping text, a <emphasis>cluster</emphasis> is a sequence of + code points that needs to be treated as a single, indivisible unit. + </para> + <para> + When you add text to a HB buffer, each character is associated with + a <emphasis>cluster value</emphasis>. This is an arbitrary number as + far as HB is concerned. + </para> + <para> + Most clients will use UTF-8, UTF-16, or UTF-32 indices, but the + actual number does not matter. Moreover, it is not required for the + cluster values to be monotonically increasing, but pretty much all + of HB's tests are performed on monotonically increasing cluster + numbers. Nevertheless, there is no such assumption in the code + itself. With that in mind, let's examine what happens with cluster + values during shaping under each cluster-level. + </para> + <para> + HarfBuzz provides three <emphasis>levels</emphasis> of clustering + support. Level 0 is the default behavior and reproduces the behavior + of the old HarfBuzz library. Level 1 tweaks this behavior slightly + to produce better results, so level 1 clustering is recommended for + code that is not required to implement backward compatibility with + the old HarfBuzz. + </para> + <para> + Level 2 differs significantly in how it treats cluster values. + Levels 0 and 1 both process ligatures and glyph decomposition by + merging clusters; level 2 does not. + </para> + <para> + The conceptual model for what the cluster values mean, in levels 0 + and 1, is this: + </para> + <itemizedlist spacing="compact"> + <listitem> + <para> + the sequence of cluster values will always remain monotone + </para> + </listitem> + <listitem> + <para> + each value represents a single cluster + </para> + </listitem> + <listitem> + <para> + each cluster contains one or more glyphs and one or more + characters + </para> + </listitem> + </itemizedlist> + <para> + Assuming that initial cluster numbers were monotonically increasing + and distinct, then all adjacent glyphs having the same cluster + number belong to the same cluster, and all characters belong to the + cluster that has the highest number not larger than their initial + cluster number. This will become clearer with an example. + </para> +</sect1> +<sect1 id="a-clustering-example-for-levels-0-and-1"> + <title>A clustering example for levels 0 and 1</title> + <para> + Let's say we start with the following character sequence and cluster + values: + </para> + <programlisting> + A,B,C,D,E + 0,1,2,3,4 +</programlisting> + <para> + We then map the characters to glyphs. For simplicity, let's assume + that each character maps to the corresponding, identical-looking + glyph: + </para> + <programlisting> + A,B,C,D,E + 0,1,2,3,4 +</programlisting> + <para> + Now if, for example, <literal>B</literal> and <literal>C</literal> + ligate, then the clusters to which they belong "merge". + This merged cluster takes for its cluster number the minimum of all + the cluster numbers of the clusters that went in. In this case, we + get: + </para> + <programlisting> + A,BC,D,E + 0,1 ,3,4 +</programlisting> + <para> + Now let's assume that the <literal>BC</literal> glyph decomposes + into three components, and <literal>D</literal> also decomposes into + two. The components each inherit the cluster value of their parent: + </para> + <programlisting> + A,BC0,BC1,BC2,D0,D1,E + 0,1 ,1 ,1 ,3 ,3 ,4 +</programlisting> + <para> + Now if <literal>BC2</literal> and <literal>D0</literal> ligate, then + their clusters (numbers 1 and 3) merge into + <literal>min(1,3) = 1</literal>: + </para> + <programlisting> + A,BC0,BC1,BC2D0,D1,E + 0,1 ,1 ,1 ,1 ,4 +</programlisting> + <para> + At this point, cluster 1 means: the character sequence + <literal>BCD</literal> is represented by glyphs + <literal>BC0,BC1,BC2D0,D1</literal> and cannot be broken down any + further. + </para> +</sect1> +<sect1 id="reordering-in-levels-0-and-1"> + <title>Reordering in levels 0 and 1</title> + <para> + Another common operation in the more complex shapers is when things + reorder. In those cases, to maintain monotone clusters, HB merges + the clusters of everything in the reordering sequence. For example, + let's again start with the character sequence: + </para> + <programlisting> + A,B,C,D,E + 0,1,2,3,4 +</programlisting> + <para> + If <literal>D</literal> is reordered before <literal>B</literal>, + then the <literal>B</literal>, <literal>C</literal>, and + <literal>D</literal> clusters merge, and we get: + </para> + <programlisting> + A,D,B,C,E + 0,1,1,1,4 +</programlisting> + <para> + This is clearly not ideal, but it is the only sensible way to + maintain monotone indices and retain the true relationship between + glyphs and characters. + </para> +</sect1> +<sect1 id="the-distinction-between-levels-0-and-1"> + <title>The distinction between levels 0 and 1</title> + <para> + So, the above is pretty much what cluster levels 0 and 1 do. The + only difference between the two is this: in level 0, at the very + beginning of the shaping process, we also merge clusters between + base characters and all Unicode marks (combining or not) following + them. E.g.: + </para> + <programlisting> + A,acute,B + 0,1 ,2 +</programlisting> + <para> + will become: + </para> + <programlisting> + A,acute,B + 0,0 ,2 +</programlisting> + <para> + This is the default behavior. We do it because Windows did it and + old HarfBuzz did it, so this remained the default. But this behavior + makes it impossible to color diacritic marks differently from their + base characters. That's why in level 1 we do not perform this + initial merging step. + </para> + <para> + For clients, level 0 is more convenient if they rely on HarfBuzz + clusters for cursor positioning. But that's wrong anyway: cursor + positions should be determined based on Unicode grapheme boundaries, + NOT shaping clusters. As such, level 1 clusters are preferred. + </para> + <para> + One last note about levels 0 and 1. We currently don't allow a + <literal>MultipleSubst</literal> lookup to replace a glyph with zero + glyphs (i.e., to delete a glyph). But in some other situations, + glyphs can be deleted. In those cases, if the glyph being deleted is + the last glyph of its cluster, we make sure to merge the cluster + with a neighboring cluster. + </para> + <para> + This is, primarily, to make sure that the starting cluster of the + text always has the cluster index pointing to the start of the text + for the run; more than one client currently relies on this + guarantee. + </para> + <para> + Incidentally, Apple's CoreText does something else to maintain the + same promise: it inserts a glyph with id 65535 at the beginning of + the glyph string if the glyph corresponding to the first character + in the run was deleted. HarfBuzz might do something similar in the + future. + </para> +</sect1> +<sect1 id="level-2"> + <title>Level 2</title> + <para> + Level 2 is a different beast from levels 0 and 1. It is simple to + describe, but hard to make sense of. It simply doesn't do any + cluster merging whatsoever. When things ligate or otherwise multiple + glyphs turn into one, the cluster value of the first glyph is + retained. + </para> + <para> + Here are a few examples of why processing cluster values produced at + this level might be tricky: + </para> + <sect2 id="ligatures-with-combining-marks"> + <title>Ligatures with combining marks</title> + <para> + Imagine capital letters are bases and lower case letters are + combining marks. With an input sequence like this: + </para> + <programlisting> + A,a,B,b,C,c + 0,1,2,3,4,5 +</programlisting> + <para> + if <literal>A,B,C</literal> ligate, then here are the cluster + values one would get under the various levels: + </para> + <para> + level 0: + </para> + <programlisting> + ABC,a,b,c + 0 ,0,0,0 +</programlisting> + <para> + level 1: + </para> + <programlisting> + ABC,a,b,c + 0 ,0,0,5 +</programlisting> + <para> + level 2: + </para> + <programlisting> + ABC,a,b,c + 0 ,1,3,5 +</programlisting> + <para> + Making sense of the last example is the hardest for a client, + because there is nothing in the cluster values to suggest that + <literal>B</literal> and <literal>C</literal> ligated with + <literal>A</literal>. + </para> + </sect2> + <sect2 id="reordering"> + <title>Reordering</title> + <para> + Another tricky case is when things reorder. Under level 2: + </para> + <programlisting> + A,B,C,D,E + 0,1,2,3,4 +</programlisting> + <para> + Now imagine <literal>D</literal> moves before + <literal>B</literal>: + </para> + <programlisting> + A,D,B,C,E + 0,3,1,2,4 +</programlisting> + <para> + Now, if <literal>D</literal> ligates with <literal>B</literal>, we + get: + </para> + <programlisting> + A,DB,C,E + 0,3 ,2,4 +</programlisting> + <para> + In a different scenario, <literal>A</literal> and + <literal>B</literal> could have ligated + <emphasis>before</emphasis> <literal>D</literal> reordered; that + would have resulted in: + </para> + <programlisting> + AB,D,C,E + 0 ,3,2,4 +</programlisting> + <para> + There's no way to differentiate between these two scenarios based + on the cluster numbers alone. + </para> + <para> + Another problem happens with ligatures under level 2 if the + direction of the text is forced to opposite of its natural + direction (e.g. left-to-right Arabic). But that's too much of a + corner case to worry about. + </para> + </sect2> +</sect1> +</chapter> diff --git a/chromium/third_party/harfbuzz-ng/src/docs/usermanual-fonts-and-faces.xml b/chromium/third_party/harfbuzz-ng/src/docs/usermanual-fonts-and-faces.xml new file mode 100644 index 00000000000..7de0f051a80 --- /dev/null +++ b/chromium/third_party/harfbuzz-ng/src/docs/usermanual-fonts-and-faces.xml @@ -0,0 +1,18 @@ +<chapter id="fonts-and-faces"> + <title>Fonts and faces</title> + <section id="using-freetype"> + <title>Using FreeType</title> + <para> + </para> + </section> + <section id="using-harfbuzzs-native-opentype-implementation"> + <title>Using HarfBuzz's native OpenType implementation</title> + <para> + </para> + </section> + <section id="using-your-own-font-functions"> + <title>Using your own font functions</title> + <para> + </para> + </section> +</chapter>
\ No newline at end of file diff --git a/chromium/third_party/harfbuzz-ng/src/docs/usermanual-glyph-information.xml b/chromium/third_party/harfbuzz-ng/src/docs/usermanual-glyph-information.xml new file mode 100644 index 00000000000..ca674c0c588 --- /dev/null +++ b/chromium/third_party/harfbuzz-ng/src/docs/usermanual-glyph-information.xml @@ -0,0 +1,8 @@ +<sect1 id="glyph-information"> + <title>Glyph information</title> + <sect2 id="names-and-numbers"> + <title>Names and numbers</title> + <para> + </para> + </sect2> +</sect1>
\ No newline at end of file diff --git a/chromium/third_party/harfbuzz-ng/src/docs/usermanual-hello-harfbuzz.xml b/chromium/third_party/harfbuzz-ng/src/docs/usermanual-hello-harfbuzz.xml new file mode 100644 index 00000000000..716b2f2dd94 --- /dev/null +++ b/chromium/third_party/harfbuzz-ng/src/docs/usermanual-hello-harfbuzz.xml @@ -0,0 +1,183 @@ +<chapter id="hello-harfbuzz"> + <title>Hello, HarfBuzz</title> + <para> + Here's the simplest HarfBuzz that can possibly work. We will improve + it later. + </para> + <orderedlist numeration="arabic"> + <listitem> + <para> + Create a buffer and put your text in it. + </para> + </listitem> + </orderedlist> + <programlisting language="C"> + #include <hb.h> + hb_buffer_t *buf; + buf = hb_buffer_create(); + hb_buffer_add_utf8(buf, text, strlen(text), 0, strlen(text)); +</programlisting> + <orderedlist numeration="arabic"> + <listitem override="2"> + <para> + Guess the script, language and direction of the buffer. + </para> + </listitem> + </orderedlist> + <programlisting language="C"> + hb_buffer_guess_segment_properties(buf); +</programlisting> + <orderedlist numeration="arabic"> + <listitem override="3"> + <para> + Create a face and a font, using FreeType for now. + </para> + </listitem> + </orderedlist> + <programlisting language="C"> + #include <hb-ft.h> + FT_New_Face(ft_library, font_path, index, &face) + hb_font_t *font = hb_ft_font_create(face); +</programlisting> + <orderedlist numeration="arabic"> + <listitem override="4"> + <para> + Shape! + </para> + </listitem> + </orderedlist> + <programlisting> + hb_shape(font, buf, NULL, 0); +</programlisting> + <orderedlist numeration="arabic"> + <listitem override="5"> + <para> + Get the glyph and position information. + </para> + </listitem> + </orderedlist> + <programlisting language="C"> + hb_glyph_info_t *glyph_info = hb_buffer_get_glyph_infos(buf, &glyph_count); + hb_glyph_position_t *glyph_pos = hb_buffer_get_glyph_positions(buf, &glyph_count); +</programlisting> + <orderedlist numeration="arabic"> + <listitem override="6"> + <para> + Iterate over each glyph. + </para> + </listitem> + </orderedlist> + <programlisting language="C"> + for (i = 0; i < glyph_count; ++i) { + glyphid = glyph_info[i].codepoint; + x_offset = glyph_pos[i].x_offset / 64.0; + y_offset = glyph_pos[i].y_offset / 64.0; + x_advance = glyph_pos[i].x_advance / 64.0; + y_advance = glyph_pos[i].y_advance / 64.0; + draw_glyph(glyphid, cursor_x + x_offset, cursor_y + y_offset); + cursor_x += x_advance; + cursor_y += y_advance; + } +</programlisting> + <orderedlist numeration="arabic"> + <listitem override="7"> + <para> + Tidy up. + </para> + </listitem> + </orderedlist> + <programlisting language="C"> + hb_buffer_destroy(buf); + hb_font_destroy(hb_ft_font); +</programlisting> + <section id="what-harfbuzz-doesnt-do"> + <title>What HarfBuzz doesn't do</title> + <para> + The code above will take a UTF8 string, shape it, and give you the + information required to lay it out correctly on a single + horizontal (or vertical) line using the font provided. That is the + extent of HarfBuzz's responsibility. + </para> + <para> + If you are implementing a text layout engine you may have other + responsibilities, that HarfBuzz will not help you with: + </para> + <itemizedlist> + <listitem> + <para> + HarfBuzz won't help you with bidirectionality. If you want to + lay out text with mixed Hebrew and English, you will need to + ensure that the buffer provided to HarfBuzz has those + characters in the correct layout order. This will be different + from the logical order in which the Unicode text is stored. In + other words, the user will hit the keys in the following + sequence: + </para> + <programlisting> +A B C [space] ג ב א [space] D E F + </programlisting> + <para> + but will expect to see in the output: + </para> + <programlisting> +ABC אבג DEF + </programlisting> + <para> + This reordering is called <emphasis>bidi processing</emphasis> + ("bidi" is short for bidirectional), and there's an + algorithm as an annex to the Unicode Standard which tells you how + to reorder a string from logical order into presentation order. + Before sending your string to HarfBuzz, you may need to apply the + bidi algorithm to it. Libraries such as ICU and fribidi can do + this for you. + </para> + </listitem> + <listitem> + <para> + HarfBuzz won't help you with text that contains different font + properties. For instance, if you have the string "a + <emphasis>huge</emphasis> breakfast", and you expect + "huge" to be italic, you will need to send three + strings to HarfBuzz: <literal>a</literal>, in your Roman font; + <literal>huge</literal> using your italic font; and + <literal>breakfast</literal> using your Roman font again. + Similarly if you change font, font size, script, language or + direction within your string, you will need to shape each run + independently and then output them independently. HarfBuzz + expects to shape a run of characters sharing the same + properties. + </para> + </listitem> + <listitem> + <para> + HarfBuzz won't help you with line breaking, hyphenation or + justification. As mentioned above, it lays out the string + along a <emphasis>single line</emphasis> of, notionally, + infinite length. If you want to find out where the potential + word, sentence and line break points are in your text, you + could use the ICU library's break iterator functions. + </para> + <para> + HarfBuzz can tell you how wide a shaped piece of text is, which is + useful input to a justification algorithm, but it knows nothing + about paragraphs, lines or line lengths. Nor will it adjust the + space between words to fit them proportionally into a line. If you + want to layout text in paragraphs, you will probably want to send + each word of your text to HarfBuzz to determine its shaped width + after glyph substitutions, then work out how many words will fit + on a line, and then finally output each word of the line separated + by a space of the correct size to fully justify the paragraph. + </para> + </listitem> + </itemizedlist> + <para> + As a layout engine implementor, HarfBuzz will help you with the + interface between your text and your font, and that's something + that you'll need - what you then do with the glyphs that your font + returns is up to you. The example we saw above enough to get us + started using HarfBuzz. Now we are going to use the remainder of + HarfBuzz's API to refine that example and improve our text shaping + capabilities. + </para> + </section> +</chapter>
\ No newline at end of file diff --git a/chromium/third_party/harfbuzz-ng/src/docs/usermanual-install-harfbuzz.xml b/chromium/third_party/harfbuzz-ng/src/docs/usermanual-install-harfbuzz.xml new file mode 100644 index 00000000000..899cc5bd671 --- /dev/null +++ b/chromium/third_party/harfbuzz-ng/src/docs/usermanual-install-harfbuzz.xml @@ -0,0 +1,70 @@ +<chapter id="install-harfbuzz"> + <title>Install HarfBuzz</title> + <section id="download"> + <title id="download.title">Download</title> + <para> + For tarball releases of HarfBuzz, look + <ulink url="http://www.freedesktop.org/software/harfbuzz/release/">here</ulink>. + At the same place you will + also find Win32 binary bundles that include libharfbuzz DLL, hb-view.exe, + hb-shape.exe, and all dependencies. + </para> + <para> + The canonical source tree is available + <ulink url="http://cgit.freedesktop.org/harfbuzz/">here</ulink>. + Also available on <ulink url="https://github.com/harfbuzz/harfbuzz">github</ulink>. + </para> + <para> + The API that comes with <filename class='headerfile'>hb.h</filename> will + not change incompatibly. Other, peripheral, headers are more likely to go + through minor modifications, but again, will do our best to never change + API in an incompatible way. We will never break the ABI. + </para> + <para> + If you are not sure whether Pango or HarfBuzz is right for you, read + <ulink url="http://mces.blogspot.in/2009/11/pango-vs-harfbuzz.html">this</ulink>. + </para> + </section> + <section id="building"> + <title>Building</title> + <para> + On Linux, install the development packages for FreeType, Cairo, and GLib. + For example, on Ubuntu / Debian, you would do: + <programlisting> +<command>sudo apt-get install</command> <package>gcc g++ libfreetype6-dev libglib2.0-dev libcairo2-dev</package> + </programlisting> + whereas on Fedora, RHEL, CentOS, and other Red Hat based systems you would do: + <programlisting> +<command>sudo yum install</command> <package>gcc gcc-c++ freetype-devel glib2-devel cairo-devel</package> + </programlisting> + or using MacPorts: + <programlisting> +<command>sudo port install</command> <package>freetype glib2 cairo</package> + </programlisting> + </para> + <para> + If you are using a tarball, you can now proceed to running + <command>configure</command> and <command>make</command> as with any + other standard package. That should leave you with a shared library in + <filename>src/</filename>, and a few utility programs including hb-view + and hb-shape under <filename>util/</filename>. + </para> + <para> + If you are bootstrapping from git, you need a few more tools before you + can run <filename>autogen.sh</filename> for the first time. Namely, + pkg-config and <ulink url="http://www.complang.org/ragel/">ragel</ulink>. + Again, on Ubuntu / Debian: + <programlisting> +<command>sudo apt-get install</command> <package>autoconf automake libtool pkg-config ragel gtk-doc-tools</package> + </programlisting> + and on Fedora, RHEL, CentOS: + <programlisting> +<command>sudo yum install</command> <package>autoconf automake libtool pkgconfig ragel gtk-doc</package> + </programlisting> + or using MacPorts: + <programlisting> +<command>sudo port install</command> <package>autoconf automake libtool pkgconfig ragel gtk-doc</package> + </programlisting> + </para> + </section> +</chapter> diff --git a/chromium/third_party/harfbuzz-ng/src/docs/usermanual-opentype-features.xml b/chromium/third_party/harfbuzz-ng/src/docs/usermanual-opentype-features.xml new file mode 100644 index 00000000000..470bab8d1fb --- /dev/null +++ b/chromium/third_party/harfbuzz-ng/src/docs/usermanual-opentype-features.xml @@ -0,0 +1,13 @@ +<chapter id="shaping-and-shape-plans"> + <title>Shaping and shape plans</title> + <section id="opentype-features"> + <title>OpenType features</title> + <para> + </para> + </section> + <section id="plans-and-caching"> + <title>Plans and caching</title> + <para> + </para> + </section> +</chapter>
\ No newline at end of file diff --git a/chromium/third_party/harfbuzz-ng/src/docs/usermanual-what-is-harfbuzz.xml b/chromium/third_party/harfbuzz-ng/src/docs/usermanual-what-is-harfbuzz.xml new file mode 100644 index 00000000000..38f40cf119c --- /dev/null +++ b/chromium/third_party/harfbuzz-ng/src/docs/usermanual-what-is-harfbuzz.xml @@ -0,0 +1,115 @@ +<chapter id="what-is-harfbuzz"> + <title>What is HarfBuzz?</title> + <para> + HarfBuzz is a <emphasis>text shaping engine</emphasis>. It solves + the problem of selecting and positioning glyphs from a font given a + Unicode string. + </para> + <section id="why-do-i-need-it"> + <title>Why do I need it?</title> + <para> + Text shaping is an integral part of preparing text for display. It + is a fairly low level operation; HarfBuzz is used directly by + graphic rendering libraries such as Pango, and the layout engines + in Firefox, LibreOffice and Chromium. Unless you are + <emphasis>writing</emphasis> one of these layout engines yourself, + you will probably not need to use HarfBuzz - normally higher level + libraries will turn text into glyphs for you. + </para> + <para> + However, if you <emphasis>are</emphasis> writing a layout engine + or graphics library yourself, you will need to perform text + shaping, and this is where HarfBuzz can help you. Here are some + reasons why you need it: + </para> + <itemizedlist> + <listitem> + <para> + OpenType fonts contain a set of glyphs, indexed by glyph ID. + The glyph ID within the font does not necessarily relate to a + Unicode codepoint. For instance, some fonts have the letter + "a" as glyph ID 1. To pull the right glyph out of + the font in order to display it, you need to consult a table + within the font (the "cmap" table) which maps + Unicode codepoints to glyph IDs. Text shaping turns codepoints + into glyph IDs. + </para> + </listitem> + <listitem> + <para> + Many OpenType fonts contain ligatures: combinations of + characters which are rendered together. For instance, it's + common for the <literal>fi</literal> combination to appear in + print as the single ligature "fi". Whether you should + render text as <literal>fi</literal> or "fi" does not + depend on the input text, but on the capabilities of the font + and the level of ligature application you wish to perform. + Text shaping involves querying the font's ligature tables and + determining what substitutions should be made. + </para> + </listitem> + <listitem> + <para> + While ligatures like "fi" are typographic + refinements, some languages <emphasis>require</emphasis> such + substitutions to be made in order to display text correctly. + In Tamil, when the letter "TTA" (ட) letter is + followed by "U" (உ), the combination should appear + as the single glyph "டு". The sequence of Unicode + characters "டஉ" needs to be rendered as a single + glyph from the font - text shaping chooses the correct glyph + from the sequence of characters provided. + </para> + </listitem> + <listitem> + <para> + Similarly, each Arabic character has four different variants: + within a font, there will be glyphs for the initial, medial, + final, and isolated forms of each letter. Unicode only encodes + one codepoint per character, and so a Unicode string will not + tell you which glyph to use. Text shaping chooses the correct + form of the letter and returns the correct glyph from the font + that you need to render. + </para> + </listitem> + <listitem> + <para> + Other languages have marks and accents which need to be + rendered in certain positions around a base character. For + instance, the Moldovan language has the Cyrillic letter + "zhe" (ж) with a breve accent, like so: ӂ. Some + fonts will contain this character as an individual glyph, + whereas other fonts will not contain a zhe-with-breve glyph + but expect the rendering engine to form the character by + overlaying the two glyphs ж and ˘. Where you should draw the + combining breve depends on the height of the preceding glyph. + Again, for Arabic, the correct positioning of vowel marks + depends on the height of the character on which you are + placing the mark. Text shaping tells you whether you have a + precomposed glyph within your font or if you need to compose a + glyph yourself out of combining marks, and if so, where to + position those marks. + </para> + </listitem> + </itemizedlist> + <para> + If this is something that you need to do, then you need a text + shaping engine: you could use Uniscribe if you are using Windows; + you could use CoreText on OS X; or you could use HarfBuzz. In the + rest of this manual, we are going to assume that you are the + implementor of a text layout engine. + </para> + </section> + <section id="why-is-it-called-harfbuzz"> + <title>Why is it called HarfBuzz?</title> + <para> + HarfBuzz began its life as text shaping code within the FreeType + project, (and you will see references to the FreeType authors + within the source code copyright declarations) but was then + abstracted out to its own project. This project is maintained by + Behdad Esfahbod, and named HarfBuzz. Originally, it was a shaping + engine for OpenType fonts - "HarfBuzz" is the Persian + for "open type". + </para> + </section> +</chapter>
\ No newline at end of file diff --git a/chromium/third_party/harfbuzz-ng/src/docs/version.xml.in b/chromium/third_party/harfbuzz-ng/src/docs/version.xml.in new file mode 100644 index 00000000000..de213c2dc25 --- /dev/null +++ b/chromium/third_party/harfbuzz-ng/src/docs/version.xml.in @@ -0,0 +1 @@ +@HB_VERSION@ diff --git a/chromium/third_party/harfbuzz-ng/src/git.mk b/chromium/third_party/harfbuzz-ng/src/git.mk new file mode 100644 index 00000000000..6e2708f2dbc --- /dev/null +++ b/chromium/third_party/harfbuzz-ng/src/git.mk @@ -0,0 +1,400 @@ +# git.mk, a small Makefile to autogenerate .gitignore files +# for autotools-based projects. +# +# Copyright 2009, Red Hat, Inc. +# Copyright 2010,2011,2012,2013 Behdad Esfahbod +# Written by Behdad Esfahbod +# +# Copying and distribution of this file, with or without modification, +# is permitted in any medium without royalty provided the copyright +# notice and this notice are preserved. +# +# The latest version of this file can be downloaded from: +GIT_MK_URL = https://raw.githubusercontent.com/behdad/git.mk/master/git.mk +# +# Bugs, etc, should be reported upstream at: +# https://github.com/behdad/git.mk +# +# To use in your project, import this file in your git repo's toplevel, +# then do "make -f git.mk". This modifies all Makefile.am files in +# your project to -include git.mk. Remember to add that line to new +# Makefile.am files you create in your project, or just rerun the +# "make -f git.mk". +# +# This enables automatic .gitignore generation. If you need to ignore +# more files, add them to the GITIGNOREFILES variable in your Makefile.am. +# But think twice before doing that. If a file has to be in .gitignore, +# chances are very high that it's a generated file and should be in one +# of MOSTLYCLEANFILES, CLEANFILES, DISTCLEANFILES, or MAINTAINERCLEANFILES. +# +# The only case that you need to manually add a file to GITIGNOREFILES is +# when remove files in one of mostlyclean-local, clean-local, distclean-local, +# or maintainer-clean-local make targets. +# +# Note that for files like editor backup, etc, there are better places to +# ignore them. See "man gitignore". +# +# If "make maintainer-clean" removes the files but they are not recognized +# by this script (that is, if "git status" shows untracked files still), send +# me the output of "git status" as well as your Makefile.am and Makefile for +# the directories involved and I'll diagnose. +# +# For a list of toplevel files that should be in MAINTAINERCLEANFILES, see +# Makefile.am.sample in the git.mk git repo. +# +# Don't EXTRA_DIST this file. It is supposed to only live in git clones, +# not tarballs. It serves no useful purpose in tarballs and clutters the +# build dir. +# +# This file knows how to handle autoconf, automake, libtool, gtk-doc, +# gnome-doc-utils, yelp.m4, mallard, intltool, gsettings, dejagnu, appdata, +# appstream, hotdoc. +# +# This makefile provides the following targets: +# +# - all: "make all" will build all gitignore files. +# - gitignore: makes all gitignore files in the current dir and subdirs. +# - .gitignore: make gitignore file for the current dir. +# - gitignore-recurse: makes all gitignore files in the subdirs. +# +# KNOWN ISSUES: +# +# - Recursive configure doesn't work as $(top_srcdir)/git.mk inside the +# submodule doesn't find us. If you have configure.{in,ac} files in +# subdirs, add a proxy git.mk file in those dirs that simply does: +# "include $(top_srcdir)/../git.mk". Add more ..'s to your taste. +# And add those files to git. See vte/gnome-pty-helper/git.mk for +# example. +# + + + +############################################################################### +# Variables user modules may want to add to toplevel MAINTAINERCLEANFILES: +############################################################################### + +# +# Most autotools-using modules should be fine including this variable in their +# toplevel MAINTAINERCLEANFILES: +GITIGNORE_MAINTAINERCLEANFILES_TOPLEVEL = \ + $(srcdir)/aclocal.m4 \ + $(srcdir)/autoscan.log \ + $(srcdir)/configure.scan \ + `AUX_DIR=$(srcdir)/$$(cd $(top_srcdir); $(AUTOCONF) --trace 'AC_CONFIG_AUX_DIR:$$1' ./configure.ac); \ + test "x$$AUX_DIR" = "x$(srcdir)/" && AUX_DIR=$(srcdir); \ + for x in \ + ar-lib \ + compile \ + config.guess \ + config.rpath \ + config.sub \ + depcomp \ + install-sh \ + ltmain.sh \ + missing \ + mkinstalldirs \ + test-driver \ + ylwrap \ + ; do echo "$$AUX_DIR/$$x"; done` \ + `cd $(top_srcdir); $(AUTOCONF) --trace 'AC_CONFIG_HEADERS:$$1' ./configure.ac | \ + head -n 1 | while read f; do echo "$(srcdir)/$$f.in"; done` +# +# All modules should also be fine including the following variable, which +# removes automake-generated Makefile.in files: +GITIGNORE_MAINTAINERCLEANFILES_MAKEFILE_IN = \ + `cd $(top_srcdir); $(AUTOCONF) --trace 'AC_CONFIG_FILES:$$1' ./configure.ac | \ + while read f; do \ + case $$f in Makefile|*/Makefile) \ + test -f "$(srcdir)/$$f.am" && echo "$(srcdir)/$$f.in";; esac; \ + done` +# +# Modules that use libtool and use AC_CONFIG_MACRO_DIR() may also include this, +# though it's harmless to include regardless. +GITIGNORE_MAINTAINERCLEANFILES_M4_LIBTOOL = \ + `MACRO_DIR=$(srcdir)/$$(cd $(top_srcdir); $(AUTOCONF) --trace 'AC_CONFIG_MACRO_DIR:$$1' ./configure.ac); \ + if test "x$$MACRO_DIR" != "x$(srcdir)/"; then \ + for x in \ + libtool.m4 \ + ltoptions.m4 \ + ltsugar.m4 \ + ltversion.m4 \ + lt~obsolete.m4 \ + ; do echo "$$MACRO_DIR/$$x"; done; \ + fi` +# +# Modules that use gettext and use AC_CONFIG_MACRO_DIR() may also include this, +# though it's harmless to include regardless. +GITIGNORE_MAINTAINERCLEANFILES_M4_GETTEXT = \ + `MACRO_DIR=$(srcdir)/$$(cd $(top_srcdir); $(AUTOCONF) --trace 'AC_CONFIG_MACRO_DIR:$$1' ./configure.ac); \ + if test "x$$MACRO_DIR" != "x$(srcdir)/"; then \ + for x in \ + codeset.m4 \ + extern-inline.m4 \ + fcntl-o.m4 \ + gettext.m4 \ + glibc2.m4 \ + glibc21.m4 \ + iconv.m4 \ + intdiv0.m4 \ + intl.m4 \ + intldir.m4 \ + intlmacosx.m4 \ + intmax.m4 \ + inttypes-pri.m4 \ + inttypes_h.m4 \ + lcmessage.m4 \ + lib-ld.m4 \ + lib-link.m4 \ + lib-prefix.m4 \ + lock.m4 \ + longlong.m4 \ + nls.m4 \ + po.m4 \ + printf-posix.m4 \ + progtest.m4 \ + size_max.m4 \ + stdint_h.m4 \ + threadlib.m4 \ + uintmax_t.m4 \ + visibility.m4 \ + wchar_t.m4 \ + wint_t.m4 \ + xsize.m4 \ + ; do echo "$$MACRO_DIR/$$x"; done; \ + fi` + + + +############################################################################### +# Default rule is to install ourselves in all Makefile.am files: +############################################################################### + +git-all: git-mk-install + +git-mk-install: + @echo "Installing git makefile" + @any_failed=; \ + find "`test -z "$(top_srcdir)" && echo . || echo "$(top_srcdir)"`" -name Makefile.am | while read x; do \ + if grep 'include .*/git.mk' $$x >/dev/null; then \ + echo "$$x already includes git.mk"; \ + else \ + failed=; \ + echo "Updating $$x"; \ + { cat $$x; \ + echo ''; \ + echo '-include $$(top_srcdir)/git.mk'; \ + } > $$x.tmp || failed=1; \ + if test x$$failed = x; then \ + mv $$x.tmp $$x || failed=1; \ + fi; \ + if test x$$failed = x; then : else \ + echo "Failed updating $$x"; >&2 \ + any_failed=1; \ + fi; \ + fi; done; test -z "$$any_failed" + +git-mk-update: + wget $(GIT_MK_URL) -O $(top_srcdir)/git.mk + +.PHONY: git-all git-mk-install git-mk-update + + + +############################################################################### +# Actual .gitignore generation: +############################################################################### + +$(srcdir)/.gitignore: Makefile.am $(top_srcdir)/git.mk + @echo "git.mk: Generating $@" + @{ \ + if test "x$(DOC_MODULE)" = x -o "x$(DOC_MAIN_SGML_FILE)" = x; then :; else \ + for x in \ + $(DOC_MODULE)-decl-list.txt \ + $(DOC_MODULE)-decl.txt \ + tmpl/$(DOC_MODULE)-unused.sgml \ + "tmpl/*.bak" \ + $(REPORT_FILES) \ + $(DOC_MODULE).pdf \ + xml html \ + ; do echo "/$$x"; done; \ + FLAVOR=$$(cd $(top_srcdir); $(AUTOCONF) --trace 'GTK_DOC_CHECK:$$2' ./configure.ac); \ + case $$FLAVOR in *no-tmpl*) echo /tmpl;; esac; \ + if echo "$(SCAN_OPTIONS)" | grep -q "\-\-rebuild-types"; then \ + echo "/$(DOC_MODULE).types"; \ + fi; \ + if echo "$(SCAN_OPTIONS)" | grep -q "\-\-rebuild-sections"; then \ + echo "/$(DOC_MODULE)-sections.txt"; \ + fi; \ + if test "$(abs_srcdir)" != "$(abs_builddir)" ; then \ + for x in \ + $(SETUP_FILES) \ + $(DOC_MODULE).types \ + ; do echo "/$$x"; done; \ + fi; \ + fi; \ + if test "x$(DOC_MODULE)$(DOC_ID)" = x -o "x$(DOC_LINGUAS)" = x; then :; else \ + for lc in $(DOC_LINGUAS); do \ + for x in \ + $(if $(DOC_MODULE),$(DOC_MODULE).xml) \ + $(DOC_PAGES) \ + $(DOC_INCLUDES) \ + ; do echo "/$$lc/$$x"; done; \ + done; \ + for x in \ + $(_DOC_OMF_ALL) \ + $(_DOC_DSK_ALL) \ + $(_DOC_HTML_ALL) \ + $(_DOC_MOFILES) \ + $(DOC_H_FILE) \ + "*/.xml2po.mo" \ + "*/*.omf.out" \ + ; do echo /$$x; done; \ + fi; \ + if test "x$(HOTDOC)" = x; then :; else \ + $(foreach project, $(HOTDOC_PROJECTS),echo "/$(call HOTDOC_TARGET,$(project))"; \ + echo "/$(shell $(call HOTDOC_PROJECT_COMMAND,$(project)) --get-conf-path output)" ; \ + echo "/$(shell $(call HOTDOC_PROJECT_COMMAND,$(project)) --get-private-folder)" ; \ + ) \ + for x in \ + .hotdoc.d \ + ; do echo "/$$x"; done; \ + fi; \ + if test "x$(HELP_ID)" = x -o "x$(HELP_LINGUAS)" = x; then :; else \ + for lc in $(HELP_LINGUAS); do \ + for x in \ + $(HELP_FILES) \ + "$$lc.stamp" \ + "$$lc.mo" \ + ; do echo "/$$lc/$$x"; done; \ + done; \ + fi; \ + if test "x$(gsettings_SCHEMAS)" = x; then :; else \ + for x in \ + $(gsettings_SCHEMAS:.xml=.valid) \ + $(gsettings__enum_file) \ + ; do echo "/$$x"; done; \ + fi; \ + if test "x$(appdata_XML)" = x; then :; else \ + for x in \ + $(appdata_XML:.xml=.valid) \ + ; do echo "/$$x"; done; \ + fi; \ + if test "x$(appstream_XML)" = x; then :; else \ + for x in \ + $(appstream_XML:.xml=.valid) \ + ; do echo "/$$x"; done; \ + fi; \ + if test -f $(srcdir)/po/Makefile.in.in; then \ + for x in \ + ABOUT-NLS \ + po/Makefile.in.in \ + po/Makefile.in.in~ \ + po/Makefile.in \ + po/Makefile \ + po/Makevars.template \ + po/POTFILES \ + po/Rules-quot \ + po/stamp-it \ + po/stamp-po \ + po/.intltool-merge-cache \ + "po/*.gmo" \ + "po/*.header" \ + "po/*.mo" \ + "po/*.sed" \ + "po/*.sin" \ + po/$(GETTEXT_PACKAGE).pot \ + intltool-extract.in \ + intltool-merge.in \ + intltool-update.in \ + ; do echo "/$$x"; done; \ + fi; \ + if test -f $(srcdir)/configure; then \ + for x in \ + autom4te.cache \ + configure \ + config.h \ + stamp-h1 \ + libtool \ + config.lt \ + ; do echo "/$$x"; done; \ + fi; \ + if test "x$(DEJATOOL)" = x; then :; else \ + for x in \ + $(DEJATOOL) \ + ; do echo "/$$x.sum"; echo "/$$x.log"; done; \ + echo /site.exp; \ + fi; \ + if test "x$(am__dirstamp)" = x; then :; else \ + echo "$(am__dirstamp)"; \ + fi; \ + if test "x$(findstring libtool,$(LTCOMPILE))" = x -a "x$(findstring libtool,$(LTCXXCOMPILE))" = x -a "x$(GTKDOC_RUN)" = x; then :; else \ + for x in \ + "*.lo" \ + ".libs" "_libs" \ + ; do echo "$$x"; done; \ + fi; \ + for x in \ + .gitignore \ + $(GITIGNOREFILES) \ + $(CLEANFILES) \ + $(PROGRAMS) $(check_PROGRAMS) $(EXTRA_PROGRAMS) \ + $(LIBRARIES) $(check_LIBRARIES) $(EXTRA_LIBRARIES) \ + $(LTLIBRARIES) $(check_LTLIBRARIES) $(EXTRA_LTLIBRARIES) \ + so_locations \ + $(MOSTLYCLEANFILES) \ + $(TEST_LOGS) \ + $(TEST_LOGS:.log=.trs) \ + $(TEST_SUITE_LOG) \ + $(TESTS:=.test) \ + "*.gcda" \ + "*.gcno" \ + $(DISTCLEANFILES) \ + $(am__CONFIG_DISTCLEAN_FILES) \ + $(CONFIG_CLEAN_FILES) \ + TAGS ID GTAGS GRTAGS GSYMS GPATH tags \ + "*.tab.c" \ + $(MAINTAINERCLEANFILES) \ + $(BUILT_SOURCES) \ + $(patsubst %.vala,%.c,$(filter %.vala,$(SOURCES))) \ + $(filter %_vala.stamp,$(DIST_COMMON)) \ + $(filter %.vapi,$(DIST_COMMON)) \ + $(filter $(addprefix %,$(notdir $(patsubst %.vapi,%.h,$(filter %.vapi,$(DIST_COMMON))))),$(DIST_COMMON)) \ + Makefile \ + Makefile.in \ + "*.orig" \ + "*.rej" \ + "*.bak" \ + "*~" \ + ".*.sw[nop]" \ + ".dirstamp" \ + ; do echo "/$$x"; done; \ + for x in \ + "*.$(OBJEXT)" \ + $(DEPDIR) \ + ; do echo "$$x"; done; \ + } | \ + sed "s@^/`echo "$(srcdir)" | sed 's/\(.\)/[\1]/g'`/@/@" | \ + sed 's@/[.]/@/@g' | \ + LC_ALL=C sort | uniq > $@.tmp && \ + mv $@.tmp $@; + +all: $(srcdir)/.gitignore gitignore-recurse-maybe +gitignore: $(srcdir)/.gitignore gitignore-recurse + +gitignore-recurse-maybe: + @for subdir in $(DIST_SUBDIRS); do \ + case " $(SUBDIRS) " in \ + *" $$subdir "*) :;; \ + *) test "$$subdir" = . -o -e "$$subdir/.git" || (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) gitignore || echo "Skipping $$subdir");; \ + esac; \ + done +gitignore-recurse: + @for subdir in $(DIST_SUBDIRS); do \ + test "$$subdir" = . -o -e "$$subdir/.git" || (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) gitignore || echo "Skipping $$subdir"); \ + done + +maintainer-clean: gitignore-clean +gitignore-clean: + -rm -f $(srcdir)/.gitignore + +.PHONY: gitignore-clean gitignore gitignore-recurse gitignore-recurse-maybe diff --git a/chromium/third_party/harfbuzz-ng/src/harfbuzz.doap b/chromium/third_party/harfbuzz-ng/src/harfbuzz.doap new file mode 100644 index 00000000000..07699697fef --- /dev/null +++ b/chromium/third_party/harfbuzz-ng/src/harfbuzz.doap @@ -0,0 +1,24 @@ +<Project xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:rdfs="http://www.w3.org/2000/01/rdf-schema#" + xmlns:foaf="http://xmlns.com/foaf/0.1/" + xmlns="http://usefulinc.com/ns/doap#"> + + <name xml:lang="en">harfbuzz</name> + <shortdesc xml:lang="en">Text shaping library</shortdesc> + + <homepage + rdf:resource="http://harfbuzz.org/" /> + <mailing-list + rdf:resource="http://lists.freedesktop.org/mailman/listinfo/harfbuzz" /> + <!--download-page + rdf:resource=""/--> + <bug-database + rdf:resource="https://github.com/harfbuzz/harfbuzz/issues" /> + + <maintainer> + <foaf:Person> + <foaf:name>Behdad Esfahbod</foaf:name> + <foaf:mbox rdf:resource="mailto:harfbuzz@behdad.org" /> + </foaf:Person> + </maintainer> +</Project> diff --git a/chromium/third_party/harfbuzz-ng/src/hb-buffer-deserialize-json.hh b/chromium/third_party/harfbuzz-ng/src/hb-buffer-deserialize-json.hh deleted file mode 100644 index 125a4192911..00000000000 --- a/chromium/third_party/harfbuzz-ng/src/hb-buffer-deserialize-json.hh +++ /dev/null @@ -1,643 +0,0 @@ - -#line 1 "hb-buffer-deserialize-json.rl" -/* - * Copyright © 2013 Google, Inc. - * - * This is part of HarfBuzz, a text shaping library. - * - * Permission is hereby granted, without written agreement and without - * license or royalty fees, to use, copy, modify, and distribute this - * software and its documentation for any purpose, provided that the - * above copyright notice and the following two paragraphs appear in - * all copies of this software. - * - * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR - * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES - * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN - * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH - * DAMAGE. - * - * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, - * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND - * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS - * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO - * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. - * - * Google Author(s): Behdad Esfahbod - */ - -#ifndef HB_BUFFER_DESERIALIZE_JSON_HH -#define HB_BUFFER_DESERIALIZE_JSON_HH - -#include "hb-private.hh" - - -#line 36 "hb-buffer-deserialize-json.hh" -static const unsigned char _deserialize_json_trans_keys[] = { - 0u, 0u, 9u, 123u, 9u, 34u, 97u, 103u, 120u, 121u, 34u, 34u, 9u, 58u, 9u, 57u, - 48u, 57u, 9u, 125u, 9u, 125u, 9u, 125u, 34u, 34u, 9u, 58u, 9u, 57u, 48u, 57u, - 9u, 125u, 9u, 125u, 108u, 108u, 34u, 34u, 9u, 58u, 9u, 57u, 9u, 125u, 9u, 125u, - 120u, 121u, 34u, 34u, 9u, 58u, 9u, 57u, 48u, 57u, 9u, 125u, 9u, 125u, 34u, 34u, - 9u, 58u, 9u, 57u, 48u, 57u, 9u, 125u, 9u, 125u, 34u, 34u, 9u, 58u, 9u, 57u, - 65u, 122u, 34u, 122u, 9u, 125u, 9u, 125u, 9u, 93u, 9u, 123u, 0u, 0u, 0 -}; - -static const char _deserialize_json_key_spans[] = { - 0, 115, 26, 7, 2, 1, 50, 49, - 10, 117, 117, 117, 1, 50, 49, 10, - 117, 117, 1, 1, 50, 49, 117, 117, - 2, 1, 50, 49, 10, 117, 117, 1, - 50, 49, 10, 117, 117, 1, 50, 49, - 58, 89, 117, 117, 85, 115, 0 -}; - -static const short _deserialize_json_index_offsets[] = { - 0, 0, 116, 143, 151, 154, 156, 207, - 257, 268, 386, 504, 622, 624, 675, 725, - 736, 854, 972, 974, 976, 1027, 1077, 1195, - 1313, 1316, 1318, 1369, 1419, 1430, 1548, 1666, - 1668, 1719, 1769, 1780, 1898, 2016, 2018, 2069, - 2119, 2178, 2268, 2386, 2504, 2590, 2706 -}; - -static const char _deserialize_json_indicies[] = { - 0, 0, 0, 0, 0, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 0, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 2, 1, 3, 3, 3, - 3, 3, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 3, 1, 4, 1, - 5, 1, 6, 7, 1, 1, 8, 1, - 9, 10, 1, 11, 1, 11, 11, 11, - 11, 11, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 11, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 12, 1, - 12, 12, 12, 12, 12, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 12, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 13, 1, 1, 14, - 15, 15, 15, 15, 15, 15, 15, 15, - 15, 1, 16, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 1, 18, 18, 18, - 18, 18, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 18, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 19, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 20, 1, 21, 21, 21, 21, 21, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 21, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 3, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 22, - 1, 18, 18, 18, 18, 18, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 18, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 19, 1, 1, 1, - 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 20, 1, 23, - 1, 23, 23, 23, 23, 23, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 23, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 24, 1, 24, 24, 24, 24, - 24, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 24, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 25, 1, 1, 26, 27, 27, 27, 27, - 27, 27, 27, 27, 27, 1, 28, 29, - 29, 29, 29, 29, 29, 29, 29, 29, - 1, 30, 30, 30, 30, 30, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 30, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 31, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 32, 1, 30, - 30, 30, 30, 30, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 30, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 31, 1, 1, 1, 29, 29, - 29, 29, 29, 29, 29, 29, 29, 29, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 32, 1, 33, 1, 34, - 1, 34, 34, 34, 34, 34, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 34, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 35, 1, 35, 35, 35, 35, - 35, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 35, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 36, 37, 37, 37, 37, - 37, 37, 37, 37, 37, 1, 38, 38, - 38, 38, 38, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 38, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 39, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 40, 1, 38, 38, 38, 38, - 38, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 38, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 39, - 1, 1, 1, 41, 41, 41, 41, 41, - 41, 41, 41, 41, 41, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 40, 1, 42, 43, 1, 44, 1, 44, - 44, 44, 44, 44, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 44, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 45, 1, 45, 45, 45, 45, 45, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 45, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 46, 1, - 1, 47, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 1, 49, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 1, 51, - 51, 51, 51, 51, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 51, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 52, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 53, 1, 51, 51, 51, - 51, 51, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 51, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 52, 1, 1, 1, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 53, 1, 54, 1, 54, 54, 54, - 54, 54, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 54, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 55, 1, - 55, 55, 55, 55, 55, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 55, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 56, 1, 1, 57, - 58, 58, 58, 58, 58, 58, 58, 58, - 58, 1, 59, 60, 60, 60, 60, 60, - 60, 60, 60, 60, 1, 61, 61, 61, - 61, 61, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 61, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 62, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 63, 1, 61, 61, 61, 61, 61, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 61, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 62, 1, - 1, 1, 60, 60, 60, 60, 60, 60, - 60, 60, 60, 60, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 63, - 1, 64, 1, 64, 64, 64, 64, 64, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 64, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 65, 1, 65, 65, - 65, 65, 65, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 65, 1, 66, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 67, 68, 68, - 68, 68, 68, 68, 68, 68, 68, 1, - 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, 1, 1, 1, 1, 1, 1, - 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, 1, 70, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 71, 71, - 1, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 1, 1, 1, 1, 1, - 1, 1, 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, 1, 1, 1, 1, - 71, 1, 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, 1, 72, 72, 72, - 72, 72, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 72, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 73, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 74, 1, 72, 72, 72, 72, 72, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 72, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 73, 1, - 1, 1, 75, 75, 75, 75, 75, 75, - 75, 75, 75, 75, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 74, - 1, 76, 76, 76, 76, 76, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 76, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 77, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 78, 1, 0, - 0, 0, 0, 0, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 0, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 2, 1, 1, 0 -}; - -static const char _deserialize_json_trans_targs[] = { - 1, 0, 2, 2, 3, 4, 18, 24, - 37, 5, 12, 6, 7, 8, 9, 11, - 9, 11, 10, 2, 44, 10, 44, 13, - 14, 15, 16, 17, 16, 17, 10, 2, - 44, 19, 20, 21, 22, 23, 10, 2, - 44, 23, 25, 31, 26, 27, 28, 29, - 30, 29, 30, 10, 2, 44, 32, 33, - 34, 35, 36, 35, 36, 10, 2, 44, - 38, 39, 40, 42, 43, 41, 10, 41, - 10, 2, 44, 43, 44, 45, 46 -}; - -static const char _deserialize_json_trans_actions[] = { - 0, 0, 1, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 2, 2, 2, - 0, 0, 3, 3, 4, 0, 5, 0, - 0, 2, 2, 2, 0, 0, 6, 6, - 7, 0, 0, 0, 2, 2, 8, 8, - 9, 0, 0, 0, 0, 0, 2, 2, - 2, 0, 0, 10, 10, 11, 0, 0, - 2, 2, 2, 0, 0, 12, 12, 13, - 0, 0, 0, 2, 2, 2, 14, 0, - 15, 15, 16, 0, 0, 0, 0 -}; - -static const int deserialize_json_start = 1; -static const int deserialize_json_first_final = 44; -static const int deserialize_json_error = 0; - -static const int deserialize_json_en_main = 1; - - -#line 97 "hb-buffer-deserialize-json.rl" - - -static hb_bool_t -_hb_buffer_deserialize_glyphs_json (hb_buffer_t *buffer, - const char *buf, - unsigned int buf_len, - const char **end_ptr, - hb_font_t *font) -{ - const char *p = buf, *pe = buf + buf_len; - - /* Ensure we have positions. */ - (void) hb_buffer_get_glyph_positions (buffer, nullptr); - - while (p < pe && ISSPACE (*p)) - p++; - if (p < pe && *p == (buffer->len ? ',' : '[')) - { - *end_ptr = ++p; - } - - const char *tok = nullptr; - int cs; - hb_glyph_info_t info = {0}; - hb_glyph_position_t pos = {0}; - -#line 466 "hb-buffer-deserialize-json.hh" - { - cs = deserialize_json_start; - } - -#line 471 "hb-buffer-deserialize-json.hh" - { - int _slen; - int _trans; - const unsigned char *_keys; - const char *_inds; - if ( p == pe ) - goto _test_eof; - if ( cs == 0 ) - goto _out; -_resume: - _keys = _deserialize_json_trans_keys + (cs<<1); - _inds = _deserialize_json_indicies + _deserialize_json_index_offsets[cs]; - - _slen = _deserialize_json_key_spans[cs]; - _trans = _inds[ _slen > 0 && _keys[0] <=(*p) && - (*p) <= _keys[1] ? - (*p) - _keys[0] : _slen ]; - - cs = _deserialize_json_trans_targs[_trans]; - - if ( _deserialize_json_trans_actions[_trans] == 0 ) - goto _again; - - switch ( _deserialize_json_trans_actions[_trans] ) { - case 1: -#line 38 "hb-buffer-deserialize-json.rl" - { - memset (&info, 0, sizeof (info)); - memset (&pos , 0, sizeof (pos )); -} - break; - case 5: -#line 43 "hb-buffer-deserialize-json.rl" - { - buffer->add_info (info); - if (buffer->in_error) - return false; - buffer->pos[buffer->len - 1] = pos; - *end_ptr = p; -} - break; - case 2: -#line 51 "hb-buffer-deserialize-json.rl" - { - tok = p; -} - break; - case 14: -#line 55 "hb-buffer-deserialize-json.rl" - { - if (!hb_font_glyph_from_string (font, - tok, p - tok, - &info.codepoint)) - return false; -} - break; - case 15: -#line 62 "hb-buffer-deserialize-json.rl" - { if (!parse_uint (tok, p, &info.codepoint)) return false; } - break; - case 8: -#line 63 "hb-buffer-deserialize-json.rl" - { if (!parse_uint (tok, p, &info.cluster )) return false; } - break; - case 10: -#line 64 "hb-buffer-deserialize-json.rl" - { if (!parse_int (tok, p, &pos.x_offset )) return false; } - break; - case 12: -#line 65 "hb-buffer-deserialize-json.rl" - { if (!parse_int (tok, p, &pos.y_offset )) return false; } - break; - case 3: -#line 66 "hb-buffer-deserialize-json.rl" - { if (!parse_int (tok, p, &pos.x_advance)) return false; } - break; - case 6: -#line 67 "hb-buffer-deserialize-json.rl" - { if (!parse_int (tok, p, &pos.y_advance)) return false; } - break; - case 16: -#line 62 "hb-buffer-deserialize-json.rl" - { if (!parse_uint (tok, p, &info.codepoint)) return false; } -#line 43 "hb-buffer-deserialize-json.rl" - { - buffer->add_info (info); - if (buffer->in_error) - return false; - buffer->pos[buffer->len - 1] = pos; - *end_ptr = p; -} - break; - case 9: -#line 63 "hb-buffer-deserialize-json.rl" - { if (!parse_uint (tok, p, &info.cluster )) return false; } -#line 43 "hb-buffer-deserialize-json.rl" - { - buffer->add_info (info); - if (buffer->in_error) - return false; - buffer->pos[buffer->len - 1] = pos; - *end_ptr = p; -} - break; - case 11: -#line 64 "hb-buffer-deserialize-json.rl" - { if (!parse_int (tok, p, &pos.x_offset )) return false; } -#line 43 "hb-buffer-deserialize-json.rl" - { - buffer->add_info (info); - if (buffer->in_error) - return false; - buffer->pos[buffer->len - 1] = pos; - *end_ptr = p; -} - break; - case 13: -#line 65 "hb-buffer-deserialize-json.rl" - { if (!parse_int (tok, p, &pos.y_offset )) return false; } -#line 43 "hb-buffer-deserialize-json.rl" - { - buffer->add_info (info); - if (buffer->in_error) - return false; - buffer->pos[buffer->len - 1] = pos; - *end_ptr = p; -} - break; - case 4: -#line 66 "hb-buffer-deserialize-json.rl" - { if (!parse_int (tok, p, &pos.x_advance)) return false; } -#line 43 "hb-buffer-deserialize-json.rl" - { - buffer->add_info (info); - if (buffer->in_error) - return false; - buffer->pos[buffer->len - 1] = pos; - *end_ptr = p; -} - break; - case 7: -#line 67 "hb-buffer-deserialize-json.rl" - { if (!parse_int (tok, p, &pos.y_advance)) return false; } -#line 43 "hb-buffer-deserialize-json.rl" - { - buffer->add_info (info); - if (buffer->in_error) - return false; - buffer->pos[buffer->len - 1] = pos; - *end_ptr = p; -} - break; -#line 624 "hb-buffer-deserialize-json.hh" - } - -_again: - if ( cs == 0 ) - goto _out; - if ( ++p != pe ) - goto _resume; - _test_eof: {} - _out: {} - } - -#line 125 "hb-buffer-deserialize-json.rl" - - - *end_ptr = p; - - return p == pe && *(p-1) != ']'; -} - -#endif /* HB_BUFFER_DESERIALIZE_JSON_HH */ diff --git a/chromium/third_party/harfbuzz-ng/src/m4/ax_check_link_flag.m4 b/chromium/third_party/harfbuzz-ng/src/m4/ax_check_link_flag.m4 new file mode 100644 index 00000000000..819409a20a4 --- /dev/null +++ b/chromium/third_party/harfbuzz-ng/src/m4/ax_check_link_flag.m4 @@ -0,0 +1,74 @@ +# =========================================================================== +# https://www.gnu.org/software/autoconf-archive/ax_check_link_flag.html +# =========================================================================== +# +# SYNOPSIS +# +# AX_CHECK_LINK_FLAG(FLAG, [ACTION-SUCCESS], [ACTION-FAILURE], [EXTRA-FLAGS], [INPUT]) +# +# DESCRIPTION +# +# Check whether the given FLAG works with the linker or gives an error. +# (Warnings, however, are ignored) +# +# ACTION-SUCCESS/ACTION-FAILURE are shell commands to execute on +# success/failure. +# +# If EXTRA-FLAGS is defined, it is added to the linker's default flags +# when the check is done. The check is thus made with the flags: "LDFLAGS +# EXTRA-FLAGS FLAG". This can for example be used to force the linker to +# issue an error when a bad flag is given. +# +# INPUT gives an alternative input source to AC_LINK_IFELSE. +# +# NOTE: Implementation based on AX_CFLAGS_GCC_OPTION. Please keep this +# macro in sync with AX_CHECK_{PREPROC,COMPILE}_FLAG. +# +# LICENSE +# +# Copyright (c) 2008 Guido U. Draheim <guidod@gmx.de> +# Copyright (c) 2011 Maarten Bosmans <mkbosmans@gmail.com> +# +# 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. +# +# 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 <https://www.gnu.org/licenses/>. +# +# As a special exception, the respective Autoconf Macro's copyright owner +# gives unlimited permission to copy, distribute and modify the configure +# scripts that are the output of Autoconf when processing the Macro. You +# need not follow the terms of the GNU General Public License when using +# or distributing such scripts, even though portions of the text of the +# Macro appear in them. The GNU General Public License (GPL) does govern +# all other use of the material that constitutes the Autoconf Macro. +# +# This special exception to the GPL applies to versions of the Autoconf +# Macro released by the Autoconf Archive. When you make and distribute a +# modified version of the Autoconf Macro, you may extend this special +# exception to the GPL to apply to your modified version as well. + +#serial 5 + +AC_DEFUN([AX_CHECK_LINK_FLAG], +[AC_PREREQ(2.64)dnl for _AC_LANG_PREFIX and AS_VAR_IF +AS_VAR_PUSHDEF([CACHEVAR],[ax_cv_check_ldflags_$4_$1])dnl +AC_CACHE_CHECK([whether the linker accepts $1], CACHEVAR, [ + ax_check_save_flags=$LDFLAGS + LDFLAGS="$LDFLAGS $4 $1" + AC_LINK_IFELSE([m4_default([$5],[AC_LANG_PROGRAM()])], + [AS_VAR_SET(CACHEVAR,[yes])], + [AS_VAR_SET(CACHEVAR,[no])]) + LDFLAGS=$ax_check_save_flags]) +AS_VAR_IF(CACHEVAR,yes, + [m4_default([$2], :)], + [m4_default([$3], :)]) +AS_VAR_POPDEF([CACHEVAR])dnl +])dnl AX_CHECK_LINK_FLAGS diff --git a/chromium/third_party/harfbuzz-ng/src/m4/ax_code_coverage.m4 b/chromium/third_party/harfbuzz-ng/src/m4/ax_code_coverage.m4 new file mode 100644 index 00000000000..6484f033243 --- /dev/null +++ b/chromium/third_party/harfbuzz-ng/src/m4/ax_code_coverage.m4 @@ -0,0 +1,264 @@ +# =========================================================================== +# https://www.gnu.org/software/autoconf-archive/ax_code_coverage.html +# =========================================================================== +# +# SYNOPSIS +# +# AX_CODE_COVERAGE() +# +# DESCRIPTION +# +# Defines CODE_COVERAGE_CPPFLAGS, CODE_COVERAGE_CFLAGS, +# CODE_COVERAGE_CXXFLAGS and CODE_COVERAGE_LIBS which should be included +# in the CPPFLAGS, CFLAGS CXXFLAGS and LIBS/LIBADD variables of every +# build target (program or library) which should be built with code +# coverage support. Also defines CODE_COVERAGE_RULES which should be +# substituted in your Makefile; and $enable_code_coverage which can be +# used in subsequent configure output. CODE_COVERAGE_ENABLED is defined +# and substituted, and corresponds to the value of the +# --enable-code-coverage option, which defaults to being disabled. +# +# Test also for gcov program and create GCOV variable that could be +# substituted. +# +# Note that all optimization flags in CFLAGS must be disabled when code +# coverage is enabled. +# +# Usage example: +# +# configure.ac: +# +# AX_CODE_COVERAGE +# +# Makefile.am: +# +# @CODE_COVERAGE_RULES@ +# my_program_LIBS = ... $(CODE_COVERAGE_LIBS) ... +# my_program_CPPFLAGS = ... $(CODE_COVERAGE_CPPFLAGS) ... +# my_program_CFLAGS = ... $(CODE_COVERAGE_CFLAGS) ... +# my_program_CXXFLAGS = ... $(CODE_COVERAGE_CXXFLAGS) ... +# +# This results in a "check-code-coverage" rule being added to any +# Makefile.am which includes "@CODE_COVERAGE_RULES@" (assuming the module +# has been configured with --enable-code-coverage). Running `make +# check-code-coverage` in that directory will run the module's test suite +# (`make check`) and build a code coverage report detailing the code which +# was touched, then print the URI for the report. +# +# In earlier versions of this macro, CODE_COVERAGE_LDFLAGS was defined +# instead of CODE_COVERAGE_LIBS. They are both still defined, but use of +# CODE_COVERAGE_LIBS is preferred for clarity; CODE_COVERAGE_LDFLAGS is +# deprecated. They have the same value. +# +# This code was derived from Makefile.decl in GLib, originally licenced +# under LGPLv2.1+. +# +# LICENSE +# +# Copyright (c) 2012, 2016 Philip Withnall +# Copyright (c) 2012 Xan Lopez +# Copyright (c) 2012 Christian Persch +# Copyright (c) 2012 Paolo Borelli +# Copyright (c) 2012 Dan Winship +# Copyright (c) 2015 Bastien ROUCARIES +# +# This library is free software; you can redistribute it and/or modify it +# under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation; either version 2.1 of the License, or (at +# your option) any later version. +# +# This library 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 Lesser +# General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public License +# along with this program. If not, see <https://www.gnu.org/licenses/>. + +#serial 25 + +AC_DEFUN([AX_CODE_COVERAGE],[ + dnl Check for --enable-code-coverage + AC_REQUIRE([AC_PROG_SED]) + + # allow to override gcov location + AC_ARG_WITH([gcov], + [AS_HELP_STRING([--with-gcov[=GCOV]], [use given GCOV for coverage (GCOV=gcov).])], + [_AX_CODE_COVERAGE_GCOV_PROG_WITH=$with_gcov], + [_AX_CODE_COVERAGE_GCOV_PROG_WITH=gcov]) + + AC_MSG_CHECKING([whether to build with code coverage support]) + AC_ARG_ENABLE([code-coverage], + AS_HELP_STRING([--enable-code-coverage], + [Whether to enable code coverage support]),, + enable_code_coverage=no) + + AM_CONDITIONAL([CODE_COVERAGE_ENABLED], [test x$enable_code_coverage = xyes]) + AC_SUBST([CODE_COVERAGE_ENABLED], [$enable_code_coverage]) + AC_MSG_RESULT($enable_code_coverage) + + AS_IF([ test "$enable_code_coverage" = "yes" ], [ + # check for gcov + AC_CHECK_TOOL([GCOV], + [$_AX_CODE_COVERAGE_GCOV_PROG_WITH], + [:]) + AS_IF([test "X$GCOV" = "X:"], + [AC_MSG_ERROR([gcov is needed to do coverage])]) + AC_SUBST([GCOV]) + + dnl Check if gcc is being used + AS_IF([ test "$GCC" = "no" ], [ + AC_MSG_ERROR([not compiling with gcc, which is required for gcov code coverage]) + ]) + + AC_CHECK_PROG([LCOV], [lcov], [lcov]) + AC_CHECK_PROG([GENHTML], [genhtml], [genhtml]) + + AS_IF([ test -z "$LCOV" ], [ + AC_MSG_ERROR([To enable code coverage reporting you must have lcov installed]) + ]) + + AS_IF([ test -z "$GENHTML" ], [ + AC_MSG_ERROR([Could not find genhtml from the lcov package]) + ]) + + dnl Build the code coverage flags + dnl Define CODE_COVERAGE_LDFLAGS for backwards compatibility + CODE_COVERAGE_CPPFLAGS="-DNDEBUG" + CODE_COVERAGE_CFLAGS="-O0 -g -fprofile-arcs -ftest-coverage" + CODE_COVERAGE_CXXFLAGS="-O0 -g -fprofile-arcs -ftest-coverage" + CODE_COVERAGE_LIBS="-lgcov" + CODE_COVERAGE_LDFLAGS="$CODE_COVERAGE_LIBS" + + AC_SUBST([CODE_COVERAGE_CPPFLAGS]) + AC_SUBST([CODE_COVERAGE_CFLAGS]) + AC_SUBST([CODE_COVERAGE_CXXFLAGS]) + AC_SUBST([CODE_COVERAGE_LIBS]) + AC_SUBST([CODE_COVERAGE_LDFLAGS]) + + [CODE_COVERAGE_RULES_CHECK=' + -$(A''M_V_at)$(MAKE) $(AM_MAKEFLAGS) -k check + $(A''M_V_at)$(MAKE) $(AM_MAKEFLAGS) code-coverage-capture +'] + [CODE_COVERAGE_RULES_CAPTURE=' + $(code_coverage_v_lcov_cap)$(LCOV) $(code_coverage_quiet) $(addprefix --directory ,$(CODE_COVERAGE_DIRECTORY)) --capture --output-file "$(CODE_COVERAGE_OUTPUT_FILE).tmp" --test-name "$(call code_coverage_sanitize,$(PACKAGE_NAME)-$(PACKAGE_VERSION))" --no-checksum --compat-libtool $(CODE_COVERAGE_LCOV_SHOPTS) $(CODE_COVERAGE_LCOV_OPTIONS) + $(code_coverage_v_lcov_ign)$(LCOV) $(code_coverage_quiet) $(addprefix --directory ,$(CODE_COVERAGE_DIRECTORY)) --remove "$(CODE_COVERAGE_OUTPUT_FILE).tmp" "/tmp/*" $(CODE_COVERAGE_IGNORE_PATTERN) --output-file "$(CODE_COVERAGE_OUTPUT_FILE)" $(CODE_COVERAGE_LCOV_SHOPTS) $(CODE_COVERAGE_LCOV_RMOPTS) + -@rm -f $(CODE_COVERAGE_OUTPUT_FILE).tmp + $(code_coverage_v_genhtml)LANG=C $(GENHTML) $(code_coverage_quiet) $(addprefix --prefix ,$(CODE_COVERAGE_DIRECTORY)) --output-directory "$(CODE_COVERAGE_OUTPUT_DIRECTORY)" --title "$(PACKAGE_NAME)-$(PACKAGE_VERSION) Code Coverage" --legend --show-details "$(CODE_COVERAGE_OUTPUT_FILE)" $(CODE_COVERAGE_GENHTML_OPTIONS) + @echo "file://$(abs_builddir)/$(CODE_COVERAGE_OUTPUT_DIRECTORY)/index.html" +'] + [CODE_COVERAGE_RULES_CLEAN=' +clean: code-coverage-clean +distclean: code-coverage-clean +code-coverage-clean: + -$(LCOV) --directory $(top_builddir) -z + -rm -rf $(CODE_COVERAGE_OUTPUT_FILE) $(CODE_COVERAGE_OUTPUT_FILE).tmp $(CODE_COVERAGE_OUTPUT_DIRECTORY) + -find . \( -name "*.gcda" -o -name "*.gcno" -o -name "*.gcov" \) -delete +'] + ], [ + [CODE_COVERAGE_RULES_CHECK=' + @echo "Need to reconfigure with --enable-code-coverage" +'] + CODE_COVERAGE_RULES_CAPTURE="$CODE_COVERAGE_RULES_CHECK" + CODE_COVERAGE_RULES_CLEAN='' + ]) + +[CODE_COVERAGE_RULES=' +# Code coverage +# +# Optional: +# - CODE_COVERAGE_DIRECTORY: Top-level directory for code coverage reporting. +# Multiple directories may be specified, separated by whitespace. +# (Default: $(top_builddir)) +# - CODE_COVERAGE_OUTPUT_FILE: Filename and path for the .info file generated +# by lcov for code coverage. (Default: +# $(PACKAGE_NAME)-$(PACKAGE_VERSION)-coverage.info) +# - CODE_COVERAGE_OUTPUT_DIRECTORY: Directory for generated code coverage +# reports to be created. (Default: +# $(PACKAGE_NAME)-$(PACKAGE_VERSION)-coverage) +# - CODE_COVERAGE_BRANCH_COVERAGE: Set to 1 to enforce branch coverage, +# set to 0 to disable it and leave empty to stay with the default. +# (Default: empty) +# - CODE_COVERAGE_LCOV_SHOPTS_DEFAULT: Extra options shared between both lcov +# instances. (Default: based on $CODE_COVERAGE_BRANCH_COVERAGE) +# - CODE_COVERAGE_LCOV_SHOPTS: Extra options to shared between both lcov +# instances. (Default: $CODE_COVERAGE_LCOV_SHOPTS_DEFAULT) +# - CODE_COVERAGE_LCOV_OPTIONS_GCOVPATH: --gcov-tool pathtogcov +# - CODE_COVERAGE_LCOV_OPTIONS_DEFAULT: Extra options to pass to the +# collecting lcov instance. (Default: $CODE_COVERAGE_LCOV_OPTIONS_GCOVPATH) +# - CODE_COVERAGE_LCOV_OPTIONS: Extra options to pass to the collecting lcov +# instance. (Default: $CODE_COVERAGE_LCOV_OPTIONS_DEFAULT) +# - CODE_COVERAGE_LCOV_RMOPTS_DEFAULT: Extra options to pass to the filtering +# lcov instance. (Default: empty) +# - CODE_COVERAGE_LCOV_RMOPTS: Extra options to pass to the filtering lcov +# instance. (Default: $CODE_COVERAGE_LCOV_RMOPTS_DEFAULT) +# - CODE_COVERAGE_GENHTML_OPTIONS_DEFAULT: Extra options to pass to the +# genhtml instance. (Default: based on $CODE_COVERAGE_BRANCH_COVERAGE) +# - CODE_COVERAGE_GENHTML_OPTIONS: Extra options to pass to the genhtml +# instance. (Default: $CODE_COVERAGE_GENHTML_OPTIONS_DEFAULT) +# - CODE_COVERAGE_IGNORE_PATTERN: Extra glob pattern of files to ignore +# +# The generated report will be titled using the $(PACKAGE_NAME) and +# $(PACKAGE_VERSION). In order to add the current git hash to the title, +# use the git-version-gen script, available online. + +# Optional variables +CODE_COVERAGE_DIRECTORY ?= $(top_builddir) +CODE_COVERAGE_OUTPUT_FILE ?= $(PACKAGE_NAME)-$(PACKAGE_VERSION)-coverage.info +CODE_COVERAGE_OUTPUT_DIRECTORY ?= $(PACKAGE_NAME)-$(PACKAGE_VERSION)-coverage +CODE_COVERAGE_BRANCH_COVERAGE ?= +CODE_COVERAGE_LCOV_SHOPTS_DEFAULT ?= $(if $(CODE_COVERAGE_BRANCH_COVERAGE),\ +--rc lcov_branch_coverage=$(CODE_COVERAGE_BRANCH_COVERAGE)) +CODE_COVERAGE_LCOV_SHOPTS ?= $(CODE_COVERAGE_LCOV_SHOPTS_DEFAULT) +CODE_COVERAGE_LCOV_OPTIONS_GCOVPATH ?= --gcov-tool "$(GCOV)" +CODE_COVERAGE_LCOV_OPTIONS_DEFAULT ?= $(CODE_COVERAGE_LCOV_OPTIONS_GCOVPATH) +CODE_COVERAGE_LCOV_OPTIONS ?= $(CODE_COVERAGE_LCOV_OPTIONS_DEFAULT) +CODE_COVERAGE_LCOV_RMOPTS_DEFAULT ?= +CODE_COVERAGE_LCOV_RMOPTS ?= $(CODE_COVERAGE_LCOV_RMOPTS_DEFAULT) +CODE_COVERAGE_GENHTML_OPTIONS_DEFAULT ?=\ +$(if $(CODE_COVERAGE_BRANCH_COVERAGE),\ +--rc genhtml_branch_coverage=$(CODE_COVERAGE_BRANCH_COVERAGE)) +CODE_COVERAGE_GENHTML_OPTIONS ?= $(CODE_COVERAGE_GENHTML_OPTIONS_DEFAULT) +CODE_COVERAGE_IGNORE_PATTERN ?= + +GITIGNOREFILES ?= +GITIGNOREFILES += $(CODE_COVERAGE_OUTPUT_FILE) $(CODE_COVERAGE_OUTPUT_DIRECTORY) + +code_coverage_v_lcov_cap = $(code_coverage_v_lcov_cap_$(V)) +code_coverage_v_lcov_cap_ = $(code_coverage_v_lcov_cap_$(AM_DEFAULT_VERBOSITY)) +code_coverage_v_lcov_cap_0 = @echo " LCOV --capture"\ + $(CODE_COVERAGE_OUTPUT_FILE); +code_coverage_v_lcov_ign = $(code_coverage_v_lcov_ign_$(V)) +code_coverage_v_lcov_ign_ = $(code_coverage_v_lcov_ign_$(AM_DEFAULT_VERBOSITY)) +code_coverage_v_lcov_ign_0 = @echo " LCOV --remove /tmp/*"\ + $(CODE_COVERAGE_IGNORE_PATTERN); +code_coverage_v_genhtml = $(code_coverage_v_genhtml_$(V)) +code_coverage_v_genhtml_ = $(code_coverage_v_genhtml_$(AM_DEFAULT_VERBOSITY)) +code_coverage_v_genhtml_0 = @echo " GEN " $(CODE_COVERAGE_OUTPUT_DIRECTORY); +code_coverage_quiet = $(code_coverage_quiet_$(V)) +code_coverage_quiet_ = $(code_coverage_quiet_$(AM_DEFAULT_VERBOSITY)) +code_coverage_quiet_0 = --quiet + +# sanitizes the test-name: replaces with underscores: dashes and dots +code_coverage_sanitize = $(subst -,_,$(subst .,_,$(1))) + +# Use recursive makes in order to ignore errors during check +check-code-coverage:'"$CODE_COVERAGE_RULES_CHECK"' + +# Capture code coverage data +code-coverage-capture: code-coverage-capture-hook'"$CODE_COVERAGE_RULES_CAPTURE"' + +# Hook rule executed before code-coverage-capture, overridable by the user +code-coverage-capture-hook: + +'"$CODE_COVERAGE_RULES_CLEAN"' + +A''M_DISTCHECK_CONFIGURE_FLAGS ?= +A''M_DISTCHECK_CONFIGURE_FLAGS += --disable-code-coverage + +.PHONY: check-code-coverage code-coverage-capture code-coverage-capture-hook code-coverage-clean +'] + + AC_SUBST([CODE_COVERAGE_RULES]) + m4_ifdef([_AM_SUBST_NOTMAKE], [_AM_SUBST_NOTMAKE([CODE_COVERAGE_RULES])]) +]) diff --git a/chromium/third_party/harfbuzz-ng/src/m4/ax_cxx_compile_stdcxx.m4 b/chromium/third_party/harfbuzz-ng/src/m4/ax_cxx_compile_stdcxx.m4 new file mode 100644 index 00000000000..5032bba8091 --- /dev/null +++ b/chromium/third_party/harfbuzz-ng/src/m4/ax_cxx_compile_stdcxx.m4 @@ -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 + +]]) diff --git a/chromium/third_party/harfbuzz-ng/src/m4/ax_pthread.m4 b/chromium/third_party/harfbuzz-ng/src/m4/ax_pthread.m4 new file mode 100644 index 00000000000..5fbf9fe0d68 --- /dev/null +++ b/chromium/third_party/harfbuzz-ng/src/m4/ax_pthread.m4 @@ -0,0 +1,485 @@ +# =========================================================================== +# https://www.gnu.org/software/autoconf-archive/ax_pthread.html +# =========================================================================== +# +# SYNOPSIS +# +# AX_PTHREAD([ACTION-IF-FOUND[, ACTION-IF-NOT-FOUND]]) +# +# DESCRIPTION +# +# This macro figures out how to build C programs using POSIX threads. It +# sets the PTHREAD_LIBS output variable to the threads library and linker +# flags, and the PTHREAD_CFLAGS output variable to any special C compiler +# flags that are needed. (The user can also force certain compiler +# flags/libs to be tested by setting these environment variables.) +# +# Also sets PTHREAD_CC to any special C compiler that is needed for +# multi-threaded programs (defaults to the value of CC otherwise). (This +# is necessary on AIX to use the special cc_r compiler alias.) +# +# NOTE: You are assumed to not only compile your program with these flags, +# but also to link with them as well. For example, you might link with +# $PTHREAD_CC $CFLAGS $PTHREAD_CFLAGS $LDFLAGS ... $PTHREAD_LIBS $LIBS +# +# If you are only building threaded programs, you may wish to use these +# variables in your default LIBS, CFLAGS, and CC: +# +# LIBS="$PTHREAD_LIBS $LIBS" +# CFLAGS="$CFLAGS $PTHREAD_CFLAGS" +# CC="$PTHREAD_CC" +# +# In addition, if the PTHREAD_CREATE_JOINABLE thread-attribute constant +# has a nonstandard name, this macro defines PTHREAD_CREATE_JOINABLE to +# that name (e.g. PTHREAD_CREATE_UNDETACHED on AIX). +# +# Also HAVE_PTHREAD_PRIO_INHERIT is defined if pthread is found and the +# PTHREAD_PRIO_INHERIT symbol is defined when compiling with +# PTHREAD_CFLAGS. +# +# ACTION-IF-FOUND is a list of shell commands to run if a threads library +# is found, and ACTION-IF-NOT-FOUND is a list of commands to run it if it +# is not found. If ACTION-IF-FOUND is not specified, the default action +# will define HAVE_PTHREAD. +# +# Please let the authors know if this macro fails on any platform, or if +# you have any other suggestions or comments. This macro was based on work +# by SGJ on autoconf scripts for FFTW (http://www.fftw.org/) (with help +# from M. Frigo), as well as ac_pthread and hb_pthread macros posted by +# Alejandro Forero Cuervo to the autoconf macro repository. We are also +# grateful for the helpful feedback of numerous users. +# +# Updated for Autoconf 2.68 by Daniel Richard G. +# +# LICENSE +# +# Copyright (c) 2008 Steven G. Johnson <stevenj@alum.mit.edu> +# Copyright (c) 2011 Daniel Richard G. <skunk@iSKUNK.ORG> +# +# 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. +# +# 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 <https://www.gnu.org/licenses/>. +# +# As a special exception, the respective Autoconf Macro's copyright owner +# gives unlimited permission to copy, distribute and modify the configure +# scripts that are the output of Autoconf when processing the Macro. You +# need not follow the terms of the GNU General Public License when using +# or distributing such scripts, even though portions of the text of the +# Macro appear in them. The GNU General Public License (GPL) does govern +# all other use of the material that constitutes the Autoconf Macro. +# +# This special exception to the GPL applies to versions of the Autoconf +# Macro released by the Autoconf Archive. When you make and distribute a +# modified version of the Autoconf Macro, you may extend this special +# exception to the GPL to apply to your modified version as well. + +#serial 24 + +AU_ALIAS([ACX_PTHREAD], [AX_PTHREAD]) +AC_DEFUN([AX_PTHREAD], [ +AC_REQUIRE([AC_CANONICAL_HOST]) +AC_REQUIRE([AC_PROG_CC]) +AC_REQUIRE([AC_PROG_SED]) +AC_LANG_PUSH([C]) +ax_pthread_ok=no + +# We used to check for pthread.h first, but this fails if pthread.h +# requires special compiler flags (e.g. on Tru64 or Sequent). +# It gets checked for in the link test anyway. + +# First of all, check if the user has set any of the PTHREAD_LIBS, +# etcetera environment variables, and if threads linking works using +# them: +if test "x$PTHREAD_CFLAGS$PTHREAD_LIBS" != "x"; then + ax_pthread_save_CC="$CC" + ax_pthread_save_CFLAGS="$CFLAGS" + ax_pthread_save_LIBS="$LIBS" + AS_IF([test "x$PTHREAD_CC" != "x"], [CC="$PTHREAD_CC"]) + CFLAGS="$CFLAGS $PTHREAD_CFLAGS" + LIBS="$PTHREAD_LIBS $LIBS" + AC_MSG_CHECKING([for pthread_join using $CC $PTHREAD_CFLAGS $PTHREAD_LIBS]) + AC_LINK_IFELSE([AC_LANG_CALL([], [pthread_join])], [ax_pthread_ok=yes]) + AC_MSG_RESULT([$ax_pthread_ok]) + if test "x$ax_pthread_ok" = "xno"; then + PTHREAD_LIBS="" + PTHREAD_CFLAGS="" + fi + CC="$ax_pthread_save_CC" + CFLAGS="$ax_pthread_save_CFLAGS" + LIBS="$ax_pthread_save_LIBS" +fi + +# We must check for the threads library under a number of different +# names; the ordering is very important because some systems +# (e.g. DEC) have both -lpthread and -lpthreads, where one of the +# libraries is broken (non-POSIX). + +# Create a list of thread flags to try. Items starting with a "-" are +# C compiler flags, and other items are library names, except for "none" +# which indicates that we try without any flags at all, and "pthread-config" +# which is a program returning the flags for the Pth emulation library. + +ax_pthread_flags="pthreads none -Kthread -pthread -pthreads -mthreads pthread --thread-safe -mt pthread-config" + +# The ordering *is* (sometimes) important. Some notes on the +# individual items follow: + +# pthreads: AIX (must check this before -lpthread) +# none: in case threads are in libc; should be tried before -Kthread and +# other compiler flags to prevent continual compiler warnings +# -Kthread: Sequent (threads in libc, but -Kthread needed for pthread.h) +# -pthread: Linux/gcc (kernel threads), BSD/gcc (userland threads), Tru64 +# (Note: HP C rejects this with "bad form for `-t' option") +# -pthreads: Solaris/gcc (Note: HP C also rejects) +# -mt: Sun Workshop C (may only link SunOS threads [-lthread], but it +# doesn't hurt to check since this sometimes defines pthreads and +# -D_REENTRANT too), HP C (must be checked before -lpthread, which +# is present but should not be used directly; and before -mthreads, +# because the compiler interprets this as "-mt" + "-hreads") +# -mthreads: Mingw32/gcc, Lynx/gcc +# pthread: Linux, etcetera +# --thread-safe: KAI C++ +# pthread-config: use pthread-config program (for GNU Pth library) + +case $host_os in + + freebsd*) + + # -kthread: FreeBSD kernel threads (preferred to -pthread since SMP-able) + # lthread: LinuxThreads port on FreeBSD (also preferred to -pthread) + + ax_pthread_flags="-kthread lthread $ax_pthread_flags" + ;; + + hpux*) + + # From the cc(1) man page: "[-mt] Sets various -D flags to enable + # multi-threading and also sets -lpthread." + + ax_pthread_flags="-mt -pthread pthread $ax_pthread_flags" + ;; + + openedition*) + + # IBM z/OS requires a feature-test macro to be defined in order to + # enable POSIX threads at all, so give the user a hint if this is + # not set. (We don't define these ourselves, as they can affect + # other portions of the system API in unpredictable ways.) + + AC_EGREP_CPP([AX_PTHREAD_ZOS_MISSING], + [ +# if !defined(_OPEN_THREADS) && !defined(_UNIX03_THREADS) + AX_PTHREAD_ZOS_MISSING +# endif + ], + [AC_MSG_WARN([IBM z/OS requires -D_OPEN_THREADS or -D_UNIX03_THREADS to enable pthreads support.])]) + ;; + + solaris*) + + # On Solaris (at least, for some versions), libc contains stubbed + # (non-functional) versions of the pthreads routines, so link-based + # tests will erroneously succeed. (N.B.: The stubs are missing + # pthread_cleanup_push, or rather a function called by this macro, + # so we could check for that, but who knows whether they'll stub + # that too in a future libc.) So we'll check first for the + # standard Solaris way of linking pthreads (-mt -lpthread). + + ax_pthread_flags="-mt,pthread pthread $ax_pthread_flags" + ;; +esac + +# GCC generally uses -pthread, or -pthreads on some platforms (e.g. SPARC) + +AS_IF([test "x$GCC" = "xyes"], + [ax_pthread_flags="-pthread -pthreads $ax_pthread_flags"]) + +# The presence of a feature test macro requesting re-entrant function +# definitions is, on some systems, a strong hint that pthreads support is +# correctly enabled + +case $host_os in + darwin* | hpux* | linux* | osf* | solaris*) + ax_pthread_check_macro="_REENTRANT" + ;; + + aix*) + ax_pthread_check_macro="_THREAD_SAFE" + ;; + + *) + ax_pthread_check_macro="--" + ;; +esac +AS_IF([test "x$ax_pthread_check_macro" = "x--"], + [ax_pthread_check_cond=0], + [ax_pthread_check_cond="!defined($ax_pthread_check_macro)"]) + +# Are we compiling with Clang? + +AC_CACHE_CHECK([whether $CC is Clang], + [ax_cv_PTHREAD_CLANG], + [ax_cv_PTHREAD_CLANG=no + # Note that Autoconf sets GCC=yes for Clang as well as GCC + if test "x$GCC" = "xyes"; then + AC_EGREP_CPP([AX_PTHREAD_CC_IS_CLANG], + [/* Note: Clang 2.7 lacks __clang_[a-z]+__ */ +# if defined(__clang__) && defined(__llvm__) + AX_PTHREAD_CC_IS_CLANG +# endif + ], + [ax_cv_PTHREAD_CLANG=yes]) + fi + ]) +ax_pthread_clang="$ax_cv_PTHREAD_CLANG" + +ax_pthread_clang_warning=no + +# Clang needs special handling, because older versions handle the -pthread +# option in a rather... idiosyncratic way + +if test "x$ax_pthread_clang" = "xyes"; then + + # Clang takes -pthread; it has never supported any other flag + + # (Note 1: This will need to be revisited if a system that Clang + # supports has POSIX threads in a separate library. This tends not + # to be the way of modern systems, but it's conceivable.) + + # (Note 2: On some systems, notably Darwin, -pthread is not needed + # to get POSIX threads support; the API is always present and + # active. We could reasonably leave PTHREAD_CFLAGS empty. But + # -pthread does define _REENTRANT, and while the Darwin headers + # ignore this macro, third-party headers might not.) + + PTHREAD_CFLAGS="-pthread" + PTHREAD_LIBS= + + ax_pthread_ok=yes + + # However, older versions of Clang make a point of warning the user + # that, in an invocation where only linking and no compilation is + # taking place, the -pthread option has no effect ("argument unused + # during compilation"). They expect -pthread to be passed in only + # when source code is being compiled. + # + # Problem is, this is at odds with the way Automake and most other + # C build frameworks function, which is that the same flags used in + # compilation (CFLAGS) are also used in linking. Many systems + # supported by AX_PTHREAD require exactly this for POSIX threads + # support, and in fact it is often not straightforward to specify a + # flag that is used only in the compilation phase and not in + # linking. Such a scenario is extremely rare in practice. + # + # Even though use of the -pthread flag in linking would only print + # a warning, this can be a nuisance for well-run software projects + # that build with -Werror. So if the active version of Clang has + # this misfeature, we search for an option to squash it. + + AC_CACHE_CHECK([whether Clang needs flag to prevent "argument unused" warning when linking with -pthread], + [ax_cv_PTHREAD_CLANG_NO_WARN_FLAG], + [ax_cv_PTHREAD_CLANG_NO_WARN_FLAG=unknown + # Create an alternate version of $ac_link that compiles and + # links in two steps (.c -> .o, .o -> exe) instead of one + # (.c -> exe), because the warning occurs only in the second + # step + ax_pthread_save_ac_link="$ac_link" + ax_pthread_sed='s/conftest\.\$ac_ext/conftest.$ac_objext/g' + ax_pthread_link_step=`$as_echo "$ac_link" | sed "$ax_pthread_sed"` + ax_pthread_2step_ac_link="($ac_compile) && (echo ==== >&5) && ($ax_pthread_link_step)" + ax_pthread_save_CFLAGS="$CFLAGS" + for ax_pthread_try in '' -Qunused-arguments -Wno-unused-command-line-argument unknown; do + AS_IF([test "x$ax_pthread_try" = "xunknown"], [break]) + CFLAGS="-Werror -Wunknown-warning-option $ax_pthread_try -pthread $ax_pthread_save_CFLAGS" + ac_link="$ax_pthread_save_ac_link" + AC_LINK_IFELSE([AC_LANG_SOURCE([[int main(void){return 0;}]])], + [ac_link="$ax_pthread_2step_ac_link" + AC_LINK_IFELSE([AC_LANG_SOURCE([[int main(void){return 0;}]])], + [break]) + ]) + done + ac_link="$ax_pthread_save_ac_link" + CFLAGS="$ax_pthread_save_CFLAGS" + AS_IF([test "x$ax_pthread_try" = "x"], [ax_pthread_try=no]) + ax_cv_PTHREAD_CLANG_NO_WARN_FLAG="$ax_pthread_try" + ]) + + case "$ax_cv_PTHREAD_CLANG_NO_WARN_FLAG" in + no | unknown) ;; + *) PTHREAD_CFLAGS="$ax_cv_PTHREAD_CLANG_NO_WARN_FLAG $PTHREAD_CFLAGS" ;; + esac + +fi # $ax_pthread_clang = yes + +if test "x$ax_pthread_ok" = "xno"; then +for ax_pthread_try_flag in $ax_pthread_flags; do + + case $ax_pthread_try_flag in + none) + AC_MSG_CHECKING([whether pthreads work without any flags]) + ;; + + -mt,pthread) + AC_MSG_CHECKING([whether pthreads work with -mt -lpthread]) + PTHREAD_CFLAGS="-mt" + PTHREAD_LIBS="-lpthread" + ;; + + -*) + AC_MSG_CHECKING([whether pthreads work with $ax_pthread_try_flag]) + PTHREAD_CFLAGS="$ax_pthread_try_flag" + ;; + + pthread-config) + AC_CHECK_PROG([ax_pthread_config], [pthread-config], [yes], [no]) + AS_IF([test "x$ax_pthread_config" = "xno"], [continue]) + PTHREAD_CFLAGS="`pthread-config --cflags`" + PTHREAD_LIBS="`pthread-config --ldflags` `pthread-config --libs`" + ;; + + *) + AC_MSG_CHECKING([for the pthreads library -l$ax_pthread_try_flag]) + PTHREAD_LIBS="-l$ax_pthread_try_flag" + ;; + esac + + ax_pthread_save_CFLAGS="$CFLAGS" + ax_pthread_save_LIBS="$LIBS" + CFLAGS="$CFLAGS $PTHREAD_CFLAGS" + LIBS="$PTHREAD_LIBS $LIBS" + + # Check for various functions. We must include pthread.h, + # since some functions may be macros. (On the Sequent, we + # need a special flag -Kthread to make this header compile.) + # We check for pthread_join because it is in -lpthread on IRIX + # while pthread_create is in libc. We check for pthread_attr_init + # due to DEC craziness with -lpthreads. We check for + # pthread_cleanup_push because it is one of the few pthread + # functions on Solaris that doesn't have a non-functional libc stub. + # We try pthread_create on general principles. + + AC_LINK_IFELSE([AC_LANG_PROGRAM([#include <pthread.h> +# if $ax_pthread_check_cond +# error "$ax_pthread_check_macro must be defined" +# endif + static void routine(void *a) { a = 0; } + static void *start_routine(void *a) { return a; }], + [pthread_t th; pthread_attr_t attr; + pthread_create(&th, 0, start_routine, 0); + pthread_join(th, 0); + pthread_attr_init(&attr); + pthread_cleanup_push(routine, 0); + pthread_cleanup_pop(0) /* ; */])], + [ax_pthread_ok=yes], + []) + + CFLAGS="$ax_pthread_save_CFLAGS" + LIBS="$ax_pthread_save_LIBS" + + AC_MSG_RESULT([$ax_pthread_ok]) + AS_IF([test "x$ax_pthread_ok" = "xyes"], [break]) + + PTHREAD_LIBS="" + PTHREAD_CFLAGS="" +done +fi + +# Various other checks: +if test "x$ax_pthread_ok" = "xyes"; then + ax_pthread_save_CFLAGS="$CFLAGS" + ax_pthread_save_LIBS="$LIBS" + CFLAGS="$CFLAGS $PTHREAD_CFLAGS" + LIBS="$PTHREAD_LIBS $LIBS" + + # Detect AIX lossage: JOINABLE attribute is called UNDETACHED. + AC_CACHE_CHECK([for joinable pthread attribute], + [ax_cv_PTHREAD_JOINABLE_ATTR], + [ax_cv_PTHREAD_JOINABLE_ATTR=unknown + for ax_pthread_attr in PTHREAD_CREATE_JOINABLE PTHREAD_CREATE_UNDETACHED; do + AC_LINK_IFELSE([AC_LANG_PROGRAM([#include <pthread.h>], + [int attr = $ax_pthread_attr; return attr /* ; */])], + [ax_cv_PTHREAD_JOINABLE_ATTR=$ax_pthread_attr; break], + []) + done + ]) + AS_IF([test "x$ax_cv_PTHREAD_JOINABLE_ATTR" != "xunknown" && \ + test "x$ax_cv_PTHREAD_JOINABLE_ATTR" != "xPTHREAD_CREATE_JOINABLE" && \ + test "x$ax_pthread_joinable_attr_defined" != "xyes"], + [AC_DEFINE_UNQUOTED([PTHREAD_CREATE_JOINABLE], + [$ax_cv_PTHREAD_JOINABLE_ATTR], + [Define to necessary symbol if this constant + uses a non-standard name on your system.]) + ax_pthread_joinable_attr_defined=yes + ]) + + AC_CACHE_CHECK([whether more special flags are required for pthreads], + [ax_cv_PTHREAD_SPECIAL_FLAGS], + [ax_cv_PTHREAD_SPECIAL_FLAGS=no + case $host_os in + solaris*) + ax_cv_PTHREAD_SPECIAL_FLAGS="-D_POSIX_PTHREAD_SEMANTICS" + ;; + esac + ]) + AS_IF([test "x$ax_cv_PTHREAD_SPECIAL_FLAGS" != "xno" && \ + test "x$ax_pthread_special_flags_added" != "xyes"], + [PTHREAD_CFLAGS="$ax_cv_PTHREAD_SPECIAL_FLAGS $PTHREAD_CFLAGS" + ax_pthread_special_flags_added=yes]) + + AC_CACHE_CHECK([for PTHREAD_PRIO_INHERIT], + [ax_cv_PTHREAD_PRIO_INHERIT], + [AC_LINK_IFELSE([AC_LANG_PROGRAM([[#include <pthread.h>]], + [[int i = PTHREAD_PRIO_INHERIT;]])], + [ax_cv_PTHREAD_PRIO_INHERIT=yes], + [ax_cv_PTHREAD_PRIO_INHERIT=no]) + ]) + AS_IF([test "x$ax_cv_PTHREAD_PRIO_INHERIT" = "xyes" && \ + test "x$ax_pthread_prio_inherit_defined" != "xyes"], + [AC_DEFINE([HAVE_PTHREAD_PRIO_INHERIT], [1], [Have PTHREAD_PRIO_INHERIT.]) + ax_pthread_prio_inherit_defined=yes + ]) + + CFLAGS="$ax_pthread_save_CFLAGS" + LIBS="$ax_pthread_save_LIBS" + + # More AIX lossage: compile with *_r variant + if test "x$GCC" != "xyes"; then + case $host_os in + aix*) + AS_CASE(["x/$CC"], + [x*/c89|x*/c89_128|x*/c99|x*/c99_128|x*/cc|x*/cc128|x*/xlc|x*/xlc_v6|x*/xlc128|x*/xlc128_v6], + [#handle absolute path differently from PATH based program lookup + AS_CASE(["x$CC"], + [x/*], + [AS_IF([AS_EXECUTABLE_P([${CC}_r])],[PTHREAD_CC="${CC}_r"])], + [AC_CHECK_PROGS([PTHREAD_CC],[${CC}_r],[$CC])])]) + ;; + esac + fi +fi + +test -n "$PTHREAD_CC" || PTHREAD_CC="$CC" + +AC_SUBST([PTHREAD_LIBS]) +AC_SUBST([PTHREAD_CFLAGS]) +AC_SUBST([PTHREAD_CC]) + +# Finally, execute ACTION-IF-FOUND/ACTION-IF-NOT-FOUND: +if test "x$ax_pthread_ok" = "xyes"; then + ifelse([$1],,[AC_DEFINE([HAVE_PTHREAD],[1],[Define if you have POSIX threads libraries and header files.])],[$1]) + : +else + ax_pthread_ok=no + $2 +fi +AC_LANG_POP +])dnl AX_PTHREAD diff --git a/chromium/third_party/harfbuzz-ng/src/m4/pkg.m4 b/chromium/third_party/harfbuzz-ng/src/m4/pkg.m4 new file mode 100644 index 00000000000..0048a3fa054 --- /dev/null +++ b/chromium/third_party/harfbuzz-ng/src/m4/pkg.m4 @@ -0,0 +1,157 @@ +# pkg.m4 - Macros to locate and utilise pkg-config. -*- Autoconf -*- +# +# Copyright © 2004 Scott James Remnant <scott@netsplit.com>. +# +# 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 2 of the License, or +# (at your option) any later version. +# +# 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, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +# +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that program. + +# PKG_PROG_PKG_CONFIG([MIN-VERSION]) +# ---------------------------------- +AC_DEFUN([PKG_PROG_PKG_CONFIG], +[m4_pattern_forbid([^_?PKG_[A-Z_]+$]) +m4_pattern_allow([^PKG_CONFIG(_PATH)?$]) +AC_ARG_VAR([PKG_CONFIG], [path to pkg-config utility])dnl +if test "x$ac_cv_env_PKG_CONFIG_set" != "xset"; then + AC_PATH_TOOL([PKG_CONFIG], [pkg-config]) +fi +if test -n "$PKG_CONFIG"; then + _pkg_min_version=m4_default([$1], [0.9.0]) + AC_MSG_CHECKING([pkg-config is at least version $_pkg_min_version]) + if $PKG_CONFIG --atleast-pkgconfig-version $_pkg_min_version; then + AC_MSG_RESULT([yes]) + else + AC_MSG_RESULT([no]) + PKG_CONFIG="" + fi + +fi[]dnl +])# PKG_PROG_PKG_CONFIG + +# PKG_CHECK_EXISTS(MODULES, [ACTION-IF-FOUND], [ACTION-IF-NOT-FOUND]) +# +# Check to see whether a particular set of modules exists. Similar +# to PKG_CHECK_MODULES(), but does not set variables or print errors. +# +# +# Similar to PKG_CHECK_MODULES, make sure that the first instance of +# this or PKG_CHECK_MODULES is called, or make sure to call +# PKG_CHECK_EXISTS manually +# -------------------------------------------------------------- +AC_DEFUN([PKG_CHECK_EXISTS], +[AC_REQUIRE([PKG_PROG_PKG_CONFIG])dnl +if test -n "$PKG_CONFIG" && \ + AC_RUN_LOG([$PKG_CONFIG --exists --print-errors "$1"]); then + m4_ifval([$2], [$2], [:]) +m4_ifvaln([$3], [else + $3])dnl +fi]) + + +# _PKG_CONFIG([VARIABLE], [COMMAND], [MODULES]) +# --------------------------------------------- +m4_define([_PKG_CONFIG], +[if test -n "$PKG_CONFIG"; then + if test -n "$$1"; then + pkg_cv_[]$1="$$1" + else + PKG_CHECK_EXISTS([$3], + [pkg_cv_[]$1=`$PKG_CONFIG --[]$2 "$3" 2>/dev/null`], + [pkg_failed=yes]) + fi +else + pkg_failed=untried +fi[]dnl +])# _PKG_CONFIG + +# _PKG_SHORT_ERRORS_SUPPORTED +# ----------------------------- +AC_DEFUN([_PKG_SHORT_ERRORS_SUPPORTED], +[AC_REQUIRE([PKG_PROG_PKG_CONFIG]) +if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then + _pkg_short_errors_supported=yes +else + _pkg_short_errors_supported=no +fi[]dnl +])# _PKG_SHORT_ERRORS_SUPPORTED + + +# PKG_CHECK_MODULES(VARIABLE-PREFIX, MODULES, [ACTION-IF-FOUND], +# [ACTION-IF-NOT-FOUND]) +# +# +# Note that if there is a possibility the first call to +# PKG_CHECK_MODULES might not happen, you should be sure to include an +# explicit call to PKG_PROG_PKG_CONFIG in your configure.ac +# +# +# -------------------------------------------------------------- +AC_DEFUN([PKG_CHECK_MODULES], +[AC_REQUIRE([PKG_PROG_PKG_CONFIG])dnl +AC_ARG_VAR([$1][_CFLAGS], [C compiler flags for $1, overriding pkg-config])dnl +AC_ARG_VAR([$1][_LIBS], [linker flags for $1, overriding pkg-config])dnl + +pkg_failed=no +AC_MSG_CHECKING([for $1]) + +_PKG_CONFIG([$1][_CFLAGS], [cflags], [$2]) +_PKG_CONFIG([$1][_LIBS], [libs], [$2]) + +m4_define([_PKG_TEXT], [Alternatively, you may set the environment variables $1[]_CFLAGS +and $1[]_LIBS to avoid the need to call pkg-config. +See the pkg-config man page for more details.]) + +if test $pkg_failed = yes; then + _PKG_SHORT_ERRORS_SUPPORTED + if test $_pkg_short_errors_supported = yes; then + $1[]_PKG_ERRORS=`$PKG_CONFIG --short-errors --errors-to-stdout --print-errors "$2"` + else + $1[]_PKG_ERRORS=`$PKG_CONFIG --errors-to-stdout --print-errors "$2"` + fi + # Put the nasty error message in config.log where it belongs + echo "$$1[]_PKG_ERRORS" >&AS_MESSAGE_LOG_FD + + ifelse([$4], , [AC_MSG_ERROR(dnl +[Package requirements ($2) were not met: + +$$1_PKG_ERRORS + +Consider adjusting the PKG_CONFIG_PATH environment variable if you +installed software in a non-standard prefix. + +_PKG_TEXT +])], + [AC_MSG_RESULT([no]) + $4]) +elif test $pkg_failed = untried; then + ifelse([$4], , [AC_MSG_FAILURE(dnl +[The pkg-config script could not be found or is too old. Make sure it +is in your PATH or set the PKG_CONFIG environment variable to the full +path to pkg-config. + +_PKG_TEXT + +To get pkg-config, see <http://pkg-config.freedesktop.org/>.])], + [$4]) +else + $1[]_CFLAGS=$pkg_cv_[]$1[]_CFLAGS + $1[]_LIBS=$pkg_cv_[]$1[]_LIBS + AC_MSG_RESULT([yes]) + ifelse([$3], , :, [$3]) +fi[]dnl +])# PKG_CHECK_MODULES diff --git a/chromium/third_party/harfbuzz-ng/src/mingw32.sh b/chromium/third_party/harfbuzz-ng/src/mingw32.sh new file mode 100755 index 00000000000..67744051c7f --- /dev/null +++ b/chromium/third_party/harfbuzz-ng/src/mingw32.sh @@ -0,0 +1,22 @@ +#!/bin/bash + +target=i686-w64-mingw32 + +unset CC +unset CXX +unset CPP +unset LD +unset LDFLAGS +unset CFLAGS +unset CXXFLAGS +unset PKG_CONFIG_PATH + +# Removed -static from the following +export CFLAGS="-static-libgcc" +export CXXFLAGS="-static-libgcc -static-libstdc++" +export CPPFLAGS="-I$HOME/.local/$target/include -O2" +export LDFLAGS=-L$HOME/.local/$target/lib +export PKG_CONFIG_LIBDIR=$HOME/.local/$target/lib/pkgconfig +export PATH=$HOME/.local/$target/bin:$PATH + +../configure --build=`../config.guess` --host=$target --prefix=$HOME/.local/$target "$@" diff --git a/chromium/third_party/harfbuzz-ng/src/mingw64.sh b/chromium/third_party/harfbuzz-ng/src/mingw64.sh new file mode 100755 index 00000000000..49a143179fe --- /dev/null +++ b/chromium/third_party/harfbuzz-ng/src/mingw64.sh @@ -0,0 +1,22 @@ +#!/bin/bash + +target=x86_64-w64-mingw32 + +unset CC +unset CXX +unset CPP +unset LD +unset LDFLAGS +unset CFLAGS +unset CXXFLAGS +unset PKG_CONFIG_PATH + +# Removed -static from the following +export CFLAGS="-static-libgcc" +export CXXFLAGS="-static-libgcc -static-libstdc++" +export CPPFLAGS="-I$HOME/.local/$target/include -O2" +export LDFLAGS=-L$HOME/.local/$target/lib +export PKG_CONFIG_LIBDIR=$HOME/.local/$target/lib/pkgconfig +export PATH=$HOME/.local/$target/bin:$PATH + +../configure --build=`../config.guess` --host=$target --prefix=$HOME/.local/$target "$@" diff --git a/chromium/third_party/harfbuzz-ng/src/replace-enum-strings.cmake b/chromium/third_party/harfbuzz-ng/src/replace-enum-strings.cmake new file mode 100644 index 00000000000..171667ccf74 --- /dev/null +++ b/chromium/third_party/harfbuzz-ng/src/replace-enum-strings.cmake @@ -0,0 +1,21 @@ +# CMake script to replace items +# in sources generated by glib-mkenums + +FILE(READ ${ENUM_INPUT_SRC} enum_in) + +STRING(REPLACE + "_t_get_type" + "_get_type" + enum_out_tmp + "${enum_in}" + ) + +STRING(REPLACE + "_T (" + " (" + enum_out + "${enum_out_tmp}" + ) + +FILE(WRITE ${ENUM_OUTPUT_SRC} "${enum_out}") +FILE(REMOVE ${ENUM_INPUT_SRC})
\ No newline at end of file diff --git a/chromium/third_party/harfbuzz-ng/src/src/Makefile.am b/chromium/third_party/harfbuzz-ng/src/src/Makefile.am new file mode 100644 index 00000000000..a81f1125353 --- /dev/null +++ b/chromium/third_party/harfbuzz-ng/src/src/Makefile.am @@ -0,0 +1,454 @@ +# Process this file with automake to produce Makefile.in + +NULL = +SUBDIRS = +DIST_SUBDIRS = +BUILT_SOURCES = +EXTRA_DIST = +CLEANFILES = +DISTCLEANFILES = +MAINTAINERCLEANFILES = +DISTCHECK_CONFIGURE_FLAGS = --enable-introspection +TESTS = +check_PROGRAMS = + +# The following warning options are useful for debugging: -Wpadded +#AM_CXXFLAGS = + +# Convenience targets: +lib: $(BUILT_SOURCES) libharfbuzz.la libharfbuzz-subset.la +fuzzing: $(BUILT_SOURCES) libharfbuzz-fuzzing.la libharfbuzz-subset-fuzzing.la + +lib_LTLIBRARIES = libharfbuzz.la + +include Makefile.sources + +HBCFLAGS = +HBLIBS = +HBNONPCLIBS = +HBDEPS = +HBSOURCES = $(HB_BASE_sources) +HBSOURCES += $(HB_BASE_RAGEL_GENERATED_sources) +HBHEADERS = $(HB_BASE_headers) + +if WITH_LIBSTDCXX +HBNOLIBCXXCFLAGS = +else +# Make sure we don't link to libstdc++ +# No threadsafe statics in C++ as we do it ourselves +HBCFLAGS += -fno-exceptions +HBNOLIBCXXFLAGS = -fno-threadsafe-statics -fno-rtti +endif + +if HAVE_OT +HBSOURCES += $(HB_OT_sources) +HBSOURCES += $(HB_OT_RAGEL_GENERATED_sources) +HBHEADERS += $(HB_OT_headers) +endif + +if HAVE_FALLBACK +HBSOURCES += $(HB_FALLBACK_sources) +endif + +if HAVE_PTHREAD +HBCFLAGS += $(PTHREAD_CFLAGS) +HBNONPCLIBS += $(PTHREAD_LIBS) +endif + +if HAVE_GLIB +HBCFLAGS += $(GLIB_CFLAGS) +HBLIBS += $(GLIB_LIBS) +HBDEPS += $(GLIB_DEPS) +HBSOURCES += $(HB_GLIB_sources) +HBHEADERS += $(HB_GLIB_headers) +endif + +if HAVE_FREETYPE +HBCFLAGS += $(FREETYPE_CFLAGS) +HBLIBS += $(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) +HBSOURCES += $(HB_FT_sources) +HBHEADERS += $(HB_FT_headers) +endif + +if HAVE_GRAPHITE2 +HBCFLAGS += $(GRAPHITE2_CFLAGS) +HBLIBS += $(GRAPHITE2_LIBS) +HBDEPS += $(GRAPHITE2_DEPS) +HBSOURCES += $(HB_GRAPHITE2_sources) +HBHEADERS += $(HB_GRAPHITE2_headers) +endif + +if HAVE_UNISCRIBE +HBCFLAGS += $(UNISCRIBE_CFLAGS) +HBNONPCLIBS += $(UNISCRIBE_LIBS) +HBSOURCES += $(HB_UNISCRIBE_sources) +HBHEADERS += $(HB_UNISCRIBE_headers) +endif + +if HAVE_DIRECTWRITE +HBCFLAGS += $(DIRECTWRITE_CXXFLAGS) +HBNONPCLIBS += $(DIRECTWRITE_LIBS) +HBSOURCES += $(HB_DIRECTWRITE_sources) +HBHEADERS += $(HB_DIRECTWRITE_headers) +endif + +if HAVE_CORETEXT +HBCFLAGS += $(CORETEXT_CFLAGS) +HBNONPCLIBS += $(CORETEXT_LIBS) +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 + + +# Put the library together + +HBLIBS += $(HBNONPCLIBS) + +if OS_WIN32 +export_symbols = -export-symbols harfbuzz.def +harfbuzz_def_dependency = harfbuzz.def +export_symbols_subset = -export-symbols harfbuzz-subset.def +harfbuzz_subset_def_dependency = harfbuzz-subset.def +export_symbols_icu = -export-symbols harfbuzz-icu.def +harfbuzz_icu_def_dependency = harfbuzz-icu.def +export_symbols_gobject = -export-symbols harfbuzz-gobject.def +harfbuzz_gobject_def_dependency = harfbuzz-gobject.def +chosen_linker = $(CXXLINK) +else +if WITH_LIBSTDCXX +chosen_linker = $(CXXLINK) +else +if HAVE_GCC +# Use a C linker for GCC, not C++; Don't link to libstdc++ +chosen_linker = $(LINK) +else +chosen_linker = $(CXXLINK) +endif +endif +endif + +@CODE_COVERAGE_RULES@ + +base_link_flags = $(AM_LDFLAGS) -lm -version-info $(HB_LIBTOOL_VERSION_INFO) -no-undefined +libharfbuzz_la_LINK = $(chosen_linker) $(libharfbuzz_la_LDFLAGS) $(CODE_COVERAGE_LDFLAGS) +libharfbuzz_la_SOURCES = $(HBSOURCES) $(HBHEADERS) +libharfbuzz_la_CPPFLAGS = $(HBCFLAGS) $(HBNOLIBCXXFLAGS) $(CODE_COVERAGE_CFLAGS) +libharfbuzz_la_LDFLAGS = $(base_link_flags) $(export_symbols) +libharfbuzz_la_LIBADD = $(HBLIBS) +EXTRA_libharfbuzz_la_DEPENDENCIES = $(harfbuzz_def_dependency) +pkginclude_HEADERS = $(HBHEADERS) +nodist_pkginclude_HEADERS = +pkgconfigdir = $(libdir)/pkgconfig +pkgconfig_DATA = harfbuzz.pc +cmakedir = $(libdir)/cmake/harfbuzz +cmake_DATA = harfbuzz-config.cmake +EXTRA_DIST += harfbuzz.pc.in harfbuzz-config.cmake.in + +lib_LTLIBRARIES += libharfbuzz-subset.la +libharfbuzz_subset_la_SOURCES = $(HB_SUBSET_sources) +libharfbuzz_subset_la_CPPFLAGS = $(HBCFLAGS) +libharfbuzz_subset_la_LDFLAGS = $(base_link_flags) $(export_symbols_subset) +libharfbuzz_subset_la_LIBADD = libharfbuzz.la +EXTRA_libharfbuzz_subset_la_DEPENDENCIES = $(harfbuzz_subset_def_dependency) +pkginclude_HEADERS += $(HB_SUBSET_headers) +pkgconfig_DATA += harfbuzz-subset.pc +EXTRA_DIST += harfbuzz-subset.pc.in + +FUZZING_CPPFLAGS = \ + -DHB_NDEBUG \ + -DHB_MAX_NESTING_LEVEL=3 \ + -DHB_SANITIZE_MAX_EDITS=3 \ + -DHB_SANITIZE_MAX_OPS_FACTOR=3 \ + -DHB_SANITIZE_MAX_OPS_MIN=128 \ + -DHB_BUFFER_MAX_LEN_FACTOR=3 \ + -DHB_BUFFER_MAX_LEN_MIN=8 \ + -DHB_BUFFER_MAX_LEN_DEFAULT=128 \ + -DHB_BUFFER_MAX_OPS_FACTOR=8 \ + -DHB_BUFFER_MAX_OPS_MIN=64 \ + -DHB_BUFFER_MAX_OPS_DEFAULT=1024 \ + $(NULL) +EXTRA_LTLIBRARIES = libharfbuzz-fuzzing.la libharfbuzz-subset-fuzzing.la + +libharfbuzz_fuzzing_la_LINK = $(chosen_linker) $(libharfbuzz_fuzzing_la_LDFLAGS) +libharfbuzz_fuzzing_la_SOURCES = $(libharfbuzz_la_SOURCES) +libharfbuzz_fuzzing_la_CPPFLAGS = $(HBCFLAGS) $(FUZZING_CPPFLAGS) +libharfbuzz_fuzzing_la_LDFLAGS = $(AM_LDFLAGS) +libharfbuzz_fuzzing_la_LIBADD = $(libharfbuzz_la_LIBADD) +EXTRA_libharfbuzz_fuzzing_la_DEPENDENCIES = $(EXTRA_libharfbuzz_la_DEPENDENCIES) +CLEANFILES += libharfbuzz-fuzzing.la + +libharfbuzz_subset_fuzzing_la_LINK = $(chosen_linker) $(libharfbuzz_subset_fuzzing_la_LDFLAGS) +libharfbuzz_subset_fuzzing_la_SOURCES = $(libharfbuzz_subset_la_SOURCES) +libharfbuzz_subset_fuzzing_la_CPPFLAGS = $(HBCFLAGS) $(FUZZING_CPPFLAGS) +libharfbuzz_subset_fuzzing_la_LDFLAGS = $(AM_LDFLAGS) +libharfbuzz_subset_fuzzing_la_LIBADD = $(libharfbuzz_subset_la_LIBADD) +EXTRA_libharfbuzz_subset_fuzzing_la_DEPENDENCIES = $(EXTRA_libharfbuzz_subset_la_DEPENDENCIES) +CLEANFILES += libharfbuzz-subset-fuzzing.la + +if HAVE_ICU +if HAVE_ICU_BUILTIN +HBCFLAGS += $(ICU_CFLAGS) +HBLIBS += $(ICU_LIBS) +HBSOURCES += $(HB_ICU_sources) +HBHEADERS += $(HB_ICU_headers) +else +lib_LTLIBRARIES += libharfbuzz-icu.la +libharfbuzz_icu_la_SOURCES = $(HB_ICU_sources) +libharfbuzz_icu_la_CPPFLAGS = $(HBCFLAGS) $(ICU_CFLAGS) +libharfbuzz_icu_la_LDFLAGS = $(base_link_flags) $(export_symbols_icu) +libharfbuzz_icu_la_LIBADD = $(ICU_LIBS) libharfbuzz.la +EXTRA_libharfbuzz_icu_la_DEPENDENCIES = $(harfbuzz_icu_def_dependency) +pkginclude_HEADERS += $(HB_ICU_headers) +pkgconfig_DATA += harfbuzz-icu.pc +endif +endif +EXTRA_DIST += harfbuzz-icu.pc.in + +if HAVE_GOBJECT +lib_LTLIBRARIES += libharfbuzz-gobject.la +libharfbuzz_gobject_la_LINK = $(chosen_linker) $(libharfbuzz_gobject_la_LDFLAGS) +libharfbuzz_gobject_la_SOURCES = $(HB_GOBJECT_DIST_sources) +nodist_libharfbuzz_gobject_la_SOURCES = $(HB_GOBJECT_NODIST_sources) +libharfbuzz_gobject_la_CPPFLAGS = $(HBCFLAGS) $(HBNOLIBCXXFLAGS) $(GOBJECT_CFLAGS) +libharfbuzz_gobject_la_LDFLAGS = $(base_link_flags) +libharfbuzz_gobject_la_LIBADD = $(GOBJECT_LIBS) libharfbuzz.la +EXTRA_libharfbuzz_gobject_la_DEPENDENCIES = $(harfbuzz_gobject_def_dependency) +pkginclude_HEADERS += $(HB_GOBJECT_DIST_headers) +nodist_pkginclude_HEADERS += $(HB_GOBJECT_NODIST_headers) +pkgconfig_DATA += harfbuzz-gobject.pc + +BUILT_SOURCES += \ + $(HB_GOBJECT_ENUM_sources) \ + $(HB_GOBJECT_ENUM_headers) \ + $(NULL) +DISTCLEANFILES += \ + $(HB_GOBJECT_ENUM_sources) \ + $(HB_GOBJECT_ENUM_headers) \ + $(NULL) +hb-gobject-enums.%: hb-gobject-enums.%.tmpl $(HBHEADERS) + $(AM_V_GEN) PYTHONIOENCODING=UTF-8 $(GLIB_MKENUMS) \ + --identifier-prefix hb_ --symbol-prefix hb_gobject \ + --template $^ | \ + sed 's/_t_get_type/_get_type/g; s/_T (/ (/g' > "$@" \ + || ($(RM) "$@"; false) +endif +EXTRA_DIST += \ + harfbuzz-gobject.pc.in \ + hb-gobject-enums.cc.tmpl \ + hb-gobject-enums.h.tmpl \ + $(NULL) + + +%.pc: %.pc.in $(top_builddir)/config.status + $(AM_V_GEN) \ + $(SED) -e 's@%prefix%@$(prefix)@g' \ + -e 's@%exec_prefix%@$(exec_prefix)@g' \ + -e 's@%libdir%@$(libdir)@g' \ + -e 's@%includedir%@$(includedir)@g' \ + -e 's@%libs_private%@$(HBNONPCLIBS)@g' \ + -e 's@%requires_private%@$(HBDEPS)@g' \ + -e 's@%VERSION%@$(VERSION)@g' \ + "$<" > "$@" \ + || ($(RM) "$@"; false) + +CLEANFILES += $(pkgconfig_DATA) + + +DEF_FILES = harfbuzz.def harfbuzz-subset.def harfbuzz-icu.def +if HAVE_GOBJECT +DEF_FILES += harfbuzz-gobject.def +endif +check: $(DEF_FILES) # For check-symbols.sh +CLEANFILES += $(DEF_FILES) +harfbuzz.def: $(HBHEADERS) $(HBNODISTHEADERS) + $(AM_V_GEN) headers="$^" $(srcdir)/gen-def.py $@ +harfbuzz-subset.def: $(HB_SUBSET_headers) + $(AM_V_GEN) headers="$^" $(srcdir)/gen-def.py $@ +harfbuzz-icu.def: $(HB_ICU_headers) + $(AM_V_GEN) headers="$^" $(srcdir)/gen-def.py $@ +harfbuzz-gobject.def: $(HB_GOBJECT_headers) + $(AM_V_GEN) headers="$^" $(srcdir)/gen-def.py $@ + + +GENERATORS = \ + gen-arabic-table.py \ + gen-indic-table.py \ + gen-use-table.py \ + gen-def.py \ + $(NULL) +EXTRA_DIST += $(GENERATORS) + +unicode-tables: arabic-table indic-table use-table + +arabic-table: gen-arabic-table.py ArabicShaping.txt UnicodeData.txt Blocks.txt + $(AM_V_GEN) $(builddir)/$^ > hb-ot-shape-complex-arabic-table.hh \ + || ($(RM) hb-ot-shape-complex-arabic-table.hh; false) + +indic-table: gen-indic-table.py IndicSyllabicCategory-7.0.0.txt IndicMatraCategory-7.0.0.txt Blocks.txt + $(AM_V_GEN) $(builddir)/$^ > hb-ot-shape-complex-indic-table.cc \ + || ($(RM) hb-ot-shape-complex-indic-table.cc; false) + +use-table: gen-use-table.py IndicSyllabicCategory.txt IndicPositionalCategory.txt UnicodeData.txt Blocks.txt + $(AM_V_GEN) $(builddir)/$^ > hb-ot-shape-complex-use-table.cc \ + || ($(RM) hb-ot-shape-complex-use-table.cc; false) + +built-sources: $(BUILT_SOURCES) + +.PHONY: unicode-tables arabic-table indic-table use-table built-sources + +RAGEL_GENERATED = \ + $(patsubst %,$(srcdir)/%,$(HB_BASE_RAGEL_GENERATED_sources)) \ + $(patsubst %,$(srcdir)/%,$(HB_OT_RAGEL_GENERATED_sources)) \ + $(NULL) +BUILT_SOURCES += $(RAGEL_GENERATED) +EXTRA_DIST += \ + $(HB_BASE_RAGEL_sources) \ + $(HB_OT_RAGEL_sources) \ + $(NULL) +# We decided to add ragel-generated files to git... +#MAINTAINERCLEANFILES += $(RAGEL_GENERATED) +$(srcdir)/%.hh: $(srcdir)/%.rl + $(AM_V_GEN)(cd $(srcdir) && $(RAGEL) -e -F1 -o "$*.hh" "$*.rl") \ + || ($(RM) "$@"; false) + +noinst_PROGRAMS = \ + main \ + test \ + test-buffer-serialize \ + test-size-params \ + test-would-substitute \ + $(NULL) +bin_PROGRAMS = + +main_SOURCES = main.cc +main_CPPFLAGS = $(HBCFLAGS) +main_LDADD = libharfbuzz.la $(HBLIBS) + +test_SOURCES = test.cc +test_CPPFLAGS = $(HBCFLAGS) $(FREETYPE_CFLAGS) +test_LDADD = libharfbuzz.la $(HBLIBS) $(FREETYPE_LIBS) + +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_size_params_SOURCES = test-size-params.cc +test_size_params_CPPFLAGS = $(HBCFLAGS) +test_size_params_LDADD = libharfbuzz.la $(HBLIBS) + +test_buffer_serialize_SOURCES = test-buffer-serialize.cc +test_buffer_serialize_CPPFLAGS = $(HBCFLAGS) +test_buffer_serialize_LDADD = libharfbuzz.la $(HBLIBS) + +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) +TESTS += $(dist_check_SCRIPTS) + +if !WITH_LIBSTDCXX +dist_check_SCRIPTS += \ + check-libstdc++.sh \ + $(NULL) +endif + +check_PROGRAMS += \ + dump-indic-data \ + dump-khmer-data \ + dump-myanmar-data \ + dump-use-data \ + $(NULL) +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) +dump_khmer_data_SOURCES = dump-khmer-data.cc hb-ot-shape-complex-indic-table.cc +dump_khmer_data_CPPFLAGS = $(HBCFLAGS) +dump_khmer_data_LDADD = libharfbuzz.la $(HBLIBS) +dump_myanmar_data_SOURCES = dump-myanmar-data.cc hb-ot-shape-complex-indic-table.cc +dump_myanmar_data_CPPFLAGS = $(HBCFLAGS) +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) + +check_PROGRAMS += test-ot-tag test-unicode-ranges +TESTS += test-ot-tag test-unicode-ranges + +test_ot_tag_SOURCES = hb-ot-tag.cc +test_ot_tag_CPPFLAGS = $(HBCFLAGS) -DMAIN +test_ot_tag_LDADD = libharfbuzz.la $(HBLIBS) + +test_unicode_ranges_SOURCES = test-unicode-ranges.cc +test_unicode_ranges_LDADD = libharfbuzz.la $(HBLIBS) + +TESTS_ENVIRONMENT = \ + srcdir="$(srcdir)" \ + MAKE="$(MAKE) $(AM_MAKEFLAGS)" \ + HBSOURCES="$(HBSOURCES)" \ + HBHEADERS="$(HBHEADERS)" \ + $(NULL) + +if HAVE_INTROSPECTION + +-include $(INTROSPECTION_MAKEFILE) +INTROSPECTION_GIRS = HarfBuzz-0.0.gir # What does the 0 mean anyway?! +INTROSPECTION_SCANNER_ARGS = -I$(srcdir) -n hb --identifier-prefix=hb_ --warn-all +INTROSPECTION_COMPILER_ARGS = --includedir=$(srcdir) +INTROSPECTION_SCANNER_ENV = CC="$(CC)" + +HarfBuzz-0.0.gir: libharfbuzz.la libharfbuzz-gobject.la +HarfBuzz_0_0_gir_INCLUDES = GObject-2.0 +HarfBuzz_0_0_gir_CFLAGS = \ + $(INCLUDES) \ + $(HBCFLAGS) \ + -DHB_H \ + -DHB_H_IN \ + -DHB_OT_H \ + -DHB_OT_H_IN \ + -DHB_GOBJECT_H \ + -DHB_GOBJECT_H_IN \ + -DHB_EXTERN= \ + $(NULL) +HarfBuzz_0_0_gir_LIBS = \ + libharfbuzz.la \ + libharfbuzz-gobject.la \ + $(NULL) +HarfBuzz_0_0_gir_FILES = \ + $(HBHEADERS) \ + $(HBSOURCES) \ + $(HB_GOBJECT_sources) \ + $(HB_GOBJECT_headers) \ + $(NULL) + +girdir = $(datadir)/gir-1.0 +gir_DATA = $(INTROSPECTION_GIRS) + +typelibdir = $(libdir)/girepository-1.0 +typelib_DATA = $(INTROSPECTION_GIRS:.gir=.typelib) + +CLEANFILES += $(gir_DATA) $(typelib_DATA) + +endif + +-include $(top_srcdir)/git.mk diff --git a/chromium/third_party/harfbuzz-ng/src/src/Makefile.sources b/chromium/third_party/harfbuzz-ng/src/src/Makefile.sources new file mode 100644 index 00000000000..cfd2b61a39a --- /dev/null +++ b/chromium/third_party/harfbuzz-ng/src/src/Makefile.sources @@ -0,0 +1,216 @@ +# Base and default-included sources and headers + +HB_BASE_sources = \ + hb-atomic-private.hh \ + hb-blob.cc \ + hb-buffer-private.hh \ + hb-buffer-serialize.cc \ + hb-buffer.cc \ + hb-common.cc \ + hb-debug.hh \ + hb-dsalgs.hh \ + hb-face-private.hh \ + hb-face.cc \ + hb-font-private.hh \ + hb-font.cc \ + hb-mutex-private.hh \ + hb-object-private.hh \ + hb-open-file-private.hh \ + hb-open-type-private.hh \ + hb-ot-color-cbdt-table.hh \ + hb-ot-cmap-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-maxp-table.hh \ + hb-ot-name-table.hh \ + hb-ot-os2-table.hh \ + hb-ot-os2-unicode-ranges.hh \ + hb-ot-post-macroman.hh \ + hb-ot-post-table.hh \ + hb-ot-tag.cc \ + hb-private.hh \ + hb-set-digest-private.hh \ + hb-set-private.hh \ + hb-set.cc \ + hb-shape.cc \ + hb-shape-plan-private.hh \ + hb-shape-plan.cc \ + hb-shaper-list.hh \ + hb-shaper-impl-private.hh \ + hb-shaper-private.hh \ + hb-shaper.cc \ + hb-string-array.hh \ + hb-unicode-private.hh \ + hb-unicode.cc \ + hb-utf-private.hh \ + hb-warning.cc \ + $(NULL) + +HB_BASE_RAGEL_GENERATED_sources = \ + hb-buffer-deserialize-json.hh \ + hb-buffer-deserialize-text.hh \ + $(NULL) +HB_BASE_RAGEL_sources = \ + hb-buffer-deserialize-json.rl \ + hb-buffer-deserialize-text.rl \ + $(NULL) + +HB_BASE_headers = \ + hb.h \ + hb-blob.h \ + hb-buffer.h \ + hb-common.h \ + hb-deprecated.h \ + hb-face.h \ + hb-font.h \ + hb-set.h \ + hb-shape.h \ + hb-shape-plan.h \ + hb-unicode.h \ + hb-version.h \ + $(NULL) + +HB_FALLBACK_sources = \ + hb-fallback-shape.cc \ + $(NULL) + +HB_OT_sources = \ + hb-aat-layout.cc \ + hb-aat-layout-common-private.hh \ + hb-aat-layout-ankr-table.hh \ + hb-aat-layout-kerx-table.hh \ + hb-aat-layout-morx-table.hh \ + hb-aat-layout-trak-table.hh \ + hb-aat-layout-private.hh \ + hb-ot-font.cc \ + hb-ot-layout.cc \ + hb-ot-layout-base-table.hh \ + hb-ot-layout-common-private.hh \ + hb-ot-layout-gdef-table.hh \ + hb-ot-layout-gpos-table.hh \ + hb-ot-layout-gsubgpos-private.hh \ + hb-ot-layout-gsub-table.hh \ + hb-ot-layout-jstf-table.hh \ + hb-ot-layout-private.hh \ + hb-ot-color.cc \ + 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-map.cc \ + hb-ot-map-private.hh \ + hb-ot-math.cc \ + hb-ot-math-table.hh \ + hb-ot-shape.cc \ + hb-ot-shape-complex-arabic.cc \ + hb-ot-shape-complex-arabic-fallback.hh \ + hb-ot-shape-complex-arabic-private.hh \ + hb-ot-shape-complex-arabic-table.hh \ + hb-ot-shape-complex-arabic-win1256.hh \ + hb-ot-shape-complex-default.cc \ + hb-ot-shape-complex-hangul.cc \ + hb-ot-shape-complex-hebrew.cc \ + hb-ot-shape-complex-indic.cc \ + hb-ot-shape-complex-indic-private.hh \ + hb-ot-shape-complex-indic-table.cc \ + hb-ot-shape-complex-khmer-private.hh \ + hb-ot-shape-complex-khmer.cc \ + hb-ot-shape-complex-myanmar-private.hh \ + hb-ot-shape-complex-myanmar.cc \ + hb-ot-shape-complex-thai.cc \ + hb-ot-shape-complex-tibetan.cc \ + hb-ot-shape-complex-use.cc \ + hb-ot-shape-complex-use-private.hh \ + hb-ot-shape-complex-use-table.cc \ + hb-ot-shape-complex-private.hh \ + hb-ot-shape-normalize-private.hh \ + hb-ot-shape-normalize.cc \ + hb-ot-shape-fallback-private.hh \ + hb-ot-shape-fallback.cc \ + hb-ot-shape-private.hh \ + hb-ot-var.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 \ + $(NULL) + +HB_OT_RAGEL_GENERATED_sources = \ + 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 \ + $(NULL) +HB_OT_RAGEL_sources = \ + hb-ot-shape-complex-indic-machine.rl \ + hb-ot-shape-complex-khmer-machine.rl \ + hb-ot-shape-complex-myanmar-machine.rl \ + hb-ot-shape-complex-use-machine.rl \ + $(NULL) + +HB_OT_headers = \ + hb-ot.h \ + hb-ot-font.h \ + hb-ot-layout.h \ + hb-ot-math.h \ + hb-ot-shape.h \ + hb-ot-tag.h \ + hb-ot-var.h \ + $(NULL) + +# Optional Sources and Headers with external deps + +HB_FT_sources = hb-ft.cc +HB_FT_headers = hb-ft.h + +HB_GLIB_sources = hb-glib.cc +HB_GLIB_headers = hb-glib.h + +HB_GRAPHITE2_sources = hb-graphite2.cc +HB_GRAPHITE2_headers = hb-graphite2.h + +# System-dependent sources and headers + +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_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-subset.cc \ + hb-subset-glyf.cc \ + hb-subset-input.cc \ + hb-subset-plan.cc \ + $(NULL) + +HB_SUBSET_headers = \ + hb-subset.h \ + hb-subset-glyf.hh \ + hb-subset-plan.hh \ + hb-subset-private.hh \ + $(NULL) + +HB_GOBJECT_DIST_sources = hb-gobject-structs.cc +HB_GOBJECT_DIST_headers = hb-gobject.h hb-gobject-structs.h +HB_GOBJECT_ENUM_sources = hb-gobject-enums.cc +HB_GOBJECT_ENUM_headers = hb-gobject-enums.h +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) diff --git a/chromium/third_party/harfbuzz-ng/src/src/check-c-linkage-decls.sh b/chromium/third_party/harfbuzz-ng/src/src/check-c-linkage-decls.sh new file mode 100755 index 00000000000..8234abc455a --- /dev/null +++ b/chromium/third_party/harfbuzz-ng/src/src/check-c-linkage-decls.sh @@ -0,0 +1,27 @@ +#!/bin/sh + +LC_ALL=C +export LC_ALL + +test -z "$srcdir" && srcdir=. +stat=0 + +test "x$HBHEADERS" = x && HBHEADERS=`cd "$srcdir"; find . -maxdepth 1 -name 'hb*.h'` +test "x$HBSOURCES" = x && HBSOURCES=`cd "$srcdir"; find . -maxdepth 1 -name 'hb*.cc'` + +for x in $HBHEADERS; do + test -f "$srcdir/$x" -a ! -f "$x" && x="$srcdir/$x" + if ! grep -q HB_BEGIN_DECLS "$x" || ! grep -q HB_END_DECLS "$x"; then + echo "Ouch, file $x does not have HB_BEGIN_DECLS / HB_END_DECLS, but it should" + stat=1 + fi +done +for x in $HBSOURCES; do + test -f "$srcdir/$x" -a ! -f "$x" && x="$srcdir/$x" + if grep -q HB_BEGIN_DECLS "$x" || grep -q HB_END_DECLS "$x"; then + echo "Ouch, file $x has HB_BEGIN_DECLS / HB_END_DECLS, but it shouldn't" + stat=1 + fi +done + +exit $stat diff --git a/chromium/third_party/harfbuzz-ng/src/src/check-externs.sh b/chromium/third_party/harfbuzz-ng/src/src/check-externs.sh new file mode 100755 index 00000000000..a6de375350c --- /dev/null +++ b/chromium/third_party/harfbuzz-ng/src/src/check-externs.sh @@ -0,0 +1,22 @@ +#!/bin/sh + +LC_ALL=C +export LC_ALL + +test -z "$srcdir" && srcdir=. +stat=0 + +test "x$HBHEADERS" = x && HBHEADERS=`cd "$srcdir"; find . -maxdepth 1 -name 'hb*.h'` +test "x$EGREP" = x && EGREP='grep -E' + + +echo 'Checking that all public symbols are exported with HB_EXTERN' + +for x in $HBHEADERS; do + test -f "$srcdir/$x" -a ! -f "$x" && x="$srcdir/$x" + $EGREP -B1 -n '^hb_' /dev/null "$x" | + $EGREP -v '(^--|:hb_|-HB_EXTERN )' -A1 +done | +grep . >&2 && stat=1 + +exit $stat diff --git a/chromium/third_party/harfbuzz-ng/src/src/check-header-guards.sh b/chromium/third_party/harfbuzz-ng/src/src/check-header-guards.sh new file mode 100755 index 00000000000..b67640fc197 --- /dev/null +++ b/chromium/third_party/harfbuzz-ng/src/src/check-header-guards.sh @@ -0,0 +1,24 @@ +#!/bin/sh + +LC_ALL=C +export LC_ALL + +test -z "$srcdir" && srcdir=. +stat=0 + +test "x$HBHEADERS" = x && HBHEADERS=`cd "$srcdir"; find . -maxdepth 1 -name 'hb*.h' ! -name 'hb-gobject-structs.h'` +test "x$HBSOURCES" = x && HBSOURCES=`cd "$srcdir"; find . -maxdepth 1 -name 'hb-*.cc' -or -name 'hb-*.hh'` + +for x in $HBHEADERS $HBSOURCES; do + test -f "$srcdir/$x" -a ! -f "$x" && x="$srcdir/$x" + echo "$x" | grep -q '[^h]$' && continue; + xx=`echo "$x" | sed 's@.*/@@'` + tag=`echo "$xx" | tr 'a-z.-' 'A-Z_'` + lines=`grep -w "$tag" "$x" | wc -l | sed 's/[ ]*//g'` + if test "x$lines" != x3; then + echo "Ouch, header file $x does not have correct preprocessor guards" + stat=1 + fi +done + +exit $stat diff --git a/chromium/third_party/harfbuzz-ng/src/src/check-includes.sh b/chromium/third_party/harfbuzz-ng/src/src/check-includes.sh new file mode 100755 index 00000000000..fd565da53fb --- /dev/null +++ b/chromium/third_party/harfbuzz-ng/src/src/check-includes.sh @@ -0,0 +1,44 @@ +#!/bin/sh + +LC_ALL=C +export LC_ALL + +test -z "$srcdir" && srcdir=. +stat=0 + +test "x$HBHEADERS" = x && HBHEADERS=`cd "$srcdir"; find . -maxdepth 1 -name 'hb*.h'` +test "x$HBSOURCES" = x && HBSOURCES=`cd "$srcdir"; find . -maxdepth 1 -name 'hb-*.cc' -or -name 'hb-*.hh'` + + +echo 'Checking that public header files #include "hb-common.h" or "hb.h" first (or none)' + +for x in $HBHEADERS; do + test -f "$srcdir/$x" -a ! -f "$x" && x="$srcdir/$x" + grep '#.*\<include\>' "$x" /dev/null | head -n 1 +done | +grep -v '"hb-common[.]h"' | +grep -v '"hb[.]h"' | +grep -v 'hb-common[.]h:' | +grep -v 'hb[.]h:' | +grep . >&2 && stat=1 + + +echo 'Checking that source files #include "hb-*private.hh" first (or none)' + +for x in $HBSOURCES; do + test -f "$srcdir/$x" -a ! -f "$x" && x="$srcdir/$x" + grep '#.*\<include\>' "$x" /dev/null | grep -v 'include _' | head -n 1 +done | +grep -v '"hb-.*private[.]hh"' | +grep -v 'hb-private[.]hh:' | +grep . >&2 && stat=1 + + +echo 'Checking that there is no #include <hb-*.h>' +for x in $HBHEADERS $HBSOURCES; do + test -f "$srcdir/$x" && x="$srcdir/$x" + grep '#.*\<include\>.*<.*hb' "$x" /dev/null >&2 && stat=1 +done + + +exit $stat diff --git a/chromium/third_party/harfbuzz-ng/src/src/check-libstdc++.sh b/chromium/third_party/harfbuzz-ng/src/src/check-libstdc++.sh new file mode 100755 index 00000000000..ce0bdab755f --- /dev/null +++ b/chromium/third_party/harfbuzz-ng/src/src/check-libstdc++.sh @@ -0,0 +1,44 @@ +#!/bin/sh + +LC_ALL=C +export LC_ALL + +test -z "$srcdir" && srcdir=. +test -z "$libs" && libs=.libs +stat=0 + + +if which ldd 2>/dev/null >/dev/null; then + LDD=ldd +else + # macOS specific tool + if which otool 2>/dev/null >/dev/null; then + LDD="otool -L" + else + echo "check-libstdc++.sh: 'ldd' not found; skipping test" + exit 77 + fi +fi + +tested=false +# harfbuzz-icu links to libstdc++ because icu does. +# harfbuzz-subset uses libstdc++. +for soname in harfbuzz harfbuzz-gobject; do + for suffix in so dylib; do + so=$libs/lib$soname.$suffix + if ! test -f "$so"; then continue; fi + + echo "Checking that we are not linking to libstdc++ or libc++ in $so" + if $LDD $so | grep 'libstdc[+][+]\|libc[+][+]'; then + echo "Ouch, linked to libstdc++ or libc++" + stat=1 + fi + tested=true + done +done +if ! $tested; then + echo "check-libstdc++.sh: libharfbuzz shared library not found; skipping test" + exit 77 +fi + +exit $stat diff --git a/chromium/third_party/harfbuzz-ng/src/src/check-static-inits.sh b/chromium/third_party/harfbuzz-ng/src/src/check-static-inits.sh new file mode 100755 index 00000000000..71551cbd4c8 --- /dev/null +++ b/chromium/third_party/harfbuzz-ng/src/src/check-static-inits.sh @@ -0,0 +1,40 @@ +#!/bin/sh + +LC_ALL=C +export LC_ALL + +test -z "$srcdir" && srcdir=. +test -z "$libs" && libs=.libs +stat=0 + + +if which objdump 2>/dev/null >/dev/null; then + : +else + echo "check-static-inits.sh: 'objdump' not found; skipping test" + exit 77 +fi + +OBJS=$libs/*.o +if test "x`echo $OBJS`" = "x$OBJS" 2>/dev/null >/dev/null; then + echo "check-static-inits.sh: object files not found; skipping test" + exit 77 +fi + +echo "Checking that no object file has static initializers" +for obj in $OBJS; do + if objdump -t "$obj" | grep '[.][cd]tors' | grep -v '\<00*\>'; then + echo "Ouch, $obj has static initializers/finalizers" + stat=1 + fi +done + +echo "Checking that no object file has lazy static C++ constructors/destructors or other such stuff" +for obj in $OBJS; do + if objdump -t "$obj" | grep '__cxa_'; then + echo "Ouch, $obj has lazy static C++ constructors/destructors or other such stuff" + stat=1 + fi +done + +exit $stat diff --git a/chromium/third_party/harfbuzz-ng/src/src/check-symbols.sh b/chromium/third_party/harfbuzz-ng/src/src/check-symbols.sh new file mode 100755 index 00000000000..bfc93b349ae --- /dev/null +++ b/chromium/third_party/harfbuzz-ng/src/src/check-symbols.sh @@ -0,0 +1,62 @@ +#!/bin/sh + +LC_ALL=C +export LC_ALL + +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_.*' + +if which nm 2>/dev/null >/dev/null; then + : +else + echo "check-symbols.sh: 'nm' not found; skipping test" + exit 77 +fi + +tested=false +for soname in harfbuzz harfbuzz-subset harfbuzz-icu harfbuzz-gobject; do + for suffix in so dylib; do + so=$libs/lib$soname.$suffix + if ! test -f "$so"; then continue; fi + + # On macOS, C symbols are prefixed with _ + symprefix= + if test $suffix = dylib; then symprefix=_; fi + + EXPORTED_SYMBOLS="`nm "$so" | grep ' [BCDGINRSTVW] .' | grep -v " $symprefix\\($IGNORED_SYMBOLS\\>\\)" | cut -d' ' -f3 | c++filt`" + + prefix=$symprefix`basename "$so" | sed 's/libharfbuzz/hb/; s/-/_/g; s/[.].*//'` + + echo + echo "Checking that $so does not expose internal symbols" + if echo "$EXPORTED_SYMBOLS" | grep -v "^${prefix}\(_\|$\)"; then + echo "Ouch, internal symbols exposed" + stat=1 + fi + + def=$soname.def + if ! test -f "$def"; then + echo "'$def' not found; skipping" + else + echo + echo "Checking that $so has the same symbol list as $def" + { + echo EXPORTS + echo "$EXPORTED_SYMBOLS" | sed -e "s/^${symprefix}hb/hb/g" + # cheat: copy the last line from the def file! + tail -n1 "$def" + } | c++filt | diff "$def" - >&2 || stat=1 + fi + + tested=true + done +done +if ! $tested; then + echo "check-symbols.sh: no shared libraries found; skipping test" + exit 77 +fi + +exit $stat diff --git a/chromium/third_party/harfbuzz-ng/src/src/dev-run.sh b/chromium/third_party/harfbuzz-ng/src/src/dev-run.sh new file mode 100755 index 00000000000..e7d0973ba07 --- /dev/null +++ b/chromium/third_party/harfbuzz-ng/src/src/dev-run.sh @@ -0,0 +1,98 @@ +#!/bin/bash +# Suggested setup to use the script: +# (on the root of the project) +# $ NOCONFIGURE=1 ./autogen.sh --with-freetype --with-glib --with-gobject --with-cairo +# $ mkdir build && cd build && ../configure && make -j5 && cd .. +# $ src/dev-run.sh [FONT-FILE] [TEXT] +# +# Or, using cmake: +# $ cmake -DHB_CHECK=ON -Bbuild -H. -GNinja && ninja -Cbuild +# $ src/dev-run.sh [FONT-FILE] [TEXT] +# +# If you want to open the result rendering using a GUI app, +# $ src/dev-run.sh open [FONT-FILE] [TEXT] +# +# And if you are using iTerm2, you can use the script like this, +# $ src/dev-run.sh img [FONT-FILE] [TEXT] +# + +[ $# = 0 ] && echo Usage: "src/dev-run.sh [FONT-FILE] [TEXT]" && exit +command -v entr >/dev/null 2>&1 || { echo >&2 "This script needs `entr` be installed"; exit 1; } + + +GDB=gdb +# if gdb doesn't exist, hopefully lldb exist +command -v $GDB >/dev/null 2>&1 || export GDB="lldb" + + +[ $1 = "open" ] && openimg=1 && shift +OPEN=xdg-open +[ "$(uname)" == "Darwin" ] && OPEN=open + + +[ $1 = "img" ] && img=1 && shift +# http://iterm2.com/documentation-images.html +osc="\033]" +if [[ $TERM == screen* ]]; then osc="\033Ptmux;\033\033]"; fi +st="\a" +if [[ $TERM == screen* ]]; then st="\a"; fi + + +tmp=tmp.png +[ -f 'build/build.ninja' ] && CMAKENINJA=TRUE +# or "fswatch -0 . -e build/ -e .git" +find src/ | entr printf '\0' | while read -d ""; do + clear + yes = | head -n`tput cols` | tr -d '\n' + if [[ $CMAKENINJA ]]; then + ninja -Cbuild hb-shape hb-view && { + build/hb-shape $@ + if [ $openimg ]; then + build/hb-view $@ -O png -o $tmp + $OPEN $tmp + elif [ $img ]; then + build/hb-view $@ -O png -o $tmp + printf "\n${osc}1337;File=;inline=1:`cat $tmp | base64`${st}\n" + else + build/hb-view $@ + fi + } + else + make -Cbuild/src -j5 -s lib && { + build/util/hb-shape $@ + if [ $openimg ]; then + build/util/hb-view $@ -O png -o $tmp + $OPEN $tmp + elif [ $img ]; then + build/util/hb-view $@ -O png -o $tmp + printf "\n${osc}1337;File=;inline=1:`cat $tmp | base64`${st}\n" + else + build/util/hb-view $@ + fi + } + fi +done + +read -n 1 -p "[C]heck, [D]ebug, [R]estart, [Q]uit? " answer +case "$answer" in +c|C ) + if [[ $CMAKENINJA ]]; then + CTEST_OUTPUT_ON_FAILURE=1 CTEST_PARALLEL_LEVEL=5 ninja -Cbuild test + else + make -Cbuild -j5 check && .ci/fail.sh + fi +;; +d|D ) + if [[ $CMAKENINJA ]]; then + echo "Not supported on cmake builds yet" + else + build/libtool --mode=execute $GDB -- build/util/hb-shape $@ + fi +;; +r|R ) + src/dev-run.sh $@ +;; +* ) + exit +;; +esac diff --git a/chromium/third_party/harfbuzz-ng/src/src/dump-indic-data.cc b/chromium/third_party/harfbuzz-ng/src/src/dump-indic-data.cc new file mode 100644 index 00000000000..d57413884be --- /dev/null +++ b/chromium/third_party/harfbuzz-ng/src/src/dump-indic-data.cc @@ -0,0 +1,43 @@ +/* + * 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 + */ + +#include "hb-ot-shape-complex-indic-private.hh" + +int +main (void) +{ + for (hb_codepoint_t u = 0; u <= 0x10FFFF; u++) + { + hb_glyph_info_t info; + info.codepoint = u; + set_indic_properties (info); + if (info.indic_category() != INDIC_SYLLABIC_CATEGORY_OTHER || + info.indic_position() != INDIC_MATRA_CATEGORY_NOT_APPLICABLE) + printf("U+%04X %u %u\n", u, + info.indic_category(), + info.indic_position()); + } +} diff --git a/chromium/third_party/harfbuzz-ng/src/src/dump-khmer-data.cc b/chromium/third_party/harfbuzz-ng/src/src/dump-khmer-data.cc new file mode 100644 index 00000000000..7dd09b2b5ca --- /dev/null +++ b/chromium/third_party/harfbuzz-ng/src/src/dump-khmer-data.cc @@ -0,0 +1,43 @@ +/* + * 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 + */ + +#include "hb-ot-shape-complex-khmer-private.hh" + +int +main (void) +{ + for (hb_codepoint_t u = 0; u <= 0x10FFFF; u++) + { + hb_glyph_info_t info; + info.codepoint = u; + set_khmer_properties (info); + if (info.khmer_category() != INDIC_SYLLABIC_CATEGORY_OTHER || + info.khmer_position() != INDIC_MATRA_CATEGORY_NOT_APPLICABLE) + printf("U+%04X %u %u\n", u, + info.khmer_category(), + info.khmer_position()); + } +} diff --git a/chromium/third_party/harfbuzz-ng/src/src/dump-myanmar-data.cc b/chromium/third_party/harfbuzz-ng/src/src/dump-myanmar-data.cc new file mode 100644 index 00000000000..2df9cd987f3 --- /dev/null +++ b/chromium/third_party/harfbuzz-ng/src/src/dump-myanmar-data.cc @@ -0,0 +1,43 @@ +/* + * 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 + */ + +#include "hb-ot-shape-complex-myanmar-private.hh" + +int +main (void) +{ + for (hb_codepoint_t u = 0; u <= 0x10FFFF; u++) + { + hb_glyph_info_t info; + info.codepoint = u; + set_myanmar_properties (info); + if (info.myanmar_category() != INDIC_SYLLABIC_CATEGORY_OTHER || + info.myanmar_position() != INDIC_MATRA_CATEGORY_NOT_APPLICABLE) + printf("U+%04X %u %u\n", u, + info.myanmar_category(), + info.myanmar_position()); + } +} diff --git a/chromium/third_party/harfbuzz-ng/src/src/dump-use-data.cc b/chromium/third_party/harfbuzz-ng/src/src/dump-use-data.cc new file mode 100644 index 00000000000..0e64688f1e0 --- /dev/null +++ b/chromium/third_party/harfbuzz-ng/src/src/dump-use-data.cc @@ -0,0 +1,38 @@ +/* + * 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 + */ + +#include "hb-ot-shape-complex-use-private.hh" + +int +main (void) +{ + for (hb_codepoint_t u = 0; u <= 0x10FFFF; u++) + { + unsigned int category = hb_use_get_category (u); + if (category != USE_O) + printf("U+%04X %u\n", u, category); + } +} diff --git a/chromium/third_party/harfbuzz-ng/src/src/gen-arabic-table.py b/chromium/third_party/harfbuzz-ng/src/src/gen-arabic-table.py new file mode 100755 index 00000000000..59bd7601296 --- /dev/null +++ b/chromium/third_party/harfbuzz-ng/src/src/gen-arabic-table.py @@ -0,0 +1,269 @@ +#!/usr/bin/python + +import sys +import os.path + +if len (sys.argv) != 4: + print >>sys.stderr, "usage: ./gen-arabic-table.py ArabicShaping.txt UnicodeData.txt Blocks.txt" + sys.exit (1) + +files = [file (x) for x in sys.argv[1:]] + +headers = [[files[0].readline (), files[0].readline ()], [files[2].readline (), files[2].readline ()]] +headers.append (["UnicodeData.txt does not have a header."]) +while files[0].readline ().find ('##################') < 0: + pass + +blocks = {} +def read_blocks(f): + global blocks + for line in f: + + j = line.find ('#') + if j >= 0: + line = line[:j] + + fields = [x.strip () for x in line.split (';')] + if len (fields) == 1: + continue + + uu = fields[0].split ('..') + start = int (uu[0], 16) + if len (uu) == 1: + end = start + else: + end = int (uu[1], 16) + + t = fields[1] + + for u in range (start, end + 1): + blocks[u] = t + +def print_joining_table(f): + + values = {} + for line in f: + + if line[0] == '#': + continue + + fields = [x.strip () for x in line.split (';')] + if len (fields) == 1: + continue + + u = int (fields[0], 16) + + if fields[3] in ["ALAPH", "DALATH RISH"]: + value = "JOINING_GROUP_" + fields[3].replace(' ', '_') + else: + value = "JOINING_TYPE_" + fields[2] + values[u] = value + + short_value = {} + for value in set([v for v in values.values()] + ['JOINING_TYPE_X']): + short = ''.join(x[0] for x in value.split('_')[2:]) + assert short not in short_value.values() + short_value[value] = short + + print + for value,short in short_value.items(): + print "#define %s %s" % (short, value) + + uu = sorted(values.keys()) + num = len(values) + all_blocks = set([blocks[u] for u in uu]) + + last = -100000 + ranges = [] + for u in uu: + if u - last <= 1+16*5: + ranges[-1][-1] = u + else: + ranges.append([u,u]) + last = u + + print + print "static const uint8_t joining_table[] =" + print "{" + last_block = None + offset = 0 + for start,end in ranges: + + print + print "#define joining_offset_0x%04xu %d" % (start, offset) + + for u in range(start, end+1): + + block = blocks.get(u, last_block) + value = values.get(u, "JOINING_TYPE_X") + + if block != last_block or u == start: + if u != start: + print + if block in all_blocks: + print "\n /* %s */" % block + else: + print "\n /* FILLER */" + last_block = block + if u % 32 != 0: + print + print " /* %04X */" % (u//32*32), " " * (u % 32), + + if u % 32 == 0: + print + print " /* %04X */ " % u, + sys.stdout.write("%s," % short_value[value]) + print + + offset += end - start + 1 + print + occupancy = num * 100. / offset + print "}; /* Table items: %d; occupancy: %d%% */" % (offset, occupancy) + print + + page_bits = 12; + print + print "static unsigned int" + print "joining_type (hb_codepoint_t u)" + print "{" + print " switch (u >> %d)" % page_bits + print " {" + pages = set([u>>page_bits for u in [s for s,e in ranges]+[e for s,e in ranges]]) + for p in sorted(pages): + print " case 0x%0Xu:" % p + for (start,end) in ranges: + if p not in [start>>page_bits, end>>page_bits]: continue + offset = "joining_offset_0x%04xu" % start + print " if (hb_in_range<hb_codepoint_t> (u, 0x%04Xu, 0x%04Xu)) return joining_table[u - 0x%04Xu + %s];" % (start, end, start, offset) + print " break;" + print "" + print " default:" + print " break;" + print " }" + print " return X;" + print "}" + print + for value,short in short_value.items(): + print "#undef %s" % (short) + print + +def print_shaping_table(f): + + shapes = {} + ligatures = {} + names = {} + for line in f: + + fields = [x.strip () for x in line.split (';')] + if fields[5][0:1] != '<': + continue + + items = fields[5].split (' ') + shape, items = items[0][1:-1], tuple (int (x, 16) for x in items[1:]) + + if not shape in ['initial', 'medial', 'isolated', 'final']: + continue + + c = int (fields[0], 16) + if len (items) != 1: + # We only care about lam-alef ligatures + if len (items) != 2 or items[0] != 0x0644 or items[1] not in [0x0622, 0x0623, 0x0625, 0x0627]: + continue + + # Save ligature + names[c] = fields[1] + if items not in ligatures: + ligatures[items] = {} + ligatures[items][shape] = c + pass + else: + # Save shape + if items[0] not in names: + names[items[0]] = fields[1] + else: + names[items[0]] = os.path.commonprefix ([names[items[0]], fields[1]]).strip () + if items[0] not in shapes: + shapes[items[0]] = {} + shapes[items[0]][shape] = c + + print + print "static const uint16_t shaping_table[][4] =" + print "{" + + keys = shapes.keys () + min_u, max_u = min (keys), max (keys) + for u in range (min_u, max_u + 1): + s = [shapes[u][shape] if u in shapes and shape in shapes[u] else 0 + for shape in ['initial', 'medial', 'final', 'isolated']] + value = ', '.join ("0x%04Xu" % c for c in s) + print " {%s}, /* U+%04X %s */" % (value, u, names[u] if u in names else "") + + print "};" + print + print "#define SHAPING_TABLE_FIRST 0x%04Xu" % min_u + print "#define SHAPING_TABLE_LAST 0x%04Xu" % max_u + print + + ligas = {} + for pair in ligatures.keys (): + for shape in ligatures[pair]: + c = ligatures[pair][shape] + if shape == 'isolated': + liga = (shapes[pair[0]]['initial'], shapes[pair[1]]['final']) + elif shape == 'final': + liga = (shapes[pair[0]]['medial'], shapes[pair[1]]['final']) + else: + raise Exception ("Unexpected shape", shape) + if liga[0] not in ligas: + ligas[liga[0]] = [] + ligas[liga[0]].append ((liga[1], c)) + max_i = max (len (ligas[l]) for l in ligas) + print + print "static const struct ligature_set_t {" + print " uint16_t first;" + print " struct ligature_pairs_t {" + print " uint16_t second;" + print " uint16_t ligature;" + print " } ligatures[%d];" % max_i + print "} ligature_table[] =" + print "{" + keys = ligas.keys () + keys.sort () + for first in keys: + + print " { 0x%04Xu, {" % (first) + for liga in ligas[first]: + print " { 0x%04Xu, 0x%04Xu }, /* %s */" % (liga[0], liga[1], names[liga[1]]) + print " }}," + + print "};" + print + + + +print "/* == Start of generated table == */" +print "/*" +print " * The following table is generated by running:" +print " *" +print " * ./gen-arabic-table.py ArabicShaping.txt UnicodeData.txt Blocks.txt" +print " *" +print " * on files with these headers:" +print " *" +for h in headers: + for l in h: + print " * %s" % (l.strip()) +print " */" +print +print "#ifndef HB_OT_SHAPE_COMPLEX_ARABIC_TABLE_HH" +print "#define HB_OT_SHAPE_COMPLEX_ARABIC_TABLE_HH" +print + +read_blocks (files[2]) +print_joining_table (files[0]) +print_shaping_table (files[1]) + +print +print "#endif /* HB_OT_SHAPE_COMPLEX_ARABIC_TABLE_HH */" +print +print "/* == End of generated table == */" + diff --git a/chromium/third_party/harfbuzz-ng/src/src/gen-def.py b/chromium/third_party/harfbuzz-ng/src/src/gen-def.py new file mode 100755 index 00000000000..de35eb7d0ea --- /dev/null +++ b/chromium/third_party/harfbuzz-ng/src/src/gen-def.py @@ -0,0 +1,19 @@ +#!/usr/bin/env python + +from __future__ import print_function + +import io, os, re, sys + +headers_content = [] +for h in os.environ["headers"].split (' '): + if h.endswith (".h"): + with io.open (h, encoding='utf-8') as f: headers_content.append (f.read ()) + +result = """EXPORTS +%s +LIBRARY lib%s-0.dll""" % ( + "\n".join (sorted (re.findall (r"^hb_\w+(?= \()", "\n".join (headers_content), re.M))), + sys.argv[1].replace ('.def', '') +) + +with open (sys.argv[1], "w") as f: f.write (result) diff --git a/chromium/third_party/harfbuzz-ng/src/src/gen-indic-table.py b/chromium/third_party/harfbuzz-ng/src/src/gen-indic-table.py new file mode 100755 index 00000000000..735b9015ec7 --- /dev/null +++ b/chromium/third_party/harfbuzz-ng/src/src/gen-indic-table.py @@ -0,0 +1,260 @@ +#!/usr/bin/python + +import sys + +if len (sys.argv) != 4: + print >>sys.stderr, "usage: ./gen-indic-table.py IndicSyllabicCategory.txt IndicPositionalCategory.txt Blocks.txt" + sys.exit (1) + +ALLOWED_SINGLES = [0x00A0, 0x25CC] +ALLOWED_BLOCKS = [ + 'Basic Latin', + 'Latin-1 Supplement', + 'Devanagari', + 'Bengali', + 'Gurmukhi', + 'Gujarati', + 'Oriya', + 'Tamil', + 'Telugu', + 'Kannada', + 'Malayalam', + 'Sinhala', + 'Myanmar', + 'Khmer', + 'Vedic Extensions', + 'General Punctuation', + 'Superscripts and Subscripts', + 'Devanagari Extended', + 'Myanmar Extended-B', + 'Myanmar Extended-A', +] + +files = [file (x) for x in sys.argv[1:]] + +headers = [[f.readline () for i in range (2)] for f in files] + +data = [{} for f in files] +values = [{} for f in files] +for i, f in enumerate (files): + for line in f: + + j = line.find ('#') + if j >= 0: + line = line[:j] + + fields = [x.strip () for x in line.split (';')] + if len (fields) == 1: + continue + + uu = fields[0].split ('..') + start = int (uu[0], 16) + if len (uu) == 1: + end = start + else: + end = int (uu[1], 16) + + t = fields[1] + + for u in range (start, end + 1): + data[i][u] = t + values[i][t] = values[i].get (t, 0) + end - start + 1 + +# Merge data into one dict: +defaults = ('Other', 'Not_Applicable', 'No_Block') +for i,v in enumerate (defaults): + values[i][v] = values[i].get (v, 0) + 1 +combined = {} +for i,d in enumerate (data): + for u,v in d.items (): + if i == 2 and not u in combined: + continue + if not u in combined: + combined[u] = list (defaults) + combined[u][i] = v +combined = {k:v for k,v in combined.items() if k in ALLOWED_SINGLES or v[2] in ALLOWED_BLOCKS} +data = combined +del combined +num = len (data) + +for u in [0x17CD, 0x17CE, 0x17CF, 0x17D0, 0x17D3]: + if data[u][0] == 'Other': + data[u][0] = "Vowel_Dependent" + +# Move the outliers NO-BREAK SPACE and DOTTED CIRCLE out +singles = {} +for u in ALLOWED_SINGLES: + singles[u] = data[u] + del data[u] + +print "/* == Start of generated table == */" +print "/*" +print " * The following table is generated by running:" +print " *" +print " * ./gen-indic-table.py IndicSyllabicCategory.txt IndicPositionalCategory.txt Blocks.txt" +print " *" +print " * on files with these headers:" +print " *" +for h in headers: + for l in h: + print " * %s" % (l.strip()) +print " */" +print +print '#include "hb-ot-shape-complex-indic-private.hh"' +print + +# Shorten values +short = [{ + "Bindu": 'Bi', + "Cantillation_Mark": 'Ca', + "Joiner": 'ZWJ', + "Non_Joiner": 'ZWNJ', + "Number": 'Nd', + "Visarga": 'Vs', + "Vowel": 'Vo', + "Vowel_Dependent": 'M', + "Consonant_Prefixed": 'CPrf', + "Other": 'x', +},{ + "Not_Applicable": 'x', +}] +all_shorts = [{},{}] + +# Add some of the values, to make them more readable, and to avoid duplicates + + +for i in range (2): + for v,s in short[i].items (): + all_shorts[i][s] = v + +what = ["INDIC_SYLLABIC_CATEGORY", "INDIC_MATRA_CATEGORY"] +what_short = ["ISC", "IMC"] +for i in range (2): + print + vv = values[i].keys () + vv.sort () + for v in vv: + v_no_and = v.replace ('_And_', '_') + if v in short[i]: + s = short[i][v] + else: + s = ''.join ([c for c in v_no_and if ord ('A') <= ord (c) <= ord ('Z')]) + if s in all_shorts[i]: + 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) +print +print "#define _(S,M) INDIC_COMBINE_CATEGORIES (ISC_##S, IMC_##M)" +print +print + +total = 0 +used = 0 +last_block = None +def print_block (block, start, end, data): + global total, used, last_block + if block and block != last_block: + print + print + print " /* %s */" % block + num = 0 + assert start % 8 == 0 + assert (end+1) % 8 == 0 + for u in range (start, end+1): + if u % 8 == 0: + print + print " /* %04X */" % u, + if u in data: + num += 1 + d = data.get (u, defaults) + sys.stdout.write ("%9s" % ("_(%s,%s)," % (short[0][d[0]], short[1][d[1]]))) + + total += end - start + 1 + used += num + if block: + last_block = block + +uu = data.keys () +uu.sort () + +last = -100000 +num = 0 +offset = 0 +starts = [] +ends = [] +print "static const INDIC_TABLE_ELEMENT_TYPE indic_table[] = {" +for u in uu: + if u <= last: + continue + block = data[u][2] + + start = u//8*8 + end = start+1 + while end in uu and block == data[end][2]: + end += 1 + end = (end-1)//8*8 + 7 + + if start != last + 1: + if start - last <= 1+16*3: + print_block (None, last+1, start-1, data) + last = start-1 + else: + if last >= 0: + ends.append (last + 1) + offset += ends[-1] - starts[-1] + print + print + print "#define indic_offset_0x%04xu %d" % (start, offset) + starts.append (start) + + print_block (block, start, end, data) + last = end +ends.append (last + 1) +offset += ends[-1] - starts[-1] +print +print +occupancy = used * 100. / total +page_bits = 12 +print "}; /* Table items: %d; occupancy: %d%% */" % (offset, occupancy) +print +print "INDIC_TABLE_ELEMENT_TYPE" +print "hb_indic_get_categories (hb_codepoint_t u)" +print "{" +print " switch (u >> %d)" % page_bits +print " {" +pages = set([u>>page_bits for u in starts+ends+singles.keys()]) +for p in sorted(pages): + print " case 0x%0Xu:" % p + for u,d in singles.items (): + if p != u>>page_bits: continue + print " if (unlikely (u == 0x%04Xu)) return _(%s,%s);" % (u, short[0][d[0]], short[1][d[1]]) + for (start,end) in zip (starts, ends): + if p not in [start>>page_bits, end>>page_bits]: continue + offset = "indic_offset_0x%04xu" % start + print " if (hb_in_range<hb_codepoint_t> (u, 0x%04Xu, 0x%04Xu)) return indic_table[u - 0x%04Xu + %s];" % (start, end-1, start, offset) + print " break;" + print "" +print " default:" +print " break;" +print " }" +print " return _(x,x);" +print "}" +print +print "#undef _" +for i in range (2): + print + vv = values[i].keys () + vv.sort () + for v in vv: + print "#undef %s_%s" % \ + (what_short[i], short[i][v]) +print +print "/* == End of generated table == */" + +# Maintain at least 30% occupancy in the table */ +if occupancy < 30: + raise Exception ("Table too sparse, please investigate: ", occupancy) diff --git a/chromium/third_party/harfbuzz-ng/src/src/gen-unicode-ranges.py b/chromium/third_party/harfbuzz-ng/src/src/gen-unicode-ranges.py new file mode 100644 index 00000000000..3b59cd862df --- /dev/null +++ b/chromium/third_party/harfbuzz-ng/src/src/gen-unicode-ranges.py @@ -0,0 +1,52 @@ +# -*- 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). + +import io +import re +import sys + +reload(sys) +sys.setdefaultencoding('utf-8') + +print (u"""static Range os2UnicodeRangesSorted[] = +{""") + +args = sys.argv[1:] +input_file = args[0] + +with io.open(input_file, mode="r", encoding="utf-8") as f: + + all_ranges = []; + current_bit = 0 + while True: + line = f.readline().strip() + if not line: + break + fields = re.split(r'\t+', line) + if len(fields) == 3: + current_bit = fields[0] + fields = fields[1:] + elif len(fields) > 3: + raise Error("bad input :(.") + + name = fields[0] + ranges = re.split("-", fields[1]) + if len(ranges) != 2: + raise Error("bad input :(.") + + v = tuple((int(ranges[0], 16), int(ranges[1], 16), int(current_bit), name)) + all_ranges.append(v) + +all_ranges = sorted(all_ranges, key=lambda t: t[0]) + +for ranges in all_ranges: + start = ("0x%X" % ranges[0]).rjust(8) + end = ("0x%X" % ranges[1]).rjust(8) + bit = ("%s" % ranges[2]).rjust(3) + + print " {%s, %s, %s}, // %s" % (start, end, bit, ranges[3]) + +print (u"""};"""); diff --git a/chromium/third_party/harfbuzz-ng/src/src/gen-use-table.py b/chromium/third_party/harfbuzz-ng/src/src/gen-use-table.py new file mode 100755 index 00000000000..06817255c92 --- /dev/null +++ b/chromium/third_party/harfbuzz-ng/src/src/gen-use-table.py @@ -0,0 +1,484 @@ +#!/usr/bin/python + +import sys + +if len (sys.argv) != 5: + print >>sys.stderr, "usage: ./gen-use-table.py IndicSyllabicCategory.txt IndicPositionalCategory.txt UnicodeData.txt Blocks.txt" + sys.exit (1) + +BLACKLISTED_BLOCKS = ["Thai", "Lao", "Tibetan"] + +files = [file (x) for x in sys.argv[1:]] + +headers = [[f.readline () for i in range (2)] for j,f in enumerate(files) if j != 2] +headers.append (["UnicodeData.txt does not have a header."]) + +data = [{} for f in files] +values = [{} for f in files] +for i, f in enumerate (files): + for line in f: + + j = line.find ('#') + if j >= 0: + line = line[:j] + + fields = [x.strip () for x in line.split (';')] + if len (fields) == 1: + continue + + uu = fields[0].split ('..') + start = int (uu[0], 16) + if len (uu) == 1: + end = start + else: + end = int (uu[1], 16) + + t = fields[1 if i != 2 else 2] + + for u in range (start, end + 1): + data[i][u] = t + values[i][t] = values[i].get (t, 0) + end - start + 1 + +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][0x2060] = defaults[0] +data[0][0x20F0] = defaults[0] +for u in range (0xFE00, 0xFE0F + 1): + data[0][u] = defaults[0] + +# Merge data into one dict: +for i,v in enumerate (defaults): + values[i][v] = values[i].get (v, 0) + 1 +combined = {} +for i,d in enumerate (data): + for u,v in d.items (): + if i >= 2 and not u in combined: + continue + if not u in combined: + combined[u] = list (defaults) + combined[u][i] = v +combined = {k:v for k,v in combined.items() if v[3] not in BLACKLISTED_BLOCKS} +data = combined +del combined +num = len (data) + + +property_names = [ + # General_Category + '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', + # Indic_Syllabic_Category + 'Other', + 'Bindu', + 'Visarga', + 'Avagraha', + 'Nukta', + 'Virama', + 'Pure_Killer', + 'Invisible_Stacker', + 'Vowel_Independent', + 'Vowel_Dependent', + 'Vowel', + 'Consonant_Placeholder', + 'Consonant', + 'Consonant_Dead', + 'Consonant_With_Stacker', + 'Consonant_Prefixed', + 'Consonant_Preceding_Repha', + 'Consonant_Succeeding_Repha', + 'Consonant_Subjoined', + 'Consonant_Medial', + 'Consonant_Final', + 'Consonant_Head_Letter', + 'Modifying_Letter', + 'Tone_Letter', + 'Tone_Mark', + 'Gemination_Mark', + 'Cantillation_Mark', + 'Register_Shifter', + 'Syllable_Modifier', + 'Consonant_Killer', + 'Non_Joiner', + 'Joiner', + 'Number_Joiner', + 'Number', + 'Brahmi_Joining_Number', + # Indic_Positional_Category + 'Not_Applicable', + 'Right', + 'Left', + 'Visual_Order_Left', + 'Left_And_Right', + 'Top', + 'Bottom', + 'Top_And_Bottom', + 'Top_And_Right', + 'Top_And_Left', + 'Top_And_Left_And_Right', + 'Bottom_And_Left', + 'Bottom_And_Right', + 'Top_And_Bottom_And_Right', + 'Overstruck', +] + +class PropertyValue(object): + def __init__(self, name_): + self.name = name_ + def __str__(self): + return self.name + def __eq__(self, other): + return self.name == (other if isinstance(other, basestring) else other.name) + def __ne__(self, other): + return not (self == other) + +property_values = {} + +for name in property_names: + value = PropertyValue(name) + assert value not in property_values + assert value not in globals() + property_values[name] = value +globals().update(property_values) + + +def is_BASE(U, UISC, UGC): + return (UISC in [Number, Consonant, Consonant_Head_Letter, + #SPEC-DRAFT Consonant_Placeholder, + Tone_Letter, + Vowel_Independent #SPEC-DRAFT + ] or + (UGC == Lo and UISC in [Avagraha, Bindu, Consonant_Final, Consonant_Medial, + Consonant_Subjoined, Vowel, Vowel_Dependent])) +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 [0x104E, 0x2022, 0x11A3F, 0x11A45]) or + False # SPEC-DRAFT-OUTDATED! U == 0x002D + ) +def is_BASE_NUM(U, UISC, UGC): + return UISC == Brahmi_Joining_Number +def is_BASE_OTHER(U, UISC, UGC): + if UISC == Consonant_Placeholder: return True #SPEC-DRAFT + #SPEC-DRAFT return U in [0x00A0, 0x00D7, 0x2015, 0x2022, 0x25CC, 0x25FB, 0x25FC, 0x25FD, 0x25FE] + return U in [0x2015, 0x2022, 0x25FB, 0x25FC, 0x25FD, 0x25FE] +def is_CGJ(U, UISC, UGC): + return U == 0x034F +def is_CONS_FINAL(U, UISC, UGC): + return ((UISC == Consonant_Final and UGC != Lo) 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 +def is_CONS_MOD(U, UISC, UGC): + return UISC in [Nukta, Gemination_Mark, Consonant_Killer] +def is_CONS_SUB(U, UISC, UGC): + #SPEC-DRAFT return UISC == Consonant_Subjoined + return UISC == Consonant_Subjoined and UGC != Lo +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] +def is_HALANT_NUM(U, UISC, UGC): + return UISC == Number_Joiner +def is_ZWNJ(U, UISC, UGC): + return UISC == Non_Joiner +def is_ZWJ(U, UISC, UGC): + return UISC == Joiner +def is_Word_Joiner(U, UISC, UGC): + return U == 0x2060 +def is_OTHER(U, UISC, UGC): + #SPEC-OUTDATED return UGC == Zs # or any other SCRIPT_COMMON characters + return (UISC == Other + and not is_SYM_MOD(U, UISC, UGC) + and not is_CGJ(U, UISC, UGC) + and not is_Word_Joiner(U, UISC, UGC) + and not is_VARIATION_SELECTOR(U, UISC, UGC) + ) +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_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] +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 + 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 + return (UISC in [Tone_Mark, Cantillation_Mark, Register_Shifter, Visarga] or + (UGC != Lo and (UISC == Bindu or U in [0xAA29]))) + +use_mapping = { + 'B': is_BASE, + 'IND': is_BASE_IND, + 'N': is_BASE_NUM, + 'GB': is_BASE_OTHER, + 'CGJ': is_CGJ, + 'F': is_CONS_FINAL, + 'FM': is_CONS_FINAL_MOD, + 'M': is_CONS_MED, + 'CM': is_CONS_MOD, + 'SUB': is_CONS_SUB, + 'CS': is_CONS_WITH_STACKER, + 'H': is_HALANT, + 'HN': is_HALANT_NUM, + 'ZWNJ': is_ZWNJ, + 'ZWJ': is_ZWJ, + 'WJ': is_Word_Joiner, + 'O': is_OTHER, + 'Rsv': is_Reserved, + 'R': is_REPHA, + 'S': is_SYM, + 'SM': is_SYM_MOD, + 'VS': is_VARIATION_SELECTOR, + 'V': is_VOWEL, + 'VM': is_VOWEL_MOD, +} + +use_positions = { + 'F': { + 'Abv': [Top], + 'Blw': [Bottom], + 'Pst': [Right], + }, + 'M': { + 'Abv': [Top], + 'Blw': [Bottom, Bottom_And_Left], + 'Pst': [Right], + 'Pre': [Left], + }, + 'CM': { + 'Abv': [Top], + 'Blw': [Bottom], + }, + 'V': { + 'Abv': [Top, Top_And_Bottom, Top_And_Bottom_And_Right, Top_And_Right], + 'Blw': [Bottom, Overstruck, Bottom_And_Right], + 'Pst': [Right], + 'Pre': [Left, Top_And_Left, Top_And_Left_And_Right, Left_And_Right], + }, + 'VM': { + 'Abv': [Top], + 'Blw': [Bottom, Overstruck], + 'Pst': [Right], + 'Pre': [Left], + }, + 'SM': { + 'Abv': [Top], + 'Blw': [Bottom], + }, + 'H': None, + 'B': None, + 'FM': None, + 'SUB': None, +} + +def map_to_use(data): + out = {} + items = use_mapping.items() + for U,(UISC,UIPC,UGC,UBlock) in data.items(): + + # Resolve Indic_Syllabic_Category + + # TODO: These don't have UISC assigned in Unicode 8.0, but + # have UIPC + if U == 0x17DD: UISC = Vowel_Dependent + if 0x1CE2 <= U <= 0x1CE8: UISC = Cantillation_Mark + + # TODO: https://github.com/harfbuzz/harfbuzz/pull/627 + if 0x1BF2 <= U <= 0x1BF3: UISC = Nukta; UIPC = Bottom + + # TODO: U+1CED should only be allowed after some of + # 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; UIPC = Bottom + + # TODO: https://github.com/harfbuzz/harfbuzz/pull/609 + if U == 0x20F0: UISC = Cantillation_Mark; UIPC = Top + + # TODO: https://github.com/harfbuzz/harfbuzz/pull/626 + if U == 0xA8B4: UISC = Consonant_Medial + + 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] + + # Resolve Indic_Positional_Category + + # TODO: Not in Unicode 8.0 yet, but in spec. + if U == 0x1B6C: UIPC = Bottom + + # TODO: These should die, but have UIPC in Unicode 8.0 + if U in [0x953, 0x954]: UIPC = Not_Applicable + + # TODO: In USE's override list but not in Unicode 8.0 + if U == 0x103C: UIPC = Left + + # TODO: These are not in USE's override list that we have, nor are they in Unicode 8.0 + if 0xA926 <= U <= 0xA92A: UIPC = Top + if U == 0x111CA: UIPC = Bottom + if U == 0x11300: UIPC = Top + if U == 0x1133C: UIPC = Bottom + if U == 0x1171E: UIPC = Left # Correct?! + if 0x1CF2 <= U <= 0x1CF3: UIPC = Right + if 0x1CF8 <= U <= 0x1CF9: UIPC = Top + + assert (UIPC in [Not_Applicable, Visual_Order_Left] or + USE in use_positions), "%s %s %s %s %s" % (hex(U), UIPC, USE, UISC, UGC) + + pos_mapping = use_positions.get(USE, None) + if pos_mapping: + values = [k for k,v in pos_mapping.items() if v and UIPC in v] + assert len(values) == 1, "%s %s %s %s %s %s" % (hex(U), UIPC, USE, UISC, UGC, values) + USE = USE + values[0] + + out[U] = (USE, UBlock) + return out + +defaults = ('O', 'No_Block') +data = map_to_use(data) + +print "/* == Start of generated table == */" +print "/*" +print " * The following table is generated by running:" +print " *" +print " * ./gen-use-table.py IndicSyllabicCategory.txt IndicPositionalCategory.txt UnicodeData.txt Blocks.txt" +print " *" +print " * on files with these headers:" +print " *" +for h in headers: + for l in h: + print " * %s" % (l.strip()) +print " */" +print +print '#include "hb-ot-shape-complex-use-private.hh"' +print + +total = 0 +used = 0 +last_block = None +def print_block (block, start, end, data): + global total, used, last_block + if block and block != last_block: + print + print + print " /* %s */" % block + if start % 16: + print ' ' * (20 + (start % 16 * 6)), + num = 0 + assert start % 8 == 0 + assert (end+1) % 8 == 0 + for u in range (start, end+1): + if u % 16 == 0: + print + print " /* %04X */" % u, + if u in data: + num += 1 + d = data.get (u, defaults) + sys.stdout.write ("%6s," % d[0]) + + total += end - start + 1 + used += num + if block: + last_block = block + +uu = data.keys () +uu.sort () + +last = -100000 +num = 0 +offset = 0 +starts = [] +ends = [] +for k,v in sorted(use_mapping.items()): + if k in use_positions and use_positions[k]: continue + print "#define %s USE_%s /* %s */" % (k, k, v.__name__[3:]) +for k,v in sorted(use_positions.items()): + if not v: continue + for suf in v.keys(): + tag = k + suf + print "#define %s USE_%s" % (tag, tag) +print "" +print "static const USE_TABLE_ELEMENT_TYPE use_table[] = {" +for u in uu: + if u <= last: + continue + block = data[u][1] + + start = u//8*8 + end = start+1 + while end in uu and block == data[end][1]: + end += 1 + end = (end-1)//8*8 + 7 + + if start != last + 1: + if start - last <= 1+16*3: + print_block (None, last+1, start-1, data) + last = start-1 + else: + if last >= 0: + ends.append (last + 1) + offset += ends[-1] - starts[-1] + print + print + print "#define use_offset_0x%04xu %d" % (start, offset) + starts.append (start) + + print_block (block, start, end, data) + last = end +ends.append (last + 1) +offset += ends[-1] - starts[-1] +print +print +occupancy = used * 100. / total +page_bits = 12 +print "}; /* Table items: %d; occupancy: %d%% */" % (offset, occupancy) +print +print "USE_TABLE_ELEMENT_TYPE" +print "hb_use_get_category (hb_codepoint_t u)" +print "{" +print " switch (u >> %d)" % page_bits +print " {" +pages = set([u>>page_bits for u in starts+ends]) +for p in sorted(pages): + print " case 0x%0Xu:" % p + for (start,end) in zip (starts, ends): + if p not in [start>>page_bits, end>>page_bits]: continue + offset = "use_offset_0x%04xu" % start + print " if (hb_in_range<hb_codepoint_t> (u, 0x%04Xu, 0x%04Xu)) return use_table[u - 0x%04Xu + %s];" % (start, end-1, start, offset) + print " break;" + print "" +print " default:" +print " break;" +print " }" +print " return USE_O;" +print "}" +print +for k in sorted(use_mapping.keys()): + if k in use_positions and use_positions[k]: continue + print "#undef %s" % k +for k,v in sorted(use_positions.items()): + if not v: continue + for suf in v.keys(): + tag = k + suf + print "#undef %s" % tag +print +print "/* == End of generated table == */" + +# Maintain at least 50% occupancy in the table */ +if occupancy < 50: + raise Exception ("Table too sparse, please investigate: ", occupancy) diff --git a/chromium/third_party/harfbuzz-ng/src/src/harfbuzz-config.cmake.in b/chromium/third_party/harfbuzz-ng/src/src/harfbuzz-config.cmake.in new file mode 100644 index 00000000000..87b15721a3a --- /dev/null +++ b/chromium/third_party/harfbuzz-ng/src/src/harfbuzz-config.cmake.in @@ -0,0 +1,82 @@ +# Set these variables so that the `${prefix}/lib` expands to something we can +# remove. +set(_harfbuzz_remove_string "REMOVE_ME") +set(exec_prefix "${_harfbuzz_remove_string}") +set(prefix "${_harfbuzz_remove_string}") + +# Compute the installation prefix by stripping components from our current +# location. +get_filename_component(_harfbuzz_prefix "${CMAKE_CURRENT_LIST_DIR}" DIRECTORY) +get_filename_component(_harfbuzz_prefix "${_harfbuzz_prefix}" DIRECTORY) +set(_harfbuzz_libdir "@libdir@") +string(REPLACE "${_harfbuzz_remove_string}/" "" _harfbuzz_libdir "${_harfbuzz_libdir}") +set(_harfbuzz_libdir_iter "${_harfbuzz_libdir}") +while (_harfbuzz_libdir_iter) + get_filename_component(_harfbuzz_libdir_iter "${_harfbuzz_libdir_iter}" DIRECTORY) + get_filename_component(_harfbuzz_prefix "${_harfbuzz_prefix}" DIRECTORY) +endwhile () +unset(_harfbuzz_libdir_iter) + +# Get the include subdir. +set(_harfbuzz_includedir "@includedir@") +string(REPLACE "${_harfbuzz_remove_string}/" "" _harfbuzz_includedir "${_harfbuzz_includedir}") + +# Extract version information from libtool. +set(_harfbuzz_version_info "@HB_LIBTOOL_VERSION_INFO@") +string(REPLACE ":" ";" _harfbuzz_version_info "${_harfbuzz_version_info}") +list(GET _harfbuzz_version_info 0 + _harfbuzz_current) +list(GET _harfbuzz_version_info 1 + _harfbuzz_revision) +list(GET _harfbuzz_version_info 2 + _harfbuzz_age) +unset(_harfbuzz_version_info) + +if (APPLE) + set(_harfbuzz_lib_suffix ".0${CMAKE_SHARED_LIBRARY_SUFFIX}") +elseif (UNIX) + set(_harfbuzz_lib_suffix "${CMAKE_SHARED_LIBRARY_SUFFIX}.0.${_harfbuzz_current}.${_harfbuzz_revision}") +else () + # Unsupported. + set(harfbuzz_FOUND 0) +endif () + +# Add the libraries. +add_library(harfbuzz::harfbuzz SHARED IMPORTED) +set_target_properties(harfbuzz::harfbuzz PROPERTIES + INTERFACE_INCLUDE_DIRECTORIES "${_harfbuzz_prefix}/${_harfbuzz_includedir}/harfbuzz" + IMPORTED_LOCATION "${_harfbuzz_prefix}/${_harfbuzz_libdir}/libharfbuzz${_harfbuzz_lib_suffix}") + +add_library(harfbuzz::icu SHARED IMPORTED) +set_target_properties(harfbuzz::icu PROPERTIES + INTERFACE_INCLUDE_DIRECTORIES "${_harfbuzz_prefix}/${_harfbuzz_includedir}/harfbuzz" + INTERFACE_LINK_LIBRARIES "harfbuzz::harfbuzz" + IMPORTED_LOCATION "${_harfbuzz_prefix}/${_harfbuzz_libdir}/libharfbuzz-icu${_harfbuzz_lib_suffix}") + +add_library(harfbuzz::subset SHARED IMPORTED) +set_target_properties(harfbuzz::subset PROPERTIES + INTERFACE_INCLUDE_DIRECTORIES "${_harfbuzz_prefix}/${_harfbuzz_includedir}/harfbuzz" + INTERFACE_LINK_LIBRARIES "harfbuzz::harfbuzz" + IMPORTED_LOCATION "${_harfbuzz_prefix}/${_harfbuzz_libdir}/libharfbuzz-subset${_harfbuzz_lib_suffix}") + +# Only add the gobject library if it was built. +set(_harfbuzz_have_gobject "@have_gobject@") +if (_harfbuzz_have_gobject) + add_library(harfbuzz::gobject SHARED IMPORTED) + set_target_properties(harfbuzz::gobject PROPERTIES + INTERFACE_INCLUDE_DIRECTORIES "${_harfbuzz_prefix}/${_harfbuzz_includedir}/harfbuzz" + INTERFACE_LINK_LIBRARIES "harfbuzz::harfbuzz" + IMPORTED_LOCATION "${_harfbuzz_prefix}/${_harfbuzz_libdir}/libharfbuzz-gobject${_harfbuzz_lib_suffix}") +endif () + +# Clean out variables we used in our scope. +unset(_harfbuzz_lib_suffix) +unset(_harfbuzz_current) +unset(_harfbuzz_revision) +unset(_harfbuzz_age) +unset(_harfbuzz_includedir) +unset(_harfbuzz_libdir) +unset(_harfbuzz_prefix) +unset(exec_prefix) +unset(prefix) +unset(_harfbuzz_remove_string) diff --git a/chromium/third_party/harfbuzz-ng/src/src/harfbuzz-gobject.pc.in b/chromium/third_party/harfbuzz-ng/src/src/harfbuzz-gobject.pc.in new file mode 100644 index 00000000000..70083601901 --- /dev/null +++ b/chromium/third_party/harfbuzz-ng/src/src/harfbuzz-gobject.pc.in @@ -0,0 +1,12 @@ +prefix=%prefix% +exec_prefix=%exec_prefix% +libdir=%libdir% +includedir=%includedir% + +Name: harfbuzz +Description: HarfBuzz text shaping library GObject integration +Version: %VERSION% + +Requires: harfbuzz gobject-2.0 glib-2.0 +Libs: -L${libdir} -lharfbuzz-gobject +Cflags: -I${includedir}/harfbuzz diff --git a/chromium/third_party/harfbuzz-ng/src/src/harfbuzz-icu.pc.in b/chromium/third_party/harfbuzz-ng/src/src/harfbuzz-icu.pc.in new file mode 100644 index 00000000000..949869a3563 --- /dev/null +++ b/chromium/third_party/harfbuzz-ng/src/src/harfbuzz-icu.pc.in @@ -0,0 +1,13 @@ +prefix=%prefix% +exec_prefix=%exec_prefix% +libdir=%libdir% +includedir=%includedir% + +Name: harfbuzz +Description: HarfBuzz text shaping library ICU integration +Version: %VERSION% + +Requires: harfbuzz +Requires.private: icu-uc +Libs: -L${libdir} -lharfbuzz-icu +Cflags: -I${includedir}/harfbuzz diff --git a/chromium/third_party/harfbuzz-ng/src/src/harfbuzz-subset.pc.in b/chromium/third_party/harfbuzz-ng/src/src/harfbuzz-subset.pc.in new file mode 100644 index 00000000000..5da64b3f126 --- /dev/null +++ b/chromium/third_party/harfbuzz-ng/src/src/harfbuzz-subset.pc.in @@ -0,0 +1,12 @@ +prefix=%prefix% +exec_prefix=%exec_prefix% +libdir=%libdir% +includedir=%includedir% + +Name: harfbuzz +Description: HarfBuzz font subsetter +Version: %VERSION% + +Requires: harfbuzz +Libs: -L${libdir} -lharfbuzz-subset +Cflags: -I${includedir}/harfbuzz diff --git a/chromium/third_party/harfbuzz-ng/src/src/harfbuzz.pc.in b/chromium/third_party/harfbuzz-ng/src/src/harfbuzz.pc.in new file mode 100644 index 00000000000..661251c2d41 --- /dev/null +++ b/chromium/third_party/harfbuzz-ng/src/src/harfbuzz.pc.in @@ -0,0 +1,13 @@ +prefix=%prefix% +exec_prefix=%exec_prefix% +libdir=%libdir% +includedir=%includedir% + +Name: harfbuzz +Description: HarfBuzz text shaping library +Version: %VERSION% + +Libs: -L${libdir} -lharfbuzz +Libs.private: -lm %libs_private% +Requires.private: %requires_private% +Cflags: -I${includedir}/harfbuzz diff --git a/chromium/third_party/harfbuzz-ng/src/src/hb-aat-layout-ankr-table.hh b/chromium/third_party/harfbuzz-ng/src/src/hb-aat-layout-ankr-table.hh new file mode 100644 index 00000000000..d0453bd8807 --- /dev/null +++ b/chromium/third_party/harfbuzz-ng/src/src/hb-aat-layout-ankr-table.hh @@ -0,0 +1,80 @@ +/* + * 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_AAT_LAYOUT_ANKR_TABLE_HH +#define HB_AAT_LAYOUT_ANKR_TABLE_HH + +#include "hb-aat-layout-common-private.hh" + +#define HB_AAT_TAG_ankr HB_TAG('a','n','k','r') + + +namespace AAT { + + +/* + * ankr -- Anchor point + */ + +struct Anchor +{ + inline bool sanitize (hb_sanitize_context_t *c) const + { + TRACE_SANITIZE (this); + return_trace (c->check_struct (this)); + } + + FWORD xCoordinate; + FWORD yCoordinate; + public: + DEFINE_SIZE_STATIC (4); +}; + +struct ankr +{ + static const hb_tag_t tableTag = HB_AAT_TAG_ankr; + + inline bool sanitize (hb_sanitize_context_t *c) const + { + TRACE_SANITIZE (this); + return_trace (c->check_struct (this) && version == 0 && + lookupTable.sanitize (c, this) && + anchors.sanitize (c, this)); + } + + protected: + HBUINT16 version; /* Version number (set to zero) */ + HBUINT16 flags; /* Flags (currently unused; set to zero) */ + LOffsetTo<Lookup<HBUINT16> > lookupTable; /* Offset to the table's lookup table */ + LOffsetTo<ArrayOf<Anchor, HBUINT32> > + anchors; /* Offset to the glyph data table */ + + public: + DEFINE_SIZE_STATIC (12); +}; + +} /* namespace AAT */ + + +#endif /* HB_AAT_LAYOUT_ANKR_TABLE_HH */ diff --git a/chromium/third_party/harfbuzz-ng/src/src/hb-aat-layout-common-private.hh b/chromium/third_party/harfbuzz-ng/src/src/hb-aat-layout-common-private.hh new file mode 100644 index 00000000000..454b141fddb --- /dev/null +++ b/chromium/third_party/harfbuzz-ng/src/src/hb-aat-layout-common-private.hh @@ -0,0 +1,644 @@ +/* + * 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_AAT_LAYOUT_COMMON_PRIVATE_HH +#define HB_AAT_LAYOUT_COMMON_PRIVATE_HH + +#include "hb-aat-layout-private.hh" + + +namespace AAT { + +using namespace OT; + + +/* + * Binary Searching Tables + */ + +struct BinSearchHeader +{ + + inline bool sanitize (hb_sanitize_context_t *c) const + { + TRACE_SANITIZE (this); + return_trace (c->check_struct (this)); + } + + HBUINT16 unitSize; /* Size of a lookup unit for this search in bytes. */ + HBUINT16 nUnits; /* Number of units of the preceding size to be searched. */ + HBUINT16 searchRange; /* The value of unitSize times the largest power of 2 + * that is less than or equal to the value of nUnits. */ + HBUINT16 entrySelector; /* The log base 2 of the largest power of 2 less than + * or equal to the value of nUnits. */ + HBUINT16 rangeShift; /* The value of unitSize times the difference of the + * value of nUnits minus the largest power of 2 less + * than or equal to the value of nUnits. */ + public: + DEFINE_SIZE_STATIC (10); +}; + +template <typename Type> +struct BinSearchArrayOf +{ + inline const Type& operator [] (unsigned int i) const + { + if (unlikely (i >= header.nUnits)) return Null(Type); + return StructAtOffset<Type> (bytes, i * header.unitSize); + } + inline Type& operator [] (unsigned int i) + { + return StructAtOffset<Type> (bytes, i * header.unitSize); + } + inline unsigned int get_size (void) const + { return header.static_size + header.nUnits * header.unitSize; } + + inline 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> (bytes, 0).sanitize (c)); + + return_trace (true); + } + inline 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 = header.nUnits; + for (unsigned int i = 0; i < count; i++) + if (unlikely (!(*this)[i].sanitize (c, base))) + return_trace (false); + return_trace (true); + } + + template <typename T> + inline const Type *bsearch (const T &key) const + { + unsigned int size = header.unitSize; + int min = 0, max = (int) header.nUnits - 1; + while (min <= max) + { + int mid = (min + max) / 2; + const Type *p = (const Type *) (((const char *) bytes) + (mid * size)); + int c = p->cmp (key); + if (c < 0) + max = mid - 1; + else if (c > 0) + min = mid + 1; + else + return p; + } + return nullptr; + } + + private: + inline bool sanitize_shallow (hb_sanitize_context_t *c) const + { + TRACE_SANITIZE (this); + return_trace (header.sanitize (c) && + Type::static_size >= header.unitSize && + c->check_array (bytes, header.unitSize, header.nUnits)); + } + + protected: + BinSearchHeader header; + HBUINT8 bytes[VAR]; + public: + DEFINE_SIZE_ARRAY (10, bytes); +}; + + +/* + * Lookup Table + */ + +template <typename T> struct Lookup; + +template <typename T> +struct LookupFormat0 +{ + friend struct Lookup<T>; + + private: + inline const T* get_value (hb_codepoint_t glyph_id, unsigned int num_glyphs) const + { + if (unlikely (glyph_id >= num_glyphs)) return nullptr; + return &arrayZ[glyph_id]; + } + + inline bool sanitize (hb_sanitize_context_t *c) const + { + TRACE_SANITIZE (this); + return_trace (arrayZ.sanitize (c, c->num_glyphs)); + } + + protected: + HBUINT16 format; /* Format identifier--format = 0 */ + UnsizedArrayOf<T> + arrayZ; /* Array of lookup values, indexed by glyph index. */ + public: + DEFINE_SIZE_ARRAY (2, arrayZ); +}; + + +template <typename T> +struct LookupSegmentSingle +{ + inline int cmp (hb_codepoint_t g) const { + return g < first ? -1 : g <= last ? 0 : +1 ; + } + + inline bool sanitize (hb_sanitize_context_t *c) const + { + TRACE_SANITIZE (this); + return_trace (c->check_struct (this) && value.sanitize (c)); + } + + GlyphID last; /* Last GlyphID in this segment */ + GlyphID first; /* First GlyphID in this segment */ + T value; /* The lookup value (only one) */ + public: + DEFINE_SIZE_STATIC (4 + T::static_size); +}; + +template <typename T> +struct LookupFormat2 +{ + friend struct Lookup<T>; + + private: + inline const T* get_value (hb_codepoint_t glyph_id) const + { + const LookupSegmentSingle<T> *v = segments.bsearch (glyph_id); + return v ? &v->value : nullptr; + } + + inline bool sanitize (hb_sanitize_context_t *c) const + { + TRACE_SANITIZE (this); + return_trace (segments.sanitize (c)); + } + + protected: + HBUINT16 format; /* Format identifier--format = 2 */ + BinSearchArrayOf<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). */ + public: + DEFINE_SIZE_ARRAY (8, segments); +}; + +template <typename T> +struct LookupSegmentArray +{ + inline const T* get_value (hb_codepoint_t glyph_id, const void *base) const + { + return first <= glyph_id && glyph_id <= last ? &(base+valuesZ)[glyph_id - first] : nullptr; + } + + inline int cmp (hb_codepoint_t g) const { + return g < first ? -1 : g <= last ? 0 : +1 ; + } + + inline bool sanitize (hb_sanitize_context_t *c, const void *base) const + { + TRACE_SANITIZE (this); + return_trace (c->check_struct (this) && + first <= last && + valuesZ.sanitize (c, base, last - first + 1)); + } + + GlyphID last; /* Last GlyphID in this segment */ + GlyphID first; /* First GlyphID in this segment */ + OffsetTo<UnsizedArrayOf<T> > + valuesZ; /* A 16-bit offset from the start of + * the table to the data. */ + public: + DEFINE_SIZE_STATIC (6); +}; + +template <typename T> +struct LookupFormat4 +{ + friend struct Lookup<T>; + + private: + inline const T* get_value (hb_codepoint_t glyph_id) const + { + const LookupSegmentArray<T> *v = segments.bsearch (glyph_id); + return v ? v->get_value (glyph_id, this) : nullptr; + } + + inline bool sanitize (hb_sanitize_context_t *c) const + { + TRACE_SANITIZE (this); + return_trace (segments.sanitize (c, this)); + } + + protected: + HBUINT16 format; /* Format identifier--format = 2 */ + BinSearchArrayOf<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). */ + public: + DEFINE_SIZE_ARRAY (8, segments); +}; + +template <typename T> +struct LookupSingle +{ + inline int cmp (hb_codepoint_t g) const { return glyph.cmp (g); } + + inline bool sanitize (hb_sanitize_context_t *c) const + { + TRACE_SANITIZE (this); + return_trace (c->check_struct (this) && value.sanitize (c)); + } + + GlyphID glyph; /* Last GlyphID */ + T value; /* The lookup value (only one) */ + public: + DEFINE_SIZE_STATIC (4 + T::static_size); +}; + +template <typename T> +struct LookupFormat6 +{ + friend struct Lookup<T>; + + private: + inline const T* get_value (hb_codepoint_t glyph_id) const + { + const LookupSingle<T> *v = entries.bsearch (glyph_id); + return v ? &v->value : nullptr; + } + + inline bool sanitize (hb_sanitize_context_t *c) const + { + TRACE_SANITIZE (this); + return_trace (entries.sanitize (c)); + } + + protected: + HBUINT16 format; /* Format identifier--format = 6 */ + BinSearchArrayOf<LookupSingle<T> > + entries; /* The actual entries, sorted by glyph index. */ + public: + DEFINE_SIZE_ARRAY (8, entries); +}; + +template <typename T> +struct LookupFormat8 +{ + friend struct Lookup<T>; + + private: + inline const T* get_value (hb_codepoint_t glyph_id) const + { + return firstGlyph <= glyph_id && glyph_id - firstGlyph < glyphCount ? &valueArrayZ[glyph_id - firstGlyph] : nullptr; + } + + inline bool sanitize (hb_sanitize_context_t *c) const + { + TRACE_SANITIZE (this); + return_trace (c->check_struct (this) && valueArrayZ.sanitize (c, glyphCount)); + } + + protected: + HBUINT16 format; /* Format identifier--format = 6 */ + GlyphID 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> + valueArrayZ; /* The lookup values (indexed by the glyph index + * minus the value of firstGlyph). */ + public: + DEFINE_SIZE_ARRAY (6, valueArrayZ); +}; + +template <typename T> +struct Lookup +{ + inline const T* get_value (hb_codepoint_t glyph_id, unsigned int num_glyphs) const + { + switch (u.format) { + case 0: return u.format0.get_value (glyph_id, num_glyphs); + case 2: return u.format2.get_value (glyph_id); + case 4: return u.format4.get_value (glyph_id); + case 6: return u.format6.get_value (glyph_id); + case 8: return u.format8.get_value (glyph_id); + default:return nullptr; + } + } + + inline bool sanitize (hb_sanitize_context_t *c) const + { + TRACE_SANITIZE (this); + if (!u.format.sanitize (c)) return_trace (false); + switch (u.format) { + case 0: return_trace (u.format0.sanitize (c)); + case 2: return_trace (u.format2.sanitize (c)); + case 4: return_trace (u.format4.sanitize (c)); + case 6: return_trace (u.format6.sanitize (c)); + case 8: return_trace (u.format8.sanitize (c)); + default:return_trace (true); + } + } + + protected: + union { + HBUINT16 format; /* Format identifier */ + LookupFormat0<T> format0; + LookupFormat2<T> format2; + LookupFormat4<T> format4; + LookupFormat6<T> format6; + LookupFormat8<T> format8; + } u; + public: + DEFINE_SIZE_UNION (2, format); +}; + + +/* + * Extended State Table + */ + +template <typename T> +struct Entry +{ + inline bool sanitize (hb_sanitize_context_t *c, unsigned int count) const + { + TRACE_SANITIZE (this); + /* Note, we don't recurse-sanitize data because we don't access it. + * That said, in our DEFINE_SIZE_STATIC we access T::static_size, + * which ensures that data has a simple sanitize(). To be determined + * if I need to remove that as well. */ + return_trace (c->check_struct (this)); + } + + public: + HBUINT16 newState; /* Byte offset from beginning of state table + * to the new state. Really?!?! Or just state + * number? The latter in morx for sure. */ + HBUINT16 flags; /* Table specific. */ + T data; /* Optional offsets to per-glyph tables. */ + public: + DEFINE_SIZE_STATIC (4 + T::static_size); +}; + +template <> +struct Entry<void> +{ + inline bool sanitize (hb_sanitize_context_t *c, unsigned int count) const + { + TRACE_SANITIZE (this); + return_trace (c->check_struct (this)); + } + + public: + HBUINT16 newState; /* Byte offset from beginning of state table to the new state. */ + HBUINT16 flags; /* Table specific. */ + public: + DEFINE_SIZE_STATIC (4); +}; + +template <typename Extra> +struct StateTable +{ + inline unsigned int get_class (hb_codepoint_t glyph_id, unsigned int num_glyphs) const + { + const HBUINT16 *v = (this+classTable).get_value (glyph_id, num_glyphs); + return v ? *v : 1; + } + + inline const Entry<Extra> *get_entries () const + { + return (this+entryTable).arrayZ; + } + + inline const Entry<Extra> *get_entryZ (unsigned int state, unsigned int klass) const + { + if (unlikely (klass >= nClasses)) return nullptr; + + const HBUINT16 *states = (this+stateArrayTable).arrayZ; + const Entry<Extra> *entries = (this+entryTable).arrayZ; + + unsigned int entry = states[state * nClasses + klass]; + + return &entries[entry]; + } + + inline bool sanitize (hb_sanitize_context_t *c, + unsigned int *num_entries_out = nullptr) const + { + TRACE_SANITIZE (this); + if (unlikely (!(c->check_struct (this) && + classTable.sanitize (c, this)))) return_trace (false); + + const HBUINT16 *states = (this+stateArrayTable).arrayZ; + const Entry<Extra> *entries = (this+entryTable).arrayZ; + + unsigned int num_states = 1; + unsigned int num_entries = 0; + + unsigned int state = 0; + unsigned int entry = 0; + while (state < num_states) + { + if (unlikely (!c->check_array (states, + states[0].static_size * nClasses, + num_states))) + return_trace (false); + { /* Sweep new states. */ + const HBUINT16 *stop = &states[num_states * nClasses]; + for (const HBUINT16 *p = &states[state * nClasses]; p < stop; p++) + num_entries = MAX<unsigned int> (num_entries, *p + 1); + state = num_states; + } + + if (unlikely (!c->check_array (entries, + entries[0].static_size, + num_entries))) + return_trace (false); + { /* Sweep new entries. */ + const Entry<Extra> *stop = &entries[num_entries]; + for (const Entry<Extra> *p = &entries[entry]; p < stop; p++) + num_states = MAX<unsigned int> (num_states, p->newState + 1); + entry = num_entries; + } + } + + if (num_entries_out) + *num_entries_out = num_entries; + + return_trace (true); + } + + protected: + HBUINT32 nClasses; /* Number of classes, which is the number of indices + * in a single line in the state array. */ + OffsetTo<Lookup<HBUINT16>, HBUINT32> + classTable; /* Offset to the class table. */ + OffsetTo<UnsizedArrayOf<HBUINT16>, HBUINT32> + stateArrayTable;/* Offset to the state array. */ + OffsetTo<UnsizedArrayOf<Entry<Extra> >, HBUINT32> + entryTable; /* Offset to the entry array. */ + + public: + DEFINE_SIZE_STATIC (16); +}; + +template <typename EntryData> +struct StateTableDriver +{ + inline StateTableDriver (const StateTable<EntryData> &machine_, + hb_buffer_t *buffer_, + hb_face_t *face_) : + machine (machine_), + buffer (buffer_), + num_glyphs (face_->get_num_glyphs ()) {} + + template <typename context_t> + inline void drive (context_t *c) + { + hb_glyph_info_t *info = buffer->info; + + if (!c->in_place) + buffer->clear_output (); + + unsigned int state = 0; + bool last_was_dont_advance = false; + for (buffer->idx = 0;;) + { + unsigned int klass = buffer->idx < buffer->len ? + machine.get_class (info[buffer->idx].codepoint, num_glyphs) : + 0 /* End of text */; + const Entry<EntryData> *entry = machine.get_entryZ (state, klass); + if (unlikely (!entry)) + break; + + /* Unsafe-to-break before this if not in state 0, as things might + * go differently if we start from state 0 here. */ + if (state && buffer->idx) + { + /* If there's no action and we're just epsilon-transitioning to state 0, + * safe to break. */ + if (c->is_actionable (this, entry) || + !(entry->newState == 0 && entry->flags == context_t::DontAdvance)) + buffer->unsafe_to_break (buffer->idx - 1, buffer->idx + 1); + } + + /* Unsafe-to-break if end-of-text would kick in here. */ + if (buffer->idx + 2 <= buffer->len) + { + const Entry<EntryData> *end_entry = machine.get_entryZ (state, 0); + if (c->is_actionable (this, end_entry)) + buffer->unsafe_to_break (buffer->idx, buffer->idx + 2); + } + + if (unlikely (!c->transition (this, entry))) + break; + + last_was_dont_advance = (entry->flags & context_t::DontAdvance) && buffer->max_ops-- > 0; + + state = entry->newState; + + if (buffer->idx == buffer->len) + break; + + if (!last_was_dont_advance) + buffer->next_glyph (); + } + + if (!c->in_place) + { + for (; buffer->idx < buffer->len;) + buffer->next_glyph (); + buffer->swap_buffers (); + } + } + + public: + const StateTable<EntryData> &machine; + hb_buffer_t *buffer; + unsigned int num_glyphs; +}; + + + +struct hb_aat_apply_context_t : + hb_dispatch_context_t<hb_aat_apply_context_t, bool, HB_DEBUG_APPLY> +{ + inline const char *get_name (void) { return "APPLY"; } + template <typename T> + inline return_t dispatch (const T &obj) { return obj.apply (this); } + static return_t default_return_value (void) { return false; } + bool stop_sublookup_iteration (return_t r) const { return r; } + + hb_font_t *font; + hb_face_t *face; + hb_buffer_t *buffer; + hb_sanitize_context_t sanitizer; + + /* Unused. For debug tracing only. */ + unsigned int lookup_index; + unsigned int debug_depth; + + inline hb_aat_apply_context_t (hb_font_t *font_, + hb_buffer_t *buffer_, + hb_blob_t *table) : + font (font_), face (font->face), buffer (buffer_), + sanitizer (), lookup_index (0), debug_depth (0) + { + sanitizer.init (table); + sanitizer.num_glyphs = face->get_num_glyphs (); + sanitizer.start_processing (); + } + + inline void set_lookup_index (unsigned int i) { lookup_index = i; } + + inline ~hb_aat_apply_context_t (void) + { + sanitizer.end_processing (); + } +}; + + +} /* namespace AAT */ + + +#endif /* HB_AAT_LAYOUT_COMMON_PRIVATE_HH */ diff --git a/chromium/third_party/harfbuzz-ng/src/src/hb-aat-layout-kerx-table.hh b/chromium/third_party/harfbuzz-ng/src/src/hb-aat-layout-kerx-table.hh new file mode 100644 index 00000000000..ce7ca105faa --- /dev/null +++ b/chromium/third_party/harfbuzz-ng/src/src/hb-aat-layout-kerx-table.hh @@ -0,0 +1,339 @@ +/* + * Copyright © 2018 Ebrahim Byagowi + * 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_AAT_LAYOUT_KERX_TABLE_HH +#define HB_AAT_LAYOUT_KERX_TABLE_HH + +#include "hb-open-type-private.hh" +#include "hb-aat-layout-common-private.hh" + +#define HB_AAT_TAG_KERX HB_TAG('k','e','r','x') + + +namespace AAT { + +using namespace OT; + + +struct KerxFormat0Records +{ + inline bool sanitize (hb_sanitize_context_t *c) const + { + TRACE_SANITIZE (this); + return_trace (c->check_struct (this)); + } + + protected: + GlyphID left; + GlyphID right; + FWORD value; + public: + DEFINE_SIZE_STATIC (6); +}; + +struct KerxSubTableFormat0 +{ + // TODO(ebraminio) Enable when we got suitable BinSearchArrayOf + // inline int get_kerning (hb_codepoint_t left, hb_codepoint_t right) const + // { + // hb_glyph_pair_t pair = {left, right}; + // int i = pairs.bsearch (pair); + // if (i == -1) + // return 0; + // return pairs[i].get_kerning (); + // } + + inline bool sanitize (hb_sanitize_context_t *c) const + { + TRACE_SANITIZE (this); + return_trace (c->check_struct (this) && + c->check_array (records, records[0].static_size, nPairs)); + } + + protected: + // TODO(ebraminio): A custom version of "BinSearchArrayOf<KerxPair> pairs;" is + // needed here to use HBUINT32 instead + HBUINT32 nPairs; /* The number of kerning pairs in this subtable */ + HBUINT32 searchRange; /* The largest power of two less than or equal to the value of nPairs, + * multiplied by the size in bytes of an entry in the subtable. */ + HBUINT32 entrySelector; /* This is calculated as log2 of the largest power of two less + * than or equal to the value of nPairs. */ + HBUINT32 rangeShift; /* The value of nPairs minus the largest power of two less than or equal to nPairs. */ + KerxFormat0Records records[VAR]; /* VAR=nPairs */ + public: + DEFINE_SIZE_ARRAY (16, records); +}; + +struct KerxSubTableFormat1 +{ + inline bool sanitize (hb_sanitize_context_t *c) const + { + TRACE_SANITIZE (this); + return_trace (c->check_struct (this) && + stateHeader.sanitize (c)); + } + + protected: + StateTable<HBUINT16> stateHeader; + LOffsetTo<ArrayOf<HBUINT16> > valueTable; + public: + DEFINE_SIZE_STATIC (20); +}; + +// TODO(ebraminio): Maybe this can be replaced with Lookup<HBUINT16>? +struct KerxClassTable +{ + inline unsigned int get_class (hb_codepoint_t g) const { return classes[g - firstGlyph]; } + + inline bool sanitize (hb_sanitize_context_t *c) const + { + TRACE_SANITIZE (this); + return_trace (firstGlyph.sanitize (c) && classes.sanitize (c)); + } + + protected: + HBUINT16 firstGlyph; /* First glyph in class range. */ + ArrayOf<HBUINT16> classes; /* Glyph classes. */ + public: + DEFINE_SIZE_ARRAY (4, classes); +}; + +struct KerxSubTableFormat2 +{ + inline int get_kerning (hb_codepoint_t left, hb_codepoint_t right, const char *end) const + { + unsigned int l = (this+leftClassTable).get_class (left); + unsigned int r = (this+leftClassTable).get_class (left); + unsigned int offset = l * rowWidth + r * sizeof (FWORD); + const FWORD *arr = &(this+array); + if (unlikely ((const void *) arr < (const void *) this || (const void *) arr >= (const void *) end)) + return 0; + const FWORD *v = &StructAtOffset<FWORD> (arr, offset); + if (unlikely ((const void *) v < (const void *) arr || (const void *) (v + 1) > (const void *) end)) + return 0; + return *v; + } + + inline bool sanitize (hb_sanitize_context_t *c) const + { + TRACE_SANITIZE (this); + return_trace (c->check_struct (this) && + rowWidth.sanitize (c) && + leftClassTable.sanitize (c, this) && + rightClassTable.sanitize (c, this) && + array.sanitize (c, this)); + } + + protected: + HBUINT32 rowWidth; /* The width, in bytes, of a row in the table. */ + LOffsetTo<KerxClassTable> + leftClassTable; /* Offset from beginning of this subtable to + * left-hand class table. */ + LOffsetTo<KerxClassTable> + rightClassTable;/* Offset from beginning of this subtable to + * right-hand class table. */ + LOffsetTo<FWORD> + array; /* Offset from beginning of this subtable to + * the start of the kerning array. */ + public: + DEFINE_SIZE_STATIC (16); +}; + +struct KerxSubTableFormat4 +{ + inline bool sanitize (hb_sanitize_context_t *c) const + { + TRACE_SANITIZE (this); + return_trace (c->check_struct (this) && + rowWidth.sanitize (c) && + leftClassTable.sanitize (c, this) && + rightClassTable.sanitize (c, this) && + array.sanitize (c, this)); + } + + protected: + HBUINT32 rowWidth; /* The width, in bytes, of a row in the table. */ + LOffsetTo<KerxClassTable> + leftClassTable; /* Offset from beginning of this subtable to + * left-hand class table. */ + LOffsetTo<KerxClassTable> + rightClassTable;/* Offset from beginning of this subtable to + * right-hand class table. */ + LOffsetTo<FWORD> + array; /* Offset from beginning of this subtable to + * the start of the kerning array. */ + public: + DEFINE_SIZE_STATIC (16); +}; + +struct KerxSubTableFormat6 +{ + inline bool sanitize (hb_sanitize_context_t *c) const + { + TRACE_SANITIZE (this); + return_trace (c->check_struct (this) && + rowIndexTable.sanitize (c, this) && + columnIndexTable.sanitize (c, this) && + kerningArray.sanitize (c, this) && + kerningVector.sanitize (c, this)); + } + + protected: + HBUINT32 flags; + HBUINT16 rowCount; + HBUINT16 columnCount; + LOffsetTo<Lookup<HBUINT16> > rowIndexTable; + LOffsetTo<Lookup<HBUINT16> > columnIndexTable; + LOffsetTo<Lookup<HBUINT16> > kerningArray; + LOffsetTo<Lookup<HBUINT16> > kerningVector; + public: + DEFINE_SIZE_STATIC (24); +}; + +enum coverage_flags_t +{ + COVERAGE_VERTICAL_FLAG = 0x80u, + COVERAGE_CROSSSTREAM_FLAG = 0x40u, + COVERAGE_VARIATION_FLAG = 0x20u, + COVERAGE_PROCESS_DIRECTION = 0x10u, +}; + +struct KerxTable +{ + inline bool apply (hb_aat_apply_context_t *c, const AAT::ankr *ankr) const + { + TRACE_APPLY (this); + /* TODO */ + return_trace (false); + } + + inline unsigned int get_size (void) const { return length; } + + inline bool sanitize (hb_sanitize_context_t *c) const + { + TRACE_SANITIZE (this); + if (!c->check_struct (this)) + return_trace (false); + + switch (format) { + case 0: return u.format0.sanitize (c); + case 1: return u.format1.sanitize (c); + case 2: return u.format2.sanitize (c); + case 4: return u.format4.sanitize (c); + case 6: return u.format6.sanitize (c); + default:return_trace (false); + } + } + +protected: + HBUINT32 length; + HBUINT8 coverage; + HBUINT16 unused; + HBUINT8 format; + HBUINT32 tupleIndex; + union { + KerxSubTableFormat0 format0; + KerxSubTableFormat1 format1; + KerxSubTableFormat2 format2; + KerxSubTableFormat4 format4; + KerxSubTableFormat6 format6; + } u; +public: + DEFINE_SIZE_MIN (12); +}; + +struct SubtableGlyphCoverageArray +{ + inline bool sanitize (hb_sanitize_context_t *c) const + { + TRACE_SANITIZE (this); + return_trace (c->check_struct (this)); + } + + protected: + HBUINT32 length; + HBUINT32 coverage; + HBUINT32 tupleCount; + public: + DEFINE_SIZE_STATIC (12); +}; + +struct kerx +{ + static const hb_tag_t tableTag = HB_AAT_TAG_KERX; + + inline bool apply (hb_aat_apply_context_t *c, const AAT::ankr *ankr) const + { + TRACE_APPLY (this); + const KerxTable &table = StructAfter<KerxTable> (*this); + return_trace (table.apply (c, ankr)); + } + + inline bool sanitize (hb_sanitize_context_t *c) const + { + TRACE_SANITIZE (this); + if (!(c->check_struct (this))) + return_trace (false); + + /* TODO: Something like `morx`s ChainSubtable should be done here instead */ + const KerxTable *table = &StructAfter<KerxTable> (*this); + if (!(table->sanitize (c))) + return_trace (false); + + for (unsigned int i = 0; i < nTables - 1; ++i) + { + table = &StructAfter<KerxTable> (*table); + if (!(table->sanitize (c))) + return_trace (false); + } + + // If version is less than 3, we are done here; otherwise better to check footer also + if (version < 3) + return_trace (true); + + // TODO: Investigate why this just work on some fonts no matter of version + // const SubtableGlyphCoverageArray &footer = + // StructAfter<SubtableGlyphCoverageArray> (*table); + // return_trace (footer.sanitize (c)); + + return_trace (true); + } + + protected: + HBUINT16 version; + HBUINT16 padding; + HBUINT32 nTables; +/*KerxTable tables[VAR];*/ +/*SubtableGlyphCoverageArray coverage_array;*/ + public: + DEFINE_SIZE_STATIC (8); +}; + +} /* namespace AAT */ + + +#endif /* HB_AAT_LAYOUT_KERX_TABLE_HH */ diff --git a/chromium/third_party/harfbuzz-ng/src/src/hb-aat-layout-morx-table.hh b/chromium/third_party/harfbuzz-ng/src/src/hb-aat-layout-morx-table.hh new file mode 100644 index 00000000000..4cc2824214e --- /dev/null +++ b/chromium/third_party/harfbuzz-ng/src/src/hb-aat-layout-morx-table.hh @@ -0,0 +1,728 @@ +/* + * 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_AAT_LAYOUT_MORX_TABLE_HH +#define HB_AAT_LAYOUT_MORX_TABLE_HH + +#include "hb-open-type-private.hh" +#include "hb-aat-layout-common-private.hh" + +#define HB_AAT_TAG_MORX HB_TAG('m','o','r','x') + + +namespace AAT { + +using namespace OT; + + +struct RearrangementSubtable +{ + typedef void EntryData; + + struct driver_context_t + { + static const bool in_place = true; + enum Flags { + MarkFirst = 0x8000, /* If set, make the current glyph the first + * glyph to be rearranged. */ + DontAdvance = 0x4000, /* If set, don't advance to the next glyph + * before going to the new state. This means + * that the glyph index doesn't change, even + * if the glyph at that index has changed. */ + MarkLast = 0x2000, /* If set, make the current glyph the last + * glyph to be rearranged. */ + Reserved = 0x1FF0, /* These bits are reserved and should be set to 0. */ + Verb = 0x000F, /* The type of rearrangement specified. */ + }; + + inline driver_context_t (const RearrangementSubtable *table) : + ret (false), + start (0), end (0) {} + + inline bool is_actionable (StateTableDriver<EntryData> *driver, + const Entry<EntryData> *entry) + { + return (entry->flags & Verb) && start < end; + } + inline bool transition (StateTableDriver<EntryData> *driver, + const Entry<EntryData> *entry) + { + hb_buffer_t *buffer = driver->buffer; + unsigned int flags = entry->flags; + + if (flags & MarkFirst) + start = buffer->idx; + + if (flags & MarkLast) + end = MIN (buffer->idx + 1, buffer->len); + + if ((flags & Verb) && start < end) + { + /* The following map has two nibbles, for start-side + * and end-side. Values of 0,1,2 mean move that many + * to the other side. Value of 3 means move 2 and + * flip them. */ + const unsigned char map[16] = + { + 0x00, /* 0 no change */ + 0x10, /* 1 Ax => xA */ + 0x01, /* 2 xD => Dx */ + 0x11, /* 3 AxD => DxA */ + 0x20, /* 4 ABx => xAB */ + 0x30, /* 5 ABx => xBA */ + 0x02, /* 6 xCD => CDx */ + 0x03, /* 7 xCD => DCx */ + 0x12, /* 8 AxCD => CDxA */ + 0x13, /* 9 AxCD => DCxA */ + 0x21, /* 10 ABxD => DxAB */ + 0x31, /* 11 ABxD => DxBA */ + 0x22, /* 12 ABxCD => CDxAB */ + 0x32, /* 13 ABxCD => CDxBA */ + 0x23, /* 14 ABxCD => DCxAB */ + 0x33, /* 15 ABxCD => DCxBA */ + }; + + unsigned int m = map[flags & Verb]; + unsigned int l = MIN<unsigned int> (2, m >> 4); + unsigned int r = MIN<unsigned int> (2, 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, end); + + hb_glyph_info_t *info = buffer->info; + hb_glyph_info_t buf[4]; + + memcpy (buf, info + start, l * sizeof (buf[0])); + memcpy (buf + 2, info + end - r, r * sizeof (buf[0])); + + if (l != r) + memmove (info + start + r, info + start + l, (end - start - l - r) * sizeof (buf[0])); + + memcpy (info + start, buf + 2, r * sizeof (buf[0])); + memcpy (info + end - l, buf, l * sizeof (buf[0])); + if (reverse_l) + { + buf[0] = info[end - 1]; + info[end - 1] = info[end - 2]; + info[end - 2] = buf[0]; + } + if (reverse_r) + { + buf[0] = info[start]; + info[start] = info[start + 1]; + info[start + 1] = buf[0]; + } + } + } + + return true; + } + + public: + bool ret; + private: + unsigned int start; + unsigned int end; + }; + + inline bool apply (hb_aat_apply_context_t *c) const + { + TRACE_APPLY (this); + + driver_context_t dc (this); + + StateTableDriver<void> driver (machine, c->buffer, c->face); + driver.drive (&dc); + + return_trace (dc.ret); + } + + inline bool sanitize (hb_sanitize_context_t *c) const + { + TRACE_SANITIZE (this); + return_trace (machine.sanitize (c)); + } + + protected: + StateTable<EntryData> machine; + public: + DEFINE_SIZE_STATIC (16); +}; + +struct ContextualSubtable +{ + struct EntryData + { + HBUINT16 markIndex; /* Index of the substitution table for the + * marked glyph (use 0xFFFF for none). */ + HBUINT16 currentIndex; /* Index of the substitution table for the + * current glyph (use 0xFFFF for none). */ + public: + DEFINE_SIZE_STATIC (4); + }; + + struct driver_context_t + { + static const bool in_place = true; + enum Flags { + SetMark = 0x8000, /* If set, make the current glyph the marked glyph. */ + DontAdvance = 0x4000, /* If set, don't advance to the next glyph before + * going to the new state. */ + Reserved = 0x3FFF, /* These bits are reserved and should be set to 0. */ + }; + + inline driver_context_t (const ContextualSubtable *table) : + ret (false), + mark_set (false), + mark (0), + subs (table+table->substitutionTables) {} + + inline bool is_actionable (StateTableDriver<EntryData> *driver, + const Entry<EntryData> *entry) + { + hb_buffer_t *buffer = driver->buffer; + + if (buffer->idx == buffer->len && !mark_set) + return false; + + return entry->data.markIndex != 0xFFFF || entry->data.currentIndex != 0xFFFF; + } + inline bool transition (StateTableDriver<EntryData> *driver, + const Entry<EntryData> *entry) + { + hb_buffer_t *buffer = driver->buffer; + + /* 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 true; + + if (entry->data.markIndex != 0xFFFF) + { + const Lookup<GlyphID> &lookup = subs[entry->data.markIndex]; + hb_glyph_info_t *info = buffer->info; + const GlyphID *replacement = lookup.get_value (info[mark].codepoint, driver->num_glyphs); + if (replacement) + { + buffer->unsafe_to_break (mark, MIN (buffer->idx + 1, buffer->len)); + info[mark].codepoint = *replacement; + ret = true; + } + } + if (entry->data.currentIndex != 0xFFFF) + { + unsigned int idx = MIN (buffer->idx, buffer->len - 1); + const Lookup<GlyphID> &lookup = subs[entry->data.currentIndex]; + hb_glyph_info_t *info = buffer->info; + const GlyphID *replacement = lookup.get_value (info[idx].codepoint, driver->num_glyphs); + if (replacement) + { + info[idx].codepoint = *replacement; + ret = true; + } + } + + if (entry->flags & SetMark) + { + mark_set = true; + mark = buffer->idx; + } + + return true; + } + + public: + bool ret; + private: + bool mark_set; + unsigned int mark; + const UnsizedOffsetListOf<Lookup<GlyphID>, HBUINT32> &subs; + }; + + inline bool apply (hb_aat_apply_context_t *c) const + { + TRACE_APPLY (this); + + driver_context_t dc (this); + + StateTableDriver<EntryData> driver (machine, c->buffer, c->face); + driver.drive (&dc); + + return_trace (dc.ret); + } + + inline bool sanitize (hb_sanitize_context_t *c) const + { + TRACE_SANITIZE (this); + + unsigned int num_entries = 0; + if (unlikely (!machine.sanitize (c, &num_entries))) return_trace (false); + + unsigned int num_lookups = 0; + + const Entry<EntryData> *entries = machine.get_entries (); + for (unsigned int i = 0; i < num_entries; i++) + { + const EntryData &data = entries[i].data; + + if (data.markIndex != 0xFFFF) + num_lookups = MAX<unsigned int> (num_lookups, 1 + data.markIndex); + if (data.currentIndex != 0xFFFF) + num_lookups = MAX<unsigned int> (num_lookups, 1 + data.currentIndex); + } + + return_trace (substitutionTables.sanitize (c, this, num_lookups)); + } + + protected: + StateTable<EntryData> machine; + OffsetTo<UnsizedOffsetListOf<Lookup<GlyphID>, HBUINT32>, HBUINT32> + substitutionTables; + public: + DEFINE_SIZE_STATIC (20); +}; + +struct LigatureSubtable +{ + struct EntryData + { + HBUINT16 ligActionIndex; /* Index to the first ligActionTable entry + * for processing this group, if indicated + * by the flags. */ + public: + DEFINE_SIZE_STATIC (2); + }; + + struct driver_context_t + { + static const bool in_place = false; + enum Flags { + SetComponent = 0x8000, /* Push this glyph onto the component stack for + * eventual processing. */ + DontAdvance = 0x4000, /* Leave the glyph pointer at this glyph for the + next iteration. */ + PerformAction = 0x2000, /* Use the ligActionIndex to process a ligature + * group. */ + Reserved = 0x1FFF, /* These bits are reserved and should be set to 0. */ + }; + enum LigActionFlags { + LigActionLast = 0x80000000, /* This is the last action in the list. This also + * implies storage. */ + LigActionStore = 0x40000000, /* Store the ligature at the current cumulated index + * in the ligature table in place of the marked + * (i.e. currently-popped) glyph. */ + LigActionOffset = 0x3FFFFFFF, /* A 30-bit value which is sign-extended to 32-bits + * and added to the glyph ID, resulting in an index + * into the component table. */ + }; + + inline driver_context_t (const LigatureSubtable *table, + hb_aat_apply_context_t *c_) : + ret (false), + c (c_), + ligAction (table+table->ligAction), + component (table+table->component), + ligature (table+table->ligature), + match_length (0) {} + + inline bool is_actionable (StateTableDriver<EntryData> *driver, + const Entry<EntryData> *entry) + { + return !!(entry->flags & PerformAction); + } + inline bool transition (StateTableDriver<EntryData> *driver, + const Entry<EntryData> *entry) + { + hb_buffer_t *buffer = driver->buffer; + unsigned int flags = entry->flags; + + if (flags & SetComponent) + { + if (unlikely (match_length >= ARRAY_LENGTH (match_positions))) + return false; + + /* Never mark same index twice, in case DontAdvance was used... */ + if (match_length && match_positions[match_length - 1] == buffer->out_len) + match_length--; + + match_positions[match_length++] = buffer->out_len; + } + + if (flags & PerformAction) + { + unsigned int end = buffer->out_len; + unsigned int action_idx = entry->data.ligActionIndex; + unsigned int action; + unsigned int ligature_idx = 0; + do + { + if (unlikely (!match_length)) + return false; + + buffer->move_to (match_positions[--match_length]); + + const HBUINT32 &actionData = ligAction[action_idx]; + if (unlikely (!actionData.sanitize (&c->sanitizer))) return false; + action = actionData; + + uint32_t uoffset = action & LigActionOffset; + if (uoffset & 0x20000000) + uoffset += 0xC0000000; + int32_t offset = (int32_t) uoffset; + unsigned int component_idx = buffer->cur().codepoint + offset; + + const HBUINT16 &componentData = component[component_idx]; + if (unlikely (!componentData.sanitize (&c->sanitizer))) return false; + ligature_idx += componentData; + + if (action & (LigActionStore | LigActionLast)) + { + const GlyphID &ligatureData = ligature[ligature_idx]; + if (unlikely (!ligatureData.sanitize (&c->sanitizer))) return false; + hb_codepoint_t lig = ligatureData; + + match_positions[match_length++] = buffer->out_len; + buffer->replace_glyph (lig); + + //ligature_idx = 0; // XXX Yes or no? + } + else + { + buffer->skip_glyph (); + end--; + } + /* TODO merge_clusters / unsafe_to_break */ + + action_idx++; + } + while (!(action & LigActionLast)); + buffer->move_to (end); + } + + return true; + } + + public: + bool ret; + private: + hb_aat_apply_context_t *c; + const UnsizedArrayOf<HBUINT32> &ligAction; + const UnsizedArrayOf<HBUINT16> &component; + const UnsizedArrayOf<GlyphID> &ligature; + unsigned int match_length; + unsigned int match_positions[HB_MAX_CONTEXT_LENGTH]; + }; + + inline bool apply (hb_aat_apply_context_t *c) const + { + TRACE_APPLY (this); + + driver_context_t dc (this, c); + + StateTableDriver<EntryData> driver (machine, c->buffer, c->face); + driver.drive (&dc); + + return_trace (dc.ret); + } + + inline bool sanitize (hb_sanitize_context_t *c) const + { + TRACE_SANITIZE (this); + /* The rest of array sanitizations are done at run-time. */ + return_trace (c->check_struct (this) && machine.sanitize (c) && + ligAction && component && ligature); + } + + protected: + StateTable<EntryData> machine; + OffsetTo<UnsizedArrayOf<HBUINT32>, HBUINT32> + ligAction; /* Offset to the ligature action table. */ + OffsetTo<UnsizedArrayOf<HBUINT16>, HBUINT32> + component; /* Offset to the component table. */ + OffsetTo<UnsizedArrayOf<GlyphID>, HBUINT32> + ligature; /* Offset to the actual ligature lists. */ + public: + DEFINE_SIZE_STATIC (28); +}; + +struct NoncontextualSubtable +{ + inline bool apply (hb_aat_apply_context_t *c) const + { + TRACE_APPLY (this); + + bool ret = false; + unsigned int num_glyphs = c->face->get_num_glyphs (); + + hb_glyph_info_t *info = c->buffer->info; + 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); + if (replacement) + { + info[i].codepoint = *replacement; + ret = true; + } + } + + return_trace (ret); + } + + inline bool sanitize (hb_sanitize_context_t *c) const + { + TRACE_SANITIZE (this); + return_trace (substitute.sanitize (c)); + } + + protected: + Lookup<GlyphID> substitute; + public: + DEFINE_SIZE_MIN (2); +}; + +struct InsertionSubtable +{ + inline bool apply (hb_aat_apply_context_t *c) const + { + TRACE_APPLY (this); + /* TODO */ + return_trace (false); + } + + inline bool sanitize (hb_sanitize_context_t *c) const + { + TRACE_SANITIZE (this); + /* TODO */ + return_trace (true); + } +}; + + +struct Feature +{ + inline bool sanitize (hb_sanitize_context_t *c) const + { + TRACE_SANITIZE (this); + return_trace (c->check_struct (this)); + } + + public: + HBUINT16 featureType; /* The type of feature. */ + HBUINT16 featureSetting; /* The feature's setting (aka selector). */ + HBUINT32 enableFlags; /* Flags for the settings that this feature + * and setting enables. */ + HBUINT32 disableFlags; /* Complement of flags for the settings that this + * feature and setting disable. */ + + public: + DEFINE_SIZE_STATIC (12); +}; + + +struct ChainSubtable +{ + friend struct Chain; + + inline unsigned int get_size (void) const { return length; } + inline unsigned int get_type (void) const { return coverage & 0xFF; } + + enum Type { + Rearrangement = 0, + Contextual = 1, + Ligature = 2, + Noncontextual = 4, + Insertion = 5 + }; + + inline void apply (hb_aat_apply_context_t *c) const + { + dispatch (c); + } + + template <typename context_t> + inline typename context_t::return_t dispatch (context_t *c) 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)); + default: return_trace (c->default_return_value ()); + } + } + + inline bool sanitize (hb_sanitize_context_t *c) const + { + TRACE_SANITIZE (this); + if (!length.sanitize (c) || + length < min_size || + !c->check_range (this, length)) + return_trace (false); + + return_trace (dispatch (c)); + } + + protected: + HBUINT32 length; /* Total subtable length, including this header. */ + HBUINT32 coverage; /* Coverage flags and subtable type. */ + HBUINT32 subFeatureFlags;/* The 32-bit mask identifying which subtable this is. */ + union { + RearrangementSubtable rearrangement; + ContextualSubtable contextual; + LigatureSubtable ligature; + NoncontextualSubtable noncontextual; + InsertionSubtable insertion; + } u; + public: + DEFINE_SIZE_MIN (12); +}; + +struct Chain +{ + inline void apply (hb_aat_apply_context_t *c) const + { + const ChainSubtable *subtable = &StructAtOffset<ChainSubtable> (featureZ, featureZ[0].static_size * featureCount); + unsigned int count = subtableCount; + for (unsigned int i = 0; i < count; i++) + { + if (!c->buffer->message (c->font, "start chain subtable %d", c->lookup_index)) + { + c->set_lookup_index (c->lookup_index + 1); + continue; + } + + subtable->apply (c); + subtable = &StructAfter<ChainSubtable> (*subtable); + + (void) c->buffer->message (c->font, "end chain subtable %d", c->lookup_index); + + c->set_lookup_index (c->lookup_index + 1); + } + } + + inline unsigned int get_size (void) const { return length; } + + inline bool sanitize (hb_sanitize_context_t *c, unsigned int major) const + { + TRACE_SANITIZE (this); + if (!length.sanitize (c) || + length < min_size || + !c->check_range (this, length)) + return_trace (false); + + if (!c->check_array (featureZ, featureZ[0].static_size, featureCount)) + return_trace (false); + + const ChainSubtable *subtable = &StructAtOffset<ChainSubtable> (featureZ, featureZ[0].static_size * featureCount); + unsigned int count = subtableCount; + for (unsigned int i = 0; i < count; i++) + { + if (!subtable->sanitize (c)) + return_trace (false); + subtable = &StructAfter<ChainSubtable> (*subtable); + } + + return_trace (true); + } + + protected: + HBUINT32 defaultFlags; /* The default specification for subtables. */ + HBUINT32 length; /* Total byte count, including this header. */ + HBUINT32 featureCount; /* Number of feature subtable entries. */ + HBUINT32 subtableCount; /* The number of subtables in the chain. */ + + Feature featureZ[VAR]; /* Features. */ + ChainSubtable subtableX[VAR]; /* Subtables. */ + // subtableGlyphCoverageArray if major == 3 + + public: + DEFINE_SIZE_MIN (16); +}; + + +/* + * The 'mort'/'morx' Tables + */ + +struct morx +{ + static const hb_tag_t tableTag = HB_AAT_TAG_MORX; + + inline void apply (hb_aat_apply_context_t *c) const + { + c->set_lookup_index (0); + const Chain *chain = chains; + unsigned int count = chainCount; + for (unsigned int i = 0; i < count; i++) + { + chain->apply (c); + chain = &StructAfter<Chain> (*chain); + } + } + + inline bool sanitize (hb_sanitize_context_t *c) const + { + TRACE_SANITIZE (this); + if (!version.sanitize (c) || + (version.major >> (sizeof (HBUINT32) == 4 ? 1 : 0)) != 1 || + !chainCount.sanitize (c)) + return_trace (false); + + const Chain *chain = chains; + unsigned int count = chainCount; + for (unsigned int i = 0; i < count; i++) + { + if (!chain->sanitize (c, version.major)) + return_trace (false); + chain = &StructAfter<Chain> (*chain); + } + + return_trace (true); + } + + protected: + FixedVersion<>version; /* Version number of the glyph metamorphosis table. + * 1 for mort, 2 or 3 for morx. */ + HBUINT32 chainCount; /* Number of metamorphosis chains contained in this + * table. */ + Chain chains[VAR]; /* Chains. */ + + public: + DEFINE_SIZE_MIN (8); +}; + +} /* namespace AAT */ + + +#endif /* HB_AAT_LAYOUT_MORX_TABLE_HH */ diff --git a/chromium/third_party/harfbuzz-ng/src/src/hb-aat-layout-private.hh b/chromium/third_party/harfbuzz-ng/src/src/hb-aat-layout-private.hh new file mode 100644 index 00000000000..ce75c8e7192 --- /dev/null +++ b/chromium/third_party/harfbuzz-ng/src/src/hb-aat-layout-private.hh @@ -0,0 +1,43 @@ +/* + * 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_AAT_LAYOUT_PRIVATE_HH +#define HB_AAT_LAYOUT_PRIVATE_HH + +#include "hb-private.hh" + +#include "hb-font-private.hh" +#include "hb-buffer-private.hh" +#include "hb-open-type-private.hh" + + +HB_INTERNAL void +hb_aat_layout_substitute (hb_font_t *font, hb_buffer_t *buffer); + +HB_INTERNAL void +hb_aat_layout_position (hb_font_t *font, hb_buffer_t *buffer); + +#endif /* HB_AAT_LAYOUT_PRIVATE_HH */ diff --git a/chromium/third_party/harfbuzz-ng/src/src/hb-aat-layout-trak-table.hh b/chromium/third_party/harfbuzz-ng/src/src/hb-aat-layout-trak-table.hh new file mode 100644 index 00000000000..ab74373362a --- /dev/null +++ b/chromium/third_party/harfbuzz-ng/src/src/hb-aat-layout-trak-table.hh @@ -0,0 +1,201 @@ +/* + * Copyright © 2018 Ebrahim Byagowi + * 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_AAT_LAYOUT_TRAK_TABLE_HH +#define HB_AAT_LAYOUT_TRAK_TABLE_HH + +#include "hb-aat-layout-common-private.hh" +#include "hb-open-type-private.hh" + +#define HB_AAT_TAG_trak HB_TAG('t','r','a','k') + + +namespace AAT { + + +struct TrackTableEntry +{ + inline bool sanitize (hb_sanitize_context_t *c, const void *base, unsigned int size) const + { + TRACE_SANITIZE (this); + return_trace (c->check_struct (this) && (values.sanitize (c, base, size))); + } + + inline float get_track_value () const + { + return track.to_float (); + } + + inline int get_value (const void *base, unsigned int index) const + { + return (base+values)[index]; + } + + protected: + Fixed track; /* Track value for this record. */ + NameID trackNameID; /* The 'name' table index for this track */ + OffsetTo<UnsizedArrayOf<FWORD> > + values; /* Offset from start of tracking table to + * per-size tracking values for this track. */ + + public: + DEFINE_SIZE_STATIC (8); +}; + +struct TrackData +{ + inline bool sanitize (hb_sanitize_context_t *c, const void *base) const + { + TRACE_SANITIZE (this); + return_trace (c->check_struct (this) && + sizeTable.sanitize (c, base, nSizes) && + trackTable.sanitize (c, nTracks, base, nSizes)); + } + + inline float 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; + Fixed fixed_size; + fixed_size.set_float (csspx); + + /* XXX Clean this up. Make it work with nSizes==1 and 0. */ + + unsigned int sizes = nSizes; + + const TrackTableEntry *trackTableEntry = nullptr; + for (unsigned int i = 0; i < sizes; ++i) + // For now we only seek for track entries with zero tracking value + if (trackTable[i].get_track_value () == 0.) + trackTableEntry = &trackTable[0]; + + // We couldn't match any, exit + if (!trackTableEntry) return 0.; + + /* TODO bfind() */ + unsigned int size_index; + UnsizedArrayOf<Fixed> size_table = base+sizeTable; + for (size_index = 0; size_index < sizes; ++size_index) + if (size_table[size_index] >= fixed_size) + break; + + // TODO(ebraminio): We don't attempt to extrapolate to larger or + // smaller values for now but we should do, per spec + if (size_index == sizes) + return trackTableEntry->get_value (base, sizes - 1); + if (size_index == 0 || size_table[size_index] == fixed_size) + return trackTableEntry->get_value (base, size_index); + + float s0 = size_table[size_index - 1].to_float (); + float s1 = size_table[size_index].to_float (); + float t = (csspx - s0) / (s1 - s0); + return t * trackTableEntry->get_value (base, size_index) + + (1.0 - t) * trackTableEntry->get_value (base, size_index - 1); + } + + protected: + HBUINT16 nTracks; /* Number of separate tracks included in this table. */ + HBUINT16 nSizes; /* Number of point sizes included in this table. */ + LOffsetTo<UnsizedArrayOf<Fixed> > /* Offset to array[nSizes] of size values. */ + sizeTable; + UnsizedArrayOf<TrackTableEntry> + trackTable; /* Array[nTracks] of TrackTableEntry records. */ + + public: + DEFINE_SIZE_ARRAY (8, trackTable); +}; + +struct trak +{ + static const hb_tag_t tableTag = HB_AAT_TAG_trak; + + inline bool sanitize (hb_sanitize_context_t *c) const + { + TRACE_SANITIZE (this); + + return_trace (c->check_struct (this) && + horizData.sanitize (c, this, this) && + vertData.sanitize (c, this, this)); + } + + inline bool apply (hb_aat_apply_context_t *c) const + { + TRACE_APPLY (this); + + const float ptem = c->font->ptem; + if (ptem <= 0.f) + return_trace (false); + + hb_buffer_t *buffer = c->buffer; + if (HB_DIRECTION_IS_HORIZONTAL (buffer->props.direction)) + { + const TrackData &trackData = this+horizData; + float tracking = trackData.get_tracking (this, ptem); + hb_position_t advance_to_add = c->font->em_scalef_x (tracking / 2); + foreach_grapheme (buffer, start, end) + { + /* TODO This is wrong. */ + buffer->pos[start].x_advance += advance_to_add; + buffer->pos[end].x_advance += advance_to_add; + } + } + else + { + const TrackData &trackData = this+vertData; + float tracking = trackData.get_tracking (this, ptem); + hb_position_t advance_to_add = c->font->em_scalef_y (tracking / 2); + foreach_grapheme (buffer, start, end) + { + /* TODO This is wrong. */ + buffer->pos[start].y_advance += advance_to_add; + buffer->pos[end].y_advance += advance_to_add; + } + } + + return_trace (true); + } + + protected: + FixedVersion<> version; /* Version of the tracking table--currently + * 0x00010000u for version 1.0. */ + HBUINT16 format; /* Format of the tracking table */ + OffsetTo<TrackData> horizData; /* TrackData for horizontal text */ + OffsetTo<TrackData> vertData; /* TrackData for vertical text */ + HBUINT16 reserved; /* Reserved. Set to 0. */ + + public: + DEFINE_SIZE_MIN (12); +}; + +} /* namespace AAT */ + + +#endif /* HB_AAT_LAYOUT_TRAK_TABLE_HH */ diff --git a/chromium/third_party/harfbuzz-ng/src/src/hb-aat-layout.cc b/chromium/third_party/harfbuzz-ng/src/src/hb-aat-layout.cc new file mode 100644 index 00000000000..45268e3e7ab --- /dev/null +++ b/chromium/third_party/harfbuzz-ng/src/src/hb-aat-layout.cc @@ -0,0 +1,143 @@ +/* + * 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 + */ + +#include "hb-open-type-private.hh" + +#include "hb-ot-layout-private.hh" +#include "hb-ot-layout-gsubgpos-private.hh" + +#include "hb-aat-layout-private.hh" +#include "hb-aat-layout-ankr-table.hh" +#include "hb-aat-layout-kerx-table.hh" +#include "hb-aat-layout-morx-table.hh" +#include "hb-aat-layout-trak-table.hh" + +/* + * morx/kerx/trak + */ + +static inline const AAT::ankr& +_get_ankr (hb_face_t *face, hb_blob_t **blob = nullptr) +{ + if (unlikely (!hb_ot_shaper_face_data_ensure (face))) + { + if (blob) + *blob = hb_blob_get_empty (); + return OT::Null(AAT::ankr); + } + hb_ot_layout_t * layout = hb_ot_layout_from_face (face); + const AAT::ankr& ankr = *(layout->ankr.get ()); + if (blob) + *blob = layout->ankr.blob; + return ankr; +} + +static inline const AAT::kerx& +_get_kerx (hb_face_t *face, hb_blob_t **blob = nullptr) +{ + if (unlikely (!hb_ot_shaper_face_data_ensure (face))) + { + if (blob) + *blob = hb_blob_get_empty (); + return OT::Null(AAT::kerx); + } + hb_ot_layout_t * layout = hb_ot_layout_from_face (face); + /* XXX this doesn't call set_num_glyphs on sanitizer. */ + const AAT::kerx& kerx = *(layout->kerx.get ()); + if (blob) + *blob = layout->kerx.blob; + return kerx; +} + +static inline const AAT::morx& +_get_morx (hb_face_t *face, hb_blob_t **blob = nullptr) +{ + if (unlikely (!hb_ot_shaper_face_data_ensure (face))) + { + if (blob) + *blob = hb_blob_get_empty (); + return OT::Null(AAT::morx); + } + hb_ot_layout_t * layout = hb_ot_layout_from_face (face); + /* XXX this doesn't call set_num_glyphs on sanitizer. */ + const AAT::morx& morx = *(layout->morx.get ()); + if (blob) + *blob = layout->morx.blob; + return morx; +} + +static inline const AAT::trak& +_get_trak (hb_face_t *face, hb_blob_t **blob = nullptr) +{ + if (unlikely (!hb_ot_shaper_face_data_ensure (face))) + { + if (blob) + *blob = hb_blob_get_empty (); + return OT::Null(AAT::trak); + } + hb_ot_layout_t * layout = hb_ot_layout_from_face (face); + const AAT::trak& trak = *(layout->trak.get ()); + if (blob) + *blob = layout->trak.blob; + return trak; +} + +// static inline void +// _hb_aat_layout_create (hb_face_t *face) +// { +// OT::Sanitizer<AAT::morx> sanitizer; +// sanitizer.set_num_glyphs (face->get_num_glyphs ()); +// hb_blob_t *morx_blob = sanitizer.sanitize (face->reference_table (HB_AAT_TAG_MORX)); +// OT::Sanitizer<AAT::morx>::lock_instance (morx_blob); + +// if (0) +// { +// OT::Sanitizer<AAT::Lookup<OT::GlyphID> >::lock_instance (morx_blob)->get_value (1, face->get_num_glyphs ()); +// } +// } + +void +hb_aat_layout_substitute (hb_font_t *font, hb_buffer_t *buffer) +{ + hb_blob_t *blob; + const AAT::morx& morx = _get_morx (font->face, &blob); + + AAT::hb_aat_apply_context_t c (font, buffer, blob); + morx.apply (&c); +} + +void +hb_aat_layout_position (hb_font_t *font, hb_buffer_t *buffer) +{ + hb_blob_t *blob; + const AAT::ankr& ankr = _get_ankr (font->face, &blob); + const AAT::kerx& kerx = _get_kerx (font->face, &blob); + const AAT::trak& trak = _get_trak (font->face, &blob); + + AAT::hb_aat_apply_context_t c (font, buffer, blob); + kerx.apply (&c, &ankr); + trak.apply (&c); +} diff --git a/chromium/third_party/harfbuzz-ng/src/hb-atomic-private.hh b/chromium/third_party/harfbuzz-ng/src/src/hb-atomic-private.hh index a7e9b11af8b..a7e9b11af8b 100644 --- a/chromium/third_party/harfbuzz-ng/src/hb-atomic-private.hh +++ b/chromium/third_party/harfbuzz-ng/src/src/hb-atomic-private.hh diff --git a/chromium/third_party/harfbuzz-ng/src/hb-blob.cc b/chromium/third_party/harfbuzz-ng/src/src/hb-blob.cc index b5291f650cc..b5291f650cc 100644 --- a/chromium/third_party/harfbuzz-ng/src/hb-blob.cc +++ b/chromium/third_party/harfbuzz-ng/src/src/hb-blob.cc diff --git a/chromium/third_party/harfbuzz-ng/src/hb-blob.h b/chromium/third_party/harfbuzz-ng/src/src/hb-blob.h index fd561f73869..fd561f73869 100644 --- a/chromium/third_party/harfbuzz-ng/src/hb-blob.h +++ b/chromium/third_party/harfbuzz-ng/src/src/hb-blob.h diff --git a/chromium/third_party/harfbuzz-ng/src/src/hb-buffer-deserialize-json.hh b/chromium/third_party/harfbuzz-ng/src/src/hb-buffer-deserialize-json.hh new file mode 100644 index 00000000000..be374c77a5b --- /dev/null +++ b/chromium/third_party/harfbuzz-ng/src/src/hb-buffer-deserialize-json.hh @@ -0,0 +1,643 @@ + +#line 1 "hb-buffer-deserialize-json.rl" +/* + * Copyright © 2013 Google, Inc. + * + * This is part of HarfBuzz, a text shaping library. + * + * Permission is hereby granted, without written agreement and without + * license or royalty fees, to use, copy, modify, and distribute this + * software and its documentation for any purpose, provided that the + * above copyright notice and the following two paragraphs appear in + * all copies of this software. + * + * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR + * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES + * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN + * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, + * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS + * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO + * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + * + * Google Author(s): Behdad Esfahbod + */ + +#ifndef HB_BUFFER_DESERIALIZE_JSON_HH +#define HB_BUFFER_DESERIALIZE_JSON_HH + +#include "hb-private.hh" + + +#line 36 "hb-buffer-deserialize-json.hh" +static const unsigned char _deserialize_json_trans_keys[] = { + 0u, 0u, 9u, 123u, 9u, 34u, 97u, 103u, 120u, 121u, 34u, 34u, 9u, 58u, 9u, 57u, + 48u, 57u, 9u, 125u, 9u, 125u, 9u, 125u, 34u, 34u, 9u, 58u, 9u, 57u, 48u, 57u, + 9u, 125u, 9u, 125u, 108u, 108u, 34u, 34u, 9u, 58u, 9u, 57u, 9u, 125u, 9u, 125u, + 120u, 121u, 34u, 34u, 9u, 58u, 9u, 57u, 48u, 57u, 9u, 125u, 9u, 125u, 34u, 34u, + 9u, 58u, 9u, 57u, 48u, 57u, 9u, 125u, 9u, 125u, 34u, 34u, 9u, 58u, 9u, 57u, + 65u, 122u, 34u, 122u, 9u, 125u, 9u, 125u, 9u, 93u, 9u, 123u, 0u, 0u, 0 +}; + +static const char _deserialize_json_key_spans[] = { + 0, 115, 26, 7, 2, 1, 50, 49, + 10, 117, 117, 117, 1, 50, 49, 10, + 117, 117, 1, 1, 50, 49, 117, 117, + 2, 1, 50, 49, 10, 117, 117, 1, + 50, 49, 10, 117, 117, 1, 50, 49, + 58, 89, 117, 117, 85, 115, 0 +}; + +static const short _deserialize_json_index_offsets[] = { + 0, 0, 116, 143, 151, 154, 156, 207, + 257, 268, 386, 504, 622, 624, 675, 725, + 736, 854, 972, 974, 976, 1027, 1077, 1195, + 1313, 1316, 1318, 1369, 1419, 1430, 1548, 1666, + 1668, 1719, 1769, 1780, 1898, 2016, 2018, 2069, + 2119, 2178, 2268, 2386, 2504, 2590, 2706 +}; + +static const char _deserialize_json_indicies[] = { + 0, 0, 0, 0, 0, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 0, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 2, 1, 3, 3, 3, + 3, 3, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 3, 1, 4, 1, + 5, 1, 6, 7, 1, 1, 8, 1, + 9, 10, 1, 11, 1, 11, 11, 11, + 11, 11, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 11, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 12, 1, + 12, 12, 12, 12, 12, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 12, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 13, 1, 1, 14, + 15, 15, 15, 15, 15, 15, 15, 15, + 15, 1, 16, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 1, 18, 18, 18, + 18, 18, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 18, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 19, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 20, 1, 21, 21, 21, 21, 21, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 21, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 3, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 22, + 1, 18, 18, 18, 18, 18, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 18, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 19, 1, 1, 1, + 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 20, 1, 23, + 1, 23, 23, 23, 23, 23, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 23, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 24, 1, 24, 24, 24, 24, + 24, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 24, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 25, 1, 1, 26, 27, 27, 27, 27, + 27, 27, 27, 27, 27, 1, 28, 29, + 29, 29, 29, 29, 29, 29, 29, 29, + 1, 30, 30, 30, 30, 30, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 30, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 31, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 32, 1, 30, + 30, 30, 30, 30, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 30, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 31, 1, 1, 1, 29, 29, + 29, 29, 29, 29, 29, 29, 29, 29, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 32, 1, 33, 1, 34, + 1, 34, 34, 34, 34, 34, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 34, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 35, 1, 35, 35, 35, 35, + 35, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 35, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 36, 37, 37, 37, 37, + 37, 37, 37, 37, 37, 1, 38, 38, + 38, 38, 38, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 38, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 39, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 40, 1, 38, 38, 38, 38, + 38, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 38, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 39, + 1, 1, 1, 41, 41, 41, 41, 41, + 41, 41, 41, 41, 41, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 40, 1, 42, 43, 1, 44, 1, 44, + 44, 44, 44, 44, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 44, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 45, 1, 45, 45, 45, 45, 45, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 45, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 46, 1, + 1, 47, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 1, 49, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 1, 51, + 51, 51, 51, 51, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 51, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 52, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 53, 1, 51, 51, 51, + 51, 51, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 51, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 52, 1, 1, 1, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 53, 1, 54, 1, 54, 54, 54, + 54, 54, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 54, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 55, 1, + 55, 55, 55, 55, 55, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 55, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 56, 1, 1, 57, + 58, 58, 58, 58, 58, 58, 58, 58, + 58, 1, 59, 60, 60, 60, 60, 60, + 60, 60, 60, 60, 1, 61, 61, 61, + 61, 61, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 61, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 62, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 63, 1, 61, 61, 61, 61, 61, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 61, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 62, 1, + 1, 1, 60, 60, 60, 60, 60, 60, + 60, 60, 60, 60, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 63, + 1, 64, 1, 64, 64, 64, 64, 64, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 64, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 65, 1, 65, 65, + 65, 65, 65, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 65, 1, 66, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 67, 68, 68, + 68, 68, 68, 68, 68, 68, 68, 1, + 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, 1, 1, 1, 1, 1, 1, + 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, 1, 70, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 71, 71, + 1, 71, 71, 71, 71, 71, 71, 71, + 71, 71, 71, 1, 1, 1, 1, 1, + 1, 1, 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, 1, 1, 1, 1, + 71, 1, 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, 1, 72, 72, 72, + 72, 72, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 72, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 73, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 74, 1, 72, 72, 72, 72, 72, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 72, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 73, 1, + 1, 1, 75, 75, 75, 75, 75, 75, + 75, 75, 75, 75, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 74, + 1, 76, 76, 76, 76, 76, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 76, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 77, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 78, 1, 0, + 0, 0, 0, 0, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 0, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 2, 1, 1, 0 +}; + +static const char _deserialize_json_trans_targs[] = { + 1, 0, 2, 2, 3, 4, 18, 24, + 37, 5, 12, 6, 7, 8, 9, 11, + 9, 11, 10, 2, 44, 10, 44, 13, + 14, 15, 16, 17, 16, 17, 10, 2, + 44, 19, 20, 21, 22, 23, 10, 2, + 44, 23, 25, 31, 26, 27, 28, 29, + 30, 29, 30, 10, 2, 44, 32, 33, + 34, 35, 36, 35, 36, 10, 2, 44, + 38, 39, 40, 42, 43, 41, 10, 41, + 10, 2, 44, 43, 44, 45, 46 +}; + +static const char _deserialize_json_trans_actions[] = { + 0, 0, 1, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 2, 2, 2, + 0, 0, 3, 3, 4, 0, 5, 0, + 0, 2, 2, 2, 0, 0, 6, 6, + 7, 0, 0, 0, 2, 2, 8, 8, + 9, 0, 0, 0, 0, 0, 2, 2, + 2, 0, 0, 10, 10, 11, 0, 0, + 2, 2, 2, 0, 0, 12, 12, 13, + 0, 0, 0, 2, 2, 2, 14, 0, + 15, 15, 16, 0, 0, 0, 0 +}; + +static const int deserialize_json_start = 1; +static const int deserialize_json_first_final = 44; +static const int deserialize_json_error = 0; + +static const int deserialize_json_en_main = 1; + + +#line 97 "hb-buffer-deserialize-json.rl" + + +static hb_bool_t +_hb_buffer_deserialize_glyphs_json (hb_buffer_t *buffer, + const char *buf, + unsigned int buf_len, + const char **end_ptr, + hb_font_t *font) +{ + const char *p = buf, *pe = buf + buf_len; + + /* Ensure we have positions. */ + (void) hb_buffer_get_glyph_positions (buffer, nullptr); + + while (p < pe && ISSPACE (*p)) + p++; + if (p < pe && *p == (buffer->len ? ',' : '[')) + { + *end_ptr = ++p; + } + + const char *tok = nullptr; + int cs; + hb_glyph_info_t info = {0}; + hb_glyph_position_t pos = {0}; + +#line 466 "hb-buffer-deserialize-json.hh" + { + cs = deserialize_json_start; + } + +#line 471 "hb-buffer-deserialize-json.hh" + { + int _slen; + int _trans; + const unsigned char *_keys; + const char *_inds; + if ( p == pe ) + goto _test_eof; + if ( cs == 0 ) + goto _out; +_resume: + _keys = _deserialize_json_trans_keys + (cs<<1); + _inds = _deserialize_json_indicies + _deserialize_json_index_offsets[cs]; + + _slen = _deserialize_json_key_spans[cs]; + _trans = _inds[ _slen > 0 && _keys[0] <=(*p) && + (*p) <= _keys[1] ? + (*p) - _keys[0] : _slen ]; + + cs = _deserialize_json_trans_targs[_trans]; + + if ( _deserialize_json_trans_actions[_trans] == 0 ) + goto _again; + + switch ( _deserialize_json_trans_actions[_trans] ) { + case 1: +#line 38 "hb-buffer-deserialize-json.rl" + { + memset (&info, 0, sizeof (info)); + memset (&pos , 0, sizeof (pos )); +} + break; + case 5: +#line 43 "hb-buffer-deserialize-json.rl" + { + buffer->add_info (info); + if (buffer->in_error) + return false; + buffer->pos[buffer->len - 1] = pos; + *end_ptr = p; +} + break; + case 2: +#line 51 "hb-buffer-deserialize-json.rl" + { + tok = p; +} + break; + case 14: +#line 55 "hb-buffer-deserialize-json.rl" + { + if (!hb_font_glyph_from_string (font, + tok, p - tok, + &info.codepoint)) + return false; +} + break; + case 15: +#line 62 "hb-buffer-deserialize-json.rl" + { if (!parse_uint (tok, p, &info.codepoint)) return false; } + break; + case 8: +#line 63 "hb-buffer-deserialize-json.rl" + { if (!parse_uint (tok, p, &info.cluster )) return false; } + break; + case 10: +#line 64 "hb-buffer-deserialize-json.rl" + { if (!parse_int (tok, p, &pos.x_offset )) return false; } + break; + case 12: +#line 65 "hb-buffer-deserialize-json.rl" + { if (!parse_int (tok, p, &pos.y_offset )) return false; } + break; + case 3: +#line 66 "hb-buffer-deserialize-json.rl" + { if (!parse_int (tok, p, &pos.x_advance)) return false; } + break; + case 6: +#line 67 "hb-buffer-deserialize-json.rl" + { if (!parse_int (tok, p, &pos.y_advance)) return false; } + break; + case 16: +#line 62 "hb-buffer-deserialize-json.rl" + { if (!parse_uint (tok, p, &info.codepoint)) return false; } +#line 43 "hb-buffer-deserialize-json.rl" + { + buffer->add_info (info); + if (buffer->in_error) + return false; + buffer->pos[buffer->len - 1] = pos; + *end_ptr = p; +} + break; + case 9: +#line 63 "hb-buffer-deserialize-json.rl" + { if (!parse_uint (tok, p, &info.cluster )) return false; } +#line 43 "hb-buffer-deserialize-json.rl" + { + buffer->add_info (info); + if (buffer->in_error) + return false; + buffer->pos[buffer->len - 1] = pos; + *end_ptr = p; +} + break; + case 11: +#line 64 "hb-buffer-deserialize-json.rl" + { if (!parse_int (tok, p, &pos.x_offset )) return false; } +#line 43 "hb-buffer-deserialize-json.rl" + { + buffer->add_info (info); + if (buffer->in_error) + return false; + buffer->pos[buffer->len - 1] = pos; + *end_ptr = p; +} + break; + case 13: +#line 65 "hb-buffer-deserialize-json.rl" + { if (!parse_int (tok, p, &pos.y_offset )) return false; } +#line 43 "hb-buffer-deserialize-json.rl" + { + buffer->add_info (info); + if (buffer->in_error) + return false; + buffer->pos[buffer->len - 1] = pos; + *end_ptr = p; +} + break; + case 4: +#line 66 "hb-buffer-deserialize-json.rl" + { if (!parse_int (tok, p, &pos.x_advance)) return false; } +#line 43 "hb-buffer-deserialize-json.rl" + { + buffer->add_info (info); + if (buffer->in_error) + return false; + buffer->pos[buffer->len - 1] = pos; + *end_ptr = p; +} + break; + case 7: +#line 67 "hb-buffer-deserialize-json.rl" + { if (!parse_int (tok, p, &pos.y_advance)) return false; } +#line 43 "hb-buffer-deserialize-json.rl" + { + buffer->add_info (info); + if (buffer->in_error) + return false; + buffer->pos[buffer->len - 1] = pos; + *end_ptr = p; +} + break; +#line 624 "hb-buffer-deserialize-json.hh" + } + +_again: + if ( cs == 0 ) + goto _out; + if ( ++p != pe ) + goto _resume; + _test_eof: {} + _out: {} + } + +#line 125 "hb-buffer-deserialize-json.rl" + + + *end_ptr = p; + + return p == pe && *(p-1) != ']'; +} + +#endif /* HB_BUFFER_DESERIALIZE_JSON_HH */ diff --git a/chromium/third_party/harfbuzz-ng/src/src/hb-buffer-deserialize-json.rl b/chromium/third_party/harfbuzz-ng/src/src/hb-buffer-deserialize-json.rl new file mode 100644 index 00000000000..0f7d48ee298 --- /dev/null +++ b/chromium/third_party/harfbuzz-ng/src/src/hb-buffer-deserialize-json.rl @@ -0,0 +1,132 @@ +/* + * Copyright © 2013 Google, Inc. + * + * This is part of HarfBuzz, a text shaping library. + * + * Permission is hereby granted, without written agreement and without + * license or royalty fees, to use, copy, modify, and distribute this + * software and its documentation for any purpose, provided that the + * above copyright notice and the following two paragraphs appear in + * all copies of this software. + * + * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR + * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES + * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN + * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, + * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS + * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO + * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + * + * Google Author(s): Behdad Esfahbod + */ + +#ifndef HB_BUFFER_DESERIALIZE_JSON_HH +#define HB_BUFFER_DESERIALIZE_JSON_HH + +#include "hb-private.hh" + +%%{ + +machine deserialize_json; +alphtype unsigned char; +write data; + +action clear_item { + memset (&info, 0, sizeof (info)); + memset (&pos , 0, sizeof (pos )); +} + +action add_item { + buffer->add_info (info); + if (buffer->in_error) + return false; + buffer->pos[buffer->len - 1] = pos; + *end_ptr = p; +} + +action tok { + tok = p; +} + +action parse_glyph { + if (!hb_font_glyph_from_string (font, + tok, p - tok, + &info.codepoint)) + return false; +} + +action parse_gid { if (!parse_uint (tok, p, &info.codepoint)) return false; } +action parse_cluster { if (!parse_uint (tok, p, &info.cluster )) return false; } +action parse_x_offset { if (!parse_int (tok, p, &pos.x_offset )) return false; } +action parse_y_offset { if (!parse_int (tok, p, &pos.y_offset )) return false; } +action parse_x_advance { if (!parse_int (tok, p, &pos.x_advance)) return false; } +action parse_y_advance { if (!parse_int (tok, p, &pos.y_advance)) return false; } + +unum = '0' | [1-9] digit*; +num = '-'? unum; + +comma = space* ',' space*; +colon = space* ':' space*; + +glyph_id = unum; +glyph_name = alpha (alnum|'_'|'.'|'-')*; + +glyph_string = '"' (glyph_name >tok %parse_glyph) '"'; +glyph_number = (glyph_id >tok %parse_gid); + +glyph = "\"g\"" colon (glyph_string | glyph_number); +cluster = "\"cl\"" colon (unum >tok %parse_cluster); +xoffset = "\"dx\"" colon (num >tok %parse_x_offset); +yoffset = "\"dy\"" colon (num >tok %parse_y_offset); +xadvance= "\"ax\"" colon (num >tok %parse_x_advance); +yadvance= "\"ay\"" colon (num >tok %parse_y_advance); + +element = glyph | cluster | xoffset | yoffset | xadvance | yadvance; +item = + ( '{' space* element (comma element)* space* '}') + >clear_item + @add_item + ; + +main := space* item (comma item)* space* (','|']')?; + +}%% + +static hb_bool_t +_hb_buffer_deserialize_glyphs_json (hb_buffer_t *buffer, + const char *buf, + unsigned int buf_len, + const char **end_ptr, + hb_font_t *font) +{ + const char *p = buf, *pe = buf + buf_len; + + /* Ensure we have positions. */ + (void) hb_buffer_get_glyph_positions (buffer, nullptr); + + while (p < pe && ISSPACE (*p)) + p++; + if (p < pe && *p == (buffer->len ? ',' : '[')) + { + *end_ptr = ++p; + } + + const char *tok = nullptr; + int cs; + hb_glyph_info_t info = {0}; + hb_glyph_position_t pos = {0}; + %%{ + write init; + write exec; + }%% + + *end_ptr = p; + + return p == pe && *(p-1) != ']'; +} + +#endif /* HB_BUFFER_DESERIALIZE_JSON_HH */ diff --git a/chromium/third_party/harfbuzz-ng/src/hb-buffer-deserialize-text.hh b/chromium/third_party/harfbuzz-ng/src/src/hb-buffer-deserialize-text.hh index 426b1375876..a6ab0bbde67 100644 --- a/chromium/third_party/harfbuzz-ng/src/hb-buffer-deserialize-text.hh +++ b/chromium/third_party/harfbuzz-ng/src/src/hb-buffer-deserialize-text.hh @@ -34,274 +34,274 @@ #line 36 "hb-buffer-deserialize-text.hh" static const unsigned char _deserialize_text_trans_keys[] = { - 0u, 0u, 9u, 122u, 45u, 57u, 48u, 57u, 45u, 57u, 48u, 57u, 48u, 57u, 45u, 57u, - 48u, 57u, 44u, 44u, 45u, 57u, 48u, 57u, 44u, 57u, 9u, 124u, 9u, 124u, 0u, 0u, - 9u, 122u, 9u, 124u, 9u, 124u, 9u, 124u, 9u, 124u, 9u, 124u, 9u, 124u, 9u, 124u, + 0u, 0u, 9u, 122u, 45u, 57u, 48u, 57u, 45u, 57u, 48u, 57u, 48u, 57u, 45u, 57u, + 48u, 57u, 44u, 44u, 45u, 57u, 48u, 57u, 44u, 57u, 9u, 124u, 9u, 124u, 0u, 0u, + 9u, 122u, 9u, 124u, 9u, 124u, 9u, 124u, 9u, 124u, 9u, 124u, 9u, 124u, 9u, 124u, 9u, 124u, 9u, 124u, 9u, 124u, 0 }; static const char _deserialize_text_key_spans[] = { - 0, 114, 13, 10, 13, 10, 10, 13, - 10, 1, 13, 10, 14, 116, 116, 0, - 114, 116, 116, 116, 116, 116, 116, 116, + 0, 114, 13, 10, 13, 10, 10, 13, + 10, 1, 13, 10, 14, 116, 116, 0, + 114, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116 }; static const short _deserialize_text_index_offsets[] = { - 0, 0, 115, 129, 140, 154, 165, 176, - 190, 201, 203, 217, 228, 243, 360, 477, - 478, 593, 710, 827, 944, 1061, 1178, 1295, + 0, 0, 115, 129, 140, 154, 165, 176, + 190, 201, 203, 217, 228, 243, 360, 477, + 478, 593, 710, 827, 944, 1061, 1178, 1295, 1412, 1529, 1646 }; static const char _deserialize_text_indicies[] = { - 0, 0, 0, 0, 0, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 0, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 2, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 1, 1, 1, 1, 1, 1, - 1, 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, 1, 1, 1, 1, 1, - 1, 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, 1, 5, 1, 1, 6, - 7, 7, 7, 7, 7, 7, 7, 7, - 7, 1, 8, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 1, 10, 1, 1, - 11, 12, 12, 12, 12, 12, 12, 12, - 12, 12, 1, 13, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 1, 15, 16, - 16, 16, 16, 16, 16, 16, 16, 16, - 1, 17, 1, 1, 18, 19, 19, 19, - 19, 19, 19, 19, 19, 19, 1, 20, - 21, 21, 21, 21, 21, 21, 21, 21, - 21, 1, 22, 1, 23, 1, 1, 24, - 25, 25, 25, 25, 25, 25, 25, 25, - 25, 1, 26, 27, 27, 27, 27, 27, - 27, 27, 27, 27, 1, 22, 1, 1, - 1, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 1, 28, 28, 28, 28, - 28, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 28, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 29, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 30, 1, 1, 31, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 32, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 33, - 1, 34, 34, 34, 34, 34, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 34, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 35, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 36, 1, 1, 0, - 0, 0, 0, 0, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 0, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 2, 3, - 3, 3, 3, 3, 3, 3, 3, 3, - 1, 1, 1, 1, 1, 1, 1, 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, 1, 1, 1, 1, 1, 1, 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, 1, 28, 28, 28, 28, 28, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 28, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 29, 1, 1, 1, - 1, 37, 37, 37, 37, 37, 37, 37, - 37, 37, 37, 1, 1, 1, 30, 1, - 1, 31, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 32, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 33, 1, 38, - 38, 38, 38, 38, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 38, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 39, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 40, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 41, 1, 42, 42, 42, 42, - 42, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 42, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 43, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 44, - 1, 42, 42, 42, 42, 42, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 42, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 43, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 44, 1, 38, 38, - 38, 38, 38, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 38, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 39, 1, 1, 1, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 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, 1, 1, - 1, 1, 40, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 41, 1, 45, 45, 45, 45, 45, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 45, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 46, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 47, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 48, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 49, 1, - 50, 50, 50, 50, 50, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 50, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 51, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 52, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 53, 1, 50, 50, 50, - 50, 50, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 50, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 51, - 1, 1, 1, 1, 27, 27, 27, 27, - 27, 27, 27, 27, 27, 27, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 52, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 53, 1, 45, 45, 45, 45, 45, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 45, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 46, 1, 1, 1, - 1, 54, 54, 54, 54, 54, 54, 54, - 54, 54, 54, 1, 1, 1, 1, 1, - 1, 47, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 48, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 49, 1, 28, - 28, 28, 28, 28, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 28, 1, - 1, 1, 1, 1, 1, 1, 1, 1, - 1, 29, 1, 55, 55, 1, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, - 1, 1, 1, 30, 1, 1, 31, 55, - 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, - 55, 1, 1, 32, 1, 55, 1, 55, - 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, + 0, 0, 0, 0, 0, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 0, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 2, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 1, 1, 1, 1, 1, 1, + 1, 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, 1, 1, 1, 1, 1, + 1, 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, 1, 5, 1, 1, 6, + 7, 7, 7, 7, 7, 7, 7, 7, + 7, 1, 8, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 1, 10, 1, 1, + 11, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 1, 13, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 1, 15, 16, + 16, 16, 16, 16, 16, 16, 16, 16, + 1, 17, 1, 1, 18, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 1, 20, + 21, 21, 21, 21, 21, 21, 21, 21, + 21, 1, 22, 1, 23, 1, 1, 24, + 25, 25, 25, 25, 25, 25, 25, 25, + 25, 1, 26, 27, 27, 27, 27, 27, + 27, 27, 27, 27, 1, 22, 1, 1, + 1, 21, 21, 21, 21, 21, 21, 21, + 21, 21, 21, 1, 28, 28, 28, 28, + 28, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 28, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 29, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 30, 1, 1, 31, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 32, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 33, + 1, 34, 34, 34, 34, 34, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 34, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 35, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 36, 1, 1, 0, + 0, 0, 0, 0, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 0, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 2, 3, + 3, 3, 3, 3, 3, 3, 3, 3, + 1, 1, 1, 1, 1, 1, 1, 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, 1, 1, 1, 1, 1, 1, 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, 1, 28, 28, 28, 28, 28, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 28, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 29, 1, 1, 1, + 1, 37, 37, 37, 37, 37, 37, 37, + 37, 37, 37, 1, 1, 1, 30, 1, + 1, 31, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 32, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 33, 1, 38, + 38, 38, 38, 38, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 38, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 39, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 40, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 41, 1, 42, 42, 42, 42, + 42, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 42, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 43, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 44, + 1, 42, 42, 42, 42, 42, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 42, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 43, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 44, 1, 38, 38, + 38, 38, 38, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 38, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 39, 1, 1, 1, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 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, 1, 1, + 1, 1, 40, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 41, 1, 45, 45, 45, 45, 45, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 45, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 46, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 47, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 48, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 49, 1, + 50, 50, 50, 50, 50, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 50, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 51, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 52, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 53, 1, 50, 50, 50, + 50, 50, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 50, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 51, + 1, 1, 1, 1, 27, 27, 27, 27, + 27, 27, 27, 27, 27, 27, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 52, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 53, 1, 45, 45, 45, 45, 45, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 45, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 46, 1, 1, 1, + 1, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 1, 1, 1, 1, 1, + 1, 47, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 48, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 49, 1, 28, + 28, 28, 28, 28, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 28, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 29, 1, 55, 55, 1, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, + 1, 1, 1, 30, 1, 1, 31, 55, + 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, + 55, 1, 1, 32, 1, 55, 1, 55, + 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 1, 33, 1, 0 }; static const char _deserialize_text_trans_targs[] = { - 1, 0, 13, 17, 26, 3, 18, 21, - 18, 21, 5, 19, 20, 19, 20, 22, - 25, 8, 9, 12, 9, 12, 10, 11, - 23, 24, 23, 24, 14, 2, 6, 7, - 15, 16, 14, 15, 16, 17, 14, 4, - 15, 16, 14, 15, 16, 14, 2, 7, + 1, 0, 13, 17, 26, 3, 18, 21, + 18, 21, 5, 19, 20, 19, 20, 22, + 25, 8, 9, 12, 9, 12, 10, 11, + 23, 24, 23, 24, 14, 2, 6, 7, + 15, 16, 14, 15, 16, 17, 14, 4, + 15, 16, 14, 15, 16, 14, 2, 7, 15, 16, 14, 2, 15, 16, 25, 26 }; static const char _deserialize_text_trans_actions[] = { - 0, 0, 1, 1, 1, 2, 2, 2, - 0, 0, 2, 2, 2, 0, 0, 2, - 2, 2, 2, 2, 0, 0, 3, 2, - 2, 2, 0, 0, 4, 5, 5, 5, - 4, 4, 0, 0, 0, 0, 6, 7, - 6, 6, 8, 8, 8, 9, 10, 10, + 0, 0, 1, 1, 1, 2, 2, 2, + 0, 0, 2, 2, 2, 0, 0, 2, + 2, 2, 2, 2, 0, 0, 3, 2, + 2, 2, 0, 0, 4, 5, 5, 5, + 4, 4, 0, 0, 0, 0, 6, 7, + 6, 6, 8, 8, 8, 9, 10, 10, 9, 9, 11, 12, 11, 11, 0, 0 }; static const char _deserialize_text_eof_actions[] = { - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 4, 0, 0, - 0, 4, 6, 8, 8, 6, 9, 11, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 4, 0, 0, + 0, 4, 6, 8, 8, 6, 9, 11, 11, 9, 4 }; @@ -338,7 +338,7 @@ _hb_buffer_deserialize_glyphs_text (hb_buffer_t *buffer, int cs; hb_glyph_info_t info = {0}; hb_glyph_position_t pos = {0}; - + #line 343 "hb-buffer-deserialize-text.hh" { cs = deserialize_text_start; diff --git a/chromium/third_party/harfbuzz-ng/src/src/hb-buffer-deserialize-text.rl b/chromium/third_party/harfbuzz-ng/src/src/hb-buffer-deserialize-text.rl new file mode 100644 index 00000000000..fd9be42df14 --- /dev/null +++ b/chromium/third_party/harfbuzz-ng/src/src/hb-buffer-deserialize-text.rl @@ -0,0 +1,126 @@ +/* + * Copyright © 2013 Google, Inc. + * + * This is part of HarfBuzz, a text shaping library. + * + * Permission is hereby granted, without written agreement and without + * license or royalty fees, to use, copy, modify, and distribute this + * software and its documentation for any purpose, provided that the + * above copyright notice and the following two paragraphs appear in + * all copies of this software. + * + * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR + * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES + * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN + * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, + * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS + * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO + * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + * + * Google Author(s): Behdad Esfahbod + */ + +#ifndef HB_BUFFER_DESERIALIZE_TEXT_HH +#define HB_BUFFER_DESERIALIZE_TEXT_HH + +#include "hb-private.hh" + +%%{ + +machine deserialize_text; +alphtype unsigned char; +write data; + +action clear_item { + memset (&info, 0, sizeof (info)); + memset (&pos , 0, sizeof (pos )); +} + +action add_item { + buffer->add_info (info); + if (buffer->in_error) + return false; + buffer->pos[buffer->len - 1] = pos; + *end_ptr = p; +} + +action tok { + tok = p; +} + +action parse_glyph { + if (!hb_font_glyph_from_string (font, + tok, p - tok, + &info.codepoint)) + return false; +} + +action parse_cluster { if (!parse_uint (tok, p, &info.cluster )) return false; } +action parse_x_offset { if (!parse_int (tok, p, &pos.x_offset )) return false; } +action parse_y_offset { if (!parse_int (tok, p, &pos.y_offset )) return false; } +action parse_x_advance { if (!parse_int (tok, p, &pos.x_advance)) return false; } +action parse_y_advance { if (!parse_int (tok, p, &pos.y_advance)) return false; } + +unum = '0' | [1-9] digit*; +num = '-'? unum; + +glyph_id = unum; +glyph_name = alpha (alnum|'_'|'.'|'-')*; + +glyph = (glyph_id | glyph_name) >tok %parse_glyph; +cluster = '=' (unum >tok %parse_cluster); +offsets = '@' (num >tok %parse_x_offset) ',' (num >tok %parse_y_offset ); +advances= '+' (num >tok %parse_x_advance) (',' (num >tok %parse_y_advance))?; +item = + ( + glyph + cluster? + offsets? + advances? + ) + >clear_item + %add_item + ; + +main := space* item (space* '|' space* item)* space* ('|'|']')?; + +}%% + +static hb_bool_t +_hb_buffer_deserialize_glyphs_text (hb_buffer_t *buffer, + const char *buf, + unsigned int buf_len, + const char **end_ptr, + hb_font_t *font) +{ + const char *p = buf, *pe = buf + buf_len; + + /* Ensure we have positions. */ + (void) hb_buffer_get_glyph_positions (buffer, nullptr); + + while (p < pe && ISSPACE (*p)) + p++; + if (p < pe && *p == (buffer->len ? '|' : '[')) + { + *end_ptr = ++p; + } + + const char *eof = pe, *tok = nullptr; + int cs; + hb_glyph_info_t info = {0}; + hb_glyph_position_t pos = {0}; + %%{ + write init; + write exec; + }%% + + *end_ptr = p; + + return p == pe && *(p-1) != ']'; +} + +#endif /* HB_BUFFER_DESERIALIZE_TEXT_HH */ diff --git a/chromium/third_party/harfbuzz-ng/src/hb-buffer-private.hh b/chromium/third_party/harfbuzz-ng/src/src/hb-buffer-private.hh index af4767f5114..af4767f5114 100644 --- a/chromium/third_party/harfbuzz-ng/src/hb-buffer-private.hh +++ b/chromium/third_party/harfbuzz-ng/src/src/hb-buffer-private.hh diff --git a/chromium/third_party/harfbuzz-ng/src/hb-buffer-serialize.cc b/chromium/third_party/harfbuzz-ng/src/src/hb-buffer-serialize.cc index 11471941de8..11471941de8 100644 --- a/chromium/third_party/harfbuzz-ng/src/hb-buffer-serialize.cc +++ b/chromium/third_party/harfbuzz-ng/src/src/hb-buffer-serialize.cc diff --git a/chromium/third_party/harfbuzz-ng/src/hb-buffer.cc b/chromium/third_party/harfbuzz-ng/src/src/hb-buffer.cc index dc0639f4f29..dc0639f4f29 100644 --- a/chromium/third_party/harfbuzz-ng/src/hb-buffer.cc +++ b/chromium/third_party/harfbuzz-ng/src/src/hb-buffer.cc diff --git a/chromium/third_party/harfbuzz-ng/src/hb-buffer.h b/chromium/third_party/harfbuzz-ng/src/src/hb-buffer.h index 8a2d3e8690f..8a2d3e8690f 100644 --- a/chromium/third_party/harfbuzz-ng/src/hb-buffer.h +++ b/chromium/third_party/harfbuzz-ng/src/src/hb-buffer.h diff --git a/chromium/third_party/harfbuzz-ng/src/hb-common.cc b/chromium/third_party/harfbuzz-ng/src/src/hb-common.cc index d1fcf799aac..d1fcf799aac 100644 --- a/chromium/third_party/harfbuzz-ng/src/hb-common.cc +++ b/chromium/third_party/harfbuzz-ng/src/src/hb-common.cc diff --git a/chromium/third_party/harfbuzz-ng/src/hb-common.h b/chromium/third_party/harfbuzz-ng/src/src/hb-common.h index 26200ce125b..26200ce125b 100644 --- a/chromium/third_party/harfbuzz-ng/src/hb-common.h +++ b/chromium/third_party/harfbuzz-ng/src/src/hb-common.h diff --git a/chromium/third_party/harfbuzz-ng/src/hb-coretext.cc b/chromium/third_party/harfbuzz-ng/src/src/hb-coretext.cc index aba7cf44d3f..aba7cf44d3f 100644 --- a/chromium/third_party/harfbuzz-ng/src/hb-coretext.cc +++ b/chromium/third_party/harfbuzz-ng/src/src/hb-coretext.cc diff --git a/chromium/third_party/harfbuzz-ng/src/hb-coretext.h b/chromium/third_party/harfbuzz-ng/src/src/hb-coretext.h index 4b0a6f01b6f..4b0a6f01b6f 100644 --- a/chromium/third_party/harfbuzz-ng/src/hb-coretext.h +++ b/chromium/third_party/harfbuzz-ng/src/src/hb-coretext.h diff --git a/chromium/third_party/harfbuzz-ng/src/hb-debug.hh b/chromium/third_party/harfbuzz-ng/src/src/hb-debug.hh index c244347b348..c244347b348 100644 --- a/chromium/third_party/harfbuzz-ng/src/hb-debug.hh +++ b/chromium/third_party/harfbuzz-ng/src/src/hb-debug.hh diff --git a/chromium/third_party/harfbuzz-ng/src/hb-deprecated.h b/chromium/third_party/harfbuzz-ng/src/src/hb-deprecated.h index eac7efb42f1..eac7efb42f1 100644 --- a/chromium/third_party/harfbuzz-ng/src/hb-deprecated.h +++ b/chromium/third_party/harfbuzz-ng/src/src/hb-deprecated.h diff --git a/chromium/third_party/harfbuzz-ng/src/src/hb-directwrite.cc b/chromium/third_party/harfbuzz-ng/src/src/hb-directwrite.cc new file mode 100644 index 00000000000..0d3b1c2e452 --- /dev/null +++ b/chromium/third_party/harfbuzz-ng/src/src/hb-directwrite.cc @@ -0,0 +1,933 @@ +/* + * Copyright © 2015-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-private.hh" +#include "hb-debug.hh" +#define HB_SHAPER directwrite +#include "hb-shaper-impl-private.hh" + +#include <DWrite_1.h> + +#include "hb-directwrite.h" + + +HB_SHAPER_DATA_ENSURE_DEFINE(directwrite, face) +HB_SHAPER_DATA_ENSURE_DEFINE(directwrite, font) + + +/* + * DirectWrite font stream helpers + */ + +// This is a font loader which provides only one font (unlike its original design). +// For a better implementation which was also source of this +// and DWriteFontFileStream, have a look at to NativeFontResourceDWrite.cpp in Mozilla +class DWriteFontFileLoader : public IDWriteFontFileLoader +{ +private: + IDWriteFontFileStream *mFontFileStream; +public: + DWriteFontFileLoader (IDWriteFontFileStream *fontFileStream) + { + mFontFileStream = fontFileStream; + } + + // IUnknown interface + IFACEMETHOD(QueryInterface)(IID const& iid, OUT void** ppObject) { return S_OK; } + IFACEMETHOD_(ULONG, AddRef)() { return 1; } + IFACEMETHOD_(ULONG, Release)() { return 1; } + + // IDWriteFontFileLoader methods + virtual HRESULT STDMETHODCALLTYPE CreateStreamFromKey(void const* fontFileReferenceKey, + UINT32 fontFileReferenceKeySize, + OUT IDWriteFontFileStream** fontFileStream) + { + *fontFileStream = mFontFileStream; + return S_OK; + } +}; + +class DWriteFontFileStream : public IDWriteFontFileStream +{ +private: + uint8_t *mData; + uint32_t mSize; +public: + DWriteFontFileStream (uint8_t *aData, uint32_t aSize) + { + mData = aData; + mSize = aSize; + } + + // IUnknown interface + IFACEMETHOD(QueryInterface)(IID const& iid, OUT void** ppObject) { return S_OK; } + IFACEMETHOD_(ULONG, AddRef)() { return 1; } + IFACEMETHOD_(ULONG, Release)() { return 1; } + + // IDWriteFontFileStream methods + virtual HRESULT STDMETHODCALLTYPE ReadFileFragment(void const** fragmentStart, + UINT64 fileOffset, + UINT64 fragmentSize, + OUT void** fragmentContext) + { + // We are required to do bounds checking. + if (fileOffset + fragmentSize > mSize) { + return E_FAIL; + } + + // truncate the 64 bit fileOffset to size_t sized index into mData + size_t index = static_cast<size_t> (fileOffset); + + // We should be alive for the duration of this. + *fragmentStart = &mData[index]; + *fragmentContext = nullptr; + return S_OK; + } + + virtual void STDMETHODCALLTYPE ReleaseFileFragment(void* fragmentContext) { } + + virtual HRESULT STDMETHODCALLTYPE GetFileSize(OUT UINT64* fileSize) + { + *fileSize = mSize; + return S_OK; + } + + virtual HRESULT STDMETHODCALLTYPE GetLastWriteTime(OUT UINT64* lastWriteTime) + { + return E_NOTIMPL; + } +}; + + +/* +* shaper face data +*/ + +struct hb_directwrite_shaper_face_data_t { + IDWriteFactory *dwriteFactory; + IDWriteFontFile *fontFile; + IDWriteFontFileStream *fontFileStream; + IDWriteFontFileLoader *fontFileLoader; + IDWriteFontFace *fontFace; + hb_blob_t *faceBlob; +}; + +hb_directwrite_shaper_face_data_t * +_hb_directwrite_shaper_face_data_create(hb_face_t *face) +{ + hb_directwrite_shaper_face_data_t *data = + (hb_directwrite_shaper_face_data_t *) malloc (sizeof (hb_directwrite_shaper_face_data_t)); + if (unlikely (!data)) + return nullptr; + + // TODO: factory and fontFileLoader should be cached separately + IDWriteFactory* dwriteFactory; + DWriteCreateFactory ( + DWRITE_FACTORY_TYPE_SHARED, + __uuidof (IDWriteFactory), + (IUnknown**) &dwriteFactory + ); + + HRESULT hr; + hb_blob_t *blob = hb_face_reference_blob (face); + DWriteFontFileStream *fontFileStream = new DWriteFontFileStream ( + (uint8_t *) hb_blob_get_data (blob, nullptr), + hb_blob_get_length (blob)); + + DWriteFontFileLoader *fontFileLoader = new DWriteFontFileLoader (fontFileStream); + dwriteFactory->RegisterFontFileLoader (fontFileLoader); + + IDWriteFontFile *fontFile; + uint64_t fontFileKey = 0; + 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!"); + return nullptr; + } + + BOOL isSupported; + DWRITE_FONT_FILE_TYPE fileType; + DWRITE_FONT_FACE_TYPE faceType; + UINT32 numberOfFaces; + hr = fontFile->Analyze (&isSupported, &fileType, &faceType, &numberOfFaces); + if (FAILED (hr) || !isSupported) { + FAIL ("Font file is not supported."); + return nullptr; + } + +#undef FAIL + + IDWriteFontFace *fontFace; + dwriteFactory->CreateFontFace (faceType, 1, &fontFile, 0, + DWRITE_FONT_SIMULATIONS_NONE, &fontFace); + + data->dwriteFactory = dwriteFactory; + data->fontFile = fontFile; + data->fontFileStream = fontFileStream; + data->fontFileLoader = fontFileLoader; + data->fontFace = fontFace; + data->faceBlob = blob; + + return data; +} + +void +_hb_directwrite_shaper_face_data_destroy(hb_directwrite_shaper_face_data_t *data) +{ + if (data->fontFace) + data->fontFace->Release (); + if (data->fontFile) + data->fontFile->Release (); + if (data->dwriteFactory) { + if (data->fontFileLoader) + data->dwriteFactory->UnregisterFontFileLoader (data->fontFileLoader); + data->dwriteFactory->Release (); + } + if (data->fontFileLoader) + delete data->fontFileLoader; + if (data->fontFileStream) + delete data->fontFileStream; + if (data->faceBlob) + hb_blob_destroy (data->faceBlob); + if (data) + free (data); +} + + +/* + * shaper font data + */ + +struct hb_directwrite_shaper_font_data_t { +}; + +hb_directwrite_shaper_font_data_t * +_hb_directwrite_shaper_font_data_create (hb_font_t *font) +{ + if (unlikely (!hb_directwrite_shaper_face_data_ensure (font->face))) return nullptr; + + hb_directwrite_shaper_font_data_t *data = + (hb_directwrite_shaper_font_data_t *) malloc (sizeof (hb_directwrite_shaper_font_data_t)); + if (unlikely (!data)) + return nullptr; + + return data; +} + +void +_hb_directwrite_shaper_font_data_destroy (hb_directwrite_shaper_font_data_t *data) +{ + free (data); +} + + +/* + * shaper shape_plan data + */ + +struct hb_directwrite_shaper_shape_plan_data_t {}; + +hb_directwrite_shaper_shape_plan_data_t * +_hb_directwrite_shaper_shape_plan_data_create (hb_shape_plan_t *shape_plan HB_UNUSED, + const hb_feature_t *user_features HB_UNUSED, + unsigned int num_user_features HB_UNUSED, + const int *coords HB_UNUSED, + unsigned int num_coords HB_UNUSED) +{ + return (hb_directwrite_shaper_shape_plan_data_t *) HB_SHAPER_DATA_SUCCEEDED; +} + +void +_hb_directwrite_shaper_shape_plan_data_destroy (hb_directwrite_shaper_shape_plan_data_t *data HB_UNUSED) +{ +} + +// Most of TextAnalysis is originally written by Bas Schouten for Mozilla project +// but now is relicensed to MIT for HarfBuzz use +class TextAnalysis + : public IDWriteTextAnalysisSource, public IDWriteTextAnalysisSink +{ +public: + + IFACEMETHOD(QueryInterface)(IID const& iid, OUT void** ppObject) { return S_OK; } + IFACEMETHOD_(ULONG, AddRef)() { return 1; } + IFACEMETHOD_(ULONG, Release)() { return 1; } + + // A single contiguous run of characters containing the same analysis + // results. + struct Run + { + uint32_t mTextStart; // starting text position of this run + uint32_t mTextLength; // number of contiguous code units covered + uint32_t mGlyphStart; // starting glyph in the glyphs array + uint32_t mGlyphCount; // number of glyphs associated with this run + // text + DWRITE_SCRIPT_ANALYSIS mScript; + uint8_t mBidiLevel; + bool mIsSideways; + + inline bool ContainsTextPosition(uint32_t aTextPosition) const + { + return aTextPosition >= mTextStart + && aTextPosition < mTextStart + mTextLength; + } + + Run *nextRun; + }; + +public: + TextAnalysis(const wchar_t* text, + uint32_t textLength, + const wchar_t* localeName, + DWRITE_READING_DIRECTION readingDirection) + : mText(text) + , mTextLength(textLength) + , mLocaleName(localeName) + , mReadingDirection(readingDirection) + , mCurrentRun(nullptr) { }; + + ~TextAnalysis() { + // delete runs, except mRunHead which is part of the TextAnalysis object + for (Run *run = mRunHead.nextRun; run;) { + Run *origRun = run; + run = run->nextRun; + free (origRun); + } + } + + STDMETHODIMP GenerateResults(IDWriteTextAnalyzer* textAnalyzer, + Run **runHead) { + // Analyzes the text using the script analyzer and returns + // the result as a series of runs. + + HRESULT hr = S_OK; + + // Initially start out with one result that covers the entire range. + // This result will be subdivided by the analysis processes. + mRunHead.mTextStart = 0; + mRunHead.mTextLength = mTextLength; + mRunHead.mBidiLevel = + (mReadingDirection == DWRITE_READING_DIRECTION_RIGHT_TO_LEFT); + mRunHead.nextRun = nullptr; + mCurrentRun = &mRunHead; + + // Call each of the analyzers in sequence, recording their results. + if (SUCCEEDED (hr = textAnalyzer->AnalyzeScript (this, 0, mTextLength, this))) { + *runHead = &mRunHead; + } + + return hr; + } + + // IDWriteTextAnalysisSource implementation + + IFACEMETHODIMP GetTextAtPosition(uint32_t textPosition, + OUT wchar_t const** textString, + OUT uint32_t* textLength) + { + if (textPosition >= mTextLength) { + // No text at this position, valid query though. + *textString = nullptr; + *textLength = 0; + } + else { + *textString = mText + textPosition; + *textLength = mTextLength - textPosition; + } + return S_OK; + } + + IFACEMETHODIMP GetTextBeforePosition(uint32_t textPosition, + OUT wchar_t const** textString, + OUT uint32_t* textLength) + { + if (textPosition == 0 || textPosition > mTextLength) { + // Either there is no text before here (== 0), or this + // is an invalid position. The query is considered valid though. + *textString = nullptr; + *textLength = 0; + } + else { + *textString = mText; + *textLength = textPosition; + } + return S_OK; + } + + IFACEMETHODIMP_(DWRITE_READING_DIRECTION) + GetParagraphReadingDirection() { return mReadingDirection; } + + IFACEMETHODIMP GetLocaleName(uint32_t textPosition, + uint32_t* textLength, + wchar_t const** localeName) + { + return S_OK; + } + + IFACEMETHODIMP + GetNumberSubstitution(uint32_t textPosition, + OUT uint32_t* textLength, + OUT IDWriteNumberSubstitution** numberSubstitution) + { + // We do not support number substitution. + *numberSubstitution = nullptr; + *textLength = mTextLength - textPosition; + + return S_OK; + } + + // IDWriteTextAnalysisSink implementation + + IFACEMETHODIMP + SetScriptAnalysis(uint32_t textPosition, + uint32_t textLength, + DWRITE_SCRIPT_ANALYSIS const* scriptAnalysis) + { + SetCurrentRun(textPosition); + SplitCurrentRun(textPosition); + while (textLength > 0) + { + Run *run = FetchNextRun(&textLength); + run->mScript = *scriptAnalysis; + } + + return S_OK; + } + + IFACEMETHODIMP + SetLineBreakpoints(uint32_t textPosition, + uint32_t textLength, + const DWRITE_LINE_BREAKPOINT* lineBreakpoints) { return S_OK; } + + IFACEMETHODIMP SetBidiLevel(uint32_t textPosition, + uint32_t textLength, + uint8_t explicitLevel, + uint8_t resolvedLevel) { return S_OK; } + + IFACEMETHODIMP + SetNumberSubstitution(uint32_t textPosition, + uint32_t textLength, + IDWriteNumberSubstitution* numberSubstitution) { return S_OK; } + +protected: + Run *FetchNextRun(IN OUT uint32_t* textLength) + { + // Used by the sink setters, this returns a reference to the next run. + // Position and length are adjusted to now point after the current run + // being returned. + + Run *origRun = mCurrentRun; + // Split the tail if needed (the length remaining is less than the + // current run's size). + if (*textLength < mCurrentRun->mTextLength) + { + SplitCurrentRun (mCurrentRun->mTextStart + *textLength); + } + else + { + // Just advance the current run. + mCurrentRun = mCurrentRun->nextRun; + } + *textLength -= origRun->mTextLength; + + // Return a reference to the run that was just current. + return origRun; + } + + void SetCurrentRun(uint32_t textPosition) + { + // Move the current run to the given position. + // Since the analyzers generally return results in a forward manner, + // this will usually just return early. If not, find the + // corresponding run for the text position. + + if (mCurrentRun && mCurrentRun->ContainsTextPosition (textPosition)) + { + return; + } + + for (Run *run = &mRunHead; run; run = run->nextRun) { + if (run->ContainsTextPosition (textPosition)) + { + mCurrentRun = run; + return; + } + } + //NS_NOTREACHED("We should always be able to find the text position in one \ + // of our runs"); + } + + void SplitCurrentRun(uint32_t splitPosition) + { + if (!mCurrentRun) + { + //NS_ASSERTION(false, "SplitCurrentRun called without current run."); + // Shouldn't be calling this when no current run is set! + return; + } + // Split the current run. + if (splitPosition <= mCurrentRun->mTextStart) + { + // No need to split, already the start of a run + // or before it. Usually the first. + return; + } + Run *newRun = (Run*) malloc (sizeof (Run)); + + *newRun = *mCurrentRun; + + // Insert the new run in our linked list. + newRun->nextRun = mCurrentRun->nextRun; + mCurrentRun->nextRun = newRun; + + // Adjust runs' text positions and lengths. + uint32_t splitPoint = splitPosition - mCurrentRun->mTextStart; + newRun->mTextStart += splitPoint; + newRun->mTextLength -= splitPoint; + mCurrentRun->mTextLength = splitPoint; + mCurrentRun = newRun; + } + +protected: + // Input + // (weak references are fine here, since this class is a transient + // stack-based helper that doesn't need to copy data) + uint32_t mTextLength; + const wchar_t* mText; + const wchar_t* mLocaleName; + DWRITE_READING_DIRECTION mReadingDirection; + + // Current processing state. + Run *mCurrentRun; + + // Output is a list of runs starting here + 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 + */ + +static hb_bool_t +_hb_directwrite_shape_full(hb_shape_plan_t *shape_plan, + hb_font_t *font, + hb_buffer_t *buffer, + const hb_feature_t *features, + unsigned int num_features, + float lineWidth) +{ + hb_face_t *face = font->face; + hb_directwrite_shaper_face_data_t *face_data = HB_SHAPER_DATA_GET (face); + hb_directwrite_shaper_font_data_t *font_data = HB_SHAPER_DATA_GET (font); + IDWriteFactory *dwriteFactory = face_data->dwriteFactory; + IDWriteFontFace *fontFace = face_data->fontFace; + + IDWriteTextAnalyzer* analyzer; + dwriteFactory->CreateTextAnalyzer(&analyzer); + + unsigned int scratch_size; + hb_buffer_t::scratch_buffer_t *scratch = buffer->get_scratch_buffer (&scratch_size); +#define ALLOCATE_ARRAY(Type, name, len) \ + Type *name = (Type *) scratch; \ + { \ + unsigned int _consumed = DIV_CEIL ((len) * sizeof (Type), sizeof (*scratch)); \ + assert (_consumed <= scratch_size); \ + scratch += _consumed; \ + scratch_size -= _consumed; \ + } + +#define utf16_index() var1.u32 + + ALLOCATE_ARRAY(wchar_t, textString, buffer->len * 2); + + unsigned int chars_len = 0; + for (unsigned int i = 0; i < buffer->len; i++) + { + hb_codepoint_t c = buffer->info[i].codepoint; + buffer->info[i].utf16_index() = chars_len; + if (likely(c <= 0xFFFFu)) + textString[chars_len++] = c; + else if (unlikely(c > 0x10FFFFu)) + textString[chars_len++] = 0xFFFDu; + else { + textString[chars_len++] = 0xD800u + ((c - 0x10000u) >> 10); + textString[chars_len++] = 0xDC00u + ((c - 0x10000u) & ((1u << 10) - 1)); + } + } + + ALLOCATE_ARRAY(WORD, log_clusters, chars_len); + // if (num_features) + { + /* Need log_clusters to assign features. */ + chars_len = 0; + for (unsigned int i = 0; i < buffer->len; i++) + { + hb_codepoint_t c = buffer->info[i].codepoint; + unsigned int cluster = buffer->info[i].cluster; + log_clusters[chars_len++] = cluster; + if (hb_in_range(c, 0x10000u, 0x10FFFFu)) + log_clusters[chars_len++] = cluster; /* Surrogates. */ + } + } + + // TODO: Handle TEST_DISABLE_OPTIONAL_LIGATURES + + DWRITE_READING_DIRECTION readingDirection = buffer->props.direction ? + DWRITE_READING_DIRECTION_RIGHT_TO_LEFT : + DWRITE_READING_DIRECTION_LEFT_TO_RIGHT; + + /* + * There's an internal 16-bit limit on some things inside the analyzer, + * but we never attempt to shape a word longer than 64K characters + * in a single gfxShapedWord, so we cannot exceed that limit. + */ + uint32_t textLength = buffer->len; + + TextAnalysis analysis(textString, textLength, nullptr, readingDirection); + TextAnalysis::Run *runHead; + HRESULT hr; + hr = analysis.GenerateResults(analyzer, &runHead); + +#define FAIL(...) \ + HB_STMT_START { \ + DEBUG_MSG (DIRECTWRITE, nullptr, __VA_ARGS__); \ + return false; \ + } HB_STMT_END; + + if (FAILED (hr)) + { + FAIL ("Analyzer failed to generate results."); + return false; + } + + uint32_t maxGlyphCount = 3 * textLength / 2 + 16; + uint32_t glyphCount; + bool isRightToLeft = HB_DIRECTION_IS_BACKWARD (buffer->props.direction); + + const wchar_t localeName[20] = {0}; + if (buffer->props.language != nullptr) + { + mbstowcs ((wchar_t*) localeName, + hb_language_to_string (buffer->props.language), 20); + } + + DWRITE_TYPOGRAPHIC_FEATURES singleFeatures; + singleFeatures.featureCount = num_features; + if (num_features) + { + DWRITE_FONT_FEATURE* dwfeatureArray = (DWRITE_FONT_FEATURE*) + malloc (sizeof (DWRITE_FONT_FEATURE) * num_features); + for (unsigned int i = 0; i < num_features; ++i) + { + dwfeatureArray[i].nameTag = (DWRITE_FONT_FEATURE_TAG) + hb_uint32_swap (features[i].tag); + dwfeatureArray[i].parameter = features[i].value; + } + singleFeatures.features = dwfeatureArray; + } + const DWRITE_TYPOGRAPHIC_FEATURES* dwFeatures = + (const DWRITE_TYPOGRAPHIC_FEATURES*) &singleFeatures; + const uint32_t featureRangeLengths[] = { textLength }; + + uint16_t* clusterMap = (uint16_t*) malloc (textLength * sizeof (uint16_t)); + DWRITE_SHAPING_TEXT_PROPERTIES* textProperties = (DWRITE_SHAPING_TEXT_PROPERTIES*) + malloc (textLength * sizeof (DWRITE_SHAPING_TEXT_PROPERTIES)); +retry_getglyphs: + uint16_t* glyphIndices = (uint16_t*) malloc (maxGlyphCount * sizeof (uint16_t)); + DWRITE_SHAPING_GLYPH_PROPERTIES* glyphProperties = (DWRITE_SHAPING_GLYPH_PROPERTIES*) + malloc (maxGlyphCount * sizeof (DWRITE_SHAPING_GLYPH_PROPERTIES)); + + hr = analyzer->GetGlyphs (textString, textLength, fontFace, false, + isRightToLeft, &runHead->mScript, localeName, nullptr, &dwFeatures, + featureRangeLengths, 1, maxGlyphCount, clusterMap, textProperties, glyphIndices, + glyphProperties, &glyphCount); + + if (unlikely (hr == HRESULT_FROM_WIN32 (ERROR_INSUFFICIENT_BUFFER))) + { + free (glyphIndices); + free (glyphProperties); + + maxGlyphCount *= 2; + + goto retry_getglyphs; + } + if (FAILED (hr)) + { + FAIL ("Analyzer failed to get glyphs."); + return false; + } + + float* glyphAdvances = (float*) malloc (maxGlyphCount * sizeof (float)); + DWRITE_GLYPH_OFFSET* glyphOffsets = (DWRITE_GLYPH_OFFSET*) + malloc(maxGlyphCount * sizeof (DWRITE_GLYPH_OFFSET)); + + /* The -2 in the following is to compensate for possible + * alignment needed after the WORD array. sizeof(WORD) == 2. */ + unsigned int glyphs_size = (scratch_size * sizeof(int) - 2) + / (sizeof(WORD) + + sizeof(DWRITE_SHAPING_GLYPH_PROPERTIES) + + sizeof(int) + + sizeof(DWRITE_GLYPH_OFFSET) + + sizeof(uint32_t)); + ALLOCATE_ARRAY (uint32_t, vis_clusters, glyphs_size); + +#undef ALLOCATE_ARRAY + + int fontEmSize = font->face->get_upem(); + if (fontEmSize < 0) + fontEmSize = -fontEmSize; + + if (fontEmSize < 0) + fontEmSize = -fontEmSize; + double x_mult = (double) font->x_scale / fontEmSize; + double y_mult = (double) font->y_scale / fontEmSize; + + hr = analyzer->GetGlyphPlacements (textString, + clusterMap, textProperties, textLength, glyphIndices, + glyphProperties, glyphCount, fontFace, fontEmSize, + false, isRightToLeft, &runHead->mScript, localeName, + &dwFeatures, featureRangeLengths, 1, + glyphAdvances, glyphOffsets); + + if (FAILED (hr)) + { + FAIL ("Analyzer failed to get glyph placements."); + return false; + } + + IDWriteTextAnalyzer1* analyzer1; + analyzer->QueryInterface (&analyzer1); + + if (analyzer1 && lineWidth) + { + + DWRITE_JUSTIFICATION_OPPORTUNITY* justificationOpportunities = + (DWRITE_JUSTIFICATION_OPPORTUNITY*) + malloc (maxGlyphCount * sizeof (DWRITE_JUSTIFICATION_OPPORTUNITY)); + hr = analyzer1->GetJustificationOpportunities (fontFace, fontEmSize, + runHead->mScript, textLength, glyphCount, textString, clusterMap, + glyphProperties, justificationOpportunities); + + if (FAILED (hr)) + { + FAIL ("Analyzer failed to get justification opportunities."); + return false; + } + + float* justifiedGlyphAdvances = + (float*) malloc (maxGlyphCount * sizeof (float)); + DWRITE_GLYPH_OFFSET* justifiedGlyphOffsets = (DWRITE_GLYPH_OFFSET*) + malloc (glyphCount * sizeof (DWRITE_GLYPH_OFFSET)); + hr = analyzer1->JustifyGlyphAdvances (lineWidth, glyphCount, justificationOpportunities, + glyphAdvances, glyphOffsets, justifiedGlyphAdvances, justifiedGlyphOffsets); + + if (FAILED (hr)) + { + FAIL("Analyzer failed to get justified glyph advances."); + return false; + } + + DWRITE_SCRIPT_PROPERTIES scriptProperties; + hr = analyzer1->GetScriptProperties (runHead->mScript, &scriptProperties); + if (FAILED (hr)) + { + FAIL("Analyzer failed to get script properties."); + return false; + } + uint32_t justificationCharacter = scriptProperties.justificationCharacter; + + // if a script justificationCharacter is not space, it can have GetJustifiedGlyphs + if (justificationCharacter != 32) + { + uint16_t* modifiedClusterMap = (uint16_t*) malloc (textLength * sizeof (uint16_t)); + retry_getjustifiedglyphs: + uint16_t* modifiedGlyphIndices = (uint16_t*) malloc (maxGlyphCount * sizeof (uint16_t)); + float* modifiedGlyphAdvances = (float*) malloc (maxGlyphCount * sizeof (float)); + DWRITE_GLYPH_OFFSET* modifiedGlyphOffsets = (DWRITE_GLYPH_OFFSET*) + malloc (maxGlyphCount * sizeof (DWRITE_GLYPH_OFFSET)); + uint32_t actualGlyphsCount; + hr = analyzer1->GetJustifiedGlyphs (fontFace, fontEmSize, runHead->mScript, + textLength, glyphCount, maxGlyphCount, clusterMap, glyphIndices, + glyphAdvances, justifiedGlyphAdvances, justifiedGlyphOffsets, + glyphProperties, &actualGlyphsCount, modifiedClusterMap, modifiedGlyphIndices, + modifiedGlyphAdvances, modifiedGlyphOffsets); + + if (hr == HRESULT_FROM_WIN32 (ERROR_INSUFFICIENT_BUFFER)) + { + maxGlyphCount = actualGlyphsCount; + free (modifiedGlyphIndices); + free (modifiedGlyphAdvances); + free (modifiedGlyphOffsets); + + maxGlyphCount = actualGlyphsCount; + + goto retry_getjustifiedglyphs; + } + if (FAILED (hr)) + { + FAIL ("Analyzer failed to get justified glyphs."); + return false; + } + + free (clusterMap); + free (glyphIndices); + free (glyphAdvances); + free (glyphOffsets); + + glyphCount = actualGlyphsCount; + clusterMap = modifiedClusterMap; + glyphIndices = modifiedGlyphIndices; + glyphAdvances = modifiedGlyphAdvances; + glyphOffsets = modifiedGlyphOffsets; + + free (justifiedGlyphAdvances); + free (justifiedGlyphOffsets); + } + else + { + free (glyphAdvances); + free (glyphOffsets); + + glyphAdvances = justifiedGlyphAdvances; + glyphOffsets = justifiedGlyphOffsets; + } + + free (justificationOpportunities); + + } + + /* Ok, we've got everything we need, now compose output buffer, + * very, *very*, carefully! */ + + /* Calculate visual-clusters. That's what we ship. */ + for (unsigned int i = 0; i < glyphCount; i++) + vis_clusters[i] = -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); + } + for (unsigned int i = 1; i < glyphCount; i++) + if (vis_clusters[i] == -1) + vis_clusters[i] = vis_clusters[i - 1]; + +#undef utf16_index + + if (unlikely (!buffer->ensure (glyphCount))) + FAIL ("Buffer in error"); + +#undef FAIL + + /* Set glyph infos */ + buffer->len = 0; + for (unsigned int i = 0; i < glyphCount; i++) + { + hb_glyph_info_t *info = &buffer->info[buffer->len++]; + + info->codepoint = glyphIndices[i]; + info->cluster = vis_clusters[i]; + + /* The rest is crap. Let's store position info there for now. */ + info->mask = glyphAdvances[i]; + info->var1.i32 = glyphOffsets[i].advanceOffset; + info->var2.i32 = glyphOffsets[i].ascenderOffset; + } + + /* Set glyph positions */ + buffer->clear_positions (); + for (unsigned int i = 0; i < glyphCount; i++) + { + hb_glyph_info_t *info = &buffer->info[i]; + hb_glyph_position_t *pos = &buffer->pos[i]; + + /* TODO vertical */ + pos->x_advance = x_mult * (int32_t) info->mask; + pos->x_offset = + x_mult * (isRightToLeft ? -info->var1.i32 : info->var1.i32); + pos->y_offset = y_mult * info->var2.i32; + } + + if (isRightToLeft) + hb_buffer_reverse (buffer); + + free (clusterMap); + free (glyphIndices); + free (textProperties); + free (glyphProperties); + free (glyphAdvances); + free (glyphOffsets); + + if (num_features) + free (singleFeatures.features); + + /* Wow, done! */ + return true; +} + +hb_bool_t +_hb_directwrite_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_directwrite_shape_full(shape_plan, font, buffer, + 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) +{ + static const char *shapers = "directwrite"; + hb_shape_plan_t *shape_plan = hb_shape_plan_create_cached (font->face, + &buffer->props, features, num_features, &shapers); + hb_bool_t res = _hb_directwrite_shape_full (shape_plan, font, buffer, + features, num_features, width); + + buffer->unsafe_to_break_all (); + + return res; +} diff --git a/chromium/third_party/harfbuzz-ng/src/src/hb-directwrite.h b/chromium/third_party/harfbuzz-ng/src/src/hb-directwrite.h new file mode 100644 index 00000000000..e743af21411 --- /dev/null +++ b/chromium/third_party/harfbuzz-ng/src/src/hb-directwrite.h @@ -0,0 +1,38 @@ +/* + * Copyright © 2015 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_DIRECTWRITE_H +#define HB_DIRECTWRITE_H + +#include "hb.h" + +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_END_DECLS + +#endif /* HB_DIRECTWRITE_H */ diff --git a/chromium/third_party/harfbuzz-ng/src/hb-dsalgs.hh b/chromium/third_party/harfbuzz-ng/src/src/hb-dsalgs.hh index e41384754e4..e41384754e4 100644 --- a/chromium/third_party/harfbuzz-ng/src/hb-dsalgs.hh +++ b/chromium/third_party/harfbuzz-ng/src/src/hb-dsalgs.hh diff --git a/chromium/third_party/harfbuzz-ng/src/hb-face-private.hh b/chromium/third_party/harfbuzz-ng/src/src/hb-face-private.hh index 43e7b1cb3ff..43e7b1cb3ff 100644 --- a/chromium/third_party/harfbuzz-ng/src/hb-face-private.hh +++ b/chromium/third_party/harfbuzz-ng/src/src/hb-face-private.hh diff --git a/chromium/third_party/harfbuzz-ng/src/hb-face.cc b/chromium/third_party/harfbuzz-ng/src/src/hb-face.cc index d8af8c1f37e..d8af8c1f37e 100644 --- a/chromium/third_party/harfbuzz-ng/src/hb-face.cc +++ b/chromium/third_party/harfbuzz-ng/src/src/hb-face.cc diff --git a/chromium/third_party/harfbuzz-ng/src/hb-face.h b/chromium/third_party/harfbuzz-ng/src/src/hb-face.h index 0ce8d0462d5..0ce8d0462d5 100644 --- a/chromium/third_party/harfbuzz-ng/src/hb-face.h +++ b/chromium/third_party/harfbuzz-ng/src/src/hb-face.h diff --git a/chromium/third_party/harfbuzz-ng/src/src/hb-fallback-shape.cc b/chromium/third_party/harfbuzz-ng/src/src/hb-fallback-shape.cc new file mode 100644 index 00000000000..3f09c3f5306 --- /dev/null +++ b/chromium/third_party/harfbuzz-ng/src/src/hb-fallback-shape.cc @@ -0,0 +1,149 @@ +/* + * Copyright © 2011 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 + */ + +#define HB_SHAPER fallback +#include "hb-shaper-impl-private.hh" + + +HB_SHAPER_DATA_ENSURE_DEFINE(fallback, face) +HB_SHAPER_DATA_ENSURE_DEFINE(fallback, font) + + +/* + * shaper face data + */ + +struct hb_fallback_shaper_face_data_t {}; + +hb_fallback_shaper_face_data_t * +_hb_fallback_shaper_face_data_create (hb_face_t *face HB_UNUSED) +{ + return (hb_fallback_shaper_face_data_t *) HB_SHAPER_DATA_SUCCEEDED; +} + +void +_hb_fallback_shaper_face_data_destroy (hb_fallback_shaper_face_data_t *data HB_UNUSED) +{ +} + + +/* + * shaper font data + */ + +struct hb_fallback_shaper_font_data_t {}; + +hb_fallback_shaper_font_data_t * +_hb_fallback_shaper_font_data_create (hb_font_t *font HB_UNUSED) +{ + return (hb_fallback_shaper_font_data_t *) HB_SHAPER_DATA_SUCCEEDED; +} + +void +_hb_fallback_shaper_font_data_destroy (hb_fallback_shaper_font_data_t *data HB_UNUSED) +{ +} + + +/* + * shaper shape_plan data + */ + +struct hb_fallback_shaper_shape_plan_data_t {}; + +hb_fallback_shaper_shape_plan_data_t * +_hb_fallback_shaper_shape_plan_data_create (hb_shape_plan_t *shape_plan HB_UNUSED, + const hb_feature_t *user_features HB_UNUSED, + unsigned int num_user_features HB_UNUSED, + const int *coords HB_UNUSED, + unsigned int num_coords HB_UNUSED) +{ + return (hb_fallback_shaper_shape_plan_data_t *) HB_SHAPER_DATA_SUCCEEDED; +} + +void +_hb_fallback_shaper_shape_plan_data_destroy (hb_fallback_shaper_shape_plan_data_t *data HB_UNUSED) +{ +} + + +/* + * shaper + */ + +hb_bool_t +_hb_fallback_shape (hb_shape_plan_t *shape_plan HB_UNUSED, + hb_font_t *font, + hb_buffer_t *buffer, + const hb_feature_t *features HB_UNUSED, + unsigned int num_features HB_UNUSED) +{ + /* TODO + * + * - Apply fallback kern. + * - Handle Variation Selectors? + * - Apply normalization? + * + * This will make the fallback shaper into a dumb "TrueType" + * shaper which many people unfortunately still request. + */ + + hb_codepoint_t space; + bool has_space = (bool) font->get_nominal_glyph (' ', &space); + + buffer->clear_positions (); + + hb_direction_t direction = buffer->props.direction; + hb_unicode_funcs_t *unicode = buffer->unicode; + unsigned int count = buffer->len; + hb_glyph_info_t *info = buffer->info; + hb_glyph_position_t *pos = buffer->pos; + for (unsigned int i = 0; i < count; i++) + { + if (has_space && unicode->is_default_ignorable (info[i].codepoint)) { + info[i].codepoint = space; + pos[i].x_advance = 0; + pos[i].y_advance = 0; + continue; + } + (void) font->get_nominal_glyph (info[i].codepoint, &info[i].codepoint); + font->get_glyph_advance_for_direction (info[i].codepoint, + direction, + &pos[i].x_advance, + &pos[i].y_advance); + font->subtract_glyph_origin_for_direction (info[i].codepoint, + direction, + &pos[i].x_offset, + &pos[i].y_offset); + } + + if (HB_DIRECTION_IS_BACKWARD (direction)) + hb_buffer_reverse (buffer); + + buffer->safe_to_break_all (); + + return true; +} diff --git a/chromium/third_party/harfbuzz-ng/src/hb-font-private.hh b/chromium/third_party/harfbuzz-ng/src/src/hb-font-private.hh index 992152f176c..992152f176c 100644 --- a/chromium/third_party/harfbuzz-ng/src/hb-font-private.hh +++ b/chromium/third_party/harfbuzz-ng/src/src/hb-font-private.hh diff --git a/chromium/third_party/harfbuzz-ng/src/hb-font.cc b/chromium/third_party/harfbuzz-ng/src/src/hb-font.cc index f3534b686bf..f3534b686bf 100644 --- a/chromium/third_party/harfbuzz-ng/src/hb-font.cc +++ b/chromium/third_party/harfbuzz-ng/src/src/hb-font.cc diff --git a/chromium/third_party/harfbuzz-ng/src/hb-font.h b/chromium/third_party/harfbuzz-ng/src/src/hb-font.h index c95b61d2da8..c95b61d2da8 100644 --- a/chromium/third_party/harfbuzz-ng/src/hb-font.h +++ b/chromium/third_party/harfbuzz-ng/src/src/hb-font.h diff --git a/chromium/third_party/harfbuzz-ng/src/hb-ft.cc b/chromium/third_party/harfbuzz-ng/src/src/hb-ft.cc index fc4b11220a9..fc4b11220a9 100644 --- a/chromium/third_party/harfbuzz-ng/src/hb-ft.cc +++ b/chromium/third_party/harfbuzz-ng/src/src/hb-ft.cc diff --git a/chromium/third_party/harfbuzz-ng/src/hb-ft.h b/chromium/third_party/harfbuzz-ng/src/src/hb-ft.h index 94013eeb915..94013eeb915 100644 --- a/chromium/third_party/harfbuzz-ng/src/hb-ft.h +++ b/chromium/third_party/harfbuzz-ng/src/src/hb-ft.h diff --git a/chromium/third_party/harfbuzz-ng/src/hb-glib.cc b/chromium/third_party/harfbuzz-ng/src/src/hb-glib.cc index 50c30e9c7b9..50c30e9c7b9 100644 --- a/chromium/third_party/harfbuzz-ng/src/hb-glib.cc +++ b/chromium/third_party/harfbuzz-ng/src/src/hb-glib.cc diff --git a/chromium/third_party/harfbuzz-ng/src/hb-glib.h b/chromium/third_party/harfbuzz-ng/src/src/hb-glib.h index 5f04183ba19..5f04183ba19 100644 --- a/chromium/third_party/harfbuzz-ng/src/hb-glib.h +++ b/chromium/third_party/harfbuzz-ng/src/src/hb-glib.h diff --git a/chromium/third_party/harfbuzz-ng/src/src/hb-gobject-enums.cc.tmpl b/chromium/third_party/harfbuzz-ng/src/src/hb-gobject-enums.cc.tmpl new file mode 100644 index 00000000000..ca458a3846c --- /dev/null +++ b/chromium/third_party/harfbuzz-ng/src/src/hb-gobject-enums.cc.tmpl @@ -0,0 +1,73 @@ +/*** BEGIN file-header ***/ +/* + * Copyright © 2011 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 + */ + +#include "hb-private.hh" + +/* g++ didn't like older gtype.h gcc-only code path. */ +#include <glib.h> +#if !GLIB_CHECK_VERSION(2,29,16) +#undef __GNUC__ +#undef __GNUC_MINOR__ +#define __GNUC__ 2 +#define __GNUC_MINOR__ 6 +#endif + +#include "hb-gobject.h" + +/*** END file-header ***/ + +/*** BEGIN file-production ***/ +/* enumerations from "@filename@" */ +/*** END file-production ***/ + +/*** BEGIN value-header ***/ +GType +@enum_name@_get_type (void) +{ + static gsize type_id = 0; + + if (g_once_init_enter (&type_id)) + { + static const G@Type@Value values[] = { +/*** END value-header ***/ + +/*** BEGIN value-production ***/ + { @VALUENAME@, "@VALUENAME@", "@valuenick@" }, +/*** END value-production ***/ + +/*** BEGIN value-tail ***/ + { 0, NULL, NULL } + }; + GType id = + g_@type@_register_static (g_intern_static_string ("@EnumName@"), values); + g_once_init_leave (&type_id, id); + } + + return type_id; +} + +/*** END value-tail ***/ diff --git a/chromium/third_party/harfbuzz-ng/src/src/hb-gobject-enums.h.tmpl b/chromium/third_party/harfbuzz-ng/src/src/hb-gobject-enums.h.tmpl new file mode 100644 index 00000000000..606727cd32d --- /dev/null +++ b/chromium/third_party/harfbuzz-ng/src/src/hb-gobject-enums.h.tmpl @@ -0,0 +1,56 @@ +/*** BEGIN file-header ***/ +/* + * Copyright © 2013 Google, Inc. + * + * This is part of HarfBuzz, a text shaping library. + * + * Permission is hereby granted, without written agreement and without + * license or royalty fees, to use, copy, modify, and distribute this + * software and its documentation for any purpose, provided that the + * above copyright notice and the following two paragraphs appear in + * all copies of this software. + * + * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR + * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES + * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN + * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, + * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS + * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO + * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + * + * Google Author(s): Behdad Esfahbod + */ + +#ifndef HB_GOBJECT_H_IN +#error "Include <hb-gobject.h> instead." +#endif + +#ifndef HB_GOBJECT_ENUMS_H +#define HB_GOBJECT_ENUMS_H + +#include "hb.h" + +#include <glib-object.h> + +HB_BEGIN_DECLS + + +/*** END file-header ***/ + +/*** BEGIN value-header ***/ +HB_EXTERN GType +@enum_name@_get_type (void) G_GNUC_CONST; +#define @ENUMPREFIX@_TYPE_@ENUMSHORT@ (@enum_name@_get_type ()) + +/*** END value-header ***/ + +/*** BEGIN file-tail ***/ + +HB_END_DECLS + +#endif /* HB_GOBJECT_ENUMS_H */ +/*** END file-tail ***/ diff --git a/chromium/third_party/harfbuzz-ng/src/hb-gobject-structs.cc b/chromium/third_party/harfbuzz-ng/src/src/hb-gobject-structs.cc index a96c35804d5..a96c35804d5 100644 --- a/chromium/third_party/harfbuzz-ng/src/hb-gobject-structs.cc +++ b/chromium/third_party/harfbuzz-ng/src/src/hb-gobject-structs.cc diff --git a/chromium/third_party/harfbuzz-ng/src/hb-gobject-structs.h b/chromium/third_party/harfbuzz-ng/src/src/hb-gobject-structs.h index a34b06abbaf..302dc9584e9 100644 --- a/chromium/third_party/harfbuzz-ng/src/hb-gobject-structs.h +++ b/chromium/third_party/harfbuzz-ng/src/src/hb-gobject-structs.h @@ -45,7 +45,8 @@ HB_BEGIN_DECLS * * Since: 0.9.2 **/ -HB_EXTERN GType hb_gobject_blob_get_type (void); +HB_EXTERN GType +hb_gobject_blob_get_type (void); #define HB_GOBJECT_TYPE_BLOB (hb_gobject_blob_get_type ()) /** @@ -53,7 +54,8 @@ HB_EXTERN GType hb_gobject_blob_get_type (void); * * Since: 0.9.2 **/ -HB_EXTERN GType hb_gobject_buffer_get_type (void); +HB_EXTERN GType +hb_gobject_buffer_get_type (void); #define HB_GOBJECT_TYPE_BUFFER (hb_gobject_buffer_get_type ()) /** @@ -61,7 +63,8 @@ HB_EXTERN GType hb_gobject_buffer_get_type (void); * * Since: 0.9.2 **/ -HB_EXTERN GType hb_gobject_face_get_type (void); +HB_EXTERN GType +hb_gobject_face_get_type (void); #define HB_GOBJECT_TYPE_FACE (hb_gobject_face_get_type ()) /** @@ -69,7 +72,8 @@ HB_EXTERN GType hb_gobject_face_get_type (void); * * Since: 0.9.2 **/ -HB_EXTERN GType hb_gobject_font_get_type (void); +HB_EXTERN GType +hb_gobject_font_get_type (void); #define HB_GOBJECT_TYPE_FONT (hb_gobject_font_get_type ()) /** @@ -77,13 +81,16 @@ HB_EXTERN GType hb_gobject_font_get_type (void); * * Since: 0.9.2 **/ -HB_EXTERN GType hb_gobject_font_funcs_get_type (void); +HB_EXTERN GType +hb_gobject_font_funcs_get_type (void); #define HB_GOBJECT_TYPE_FONT_FUNCS (hb_gobject_font_funcs_get_type ()) -HB_EXTERN GType hb_gobject_set_get_type (void); +HB_EXTERN GType +hb_gobject_set_get_type (void); #define HB_GOBJECT_TYPE_SET (hb_gobject_set_get_type ()) -HB_EXTERN GType hb_gobject_shape_plan_get_type (void); +HB_EXTERN GType +hb_gobject_shape_plan_get_type (void); #define HB_GOBJECT_TYPE_SHAPE_PLAN (hb_gobject_shape_plan_get_type ()) /** @@ -91,30 +98,38 @@ HB_EXTERN GType hb_gobject_shape_plan_get_type (void); * * Since: 0.9.2 **/ -HB_EXTERN GType hb_gobject_unicode_funcs_get_type (void); +HB_EXTERN GType +hb_gobject_unicode_funcs_get_type (void); #define HB_GOBJECT_TYPE_UNICODE_FUNCS (hb_gobject_unicode_funcs_get_type ()) /* Value types */ -HB_EXTERN GType hb_gobject_feature_get_type (void); +HB_EXTERN GType +hb_gobject_feature_get_type (void); #define HB_GOBJECT_TYPE_FEATURE (hb_gobject_feature_get_type ()) -HB_EXTERN GType hb_gobject_glyph_info_get_type (void); +HB_EXTERN GType +hb_gobject_glyph_info_get_type (void); #define HB_GOBJECT_TYPE_GLYPH_INFO (hb_gobject_glyph_info_get_type ()) -HB_EXTERN GType hb_gobject_glyph_position_get_type (void); +HB_EXTERN GType +hb_gobject_glyph_position_get_type (void); #define HB_GOBJECT_TYPE_GLYPH_POSITION (hb_gobject_glyph_position_get_type ()) -HB_EXTERN GType hb_gobject_segment_properties_get_type (void); +HB_EXTERN GType +hb_gobject_segment_properties_get_type (void); #define HB_GOBJECT_TYPE_SEGMENT_PROPERTIES (hb_gobject_segment_properties_get_type ()) -HB_EXTERN GType hb_gobject_user_data_key_get_type (void); +HB_EXTERN GType +hb_gobject_user_data_key_get_type (void); #define HB_GOBJECT_TYPE_USER_DATA_KEY (hb_gobject_user_data_key_get_type ()) -HB_EXTERN GType hb_gobject_ot_math_glyph_variant_get_type (void); +HB_EXTERN GType +hb_gobject_ot_math_glyph_variant_get_type (void); #define HB_GOBJECT_TYPE_OT_MATH_GLYPH_VARIANT (hb_gobject_ot_math_glyph_variant_get_type ()) -HB_EXTERN GType hb_gobject_ot_math_glyph_part_get_type (void); +HB_EXTERN GType +hb_gobject_ot_math_glyph_part_get_type (void); #define HB_GOBJECT_TYPE_OT_MATH_GLYPH_PART (hb_gobject_ot_math_glyph_part_get_type ()) diff --git a/chromium/third_party/harfbuzz-ng/src/hb-gobject.h b/chromium/third_party/harfbuzz-ng/src/src/hb-gobject.h index ea1bd25df82..ea1bd25df82 100644 --- a/chromium/third_party/harfbuzz-ng/src/hb-gobject.h +++ b/chromium/third_party/harfbuzz-ng/src/src/hb-gobject.h diff --git a/chromium/third_party/harfbuzz-ng/src/hb-graphite2.cc b/chromium/third_party/harfbuzz-ng/src/src/hb-graphite2.cc index 46fe1399913..46fe1399913 100644 --- a/chromium/third_party/harfbuzz-ng/src/hb-graphite2.cc +++ b/chromium/third_party/harfbuzz-ng/src/src/hb-graphite2.cc diff --git a/chromium/third_party/harfbuzz-ng/src/hb-graphite2.h b/chromium/third_party/harfbuzz-ng/src/src/hb-graphite2.h index 82b1e64cd2c..82b1e64cd2c 100644 --- a/chromium/third_party/harfbuzz-ng/src/hb-graphite2.h +++ b/chromium/third_party/harfbuzz-ng/src/src/hb-graphite2.h diff --git a/chromium/third_party/harfbuzz-ng/src/hb-icu.cc b/chromium/third_party/harfbuzz-ng/src/src/hb-icu.cc index 552eaeca51e..552eaeca51e 100644 --- a/chromium/third_party/harfbuzz-ng/src/hb-icu.cc +++ b/chromium/third_party/harfbuzz-ng/src/src/hb-icu.cc diff --git a/chromium/third_party/harfbuzz-ng/src/hb-icu.h b/chromium/third_party/harfbuzz-ng/src/src/hb-icu.h index 2db6a7b6797..2db6a7b6797 100644 --- a/chromium/third_party/harfbuzz-ng/src/hb-icu.h +++ b/chromium/third_party/harfbuzz-ng/src/src/hb-icu.h diff --git a/chromium/third_party/harfbuzz-ng/src/hb-mutex-private.hh b/chromium/third_party/harfbuzz-ng/src/src/hb-mutex-private.hh index 49ed10e08a6..49ed10e08a6 100644 --- a/chromium/third_party/harfbuzz-ng/src/hb-mutex-private.hh +++ b/chromium/third_party/harfbuzz-ng/src/src/hb-mutex-private.hh diff --git a/chromium/third_party/harfbuzz-ng/src/hb-object-private.hh b/chromium/third_party/harfbuzz-ng/src/src/hb-object-private.hh index baa1f8f05cc..baa1f8f05cc 100644 --- a/chromium/third_party/harfbuzz-ng/src/hb-object-private.hh +++ b/chromium/third_party/harfbuzz-ng/src/src/hb-object-private.hh diff --git a/chromium/third_party/harfbuzz-ng/src/hb-open-file-private.hh b/chromium/third_party/harfbuzz-ng/src/src/hb-open-file-private.hh index f01ab87182d..e2644eaf91e 100644 --- a/chromium/third_party/harfbuzz-ng/src/hb-open-file-private.hh +++ b/chromium/third_party/harfbuzz-ng/src/src/hb-open-file-private.hh @@ -30,6 +30,7 @@ #define HB_OPEN_FILE_PRIVATE_HH #include "hb-open-type-private.hh" +#include "hb-ot-head-table.hh" namespace OT { @@ -54,7 +55,7 @@ struct TTCHeader; typedef struct TableRecord { int cmp (Tag t) const - { return t.cmp (tag); } + { return -t.cmp (tag); } static int cmp (const void *pa, const void *pb) { @@ -133,39 +134,67 @@ typedef struct OffsetTable unsigned int table_count) { TRACE_SERIALIZE (this); - /* alloc 12 for the OTHeader */ + /* Alloc 12 for the OTHeader. */ if (unlikely (!c->extend_min (*this))) return_trace (false); - /* write sfntVersion (bytes 0..3) */ + /* Write sfntVersion (bytes 0..3). */ sfnt_version.set (sfnt_tag); - /* take space for numTables, searchRange, entrySelector, RangeShift - * and the TableRecords themselves - */ + /* Take space for numTables, searchRange, entrySelector, RangeShift + * and the TableRecords themselves. */ if (unlikely (!tables.serialize (c, table_count))) return_trace (false); - /* write OffsetTables, alloc for and write actual table blobs */ + const char *dir_end = (const char *) c->head; + HBUINT32 *checksum_adjustment = nullptr; + + /* Write OffsetTables, alloc for and write actual table blobs. */ for (unsigned int i = 0; i < table_count; i++) { TableRecord &rec = tables.array[i]; hb_blob_t *blob = blobs[i]; rec.tag.set (tags[i]); rec.length.set (hb_blob_get_length (blob)); - rec.checkSum.set_for_data (hb_blob_get_data (blob, nullptr), rec.length); rec.offset.serialize (c, this); - // take room for the table - void *p = c->allocate_size<void> (rec.length); - if (unlikely (!p)) {return false;} - /* copy the actual table */ - memcpy (p, hb_blob_get_data (blob, nullptr), rec.length); - /* 4-byte allignment */ + + /* Allocate room for the table and copy it. */ + char *start = (char *) c->allocate_size<void> (rec.length); + if (unlikely (!start)) {return false;} + + memcpy (start, hb_blob_get_data (blob, nullptr), rec.length); + + /* 4-byte allignment. */ if (rec.length % 4) - p = c->allocate_size<void> (4 - rec.length % 4); + c->allocate_size<void> (4 - rec.length % 4); + const char *end = (const char *) c->head; + + if (tags[i] == HB_OT_TAG_head && end - start >= head::static_size) + { + head *h = (head *) start; + checksum_adjustment = &h->checkSumAdjustment; + checksum_adjustment->set (0); + } + + rec.checkSum.set_for_data (start, end - start); } tags += table_count; blobs += table_count; - /* TODO: update head table checkSumAdjustment. */ - tables.qsort (); + + if (checksum_adjustment) + { + CheckSum checksum; + + /* The following line is a slower version of the following block. */ + //checksum.set_for_data (this, (const char *) c->head - (const char *) this); + checksum.set_for_data (this, dir_end - (const char *) this); + for (unsigned int i = 0; i < table_count; i++) + { + TableRecord &rec = tables.array[i]; + checksum.set (checksum + rec.checkSum); + } + + checksum_adjustment->set (0xB1B0AFBAu - checksum); + } + return_trace (true); } diff --git a/chromium/third_party/harfbuzz-ng/src/hb-open-type-private.hh b/chromium/third_party/harfbuzz-ng/src/src/hb-open-type-private.hh index 080dcca1b8c..5060b3eb744 100644 --- a/chromium/third_party/harfbuzz-ng/src/hb-open-type-private.hh +++ b/chromium/third_party/harfbuzz-ng/src/src/hb-open-type-private.hh @@ -692,8 +692,8 @@ struct F2DOT14 : HBINT16 /* 32-bit signed fixed-point number (16.16). */ struct Fixed: HBINT32 { - //inline float to_float (void) const { return ???; } - //inline void set_float (float f) { v.set (f * ???); } + inline float to_float (void) const { return ((int32_t) v) / 65536.0; } + inline void set_float (float f) { v.set (round (f * 65536.0)); } public: DEFINE_SIZE_STATIC (4); }; @@ -729,6 +729,9 @@ DEFINE_NULL_DATA (Tag, " "); /* Glyph index number, same as uint16 (length = 16 bits) */ typedef HBUINT16 GlyphID; +/* Name-table index, same as uint16 (length = 16 bits) */ +typedef HBUINT16 NameID; + /* Script/language-system/feature index */ struct Index : HBUINT16 { static const unsigned int NOT_FOUND_INDEX = 0xFFFFu; @@ -740,8 +743,6 @@ template <typename Type> struct Offset : Type { inline bool is_null (void) const { return 0 == *this; } - public: - DEFINE_SIZE_STATIC (sizeof(Type)); inline void *serialize (hb_serialize_context_t *c, const void *base) { @@ -749,6 +750,9 @@ struct Offset : Type this->set ((char *) t - (char *) base); /* TODO(serialize) Overflow? */ return t; } + + public: + DEFINE_SIZE_STATIC (sizeof(Type)); }; typedef Offset<HBUINT16> Offset16; @@ -762,7 +766,8 @@ struct CheckSum : HBUINT32 static inline uint32_t CalcTableChecksum (const HBUINT32 *Table, uint32_t Length) { uint32_t Sum = 0L; - const HBUINT32 *EndPtr = Table+((Length+3) & ~3) / HBUINT32::static_size; + assert (0 == (Length & 3)); + const HBUINT32 *EndPtr = Table + Length / HBUINT32::static_size; while (Table < EndPtr) Sum += *Table++; @@ -860,6 +865,90 @@ static inline Type& operator + (Base &base, OffsetTo<Type, OffsetType> &offset) * Array Types */ + +/* TODO Use it in ArrayOf, HeadlessArrayOf, and other places around the code base?? */ +template <typename Type> +struct UnsizedArrayOf +{ + inline const Type& operator [] (unsigned int i) const { return arrayZ[i]; } + inline Type& operator [] (unsigned int i) { return arrayZ[i]; } + + inline bool sanitize (hb_sanitize_context_t *c, unsigned int count) const + { + 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)); + + return_trace (true); + } + inline bool sanitize (hb_sanitize_context_t *c, unsigned int count, const void *base) const + { + 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); + return_trace (true); + } + template <typename T> + inline bool sanitize (hb_sanitize_context_t *c, unsigned int count, const void *base, T user_data) const + { + 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, user_data))) + return_trace (false); + return_trace (true); + } + + private: + inline bool sanitize_shallow (hb_sanitize_context_t *c, unsigned int count) const + { + TRACE_SANITIZE (this); + return_trace (c->check_array (arrayZ, arrayZ[0].static_size, count)); + } + + public: + Type arrayZ[VAR]; + public: + DEFINE_SIZE_ARRAY (0, arrayZ); +}; + +/* Unsized array of offset's */ +template <typename Type, typename OffsetType> +struct UnsizedOffsetArrayOf : UnsizedArrayOf<OffsetTo<Type, OffsetType> > {}; + +/* Unsized array of offsets relative to the beginning of the array itself. */ +template <typename Type, typename OffsetType> +struct UnsizedOffsetListOf : UnsizedOffsetArrayOf<Type, OffsetType> +{ + inline const Type& operator [] (unsigned int i) const + { + return this+this->arrayZ[i]; + } + + inline bool sanitize (hb_sanitize_context_t *c, unsigned int count) const + { + TRACE_SANITIZE (this); + return_trace ((UnsizedOffsetArrayOf<Type, OffsetType>::sanitize (c, count, this))); + } + template <typename T> + inline bool sanitize (hb_sanitize_context_t *c, unsigned int count, T user_data) const + { + TRACE_SANITIZE (this); + return_trace ((UnsizedOffsetArrayOf<Type, OffsetType>::sanitize (c, count, this, user_data))); + } +}; + + /* An array with a number of elements. */ template <typename Type, typename LenType=HBUINT16> struct ArrayOf @@ -1113,7 +1202,9 @@ struct BinSearchHeader assert (len == v); entrySelectorZ.set (MAX (1u, _hb_bit_storage (v)) - 1); searchRangeZ.set (16 * (1u << entrySelectorZ)); - rangeShiftZ.set (16 * MAX (0, (int) v - searchRangeZ)); + rangeShiftZ.set (v * 16 > searchRangeZ + ? 16 * v - searchRangeZ + : 0); } protected: diff --git a/chromium/third_party/harfbuzz-ng/src/hb-ot-cmap-table.hh b/chromium/third_party/harfbuzz-ng/src/src/hb-ot-cmap-table.hh index 8d9ade432ea..02079898683 100644 --- a/chromium/third_party/harfbuzz-ng/src/hb-ot-cmap-table.hh +++ b/chromium/third_party/harfbuzz-ng/src/src/hb-ot-cmap-table.hh @@ -602,9 +602,9 @@ struct cmap + 8 // 1 EncodingRecord + 16 // Format 12 header + 12 * groups.len; // SequentialMapGroup records - void *dest = calloc (dest_sz, 1); + void *dest = malloc (dest_sz); if (unlikely (!dest)) { - DEBUG_MSG(SUBSET, nullptr, "Unable to alloc %zu for cmap subset output", dest_sz); + DEBUG_MSG(SUBSET, nullptr, "Unable to alloc %lu for cmap subset output", (unsigned long) dest_sz); return false; } @@ -618,9 +618,11 @@ struct cmap hb_blob_t *cmap_prime = hb_blob_create ((const char *)dest, dest_sz, HB_MEMORY_MODE_READONLY, - /* userdata */ nullptr, + dest, free); - return hb_subset_plan_add_table (plan, HB_OT_TAG_cmap, cmap_prime); + bool result = hb_subset_plan_add_table (plan, HB_OT_TAG_cmap, cmap_prime); + hb_blob_destroy (cmap_prime); + return result; } struct accelerator_t diff --git a/chromium/third_party/harfbuzz-ng/src/hb-ot-cbdt-table.hh b/chromium/third_party/harfbuzz-ng/src/src/hb-ot-color-cbdt-table.hh index e4519529b1e..b4971bda7f8 100644 --- a/chromium/third_party/harfbuzz-ng/src/hb-ot-cbdt-table.hh +++ b/chromium/third_party/harfbuzz-ng/src/src/hb-ot-color-cbdt-table.hh @@ -24,8 +24,8 @@ * Google Author(s): Seigo Nonaka */ -#ifndef HB_OT_CBDT_TABLE_HH -#define HB_OT_CBDT_TABLE_HH +#ifndef HB_OT_COLOR_CBDT_TABLE_HH +#define HB_OT_COLOR_CBDT_TABLE_HH #include "hb-open-type-private.hh" @@ -47,21 +47,21 @@ struct SmallGlyphMetrics extents->height = -height; } - HBUINT8 height; - HBUINT8 width; - HBINT8 bearingX; - HBINT8 bearingY; - HBUINT8 advance; - + HBUINT8 height; + HBUINT8 width; + HBINT8 bearingX; + HBINT8 bearingY; + HBUINT8 advance; + public: DEFINE_SIZE_STATIC(5); }; struct BigGlyphMetrics : SmallGlyphMetrics { - HBINT8 vertBearingX; - HBINT8 vertBearingY; - HBUINT8 vertAdvance; - + HBINT8 vertBearingX; + HBINT8 vertBearingY; + HBUINT8 vertAdvance; + public: DEFINE_SIZE_STATIC(8); }; @@ -73,19 +73,19 @@ struct SBitLineMetrics return_trace (c->check_struct (this)); } - HBINT8 ascender; - HBINT8 decender; - HBUINT8 widthMax; - HBINT8 caretSlopeNumerator; - HBINT8 caretSlopeDenominator; - HBINT8 caretOffset; - HBINT8 minOriginSB; - HBINT8 minAdvanceSB; - HBINT8 maxBeforeBL; - HBINT8 minAfterBL; - HBINT8 padding1; - HBINT8 padding2; - + HBINT8 ascender; + HBINT8 decender; + HBUINT8 widthMax; + HBINT8 caretSlopeNumerator; + HBINT8 caretSlopeDenominator; + HBINT8 caretOffset; + HBINT8 minOriginSB; + HBINT8 minAdvanceSB; + HBINT8 maxBeforeBL; + HBINT8 minAfterBL; + HBINT8 padding1; + HBINT8 padding2; + public: DEFINE_SIZE_STATIC(12); }; @@ -102,10 +102,10 @@ struct IndexSubtableHeader return_trace (c->check_struct (this)); } - HBUINT16 indexFormat; - HBUINT16 imageFormat; - HBUINT32 imageDataOffset; - + HBUINT16 indexFormat; + HBUINT16 imageFormat; + HBUINT32 imageDataOffset; + public: DEFINE_SIZE_STATIC(8); }; @@ -131,9 +131,9 @@ struct IndexSubtableFormat1Or3 return true; } - IndexSubtableHeader header; - Offset<OffsetType> offsetArrayZ[VAR]; - + IndexSubtableHeader header; + Offset<OffsetType> offsetArrayZ[VAR]; + public: DEFINE_SIZE_ARRAY(8, offsetArrayZ); }; @@ -214,10 +214,10 @@ struct IndexSubtableRecord offset, length, format); } - HBUINT16 firstGlyphIndex; - HBUINT16 lastGlyphIndex; - LOffsetTo<IndexSubtable> offsetToSubtable; - + GlyphID firstGlyphIndex; + GlyphID lastGlyphIndex; + LOffsetTo<IndexSubtable> offsetToSubtable; + public: DEFINE_SIZE_STATIC(8); }; @@ -249,8 +249,7 @@ struct IndexSubtableArray } protected: - IndexSubtableRecord indexSubtablesZ[VAR]; - + IndexSubtableRecord indexSubtablesZ[VAR]; public: DEFINE_SIZE_ARRAY(0, indexSubtablesZ); }; @@ -275,19 +274,19 @@ struct BitmapSizeTable } protected: - LOffsetTo<IndexSubtableArray> indexSubtableArrayOffset; - HBUINT32 indexTablesSize; - HBUINT32 numberOfIndexSubtables; - HBUINT32 colorRef; - SBitLineMetrics horizontal; - SBitLineMetrics vertical; - HBUINT16 startGlyphIndex; - HBUINT16 endGlyphIndex; - HBUINT8 ppemX; - HBUINT8 ppemY; - HBUINT8 bitDepth; - HBINT8 flags; - + LOffsetTo<IndexSubtableArray> + indexSubtableArrayOffset; + HBUINT32 indexTablesSize; + HBUINT32 numberOfIndexSubtables; + HBUINT32 colorRef; + SBitLineMetrics horizontal; + SBitLineMetrics vertical; + GlyphID startGlyphIndex; + GlyphID endGlyphIndex; + HBUINT8 ppemX; + HBUINT8 ppemY; + HBUINT8 bitDepth; + HBINT8 flags; public: DEFINE_SIZE_STATIC(48); }; @@ -299,11 +298,10 @@ struct BitmapSizeTable struct GlyphBitmapDataFormat17 { - SmallGlyphMetrics glyphMetrics; - HBUINT32 dataLen; - HBUINT8 dataZ[VAR]; - - DEFINE_SIZE_ARRAY(9, dataZ); + SmallGlyphMetrics glyphMetrics; + ArrayOf<HBUINT8, HBUINT32> data; + public: + DEFINE_SIZE_ARRAY(9, data); }; @@ -352,7 +350,6 @@ struct CBLC protected: FixedVersion<> version; LArrayOf<BitmapSizeTable> sizeTables; - public: DEFINE_SIZE_ARRAY(8, sizeTables); }; @@ -459,13 +456,12 @@ struct CBDT protected: - FixedVersion<>version; - HBUINT8 dataZ[VAR]; - + FixedVersion<> version; + HBUINT8 dataZ[VAR]; public: DEFINE_SIZE_ARRAY(4, dataZ); }; } /* namespace OT */ -#endif /* HB_OT_CBDT_TABLE_HH */ +#endif /* HB_OT_COLOR_CBDT_TABLE_HH */ diff --git a/chromium/third_party/harfbuzz-ng/src/src/hb-ot-color-colr-table.hh b/chromium/third_party/harfbuzz-ng/src/src/hb-ot-color-colr-table.hh new file mode 100644 index 00000000000..c1cf6de573d --- /dev/null +++ b/chromium/third_party/harfbuzz-ng/src/src/hb-ot-color-colr-table.hh @@ -0,0 +1,102 @@ +/* + * Copyright © 2018 Ebrahim Byagowi + * + * This is part of HarfBuzz, a text shaping library. + * + * Permission is hereby granted, without written agreement and without + * license or royalty fees, to use, copy, modify, and distribute this + * software and its documentation for any purpose, provided that the + * above copyright notice and the following two paragraphs appear in + * all copies of this software. + * + * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR + * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES + * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN + * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, + * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS + * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO + * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + */ + +#ifndef HB_OT_COLOR_COLR_TABLE_HH +#define HB_OT_COLOR_COLR_TABLE_HH + +#include "hb-open-type-private.hh" + +/* + * Color Palette + * http://www.microsoft.com/typography/otspec/colr.htm + */ + +#define HB_OT_TAG_COLR HB_TAG('C','O','L','R') + +namespace OT { + + +struct LayerRecord +{ + friend struct COLR; + + inline bool sanitize (hb_sanitize_context_t *c) const + { + TRACE_SANITIZE (this); + return_trace (c->check_struct (this)); + } + + protected: + GlyphID glyphid; /* Glyph ID of layer glyph */ + HBUINT16 colorIdx; /* Index value to use with a selected color palette */ + public: + DEFINE_SIZE_STATIC (4); +}; + +struct BaseGlyphRecord +{ + friend struct COLR; + + inline bool sanitize (hb_sanitize_context_t *c) const + { + TRACE_SANITIZE (this); + return_trace (c->check_struct (this)); + } + + protected: + GlyphID glyphid; /* Glyph ID of reference glyph */ + HBUINT16 firstLayerIdx; /* Index to the layer record */ + HBUINT16 numLayers; /* Number of color layers associated with this glyph */ + public: + DEFINE_SIZE_STATIC (6); +}; + +struct COLR +{ + static const hb_tag_t tableTag = HB_OT_TAG_COLR; + + inline bool sanitize (hb_sanitize_context_t *c) const + { + TRACE_SANITIZE (this); + return_trace (c->check_struct (this) && + (this+baseGlyphs).sanitize (c, numBaseGlyphs) && + (this+layers).sanitize (c, numLayers)); + } + + protected: + HBUINT16 version; /* Table version number */ + HBUINT16 numBaseGlyphs; /* Number of Base Glyph Records */ + LOffsetTo<UnsizedArrayOf<BaseGlyphRecord> > + baseGlyphs; /* Offset to Base Glyph records. */ + LOffsetTo<UnsizedArrayOf<LayerRecord> > + layers; /* Offset to Layer Records */ + HBUINT16 numLayers; /* Number of Layer Records */ + public: + DEFINE_SIZE_STATIC (14); +}; + +} /* namespace OT */ + + +#endif /* HB_OT_COLOR_COLR_TABLE_HH */ diff --git a/chromium/third_party/harfbuzz-ng/src/src/hb-ot-color-cpal-table.hh b/chromium/third_party/harfbuzz-ng/src/src/hb-ot-color-cpal-table.hh new file mode 100644 index 00000000000..e364c8a44d3 --- /dev/null +++ b/chromium/third_party/harfbuzz-ng/src/src/hb-ot-color-cpal-table.hh @@ -0,0 +1,208 @@ +/* + * Copyright © 2016 Google, Inc. + * Copyright © 2018 Ebrahim Byagowi + * + * This is part of HarfBuzz, a text shaping library. + * + * Permission is hereby granted, without written agreement and without + * license or royalty fees, to use, copy, modify, and distribute this + * software and its documentation for any purpose, provided that the + * above copyright notice and the following two paragraphs appear in + * all copies of this software. + * + * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR + * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES + * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN + * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, + * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS + * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO + * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + * + * Google Author(s): Sascha Brawer + */ + +#ifndef HB_OT_COLOR_CPAL_TABLE_HH +#define HB_OT_COLOR_CPAL_TABLE_HH + +#include "hb-open-type-private.hh" + + +/* + * Following parts to be moved to a public header. + */ + +/** + * hb_ot_color_t: + * ARGB data type for holding color values. + * + * Since: REPLACEME + */ +typedef uint32_t hb_ot_color_t; + + +/** + * hb_ot_color_palette_flags_t: + * @HB_OT_COLOR_PALETTE_FLAG_DEFAULT: default indicating that there is nothing special to note about a color palette. + * @HB_OT_COLOR_PALETTE_FLAG_FOR_LIGHT_BACKGROUND: flag indicating that the color palette is suitable for rendering text on light background. + * @HB_OT_COLOR_PALETTE_FLAG_FOR_DARK_BACKGROUND: flag indicating that the color palette is suitable for rendering text on dark background. + * + * Since: REPLACEME + */ +typedef enum { /*< flags >*/ + HB_OT_COLOR_PALETTE_FLAG_DEFAULT = 0x00000000u, + HB_OT_COLOR_PALETTE_FLAG_FOR_LIGHT_BACKGROUND = 0x00000001u, + HB_OT_COLOR_PALETTE_FLAG_FOR_DARK_BACKGROUND = 0x00000002u, +} hb_ot_color_palette_flags_t; + +// HB_EXTERN unsigned int +// hb_ot_color_get_palette_count (hb_face_t *face); + +// HB_EXTERN unsigned int +// hb_ot_color_get_palette_name_id (hb_face_t *face, unsigned int palette); + +// HB_EXTERN hb_ot_color_palette_flags_t +// hb_ot_color_get_palette_flags (hb_face_t *face, unsigned int palette); + +// HB_EXTERN unsigned int +// hb_ot_color_get_palette_colors (hb_face_t *face, +// unsigned int palette, /* default=0 */ +// unsigned int start_offset, +// unsigned int *color_count /* IN/OUT */, +// hb_ot_color_t *colors /* OUT */); + + + + + +/* + * Color Palette + * http://www.microsoft.com/typography/otspec/cpal.htm + */ + +#define HB_OT_TAG_CPAL HB_TAG('C','P','A','L') + +namespace OT { + + +struct CPALV1Tail +{ + friend struct CPAL; + + inline bool sanitize (hb_sanitize_context_t *c, unsigned int palettes) const + { + TRACE_SANITIZE (this); + return_trace ( + c->check_struct (this) && + c->check_array ((const void*) &paletteFlags, sizeof (HBUINT32), palettes) && + c->check_array ((const void*) &paletteLabel, sizeof (HBUINT16), palettes) && + c->check_array ((const void*) &paletteEntryLabel, sizeof (HBUINT16), palettes)); + } + + private: + inline hb_ot_color_palette_flags_t + get_palette_flags (const void *base, unsigned int palette) const + { + const HBUINT32* flags = &paletteFlags (base); + return (hb_ot_color_palette_flags_t) (uint32_t) flags[palette]; + } + + inline unsigned int + get_palette_name_id (const void *base, unsigned int palette) const + { + const HBUINT16* name_ids = &paletteLabel (base); + return name_ids[palette]; + } + + protected: + LOffsetTo<HBUINT32> paletteFlags; + LOffsetTo<HBUINT16> paletteLabel; + LOffsetTo<HBUINT16> paletteEntryLabel; + public: + DEFINE_SIZE_STATIC (12); +}; + +typedef HBUINT32 BGRAColor; + +struct CPAL +{ + static const hb_tag_t tableTag = HB_OT_TAG_CPAL; + + inline bool sanitize (hb_sanitize_context_t *c) const + { + TRACE_SANITIZE (this); + if (!(c->check_struct (this) && // This checks colorRecordIndicesX sanity also, see #get_size + c->check_array ((const void*) &colorRecordsZ, sizeof (BGRAColor), numColorRecords))) + return_trace (false); + + // Check for indices sanity so no need for doing it runtime + for (unsigned int i = 0; i < numPalettes; ++i) + if (colorRecordIndicesX[i] + numPaletteEntries > numColorRecords) + return_trace (false); + + // If version is zero, we are done here; otherwise we need to check tail also + if (version == 0) + return_trace (true); + + const CPALV1Tail &v1 = StructAfter<CPALV1Tail> (*this); + return_trace (v1.sanitize (c, numPalettes)); + } + + inline unsigned int get_size (void) const + { + return min_size + numPalettes * sizeof (HBUINT16); + } + + inline hb_ot_color_palette_flags_t get_palette_flags (unsigned int palette) const + { + if (version == 0 || palette >= numPalettes) + return HB_OT_COLOR_PALETTE_FLAG_DEFAULT; + + const CPALV1Tail& cpal1 = StructAfter<CPALV1Tail> (*this); + return cpal1.get_palette_flags (this, palette); + } + + inline unsigned int get_palette_name_id (unsigned int palette) const + { + if (version == 0 || palette >= numPalettes) + return 0xFFFF; + + const CPALV1Tail& cpal1 = StructAfter<CPALV1Tail> (*this); + return cpal1.get_palette_name_id (this, palette); + } + + inline unsigned int get_palette_count () const + { + return numPalettes; + } + + inline hb_ot_color_t get_color_record_argb (unsigned int color_index, unsigned int palette) const + { + if (color_index >= numPaletteEntries || palette >= numPalettes) + return 0; + + const BGRAColor* records = &colorRecordsZ(this); + // No need for more range check as it is already done on #sanitize + return records[colorRecordIndicesX[palette] + color_index]; + } + + protected: + HBUINT16 version; + /* Version 0 */ + HBUINT16 numPaletteEntries; + HBUINT16 numPalettes; + HBUINT16 numColorRecords; + LOffsetTo<HBUINT32> colorRecordsZ; + HBUINT16 colorRecordIndicesX[VAR]; // VAR=numPalettes +/*CPALV1Tail v1[VAR];*/ + public: + DEFINE_SIZE_ARRAY (12, colorRecordIndicesX); +}; + +} /* namespace OT */ + + +#endif /* HB_OT_COLOR_CPAL_TABLE_HH */ diff --git a/chromium/third_party/harfbuzz-ng/src/src/hb-ot-color-sbix-table.hh b/chromium/third_party/harfbuzz-ng/src/src/hb-ot-color-sbix-table.hh new file mode 100644 index 00000000000..c0d8f9b3dda --- /dev/null +++ b/chromium/third_party/harfbuzz-ng/src/src/hb-ot-color-sbix-table.hh @@ -0,0 +1,132 @@ +/* + * Copyright © 2018 Ebrahim Byagowi + * + * This is part of HarfBuzz, a text shaping library. + * + * Permission is hereby granted, without written agreement and without + * license or royalty fees, to use, copy, modify, and distribute this + * software and its documentation for any purpose, provided that the + * above copyright notice and the following two paragraphs appear in + * all copies of this software. + * + * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR + * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES + * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN + * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, + * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS + * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO + * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + */ + +#ifndef HB_OT_COLOR_SBIX_TABLE_HH +#define HB_OT_COLOR_SBIX_TABLE_HH + +#include "hb-open-type-private.hh" + +#define HB_OT_TAG_SBIX HB_TAG('s','b','i','x') + +namespace OT { + + +struct SBIXGlyph +{ + HBINT16 xOffset; /* The horizontal (x-axis) offset from the left + * edge of the graphic to the glyph’s origin. + * That is, the x-coordinate of the point on the + * baseline at the left edge of the glyph. */ + HBINT16 yOffset; /* The vertical (y-axis) offset from the bottom + * edge of the graphic to the glyph’s origin. + * That is, the y-coordinate of the point on the + * baseline at the left edge of the glyph. */ + Tag graphicType; /* Indicates the format of the embedded graphic + * data: one of 'jpg ', 'png ' or 'tiff', or the + * special format 'dupe'. */ + HBUINT8 data[VAR]; /* The actual embedded graphic data. The total + * length is inferred from sequential entries in + * the glyphDataOffsets array and the fixed size + * (8 bytes) of the preceding fields. */ + public: + DEFINE_SIZE_ARRAY (8, data); +}; + +struct SBIXStrike +{ + inline bool sanitize (hb_sanitize_context_t *c) const + { + TRACE_SANITIZE (this); + return_trace (c->check_struct (this) && + c->check_array (imageOffsetsZ, + sizeof (HBUINT32), + 1 + c->num_glyphs)); + } + + HBUINT16 ppem; /* The PPEM size for which this strike was designed. */ + HBUINT16 resolution; /* The device pixel density (in PPI) for which this + * strike was designed. (E.g., 96 PPI, 192 PPI.) */ + protected: + LOffsetTo<SBIXGlyph> imageOffsetsZ[VAR]; // VAR=maxp.numGlyphs + 1 + /* Offset from the beginning of the strike data header + * to bitmap data for an individual glyph ID. */ + public: + DEFINE_SIZE_STATIC (8); +}; + +/* + * sbix -- Standard Bitmap Graphics Table + */ +// It should be called with something like this so it can have +// access to num_glyph while sanitizing. +// +// static inline const OT::sbix* +// _get_sbix (hb_face_t *face) +// { +// OT::Sanitizer<OT::sbix> sanitizer; +// sanitizer.set_num_glyphs (face->get_num_glyphs ()); +// hb_blob_t *sbix_blob = sanitizer.sanitize (face->reference_table (HB_OT_TAG_SBIX)); +// return OT::Sanitizer<OT::sbix>::lock_instance (sbix_blob); +// } +// +struct sbix +{ + static const hb_tag_t tableTag = HB_OT_TAG_SBIX; + + inline bool sanitize (hb_sanitize_context_t *c) const + { + TRACE_SANITIZE (this); + return_trace (c->check_struct (this) && strikes.sanitize (c, this)); + } + + // inline void dump (unsigned int num_glyphs, unsigned int group) const + // { + // const SBIXStrike &strike = strikes[group](this); + // for (unsigned int i = 0; i < num_glyphs; ++i) + // if (strike.imageOffsetsZ[i + 1] - strike.imageOffsetsZ[i] > 0) + // { + // const SBIXGlyph &sbixGlyph = strike.imageOffsetsZ[i]((const void *) &strike); + // char outName[255]; + // sprintf (outName, "out/%d-%d.png", group, i); + // FILE *f = fopen (outName, "wb"); + // fwrite (sbixGlyph.data, 1, + // strike.imageOffsetsZ[i + 1] - strike.imageOffsetsZ[i] - 8, f); + // fclose (f); + // } + // } + + protected: + HBUINT16 version; /* Table version number — set to 1 */ + HBUINT16 flags; /* Bit 0: Set to 1. Bit 1: Draw outlines. + * Bits 2 to 15: reserved (set to 0). */ + ArrayOf<LOffsetTo<SBIXStrike>, HBUINT32> + strikes; /* Offsets from the beginning of the 'sbix' + * table to data for each individual bitmap strike. */ + public: + DEFINE_SIZE_ARRAY (8, strikes); +}; + +} /* namespace OT */ + +#endif /* HB_OT_COLOR_SBIX_TABLE_HH */ diff --git a/chromium/third_party/harfbuzz-ng/src/src/hb-ot-color-svg-table.hh b/chromium/third_party/harfbuzz-ng/src/src/hb-ot-color-svg-table.hh new file mode 100644 index 00000000000..3dc24e99500 --- /dev/null +++ b/chromium/third_party/harfbuzz-ng/src/src/hb-ot-color-svg-table.hh @@ -0,0 +1,119 @@ +/* + * Copyright © 2018 Ebrahim Byagowi + * + * This is part of HarfBuzz, a text shaping library. + * + * Permission is hereby granted, without written agreement and without + * license or royalty fees, to use, copy, modify, and distribute this + * software and its documentation for any purpose, provided that the + * above copyright notice and the following two paragraphs appear in + * all copies of this software. + * + * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR + * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES + * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN + * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, + * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS + * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO + * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + */ + +#ifndef HB_OT_COLOR_SVG_TABLE_HH +#define HB_OT_COLOR_SVG_TABLE_HH + +#include "hb-open-type-private.hh" + +/* + * The SVG (Scalable Vector Graphics) table + * https://docs.microsoft.com/en-us/typography/opentype/spec/svg + */ + +#define HB_OT_TAG_SVG HB_TAG('S','V','G',' ') + +namespace OT { + + +struct SVGDocumentIndexEntry +{ + // friend struct SVGDocumentIndex; + + inline bool sanitize (hb_sanitize_context_t *c, const void* base) const + { + TRACE_SANITIZE (this); + return_trace (c->check_struct (this) && + c->check_range (&svgDoc (base), svgDocLength)); + } + + protected: + HBUINT16 startGlyphID; /* The first glyph ID in the range described by + * this index entry. */ + HBUINT16 endGlyphID; /* The last glyph ID in the range described by + * this index entry. Must be >= startGlyphID. */ + LOffsetTo<const uint8_t *> + svgDoc; /* Offset from the beginning of the SVG Document Index + * to an SVG document. Must be non-zero. */ + HBUINT32 svgDocLength; /* Length of the SVG document. + * Must be non-zero. */ + public: + DEFINE_SIZE_STATIC (12); +}; + +struct SVGDocumentIndex +{ + inline bool sanitize (hb_sanitize_context_t *c) const + { + TRACE_SANITIZE (this); + // dump (); + return_trace (c->check_struct (this) && + entries.sanitize (c, this)); + } + + // inline void dump () const + // { + // for (unsigned int i = 0; i < entries.len; ++i) + // { + // char outName[255]; + // sprintf (outName, "out/%d.svg", i); + // const SVGDocumentIndexEntry &entry = entries[i]; + // FILE *f = fopen (outName, "wb"); + // fwrite (&entry.svgDoc (this), 1, entry.svgDocLength, f); + // fclose (f); + // } + // } + + protected: + ArrayOf<SVGDocumentIndexEntry> + entries; /* Array of SVG Document Index Entries. */ + public: + DEFINE_SIZE_ARRAY (2, entries); +}; + +struct SVG +{ + static const hb_tag_t tableTag = HB_OT_TAG_SVG; + + inline bool sanitize (hb_sanitize_context_t *c) const + { + TRACE_SANITIZE (this); + return_trace (c->check_struct (this) && + svgDocIndex(this).sanitize (c)); + } + + protected: + HBUINT16 version; /* Table version (starting at 0). */ + LOffsetTo<SVGDocumentIndex> + svgDocIndex; /* Offset (relative to the start of the SVG table) to the + * SVG Documents Index. Must be non-zero. */ + HBUINT32 reserved; /* Set to 0. */ + public: + DEFINE_SIZE_STATIC (10); +}; + +} /* namespace OT */ + + +#endif /* HB_OT_COLOR_SVG_TABLE_HH */ diff --git a/chromium/third_party/harfbuzz-ng/src/src/hb-ot-color.cc b/chromium/third_party/harfbuzz-ng/src/src/hb-ot-color.cc new file mode 100644 index 00000000000..ceebe0b7a02 --- /dev/null +++ b/chromium/third_party/harfbuzz-ng/src/src/hb-ot-color.cc @@ -0,0 +1,183 @@ +/* + * Copyright © 2016 Google, Inc. + * Copyright © 2018 Ebrahim Byagowi + * + * This is part of HarfBuzz, a text shaping library. + * + * Permission is hereby granted, without written agreement and without + * license or royalty fees, to use, copy, modify, and distribute this + * software and its documentation for any purpose, provided that the + * above copyright notice and the following two paragraphs appear in + * all copies of this software. + * + * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR + * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES + * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN + * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, + * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS + * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO + * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + * + * Google Author(s): Sascha Brawer + */ + +#include "hb-open-type-private.hh" +#include "hb-ot-color-colr-table.hh" +#include "hb-ot-color-cpal-table.hh" +#include "hb-ot.h" + +#include <stdlib.h> +#include <string.h> + +#include "hb-ot-layout-private.hh" +#include "hb-shaper-private.hh" + +#if 0 +HB_MARK_AS_FLAG_T (hb_ot_color_palette_flags_t) +//HB_SHAPER_DATA_ENSURE_DECLARE(ot, face) Hmm? + + +static inline const OT::COLR& +_get_colr (hb_face_t *face) +{ + if (unlikely (!hb_ot_shaper_face_data_ensure (face))) return OT::Null(OT::COLR); + hb_ot_layout_t * layout = hb_ot_layout_from_face (face); + return *(layout->colr.get ()); +} + +static inline const OT::CPAL& +_get_cpal (hb_face_t *face) +{ + if (unlikely (!hb_ot_shaper_face_data_ensure (face))) return OT::Null(OT::CPAL); + hb_ot_layout_t * layout = hb_ot_layout_from_face (face); + return *(layout->cpal.get ()); +} + + +/** + * hb_ot_color_get_palette_count: + * @face: a font face. + * + * Returns: the number of color palettes in @face, or zero if @face has + * no colors. + * + * Since: REPLACEME + */ +unsigned int +hb_ot_color_get_palette_count (hb_face_t *face) +{ + const OT::CPAL& cpal = _get_cpal (face); + return cpal.get_palette_count (); +} + + +/** + * hb_ot_color_get_palette_name_id: + * @face: a font face. + * @palette: the index of the color palette whose name is being requested. + * + * Retrieves the name id of a color palette. For example, a color font can + * have themed palettes like "Spring", "Summer", "Fall", and "Winter". + * + * Returns: an identifier within @face's `name` table. + * If the requested palette has no name, or if @face has no colors, + * or if @palette is not between 0 and hb_ot_color_get_palette_count(), + * the result is 0xFFFF. The implementation does not check whether + * the returned palette name id is actually in @face's `name` table. + * + * Since: REPLACEME + */ +unsigned int +hb_ot_color_get_palette_name_id (hb_face_t *face, unsigned int palette) +{ + const OT::CPAL& cpal = _get_cpal (face); + return cpal.get_palette_name_id (palette); +} + + +/** + * hb_ot_color_get_palette_flags: + * @face: a font face + * @palette: the index of the color palette whose flags are being requested + * + * Returns: the flags for the requested color palette. If @face has no colors, + * or if @palette is not between 0 and hb_ot_color_get_palette_count(), + * the result is #HB_OT_COLOR_PALETTE_FLAG_DEFAULT. + * + * Since: REPLACEME + */ +hb_ot_color_palette_flags_t +hb_ot_color_get_palette_flags (hb_face_t *face, unsigned int palette) +{ + const OT::CPAL& cpal = _get_cpal(face); + return cpal.get_palette_flags (palette); +} + + +/** + * hb_ot_color_get_palette_colors: + * @face: a font face. + * @palette: 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) (optional): + * an array of #hb_ot_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_get_palette_colors() a second time. + * + * Retrieves the colors in a color palette. + * + * Returns: the total number of colors in the palette. All palettes in + * a font have the same number of colors. If @face has no colors, or if + * @palette is not between 0 and hb_ot_color_get_palette_count(), + * the result is zero. + * + * Since: REPLACEME + */ +unsigned int +hb_ot_color_get_palette_colors (hb_face_t *face, + unsigned int palette, /* default=0 */ + unsigned int start_offset, + unsigned int *color_count /* IN/OUT */, + hb_ot_color_t *colors /* OUT */) +{ + const OT::CPAL& cpal = _get_cpal(face); + if (unlikely (palette >= cpal.numPalettes)) + { + if (color_count) *color_count = 0; + return 0; + } + + const OT::ColorRecord* crec = &cpal.offsetFirstColorRecord (&cpal); + crec += cpal.colorRecordIndices[palette]; + + unsigned int num_results = 0; + if (likely (color_count && colors)) + { + for (unsigned int i = start_offset; + i < cpal.numPaletteEntries && num_results < *color_count; ++i) + { + hb_ot_color_t* result = &colors[num_results]; + result->red = crec[i].red; + result->green = crec[i].green; + result->blue = crec[i].blue; + result->alpha = crec[i].alpha; + ++num_results; + } + } + + if (likely (color_count)) *color_count = num_results; + return cpal.numPaletteEntries; +} +#endif diff --git a/chromium/third_party/harfbuzz-ng/src/hb-ot-font.cc b/chromium/third_party/harfbuzz-ng/src/src/hb-ot-font.cc index 9864064b112..0e373d30f92 100644 --- a/chromium/third_party/harfbuzz-ng/src/hb-ot-font.cc +++ b/chromium/third_party/harfbuzz-ng/src/src/hb-ot-font.cc @@ -31,12 +31,13 @@ #include "hb-font-private.hh" #include "hb-ot-cmap-table.hh" -#include "hb-ot-cbdt-table.hh" #include "hb-ot-glyf-table.hh" #include "hb-ot-hmtx-table.hh" #include "hb-ot-kern-table.hh" #include "hb-ot-post-table.hh" +#include "hb-ot-color-cbdt-table.hh" + struct hb_ot_font_t { diff --git a/chromium/third_party/harfbuzz-ng/src/hb-ot-font.h b/chromium/third_party/harfbuzz-ng/src/src/hb-ot-font.h index 80eaa54b1ad..80eaa54b1ad 100644 --- a/chromium/third_party/harfbuzz-ng/src/hb-ot-font.h +++ b/chromium/third_party/harfbuzz-ng/src/src/hb-ot-font.h diff --git a/chromium/third_party/harfbuzz-ng/src/hb-ot-glyf-table.hh b/chromium/third_party/harfbuzz-ng/src/src/hb-ot-glyf-table.hh index a73fd4aaad7..d62f24bd916 100644 --- a/chromium/third_party/harfbuzz-ng/src/hb-ot-glyf-table.hh +++ b/chromium/third_party/harfbuzz-ng/src/src/hb-ot-glyf-table.hh @@ -29,7 +29,9 @@ #include "hb-open-type-private.hh" #include "hb-ot-head-table.hh" - +#include "hb-subset-glyf.hh" +#include "hb-subset-plan.hh" +#include "hb-subset-private.hh" namespace OT { @@ -78,6 +80,44 @@ struct glyf return_trace (true); } + inline bool subset (hb_subset_plan_t *plan) const + { + 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 && hb_subset_plan_add_table (plan, HB_OT_TAG_glyf, glyf_prime); + success = success && hb_subset_plan_add_table (plan, HB_OT_TAG_loca, loca_prime); + success = success && _add_head_and_set_loca_version (plan->source, use_short_loca, plan->dest); + } else { + success = false; + } + hb_blob_destroy (loca_prime); + hb_blob_destroy (glyf_prime); + + return success; + } + + static bool + _add_head_and_set_loca_version (hb_face_t *source, bool use_short_loca, hb_face_t *dest) + { + hb_blob_t *head_blob = OT::Sanitizer<OT::head>().sanitize (hb_face_reference_table (source, HB_OT_TAG_head)); + hb_blob_t *head_prime_blob = hb_blob_copy_writable_or_fail (head_blob); + hb_blob_destroy (head_blob); + + if (unlikely (!head_prime_blob)) + return false; + + OT::head *head_prime = (OT::head *) hb_blob_get_data_writable (head_prime_blob, nullptr); + head_prime->indexToLocFormat.set (use_short_loca ? 0 : 1); + bool success = hb_subset_face_add_table (dest, 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 @@ -235,6 +275,90 @@ struct glyf composite); } + /* based on FontTools _g_l_y_f.py::trim */ + inline bool remove_padding(unsigned int start_offset, + unsigned int *end_offset) const + { + static const int FLAG_X_SHORT = 0x02; + static const int FLAG_Y_SHORT = 0x04; + static const int FLAG_REPEAT = 0x08; + static const int FLAG_X_SAME = 0x10; + static const int FLAG_Y_SAME = 0x20; + + if (*end_offset - start_offset < GlyphHeader::static_size) + return true; + + 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; + + if (num_contours < 0) + /* Trimming for composites not implemented. + * If removing hints it falls out of that. */ + return true; + else if (num_contours > 0) + { + /* simple glyph w/contours, possibly trimmable */ + glyph += GlyphHeader::static_size + 2 * num_contours; + + 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); + + glyph += 2 + nInstructions; + if (unlikely (glyph + 2 >= glyph_end)) return false; + + unsigned int coordBytes = 0; + unsigned int coordsWithFlags = 0; + while (glyph < glyph_end) + { + uint8_t flag = (uint8_t) *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; + glyph++; + } + + unsigned int xBytes, yBytes; + xBytes = yBytes = 0; + if (flag & FLAG_X_SHORT) + xBytes = 1; + else if ((flag & FLAG_X_SAME) == 0) + xBytes = 2; + + 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; + } + + if (coordsWithFlags != nCoordinates) + { + DEBUG_MSG(SUBSET, nullptr, "Expect %d coords to have flags, got flags for %d", nCoordinates, coordsWithFlags); + return false; + } + glyph += coordBytes; + + if (glyph < glyph_end) + *end_offset -= glyph_end - glyph; + } + return true; + } + inline bool get_offsets (hb_codepoint_t glyph, unsigned int *start_offset /* OUT */, unsigned int *end_offset /* OUT */) const @@ -251,6 +375,7 @@ struct glyf else { const HBUINT32 *offsets = (const HBUINT32 *) loca_table->dataX; + *start_offset = offsets[glyph]; *end_offset = offsets[glyph + 1]; } @@ -261,6 +386,51 @@ struct glyf return true; } + inline bool get_instruction_offsets(unsigned int start_offset, + unsigned int end_offset, + unsigned int *instruction_start /* OUT */, + unsigned int *instruction_end /* OUT */) const + { + if (end_offset - start_offset < GlyphHeader::static_size) + { + *instruction_start = 0; + *instruction_end = 0; + return true; /* Empty glyph; no instructions. */ + } + const GlyphHeader &glyph_header = StructAtOffset<GlyphHeader> (glyf_table, start_offset); + int16_t num_contours = (int16_t) glyph_header.numberOfContours; + if (num_contours < 0) + { + 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->dataX) + last->get_size(); + else + *instruction_start = end_offset; + *instruction_end = end_offset; + if (unlikely (*instruction_start > *instruction_end)) + { + DEBUG_MSG(SUBSET, nullptr, "Invalid instruction offset, %d is outside [%d, %d]", *instruction_start, start_offset, end_offset); + return false; + } + } + else + { + unsigned int instruction_length_offset = start_offset + GlyphHeader::static_size + 2 * num_contours; + const HBUINT16 &instruction_length = StructAtOffset<HBUINT16> (glyf_table, instruction_length_offset); + *instruction_start = instruction_length_offset + 2; + *instruction_end = *instruction_start + (uint16_t) instruction_length; + } + return true; + } + inline bool get_extents (hb_codepoint_t glyph, hb_glyph_extents_t *extents) const { diff --git a/chromium/third_party/harfbuzz-ng/src/src/hb-ot-hdmx-table.hh b/chromium/third_party/harfbuzz-ng/src/src/hb-ot-hdmx-table.hh new file mode 100644 index 00000000000..f08fe39d8be --- /dev/null +++ b/chromium/third_party/harfbuzz-ng/src/src/hb-ot-hdmx-table.hh @@ -0,0 +1,198 @@ +/* + * 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 + */ + +#ifndef HB_OT_HDMX_TABLE_HH +#define HB_OT_HDMX_TABLE_HH + +#include "hb-open-type-private.hh" + +namespace OT { + + +/* + * hdmx - Horizontal Device Metric + */ + +#define HB_OT_TAG_hdmx HB_TAG('h','d','m','x') + +struct DeviceRecord +{ + struct SubsetView + { + const DeviceRecord *source_device_record; + hb_subset_plan_t *subset_plan; + + inline void init(const DeviceRecord *source_device_record, + hb_subset_plan_t *subset_plan) + { + this->source_device_record = source_device_record; + this->subset_plan = subset_plan; + } + + inline unsigned int len () const + { + return this->subset_plan->gids_to_retain_sorted.len; + } + + inline const HBUINT8& operator [] (unsigned int i) const + { + if (unlikely (i >= len())) return Null(HBUINT8); + hb_codepoint_t gid = this->subset_plan->gids_to_retain_sorted [i]; + return this->source_device_record->widths[gid]; + } + }; + + static inline unsigned int get_size (unsigned int count) + { + unsigned int raw_size = min_size + count * HBUINT8::static_size; + if (raw_size % 4) + /* Align to 32 bits */ + return raw_size + (4 - (raw_size % 4)); + return raw_size; + } + + inline bool serialize (hb_serialize_context_t *c, const SubsetView &subset_view) + { + TRACE_SERIALIZE (this); + + if (unlikely (!c->allocate_size<DeviceRecord> (get_size (subset_view.len())))) + return_trace (false); + + this->pixel_size.set (subset_view.source_device_record->pixel_size); + this->max_width.set (subset_view.source_device_record->max_width); + + for (unsigned int i = 0; i < subset_view.len(); i++) + widths[i].set (subset_view[i]); + + return_trace (true); + } + + inline bool sanitize (hb_sanitize_context_t *c, unsigned int size_device_record) const + { + TRACE_SANITIZE (this); + return_trace (likely (c->check_struct (this) && + c->check_range (this, size_device_record))); + } + + HBUINT8 pixel_size; /* Pixel size for following widths (as ppem). */ + HBUINT8 max_width; /* Maximum width. */ + HBUINT8 widths[VAR]; /* Array of widths (numGlyphs is from the 'maxp' table). */ + public: + DEFINE_SIZE_ARRAY (2, widths); +}; + + +struct hdmx +{ + static const hb_tag_t tableTag = HB_OT_TAG_hdmx; + + inline unsigned int get_size (void) const + { + return min_size + num_records * size_device_record; + } + + inline const DeviceRecord& operator [] (unsigned int i) const + { + if (unlikely (i >= num_records)) return Null(DeviceRecord); + return StructAtOffset<DeviceRecord> (this, min_size + i * size_device_record); + } + + inline bool serialize (hb_serialize_context_t *c, const hdmx *source_hdmx, hb_subset_plan_t *plan) + { + TRACE_SERIALIZE (this); + + if (unlikely (!c->extend_min ((*this)))) return_trace (false); + + this->version.set (source_hdmx->version); + this->num_records.set (source_hdmx->num_records); + this->size_device_record.set (DeviceRecord::get_size (plan->gids_to_retain_sorted.len)); + + for (unsigned int i = 0; i < source_hdmx->num_records; i++) + { + DeviceRecord::SubsetView subset_view; + subset_view.init (&(*source_hdmx)[i], plan); + + c->start_embed<DeviceRecord> ()->serialize (c, subset_view); + } + + return_trace (true); + } + + static inline size_t get_subsetted_size (hb_subset_plan_t *plan) + { + return min_size + DeviceRecord::get_size (plan->gids_to_retain_sorted.len); + } + + inline bool subset (hb_subset_plan_t *plan) const + { + size_t dest_size = get_subsetted_size (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); + 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 = hb_subset_plan_add_table (plan, HB_OT_TAG_hdmx, hdmx_prime_blob); + hb_blob_destroy (hdmx_prime_blob); + + return result; + } + + inline bool sanitize (hb_sanitize_context_t *c) const + { + TRACE_SANITIZE (this); + return_trace (c->check_struct (this) && version == 0 && + !_hb_unsigned_int_mul_overflows (num_records, size_device_record) && + c->check_range (this, get_size())); + } + + protected: + HBUINT16 version; /* Table version number (0) */ + HBUINT16 num_records; /* Number of device records. */ + HBUINT32 size_device_record; /* Size of a device record, 32-bit aligned. */ + HBUINT8 data[VAR]; /* Array of device records. */ + public: + DEFINE_SIZE_ARRAY (8, data); +}; + +} /* namespace OT */ + + +#endif /* HB_OT_HDMX_TABLE_HH */ diff --git a/chromium/third_party/harfbuzz-ng/src/hb-ot-head-table.hh b/chromium/third_party/harfbuzz-ng/src/src/hb-ot-head-table.hh index 2024cea7e78..1d458404517 100644 --- a/chromium/third_party/harfbuzz-ng/src/hb-ot-head-table.hh +++ b/chromium/third_party/harfbuzz-ng/src/src/hb-ot-head-table.hh @@ -43,6 +43,8 @@ namespace OT { struct head { + friend struct OffsetTable; + static const hb_tag_t tableTag = HB_OT_TAG_head; inline unsigned int get_upem (void) const diff --git a/chromium/third_party/harfbuzz-ng/src/hb-ot-hhea-table.hh b/chromium/third_party/harfbuzz-ng/src/src/hb-ot-hhea-table.hh index 97952b4ebbb..97952b4ebbb 100644 --- a/chromium/third_party/harfbuzz-ng/src/hb-ot-hhea-table.hh +++ b/chromium/third_party/harfbuzz-ng/src/src/hb-ot-hhea-table.hh diff --git a/chromium/third_party/harfbuzz-ng/src/hb-ot-hmtx-table.hh b/chromium/third_party/harfbuzz-ng/src/src/hb-ot-hmtx-table.hh index 11cc92794a1..bff792a6013 100644 --- a/chromium/third_party/harfbuzz-ng/src/hb-ot-hmtx-table.hh +++ b/chromium/third_party/harfbuzz-ng/src/src/hb-ot-hmtx-table.hh @@ -105,7 +105,7 @@ struct hmtxvmtx /* alloc the new table */ size_t dest_sz = num_advances * 4 + (gids.len - num_advances) * 2; - void *dest = (void *) calloc (dest_sz, 1); + void *dest = (void *) malloc (dest_sz); if (unlikely (!dest)) { return false; @@ -166,9 +166,11 @@ struct hmtxvmtx hb_blob_t *result = hb_blob_create ((const char *)dest, dest_sz, HB_MEMORY_MODE_READONLY, - /* userdata */ nullptr, + dest, free); - return hb_subset_plan_add_table (plan, T::tableTag, result); + bool success = hb_subset_plan_add_table (plan, T::tableTag, result); + hb_blob_destroy (result); + return success; } struct accelerator_t @@ -262,7 +264,7 @@ struct hmtxvmtx { advance += (font->num_coords ? var_table->get_advance_var (glyph, font->coords, font->num_coords) : 0); // TODO Optimize?! } - return advance; + return advance; } public: diff --git a/chromium/third_party/harfbuzz-ng/src/hb-ot-kern-table.hh b/chromium/third_party/harfbuzz-ng/src/src/hb-ot-kern-table.hh index 368f547a693..368f547a693 100644 --- a/chromium/third_party/harfbuzz-ng/src/hb-ot-kern-table.hh +++ b/chromium/third_party/harfbuzz-ng/src/src/hb-ot-kern-table.hh diff --git a/chromium/third_party/harfbuzz-ng/src/src/hb-ot-layout-base-table.hh b/chromium/third_party/harfbuzz-ng/src/src/hb-ot-layout-base-table.hh new file mode 100644 index 00000000000..20b8bd76223 --- /dev/null +++ b/chromium/third_party/harfbuzz-ng/src/src/hb-ot-layout-base-table.hh @@ -0,0 +1,655 @@ +/* + * Copyright © 2016 Elie Roux <elie.roux@telecom-bretagne.eu> + * 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_OT_LAYOUT_BASE_TABLE_HH +#define HB_OT_LAYOUT_BASE_TABLE_HH + +#include "hb-open-type-private.hh" +#include "hb-ot-layout-common-private.hh" + +namespace OT { + +#define NOT_INDEXED ((unsigned int) -1) + +/* + * BASE -- The BASE Table + */ + +struct BaseCoordFormat1 +{ + inline int get_coord (void) const { return coordinate; } + + inline bool sanitize (hb_sanitize_context_t *c) const + { + TRACE_SANITIZE (this); + return_trace (c->check_struct (this)); + } + + protected: + HBUINT16 format; /* Format identifier--format = 1 */ + HBINT16 coordinate; /* X or Y value, in design units */ + public: + DEFINE_SIZE_STATIC (4); +}; + +struct BaseCoordFormat2 +{ + inline int get_coord (void) const + { + /* TODO */ + return coordinate; + } + + inline bool sanitize (hb_sanitize_context_t *c) const + { + TRACE_SANITIZE (this); + return_trace (c->check_struct (this)); + } + + protected: + HBUINT16 format; /* Format identifier--format = 2 */ + HBINT16 coordinate; /* X or Y value, in design units */ + GlyphID referenceGlyph; /* Glyph ID of control glyph */ + HBUINT16 coordPoint; /* Index of contour point on the + * reference glyph */ + public: + DEFINE_SIZE_STATIC (8); +}; + +struct BaseCoordFormat3 +{ + inline int get_coord (void) const + { + /* TODO */ + return coordinate; + } + + inline bool sanitize (hb_sanitize_context_t *c) const + { + TRACE_SANITIZE (this); + return_trace (c->check_struct (this) && deviceTable.sanitize (c, this)); + } + + protected: + HBUINT16 format; /* Format identifier--format = 3 */ + HBINT16 coordinate; /* X or Y value, in design units */ + OffsetTo<Device> deviceTable; /* Offset to Device table for X or + * Y value, from beginning of + * BaseCoord table (may be NULL). */ + public: + DEFINE_SIZE_STATIC (6); +}; + +struct BaseCoord +{ + inline int get_coord (void) const + { + switch (u.format) { + case 1: return u.format1.get_coord (); + case 2: return u.format2.get_coord (); + case 3: return u.format3.get_coord (); + default:return 0; + } + } + + inline bool sanitize (hb_sanitize_context_t *c) const + { + TRACE_SANITIZE (this); + if (!u.format.sanitize (c)) return_trace (false); + switch (u.format) { + case 1: return_trace (u.format1.sanitize (c)); + case 2: return_trace (u.format2.sanitize (c)); + case 3: return_trace (u.format3.sanitize (c)); + default:return_trace (false); + } + } + + protected: + union { + HBUINT16 format; + BaseCoordFormat1 format1; + BaseCoordFormat2 format2; + BaseCoordFormat3 format3; + } u; + public: + DEFINE_SIZE_UNION (2, format); +}; + +struct FeatMinMaxRecord +{ + inline int get_min_value (void) const + { return (this+minCoord).get_coord(); } + + inline int get_max_value (void) const + { return (this+maxCoord).get_coord(); } + + inline const Tag &get_tag () const + { return tag; } + + inline bool sanitize (hb_sanitize_context_t *c, const void *base) const + { + TRACE_SANITIZE (this); + return_trace (c->check_struct (this) && + minCoord.sanitize (c, base) && + maxCoord.sanitize (c, base)); + } + + protected: + Tag tag; /* 4-byte feature identification tag--must + * match feature tag in FeatureList */ + OffsetTo<BaseCoord> minCoord; /* Offset to BaseCoord table that defines + * the minimum extent value, from beginning + * of MinMax table (may be NULL) */ + OffsetTo<BaseCoord> maxCoord; /* Offset to BaseCoord table that defines + * the maximum extent value, from beginning + * of MinMax table (may be NULL) */ + public: + DEFINE_SIZE_STATIC (8); + +}; + +struct MinMax +{ + inline unsigned int get_feature_tag_index (Tag featureTableTag) const + { + /* TODO bsearch */ + unsigned int count = featMinMaxRecords.len; + for (unsigned int i = 0; i < count; i++) + { + Tag tag = featMinMaxRecords[i].get_tag(); + int cmp = tag.cmp(featureTableTag); + if (cmp == 0) return i; + if (cmp > 0) return NOT_INDEXED; + } + return NOT_INDEXED; + } + + inline int get_min_value (unsigned int featureTableTagIndex) const + { + if (featureTableTagIndex == NOT_INDEXED) + return (this+minCoord).get_coord(); + return featMinMaxRecords[featureTableTagIndex].get_min_value(); + } + + inline int get_max_value (unsigned int featureTableTagIndex) const + { + if (featureTableTagIndex == NOT_INDEXED) + return (this+maxCoord).get_coord(); + return featMinMaxRecords[featureTableTagIndex].get_max_value(); + } + + inline bool sanitize (hb_sanitize_context_t *c) const + { + TRACE_SANITIZE (this); + return_trace (c->check_struct (this) && + minCoord.sanitize (c, this) && + maxCoord.sanitize (c, this) && + featMinMaxRecords.sanitize (c, this)); + } + + protected: + OffsetTo<BaseCoord> minCoord; /* Offset to BaseCoord table that defines + * minimum extent value, from the beginning + * of MinMax table (may be NULL) */ + OffsetTo<BaseCoord> maxCoord; /* Offset to BaseCoord table that defines + * maximum extent value, from the beginning + * of MinMax table (may be NULL) */ + ArrayOf<FeatMinMaxRecord> + featMinMaxRecords; /* Array of FeatMinMaxRecords, in alphabetical + * order by featureTableTag */ + public: + DEFINE_SIZE_ARRAY (6, featMinMaxRecords); +}; + +/* TODO... */ +struct BaseLangSysRecord +{ + inline const Tag& get_tag(void) const + { return baseLangSysTag; } + + inline unsigned int get_feature_tag_index (Tag featureTableTag) const + { return (this+minMax).get_feature_tag_index(featureTableTag); } + + inline int get_min_value (unsigned int featureTableTagIndex) const + { return (this+minMax).get_min_value(featureTableTagIndex); } + + inline int get_max_value (unsigned int featureTableTagIndex) const + { return (this+minMax).get_max_value(featureTableTagIndex); } + + inline bool sanitize (hb_sanitize_context_t *c, const void *base) const + { + TRACE_SANITIZE (this); + return_trace (c->check_struct (this) && + minMax.sanitize (c, base)); + } + + protected: + Tag baseLangSysTag; + OffsetTo<MinMax> minMax; + public: + DEFINE_SIZE_STATIC (6); + +}; + +struct BaseValues +{ + inline unsigned int get_default_base_tag_index (void) const + { return defaultIndex; } + + inline int get_base_coord (unsigned int baselineTagIndex) const + { + return (this+baseCoords[baselineTagIndex]).get_coord(); + } + + inline bool sanitize (hb_sanitize_context_t *c) const + { + TRACE_SANITIZE (this); + return_trace (c->check_struct (this) && + defaultIndex <= baseCoordCount && + baseCoords.sanitize (c, this)); + } + + protected: + Index defaultIndex; + HBUINT16 baseCoordCount; + OffsetArrayOf<BaseCoord> baseCoords; + public: + DEFINE_SIZE_ARRAY (6, baseCoords); + +}; + +struct BaseScript { + + inline unsigned int get_lang_tag_index (Tag baseLangSysTag) const + { + Tag tag; + int cmp; + for (unsigned int i = 0; i < baseLangSysCount; i++) { + tag = baseLangSysRecords[i].get_tag(); + // taking advantage of alphabetical order + cmp = tag.cmp(baseLangSysTag); + if (cmp == 0) return i; + if (cmp > 0) return NOT_INDEXED; + } + return NOT_INDEXED; + } + + inline unsigned int get_feature_tag_index (unsigned int baseLangSysIndex, Tag featureTableTag) const + { + if (baseLangSysIndex == NOT_INDEXED) { + if (unlikely(defaultMinMax)) return NOT_INDEXED; + return (this+defaultMinMax).get_feature_tag_index(featureTableTag); + } + if (unlikely(baseLangSysIndex >= baseLangSysCount)) return NOT_INDEXED; + return baseLangSysRecords[baseLangSysIndex].get_feature_tag_index(featureTableTag); + } + + inline int get_min_value (unsigned int baseLangSysIndex, unsigned int featureTableTagIndex) const + { + if (baseLangSysIndex == NOT_INDEXED) + return (this+defaultMinMax).get_min_value(featureTableTagIndex); + return baseLangSysRecords[baseLangSysIndex].get_max_value(featureTableTagIndex); + } + + inline int get_max_value (unsigned int baseLangSysIndex, unsigned int featureTableTagIndex) const + { + if (baseLangSysIndex == NOT_INDEXED) + return (this+defaultMinMax).get_min_value(featureTableTagIndex); + return baseLangSysRecords[baseLangSysIndex].get_max_value(featureTableTagIndex); + } + + inline unsigned int get_default_base_tag_index (void) const + { return (this+baseValues).get_default_base_tag_index(); } + + inline int get_base_coord (unsigned int baselineTagIndex) const + { return (this+baseValues).get_base_coord(baselineTagIndex); } + + inline bool sanitize (hb_sanitize_context_t *c) const + { + TRACE_SANITIZE (this); + return_trace (c->check_struct (this) && + baseValues.sanitize (c, this) && + defaultMinMax.sanitize (c, this) && + baseLangSysRecords.sanitize (c, this)); + } + + protected: + OffsetTo<BaseValues> baseValues; + OffsetTo<MinMax> defaultMinMax; + HBUINT16 baseLangSysCount; + ArrayOf<BaseLangSysRecord> baseLangSysRecords; + + public: + DEFINE_SIZE_ARRAY (8, baseLangSysRecords); +}; + + +struct BaseScriptRecord { + + inline const Tag& get_tag (void) const + { return baseScriptTag; } + + inline unsigned int get_default_base_tag_index(void) const + { return (this+baseScript).get_default_base_tag_index(); } + + inline int get_base_coord(unsigned int baselineTagIndex) const + { return (this+baseScript).get_base_coord(baselineTagIndex); } + + inline unsigned int get_lang_tag_index (Tag baseLangSysTag) const + { return (this+baseScript).get_lang_tag_index(baseLangSysTag); } + + inline unsigned int get_feature_tag_index (unsigned int baseLangSysIndex, Tag featureTableTag) const + { return (this+baseScript).get_feature_tag_index(baseLangSysIndex, featureTableTag); } + + inline int get_max_value (unsigned int baseLangSysIndex, unsigned int featureTableTagIndex) const + { return (this+baseScript).get_max_value(baseLangSysIndex, featureTableTagIndex); } + + inline int get_min_value (unsigned int baseLangSysIndex, unsigned int featureTableTagIndex) const + { return (this+baseScript).get_min_value(baseLangSysIndex, featureTableTagIndex); } + + inline bool sanitize (hb_sanitize_context_t *c, const void *base) const + { + TRACE_SANITIZE (this); + return_trace (c->check_struct (this) && + baseScript != Null(OffsetTo<BaseScript>) && + baseScript.sanitize (c, base)); + } + + protected: + Tag baseScriptTag; + OffsetTo<BaseScript> baseScript; + + public: + DEFINE_SIZE_STATIC (6); +}; + +struct BaseScriptList { + + inline unsigned int get_base_script_index (Tag baseScriptTag) const + { + for (unsigned int i = 0; i < baseScriptCount; i++) + if (baseScriptRecords[i].get_tag() == baseScriptTag) + return i; + return NOT_INDEXED; + } + + inline unsigned int get_default_base_tag_index (unsigned int baseScriptIndex) const + { + if (unlikely(baseScriptIndex >= baseScriptCount)) return NOT_INDEXED; + return baseScriptRecords[baseScriptIndex].get_default_base_tag_index(); + } + + inline int get_base_coord(unsigned int baseScriptIndex, unsigned int baselineTagIndex) const + { + return baseScriptRecords[baseScriptIndex].get_base_coord(baselineTagIndex); + } + + inline unsigned int get_lang_tag_index (unsigned int baseScriptIndex, Tag baseLangSysTag) const + { + if (unlikely(baseScriptIndex >= baseScriptCount)) return NOT_INDEXED; + return baseScriptRecords[baseScriptIndex].get_lang_tag_index(baseLangSysTag); + } + + inline unsigned int get_feature_tag_index (unsigned int baseScriptIndex, unsigned int baseLangSysIndex, Tag featureTableTag) const + { + if (unlikely(baseScriptIndex >= baseScriptCount)) return NOT_INDEXED; + return baseScriptRecords[baseScriptIndex].get_feature_tag_index(baseLangSysIndex, featureTableTag); + } + + inline int get_max_value (unsigned int baseScriptIndex, unsigned int baseLangSysIndex, unsigned int featureTableTagIndex) const + { + return baseScriptRecords[baseScriptIndex].get_max_value(baseLangSysIndex, featureTableTagIndex); + } + + inline int get_min_value (unsigned int baseScriptIndex, unsigned int baseLangSysIndex, unsigned int featureTableTagIndex) const + { + return baseScriptRecords[baseScriptIndex].get_min_value(baseLangSysIndex, featureTableTagIndex); + } + + inline bool sanitize (hb_sanitize_context_t *c) const + { + TRACE_SANITIZE (this); + return_trace (c->check_struct (this) && + baseScriptRecords.sanitize (c, this)); + } + + protected: + HBUINT16 baseScriptCount; + ArrayOf<BaseScriptRecord> baseScriptRecords; + + public: + DEFINE_SIZE_ARRAY (4, baseScriptRecords); + +}; + +struct BaseTagList +{ + + inline unsigned int get_tag_index(Tag baselineTag) const + { + for (unsigned int i = 0; i < baseTagCount; i++) + if (baselineTags[i] == baselineTag) + return i; + return NOT_INDEXED; + } + + inline bool sanitize (hb_sanitize_context_t *c) const + { + TRACE_SANITIZE (this); + return_trace (c->check_struct (this)); + } + + protected: + HBUINT16 baseTagCount; + SortedArrayOf<Tag> baselineTags; + + public: + DEFINE_SIZE_ARRAY (4, baselineTags); +}; + +struct Axis +{ + + inline unsigned int get_base_tag_index(Tag baselineTag) const + { + if (unlikely(baseTagList == Null(OffsetTo<BaseTagList>))) return NOT_INDEXED; + return (this+baseTagList).get_tag_index(baselineTag); + } + + inline unsigned int get_default_base_tag_index_for_script_index (unsigned int baseScriptIndex) const + { + if (unlikely(baseScriptList == Null(OffsetTo<BaseScriptList>))) return NOT_INDEXED; + return (this+baseScriptList).get_default_base_tag_index(baseScriptIndex); + } + + inline int get_base_coord(unsigned int baseScriptIndex, unsigned int baselineTagIndex) const + { + return (this+baseScriptList).get_base_coord(baseScriptIndex, baselineTagIndex); + } + + inline unsigned int get_lang_tag_index (unsigned int baseScriptIndex, Tag baseLangSysTag) const + { + if (unlikely(baseScriptList == Null(OffsetTo<BaseScriptList>))) return NOT_INDEXED; + return (this+baseScriptList).get_lang_tag_index(baseScriptIndex, baseLangSysTag); + } + + inline unsigned int get_feature_tag_index (unsigned int baseScriptIndex, unsigned int baseLangSysIndex, Tag featureTableTag) const + { + if (unlikely(baseScriptList == Null(OffsetTo<BaseScriptList>))) return NOT_INDEXED; + return (this+baseScriptList).get_feature_tag_index(baseScriptIndex, baseLangSysIndex, featureTableTag); + } + + inline int get_max_value (unsigned int baseScriptIndex, unsigned int baseLangSysIndex, unsigned int featureTableTagIndex) const + { + return (this+baseScriptList).get_max_value(baseScriptIndex, baseLangSysIndex, featureTableTagIndex); + } + + inline int get_min_value (unsigned int baseScriptIndex, unsigned int baseLangSysIndex, unsigned int featureTableTagIndex) const + { + return (this+baseScriptList).get_min_value(baseScriptIndex, baseLangSysIndex, featureTableTagIndex); + } + + inline bool sanitize (hb_sanitize_context_t *c) const + { + TRACE_SANITIZE (this); + return_trace (c->check_struct (this) && + baseTagList.sanitize (c, this) && + baseScriptList.sanitize (c, this)); + } + + protected: + OffsetTo<BaseTagList> baseTagList; + OffsetTo<BaseScriptList> baseScriptList; + + public: + DEFINE_SIZE_STATIC (4); +}; + +struct BASE +{ + static const hb_tag_t tableTag = HB_OT_TAG_BASE; + + inline bool has_vert_axis(void) + { return vertAxis != Null(OffsetTo<Axis>); } + + inline bool has_horiz_axis(void) + { return horizAxis != Null(OffsetTo<Axis>); } + + // horizontal axis base coords: + + inline unsigned int get_horiz_base_tag_index(Tag baselineTag) const + { + if (unlikely(horizAxis == Null(OffsetTo<Axis>))) return NOT_INDEXED; + return (this+horizAxis).get_base_tag_index(baselineTag); + } + + inline unsigned int get_horiz_default_base_tag_index_for_script_index (unsigned int baseScriptIndex) const + { + if (unlikely(horizAxis == Null(OffsetTo<Axis>))) return NOT_INDEXED; + return (this+horizAxis).get_default_base_tag_index_for_script_index(baseScriptIndex); + } + + inline int get_horiz_base_coord(unsigned int baseScriptIndex, unsigned int baselineTagIndex) const + { + return (this+horizAxis).get_base_coord(baseScriptIndex, baselineTagIndex); + } + + // vertical axis base coords: + + inline unsigned int get_vert_base_tag_index(Tag baselineTag) const + { + if (unlikely(vertAxis == Null(OffsetTo<Axis>))) return NOT_INDEXED; + return (this+vertAxis).get_base_tag_index(baselineTag); + } + + inline unsigned int get_vert_default_base_tag_index_for_script_index (unsigned int baseScriptIndex) const + { + if (unlikely(vertAxis == Null(OffsetTo<Axis>))) return NOT_INDEXED; + return (this+vertAxis).get_default_base_tag_index_for_script_index(baseScriptIndex); + } + + inline int get_vert_base_coord(unsigned int baseScriptIndex, unsigned int baselineTagIndex) const + { + return (this+vertAxis).get_base_coord(baseScriptIndex, baselineTagIndex); + } + + // horizontal axis min/max coords: + + inline unsigned int get_horiz_lang_tag_index (unsigned int baseScriptIndex, Tag baseLangSysTag) const + { + if (unlikely(horizAxis == Null(OffsetTo<Axis>))) return NOT_INDEXED; + return (this+horizAxis).get_lang_tag_index (baseScriptIndex, baseLangSysTag); + } + + inline unsigned int get_horiz_feature_tag_index (unsigned int baseScriptIndex, unsigned int baseLangSysIndex, Tag featureTableTag) const + { + if (unlikely(horizAxis == Null(OffsetTo<Axis>))) return NOT_INDEXED; + return (this+horizAxis).get_feature_tag_index (baseScriptIndex, baseLangSysIndex, featureTableTag); + } + + inline int get_horiz_max_value (unsigned int baseScriptIndex, unsigned int baseLangSysIndex, unsigned int featureTableTagIndex) const + { + return (this+horizAxis).get_max_value (baseScriptIndex, baseLangSysIndex, featureTableTagIndex); + } + + inline int get_horiz_min_value (unsigned int baseScriptIndex, unsigned int baseLangSysIndex, unsigned int featureTableTagIndex) const + { + return (this+horizAxis).get_min_value (baseScriptIndex, baseLangSysIndex, featureTableTagIndex); + } + + // vertical axis min/max coords: + + inline unsigned int get_vert_lang_tag_index (unsigned int baseScriptIndex, Tag baseLangSysTag) const + { + if (unlikely(vertAxis == Null(OffsetTo<Axis>))) return NOT_INDEXED; + return (this+vertAxis).get_lang_tag_index (baseScriptIndex, baseLangSysTag); + } + + inline unsigned int get_vert_feature_tag_index (unsigned int baseScriptIndex, unsigned int baseLangSysIndex, Tag featureTableTag) const + { + if (unlikely(vertAxis == Null(OffsetTo<Axis>))) return NOT_INDEXED; + return (this+vertAxis).get_feature_tag_index (baseScriptIndex, baseLangSysIndex, featureTableTag); + } + + inline int get_vert_max_value (unsigned int baseScriptIndex, unsigned int baseLangSysIndex, unsigned int featureTableTagIndex) const + { + return (this+vertAxis).get_max_value (baseScriptIndex, baseLangSysIndex, featureTableTagIndex); + } + + inline int get_vert_min_value (unsigned int baseScriptIndex, unsigned int baseLangSysIndex, unsigned int featureTableTagIndex) const + { + return (this+vertAxis).get_min_value (baseScriptIndex, baseLangSysIndex, featureTableTagIndex); + } + + inline bool sanitize (hb_sanitize_context_t *c) const + { + TRACE_SANITIZE (this); + return_trace (c->check_struct (this) && + likely (version.major == 1) && + horizAxis.sanitize (c, this) && + vertAxis.sanitize (c, this) && + (version.to_int () < 0x00010001u || varStore.sanitize (c, this))); + } + + protected: + FixedVersion<> version; + OffsetTo<Axis> horizAxis; + OffsetTo<Axis> vertAxis; + LOffsetTo<VariationStore> + varStore; /* Offset to the table of Item Variation + * Store--from beginning of BASE + * header (may be NULL). Introduced + * in version 0x00010001. */ + public: + DEFINE_SIZE_MIN (8); +}; + + +} /* namespace OT */ + + +#endif /* HB_OT_LAYOUT_BASE_TABLE_HH */ diff --git a/chromium/third_party/harfbuzz-ng/src/hb-ot-layout-common-private.hh b/chromium/third_party/harfbuzz-ng/src/src/hb-ot-layout-common-private.hh index cb66c81addb..e9240aaa723 100644 --- a/chromium/third_party/harfbuzz-ng/src/hb-ot-layout-common-private.hh +++ b/chromium/third_party/harfbuzz-ng/src/src/hb-ot-layout-common-private.hh @@ -398,7 +398,7 @@ struct FeatureParamsStylisticSet * added to the end of this Feature Parameters * table in the future. */ - HBUINT16 uiNameID; /* The 'name' table name ID that specifies a + NameID uiNameID; /* The 'name' table name ID that specifies a * string (or strings, for multiple languages) * for a user-interface label for this * feature. The values of uiLabelNameId and @@ -427,24 +427,24 @@ struct FeatureParamsCharacterVariants } HBUINT16 format; /* Format number is set to 0. */ - HBUINT16 featUILableNameID; /* The ‘name’ table name ID that + NameID featUILableNameID; /* The ‘name’ table name ID that * specifies a string (or strings, * for multiple languages) for a * user-interface label for this * feature. (May be nullptr.) */ - HBUINT16 featUITooltipTextNameID;/* The ‘name’ table name ID that + NameID featUITooltipTextNameID;/* The ‘name’ table name ID that * specifies a string (or strings, * for multiple languages) that an * application can use for tooltip * text for this feature. (May be * nullptr.) */ - HBUINT16 sampleTextNameID; /* The ‘name’ table name ID that + NameID sampleTextNameID; /* The ‘name’ table name ID that * specifies sample text that * illustrates the effect of this * feature. (May be nullptr.) */ HBUINT16 numNamedParameters; /* Number of named parameters. (May * be zero.) */ - HBUINT16 firstParamUILabelNameID;/* The first ‘name’ table name ID + NameID firstParamUILabelNameID;/* The first ‘name’ table name ID * used to specify strings for * user-interface labels for the * feature parameters. (Must be zero @@ -1057,7 +1057,7 @@ struct ClassDefFormat1 if (klass == 0) { /* Match if there's any glyph that is not listed! */ - hb_codepoint_t g = -1; + hb_codepoint_t g = HB_SET_VALUE_INVALID; if (!hb_set_next (glyphs, &g)) return false; if (g < startGlyph) @@ -1128,7 +1128,7 @@ struct ClassDefFormat2 if (klass == 0) { /* Match if there's any glyph that is not listed! */ - hb_codepoint_t g = (hb_codepoint_t) -1; + hb_codepoint_t g = HB_SET_VALUE_INVALID; for (unsigned int i = 0; i < count; i++) { if (!hb_set_next (glyphs, &g)) @@ -1137,7 +1137,7 @@ struct ClassDefFormat2 return true; g = rangeRecord[i].end; } - if (g != (hb_codepoint_t) -1 && hb_set_next (glyphs, &g)) + if (g != HB_SET_VALUE_INVALID && hb_set_next (glyphs, &g)) return true; /* Fall through. */ } diff --git a/chromium/third_party/harfbuzz-ng/src/hb-ot-layout-gdef-table.hh b/chromium/third_party/harfbuzz-ng/src/src/hb-ot-layout-gdef-table.hh index aad7d60290d..2d6c66e6c99 100644 --- a/chromium/third_party/harfbuzz-ng/src/hb-ot-layout-gdef-table.hh +++ b/chromium/third_party/harfbuzz-ng/src/src/hb-ot-layout-gdef-table.hh @@ -110,7 +110,7 @@ struct CaretValueFormat1 protected: HBUINT16 caretValueFormat; /* Format identifier--format = 1 */ - HBINT16 coordinate; /* X or Y value, in design units */ + FWORD coordinate; /* X or Y value, in design units */ public: DEFINE_SIZE_STATIC (4); }; @@ -161,7 +161,7 @@ struct CaretValueFormat3 protected: HBUINT16 caretValueFormat; /* Format identifier--format = 3 */ - HBINT16 coordinate; /* X or Y value, in design units */ + FWORD coordinate; /* X or Y value, in design units */ OffsetTo<Device> deviceTable; /* Offset to Device table for X or Y * value--from beginning of CaretValue diff --git a/chromium/third_party/harfbuzz-ng/src/hb-ot-layout-gpos-table.hh b/chromium/third_party/harfbuzz-ng/src/src/hb-ot-layout-gpos-table.hh index 4e1a10d7774..46ffcc66883 100644 --- a/chromium/third_party/harfbuzz-ng/src/hb-ot-layout-gpos-table.hh +++ b/chromium/third_party/harfbuzz-ng/src/src/hb-ot-layout-gpos-table.hh @@ -248,8 +248,8 @@ struct AnchorFormat1 protected: HBUINT16 format; /* Format identifier--format = 1 */ - HBINT16 xCoordinate; /* Horizontal value--in design units */ - HBINT16 yCoordinate; /* Vertical value--in design units */ + FWORD xCoordinate; /* Horizontal value--in design units */ + FWORD yCoordinate; /* Vertical value--in design units */ public: DEFINE_SIZE_STATIC (6); }; @@ -279,8 +279,8 @@ struct AnchorFormat2 protected: HBUINT16 format; /* Format identifier--format = 2 */ - HBINT16 xCoordinate; /* Horizontal value--in design units */ - HBINT16 yCoordinate; /* Vertical value--in design units */ + FWORD xCoordinate; /* Horizontal value--in design units */ + FWORD yCoordinate; /* Vertical value--in design units */ HBUINT16 anchorPoint; /* Index to glyph contour point */ public: DEFINE_SIZE_STATIC (8); @@ -309,8 +309,8 @@ struct AnchorFormat3 protected: HBUINT16 format; /* Format identifier--format = 3 */ - HBINT16 xCoordinate; /* Horizontal value--in design units */ - HBINT16 yCoordinate; /* Vertical value--in design units */ + FWORD xCoordinate; /* Horizontal value--in design units */ + FWORD yCoordinate; /* Vertical value--in design units */ OffsetTo<Device> xDeviceTable; /* Offset to Device table for X * coordinate-- from beginning of diff --git a/chromium/third_party/harfbuzz-ng/src/hb-ot-layout-gsub-table.hh b/chromium/third_party/harfbuzz-ng/src/src/hb-ot-layout-gsub-table.hh index 97f1d21a5be..5f67aed21ed 100644 --- a/chromium/third_party/harfbuzz-ng/src/hb-ot-layout-gsub-table.hh +++ b/chromium/third_party/harfbuzz-ng/src/src/hb-ot-layout-gsub-table.hh @@ -114,7 +114,7 @@ struct SingleSubstFormat1 OffsetTo<Coverage> coverage; /* Offset to Coverage table--from * beginning of Substitution table */ - HBINT16 deltaGlyphID; /* Add to original GlyphID to get + HBINT16 deltaGlyphID; /* Add to original GlyphID to get * substitute GlyphID */ public: DEFINE_SIZE_STATIC (6); diff --git a/chromium/third_party/harfbuzz-ng/src/hb-ot-layout-gsubgpos-private.hh b/chromium/third_party/harfbuzz-ng/src/src/hb-ot-layout-gsubgpos-private.hh index 90546344d69..90546344d69 100644 --- a/chromium/third_party/harfbuzz-ng/src/hb-ot-layout-gsubgpos-private.hh +++ b/chromium/third_party/harfbuzz-ng/src/src/hb-ot-layout-gsubgpos-private.hh diff --git a/chromium/third_party/harfbuzz-ng/src/hb-ot-layout-jstf-table.hh b/chromium/third_party/harfbuzz-ng/src/src/hb-ot-layout-jstf-table.hh index adbaad64f39..adbaad64f39 100644 --- a/chromium/third_party/harfbuzz-ng/src/hb-ot-layout-jstf-table.hh +++ b/chromium/third_party/harfbuzz-ng/src/src/hb-ot-layout-jstf-table.hh diff --git a/chromium/third_party/harfbuzz-ng/src/hb-ot-layout-private.hh b/chromium/third_party/harfbuzz-ng/src/src/hb-ot-layout-private.hh index cf691d37051..870ba73fa88 100644 --- a/chromium/third_party/harfbuzz-ng/src/hb-ot-layout-private.hh +++ b/chromium/third_party/harfbuzz-ng/src/src/hb-ot-layout-private.hh @@ -122,6 +122,9 @@ hb_ot_layout_position_finish_offsets (hb_font_t *font, */ namespace OT { + struct BASE; + struct COLR; + struct CPAL; struct GDEF; struct GSUB; struct GPOS; @@ -131,8 +134,10 @@ namespace OT { } namespace AAT { + struct ankr; struct kerx; struct morx; + struct trak; } struct hb_ot_layout_lookup_accelerator_t @@ -167,11 +172,16 @@ struct hb_ot_layout_t const struct OT::GPOS *gpos; /* TODO Move the following out of this struct. */ + OT::hb_lazy_table_loader_t<struct OT::BASE> base; + OT::hb_lazy_table_loader_t<struct OT::COLR> colr; + OT::hb_lazy_table_loader_t<struct OT::CPAL> cpal; OT::hb_lazy_table_loader_t<struct OT::MATH> math; OT::hb_lazy_table_loader_t<struct OT::fvar> fvar; OT::hb_lazy_table_loader_t<struct OT::avar> avar; + OT::hb_lazy_table_loader_t<struct AAT::ankr> ankr; OT::hb_lazy_table_loader_t<struct AAT::kerx> kerx; OT::hb_lazy_table_loader_t<struct AAT::morx> morx; + OT::hb_lazy_table_loader_t<struct AAT::trak> trak; unsigned int gsub_lookup_count; unsigned int gpos_lookup_count; @@ -361,6 +371,28 @@ _hb_glyph_info_get_modified_combining_class (const hb_glyph_info_t *info) return _hb_glyph_info_is_unicode_mark (info) ? info->unicode_props()>>8 : 0; } + +/* Loop over grapheme. Based on foreach_cluster(). */ +#define foreach_grapheme(buffer, start, end) \ + for (unsigned int \ + _count = buffer->len, \ + start = 0, end = _count ? _next_grapheme (buffer, 0) : 0; \ + start < _count; \ + start = end, end = _next_grapheme (buffer, start)) + +static inline unsigned int +_next_grapheme (hb_buffer_t *buffer, unsigned int start) +{ + hb_glyph_info_t *info = buffer->info; + unsigned int count = buffer->len; + + while (++start < count && _hb_glyph_info_is_unicode_mark (&info[start])) + ; + + return start; +} + + #define info_cc(info) (_hb_glyph_info_get_modified_combining_class (&(info))) static inline bool diff --git a/chromium/third_party/harfbuzz-ng/src/hb-ot-layout.cc b/chromium/third_party/harfbuzz-ng/src/src/hb-ot-layout.cc index 4cf6c722c7e..9e6f858c248 100644 --- a/chromium/third_party/harfbuzz-ng/src/hb-ot-layout.cc +++ b/chromium/third_party/harfbuzz-ng/src/src/hb-ot-layout.cc @@ -31,11 +31,16 @@ #include "hb-open-type-private.hh" #include "hb-ot-layout-private.hh" +#include "hb-ot-layout-base-table.hh" #include "hb-ot-layout-gdef-table.hh" #include "hb-ot-layout-gsub-table.hh" #include "hb-ot-layout-gpos-table.hh" #include "hb-ot-layout-jstf-table.hh" // Just so we compile it; unused otherwise. #include "hb-ot-name-table.hh" // Just so we compile it; unused otherwise. +#include "hb-ot-color-colr-table.hh" +#include "hb-ot-color-cpal-table.hh" +#include "hb-ot-color-sbix-table.hh" // Just so we compile it; unused otherwise. +#include "hb-ot-color-svg-table.hh" // Just so we compile it; unused otherwise. #include "hb-ot-map-private.hh" @@ -61,10 +66,16 @@ _hb_ot_layout_create (hb_face_t *face) layout->gpos_blob = OT::Sanitizer<OT::GPOS>().sanitize (face->reference_table (HB_OT_TAG_GPOS)); layout->gpos = OT::Sanitizer<OT::GPOS>::lock_instance (layout->gpos_blob); + layout->base.init (face); + layout->colr.init (face); + layout->cpal.init (face); layout->math.init (face); layout->fvar.init (face); layout->avar.init (face); + layout->ankr.init (face); + layout->kerx.init (face); layout->morx.init (face); + layout->trak.init (face); { /* @@ -211,14 +222,28 @@ _hb_ot_layout_destroy (hb_ot_layout_t *layout) hb_blob_destroy (layout->gsub_blob); hb_blob_destroy (layout->gpos_blob); + layout->base.fini (); + layout->colr.fini (); + layout->cpal.fini (); layout->math.fini (); layout->fvar.fini (); layout->avar.fini (); + layout->ankr.fini (); + layout->kerx.fini (); layout->morx.fini (); + layout->trak.fini (); free (layout); } +// static inline const OT::BASE& +// _get_base (hb_face_t *face) +// { +// if (unlikely (!hb_ot_shaper_face_data_ensure (face))) return OT::Null(OT::BASE); +// hb_ot_layout_t * layout = hb_ot_layout_from_face (face); +// return *(layout->base.get ()); +// } + static inline const OT::GDEF& _get_gdef (hb_face_t *face) { @@ -1264,3 +1289,27 @@ hb_ot_layout_substitute_lookup (OT::hb_ot_apply_context_t *c, { apply_string<GSUBProxy> (c, lookup, accel); } + + + + +/* + * OT::BASE + */ + +// /** +// * hb_ot_base_has_data: +// * @face: #hb_face_t to test +// * +// * This function allows to verify the presence of an OpenType BASE table on the +// * face. +// * +// * Return value: true if face has a BASE table, false otherwise +// * +// * Since: XXX +// **/ +// hb_bool_t +// hb_ot_base_has_data (hb_face_t *face) +// { +// return &_get_base (face) != &OT::Null(OT::BASE); +// } diff --git a/chromium/third_party/harfbuzz-ng/src/hb-ot-layout.h b/chromium/third_party/harfbuzz-ng/src/src/hb-ot-layout.h index 9861f0fc7bb..85938ba123e 100644 --- a/chromium/third_party/harfbuzz-ng/src/hb-ot-layout.h +++ b/chromium/third_party/harfbuzz-ng/src/src/hb-ot-layout.h @@ -38,6 +38,7 @@ HB_BEGIN_DECLS +#define HB_OT_TAG_BASE HB_TAG('B','A','S','E') #define HB_OT_TAG_GDEF HB_TAG('G','D','E','F') #define HB_OT_TAG_GSUB HB_TAG('G','S','U','B') #define HB_OT_TAG_GPOS HB_TAG('G','P','O','S') @@ -316,6 +317,22 @@ hb_ot_layout_get_size_params (hb_face_t *face, unsigned int *range_end /* OUT. May be NULL */); +/* + * BASE + */ +#if 0 + +#define HB_OT_TAG_BASE_HANG HB_TAG('h','a','n','g') +#define HB_OT_TAG_BASE_ICFB HB_TAG('i','c','f','b') +#define HB_OT_TAG_BASE_ICFT HB_TAG('i','c','f','t') +#define HB_OT_TAG_BASE_IDEO HB_TAG('i','d','e','o') +#define HB_OT_TAG_BASE_IDTB HB_TAG('i','d','t','b') +#define HB_OT_TAG_BASE_MATH HB_TAG('m','a','t','h') +#define HB_OT_TAG_BASE_ROMN HB_TAG('r','o','m','n') + +#endif + + HB_END_DECLS #endif /* HB_OT_LAYOUT_H */ diff --git a/chromium/third_party/harfbuzz-ng/src/hb-ot-map-private.hh b/chromium/third_party/harfbuzz-ng/src/src/hb-ot-map-private.hh index e6bd8ea5ef3..e6bd8ea5ef3 100644 --- a/chromium/third_party/harfbuzz-ng/src/hb-ot-map-private.hh +++ b/chromium/third_party/harfbuzz-ng/src/src/hb-ot-map-private.hh diff --git a/chromium/third_party/harfbuzz-ng/src/hb-ot-map.cc b/chromium/third_party/harfbuzz-ng/src/src/hb-ot-map.cc index 54b0ce377d7..54b0ce377d7 100644 --- a/chromium/third_party/harfbuzz-ng/src/hb-ot-map.cc +++ b/chromium/third_party/harfbuzz-ng/src/src/hb-ot-map.cc diff --git a/chromium/third_party/harfbuzz-ng/src/hb-ot-math-table.hh b/chromium/third_party/harfbuzz-ng/src/src/hb-ot-math-table.hh index 571ce01b71e..571ce01b71e 100644 --- a/chromium/third_party/harfbuzz-ng/src/hb-ot-math-table.hh +++ b/chromium/third_party/harfbuzz-ng/src/src/hb-ot-math-table.hh diff --git a/chromium/third_party/harfbuzz-ng/src/hb-ot-math.cc b/chromium/third_party/harfbuzz-ng/src/src/hb-ot-math.cc index f82a07353c9..f82a07353c9 100644 --- a/chromium/third_party/harfbuzz-ng/src/hb-ot-math.cc +++ b/chromium/third_party/harfbuzz-ng/src/src/hb-ot-math.cc diff --git a/chromium/third_party/harfbuzz-ng/src/hb-ot-math.h b/chromium/third_party/harfbuzz-ng/src/src/hb-ot-math.h index 521a5ca0376..521a5ca0376 100644 --- a/chromium/third_party/harfbuzz-ng/src/hb-ot-math.h +++ b/chromium/third_party/harfbuzz-ng/src/src/hb-ot-math.h diff --git a/chromium/third_party/harfbuzz-ng/src/hb-ot-maxp-table.hh b/chromium/third_party/harfbuzz-ng/src/src/hb-ot-maxp-table.hh index 3ffa57b1528..881dedad54c 100644 --- a/chromium/third_party/harfbuzz-ng/src/hb-ot-maxp-table.hh +++ b/chromium/third_party/harfbuzz-ng/src/src/hb-ot-maxp-table.hh @@ -39,9 +39,39 @@ namespace OT { #define HB_OT_TAG_maxp HB_TAG('m','a','x','p') +struct maxpV1Tail +{ + inline bool sanitize (hb_sanitize_context_t *c) const + { + TRACE_SANITIZE (this); + return_trace (c->check_struct (this)); + } + + HBUINT16 maxPoints; /* Maximum points in a non-composite glyph. */ + HBUINT16 maxContours; /* Maximum contours in a non-composite glyph. */ + HBUINT16 maxCompositePoints; /* Maximum points in a composite glyph. */ + HBUINT16 maxCompositeContours; /* Maximum contours in a composite glyph. */ + HBUINT16 maxZones; /* 1 if instructions do not use the twilight zone (Z0), + * or 2 if instructions do use Z0; should be set to 2 in + * most cases. */ + HBUINT16 maxTwilightPoints; /* Maximum points used in Z0. */ + HBUINT16 maxStorage; /* Number of Storage Area locations. */ + HBUINT16 maxFunctionDefs; /* Number of FDEFs, equal to the highest function number + 1. */ + HBUINT16 maxInstructionDefs; /* Number of IDEFs. */ + HBUINT16 maxStackElements; /* Maximum stack depth. (This includes Font and CVT + * Programs, as well as the instructions for each glyph.) */ + HBUINT16 maxSizeOfInstructions; /* Maximum byte count for glyph instructions. */ + HBUINT16 maxComponentElements; /* Maximum number of components referenced at + * "top level" for any composite glyph. */ + HBUINT16 maxComponentDepth; /* Maximum levels of recursion; 1 for simple components. */ + public: + DEFINE_SIZE_STATIC (26); +}; + + struct maxp { - static const hb_tag_t tableTag = HB_OT_TAG_maxp; + static const hb_tag_t tableTag = HB_OT_TAG_maxp; inline unsigned int get_num_glyphs (void) const { @@ -56,9 +86,15 @@ struct maxp inline bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); - return_trace (c->check_struct (this) && - likely (version.major == 1 || - (version.major == 0 && version.minor == 0x5000u))); + if (unlikely (!c->check_struct (this))) + return_trace (false); + + if (version.major == 1) + { + const maxpV1Tail &v1 = StructAfter<maxpV1Tail> (*this); + return v1.sanitize (c); + } + return_trace (likely (version.major == 0 && version.minor == 0x5000u)); } inline bool subset (hb_subset_plan_t *plan) const @@ -70,21 +106,37 @@ struct maxp if (unlikely (!maxp_prime_blob)) { return false; } - unsigned int length; - OT::maxp *maxp_prime = (OT::maxp *) hb_blob_get_data (maxp_prime_blob, &length); + OT::maxp *maxp_prime = (OT::maxp *) hb_blob_get_data (maxp_prime_blob, nullptr); maxp_prime->set_num_glyphs (plan->gids_to_retain_sorted.len); + if (plan->drop_hints) + drop_hint_fields (plan, maxp_prime); bool result = hb_subset_plan_add_table(plan, HB_OT_TAG_maxp, maxp_prime_blob); hb_blob_destroy (maxp_prime_blob); return result; } - /* We only implement version 0.5 as none of the extra fields in version 1.0 are useful. */ + static inline void drop_hint_fields (hb_subset_plan_t *plan, OT::maxp *maxp_prime) + { + 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); + } + } + 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]; */ public: DEFINE_SIZE_STATIC (6); }; diff --git a/chromium/third_party/harfbuzz-ng/src/hb-ot-name-table.hh b/chromium/third_party/harfbuzz-ng/src/src/hb-ot-name-table.hh index eb013337981..eb013337981 100644 --- a/chromium/third_party/harfbuzz-ng/src/hb-ot-name-table.hh +++ b/chromium/third_party/harfbuzz-ng/src/src/hb-ot-name-table.hh diff --git a/chromium/third_party/harfbuzz-ng/src/hb-ot-os2-table.hh b/chromium/third_party/harfbuzz-ng/src/src/hb-ot-os2-table.hh index 2d9d214959c..6cb8d494958 100644 --- a/chromium/third_party/harfbuzz-ng/src/hb-ot-os2-table.hh +++ b/chromium/third_party/harfbuzz-ng/src/src/hb-ot-os2-table.hh @@ -28,7 +28,7 @@ #define HB_OT_OS2_TABLE_HH #include "hb-open-type-private.hh" - +#include "hb-ot-os2-unicode-ranges.hh" namespace OT { @@ -67,11 +67,40 @@ struct os2 os2_prime->usFirstCharIndex.set (min_cp); os2_prime->usLastCharIndex.set (max_cp); + _update_unicode_ranges (plan->codepoints, os2_prime->ulUnicodeRange); bool result = hb_subset_plan_add_table(plan, HB_OT_TAG_os2, os2_prime_blob); + hb_blob_destroy (os2_prime_blob); return result; } + inline void _update_unicode_ranges (const hb_prealloced_array_t<hb_codepoint_t> &codepoints, + HBUINT32 ulUnicodeRange[4]) const + { + for (unsigned int i = 0; i < 4; i++) + ulUnicodeRange[i].set (0); + + for (unsigned int i = 0; i < codepoints.len; i++) + { + hb_codepoint_t cp = codepoints[i]; + unsigned int bit = hb_get_unicode_range_bit (cp); + if (bit < 128) + { + 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); + } + 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)); + } + } + } + static inline void find_min_and_max_codepoint (const hb_prealloced_array_t<hb_codepoint_t> &codepoints, uint16_t *min_cp, /* OUT */ uint16_t *max_cp /* OUT */) diff --git a/chromium/third_party/harfbuzz-ng/src/src/hb-ot-os2-unicode-ranges.hh b/chromium/third_party/harfbuzz-ng/src/src/hb-ot-os2-unicode-ranges.hh new file mode 100644 index 00000000000..2cf168f9c55 --- /dev/null +++ b/chromium/third_party/harfbuzz-ng/src/src/hb-ot-os2-unicode-ranges.hh @@ -0,0 +1,247 @@ +/* + * 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 + */ + +#ifndef HB_OT_OS2_UNICODE_RANGES_HH +#define HB_OT_OS2_UNICODE_RANGES_HH + +#include "hb-private.hh" +#include "hb-dsalgs.hh" + +namespace OT { + +struct Range { + hb_codepoint_t start; + hb_codepoint_t end; + unsigned int bit; +}; + +/* Note: The contents of this array was generated using src/gen-unicode-ranges.py. */ +static Range os2UnicodeRangesSorted[] = +{ + { 0x0, 0x7F, 0}, // Basic Latin + { 0x80, 0xFF, 1}, // Latin-1 Supplement + { 0x100, 0x17F, 2}, // Latin Extended-A + { 0x180, 0x24F, 3}, // Latin Extended-B + { 0x250, 0x2AF, 4}, // IPA Extensions + { 0x2B0, 0x2FF, 5}, // Spacing Modifier Letters + { 0x300, 0x36F, 6}, // Combining Diacritical Marks + { 0x370, 0x3FF, 7}, // Greek and Coptic + { 0x400, 0x4FF, 9}, // Cyrillic + { 0x500, 0x52F, 9}, // Cyrillic Supplement + { 0x530, 0x58F, 10}, // Armenian + { 0x590, 0x5FF, 11}, // Hebrew + { 0x600, 0x6FF, 13}, // Arabic + { 0x700, 0x74F, 71}, // Syriac + { 0x750, 0x77F, 13}, // Arabic Supplement + { 0x780, 0x7BF, 72}, // Thaana + { 0x7C0, 0x7FF, 14}, // NKo + { 0x900, 0x97F, 15}, // Devanagari + { 0x980, 0x9FF, 16}, // Bengali + { 0xA00, 0xA7F, 17}, // Gurmukhi + { 0xA80, 0xAFF, 18}, // Gujarati + { 0xB00, 0xB7F, 19}, // Oriya + { 0xB80, 0xBFF, 20}, // Tamil + { 0xC00, 0xC7F, 21}, // Telugu + { 0xC80, 0xCFF, 22}, // Kannada + { 0xD00, 0xD7F, 23}, // Malayalam + { 0xD80, 0xDFF, 73}, // Sinhala + { 0xE00, 0xE7F, 24}, // Thai + { 0xE80, 0xEFF, 25}, // Lao + { 0xF00, 0xFFF, 70}, // Tibetan + { 0x1000, 0x109F, 74}, // Myanmar + { 0x10A0, 0x10FF, 26}, // Georgian + { 0x1100, 0x11FF, 28}, // Hangul Jamo + { 0x1200, 0x137F, 75}, // Ethiopic + { 0x1380, 0x139F, 75}, // Ethiopic Supplement + { 0x13A0, 0x13FF, 76}, // Cherokee + { 0x1400, 0x167F, 77}, // Unified Canadian Aboriginal Syllabics + { 0x1680, 0x169F, 78}, // Ogham + { 0x16A0, 0x16FF, 79}, // Runic + { 0x1700, 0x171F, 84}, // Tagalog + { 0x1720, 0x173F, 84}, // Hanunoo + { 0x1740, 0x175F, 84}, // Buhid + { 0x1760, 0x177F, 84}, // Tagbanwa + { 0x1780, 0x17FF, 80}, // Khmer + { 0x1800, 0x18AF, 81}, // Mongolian + { 0x1900, 0x194F, 93}, // Limbu + { 0x1950, 0x197F, 94}, // Tai Le + { 0x1980, 0x19DF, 95}, // New Tai Lue + { 0x19E0, 0x19FF, 80}, // Khmer Symbols + { 0x1A00, 0x1A1F, 96}, // Buginese + { 0x1B00, 0x1B7F, 27}, // Balinese + { 0x1B80, 0x1BBF, 112}, // Sundanese + { 0x1C00, 0x1C4F, 113}, // Lepcha + { 0x1C50, 0x1C7F, 114}, // Ol Chiki + { 0x1D00, 0x1D7F, 4}, // Phonetic Extensions + { 0x1D80, 0x1DBF, 4}, // Phonetic Extensions Supplement + { 0x1DC0, 0x1DFF, 6}, // Combining Diacritical Marks Supplement + { 0x1E00, 0x1EFF, 29}, // Latin Extended Additional + { 0x1F00, 0x1FFF, 30}, // Greek Extended + { 0x2000, 0x206F, 31}, // General Punctuation + { 0x2070, 0x209F, 32}, // Superscripts And Subscripts + { 0x20A0, 0x20CF, 33}, // Currency Symbols + { 0x20D0, 0x20FF, 34}, // Combining Diacritical Marks For Symbols + { 0x2100, 0x214F, 35}, // Letterlike Symbols + { 0x2150, 0x218F, 36}, // Number Forms + { 0x2190, 0x21FF, 37}, // Arrows + { 0x2200, 0x22FF, 38}, // Mathematical Operators + { 0x2300, 0x23FF, 39}, // Miscellaneous Technical + { 0x2400, 0x243F, 40}, // Control Pictures + { 0x2440, 0x245F, 41}, // Optical Character Recognition + { 0x2460, 0x24FF, 42}, // Enclosed Alphanumerics + { 0x2500, 0x257F, 43}, // Box Drawing + { 0x2580, 0x259F, 44}, // Block Elements + { 0x25A0, 0x25FF, 45}, // Geometric Shapes + { 0x2600, 0x26FF, 46}, // Miscellaneous Symbols + { 0x2700, 0x27BF, 47}, // Dingbats + { 0x27C0, 0x27EF, 38}, // Miscellaneous Mathematical Symbols-A + { 0x27F0, 0x27FF, 37}, // Supplemental Arrows-A + { 0x2800, 0x28FF, 82}, // Braille Patterns + { 0x2900, 0x297F, 37}, // Supplemental Arrows-B + { 0x2980, 0x29FF, 38}, // Miscellaneous Mathematical Symbols-B + { 0x2A00, 0x2AFF, 38}, // Supplemental Mathematical Operators + { 0x2B00, 0x2BFF, 37}, // Miscellaneous Symbols and Arrows + { 0x2C00, 0x2C5F, 97}, // Glagolitic + { 0x2C60, 0x2C7F, 29}, // Latin Extended-C + { 0x2C80, 0x2CFF, 8}, // Coptic + { 0x2D00, 0x2D2F, 26}, // Georgian Supplement + { 0x2D30, 0x2D7F, 98}, // Tifinagh + { 0x2D80, 0x2DDF, 75}, // Ethiopic Extended + { 0x2DE0, 0x2DFF, 9}, // Cyrillic Extended-A + { 0x2E00, 0x2E7F, 31}, // Supplemental Punctuation + { 0x2E80, 0x2EFF, 59}, // CJK Radicals Supplement + { 0x2F00, 0x2FDF, 59}, // Kangxi Radicals + { 0x2FF0, 0x2FFF, 59}, // Ideographic Description Characters + { 0x3000, 0x303F, 48}, // CJK Symbols And Punctuation + { 0x3040, 0x309F, 49}, // Hiragana + { 0x30A0, 0x30FF, 50}, // Katakana + { 0x3100, 0x312F, 51}, // Bopomofo + { 0x3130, 0x318F, 52}, // Hangul Compatibility Jamo + { 0x3190, 0x319F, 59}, // Kanbun + { 0x31A0, 0x31BF, 51}, // Bopomofo Extended + { 0x31C0, 0x31EF, 61}, // CJK Strokes + { 0x31F0, 0x31FF, 50}, // Katakana Phonetic Extensions + { 0x3200, 0x32FF, 54}, // Enclosed CJK Letters And Months + { 0x3300, 0x33FF, 55}, // CJK Compatibility + { 0x3400, 0x4DBF, 59}, // CJK Unified Ideographs Extension A + { 0x4DC0, 0x4DFF, 99}, // Yijing Hexagram Symbols + { 0x4E00, 0x9FFF, 59}, // CJK Unified Ideographs + { 0xA000, 0xA48F, 83}, // Yi Syllables + { 0xA490, 0xA4CF, 83}, // Yi Radicals + { 0xA500, 0xA63F, 12}, // Vai + { 0xA640, 0xA69F, 9}, // Cyrillic Extended-B + { 0xA700, 0xA71F, 5}, // Modifier Tone Letters + { 0xA720, 0xA7FF, 29}, // Latin Extended-D + { 0xA800, 0xA82F, 100}, // Syloti Nagri + { 0xA840, 0xA87F, 53}, // Phags-pa + { 0xA880, 0xA8DF, 115}, // Saurashtra + { 0xA900, 0xA92F, 116}, // Kayah Li + { 0xA930, 0xA95F, 117}, // Rejang + { 0xAA00, 0xAA5F, 118}, // Cham + { 0xAC00, 0xD7AF, 56}, // Hangul Syllables + { 0xD800, 0xDFFF, 57}, // Non-Plane 0 * + { 0xE000, 0xF8FF, 60}, // Private Use Area (plane 0) + { 0xF900, 0xFAFF, 61}, // CJK Compatibility Ideographs + { 0xFB00, 0xFB4F, 62}, // Alphabetic Presentation Forms + { 0xFB50, 0xFDFF, 63}, // Arabic Presentation Forms-A + { 0xFE00, 0xFE0F, 91}, // Variation Selectors + { 0xFE10, 0xFE1F, 65}, // Vertical Forms + { 0xFE20, 0xFE2F, 64}, // Combining Half Marks + { 0xFE30, 0xFE4F, 65}, // CJK Compatibility Forms + { 0xFE50, 0xFE6F, 66}, // Small Form Variants + { 0xFE70, 0xFEFF, 67}, // Arabic Presentation Forms-B + { 0xFF00, 0xFFEF, 68}, // Halfwidth And Fullwidth Forms + { 0xFFF0, 0xFFFF, 69}, // Specials + { 0x10000, 0x1007F, 101}, // Linear B Syllabary + { 0x10080, 0x100FF, 101}, // Linear B Ideograms + { 0x10100, 0x1013F, 101}, // Aegean Numbers + { 0x10140, 0x1018F, 102}, // Ancient Greek Numbers + { 0x10190, 0x101CF, 119}, // Ancient Symbols + { 0x101D0, 0x101FF, 120}, // Phaistos Disc + { 0x10280, 0x1029F, 121}, // Lycian + { 0x102A0, 0x102DF, 121}, // Carian + { 0x10300, 0x1032F, 85}, // Old Italic + { 0x10330, 0x1034F, 86}, // Gothic + { 0x10380, 0x1039F, 103}, // Ugaritic + { 0x103A0, 0x103DF, 104}, // Old Persian + { 0x10400, 0x1044F, 87}, // Deseret + { 0x10450, 0x1047F, 105}, // Shavian + { 0x10480, 0x104AF, 106}, // Osmanya + { 0x10800, 0x1083F, 107}, // Cypriot Syllabary + { 0x10900, 0x1091F, 58}, // Phoenician + { 0x10920, 0x1093F, 121}, // Lydian + { 0x10A00, 0x10A5F, 108}, // Kharoshthi + { 0x12000, 0x123FF, 110}, // Cuneiform + { 0x12400, 0x1247F, 110}, // Cuneiform Numbers and Punctuation + { 0x1D000, 0x1D0FF, 88}, // Byzantine Musical Symbols + { 0x1D100, 0x1D1FF, 88}, // Musical Symbols + { 0x1D200, 0x1D24F, 88}, // Ancient Greek Musical Notation + { 0x1D300, 0x1D35F, 109}, // Tai Xuan Jing Symbols + { 0x1D360, 0x1D37F, 111}, // Counting Rod Numerals + { 0x1D400, 0x1D7FF, 89}, // Mathematical Alphanumeric Symbols + { 0x1F000, 0x1F02F, 122}, // Mahjong Tiles + { 0x1F030, 0x1F09F, 122}, // Domino Tiles + { 0x20000, 0x2A6DF, 59}, // CJK Unified Ideographs Extension B + { 0x2F800, 0x2FA1F, 61}, // CJK Compatibility Ideographs Supplement + { 0xE0000, 0xE007F, 92}, // Tags + { 0xE0100, 0xE01EF, 91}, // Variation Selectors Supplement + { 0xF0000, 0xFFFFD, 90}, // Private Use (plane 15) + {0x100000, 0x10FFFD, 90}, // Private Use (plane 16) +}; + +static int +_compare_range (const void *_key, const void *_item, void *_arg) +{ + hb_codepoint_t cp = *((hb_codepoint_t *) _key); + const Range *range = (Range *) _item; + + if (cp < range->start) + return -1; + else if (cp <= range->end) + return 0; + else + return 1; +} + +/** + * hb_get_unicode_range_bit: + * Returns the bit to be set in os/2 ulUnicodeRange for a given codepoint. + **/ +static unsigned int +hb_get_unicode_range_bit (hb_codepoint_t cp) +{ + Range *range = (Range*) hb_bsearch_r (&cp, os2UnicodeRangesSorted, + sizeof (os2UnicodeRangesSorted) / sizeof(Range), + sizeof(Range), + _compare_range, nullptr); + if (range != NULL) + return range->bit; + return -1; +} + +} /* namespace OT */ + +#endif /* HB_OT_OS2_UNICODE_RANGES_HH */ diff --git a/chromium/third_party/harfbuzz-ng/src/hb-ot-post-macroman.hh b/chromium/third_party/harfbuzz-ng/src/src/hb-ot-post-macroman.hh index dbbb97e5a9f..dbbb97e5a9f 100644 --- a/chromium/third_party/harfbuzz-ng/src/hb-ot-post-macroman.hh +++ b/chromium/third_party/harfbuzz-ng/src/src/hb-ot-post-macroman.hh diff --git a/chromium/third_party/harfbuzz-ng/src/hb-ot-post-table.hh b/chromium/third_party/harfbuzz-ng/src/src/hb-ot-post-table.hh index 9e4792115ea..c5ad6654794 100644 --- a/chromium/third_party/harfbuzz-ng/src/hb-ot-post-table.hh +++ b/chromium/third_party/harfbuzz-ng/src/src/hb-ot-post-table.hh @@ -82,6 +82,28 @@ struct post return_trace (true); } + inline bool subset (hb_subset_plan_t *plan) const + { + unsigned int post_prime_length; + hb_blob_t *post_blob = OT::Sanitizer<post>().sanitize (hb_face_reference_table (plan->source, HB_OT_TAG_post)); + hb_blob_t *post_prime_blob = hb_blob_create_sub_blob (post_blob, 0, post::static_size); + post *post_prime = (post *) hb_blob_get_data_writable (post_prime_blob, &post_prime_length); + hb_blob_destroy (post_blob); + + if (unlikely (!post_prime || post_prime_length != post::static_size)) + { + hb_blob_destroy (post_prime_blob); + DEBUG_MSG(SUBSET, nullptr, "Invalid source post table with length %d.", post_prime_length); + return false; + } + + post_prime->version.major.set (3); // Version 3 does not have any glyph names. + bool result = hb_subset_plan_add_table (plan, HB_OT_TAG_post, post_prime_blob); + hb_blob_destroy (post_prime_blob); + + return result; + } + struct accelerator_t { inline void init (hb_face_t *face) diff --git a/chromium/third_party/harfbuzz-ng/src/hb-ot-shape-complex-arabic-fallback.hh b/chromium/third_party/harfbuzz-ng/src/src/hb-ot-shape-complex-arabic-fallback.hh index 5a257f042d0..5a257f042d0 100644 --- a/chromium/third_party/harfbuzz-ng/src/hb-ot-shape-complex-arabic-fallback.hh +++ b/chromium/third_party/harfbuzz-ng/src/src/hb-ot-shape-complex-arabic-fallback.hh diff --git a/chromium/third_party/harfbuzz-ng/src/hb-ot-shape-complex-arabic-private.hh b/chromium/third_party/harfbuzz-ng/src/src/hb-ot-shape-complex-arabic-private.hh index fcedc7d7420..fcedc7d7420 100644 --- a/chromium/third_party/harfbuzz-ng/src/hb-ot-shape-complex-arabic-private.hh +++ b/chromium/third_party/harfbuzz-ng/src/src/hb-ot-shape-complex-arabic-private.hh diff --git a/chromium/third_party/harfbuzz-ng/src/hb-ot-shape-complex-arabic-table.hh b/chromium/third_party/harfbuzz-ng/src/src/hb-ot-shape-complex-arabic-table.hh index cd6e4058b56..cd6e4058b56 100644 --- a/chromium/third_party/harfbuzz-ng/src/hb-ot-shape-complex-arabic-table.hh +++ b/chromium/third_party/harfbuzz-ng/src/src/hb-ot-shape-complex-arabic-table.hh diff --git a/chromium/third_party/harfbuzz-ng/src/hb-ot-shape-complex-arabic-win1256.hh b/chromium/third_party/harfbuzz-ng/src/src/hb-ot-shape-complex-arabic-win1256.hh index 54c6cdc24f1..54c6cdc24f1 100644 --- a/chromium/third_party/harfbuzz-ng/src/hb-ot-shape-complex-arabic-win1256.hh +++ b/chromium/third_party/harfbuzz-ng/src/src/hb-ot-shape-complex-arabic-win1256.hh diff --git a/chromium/third_party/harfbuzz-ng/src/hb-ot-shape-complex-arabic.cc b/chromium/third_party/harfbuzz-ng/src/src/hb-ot-shape-complex-arabic.cc index 47961bfd55f..47961bfd55f 100644 --- a/chromium/third_party/harfbuzz-ng/src/hb-ot-shape-complex-arabic.cc +++ b/chromium/third_party/harfbuzz-ng/src/src/hb-ot-shape-complex-arabic.cc diff --git a/chromium/third_party/harfbuzz-ng/src/hb-ot-shape-complex-default.cc b/chromium/third_party/harfbuzz-ng/src/src/hb-ot-shape-complex-default.cc index 68a62a10d44..68a62a10d44 100644 --- a/chromium/third_party/harfbuzz-ng/src/hb-ot-shape-complex-default.cc +++ b/chromium/third_party/harfbuzz-ng/src/src/hb-ot-shape-complex-default.cc diff --git a/chromium/third_party/harfbuzz-ng/src/hb-ot-shape-complex-hangul.cc b/chromium/third_party/harfbuzz-ng/src/src/hb-ot-shape-complex-hangul.cc index 7508c223c47..7508c223c47 100644 --- a/chromium/third_party/harfbuzz-ng/src/hb-ot-shape-complex-hangul.cc +++ b/chromium/third_party/harfbuzz-ng/src/src/hb-ot-shape-complex-hangul.cc diff --git a/chromium/third_party/harfbuzz-ng/src/hb-ot-shape-complex-hebrew.cc b/chromium/third_party/harfbuzz-ng/src/src/hb-ot-shape-complex-hebrew.cc index 34cf28b8e24..34cf28b8e24 100644 --- a/chromium/third_party/harfbuzz-ng/src/hb-ot-shape-complex-hebrew.cc +++ b/chromium/third_party/harfbuzz-ng/src/src/hb-ot-shape-complex-hebrew.cc diff --git a/chromium/third_party/harfbuzz-ng/src/hb-ot-shape-complex-indic-machine.hh b/chromium/third_party/harfbuzz-ng/src/src/hb-ot-shape-complex-indic-machine.hh index f3cea227123..f3cea227123 100644 --- a/chromium/third_party/harfbuzz-ng/src/hb-ot-shape-complex-indic-machine.hh +++ b/chromium/third_party/harfbuzz-ng/src/src/hb-ot-shape-complex-indic-machine.hh diff --git a/chromium/third_party/harfbuzz-ng/src/src/hb-ot-shape-complex-indic-machine.rl b/chromium/third_party/harfbuzz-ng/src/src/hb-ot-shape-complex-indic-machine.rl new file mode 100644 index 00000000000..0ea91c0cfe7 --- /dev/null +++ b/chromium/third_party/harfbuzz-ng/src/src/hb-ot-shape-complex-indic-machine.rl @@ -0,0 +1,125 @@ +/* + * Copyright © 2011,2012 Google, Inc. + * + * This is part of HarfBuzz, a text shaping library. + * + * Permission is hereby granted, without written agreement and without + * license or royalty fees, to use, copy, modify, and distribute this + * software and its documentation for any purpose, provided that the + * above copyright notice and the following two paragraphs appear in + * all copies of this software. + * + * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR + * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES + * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN + * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, + * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS + * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO + * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + * + * Google Author(s): Behdad Esfahbod + */ + +#ifndef HB_OT_SHAPE_COMPLEX_INDIC_MACHINE_HH +#define HB_OT_SHAPE_COMPLEX_INDIC_MACHINE_HH + +#include "hb-private.hh" + +%%{ + machine indic_syllable_machine; + alphtype unsigned char; + write data; +}%% + +%%{ + +# Same order as enum indic_category_t. Not sure how to avoid duplication. +C = 1; +V = 2; +N = 3; +H = 4; +ZWNJ = 5; +ZWJ = 6; +M = 7; +SM = 8; +A = 10; +PLACEHOLDER = 11; +DOTTEDCIRCLE = 12; +RS = 13; +Repha = 15; +Ra = 16; +CM = 17; +Symbol= 18; +CS = 19; + +c = (C | Ra); # is_consonant +n = ((ZWNJ?.RS)? (N.N?)?); # is_consonant_modifier +z = ZWJ|ZWNJ; # is_joiner +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}?; +halant_group = (z?.H.(ZWJ.N?)?); +final_halant_group = halant_group | H.ZWNJ; +medial_group = CM?; +halant_or_matra_group = (final_halant_group | (H.ZWJ)? matra_group{0,4}); + + +consonant_syllable = (Repha|CS)? (cn.halant_group){0,4} cn medial_group halant_or_matra_group syllable_tail; +vowel_syllable = reph? V.n? (ZWJ | (halant_group.cn){0,4} medial_group halant_or_matra_group syllable_tail); +standalone_cluster = ((Repha|CS)? PLACEHOLDER | reph? DOTTEDCIRCLE).n? (halant_group.cn){0,4} medial_group halant_or_matra_group syllable_tail; +symbol_cluster = symbol syllable_tail; +broken_cluster = reph? n? (halant_group.cn){0,4} medial_group halant_or_matra_group syllable_tail; +other = any; + +main := |* + consonant_syllable => { found_syllable (consonant_syllable); }; + vowel_syllable => { found_syllable (vowel_syllable); }; + standalone_cluster => { found_syllable (standalone_cluster); }; + symbol_cluster => { found_syllable (symbol_cluster); }; + broken_cluster => { found_syllable (broken_cluster); }; + other => { found_syllable (non_indic_cluster); }; +*|; + + +}%% + +#define found_syllable(syllable_type) \ + HB_STMT_START { \ + if (0) fprintf (stderr, "syllable %d..%d %s\n", last, p+1, #syllable_type); \ + for (unsigned int i = last; i < p+1; i++) \ + info[i].syllable() = (syllable_serial << 4) | syllable_type; \ + last = p+1; \ + syllable_serial++; \ + if (unlikely (syllable_serial == 16)) syllable_serial = 1; \ + } HB_STMT_END + +static void +find_syllables (hb_buffer_t *buffer) +{ + unsigned int p, pe, eof, ts HB_UNUSED, te HB_UNUSED, act HB_UNUSED; + int cs; + hb_glyph_info_t *info = buffer->info; + %%{ + write init; + getkey info[p].indic_category(); + }%% + + p = 0; + pe = eof = buffer->len; + + unsigned int last = 0; + unsigned int syllable_serial = 1; + %%{ + write exec; + }%% +} + +#endif /* HB_OT_SHAPE_COMPLEX_INDIC_MACHINE_HH */ diff --git a/chromium/third_party/harfbuzz-ng/src/hb-ot-shape-complex-indic-private.hh b/chromium/third_party/harfbuzz-ng/src/src/hb-ot-shape-complex-indic-private.hh index 867b936278b..867b936278b 100644 --- a/chromium/third_party/harfbuzz-ng/src/hb-ot-shape-complex-indic-private.hh +++ b/chromium/third_party/harfbuzz-ng/src/src/hb-ot-shape-complex-indic-private.hh diff --git a/chromium/third_party/harfbuzz-ng/src/hb-ot-shape-complex-indic-table.cc b/chromium/third_party/harfbuzz-ng/src/src/hb-ot-shape-complex-indic-table.cc index 867cfb33bf1..867cfb33bf1 100644 --- a/chromium/third_party/harfbuzz-ng/src/hb-ot-shape-complex-indic-table.cc +++ b/chromium/third_party/harfbuzz-ng/src/src/hb-ot-shape-complex-indic-table.cc diff --git a/chromium/third_party/harfbuzz-ng/src/hb-ot-shape-complex-indic.cc b/chromium/third_party/harfbuzz-ng/src/src/hb-ot-shape-complex-indic.cc index 32ad86a5f32..32ad86a5f32 100644 --- a/chromium/third_party/harfbuzz-ng/src/hb-ot-shape-complex-indic.cc +++ b/chromium/third_party/harfbuzz-ng/src/src/hb-ot-shape-complex-indic.cc diff --git a/chromium/third_party/harfbuzz-ng/src/hb-ot-shape-complex-khmer-machine.hh b/chromium/third_party/harfbuzz-ng/src/src/hb-ot-shape-complex-khmer-machine.hh index 380705a5051..380705a5051 100644 --- a/chromium/third_party/harfbuzz-ng/src/hb-ot-shape-complex-khmer-machine.hh +++ b/chromium/third_party/harfbuzz-ng/src/src/hb-ot-shape-complex-khmer-machine.hh diff --git a/chromium/third_party/harfbuzz-ng/src/src/hb-ot-shape-complex-khmer-machine.rl b/chromium/third_party/harfbuzz-ng/src/src/hb-ot-shape-complex-khmer-machine.rl new file mode 100644 index 00000000000..8b00c37f093 --- /dev/null +++ b/chromium/third_party/harfbuzz-ng/src/src/hb-ot-shape-complex-khmer-machine.rl @@ -0,0 +1,107 @@ +/* + * Copyright © 2011,2012 Google, Inc. + * + * This is part of HarfBuzz, a text shaping library. + * + * Permission is hereby granted, without written agreement and without + * license or royalty fees, to use, copy, modify, and distribute this + * software and its documentation for any purpose, provided that the + * above copyright notice and the following two paragraphs appear in + * all copies of this software. + * + * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR + * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES + * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN + * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, + * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS + * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO + * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + * + * Google Author(s): Behdad Esfahbod + */ + +#ifndef HB_OT_SHAPE_COMPLEX_KHMER_MACHINE_HH +#define HB_OT_SHAPE_COMPLEX_KHMER_MACHINE_HH + +#include "hb-private.hh" + +%%{ + machine khmer_syllable_machine; + alphtype unsigned char; + write data; +}%% + +%%{ + +# Same order as enum khmer_category_t. Not sure how to avoid duplication. +C = 1; +V = 2; +N = 3; +ZWNJ = 5; +ZWJ = 6; +M = 7; +SM = 8; +PLACEHOLDER = 11; +DOTTEDCIRCLE = 12; +RS = 13; +Coeng = 14; +Ra = 16; + +c = (C | Ra | V); # is_consonant +n = ((ZWNJ?.RS)? (N.N?)?); # is_consonant_modifier +z = ZWJ|ZWNJ; # is_joiner + +cn = c.n?; +matra_group = z?.M.N?; +syllable_tail = (SM.SM?)?; + + +broken_cluster = n? (Coeng.cn)* matra_group* (Coeng.cn)? syllable_tail; +consonant_syllable = (c|PLACEHOLDER|DOTTEDCIRCLE) broken_cluster; +other = any; + +main := |* + consonant_syllable => { found_syllable (consonant_syllable); }; + broken_cluster => { found_syllable (broken_cluster); }; + other => { found_syllable (non_khmer_cluster); }; +*|; + + +}%% + +#define found_syllable(syllable_type) \ + HB_STMT_START { \ + if (0) fprintf (stderr, "syllable %d..%d %s\n", last, p+1, #syllable_type); \ + for (unsigned int i = last; i < p+1; i++) \ + info[i].syllable() = (syllable_serial << 4) | syllable_type; \ + last = p+1; \ + syllable_serial++; \ + if (unlikely (syllable_serial == 16)) syllable_serial = 1; \ + } HB_STMT_END + +static void +find_syllables (hb_buffer_t *buffer) +{ + unsigned int p, pe, eof, ts HB_UNUSED, te HB_UNUSED, act HB_UNUSED; + int cs; + hb_glyph_info_t *info = buffer->info; + %%{ + write init; + getkey info[p].khmer_category(); + }%% + + p = 0; + pe = eof = buffer->len; + + unsigned int last = 0; + unsigned int syllable_serial = 1; + %%{ + write exec; + }%% +} + +#endif /* HB_OT_SHAPE_COMPLEX_KHMER_MACHINE_HH */ diff --git a/chromium/third_party/harfbuzz-ng/src/hb-ot-shape-complex-khmer-private.hh b/chromium/third_party/harfbuzz-ng/src/src/hb-ot-shape-complex-khmer-private.hh index f90ef967440..f90ef967440 100644 --- a/chromium/third_party/harfbuzz-ng/src/hb-ot-shape-complex-khmer-private.hh +++ b/chromium/third_party/harfbuzz-ng/src/src/hb-ot-shape-complex-khmer-private.hh diff --git a/chromium/third_party/harfbuzz-ng/src/hb-ot-shape-complex-khmer.cc b/chromium/third_party/harfbuzz-ng/src/src/hb-ot-shape-complex-khmer.cc index 304879d8fbb..304879d8fbb 100644 --- a/chromium/third_party/harfbuzz-ng/src/hb-ot-shape-complex-khmer.cc +++ b/chromium/third_party/harfbuzz-ng/src/src/hb-ot-shape-complex-khmer.cc diff --git a/chromium/third_party/harfbuzz-ng/src/hb-ot-shape-complex-myanmar-machine.hh b/chromium/third_party/harfbuzz-ng/src/src/hb-ot-shape-complex-myanmar-machine.hh index fb67dd42e64..fb67dd42e64 100644 --- a/chromium/third_party/harfbuzz-ng/src/hb-ot-shape-complex-myanmar-machine.hh +++ b/chromium/third_party/harfbuzz-ng/src/src/hb-ot-shape-complex-myanmar-machine.hh diff --git a/chromium/third_party/harfbuzz-ng/src/src/hb-ot-shape-complex-myanmar-machine.rl b/chromium/third_party/harfbuzz-ng/src/src/hb-ot-shape-complex-myanmar-machine.rl new file mode 100644 index 00000000000..0cd84fa1b88 --- /dev/null +++ b/chromium/third_party/harfbuzz-ng/src/src/hb-ot-shape-complex-myanmar-machine.rl @@ -0,0 +1,129 @@ +/* + * Copyright © 2011,2012 Google, Inc. + * + * This is part of HarfBuzz, a text shaping library. + * + * Permission is hereby granted, without written agreement and without + * license or royalty fees, to use, copy, modify, and distribute this + * software and its documentation for any purpose, provided that the + * above copyright notice and the following two paragraphs appear in + * all copies of this software. + * + * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR + * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES + * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN + * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, + * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS + * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO + * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + * + * Google Author(s): Behdad Esfahbod + */ + +#ifndef HB_OT_SHAPE_COMPLEX_MYANMAR_MACHINE_HH +#define HB_OT_SHAPE_COMPLEX_MYANMAR_MACHINE_HH + +#include "hb-private.hh" + +%%{ + machine myanmar_syllable_machine; + alphtype unsigned char; + write data; +}%% + +%%{ + +# Same order as enum myanmar_category_t. Not sure how to avoid duplication. +A = 10; +As = 18; +C = 1; +D = 32; +D0 = 20; +DB = 3; +GB = 11; +H = 4; +IV = 2; +MH = 21; +MR = 22; +MW = 23; +MY = 24; +PT = 25; +V = 8; +VAbv = 26; +VBlw = 27; +VPre = 28; +VPst = 29; +VS = 30; +ZWJ = 6; +ZWNJ = 5; +Ra = 16; +P = 31; +CS = 19; + +j = ZWJ|ZWNJ; # Joiners +k = (Ra As H); # Kinzi + +c = C|Ra; # is_consonant + +medial_group = MY? MR? MW? 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); + +consonant_syllable = (k|CS)? (c|IV|D|GB).VS? (H (c|IV).VS?)* syllable_tail; +punctuation_cluster = P V; +broken_cluster = k? VS? syllable_tail; +other = any; + +main := |* + consonant_syllable => { found_syllable (consonant_syllable); }; + j => { found_syllable (non_myanmar_cluster); }; + punctuation_cluster => { found_syllable (punctuation_cluster); }; + broken_cluster => { found_syllable (broken_cluster); }; + other => { found_syllable (non_myanmar_cluster); }; +*|; + + +}%% + +#define found_syllable(syllable_type) \ + HB_STMT_START { \ + if (0) fprintf (stderr, "syllable %d..%d %s\n", last, p+1, #syllable_type); \ + for (unsigned int i = last; i < p+1; i++) \ + info[i].syllable() = (syllable_serial << 4) | syllable_type; \ + last = p+1; \ + syllable_serial++; \ + if (unlikely (syllable_serial == 16)) syllable_serial = 1; \ + } HB_STMT_END + +static void +find_syllables (hb_buffer_t *buffer) +{ + unsigned int p, pe, eof, ts HB_UNUSED, te HB_UNUSED, act HB_UNUSED; + int cs; + hb_glyph_info_t *info = buffer->info; + %%{ + write init; + getkey info[p].myanmar_category(); + }%% + + p = 0; + pe = eof = buffer->len; + + unsigned int last = 0; + unsigned int syllable_serial = 1; + %%{ + write exec; + }%% +} + +#undef found_syllable + +#endif /* HB_OT_SHAPE_COMPLEX_MYANMAR_MACHINE_HH */ diff --git a/chromium/third_party/harfbuzz-ng/src/hb-ot-shape-complex-myanmar-private.hh b/chromium/third_party/harfbuzz-ng/src/src/hb-ot-shape-complex-myanmar-private.hh index 04f81bd1227..04f81bd1227 100644 --- a/chromium/third_party/harfbuzz-ng/src/hb-ot-shape-complex-myanmar-private.hh +++ b/chromium/third_party/harfbuzz-ng/src/src/hb-ot-shape-complex-myanmar-private.hh diff --git a/chromium/third_party/harfbuzz-ng/src/hb-ot-shape-complex-myanmar.cc b/chromium/third_party/harfbuzz-ng/src/src/hb-ot-shape-complex-myanmar.cc index 3c57bc1ff66..3c57bc1ff66 100644 --- a/chromium/third_party/harfbuzz-ng/src/hb-ot-shape-complex-myanmar.cc +++ b/chromium/third_party/harfbuzz-ng/src/src/hb-ot-shape-complex-myanmar.cc diff --git a/chromium/third_party/harfbuzz-ng/src/hb-ot-shape-complex-private.hh b/chromium/third_party/harfbuzz-ng/src/src/hb-ot-shape-complex-private.hh index 08b6fe9697d..08b6fe9697d 100644 --- a/chromium/third_party/harfbuzz-ng/src/hb-ot-shape-complex-private.hh +++ b/chromium/third_party/harfbuzz-ng/src/src/hb-ot-shape-complex-private.hh diff --git a/chromium/third_party/harfbuzz-ng/src/hb-ot-shape-complex-thai.cc b/chromium/third_party/harfbuzz-ng/src/src/hb-ot-shape-complex-thai.cc index 6ba925c675c..6ba925c675c 100644 --- a/chromium/third_party/harfbuzz-ng/src/hb-ot-shape-complex-thai.cc +++ b/chromium/third_party/harfbuzz-ng/src/src/hb-ot-shape-complex-thai.cc diff --git a/chromium/third_party/harfbuzz-ng/src/hb-ot-shape-complex-tibetan.cc b/chromium/third_party/harfbuzz-ng/src/src/hb-ot-shape-complex-tibetan.cc index eaac0bf689f..eaac0bf689f 100644 --- a/chromium/third_party/harfbuzz-ng/src/hb-ot-shape-complex-tibetan.cc +++ b/chromium/third_party/harfbuzz-ng/src/src/hb-ot-shape-complex-tibetan.cc diff --git a/chromium/third_party/harfbuzz-ng/src/hb-ot-shape-complex-use-machine.hh b/chromium/third_party/harfbuzz-ng/src/src/hb-ot-shape-complex-use-machine.hh index 0bf3ad3024a..0bf3ad3024a 100644 --- a/chromium/third_party/harfbuzz-ng/src/hb-ot-shape-complex-use-machine.hh +++ b/chromium/third_party/harfbuzz-ng/src/src/hb-ot-shape-complex-use-machine.hh diff --git a/chromium/third_party/harfbuzz-ng/src/src/hb-ot-shape-complex-use-machine.rl b/chromium/third_party/harfbuzz-ng/src/src/hb-ot-shape-complex-use-machine.rl new file mode 100644 index 00000000000..11fb47020ac --- /dev/null +++ b/chromium/third_party/harfbuzz-ng/src/src/hb-ot-shape-complex-use-machine.rl @@ -0,0 +1,176 @@ +/* + * Copyright © 2015 Mozilla Foundation. + * Copyright © 2015 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. + * + * Mozilla Author(s): Jonathan Kew + * Google Author(s): Behdad Esfahbod + */ + +#ifndef HB_OT_SHAPE_COMPLEX_USE_MACHINE_HH +#define HB_OT_SHAPE_COMPLEX_USE_MACHINE_HH + +#include "hb-private.hh" + +%%{ + machine use_syllable_machine; + alphtype unsigned char; + write data; +}%% + +%%{ + +# Same order as enum use_category_t. Not sure how to avoid duplication. + +O = 0; # OTHER + +B = 1; # BASE +IND = 3; # BASE_IND +N = 4; # BASE_NUM +GB = 5; # BASE_OTHER +CGJ = 6; # CGJ +#F = 7; # CONS_FINAL +FM = 8; # CONS_FINAL_MOD +#M = 9; # CONS_MED +#CM = 10; # CONS_MOD +SUB = 11; # CONS_SUB +H = 12; # HALANT + +HN = 13; # HALANT_NUM +ZWNJ = 14; # Zero width non-joiner +ZWJ = 15; # Zero width joiner +WJ = 16; # Word joiner +Rsv = 17; # Reserved characters +R = 18; # REPHA +S = 19; # SYM +#SM = 20; # SYM_MOD +VS = 21; # VARIATION_SELECTOR +#V = 36; # VOWEL +#VM = 40; # VOWEL_MOD + +FAbv = 24; # CONS_FINAL_ABOVE +FBlw = 25; # CONS_FINAL_BELOW +FPst = 26; # CONS_FINAL_POST +MAbv = 27; # CONS_MED_ABOVE +MBlw = 28; # CONS_MED_BELOW +MPst = 29; # CONS_MED_POST +MPre = 30; # CONS_MED_PRE +CMAbv = 31; # CONS_MOD_ABOVE +CMBlw = 32; # CONS_MOD_BELOW +VAbv = 33; # VOWEL_ABOVE / VOWEL_ABOVE_BELOW / VOWEL_ABOVE_BELOW_POST / VOWEL_ABOVE_POST +VBlw = 34; # VOWEL_BELOW / VOWEL_BELOW_POST +VPst = 35; # VOWEL_POST UIPC = Right +VPre = 22; # VOWEL_PRE / VOWEL_PRE_ABOVE / VOWEL_PRE_ABOVE_POST / VOWEL_PRE_POST +VMAbv = 37; # VOWEL_MOD_ABOVE +VMBlw = 38; # VOWEL_MOD_BELOW +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 + + +# Override: Adjoc ZWJ placement. https://github.com/harfbuzz/harfbuzz/issues/542#issuecomment-353169729 +consonant_modifiers = CMAbv* CMBlw* ((ZWJ?.H.ZWJ? B | SUB) VS? CMAbv? CMBlw*)*; +# Override: Allow two MBlw. https://github.com/harfbuzz/harfbuzz/issues/376 +medial_consonants = MPre? MAbv? MBlw?.MBlw? MPst?; +dependent_vowels = VPre* VAbv* VBlw* VPst*; +vowel_modifiers = VMPre* VMAbv* VMBlw* VMPst*; +final_consonants = FAbv* FBlw* FPst* FM?; + +virama_terminated_cluster = + (R|CS)? (B | GB) VS? + consonant_modifiers + ZWJ?.H.ZWJ? +; +standard_cluster = + (R|CS)? (B | GB) VS? + consonant_modifiers + medial_consonants + dependent_vowels + vowel_modifiers + final_consonants +; + +broken_cluster = + R? + consonant_modifiers + medial_consonants + dependent_vowels + vowel_modifiers + final_consonants +; + +number_joiner_terminated_cluster = N VS? (HN N VS?)* HN; +numeral_cluster = N VS? (HN N VS?)*; +symbol_cluster = S VS? SMAbv* SMBlw*; +independent_cluster = (IND | O | Rsv | WJ) VS?; +other = any; + +main := |* + independent_cluster => { found_syllable (independent_cluster); }; + virama_terminated_cluster => { found_syllable (virama_terminated_cluster); }; + standard_cluster => { found_syllable (standard_cluster); }; + number_joiner_terminated_cluster => { found_syllable (number_joiner_terminated_cluster); }; + numeral_cluster => { found_syllable (numeral_cluster); }; + symbol_cluster => { found_syllable (symbol_cluster); }; + broken_cluster => { found_syllable (broken_cluster); }; + other => { found_syllable (non_cluster); }; +*|; + + +}%% + +#define found_syllable(syllable_type) \ + HB_STMT_START { \ + if (0) fprintf (stderr, "syllable %d..%d %s\n", last, p+1, #syllable_type); \ + for (unsigned int i = last; i < p+1; i++) \ + info[i].syllable() = (syllable_serial << 4) | syllable_type; \ + last = p+1; \ + syllable_serial++; \ + if (unlikely (syllable_serial == 16)) syllable_serial = 1; \ + } HB_STMT_END + +static void +find_syllables (hb_buffer_t *buffer) +{ + unsigned int p, pe, eof, ts HB_UNUSED, te HB_UNUSED, act HB_UNUSED; + int cs; + hb_glyph_info_t *info = buffer->info; + %%{ + write init; + getkey info[p].use_category(); + }%% + + p = 0; + pe = eof = buffer->len; + + unsigned int last = 0; + unsigned int syllable_serial = 1; + %%{ + write exec; + }%% +} + +#undef found_syllable + +#endif /* HB_OT_SHAPE_COMPLEX_USE_MACHINE_HH */ diff --git a/chromium/third_party/harfbuzz-ng/src/hb-ot-shape-complex-use-private.hh b/chromium/third_party/harfbuzz-ng/src/src/hb-ot-shape-complex-use-private.hh index f7ded133d6b..f7ded133d6b 100644 --- a/chromium/third_party/harfbuzz-ng/src/hb-ot-shape-complex-use-private.hh +++ b/chromium/third_party/harfbuzz-ng/src/src/hb-ot-shape-complex-use-private.hh diff --git a/chromium/third_party/harfbuzz-ng/src/hb-ot-shape-complex-use-table.cc b/chromium/third_party/harfbuzz-ng/src/src/hb-ot-shape-complex-use-table.cc index 6823392f4b4..6823392f4b4 100644 --- a/chromium/third_party/harfbuzz-ng/src/hb-ot-shape-complex-use-table.cc +++ b/chromium/third_party/harfbuzz-ng/src/src/hb-ot-shape-complex-use-table.cc diff --git a/chromium/third_party/harfbuzz-ng/src/hb-ot-shape-complex-use.cc b/chromium/third_party/harfbuzz-ng/src/src/hb-ot-shape-complex-use.cc index ee7653b51ce..ee7653b51ce 100644 --- a/chromium/third_party/harfbuzz-ng/src/hb-ot-shape-complex-use.cc +++ b/chromium/third_party/harfbuzz-ng/src/src/hb-ot-shape-complex-use.cc diff --git a/chromium/third_party/harfbuzz-ng/src/hb-ot-shape-fallback-private.hh b/chromium/third_party/harfbuzz-ng/src/src/hb-ot-shape-fallback-private.hh index e134224df92..e134224df92 100644 --- a/chromium/third_party/harfbuzz-ng/src/hb-ot-shape-fallback-private.hh +++ b/chromium/third_party/harfbuzz-ng/src/src/hb-ot-shape-fallback-private.hh diff --git a/chromium/third_party/harfbuzz-ng/src/hb-ot-shape-fallback.cc b/chromium/third_party/harfbuzz-ng/src/src/hb-ot-shape-fallback.cc index c7b46053d8c..c7b46053d8c 100644 --- a/chromium/third_party/harfbuzz-ng/src/hb-ot-shape-fallback.cc +++ b/chromium/third_party/harfbuzz-ng/src/src/hb-ot-shape-fallback.cc diff --git a/chromium/third_party/harfbuzz-ng/src/hb-ot-shape-normalize-private.hh b/chromium/third_party/harfbuzz-ng/src/src/hb-ot-shape-normalize-private.hh index c744e26451d..c744e26451d 100644 --- a/chromium/third_party/harfbuzz-ng/src/hb-ot-shape-normalize-private.hh +++ b/chromium/third_party/harfbuzz-ng/src/src/hb-ot-shape-normalize-private.hh diff --git a/chromium/third_party/harfbuzz-ng/src/hb-ot-shape-normalize.cc b/chromium/third_party/harfbuzz-ng/src/src/hb-ot-shape-normalize.cc index 62cbb9de998..62cbb9de998 100644 --- a/chromium/third_party/harfbuzz-ng/src/hb-ot-shape-normalize.cc +++ b/chromium/third_party/harfbuzz-ng/src/src/hb-ot-shape-normalize.cc diff --git a/chromium/third_party/harfbuzz-ng/src/hb-ot-shape-private.hh b/chromium/third_party/harfbuzz-ng/src/src/hb-ot-shape-private.hh index fe5d2b7f333..fe5d2b7f333 100644 --- a/chromium/third_party/harfbuzz-ng/src/hb-ot-shape-private.hh +++ b/chromium/third_party/harfbuzz-ng/src/src/hb-ot-shape-private.hh diff --git a/chromium/third_party/harfbuzz-ng/src/hb-ot-shape.cc b/chromium/third_party/harfbuzz-ng/src/src/hb-ot-shape.cc index ec7c0d00ed9..263d65c0ccb 100644 --- a/chromium/third_party/harfbuzz-ng/src/hb-ot-shape.cc +++ b/chromium/third_party/harfbuzz-ng/src/src/hb-ot-shape.cc @@ -41,6 +41,7 @@ #include "hb-set-private.hh" #include "hb-ot-layout-gsubgpos-private.hh" +//#include "hb-aat-layout-private.hh" static hb_tag_t common_features[] = { HB_TAG('c','c','m','p'), @@ -786,6 +787,8 @@ hb_ot_position (hb_ot_shape_context_t *c) _hb_ot_shape_fallback_kern (c->plan, c->font, c->buffer); _hb_buffer_deallocate_gsubgpos_vars (c->buffer); + + //hb_aat_layout_position (c->font, c->buffer); } static inline void @@ -956,7 +959,7 @@ hb_ot_shape_glyphs_closure (hb_font_t *font, hb_set_t *copy = hb_set_create (); do { copy->set (glyphs); - for (hb_codepoint_t lookup_index = -1; hb_set_next (lookups, &lookup_index);) + for (hb_codepoint_t lookup_index = HB_SET_VALUE_INVALID; hb_set_next (lookups, &lookup_index);) hb_ot_layout_lookup_substitute_closure (font->face, lookup_index, glyphs); } while (!copy->is_equal (glyphs)); hb_set_destroy (copy); diff --git a/chromium/third_party/harfbuzz-ng/src/hb-ot-shape.h b/chromium/third_party/harfbuzz-ng/src/src/hb-ot-shape.h index 7b1bcc06378..7b1bcc06378 100644 --- a/chromium/third_party/harfbuzz-ng/src/hb-ot-shape.h +++ b/chromium/third_party/harfbuzz-ng/src/src/hb-ot-shape.h diff --git a/chromium/third_party/harfbuzz-ng/src/hb-ot-tag.cc b/chromium/third_party/harfbuzz-ng/src/src/hb-ot-tag.cc index 1338c31732f..1338c31732f 100644 --- a/chromium/third_party/harfbuzz-ng/src/hb-ot-tag.cc +++ b/chromium/third_party/harfbuzz-ng/src/src/hb-ot-tag.cc diff --git a/chromium/third_party/harfbuzz-ng/src/hb-ot-tag.h b/chromium/third_party/harfbuzz-ng/src/src/hb-ot-tag.h index 54fb747f582..54fb747f582 100644 --- a/chromium/third_party/harfbuzz-ng/src/hb-ot-tag.h +++ b/chromium/third_party/harfbuzz-ng/src/src/hb-ot-tag.h diff --git a/chromium/third_party/harfbuzz-ng/src/hb-ot-var-avar-table.hh b/chromium/third_party/harfbuzz-ng/src/src/hb-ot-var-avar-table.hh index e305a67c261..e305a67c261 100644 --- a/chromium/third_party/harfbuzz-ng/src/hb-ot-var-avar-table.hh +++ b/chromium/third_party/harfbuzz-ng/src/src/hb-ot-var-avar-table.hh diff --git a/chromium/third_party/harfbuzz-ng/src/hb-ot-var-fvar-table.hh b/chromium/third_party/harfbuzz-ng/src/src/hb-ot-var-fvar-table.hh index 999b7236f3b..17ff0e5177b 100644 --- a/chromium/third_party/harfbuzz-ng/src/hb-ot-var-fvar-table.hh +++ b/chromium/third_party/harfbuzz-ng/src/src/hb-ot-var-fvar-table.hh @@ -42,11 +42,11 @@ struct InstanceRecord } protected: - HBUINT16 subfamilyNameID;/* The name ID for entries in the 'name' table + NameID subfamilyNameID;/* The name ID for entries in the 'name' table * that provide subfamily names for this instance. */ HBUINT16 reserved; /* Reserved for future use — set to 0. */ Fixed coordinates[VAR];/* The coordinates array for this instance. */ - //HBUINT16 postScriptNameIDX;/*Optional. The name ID for entries in the 'name' + //NameID postScriptNameIDX;/*Optional. The name ID for entries in the 'name' // * table that provide PostScript names for this // * instance. */ @@ -68,7 +68,7 @@ struct AxisRecord Fixed defaultValue; /* The default coordinate value for the axis. */ Fixed maxValue; /* The maximum coordinate value for the axis. */ HBUINT16 reserved; /* Reserved for future use — set to 0. */ - HBUINT16 axisNameID; /* The name ID for entries in the 'name' table that + NameID axisNameID; /* The name ID for entries in the 'name' table that * provide a display name for this axis. */ public: diff --git a/chromium/third_party/harfbuzz-ng/src/hb-ot-var-hvar-table.hh b/chromium/third_party/harfbuzz-ng/src/src/hb-ot-var-hvar-table.hh index e20131b161a..e20131b161a 100644 --- a/chromium/third_party/harfbuzz-ng/src/hb-ot-var-hvar-table.hh +++ b/chromium/third_party/harfbuzz-ng/src/src/hb-ot-var-hvar-table.hh diff --git a/chromium/third_party/harfbuzz-ng/src/hb-ot-var-mvar-table.hh b/chromium/third_party/harfbuzz-ng/src/src/hb-ot-var-mvar-table.hh index e835768521e..e835768521e 100644 --- a/chromium/third_party/harfbuzz-ng/src/hb-ot-var-mvar-table.hh +++ b/chromium/third_party/harfbuzz-ng/src/src/hb-ot-var-mvar-table.hh diff --git a/chromium/third_party/harfbuzz-ng/src/hb-ot-var.cc b/chromium/third_party/harfbuzz-ng/src/src/hb-ot-var.cc index 90ba0bd02c6..90ba0bd02c6 100644 --- a/chromium/third_party/harfbuzz-ng/src/hb-ot-var.cc +++ b/chromium/third_party/harfbuzz-ng/src/src/hb-ot-var.cc diff --git a/chromium/third_party/harfbuzz-ng/src/hb-ot-var.h b/chromium/third_party/harfbuzz-ng/src/src/hb-ot-var.h index a2c0c5f2b02..a2c0c5f2b02 100644 --- a/chromium/third_party/harfbuzz-ng/src/hb-ot-var.h +++ b/chromium/third_party/harfbuzz-ng/src/src/hb-ot-var.h diff --git a/chromium/third_party/harfbuzz-ng/src/hb-ot.h b/chromium/third_party/harfbuzz-ng/src/src/hb-ot.h index 2120a3efa34..2120a3efa34 100644 --- a/chromium/third_party/harfbuzz-ng/src/hb-ot.h +++ b/chromium/third_party/harfbuzz-ng/src/src/hb-ot.h diff --git a/chromium/third_party/harfbuzz-ng/src/hb-private.hh b/chromium/third_party/harfbuzz-ng/src/src/hb-private.hh index daa496e98cd..daa496e98cd 100644 --- a/chromium/third_party/harfbuzz-ng/src/hb-private.hh +++ b/chromium/third_party/harfbuzz-ng/src/src/hb-private.hh diff --git a/chromium/third_party/harfbuzz-ng/src/hb-set-digest-private.hh b/chromium/third_party/harfbuzz-ng/src/src/hb-set-digest-private.hh index e099a826414..e099a826414 100644 --- a/chromium/third_party/harfbuzz-ng/src/hb-set-digest-private.hh +++ b/chromium/third_party/harfbuzz-ng/src/src/hb-set-digest-private.hh diff --git a/chromium/third_party/harfbuzz-ng/src/hb-set-private.hh b/chromium/third_party/harfbuzz-ng/src/src/hb-set-private.hh index 49cd791222f..3615c50e9e2 100644 --- a/chromium/third_party/harfbuzz-ng/src/hb-set-private.hh +++ b/chromium/third_party/harfbuzz-ng/src/src/hb-set-private.hh @@ -389,6 +389,7 @@ struct hb_set_t unsigned int na = pages.len; unsigned int nb = other->pages.len; + unsigned int next_page = na; unsigned int count = 0; unsigned int a = 0, b = 0; @@ -430,27 +431,47 @@ struct hb_set_t { a--; b--; - Op::process (page_at (--count).v, page_at (a).v, other->page_at (b).v); + count--; + page_map[count] = page_map[a]; + Op::process (page_at (count).v, page_at (a).v, other->page_at (b).v); } else if (page_map[a - 1].major > other->page_map[b - 1].major) { - a--; - if (Op::passthru_left) - page_at (--count).v = page_at (a).v; + a--; + if (Op::passthru_left) + { + count--; + page_map[count] = page_map[a]; + } } else { - b--; - if (Op::passthru_right) - page_at (--count).v = other->page_at (b).v; + b--; + if (Op::passthru_right) + { + count--; + page_map[count].major = other->page_map[b].major; + page_map[count].index = next_page++; + page_at (count).v = other->page_at (b).v; + } } } if (Op::passthru_left) while (a) - page_at (--count).v = page_at (--a).v; + { + a--; + count--; + page_map[count] = page_map [a]; + } if (Op::passthru_right) while (b) - page_at (--count).v = other->page_at (--b).v; + { + b--; + count--; + page_map[count].major = other->page_map[b].major; + page_map[count].index = next_page++; + page_at (count).v = other->page_at (b).v; + } assert (!count); } diff --git a/chromium/third_party/harfbuzz-ng/src/hb-set.cc b/chromium/third_party/harfbuzz-ng/src/src/hb-set.cc index 07cf9d09b55..07cf9d09b55 100644 --- a/chromium/third_party/harfbuzz-ng/src/hb-set.cc +++ b/chromium/third_party/harfbuzz-ng/src/src/hb-set.cc diff --git a/chromium/third_party/harfbuzz-ng/src/hb-set.h b/chromium/third_party/harfbuzz-ng/src/src/hb-set.h index b0f82f82208..b0f82f82208 100644 --- a/chromium/third_party/harfbuzz-ng/src/hb-set.h +++ b/chromium/third_party/harfbuzz-ng/src/src/hb-set.h diff --git a/chromium/third_party/harfbuzz-ng/src/hb-shape-plan-private.hh b/chromium/third_party/harfbuzz-ng/src/src/hb-shape-plan-private.hh index aa0413a272d..aa0413a272d 100644 --- a/chromium/third_party/harfbuzz-ng/src/hb-shape-plan-private.hh +++ b/chromium/third_party/harfbuzz-ng/src/src/hb-shape-plan-private.hh diff --git a/chromium/third_party/harfbuzz-ng/src/hb-shape-plan.cc b/chromium/third_party/harfbuzz-ng/src/src/hb-shape-plan.cc index 6eeba2b3d1f..6eeba2b3d1f 100644 --- a/chromium/third_party/harfbuzz-ng/src/hb-shape-plan.cc +++ b/chromium/third_party/harfbuzz-ng/src/src/hb-shape-plan.cc diff --git a/chromium/third_party/harfbuzz-ng/src/hb-shape-plan.h b/chromium/third_party/harfbuzz-ng/src/src/hb-shape-plan.h index b62ae7ca350..b62ae7ca350 100644 --- a/chromium/third_party/harfbuzz-ng/src/hb-shape-plan.h +++ b/chromium/third_party/harfbuzz-ng/src/src/hb-shape-plan.h diff --git a/chromium/third_party/harfbuzz-ng/src/hb-shape.cc b/chromium/third_party/harfbuzz-ng/src/src/hb-shape.cc index 39355b337d6..39355b337d6 100644 --- a/chromium/third_party/harfbuzz-ng/src/hb-shape.cc +++ b/chromium/third_party/harfbuzz-ng/src/src/hb-shape.cc diff --git a/chromium/third_party/harfbuzz-ng/src/hb-shape.h b/chromium/third_party/harfbuzz-ng/src/src/hb-shape.h index 39507ff744b..39507ff744b 100644 --- a/chromium/third_party/harfbuzz-ng/src/hb-shape.h +++ b/chromium/third_party/harfbuzz-ng/src/src/hb-shape.h diff --git a/chromium/third_party/harfbuzz-ng/src/hb-shaper-impl-private.hh b/chromium/third_party/harfbuzz-ng/src/src/hb-shaper-impl-private.hh index 7844081e95b..7844081e95b 100644 --- a/chromium/third_party/harfbuzz-ng/src/hb-shaper-impl-private.hh +++ b/chromium/third_party/harfbuzz-ng/src/src/hb-shaper-impl-private.hh diff --git a/chromium/third_party/harfbuzz-ng/src/hb-shaper-list.hh b/chromium/third_party/harfbuzz-ng/src/src/hb-shaper-list.hh index b0835d31ab1..b0835d31ab1 100644 --- a/chromium/third_party/harfbuzz-ng/src/hb-shaper-list.hh +++ b/chromium/third_party/harfbuzz-ng/src/src/hb-shaper-list.hh diff --git a/chromium/third_party/harfbuzz-ng/src/hb-shaper-private.hh b/chromium/third_party/harfbuzz-ng/src/src/hb-shaper-private.hh index ce2d9f28395..ce2d9f28395 100644 --- a/chromium/third_party/harfbuzz-ng/src/hb-shaper-private.hh +++ b/chromium/third_party/harfbuzz-ng/src/src/hb-shaper-private.hh diff --git a/chromium/third_party/harfbuzz-ng/src/hb-shaper.cc b/chromium/third_party/harfbuzz-ng/src/src/hb-shaper.cc index 2c44cf26533..2c44cf26533 100644 --- a/chromium/third_party/harfbuzz-ng/src/hb-shaper.cc +++ b/chromium/third_party/harfbuzz-ng/src/src/hb-shaper.cc diff --git a/chromium/third_party/harfbuzz-ng/src/hb-string-array.hh b/chromium/third_party/harfbuzz-ng/src/src/hb-string-array.hh index ba829b0cf04..ba829b0cf04 100644 --- a/chromium/third_party/harfbuzz-ng/src/hb-string-array.hh +++ b/chromium/third_party/harfbuzz-ng/src/src/hb-string-array.hh diff --git a/chromium/third_party/harfbuzz-ng/src/src/hb-subset-glyf.cc b/chromium/third_party/harfbuzz-ng/src/src/hb-subset-glyf.cc new file mode 100644 index 00000000000..0b84c856c2b --- /dev/null +++ b/chromium/third_party/harfbuzz-ng/src/src/hb-subset-glyf.cc @@ -0,0 +1,307 @@ +/* + * 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-private.hh" +#include "hb-ot-glyf-table.hh" +#include "hb-set.h" +#include "hb-subset-glyf.hh" +#include "hb-subset-plan.hh" + +static bool +_calculate_glyf_and_loca_prime_size (const OT::glyf::accelerator_t &glyf, + hb_prealloced_array_t<hb_codepoint_t> &glyph_ids, + hb_bool_t drop_hints, + bool *use_short_loca /* OUT */, + unsigned int *glyf_size /* OUT */, + unsigned int *loca_size /* OUT */, + hb_prealloced_array_t<unsigned int> *instruction_ranges /* OUT */) +{ + unsigned int total = 0; + for (unsigned int i = 0; i < glyph_ids.len; i++) + { + hb_codepoint_t next_glyph = glyph_ids[i]; + unsigned int *instruction_start = instruction_ranges->push(); + unsigned int *instruction_end = instruction_ranges->push(); + *instruction_start = 0; + *instruction_end = 0; + + 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); + continue; + } + if (end_offset - start_offset < OT::glyf::GlyphHeader::static_size) + continue; /* 0-length glyph */ + + if (drop_hints) + { + if (unlikely (!glyf.get_instruction_offsets(start_offset, end_offset, + instruction_start, instruction_end))) + { + DEBUG_MSG(SUBSET, nullptr, "Unable to get instruction offsets for %d", next_glyph); + return false; + } + } + + total += end_offset - start_offset - (*instruction_end - *instruction_start); + /* round2 so short loca will work */ + total += total % 2; + } + + *glyf_size = total; + *use_short_loca = (total <= 131070); + *loca_size = (glyph_ids.len + 1) + * (*use_short_loca ? 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_size, + *use_short_loca ? "short" : "long"); + return true; +} + +static bool +_write_loca_entry (unsigned int id, + unsigned int offset, + bool is_short, + void *loca_prime, + unsigned int loca_size) +{ + unsigned int entry_size = is_short ? sizeof (OT::HBUINT16) : sizeof (OT::HBUINT32); + if ((id + 1) * entry_size <= loca_size) + { + if (is_short) { + ((OT::HBUINT16*) loca_prime) [id].set (offset / 2); + } else { + ((OT::HBUINT32*) loca_prime) [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, + loca_size); + return false; +} + +static void +_update_components (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 (!hb_subset_plan_new_gid_for_old_id (plan, + 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 (hb_subset_plan_t *plan, + const OT::glyf::accelerator_t &glyf, + const char *glyf_data, + bool use_short_loca, + hb_prealloced_array_t<unsigned int> &instruction_ranges, + unsigned int glyf_prime_size, + char *glyf_prime_data /* OUT */, + unsigned int loca_prime_size, + char *loca_prime_data /* OUT */) +{ + hb_prealloced_array_t<hb_codepoint_t> &glyph_ids = plan->gids_to_retain_sorted; + char *glyf_prime_data_next = glyf_prime_data; + + bool success = true; + for (unsigned int i = 0; i < glyph_ids.len; i++) + { + unsigned int start_offset, end_offset; + if (unlikely (!(glyf.get_offsets (glyph_ids[i], &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); + length += length % 2; + + 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 && _write_loca_entry (i, + glyf_prime_data_next - glyf_prime_data, + use_short_loca, + loca_prime_data, + loca_prime_size); + _update_components (plan, glyf_prime_data_next, length); + + glyf_prime_data_next += length; + } + + success = success && _write_loca_entry (glyph_ids.len, + glyf_prime_data_next - glyf_prime_data, + use_short_loca, + loca_prime_data, + loca_prime_size); + 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 /* OUT */, + hb_blob_t **loca_prime /* OUT */) +{ + // TODO(grieger): Sanity check allocation size for the new table. + hb_prealloced_array_t<hb_codepoint_t> &glyphs_to_retain = plan->gids_to_retain_sorted; + + unsigned int glyf_prime_size; + unsigned int loca_prime_size; + hb_prealloced_array_t<unsigned int> instruction_ranges; + instruction_ranges.init(); + + if (unlikely (!_calculate_glyf_and_loca_prime_size (glyf, + glyphs_to_retain, + plan->drop_hints, + use_short_loca, + &glyf_prime_size, + &loca_prime_size, + &instruction_ranges))) { + instruction_ranges.finish(); + return false; + } + + char *glyf_prime_data = (char *) calloc (1, glyf_prime_size); + char *loca_prime_data = (char *) calloc (1, loca_prime_size); + if (unlikely (!_write_glyf_and_loca_prime (plan, glyf, glyf_data, + *use_short_loca, + instruction_ranges, + glyf_prime_size, glyf_prime_data, + loca_prime_size, loca_prime_data))) { + free (glyf_prime_data); + free (loca_prime_data); + instruction_ranges.finish(); + return false; + } + instruction_ranges.finish(); + + *glyf_prime = hb_blob_create (glyf_prime_data, + glyf_prime_size, + HB_MEMORY_MODE_READONLY, + glyf_prime_data, + free); + *loca_prime = hb_blob_create (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 = OT::Sanitizer<OT::glyf>().sanitize (plan->source->reference_table (HB_OT_TAG_glyf)); + 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; +} diff --git a/chromium/third_party/harfbuzz-ng/src/src/hb-subset-glyf.hh b/chromium/third_party/harfbuzz-ng/src/src/hb-subset-glyf.hh new file mode 100644 index 00000000000..99b76db9bbe --- /dev/null +++ b/chromium/third_party/harfbuzz-ng/src/src/hb-subset-glyf.hh @@ -0,0 +1,40 @@ +/* + * 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 + */ + +#ifndef HB_SUBSET_GLYF_HH +#define HB_SUBSET_GLYF_HH + +#include "hb-private.hh" + +#include "hb-subset-plan.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 */); + +#endif /* HB_SUBSET_GLYF_HH */ diff --git a/chromium/third_party/harfbuzz-ng/src/src/hb-subset-input.cc b/chromium/third_party/harfbuzz-ng/src/src/hb-subset-input.cc new file mode 100644 index 00000000000..c4003dd3ad1 --- /dev/null +++ b/chromium/third_party/harfbuzz-ng/src/src/hb-subset-input.cc @@ -0,0 +1,119 @@ +/* + * 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, Rod Sheeter, Behdad Esfahbod + */ + +#include "hb-object-private.hh" +#include "hb-subset-private.hh" +#include "hb-set-private.hh" + +/** + * hb_subset_input_create_or_fail: + * + * Return value: New subset input. + * + * Since: 1.8.0 + **/ +hb_subset_input_t * +hb_subset_input_create_or_fail (void) +{ + hb_subset_input_t *input = hb_object_create<hb_subset_input_t>(); + + if (unlikely (!input)) + return nullptr; + + input->unicodes = hb_set_create (); + input->glyphs = hb_set_create (); + + return input; +} + +/** + * hb_subset_input_reference: (skip) + * @subset_input: a subset_input. + * + * + * + * Return value: + * + * Since: 1.8.0 + **/ +hb_subset_input_t * +hb_subset_input_reference (hb_subset_input_t *subset_input) +{ + return hb_object_reference (subset_input); +} + +/** + * hb_subset_input_destroy: + * @subset_input: a subset_input. + * + * Since: 1.8.0 + **/ +void +hb_subset_input_destroy(hb_subset_input_t *subset_input) +{ + if (!hb_object_destroy (subset_input)) return; + + hb_set_destroy (subset_input->unicodes); + hb_set_destroy (subset_input->glyphs); + + free (subset_input); +} + +/** + * hb_subset_input_unicode_set: + * @subset_input: a subset_input. + * + * Since: 1.8.0 + **/ +HB_EXTERN hb_set_t * +hb_subset_input_unicode_set (hb_subset_input_t *subset_input) +{ + return subset_input->unicodes; +} + +/** + * hb_subset_input_glyph_set: + * @subset_input: a subset_input. + * + * Since: 1.8.0 + **/ +HB_EXTERN hb_set_t * +hb_subset_input_glyph_set (hb_subset_input_t *subset_input) +{ + return subset_input->glyphs; +} + +/** + * hb_subset_input_drop_hints: + * @subset_input: a subset_input. + * + * Since: 1.8.0 + **/ +HB_EXTERN hb_bool_t * +hb_subset_input_drop_hints (hb_subset_input_t *subset_input) +{ + return &subset_input->drop_hints; +} diff --git a/chromium/third_party/harfbuzz-ng/src/src/hb-subset-plan.cc b/chromium/third_party/harfbuzz-ng/src/src/hb-subset-plan.cc new file mode 100644 index 00000000000..f8a09efe4d1 --- /dev/null +++ b/chromium/third_party/harfbuzz-ng/src/src/hb-subset-plan.cc @@ -0,0 +1,227 @@ +/* + * 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-subset-private.hh" + +#include "hb-subset-plan.hh" +#include "hb-ot-cmap-table.hh" +#include "hb-ot-glyf-table.hh" + +static int +_hb_codepoint_t_cmp (const void *pa, const void *pb) +{ + hb_codepoint_t a = * (hb_codepoint_t *) pa; + hb_codepoint_t b = * (hb_codepoint_t *) pb; + + return a < b ? -1 : a > b ? +1 : 0; +} + +hb_bool_t +hb_subset_plan_new_gid_for_codepoint (hb_subset_plan_t *plan, + hb_codepoint_t codepoint, + hb_codepoint_t *new_gid) +{ + // TODO actual map, delete this garbage. + for (unsigned int i = 0; i < plan->codepoints.len; i++) + { + if (plan->codepoints[i] != codepoint) continue; + if (!hb_subset_plan_new_gid_for_old_id(plan, plan->gids_to_retain[i], new_gid)) + { + return false; + } + return true; + } + return false; +} + +hb_bool_t +hb_subset_plan_new_gid_for_old_id (hb_subset_plan_t *plan, + hb_codepoint_t old_gid, + hb_codepoint_t *new_gid) +{ + // the index in old_gids is the new gid; only up to codepoints.len are valid + for (unsigned int i = 0; i < plan->gids_to_retain_sorted.len; i++) + { + if (plan->gids_to_retain_sorted[i] == old_gid) + { + *new_gid = i; + return true; + } + } + return false; +} + +hb_bool_t +hb_subset_plan_add_table (hb_subset_plan_t *plan, + hb_tag_t tag, + hb_blob_t *contents) +{ + hb_blob_t *source_blob = plan->source->reference_table (tag); + DEBUG_MSG(SUBSET, nullptr, "add table %c%c%c%c, dest %d bytes, source %d bytes", HB_UNTAG(tag), hb_blob_get_length (contents), hb_blob_get_length (source_blob)); + hb_blob_destroy (source_blob); + return hb_subset_face_add_table(plan->dest, tag, contents); +} + +static void +_populate_codepoints (hb_set_t *input_codepoints, + hb_prealloced_array_t<hb_codepoint_t>& plan_codepoints) +{ + plan_codepoints.alloc (hb_set_get_population (input_codepoints)); + hb_codepoint_t cp = -1; + while (hb_set_next (input_codepoints, &cp)) { + hb_codepoint_t *wr = plan_codepoints.push(); + *wr = cp; + } + plan_codepoints.qsort (_hb_codepoint_t_cmp); +} + +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 +_populate_gids_to_retain (hb_face_t *face, + hb_prealloced_array_t<hb_codepoint_t>& codepoints, + hb_prealloced_array_t<hb_codepoint_t>& old_gids, + hb_prealloced_array_t<hb_codepoint_t>& old_gids_sorted) +{ + OT::cmap::accelerator_t cmap; + OT::glyf::accelerator_t glyf; + cmap.init (face); + glyf.init (face); + + hb_auto_array_t<unsigned int> bad_indices; + + old_gids.alloc (codepoints.len); + for (unsigned int i = 0; i < codepoints.len; i++) + { + hb_codepoint_t gid; + if (!cmap.get_nominal_glyph (codepoints[i], &gid)) + { + gid = -1; + *(bad_indices.push ()) = i; + } + *(old_gids.push ()) = gid; + } + + /* Generally there shouldn't be any */ + while (bad_indices.len > 0) + { + unsigned int i = bad_indices[bad_indices.len - 1]; + bad_indices.pop (); + DEBUG_MSG(SUBSET, nullptr, "Drop U+%04X; no gid", codepoints[i]); + codepoints.remove (i); + old_gids.remove (i); + } + + // Populate a full set of glyphs to retain by adding all referenced + // composite glyphs. + // TODO expand with glyphs reached by G* + hb_set_t * all_gids_to_retain = hb_set_create (); + _add_gid_and_children (glyf, 0, all_gids_to_retain); + for (unsigned int i = 0; i < old_gids.len; i++) + _add_gid_and_children (glyf, old_gids[i], all_gids_to_retain); + + // Transfer to a sorted list. + old_gids_sorted.alloc (hb_set_get_population (all_gids_to_retain)); + hb_codepoint_t gid = HB_SET_VALUE_INVALID; + while (hb_set_next (all_gids_to_retain, &gid)) + *(old_gids_sorted.push ()) = gid; + + hb_set_destroy (all_gids_to_retain); + glyf.fini (); + cmap.fini (); +} + +/** + * hb_subset_plan_create: + * Computes a plan for subsetting the supplied face according + * to a provide profile and input. The plan describes + * which tables and glyphs should be retained. + * + * Return value: New subset plan. + * + * Since: 1.7.5 + **/ +hb_subset_plan_t * +hb_subset_plan_create (hb_face_t *face, + hb_subset_profile_t *profile, + hb_subset_input_t *input) +{ + hb_subset_plan_t *plan = hb_object_create<hb_subset_plan_t> (); + + plan->codepoints.init(); + plan->gids_to_retain.init(); + plan->gids_to_retain_sorted.init(); + plan->source = hb_face_reference (face); + plan->dest = hb_subset_face_create (); + plan->drop_hints = input->drop_hints; + + _populate_codepoints (input->unicodes, plan->codepoints); + _populate_gids_to_retain (face, + plan->codepoints, + plan->gids_to_retain, + plan->gids_to_retain_sorted); + + return plan; +} + +/** + * hb_subset_plan_destroy: + * + * Since: 1.7.5 + **/ +void +hb_subset_plan_destroy (hb_subset_plan_t *plan) +{ + if (!hb_object_destroy (plan)) return; + + plan->codepoints.finish (); + plan->gids_to_retain.finish (); + plan->gids_to_retain_sorted.finish (); + + hb_face_destroy (plan->source); + hb_face_destroy (plan->dest); + + free (plan); +} diff --git a/chromium/third_party/harfbuzz-ng/src/hb-subset-plan.hh b/chromium/third_party/harfbuzz-ng/src/src/hb-subset-plan.hh index a74152858ba..d1b66b44d54 100644 --- a/chromium/third_party/harfbuzz-ng/src/hb-subset-plan.hh +++ b/chromium/third_party/harfbuzz-ng/src/src/hb-subset-plan.hh @@ -37,6 +37,8 @@ struct hb_subset_plan_t { hb_object_header_t header; ASSERT_POD (); + hb_bool_t drop_hints; + // TODO(Q1) actual map, drop this crap // Look at me ma, I'm a poor mans map codepoint : new gid // codepoints is sorted and aligned with gids_to_retain. diff --git a/chromium/third_party/harfbuzz-ng/src/src/hb-subset-private.hh b/chromium/third_party/harfbuzz-ng/src/src/hb-subset-private.hh new file mode 100644 index 00000000000..5fa72527671 --- /dev/null +++ b/chromium/third_party/harfbuzz-ng/src/src/hb-subset-private.hh @@ -0,0 +1,62 @@ +/* + * Copyright © 2018 Google, Inc. + * + * This is part of HarfBuzz, a text shaping library. + * + * Permission is hereby granted, without written agreement and without + * license or royalty fees, to use, copy, modify, and distribute this + * software and its documentation for any purpose, provided that the + * above copyright notice and the following two paragraphs appear in + * all copies of this software. + * + * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR + * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES + * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN + * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, + * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS + * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO + * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + * + * Google Author(s): Garret Rieger, Roderick Sheeter + */ + +#ifndef HB_SUBSET_PRIVATE_HH +#define HB_SUBSET_PRIVATE_HH + + +#include "hb-private.hh" + +#include "hb-subset.h" + +#include "hb-font-private.hh" + +typedef struct hb_subset_face_data_t hb_subset_face_data_t; + +struct hb_subset_input_t { + hb_object_header_t header; + ASSERT_POD (); + + hb_set_t *unicodes; + hb_set_t *glyphs; + + hb_bool_t drop_hints; + /* TODO + * + * features + * lookups + * nameIDs + * ... + */ +}; + +HB_INTERNAL hb_face_t * +hb_subset_face_create (void); + +HB_INTERNAL hb_bool_t +hb_subset_face_add_table (hb_face_t *face, hb_tag_t tag, hb_blob_t *blob); + +#endif /* HB_SUBSET_PRIVATE_HH */ diff --git a/chromium/third_party/harfbuzz-ng/src/src/hb-subset.cc b/chromium/third_party/harfbuzz-ng/src/src/hb-subset.cc new file mode 100644 index 00000000000..30cba3fcac0 --- /dev/null +++ b/chromium/third_party/harfbuzz-ng/src/src/hb-subset.cc @@ -0,0 +1,368 @@ +/* + * 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, Rod Sheeter, Behdad Esfahbod + */ + +#include "hb-private.hh" +#include "hb-object-private.hh" +#include "hb-open-type-private.hh" + +#include "hb-subset-glyf.hh" +#include "hb-subset-private.hh" +#include "hb-subset-plan.hh" + +#include "hb-open-file-private.hh" +#include "hb-ot-cmap-table.hh" +#include "hb-ot-glyf-table.hh" +#include "hb-ot-hdmx-table.hh" +#include "hb-ot-head-table.hh" +#include "hb-ot-hhea-table.hh" +#include "hb-ot-hmtx-table.hh" +#include "hb-ot-maxp-table.hh" +#include "hb-ot-os2-table.hh" +#include "hb-ot-post-table.hh" + + +#ifndef HB_NO_VISIBILITY +const void * const OT::_hb_NullPool[HB_NULL_POOL_SIZE / sizeof (void *)] = {}; +#endif + + +struct hb_subset_profile_t { + hb_object_header_t header; + ASSERT_POD (); +}; + +/** + * hb_subset_profile_create: + * + * Return value: New profile with default settings. + * + * Since: 1.8.0 + **/ +hb_subset_profile_t * +hb_subset_profile_create () +{ + return hb_object_create<hb_subset_profile_t>(); +} + +/** + * hb_subset_profile_destroy: + * + * Since: 1.8.0 + **/ +void +hb_subset_profile_destroy (hb_subset_profile_t *profile) +{ + if (!hb_object_destroy (profile)) return; + + free (profile); +} + +template<typename TableType> +static bool +_subset (hb_subset_plan_t *plan) +{ + OT::Sanitizer<TableType> sanitizer; + + hb_blob_t *source_blob = sanitizer.sanitize (plan->source->reference_table (TableType::tableTag)); + const TableType *table = OT::Sanitizer<TableType>::lock_instance (source_blob); + + hb_bool_t result = false; + if (table != &OT::Null(TableType)) + result = table->subset(plan); + + hb_blob_destroy (source_blob); + hb_tag_t tag = TableType::tableTag; + DEBUG_MSG(SUBSET, nullptr, "OT::%c%c%c%c::subset %s", HB_UNTAG(tag), result ? "success" : "FAILED!"); + return result; +} + + +/* + * A face that has add_table(). + */ + +struct hb_subset_face_data_t +{ + struct table_entry_t + { + inline int cmp (const hb_tag_t *t) const + { + if (*t < tag) return -1; + if (*t > tag) return -1; + return 0; + } + + hb_tag_t tag; + hb_blob_t *blob; + }; + + hb_prealloced_array_t<table_entry_t, 32> tables; +}; + +static hb_subset_face_data_t * +_hb_subset_face_data_create (void) +{ + hb_subset_face_data_t *data = (hb_subset_face_data_t *) calloc (1, sizeof (hb_subset_face_data_t)); + if (unlikely (!data)) + return nullptr; + + return data; +} + +static void +_hb_subset_face_data_destroy (void *user_data) +{ + hb_subset_face_data_t *data = (hb_subset_face_data_t *) user_data; + + for (unsigned int i = 0; i < data->tables.len; i++) + hb_blob_destroy (data->tables[i].blob); + + data->tables.finish (); + + free (data); +} + +static hb_blob_t * +_hb_subset_face_data_reference_blob (hb_subset_face_data_t *data) +{ + + unsigned int table_count = data->tables.len; + unsigned int face_length = table_count * 16 + 12; + + for (unsigned int i = 0; i < table_count; i++) + face_length += _hb_ceil_to_4 (hb_blob_get_length (data->tables.array[i].blob)); + + char *buf = (char *) malloc (face_length); + if (unlikely (!buf)) + return nullptr; + + OT::hb_serialize_context_t c (buf, face_length); + OT::OpenTypeFontFile *f = c.start_serialize<OT::OpenTypeFontFile> (); + + bool is_cff = data->tables.lsearch (HB_TAG ('C','F','F',' ')) || data->tables.lsearch (HB_TAG ('C','F','F','2')); + hb_tag_t sfnt_tag = is_cff ? OT::OpenTypeFontFile::CFFTag : OT::OpenTypeFontFile::TrueTypeTag; + + OT::Supplier<hb_tag_t> tags_supplier (&data->tables[0].tag, table_count, sizeof (data->tables[0])); + OT::Supplier<hb_blob_t *> blobs_supplier (&data->tables[0].blob, table_count, sizeof (data->tables[0])); + bool ret = f->serialize_single (&c, + sfnt_tag, + tags_supplier, + blobs_supplier, + table_count); + + c.end_serialize (); + + if (unlikely (!ret)) + { + free (buf); + return nullptr; + } + + return hb_blob_create (buf, face_length, HB_MEMORY_MODE_WRITABLE, buf, free); +} + +static hb_blob_t * +_hb_subset_face_reference_table (hb_face_t *face, hb_tag_t tag, void *user_data) +{ + hb_subset_face_data_t *data = (hb_subset_face_data_t *) user_data; + + if (!tag) + return _hb_subset_face_data_reference_blob (data); + + hb_subset_face_data_t::table_entry_t *entry = data->tables.lsearch (tag); + if (entry) + return hb_blob_reference (entry->blob); + + return nullptr; +} + +/* TODO: Move this to hb-face.h and rename to hb_face_builder_create() + * with hb_face_builder_add_table(). */ +hb_face_t * +hb_subset_face_create (void) +{ + hb_subset_face_data_t *data = _hb_subset_face_data_create (); + if (unlikely (!data)) return hb_face_get_empty (); + + return hb_face_create_for_tables (_hb_subset_face_reference_table, + data, + _hb_subset_face_data_destroy); +} + +hb_bool_t +hb_subset_face_add_table (hb_face_t *face, hb_tag_t tag, hb_blob_t *blob) +{ + if (unlikely (face->destroy != _hb_subset_face_data_destroy)) + return false; + + hb_subset_face_data_t *data = (hb_subset_face_data_t *) face->user_data; + hb_subset_face_data_t::table_entry_t *entry = data->tables.push (); + if (unlikely (!entry)) + return false; + + entry->tag = tag; + entry->blob = hb_blob_reference (blob); + + return true; +} + +static bool +_subset_table (hb_subset_plan_t *plan, + hb_tag_t tag) +{ + DEBUG_MSG(SUBSET, nullptr, "begin subset %c%c%c%c", HB_UNTAG(tag)); + bool result = true; + switch (tag) { + case HB_OT_TAG_glyf: + result = _subset<const OT::glyf> (plan); + break; + case HB_OT_TAG_hdmx: + result = _subset<const OT::hdmx> (plan); + break; + case HB_OT_TAG_head: + // TODO that won't work well if there is no glyf + DEBUG_MSG(SUBSET, nullptr, "skip head, handled by glyf"); + result = true; + break; + case HB_OT_TAG_hhea: + DEBUG_MSG(SUBSET, nullptr, "skip hhea handled by hmtx"); + return true; + case HB_OT_TAG_hmtx: + result = _subset<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); + break; + case HB_OT_TAG_maxp: + result = _subset<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); + break; + case HB_OT_TAG_os2: + result = _subset<const OT::os2> (plan); + break; + case HB_OT_TAG_post: + result = _subset<const OT::post> (plan); + break; + default: + hb_blob_t *source_table = hb_face_reference_table(plan->source, tag); + if (likely (source_table)) + result = hb_subset_plan_add_table(plan, tag, source_table); + else + result = false; + hb_blob_destroy (source_table); + break; + } + DEBUG_MSG(SUBSET, nullptr, "subset %c%c%c%c %s", HB_UNTAG(tag), result ? "ok" : "FAILED"); + return result; +} + +static bool +_should_drop_table(hb_subset_plan_t *plan, hb_tag_t tag) +{ + switch (tag) { + case HB_TAG ('c', 'v', 'a', 'r'): /* hint table, fallthrough */ + case HB_TAG ('c', 'v', 't', ' '): /* hint table, fallthrough */ + case HB_TAG ('f', 'p', 'g', 'm'): /* hint table, fallthrough */ + case HB_TAG ('p', 'r', 'e', 'p'): /* hint table, fallthrough */ + case HB_TAG ('h', 'd', 'm', 'x'): /* hint table, fallthrough */ + case HB_TAG ('V', 'D', 'M', 'X'): /* hint table, fallthrough */ + return plan->drop_hints; + // Drop Layout Tables until subsetting is supported. + case HB_TAG ('G', 'D', 'E', 'F'): /* temporary */ + case HB_TAG ('G', 'P', 'O', 'S'): /* temporary */ + case HB_TAG ('G', 'S', 'U', 'B'): /* temporary */ + // 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'): + return true; + default: + return false; + } +} + +/** + * hb_subset: + * @source: font face data to be subset. + * @profile: profile to use for the subsetting. + * @input: input to use for the subsetting. + * + * Subsets a font according to provided profile and input. + **/ +hb_face_t * +hb_subset (hb_face_t *source, + hb_subset_profile_t *profile, + hb_subset_input_t *input) +{ + if (unlikely (!profile || !input || !source)) return hb_face_get_empty(); + + hb_subset_plan_t *plan = hb_subset_plan_create (source, profile, input); + + hb_tag_t table_tags[32]; + unsigned int offset = 0, count; + bool success = true; + 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)) + { + DEBUG_MSG(SUBSET, nullptr, "drop %c%c%c%c", HB_UNTAG(tag)); + continue; + } + success = success && _subset_table (plan, tag); + } + } while (count == ARRAY_LENGTH (table_tags)); + + hb_face_t *result = success ? hb_face_reference(plan->dest) : hb_face_get_empty(); + hb_subset_plan_destroy (plan); + return result; +} diff --git a/chromium/third_party/harfbuzz-ng/src/hb-subset.h b/chromium/third_party/harfbuzz-ng/src/src/hb-subset.h index de7759b22f9..55ce25b0a1a 100644 --- a/chromium/third_party/harfbuzz-ng/src/hb-subset.h +++ b/chromium/third_party/harfbuzz-ng/src/src/hb-subset.h @@ -68,6 +68,8 @@ 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_bool_t * +hb_subset_input_drop_hints (hb_subset_input_t *subset_input); /* hb_subset() */ diff --git a/chromium/third_party/harfbuzz-ng/src/hb-ucdn.cc b/chromium/third_party/harfbuzz-ng/src/src/hb-ucdn.cc index 9515bda2567..9515bda2567 100644 --- a/chromium/third_party/harfbuzz-ng/src/hb-ucdn.cc +++ b/chromium/third_party/harfbuzz-ng/src/src/hb-ucdn.cc diff --git a/chromium/third_party/harfbuzz-ng/src/src/hb-ucdn/COPYING b/chromium/third_party/harfbuzz-ng/src/src/hb-ucdn/COPYING new file mode 100644 index 00000000000..be5205c658d --- /dev/null +++ b/chromium/third_party/harfbuzz-ng/src/src/hb-ucdn/COPYING @@ -0,0 +1,13 @@ +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/chromium/third_party/harfbuzz-ng/src/src/hb-ucdn/Makefile.am b/chromium/third_party/harfbuzz-ng/src/src/hb-ucdn/Makefile.am new file mode 100644 index 00000000000..73b55025477 --- /dev/null +++ b/chromium/third_party/harfbuzz-ng/src/src/hb-ucdn/Makefile.am @@ -0,0 +1,16 @@ +## 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/chromium/third_party/harfbuzz-ng/src/src/hb-ucdn/Makefile.sources b/chromium/third_party/harfbuzz-ng/src/src/hb-ucdn/Makefile.sources new file mode 100644 index 00000000000..cb823b60595 --- /dev/null +++ b/chromium/third_party/harfbuzz-ng/src/src/hb-ucdn/Makefile.sources @@ -0,0 +1,7 @@ +NULL = + +LIBHB_UCDN_sources = \ + ucdn.h \ + ucdn.c \ + ucdn_db.h \ + $(NULL) diff --git a/chromium/third_party/harfbuzz-ng/src/src/hb-ucdn/README b/chromium/third_party/harfbuzz-ng/src/src/hb-ucdn/README new file mode 100644 index 00000000000..2203ae69a33 --- /dev/null +++ b/chromium/third_party/harfbuzz-ng/src/src/hb-ucdn/README @@ -0,0 +1,40 @@ +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/chromium/third_party/harfbuzz-ng/src/src/hb-ucdn/ucdn.c b/chromium/third_party/harfbuzz-ng/src/src/hb-ucdn/ucdn.c new file mode 100644 index 00000000000..30747fea251 --- /dev/null +++ b/chromium/third_party/harfbuzz-ng/src/src/hb-ucdn/ucdn.c @@ -0,0 +1,360 @@ +/* + * 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/chromium/third_party/harfbuzz-ng/src/src/hb-ucdn/ucdn.h b/chromium/third_party/harfbuzz-ng/src/src/hb-ucdn/ucdn.h new file mode 100644 index 00000000000..2d5fc359161 --- /dev/null +++ b/chromium/third_party/harfbuzz-ng/src/src/hb-ucdn/ucdn.h @@ -0,0 +1,453 @@ +/* + * 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> +#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_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); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/chromium/third_party/harfbuzz-ng/src/src/hb-ucdn/ucdn_db.h b/chromium/third_party/harfbuzz-ng/src/src/hb-ucdn/ucdn_db.h new file mode 100644 index 00000000000..8d2d8de3766 --- /dev/null +++ b/chromium/third_party/harfbuzz-ng/src/src/hb-ucdn/ucdn_db.h @@ -0,0 +1,5540 @@ +/* this file was generated by makeunicodedata.py 3.2 */ + +#define UNIDATA_VERSION "10.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}, + {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}, + {12, 230, 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, 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}, + {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}, + {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}, + {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}, + {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}, + {7, 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}, + {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}, + {5, 0, 0, 5, 23, 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}, + {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}, + {15, 0, 11, 5, 6, 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, 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}, + {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}, + {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, 141, 12}, + {12, 0, 13, 5, 141, 21}, + {10, 0, 0, 5, 141, 21}, + {12, 9, 13, 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, 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}, + {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}, + {7, 0, 0, 5, 98, 12}, + {10, 0, 0, 5, 98, 21}, + {12, 0, 13, 5, 98, 21}, + {6, 0, 0, 5, 98, 12}, + {6, 0, 0, 2, 137, 5}, + {6, 0, 0, 2, 139, 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, 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}, + {13, 0, 3, 5, 132, 11}, + {21, 0, 3, 5, 132, 0}, + {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 364 +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}, + {8764, 8765}, + {8765, 8764}, + {8771, 8909}, + {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}, + {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}, + {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}, + {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}, + {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}, + {10877, 10878}, + {10878, 10877}, + {10879, 10880}, + {10880, 10879}, + {10881, 10882}, + {10882, 10881}, + {10883, 10884}, + {10884, 10883}, + {10891, 10892}, + {10892, 10891}, + {10897, 10898}, + {10898, 10897}, + {10899, 10900}, + {10900, 10899}, + {10901, 10902}, + {10902, 10901}, + {10903, 10904}, + {10904, 10903}, + {10905, 10906}, + {10906, 10905}, + {10907, 10908}, + {10908, 10907}, + {10913, 10914}, + {10914, 10913}, + {10918, 10919}, + {10919, 10918}, + {10920, 10921}, + {10921, 10920}, + {10922, 10923}, + {10923, 10922}, + {10924, 10925}, + {10925, 10924}, + {10927, 10928}, + {10928, 10927}, + {10931, 10932}, + {10932, 10931}, + {10939, 10940}, + {10940, 10939}, + {10941, 10942}, + {10942, 10941}, + {10943, 10944}, + {10944, 10943}, + {10945, 10946}, + {10946, 10945}, + {10947, 10948}, + {10948, 10947}, + {10949, 10950}, + {10950, 10949}, + {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}, + {10999, 11000}, + {11000, 10999}, + {11001, 11002}, + {11002, 11001}, + {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_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, 94, 96, + 97, 98, 99, 100, 101, 102, 103, 104, 94, 105, 94, 106, 107, 94, 94, 108, + 108, 108, 109, 110, 111, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 112, + 112, 113, 114, 115, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, + 94, 94, 116, 117, 118, 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, + 94, 94, 94, 119, 119, 120, 121, 94, 94, 94, 122, 123, 123, 123, 123, 123, + 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, + 123, 123, 123, 123, 124, 123, 123, 125, 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, 94, 94, 94, 94, 94, 94, 94, 126, 127, 128, 94, 94, 94, + 94, 94, 94, 94, 94, 94, 129, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, + 94, 94, 94, 94, 94, 94, 94, 94, 130, 131, 132, 133, 134, 135, 136, 137, + 138, 138, 139, 94, 94, 94, 94, 94, 140, 94, 94, 94, 94, 94, 94, 94, 141, + 142, 94, 94, 94, 94, 143, 94, 144, 145, 146, 147, 148, 149, 150, 151, + 152, 153, 154, 154, 154, 154, 154, 155, 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, 156, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 157, 158, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 159, 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, 160, 161, 161, 161, 161, 161, + 161, 161, 161, 161, 161, 161, 161, 52, 52, 162, 161, 161, 161, 161, 163, + 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, + 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, + 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, + 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, + 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, + 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, + 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, + 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, + 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, + 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, + 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, + 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, + 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, + 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, + 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, + 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, + 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, + 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, + 161, 161, 161, 163, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 94, + 94, 94, 94, 94, 94, 94, 94, 94, 94, 164, 165, 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, 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, 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, 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, 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, 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, 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, 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, 94, + 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 74, 74, 74, 74, 74, + 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, + 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, + 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, + 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, + 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, + 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, + 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, + 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, + 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, + 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, + 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, + 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, + 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, + 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 166, 74, + 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, + 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, + 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, + 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, + 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, + 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, + 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, + 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, + 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, + 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, + 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, + 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, + 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, + 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, + 74, 74, 166, +}; + +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, 111, + 111, 111, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 121, + 121, 122, 123, 120, 124, 125, 126, 127, 128, 128, 128, 128, 129, 130, + 131, 132, 133, 134, 135, 128, 128, 128, 128, 128, 128, 128, 128, 128, + 128, 128, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 145, 145, + 146, 147, 148, 149, 128, 128, 128, 128, 128, 128, 150, 150, 150, 150, + 151, 152, 153, 120, 154, 155, 156, 156, 156, 157, 158, 159, 160, 160, + 161, 162, 163, 164, 165, 166, 167, 167, 167, 168, 145, 169, 120, 120, + 120, 120, 120, 120, 128, 128, 170, 171, 120, 120, 172, 126, 173, 174, + 175, 176, 177, 178, 178, 178, 178, 178, 178, 179, 180, 181, 182, 178, + 183, 184, 185, 178, 186, 187, 188, 189, 189, 190, 191, 192, 193, 194, + 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 204, 205, 206, 207, + 208, 209, 210, 211, 212, 213, 214, 120, 215, 216, 217, 218, 218, 219, + 220, 221, 222, 223, 224, 120, 225, 226, 227, 228, 229, 230, 231, 232, + 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 120, 243, 244, + 245, 246, 247, 244, 248, 249, 250, 251, 252, 120, 253, 254, 255, 256, + 257, 258, 259, 260, 260, 259, 260, 261, 262, 263, 264, 265, 266, 267, + 120, 268, 269, 270, 271, 272, 272, 271, 273, 274, 275, 276, 277, 278, + 279, 280, 281, 120, 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, 120, 307, 308, 308, 308, 308, 308, + 309, 310, 311, 312, 313, 314, 120, 120, 120, 120, 315, 316, 317, 318, + 319, 320, 321, 322, 323, 324, 325, 326, 120, 120, 120, 120, 327, 328, + 329, 330, 331, 332, 333, 334, 335, 336, 335, 335, 335, 337, 338, 339, + 340, 341, 342, 343, 342, 342, 342, 344, 345, 346, 347, 348, 120, 120, + 120, 120, 349, 349, 349, 349, 349, 350, 351, 352, 353, 354, 355, 356, + 357, 358, 359, 349, 360, 361, 353, 362, 363, 363, 363, 363, 364, 365, + 366, 366, 366, 366, 366, 367, 368, 368, 368, 368, 368, 368, 368, 368, + 368, 368, 368, 368, 369, 369, 369, 369, 369, 369, 369, 369, 369, 370, + 370, 370, 370, 370, 370, 370, 370, 370, 370, 370, 371, 371, 371, 371, + 371, 371, 371, 371, 371, 372, 373, 372, 371, 371, 371, 371, 371, 372, + 371, 371, 371, 371, 372, 373, 372, 371, 373, 371, 371, 371, 371, 371, + 371, 371, 372, 371, 371, 371, 371, 371, 371, 371, 371, 374, 375, 376, + 377, 378, 371, 371, 379, 380, 381, 381, 381, 381, 381, 381, 381, 381, + 381, 381, 382, 383, 384, 385, 385, 385, 385, 385, 385, 385, 385, 385, + 385, 385, 385, 385, 385, 385, 385, 385, 385, 385, 385, 385, 385, 385, + 385, 385, 385, 385, 385, 385, 385, 385, 385, 385, 385, 385, 385, 385, + 385, 385, 385, 385, 385, 385, 385, 385, 385, 385, 385, 385, 385, 385, + 385, 385, 385, 385, 385, 385, 385, 385, 385, 385, 385, 385, 385, 385, + 385, 385, 385, 385, 385, 385, 385, 385, 385, 385, 385, 386, 385, 385, + 387, 388, 388, 389, 390, 390, 390, 390, 390, 390, 390, 390, 390, 391, + 392, 393, 394, 395, 396, 120, 397, 397, 398, 120, 399, 399, 400, 120, + 401, 402, 403, 120, 404, 404, 404, 404, 404, 404, 405, 406, 407, 408, + 409, 410, 411, 412, 413, 414, 415, 416, 417, 418, 419, 419, 419, 419, + 420, 419, 419, 419, 419, 419, 419, 120, 421, 419, 419, 419, 419, 422, + 385, 385, 385, 385, 385, 385, 385, 385, 423, 120, 424, 424, 424, 425, + 426, 427, 428, 429, 430, 431, 432, 432, 432, 433, 434, 120, 435, 435, + 435, 435, 435, 436, 435, 435, 435, 437, 438, 439, 440, 440, 440, 440, + 441, 441, 442, 443, 444, 444, 444, 444, 444, 444, 445, 446, 447, 448, + 449, 450, 451, 452, 451, 452, 453, 454, 455, 456, 120, 120, 120, 120, + 120, 120, 120, 120, 457, 458, 458, 458, 458, 458, 459, 460, 461, 462, + 463, 464, 465, 466, 467, 468, 469, 470, 470, 470, 471, 472, 473, 474, + 475, 475, 475, 475, 476, 477, 478, 479, 480, 480, 480, 480, 481, 482, + 483, 484, 485, 486, 487, 488, 489, 489, 489, 490, 100, 491, 120, 120, + 120, 120, 120, 120, 492, 120, 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, + 120, 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, 120, 120, 120, 580, 617, 120, 120, 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, 688, 580, 689, 617, 120, 120, + 690, 120, 120, 691, 691, 691, 691, 691, 692, 693, 693, 693, 693, 693, + 694, 695, 696, 697, 698, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, + 699, 700, 701, 702, 703, 703, 703, 703, 704, 705, 706, 706, 706, 706, + 706, 706, 706, 707, 708, 709, 371, 371, 373, 120, 373, 373, 373, 373, + 373, 373, 373, 373, 710, 710, 710, 710, 711, 712, 713, 714, 715, 716, + 717, 718, 719, 720, 120, 120, 120, 120, 120, 120, 721, 721, 721, 722, + 721, 721, 721, 721, 721, 721, 721, 721, 721, 721, 723, 120, 721, 721, + 721, 721, 721, 721, 721, 721, 721, 721, 721, 721, 721, 721, 721, 721, + 721, 721, 721, 721, 721, 721, 721, 721, 721, 721, 724, 120, 120, 120, + 725, 726, 727, 728, 729, 730, 731, 732, 733, 734, 735, 736, 737, 737, + 738, 737, 737, 737, 739, 740, 741, 742, 743, 744, 745, 745, 746, 745, + 745, 745, 747, 748, 749, 750, 751, 752, 752, 752, 752, 753, 754, 755, + 755, 755, 755, 755, 755, 755, 755, 755, 755, 756, 757, 758, 752, 752, + 752, 759, 725, 725, 725, 725, 726, 120, 760, 760, 761, 761, 761, 762, + 763, 764, 758, 758, 758, 765, 766, 767, 761, 761, 761, 768, 763, 764, + 758, 758, 758, 758, 769, 767, 758, 770, 771, 771, 771, 771, 771, 772, + 771, 771, 771, 771, 771, 771, 771, 771, 771, 771, 771, 758, 758, 758, + 773, 774, 758, 758, 758, 758, 758, 758, 758, 758, 758, 758, 758, 775, + 758, 758, 758, 773, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, + 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, + 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, + 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, + 776, 776, 777, 778, 580, 580, 580, 580, 580, 580, 580, 580, 776, 776, + 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, + 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 779, + 778, 778, 780, 780, 781, 780, 780, 780, 780, 780, 780, 780, 780, 780, + 780, 780, 780, 780, 780, 780, 780, 780, 780, 780, 780, 780, 780, 780, + 780, 780, 780, 780, 780, 780, 780, 780, 780, 780, 780, 780, 780, 780, + 780, 780, 780, 780, 780, 780, 780, 780, 780, 780, 780, 780, 780, 780, + 780, 780, 780, 780, 780, 780, 780, 780, 780, 780, 780, 780, 780, 780, + 780, 780, 780, 780, 780, 780, 780, 780, 780, 780, 780, 780, 780, 782, + 783, 783, 783, 783, 783, 783, 784, 120, 785, 785, 785, 785, 785, 786, + 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, + 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, + 787, 787, 787, 787, 787, 788, 787, 787, 789, 790, 120, 120, 101, 101, + 101, 101, 101, 791, 792, 793, 101, 101, 101, 794, 795, 795, 795, 795, + 795, 795, 795, 795, 796, 797, 798, 120, 64, 64, 799, 800, 801, 27, 802, + 27, 27, 27, 27, 27, 27, 27, 803, 804, 27, 805, 806, 27, 27, 807, 808, + 120, 120, 120, 120, 120, 120, 120, 809, 810, 811, 812, 813, 813, 814, + 815, 816, 817, 818, 818, 818, 818, 818, 818, 819, 120, 820, 821, 821, + 821, 821, 821, 822, 823, 824, 825, 826, 827, 828, 828, 829, 830, 831, + 832, 833, 833, 834, 835, 836, 836, 837, 838, 839, 840, 368, 368, 368, + 841, 842, 843, 843, 843, 843, 843, 844, 845, 846, 847, 848, 849, 850, + 349, 353, 851, 852, 852, 852, 852, 852, 853, 854, 120, 855, 856, 857, + 858, 349, 349, 859, 860, 861, 861, 861, 861, 861, 861, 862, 863, 864, + 120, 120, 865, 866, 867, 868, 120, 869, 869, 869, 120, 373, 373, 54, 54, + 54, 54, 54, 870, 871, 120, 872, 872, 872, 872, 872, 872, 872, 872, 872, + 872, 866, 866, 866, 866, 873, 874, 875, 876, 877, 878, 878, 879, 878, + 878, 878, 877, 878, 878, 879, 878, 878, 878, 877, 878, 878, 879, 878, + 878, 878, 877, 878, 878, 879, 878, 878, 878, 877, 878, 878, 879, 878, + 878, 878, 877, 878, 878, 879, 878, 878, 878, 877, 878, 878, 879, 878, + 878, 878, 877, 878, 878, 879, 878, 878, 878, 877, 878, 878, 879, 878, + 878, 878, 877, 878, 878, 879, 878, 878, 878, 877, 878, 878, 879, 878, + 878, 878, 877, 878, 878, 879, 878, 878, 878, 877, 878, 878, 879, 878, + 878, 878, 877, 878, 878, 879, 878, 878, 878, 877, 878, 878, 879, 878, + 878, 878, 877, 878, 878, 879, 878, 878, 878, 877, 878, 878, 879, 878, + 878, 878, 877, 878, 878, 879, 878, 878, 878, 877, 878, 878, 879, 878, + 878, 878, 877, 878, 878, 879, 878, 878, 878, 877, 878, 878, 879, 878, + 878, 878, 877, 878, 878, 879, 878, 878, 878, 877, 878, 878, 879, 878, + 878, 878, 877, 878, 878, 879, 878, 878, 878, 877, 878, 878, 879, 878, + 878, 878, 877, 878, 878, 879, 878, 878, 878, 877, 878, 878, 879, 878, + 878, 878, 877, 878, 878, 879, 878, 878, 878, 877, 878, 878, 879, 878, + 878, 878, 877, 878, 878, 879, 878, 878, 878, 877, 878, 878, 879, 878, + 878, 878, 877, 878, 878, 879, 878, 878, 878, 878, 878, 878, 877, 878, + 878, 879, 878, 878, 878, 877, 878, 878, 879, 878, 878, 878, 877, 878, + 878, 880, 120, 369, 369, 881, 882, 370, 370, 370, 370, 370, 883, 884, + 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, + 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, + 884, 884, 884, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, + 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, + 885, 885, 885, 885, 885, 885, 885, 776, 776, 776, 776, 776, 776, 776, + 776, 776, 776, 776, 776, 776, 777, 776, 776, 776, 776, 776, 776, 776, + 776, 776, 776, 776, 776, 776, 886, 778, 778, 778, 778, 887, 120, 888, + 889, 121, 890, 891, 892, 893, 121, 128, 128, 128, 128, 128, 128, 128, + 128, 128, 128, 128, 128, 894, 895, 896, 120, 897, 128, 128, 128, 128, + 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, + 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, + 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 898, 120, + 120, 128, 128, 128, 128, 128, 128, 128, 128, 899, 128, 128, 128, 128, + 128, 128, 120, 120, 120, 120, 120, 128, 900, 901, 901, 902, 903, 904, + 905, 906, 907, 908, 909, 910, 911, 912, 913, 170, 128, 128, 128, 128, + 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 914, 915, + 916, 917, 918, 919, 920, 920, 921, 922, 923, 923, 924, 925, 926, 927, + 928, 928, 928, 928, 929, 930, 930, 930, 931, 932, 932, 932, 933, 934, + 935, 120, 936, 937, 938, 937, 937, 939, 937, 937, 940, 937, 941, 937, + 941, 120, 120, 120, 120, 937, 937, 937, 937, 937, 937, 937, 937, 937, + 937, 937, 937, 937, 937, 937, 942, 943, 944, 944, 944, 944, 944, 945, + 609, 946, 946, 946, 946, 946, 946, 947, 948, 949, 950, 580, 951, 952, + 120, 120, 120, 120, 120, 609, 609, 609, 609, 609, 953, 120, 120, 120, + 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 954, + 954, 954, 955, 956, 956, 956, 956, 956, 956, 957, 120, 958, 959, 959, + 960, 961, 961, 961, 961, 962, 963, 964, 964, 965, 966, 967, 967, 967, + 967, 968, 969, 970, 970, 970, 971, 972, 972, 972, 972, 973, 972, 974, + 120, 120, 120, 120, 120, 975, 975, 975, 975, 975, 976, 976, 976, 976, + 976, 977, 977, 977, 977, 977, 977, 978, 978, 978, 979, 980, 981, 982, + 982, 982, 982, 983, 984, 984, 984, 984, 985, 986, 986, 986, 986, 986, + 120, 987, 987, 987, 987, 987, 987, 988, 989, 120, 120, 120, 120, 120, + 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 990, + 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, + 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, + 990, 990, 990, 990, 990, 990, 990, 990, 990, 991, 120, 990, 990, 992, + 120, 990, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, + 120, 120, 120, 120, 120, 120, 120, 993, 994, 995, 995, 995, 995, 996, + 997, 998, 998, 999, 1000, 1001, 1001, 1002, 1003, 1004, 1004, 1004, 1005, + 1006, 1007, 120, 120, 120, 120, 120, 120, 1008, 1008, 1009, 1010, 1011, + 1011, 1012, 1013, 1014, 1014, 1014, 1015, 120, 120, 120, 120, 120, 120, + 120, 120, 1016, 1016, 1016, 1016, 1017, 1017, 1017, 1018, 1019, 1019, + 1020, 1019, 1019, 1019, 1019, 1019, 1021, 1022, 1023, 1024, 1025, 1025, + 1026, 1027, 1028, 120, 1029, 1030, 1031, 1031, 1031, 1032, 1033, 1033, + 1033, 1034, 120, 120, 120, 120, 1035, 1036, 1035, 1035, 1037, 1038, 1039, + 120, 1040, 1040, 1040, 1040, 1040, 1040, 1041, 1042, 1043, 1043, 1044, + 1045, 1046, 1046, 1047, 1048, 1049, 1049, 1050, 1051, 120, 1052, 120, + 120, 120, 120, 120, 120, 120, 120, 120, 120, 1053, 1053, 1053, 1053, + 1053, 1053, 1053, 1053, 1053, 1054, 120, 120, 120, 120, 120, 120, 1055, + 1055, 1055, 1055, 1055, 1055, 1056, 120, 1057, 1057, 1057, 1057, 1057, + 1057, 1058, 1059, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, + 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, + 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, + 120, 120, 120, 120, 120, 1060, 1060, 1060, 1061, 120, 120, 120, 120, 120, + 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 1062, 1063, 1063, + 1063, 1063, 1063, 1063, 1064, 1065, 1066, 1067, 1068, 1069, 1070, 120, + 1071, 1072, 1073, 1073, 1073, 1073, 1073, 1074, 1075, 1076, 120, 1077, + 1077, 1077, 1078, 1079, 1080, 1081, 1082, 1082, 1082, 1083, 1084, 1085, + 1086, 1087, 120, 1088, 1088, 1088, 1088, 1089, 120, 1090, 1091, 1091, + 1091, 1091, 1091, 1092, 1093, 1094, 1095, 1096, 1097, 1098, 1099, 1100, + 120, 1101, 1101, 1102, 1101, 1101, 1103, 1104, 1105, 120, 120, 120, 120, + 120, 120, 120, 120, 1106, 1107, 1108, 1109, 1108, 1110, 1111, 1111, 1111, + 1111, 1111, 1112, 1113, 1114, 1115, 1116, 1117, 1118, 1119, 1120, 1120, + 1121, 1122, 1123, 1124, 1125, 1126, 1127, 1128, 1129, 1129, 120, 120, + 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, + 120, 1130, 1130, 1130, 1130, 1130, 1130, 1131, 1132, 1133, 1134, 1135, + 1136, 120, 120, 120, 120, 1137, 1137, 1137, 1137, 1137, 1137, 1138, 1139, + 1140, 120, 1141, 1142, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, + 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 1143, 1143, 1143, 1143, + 1143, 1144, 1145, 1146, 1147, 1148, 1149, 1150, 120, 120, 120, 120, 1151, + 1151, 1151, 1151, 1151, 1151, 1152, 1153, 1154, 120, 1155, 1156, 1157, + 1158, 120, 120, 1159, 1159, 1159, 1159, 1159, 1160, 1161, 120, 1162, + 1163, 120, 120, 120, 120, 120, 120, 1164, 1164, 1164, 1165, 1166, 1167, + 1168, 1169, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, + 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, + 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, + 120, 120, 120, 120, 1170, 1170, 1170, 1170, 1171, 1171, 1171, 1171, 1172, + 1173, 1174, 1175, 1176, 1177, 1178, 1178, 1178, 1178, 1179, 1180, 1181, + 120, 1182, 1183, 1184, 1184, 1184, 1184, 1185, 1186, 1187, 1188, 1189, + 120, 120, 120, 1190, 1190, 1190, 1190, 1190, 1190, 1190, 1191, 1192, + 1193, 1192, 1192, 1192, 1194, 1195, 1196, 1197, 120, 1198, 1199, 1200, + 1201, 1202, 1203, 1203, 1203, 1204, 1205, 1205, 1206, 1207, 120, 120, + 120, 120, 120, 120, 120, 120, 120, 1208, 1209, 1210, 1210, 1210, 1210, + 1211, 1212, 1213, 120, 1214, 1215, 120, 120, 120, 120, 120, 120, 120, + 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 1216, + 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, + 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, + 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, + 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, + 1216, 1216, 1217, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, + 120, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, 1218, + 1218, 1218, 1219, 1220, 120, 1216, 1216, 1216, 1216, 1216, 1216, 1216, + 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, 1216, + 1216, 1216, 1216, 1216, 1216, 1221, 120, 120, 120, 120, 120, 120, 120, + 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, + 120, 120, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, + 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, + 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, + 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1223, 1222, 1222, + 1222, 1222, 1224, 1225, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, + 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, + 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1226, 1222, 1222, + 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, + 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1227, 120, 120, 120, 120, 120, + 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, + 120, 120, 120, 120, 120, 120, 120, 1228, 1228, 1228, 1228, 1228, 1228, + 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, + 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, + 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, + 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, + 1228, 1228, 1228, 1229, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, + 1228, 1228, 1228, 1228, 1228, 1228, 1230, 120, 120, 120, 120, 120, 120, + 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, + 120, 120, 120, 795, 795, 795, 795, 795, 795, 795, 795, 795, 795, 795, + 795, 795, 795, 795, 795, 795, 795, 795, 795, 795, 795, 795, 795, 795, + 795, 795, 795, 795, 795, 795, 795, 795, 795, 795, 795, 795, 795, 795, + 1231, 1232, 1232, 1232, 1233, 1234, 1235, 120, 120, 120, 120, 120, 120, + 120, 120, 120, 120, 120, 120, 1236, 1236, 1236, 1237, 1238, 120, 1239, + 1239, 1239, 1239, 1239, 1239, 1240, 1241, 1242, 120, 1243, 1244, 1245, + 1239, 1239, 1246, 1239, 1239, 120, 120, 120, 120, 120, 120, 120, 120, + 120, 120, 120, 120, 120, 120, 1247, 1247, 1247, 1247, 1247, 1247, 1247, + 1247, 1248, 120, 1249, 1250, 1250, 1250, 1250, 1251, 120, 1252, 1253, + 1254, 120, 120, 120, 120, 120, 120, 120, 120, 1255, 120, 120, 120, 1256, + 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, + 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, + 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, + 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, + 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, + 1257, 120, 120, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, + 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, + 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1256, 1258, 120, 1259, + 737, 737, 737, 737, 737, 737, 737, 737, 737, 737, 737, 737, 737, 737, + 737, 737, 737, 737, 737, 737, 737, 737, 737, 737, 737, 737, 737, 737, + 737, 737, 737, 737, 737, 737, 1260, 120, 120, 120, 120, 120, 120, 120, + 120, 120, 120, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, + 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, + 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, + 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, + 1261, 1261, 1261, 1261, 1262, 1263, 1263, 1263, 1263, 1263, 1263, 1263, + 1263, 1263, 1263, 1263, 1263, 1263, 1264, 1263, 1265, 1263, 1266, 1263, + 1267, 1268, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 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, 1269, 120, 609, 609, 609, 609, 1270, 1271, 609, 609, 609, 609, 609, + 609, 1272, 1273, 1274, 1275, 1276, 1277, 609, 609, 609, 1278, 609, 609, + 609, 609, 609, 609, 609, 1279, 120, 120, 949, 949, 949, 949, 949, 949, + 949, 949, 1280, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, + 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 580, 580, + 580, 580, 580, 580, 580, 580, 580, 580, 616, 120, 944, 944, 1281, 120, + 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, + 120, 120, 1282, 1282, 1282, 1283, 1284, 1284, 1285, 1282, 1282, 1286, + 1287, 1284, 1284, 1282, 1282, 1282, 1283, 1284, 1284, 1288, 1289, 1290, + 1286, 1291, 1292, 1284, 1282, 1282, 1282, 1283, 1284, 1284, 1293, 1294, + 1295, 1296, 1284, 1284, 1284, 1297, 1298, 1299, 1300, 1284, 1284, 1285, + 1282, 1282, 1286, 1284, 1284, 1284, 1282, 1282, 1282, 1283, 1284, 1284, + 1285, 1282, 1282, 1286, 1284, 1284, 1284, 1282, 1282, 1282, 1283, 1284, + 1284, 1285, 1282, 1282, 1286, 1284, 1284, 1284, 1282, 1282, 1282, 1283, + 1284, 1284, 1301, 1282, 1282, 1282, 1302, 1284, 1284, 1303, 1304, 1282, + 1282, 1305, 1284, 1284, 1306, 1285, 1282, 1282, 1307, 1284, 1284, 1308, + 1309, 1282, 1282, 1310, 1284, 1284, 1284, 1311, 1282, 1282, 1282, 1302, + 1284, 1284, 1303, 1312, 1313, 1313, 1313, 1313, 1313, 1313, 1314, 1314, + 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, + 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, + 1314, 1314, 1314, 1314, 1314, 1314, 1315, 1315, 1315, 1315, 1315, 1315, + 1316, 1317, 1315, 1315, 1315, 1315, 1315, 1318, 1319, 1314, 1320, 1321, + 120, 1322, 1323, 1315, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, + 1324, 1325, 1325, 1326, 1327, 1328, 120, 120, 120, 120, 120, 120, 120, + 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, + 120, 120, 120, 120, 120, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, + 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1329, + 1329, 1329, 1329, 1329, 1330, 1331, 1332, 120, 120, 120, 120, 120, 1333, + 1333, 1333, 1333, 1334, 1335, 1335, 1335, 1336, 1337, 1338, 1339, 120, + 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, + 120, 120, 120, 120, 120, 1340, 128, 128, 128, 1341, 1342, 1343, 1344, + 1345, 1346, 1341, 1347, 1341, 1343, 1343, 1348, 128, 1349, 128, 1350, + 1351, 1349, 128, 1350, 120, 120, 120, 120, 120, 120, 1352, 120, 1353, + 1354, 1354, 1354, 1354, 1355, 1354, 1354, 1354, 1354, 1354, 1354, 1354, + 1354, 1354, 1354, 1354, 1354, 1355, 1356, 1354, 1357, 1358, 1354, 1358, + 1359, 1358, 1354, 1354, 1354, 1360, 1356, 619, 1361, 621, 621, 621, 1362, + 621, 621, 621, 621, 621, 621, 621, 1363, 621, 621, 621, 1364, 1365, 1366, + 621, 1367, 1356, 1356, 1356, 1356, 1356, 1356, 1368, 1369, 1369, 1369, + 1370, 1356, 758, 758, 758, 758, 758, 1371, 758, 1372, 1373, 1356, 1374, + 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, + 1356, 1356, 1356, 1356, 1356, 1356, 1356, 725, 725, 725, 725, 1375, 1376, + 1377, 725, 725, 725, 725, 725, 725, 725, 725, 1378, 1379, 725, 1380, + 1381, 725, 725, 1382, 1383, 1384, 1385, 1380, 1354, 725, 725, 1386, 1387, + 725, 725, 725, 725, 725, 725, 725, 1388, 1389, 1390, 1391, 725, 1392, + 1393, 1390, 1394, 1395, 725, 725, 725, 1396, 1397, 1398, 725, 725, 725, + 725, 725, 725, 725, 725, 1399, 1400, 725, 1401, 642, 1402, 725, 1403, + 1404, 580, 1405, 725, 725, 725, 1354, 1406, 1407, 1354, 1354, 1408, 1354, + 1353, 1354, 1354, 1354, 1354, 1354, 1409, 1410, 1354, 1354, 1409, 1411, + 725, 725, 725, 725, 725, 725, 725, 725, 1412, 1413, 580, 580, 580, 580, + 1414, 1415, 725, 725, 725, 725, 1416, 725, 1417, 725, 1418, 1419, 1420, + 1356, 1354, 1421, 1422, 1423, 580, 580, 580, 580, 580, 580, 580, 580, + 580, 580, 580, 580, 580, 580, 1424, 1356, 580, 580, 580, 580, 580, 580, + 580, 580, 580, 580, 1425, 1356, 1356, 1356, 1356, 1356, 580, 1424, 580, + 580, 580, 580, 580, 580, 580, 1356, 580, 1426, 580, 580, 580, 580, 580, + 1356, 580, 580, 580, 1427, 1356, 1356, 1356, 1356, 1356, 1356, 1356, + 1356, 1356, 1356, 580, 1424, 725, 1428, 1429, 725, 1390, 1430, 725, 1431, + 725, 725, 725, 1432, 1356, 1356, 725, 725, 725, 1356, 1356, 1356, 1356, + 1356, 1423, 1356, 1433, 1434, 1435, 1356, 1356, 1356, 1356, 1356, 1356, + 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, + 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, + 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, + 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, + 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, 1356, + 1436, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, + 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 1437, + 778, 778, 778, 778, 778, 776, 776, 776, 776, 776, 776, 1438, 778, 776, + 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, + 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 777, 776, + 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, + 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, + 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, + 776, 776, 776, 776, 776, 886, 778, 776, 776, 776, 776, 776, 776, 776, + 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, + 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, 776, + 776, 776, 776, 1439, 778, 778, 778, 778, 778, 778, 778, 778, 778, 778, + 778, 778, 778, 778, 778, 778, 778, 778, 778, 778, 778, 778, 778, 778, + 778, 778, 778, 778, 778, 778, 778, 778, 778, 778, 778, 776, 776, 776, + 777, 778, 778, 778, 778, 778, 778, 778, 778, 778, 778, 778, 778, 778, + 778, 778, 778, 778, 778, 778, 778, 778, 778, 778, 778, 778, 778, 778, + 778, 778, 778, 778, 778, 778, 778, 778, 778, 778, 778, 778, 778, 778, + 778, 778, 778, 778, 778, 778, 778, 778, 778, 778, 778, 778, 778, 778, + 778, 778, 778, 778, 1440, 1441, 120, 120, 120, 1442, 1442, 1442, 1442, + 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1442, 120, 120, 120, 120, 120, + 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 901, 901, 901, + 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, + 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 901, 120, + 120, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, + 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, 885, + 885, 885, 885, 885, 1443, +}; + +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, 81, 101, 101, 101, 101, 101, 101, + 101, 101, 101, 101, 101, 101, 101, 101, 101, 81, 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, 81, 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, 81, 81, + 81, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, + 183, 183, 183, 183, 184, 183, 183, 183, 183, 183, 183, 183, 183, 183, + 184, 183, 183, 183, 184, 183, 183, 183, 183, 183, 81, 81, 185, 185, 185, + 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 81, 186, 186, + 186, 186, 186, 186, 186, 186, 186, 187, 187, 187, 81, 81, 188, 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, 81, 139, 139, 139, 139, 139, + 139, 131, 157, 139, 139, 157, 139, 139, 157, 139, 139, 139, 157, 157, + 157, 189, 190, 191, 139, 139, 139, 157, 139, 139, 157, 157, 139, 139, + 139, 139, 139, 192, 192, 192, 193, 194, 194, 194, 194, 194, 194, 194, + 194, 194, 194, 194, 194, 194, 194, 192, 193, 195, 194, 193, 193, 193, + 192, 192, 192, 192, 192, 192, 192, 192, 193, 193, 193, 193, 196, 193, + 193, 194, 96, 156, 197, 197, 192, 192, 192, 194, 194, 192, 192, 198, 198, + 199, 199, 199, 199, 199, 199, 199, 199, 199, 199, 200, 201, 194, 194, + 194, 194, 194, 194, 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, 81, 81, + 81, 214, 214, 215, 81, 216, 216, 216, 216, 216, 216, 81, 81, 81, 81, 216, + 216, 81, 81, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, + 216, 216, 81, 216, 216, 216, 216, 216, 216, 216, 81, 216, 216, 81, 216, + 216, 81, 216, 216, 81, 81, 217, 81, 215, 215, 215, 214, 214, 81, 81, 81, + 81, 214, 214, 81, 81, 214, 214, 218, 81, 81, 81, 214, 81, 81, 81, 81, 81, + 81, 81, 216, 216, 216, 216, 81, 216, 81, 81, 81, 81, 81, 81, 81, 219, + 219, 219, 219, 219, 219, 219, 219, 219, 219, 214, 214, 216, 216, 216, + 214, 81, 81, 81, 220, 220, 221, 81, 222, 222, 222, 222, 222, 222, 222, + 222, 222, 81, 222, 222, 222, 81, 222, 222, 222, 222, 222, 222, 222, 222, + 222, 222, 222, 222, 222, 222, 81, 222, 222, 222, 222, 222, 222, 222, 81, + 222, 222, 81, 222, 222, 222, 222, 222, 81, 81, 223, 222, 221, 221, 221, + 220, 220, 220, 220, 220, 81, 220, 220, 221, 81, 221, 221, 224, 81, 81, + 222, 81, 81, 81, 81, 81, 81, 81, 222, 222, 220, 220, 81, 81, 225, 225, + 225, 225, 225, 225, 225, 225, 225, 225, 226, 227, 81, 81, 81, 81, 81, 81, + 81, 222, 220, 220, 220, 220, 220, 220, 81, 228, 229, 229, 81, 230, 230, + 230, 230, 230, 230, 230, 230, 81, 81, 230, 230, 81, 81, 230, 230, 230, + 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 81, 230, 230, 230, + 230, 230, 230, 230, 81, 230, 230, 81, 230, 230, 230, 230, 230, 81, 81, + 231, 230, 229, 228, 229, 228, 228, 228, 228, 81, 81, 229, 229, 81, 81, + 229, 229, 232, 81, 81, 81, 81, 81, 81, 81, 81, 228, 229, 81, 81, 81, 81, + 230, 230, 81, 230, 230, 230, 228, 228, 81, 81, 233, 233, 233, 233, 233, + 233, 233, 233, 233, 233, 234, 230, 235, 235, 235, 235, 235, 235, 81, 81, + 236, 237, 81, 237, 237, 237, 237, 237, 237, 81, 81, 81, 237, 237, 237, + 81, 237, 237, 237, 237, 81, 81, 81, 237, 237, 81, 237, 81, 237, 237, 81, + 81, 81, 237, 237, 81, 81, 81, 237, 237, 237, 237, 237, 237, 237, 237, + 237, 237, 81, 81, 81, 81, 238, 238, 236, 238, 238, 81, 81, 81, 238, 238, + 238, 81, 238, 238, 238, 239, 81, 81, 237, 81, 81, 81, 81, 81, 81, 238, + 81, 81, 81, 81, 81, 81, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, + 241, 241, 241, 242, 242, 242, 242, 242, 242, 243, 242, 81, 81, 81, 81, + 81, 244, 245, 245, 245, 81, 246, 246, 246, 246, 246, 246, 246, 246, 81, + 246, 246, 246, 81, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, + 246, 246, 246, 246, 246, 81, 81, 81, 246, 244, 244, 244, 245, 245, 245, + 245, 81, 244, 244, 244, 81, 244, 244, 244, 247, 81, 81, 81, 81, 81, 81, + 81, 248, 249, 81, 246, 246, 246, 81, 81, 81, 81, 81, 246, 246, 244, 244, + 81, 81, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 251, 251, 251, + 251, 251, 251, 251, 252, 253, 254, 255, 255, 81, 253, 253, 253, 253, 253, + 253, 253, 253, 81, 253, 253, 253, 81, 253, 253, 253, 253, 253, 253, 253, + 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 81, 253, 253, 253, + 253, 253, 81, 81, 256, 253, 255, 257, 255, 255, 255, 255, 255, 81, 257, + 255, 255, 81, 255, 255, 254, 258, 81, 81, 81, 81, 81, 81, 81, 255, 255, + 81, 81, 81, 81, 81, 81, 81, 253, 81, 253, 253, 254, 254, 81, 81, 259, + 259, 259, 259, 259, 259, 259, 259, 259, 259, 81, 253, 253, 81, 81, 81, + 81, 81, 260, 260, 261, 261, 81, 262, 262, 262, 262, 262, 262, 262, 262, + 81, 262, 262, 262, 81, 262, 262, 262, 262, 262, 262, 262, 262, 262, 262, + 262, 262, 262, 262, 262, 262, 262, 263, 263, 262, 261, 261, 261, 260, + 260, 260, 260, 81, 261, 261, 261, 81, 261, 261, 261, 263, 262, 264, 81, + 81, 81, 81, 262, 262, 262, 261, 265, 265, 265, 265, 265, 265, 265, 262, + 262, 262, 260, 260, 81, 81, 266, 266, 266, 266, 266, 266, 266, 266, 266, + 266, 265, 265, 265, 265, 265, 265, 265, 265, 265, 267, 262, 262, 262, + 262, 262, 262, 81, 81, 268, 268, 81, 269, 269, 269, 269, 269, 269, 269, + 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 81, 81, 81, 269, + 269, 269, 269, 269, 269, 269, 269, 81, 269, 269, 269, 269, 269, 269, 269, + 269, 269, 81, 269, 81, 81, 81, 81, 270, 81, 81, 81, 81, 268, 268, 268, + 271, 271, 271, 81, 271, 81, 268, 268, 268, 268, 268, 268, 268, 268, 81, + 81, 81, 81, 81, 81, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 81, + 81, 268, 268, 273, 81, 81, 81, 81, 274, 274, 274, 274, 274, 274, 274, + 274, 274, 274, 274, 274, 274, 274, 274, 274, 275, 274, 274, 275, 275, + 275, 275, 276, 276, 277, 81, 81, 81, 81, 278, 274, 274, 274, 274, 274, + 274, 279, 275, 280, 280, 280, 280, 275, 275, 275, 281, 282, 282, 282, + 282, 282, 282, 282, 282, 282, 282, 283, 283, 81, 81, 81, 81, 81, 284, + 284, 81, 284, 81, 81, 284, 284, 81, 284, 81, 81, 284, 81, 81, 81, 81, 81, + 81, 284, 284, 284, 284, 81, 284, 284, 284, 284, 284, 284, 284, 81, 284, + 284, 284, 81, 284, 81, 284, 81, 81, 284, 284, 81, 284, 284, 284, 284, + 285, 284, 284, 285, 285, 285, 285, 286, 286, 81, 285, 285, 284, 81, 81, + 284, 284, 284, 284, 284, 81, 287, 81, 288, 288, 288, 288, 285, 285, 81, + 81, 289, 289, 289, 289, 289, 289, 289, 289, 289, 289, 81, 81, 284, 284, + 284, 284, 290, 291, 291, 291, 292, 293, 292, 292, 294, 292, 292, 295, + 294, 296, 296, 296, 296, 296, 294, 297, 296, 297, 297, 297, 298, 298, + 297, 297, 297, 297, 297, 297, 299, 299, 299, 299, 299, 299, 299, 299, + 299, 299, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 301, 298, + 297, 298, 297, 302, 303, 304, 303, 304, 305, 305, 290, 290, 290, 290, + 290, 290, 290, 290, 81, 290, 290, 290, 290, 290, 290, 290, 290, 290, 290, + 290, 290, 81, 81, 81, 81, 306, 307, 308, 309, 308, 308, 308, 308, 308, + 307, 307, 307, 307, 308, 310, 307, 308, 311, 311, 312, 295, 311, 311, + 290, 290, 290, 290, 290, 308, 308, 308, 308, 308, 308, 308, 308, 308, + 308, 308, 81, 308, 308, 308, 308, 308, 308, 308, 308, 308, 308, 308, 308, + 81, 301, 301, 297, 297, 297, 297, 297, 297, 298, 297, 297, 297, 297, 297, + 297, 81, 297, 297, 292, 292, 295, 292, 293, 313, 313, 313, 313, 294, 294, + 81, 81, 81, 81, 81, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, + 314, 315, 315, 316, 316, 316, 316, 315, 316, 316, 316, 316, 316, 317, + 315, 318, 318, 315, 315, 316, 316, 314, 319, 319, 319, 319, 319, 319, + 319, 319, 319, 319, 320, 320, 321, 321, 321, 321, 314, 314, 314, 314, + 314, 314, 315, 315, 316, 316, 314, 314, 314, 314, 316, 316, 316, 314, + 315, 315, 315, 314, 314, 315, 315, 315, 315, 315, 315, 315, 314, 314, + 314, 316, 316, 316, 316, 314, 314, 314, 314, 314, 316, 315, 315, 316, + 316, 315, 315, 315, 315, 315, 315, 322, 314, 315, 319, 319, 315, 315, + 315, 316, 323, 323, 324, 324, 324, 324, 324, 324, 324, 324, 324, 324, + 324, 324, 324, 324, 81, 324, 81, 81, 81, 81, 81, 324, 81, 81, 325, 325, + 325, 325, 325, 325, 325, 325, 325, 325, 325, 326, 327, 325, 325, 325, + 328, 328, 328, 328, 328, 328, 328, 328, 329, 329, 329, 329, 329, 329, + 329, 329, 330, 330, 330, 330, 330, 330, 330, 330, 331, 331, 331, 331, + 331, 331, 331, 331, 331, 81, 331, 331, 331, 331, 81, 81, 331, 331, 331, + 331, 331, 331, 331, 81, 331, 331, 331, 81, 81, 332, 332, 332, 333, 334, + 333, 333, 333, 333, 333, 333, 333, 335, 335, 335, 335, 335, 335, 335, + 335, 335, 335, 335, 335, 335, 335, 335, 335, 335, 335, 335, 335, 81, 81, + 81, 336, 336, 336, 336, 336, 336, 336, 336, 336, 336, 81, 81, 81, 81, 81, + 81, 337, 337, 337, 337, 337, 337, 337, 337, 337, 337, 337, 337, 337, 337, + 81, 81, 338, 338, 338, 338, 338, 338, 81, 81, 339, 340, 340, 340, 340, + 340, 340, 340, 340, 340, 340, 340, 340, 340, 340, 340, 340, 340, 340, + 340, 340, 341, 341, 340, 342, 343, 343, 343, 343, 343, 343, 343, 343, + 343, 343, 343, 343, 343, 343, 343, 343, 343, 343, 344, 345, 81, 81, 81, + 346, 346, 346, 346, 346, 346, 346, 346, 346, 346, 346, 198, 198, 198, + 347, 347, 347, 346, 346, 346, 346, 346, 346, 346, 346, 81, 81, 81, 81, + 81, 81, 81, 348, 348, 348, 348, 348, 348, 348, 348, 348, 348, 348, 348, + 348, 81, 348, 348, 348, 348, 349, 349, 350, 81, 81, 81, 351, 351, 351, + 351, 351, 351, 351, 351, 351, 351, 352, 352, 353, 198, 198, 81, 354, 354, + 354, 354, 354, 354, 354, 354, 354, 354, 355, 355, 81, 81, 81, 81, 356, + 356, 356, 356, 356, 356, 356, 356, 356, 356, 356, 356, 356, 81, 356, 356, + 356, 81, 357, 357, 81, 81, 81, 81, 358, 358, 358, 358, 358, 358, 358, + 358, 358, 358, 358, 358, 359, 359, 360, 359, 359, 359, 359, 359, 359, + 359, 360, 360, 360, 360, 360, 360, 360, 360, 359, 360, 360, 359, 359, + 359, 359, 359, 359, 359, 359, 359, 361, 359, 362, 362, 363, 364, 362, + 365, 362, 366, 358, 367, 81, 81, 368, 368, 368, 368, 368, 368, 368, 368, + 368, 368, 81, 81, 81, 81, 81, 81, 369, 369, 369, 369, 369, 369, 369, 369, + 369, 369, 81, 81, 81, 81, 81, 81, 370, 370, 371, 371, 372, 373, 374, 370, + 375, 375, 370, 376, 376, 376, 377, 81, 378, 378, 378, 378, 378, 378, 378, + 378, 378, 378, 81, 81, 81, 81, 81, 81, 379, 379, 379, 379, 379, 379, 379, + 379, 379, 379, 379, 380, 379, 379, 379, 379, 379, 379, 379, 379, 379, + 376, 376, 379, 379, 381, 379, 81, 81, 81, 81, 81, 340, 340, 340, 340, + 340, 340, 81, 81, 382, 382, 382, 382, 382, 382, 382, 382, 382, 382, 382, + 382, 382, 382, 382, 81, 383, 383, 383, 384, 384, 384, 384, 383, 383, 384, + 384, 384, 81, 81, 81, 81, 384, 384, 383, 384, 384, 384, 384, 384, 384, + 385, 386, 387, 81, 81, 81, 81, 388, 81, 81, 81, 389, 389, 390, 390, 390, + 390, 390, 390, 390, 390, 390, 390, 391, 391, 391, 391, 391, 391, 391, + 391, 391, 391, 391, 391, 391, 391, 81, 81, 391, 391, 391, 391, 391, 81, + 81, 81, 392, 392, 392, 392, 392, 392, 392, 392, 392, 392, 392, 392, 81, + 81, 81, 81, 392, 392, 81, 81, 81, 81, 81, 81, 393, 393, 393, 393, 393, + 393, 393, 393, 393, 393, 394, 81, 81, 81, 395, 395, 396, 396, 396, 396, + 396, 396, 396, 396, 397, 397, 397, 397, 397, 397, 397, 397, 397, 397, + 397, 397, 397, 397, 397, 398, 399, 400, 400, 401, 81, 81, 402, 402, 403, + 403, 403, 403, 403, 403, 403, 403, 403, 403, 403, 403, 403, 404, 405, + 404, 405, 405, 405, 405, 405, 405, 405, 81, 406, 404, 405, 404, 404, 405, + 405, 405, 405, 405, 405, 405, 405, 404, 404, 404, 404, 404, 404, 405, + 405, 407, 407, 407, 407, 407, 407, 407, 407, 81, 81, 408, 409, 409, 409, + 409, 409, 409, 409, 409, 409, 409, 81, 81, 81, 81, 81, 81, 410, 410, 410, + 410, 410, 410, 410, 411, 410, 410, 410, 410, 410, 410, 81, 81, 96, 96, + 96, 96, 96, 156, 156, 156, 156, 156, 156, 96, 96, 156, 412, 81, 413, 413, + 413, 413, 414, 415, 415, 415, 415, 415, 415, 415, 415, 415, 415, 415, + 415, 415, 415, 415, 416, 414, 413, 413, 413, 413, 413, 414, 413, 414, + 414, 414, 414, 414, 413, 414, 417, 415, 415, 415, 415, 415, 415, 415, 81, + 81, 81, 81, 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, 419, 419, + 420, 419, 419, 419, 419, 421, 421, 421, 421, 421, 421, 421, 421, 421, + 421, 422, 423, 422, 422, 422, 422, 422, 422, 422, 421, 421, 421, 421, + 421, 421, 421, 421, 421, 81, 81, 81, 424, 424, 425, 426, 426, 426, 426, + 426, 426, 426, 426, 426, 426, 426, 426, 426, 426, 425, 424, 424, 424, + 424, 425, 425, 424, 424, 427, 428, 424, 424, 426, 426, 429, 429, 429, + 429, 429, 429, 429, 429, 429, 429, 426, 426, 426, 426, 426, 426, 430, + 430, 430, 430, 430, 430, 430, 430, 430, 430, 430, 430, 430, 430, 431, + 432, 433, 433, 432, 432, 432, 433, 432, 433, 433, 433, 434, 434, 81, 81, + 81, 81, 81, 81, 81, 81, 435, 435, 435, 435, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 436, 436, 437, 437, 437, 437, 437, 437, 437, 437, + 438, 438, 438, 438, 438, 438, 438, 438, 437, 437, 438, 439, 81, 81, 81, + 440, 440, 440, 440, 440, 441, 441, 441, 441, 441, 441, 441, 441, 441, + 441, 81, 81, 81, 436, 436, 436, 442, 442, 442, 442, 442, 442, 442, 442, + 442, 442, 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, + 443, 443, 444, 444, 444, 444, 444, 444, 445, 445, 93, 81, 81, 81, 81, 81, + 81, 81, 446, 446, 446, 446, 446, 446, 446, 446, 96, 96, 96, 326, 447, + 156, 156, 156, 156, 156, 96, 96, 156, 156, 156, 156, 96, 448, 447, 447, + 447, 447, 447, 447, 447, 449, 449, 449, 449, 156, 449, 449, 449, 449, + 448, 448, 96, 449, 449, 448, 96, 96, 81, 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, 450, 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, 451, 452, 156, 453, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, + 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 454, 455, 455, 156, 81, 96, 456, + 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, 457, 457, 457, 457, 457, 457, 457, 457, 79, 79, 79, + 79, 79, 81, 79, 79, 78, 78, 78, 78, 457, 80, 79, 80, 80, 80, 79, 79, 79, + 81, 79, 79, 78, 78, 78, 78, 457, 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, 457, 458, 80, 81, 459, 459, + 459, 459, 459, 459, 459, 460, 459, 459, 459, 461, 462, 463, 464, 465, + 466, 467, 468, 466, 469, 470, 38, 84, 471, 472, 473, 42, 471, 472, 473, + 42, 38, 38, 474, 84, 475, 475, 475, 476, 477, 478, 479, 480, 481, 482, + 483, 33, 484, 485, 484, 484, 485, 486, 487, 487, 84, 42, 50, 38, 488, + 488, 474, 489, 489, 84, 84, 84, 490, 473, 491, 488, 488, 488, 84, 84, 84, + 84, 84, 84, 84, 84, 492, 84, 489, 84, 373, 84, 373, 373, 373, 373, 84, + 373, 373, 459, 493, 494, 494, 494, 494, 81, 495, 496, 497, 498, 499, 499, + 499, 499, 499, 499, 500, 59, 81, 81, 47, 500, 500, 500, 500, 500, 501, + 501, 492, 473, 491, 502, 500, 47, 47, 47, 47, 500, 500, 500, 500, 500, + 501, 501, 492, 473, 491, 81, 59, 59, 59, 59, 59, 81, 81, 81, 278, 278, + 278, 278, 278, 278, 278, 503, 278, 504, 278, 278, 36, 278, 278, 278, 278, + 278, 278, 278, 278, 278, 503, 278, 278, 278, 278, 503, 278, 278, 503, + 278, 505, 505, 505, 505, 505, 505, 505, 505, 96, 96, 447, 447, 96, 96, + 96, 96, 447, 447, 447, 96, 96, 412, 412, 412, 412, 96, 412, 412, 412, + 447, 447, 96, 156, 96, 447, 447, 156, 156, 156, 156, 96, 81, 81, 81, 81, + 81, 81, 81, 40, 40, 506, 507, 40, 508, 40, 506, 40, 507, 49, 506, 506, + 506, 49, 49, 506, 506, 506, 509, 40, 506, 510, 40, 492, 506, 506, 506, + 506, 506, 40, 40, 40, 508, 508, 40, 506, 40, 85, 40, 506, 40, 52, 511, + 506, 506, 512, 49, 506, 506, 52, 506, 49, 449, 449, 449, 449, 49, 40, 40, + 49, 49, 506, 506, 492, 492, 492, 492, 492, 506, 49, 49, 49, 49, 40, 492, + 40, 40, 56, 313, 513, 513, 513, 514, 51, 515, 513, 513, 513, 513, 513, + 51, 514, 514, 51, 513, 516, 516, 516, 516, 516, 516, 516, 516, 516, 516, + 516, 516, 517, 517, 517, 517, 516, 516, 517, 517, 517, 517, 517, 517, + 517, 517, 517, 52, 56, 517, 517, 517, 517, 51, 40, 40, 81, 81, 81, 81, + 54, 54, 54, 54, 54, 508, 508, 508, 508, 508, 492, 492, 40, 40, 40, 40, + 492, 40, 40, 492, 40, 40, 492, 40, 40, 40, 40, 40, 40, 40, 492, 40, 40, + 40, 40, 40, 40, 40, 40, 40, 44, 44, 40, 40, 40, 40, 40, 40, 40, 40, 40, + 40, 40, 40, 492, 492, 40, 40, 54, 40, 54, 40, 40, 40, 40, 40, 40, 40, 40, + 40, 40, 44, 40, 40, 40, 40, 492, 492, 492, 492, 492, 492, 492, 492, 492, + 492, 492, 492, 54, 492, 54, 54, 492, 492, 492, 54, 54, 492, 492, 54, 492, + 492, 492, 54, 492, 54, 518, 519, 492, 54, 492, 492, 492, 492, 54, 492, + 492, 54, 54, 54, 54, 492, 492, 54, 492, 54, 492, 54, 54, 54, 54, 54, 54, + 492, 54, 492, 492, 492, 492, 492, 54, 54, 54, 54, 492, 492, 492, 492, 54, + 54, 492, 492, 54, 492, 492, 492, 54, 492, 492, 492, 492, 492, 54, 492, + 492, 492, 492, 492, 54, 54, 492, 492, 54, 54, 54, 54, 492, 492, 54, 54, + 492, 492, 54, 54, 492, 492, 492, 492, 492, 54, 492, 492, 492, 54, 492, + 492, 492, 492, 492, 492, 492, 492, 492, 492, 492, 492, 492, 54, 492, 492, + 492, 492, 492, 492, 492, 520, 473, 491, 473, 491, 40, 40, 40, 40, 40, 40, + 508, 40, 40, 40, 40, 40, 40, 40, 521, 521, 40, 40, 40, 40, 492, 492, 40, + 40, 40, 40, 40, 40, 40, 522, 523, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, + 40, 313, 313, 313, 313, 313, 313, 313, 313, 313, 313, 313, 313, 313, 40, + 492, 40, 40, 40, 40, 40, 40, 40, 40, 313, 40, 40, 40, 40, 40, 492, 492, + 492, 492, 492, 492, 492, 492, 492, 40, 40, 40, 40, 40, 524, 524, 524, + 524, 40, 40, 40, 521, 525, 525, 521, 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, 526, 526, 526, 526, + 526, 526, 526, 526, 526, 526, 526, 526, 526, 526, 515, 51, 51, 51, 51, + 51, 51, 51, 51, 51, 51, 51, 51, 514, 508, 508, 508, 508, 508, 508, 508, + 508, 508, 508, 508, 508, 40, 40, 40, 40, 508, 508, 508, 508, 527, 40, 40, + 40, 40, 40, 508, 508, 508, 508, 40, 40, 508, 508, 40, 508, 508, 508, 508, + 508, 508, 508, 40, 40, 40, 40, 40, 40, 40, 40, 508, 508, 40, 40, 508, 54, + 40, 40, 40, 40, 508, 508, 40, 40, 508, 54, 40, 40, 40, 40, 508, 508, 508, + 40, 40, 508, 40, 40, 508, 508, 40, 40, 40, 40, 40, 40, 40, 508, 492, 492, + 492, 492, 492, 528, 528, 492, 525, 525, 525, 525, 40, 508, 508, 40, 40, + 508, 40, 40, 40, 40, 508, 508, 40, 40, 40, 40, 521, 521, 527, 527, 525, + 40, 525, 525, 529, 530, 529, 525, 40, 525, 525, 525, 40, 40, 40, 40, 508, + 40, 508, 40, 40, 40, 40, 40, 524, 524, 524, 524, 524, 524, 524, 524, 524, + 524, 524, 524, 40, 40, 40, 40, 508, 508, 40, 508, 508, 508, 40, 508, 529, + 508, 508, 40, 508, 508, 40, 54, 40, 40, 40, 40, 40, 40, 40, 521, 40, 40, + 40, 524, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 508, 508, 40, 524, 40, + 40, 40, 40, 40, 40, 40, 40, 524, 524, 313, 40, 40, 40, 40, 40, 40, 40, + 40, 521, 521, 529, 525, 525, 525, 525, 521, 521, 529, 529, 529, 508, 508, + 508, 508, 529, 524, 529, 529, 529, 508, 529, 521, 508, 508, 508, 529, + 529, 508, 508, 529, 508, 508, 529, 529, 529, 40, 508, 40, 40, 40, 40, + 508, 508, 521, 508, 508, 508, 508, 508, 508, 529, 521, 521, 529, 521, + 508, 529, 529, 531, 521, 508, 508, 521, 529, 529, 525, 525, 525, 525, + 525, 524, 40, 40, 525, 525, 532, 532, 530, 530, 40, 40, 524, 40, 40, 40, + 40, 40, 40, 40, 40, 40, 40, 40, 40, 44, 40, 40, 40, 40, 40, 40, 524, 40, + 524, 40, 40, 40, 40, 524, 524, 524, 40, 533, 40, 40, 40, 534, 534, 534, + 534, 534, 534, 40, 535, 535, 525, 40, 40, 40, 473, 491, 473, 491, 473, + 491, 473, 491, 473, 491, 473, 491, 473, 491, 51, 51, 515, 515, 515, 515, + 515, 515, 515, 515, 515, 515, 515, 515, 40, 524, 524, 524, 40, 40, 40, + 40, 40, 40, 40, 524, 492, 492, 492, 492, 492, 473, 491, 492, 492, 492, + 492, 492, 492, 492, 16, 31, 16, 31, 16, 31, 16, 31, 473, 491, 536, 536, + 536, 536, 536, 536, 536, 536, 492, 492, 492, 473, 491, 16, 31, 473, 491, + 473, 491, 473, 491, 473, 491, 473, 491, 492, 492, 492, 492, 492, 492, + 492, 473, 491, 473, 491, 492, 492, 492, 492, 492, 492, 492, 492, 473, + 491, 492, 492, 40, 40, 40, 524, 524, 40, 40, 40, 492, 492, 492, 492, 492, + 40, 40, 492, 492, 492, 492, 492, 492, 40, 40, 40, 524, 40, 40, 40, 40, + 533, 508, 508, 40, 40, 40, 40, 81, 81, 40, 40, 40, 40, 40, 40, 40, 40, + 81, 81, 40, 40, 81, 81, 81, 40, 40, 40, 40, 81, 40, 40, 40, 40, 40, 40, + 81, 81, 81, 81, 40, 40, 40, 40, 537, 537, 537, 537, 537, 537, 537, 537, + 537, 537, 537, 537, 537, 537, 537, 81, 538, 538, 538, 538, 538, 538, 538, + 538, 538, 538, 538, 538, 538, 538, 538, 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, 539, 539, 539, 539, 539, + 539, 87, 88, 87, 88, 540, 540, 540, 87, 88, 81, 81, 81, 81, 81, 541, 542, + 542, 542, 543, 541, 542, 544, 544, 544, 544, 544, 544, 544, 544, 544, + 544, 544, 544, 544, 544, 81, 544, 81, 81, 81, 81, 81, 544, 81, 81, 545, + 545, 545, 545, 545, 545, 545, 545, 81, 81, 81, 81, 81, 81, 81, 546, 547, + 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 548, 95, 95, 95, + 95, 95, 95, 95, 95, 549, 549, 42, 50, 42, 50, 549, 549, 549, 42, 50, 549, + 42, 50, 373, 373, 373, 373, 373, 373, 373, 373, 84, 468, 550, 373, 551, + 84, 42, 50, 84, 84, 42, 50, 473, 491, 473, 491, 473, 491, 473, 491, 373, + 373, 373, 373, 371, 60, 373, 373, 84, 373, 373, 84, 84, 84, 84, 84, 552, + 552, 373, 373, 373, 84, 468, 373, 473, 373, 373, 373, 373, 373, 373, 373, + 81, 81, 81, 81, 81, 81, 553, 553, 553, 553, 553, 553, 553, 553, 553, 553, + 81, 553, 553, 553, 553, 553, 553, 553, 553, 553, 81, 81, 81, 81, 553, + 553, 553, 553, 553, 553, 81, 81, 521, 521, 521, 521, 521, 521, 521, 521, + 521, 521, 521, 521, 81, 81, 81, 81, 554, 555, 555, 556, 521, 557, 558, + 559, 522, 523, 522, 523, 522, 523, 522, 523, 522, 523, 521, 521, 522, + 523, 522, 523, 522, 523, 522, 523, 560, 522, 523, 523, 521, 559, 559, + 559, 559, 559, 559, 559, 559, 559, 561, 562, 563, 564, 565, 565, 566, + 567, 567, 567, 567, 568, 521, 521, 559, 559, 559, 557, 569, 556, 521, + 525, 81, 570, 571, 570, 571, 570, 571, 570, 571, 570, 571, 571, 571, 571, + 571, 571, 571, 571, 571, 571, 571, 571, 571, 571, 571, 571, 571, 570, + 571, 571, 571, 571, 571, 571, 571, 570, 571, 570, 571, 570, 571, 571, + 571, 571, 571, 571, 570, 571, 571, 571, 571, 571, 571, 570, 570, 81, 81, + 572, 572, 573, 573, 574, 574, 571, 560, 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, 576, 576, 576, 576, 577, 578, 579, 579, + 576, 81, 81, 81, 81, 81, 580, 580, 580, 580, 580, 580, 580, 580, 580, + 580, 580, 580, 580, 580, 580, 580, 580, 580, 81, 81, 581, 581, 581, 581, + 581, 581, 581, 581, 581, 581, 581, 581, 581, 581, 581, 581, 581, 581, + 581, 581, 581, 581, 81, 582, 582, 583, 583, 583, 583, 582, 582, 582, 582, + 582, 582, 582, 582, 582, 582, 580, 580, 580, 81, 81, 81, 81, 81, 575, + 575, 575, 575, 575, 575, 575, 575, 584, 584, 584, 584, 584, 584, 584, + 584, 584, 584, 584, 584, 584, 585, 585, 81, 583, 583, 583, 583, 583, 583, + 583, 583, 583, 583, 582, 582, 582, 582, 582, 582, 586, 586, 586, 586, + 586, 586, 586, 586, 521, 587, 587, 587, 587, 587, 587, 587, 587, 587, + 587, 587, 587, 587, 587, 587, 584, 584, 584, 584, 585, 585, 585, 582, + 582, 587, 587, 587, 587, 587, 587, 587, 582, 582, 582, 582, 521, 521, + 521, 521, 588, 588, 588, 588, 588, 588, 588, 588, 588, 588, 588, 588, + 588, 588, 588, 81, 582, 582, 582, 582, 582, 582, 582, 521, 521, 521, 521, + 582, 582, 582, 582, 582, 582, 582, 582, 582, 582, 582, 521, 521, 589, + 589, 589, 589, 589, 589, 589, 589, 589, 589, 589, 589, 589, 589, 590, + 590, 590, 590, 590, 590, 590, 590, 590, 590, 589, 589, 589, 590, 590, + 590, 590, 590, 591, 591, 591, 591, 591, 591, 591, 591, 591, 591, 591, + 591, 591, 592, 591, 591, 591, 591, 591, 591, 591, 81, 81, 81, 593, 593, + 593, 593, 593, 593, 593, 593, 593, 593, 593, 593, 593, 593, 593, 81, 594, + 594, 594, 594, 594, 594, 594, 594, 595, 595, 595, 595, 595, 595, 596, + 596, 597, 597, 597, 597, 597, 597, 597, 597, 597, 597, 597, 597, 598, + 599, 600, 599, 601, 601, 601, 601, 601, 601, 601, 601, 601, 601, 597, + 597, 81, 81, 81, 81, 90, 93, 90, 93, 90, 93, 602, 95, 97, 97, 97, 603, + 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 603, 604, 90, 93, 90, 93, 450, + 450, 95, 95, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, + 605, 605, 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, 607, 607, + 608, 609, 609, 609, 609, 609, 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, 610, 610, 52, 56, 52, 56, 57, 52, 56, 52, 56, 56, 56, 52, 56, 52, + 56, 52, 52, 52, 52, 52, 81, 52, 52, 52, 52, 52, 56, 52, 56, 81, 81, 81, + 81, 81, 81, 81, 57, 59, 59, 56, 57, 57, 57, 57, 57, 611, 611, 612, 611, + 611, 611, 613, 611, 611, 611, 611, 612, 611, 611, 611, 611, 611, 611, + 611, 611, 611, 611, 611, 611, 611, 611, 611, 614, 614, 612, 612, 614, + 615, 615, 615, 615, 81, 81, 81, 81, 616, 616, 616, 616, 616, 616, 313, + 313, 503, 512, 81, 81, 81, 81, 81, 81, 617, 617, 617, 617, 617, 617, 617, + 617, 617, 617, 617, 617, 618, 618, 619, 619, 620, 620, 621, 621, 621, + 621, 621, 621, 621, 621, 621, 621, 621, 621, 621, 621, 621, 621, 621, + 621, 620, 620, 620, 620, 620, 620, 620, 620, 620, 620, 620, 620, 620, + 620, 620, 620, 622, 623, 81, 81, 81, 81, 81, 81, 81, 81, 624, 624, 625, + 625, 625, 625, 625, 625, 625, 625, 625, 625, 81, 81, 81, 81, 81, 81, 197, + 197, 197, 197, 197, 197, 197, 197, 197, 197, 194, 194, 194, 194, 194, + 194, 200, 200, 200, 194, 626, 194, 81, 81, 627, 627, 627, 627, 627, 627, + 627, 627, 627, 627, 628, 628, 628, 628, 628, 628, 628, 628, 628, 628, + 628, 628, 628, 628, 628, 628, 628, 628, 628, 628, 629, 629, 629, 629, + 629, 630, 630, 630, 198, 631, 632, 632, 632, 632, 632, 632, 632, 632, + 632, 632, 632, 632, 632, 632, 632, 633, 633, 633, 633, 633, 633, 633, + 633, 633, 633, 633, 634, 635, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, + 636, 328, 328, 328, 328, 328, 81, 81, 81, 637, 637, 637, 638, 639, 639, + 639, 639, 639, 639, 639, 639, 639, 639, 639, 639, 639, 639, 639, 640, + 638, 638, 637, 637, 637, 637, 638, 638, 637, 638, 638, 638, 641, 642, + 642, 642, 642, 642, 642, 643, 643, 643, 642, 642, 642, 642, 81, 61, 644, + 644, 644, 644, 644, 644, 644, 644, 644, 644, 81, 81, 81, 81, 642, 642, + 314, 314, 314, 314, 314, 316, 645, 314, 319, 319, 314, 314, 314, 314, + 314, 81, 646, 646, 646, 646, 646, 646, 646, 646, 646, 647, 647, 647, 647, + 647, 647, 648, 648, 647, 647, 648, 648, 647, 647, 81, 646, 646, 646, 647, + 646, 646, 646, 646, 646, 646, 646, 646, 647, 648, 81, 81, 649, 649, 649, + 649, 649, 649, 649, 649, 649, 649, 81, 81, 650, 651, 651, 651, 645, 314, + 314, 314, 314, 314, 314, 323, 323, 323, 314, 315, 316, 315, 314, 314, + 652, 652, 652, 652, 652, 652, 652, 652, 653, 652, 653, 653, 654, 652, + 652, 653, 653, 652, 652, 652, 652, 652, 653, 653, 652, 653, 652, 81, 81, + 81, 81, 81, 81, 81, 81, 652, 652, 655, 656, 656, 657, 657, 657, 657, 657, + 657, 657, 657, 657, 657, 657, 658, 659, 659, 658, 658, 660, 660, 657, + 661, 661, 658, 662, 81, 81, 331, 331, 331, 331, 331, 331, 81, 56, 56, 56, + 610, 59, 59, 59, 59, 56, 56, 56, 56, 56, 79, 81, 81, 338, 338, 338, 338, + 338, 338, 338, 338, 657, 657, 657, 658, 658, 659, 658, 658, 659, 658, + 658, 660, 658, 662, 81, 81, 663, 663, 663, 663, 663, 663, 663, 663, 663, + 663, 81, 81, 81, 81, 81, 81, 664, 665, 665, 665, 665, 665, 665, 665, 665, + 665, 665, 665, 665, 665, 665, 665, 665, 665, 665, 665, 664, 665, 665, + 665, 665, 665, 665, 665, 81, 81, 81, 81, 329, 329, 329, 329, 329, 329, + 329, 81, 81, 81, 81, 330, 330, 330, 330, 330, 330, 330, 330, 330, 81, 81, + 81, 81, 666, 666, 666, 666, 666, 666, 666, 666, 667, 667, 667, 667, 667, + 667, 667, 667, 589, 589, 590, 590, 590, 590, 590, 590, 56, 56, 56, 56, + 56, 56, 56, 81, 81, 81, 81, 101, 101, 101, 101, 101, 81, 81, 81, 81, 81, + 129, 668, 129, 129, 669, 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, 670, 670, 670, 670, 670, 670, 670, + 670, 670, 670, 670, 670, 670, 670, 670, 670, 81, 81, 81, 81, 81, 81, 81, + 81, 81, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 491, 473, + 81, 81, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 135, 138, 81, + 81, 671, 671, 671, 671, 671, 671, 671, 671, 672, 555, 555, 672, 672, 673, + 673, 522, 523, 674, 81, 81, 81, 81, 81, 81, 96, 96, 96, 96, 96, 96, 96, + 156, 156, 156, 156, 156, 156, 156, 95, 95, 556, 566, 566, 675, 675, 522, + 523, 522, 523, 522, 523, 522, 523, 522, 523, 522, 523, 522, 523, 522, + 523, 556, 556, 522, 523, 556, 556, 556, 556, 675, 675, 675, 676, 556, + 676, 81, 577, 677, 673, 673, 566, 522, 523, 522, 523, 522, 523, 678, 556, + 556, 679, 680, 681, 681, 681, 81, 556, 682, 683, 556, 81, 81, 81, 81, + 146, 146, 146, 146, 146, 81, 81, 493, 81, 684, 685, 686, 687, 688, 685, + 685, 689, 690, 685, 691, 692, 693, 692, 694, 695, 695, 695, 695, 695, + 695, 695, 695, 695, 695, 696, 697, 698, 698, 698, 684, 685, 699, 699, + 699, 699, 699, 699, 699, 699, 699, 699, 699, 699, 699, 699, 699, 699, + 699, 699, 689, 685, 690, 700, 701, 700, 702, 702, 702, 702, 702, 702, + 702, 702, 702, 702, 702, 702, 702, 702, 702, 702, 702, 702, 689, 698, + 690, 698, 689, 690, 703, 704, 705, 703, 706, 707, 708, 708, 708, 708, + 708, 708, 708, 708, 708, 709, 707, 707, 707, 707, 707, 707, 707, 707, + 707, 707, 707, 707, 707, 707, 707, 707, 707, 707, 707, 707, 707, 710, + 710, 711, 711, 711, 711, 711, 711, 711, 711, 711, 711, 711, 711, 711, + 711, 711, 81, 81, 81, 711, 711, 711, 711, 711, 711, 81, 81, 711, 711, + 711, 81, 81, 81, 712, 687, 698, 700, 713, 687, 687, 81, 714, 715, 715, + 715, 715, 714, 714, 81, 81, 716, 716, 716, 717, 508, 81, 81, 718, 718, + 718, 718, 718, 718, 718, 718, 718, 718, 718, 718, 81, 718, 718, 718, 718, + 718, 718, 718, 718, 718, 718, 81, 718, 718, 718, 81, 718, 718, 81, 718, + 718, 718, 718, 718, 718, 718, 81, 81, 718, 718, 718, 81, 81, 81, 81, 81, + 198, 373, 198, 81, 81, 81, 81, 616, 616, 616, 616, 616, 616, 616, 616, + 616, 616, 616, 616, 616, 81, 81, 81, 313, 719, 719, 719, 719, 719, 719, + 719, 719, 719, 719, 719, 719, 719, 720, 720, 720, 720, 721, 721, 721, + 721, 721, 721, 721, 721, 721, 721, 721, 721, 721, 721, 721, 721, 721, + 720, 720, 721, 722, 722, 81, 40, 40, 40, 40, 81, 81, 81, 81, 721, 81, 81, + 81, 81, 81, 81, 81, 313, 313, 313, 313, 313, 156, 81, 81, 723, 723, 723, + 723, 723, 723, 723, 723, 723, 723, 723, 723, 723, 81, 81, 81, 724, 724, + 724, 724, 724, 724, 724, 724, 724, 81, 81, 81, 81, 81, 81, 81, 156, 500, + 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, + 500, 500, 500, 500, 81, 81, 81, 81, 725, 725, 725, 725, 725, 725, 725, + 725, 726, 726, 726, 726, 81, 81, 81, 81, 81, 81, 81, 81, 81, 725, 725, + 725, 727, 727, 727, 727, 727, 727, 727, 727, 727, 728, 727, 727, 727, + 727, 727, 727, 727, 727, 728, 81, 81, 81, 81, 81, 729, 729, 729, 729, + 729, 729, 729, 729, 729, 729, 729, 729, 729, 729, 730, 730, 730, 730, + 730, 81, 81, 81, 81, 81, 731, 731, 731, 731, 731, 731, 731, 731, 731, + 731, 731, 731, 731, 731, 81, 732, 733, 733, 733, 733, 733, 733, 733, 733, + 733, 733, 733, 733, 81, 81, 81, 81, 734, 735, 735, 735, 735, 735, 81, 81, + 736, 736, 736, 736, 736, 736, 736, 736, 737, 737, 737, 737, 737, 737, + 737, 737, 738, 738, 738, 738, 738, 738, 738, 738, 739, 739, 739, 739, + 739, 739, 739, 739, 739, 739, 739, 739, 739, 739, 81, 81, 740, 740, 740, + 740, 740, 740, 740, 740, 740, 740, 81, 81, 81, 81, 81, 81, 741, 741, 741, + 741, 741, 741, 741, 741, 741, 741, 741, 741, 81, 81, 81, 81, 742, 742, + 742, 742, 742, 742, 742, 742, 742, 742, 742, 742, 81, 81, 81, 81, 743, + 743, 743, 743, 743, 743, 743, 743, 744, 744, 744, 744, 744, 744, 744, + 744, 744, 744, 744, 744, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 745, + 746, 746, 746, 746, 746, 746, 746, 746, 746, 746, 746, 746, 746, 746, + 746, 81, 746, 746, 746, 746, 746, 746, 81, 81, 747, 747, 747, 747, 747, + 747, 81, 81, 747, 81, 747, 747, 747, 747, 747, 747, 747, 747, 747, 747, + 747, 747, 747, 747, 747, 747, 747, 747, 747, 747, 81, 747, 747, 81, 81, + 81, 747, 81, 81, 747, 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, + 748, 748, 748, 748, 81, 749, 750, 750, 750, 750, 750, 750, 750, 750, 751, + 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, + 752, 752, 753, 753, 753, 753, 753, 753, 753, 754, 754, 754, 754, 754, + 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, 81, 81, 81, 81, 81, 81, + 81, 81, 755, 755, 755, 755, 755, 755, 755, 755, 755, 756, 756, 756, 756, + 756, 756, 756, 756, 756, 756, 756, 81, 756, 756, 81, 81, 81, 81, 81, 757, + 757, 757, 757, 757, 758, 758, 758, 758, 758, 758, 758, 758, 758, 758, + 758, 758, 758, 758, 759, 759, 759, 759, 759, 759, 81, 81, 81, 760, 761, + 761, 761, 761, 761, 761, 761, 761, 761, 761, 81, 81, 81, 81, 81, 762, + 763, 763, 763, 763, 763, 763, 763, 763, 764, 764, 764, 764, 764, 764, + 764, 764, 81, 81, 81, 81, 765, 765, 764, 764, 765, 765, 765, 765, 765, + 765, 765, 765, 81, 81, 765, 765, 765, 765, 765, 765, 766, 767, 767, 767, + 81, 767, 767, 81, 81, 81, 81, 81, 767, 768, 767, 769, 766, 766, 766, 766, + 81, 766, 766, 766, 81, 766, 766, 766, 766, 766, 766, 766, 766, 766, 766, + 766, 766, 766, 766, 766, 766, 766, 766, 766, 81, 81, 81, 81, 769, 770, + 768, 81, 81, 81, 81, 771, 772, 772, 772, 772, 772, 772, 772, 772, 773, + 773, 773, 773, 773, 773, 773, 773, 774, 81, 81, 81, 81, 81, 81, 81, 775, + 775, 775, 775, 775, 775, 775, 775, 775, 775, 775, 775, 775, 776, 776, + 777, 778, 778, 778, 778, 778, 778, 778, 778, 778, 778, 778, 778, 778, + 779, 779, 779, 780, 780, 780, 780, 780, 780, 780, 780, 781, 780, 780, + 780, 780, 780, 780, 780, 780, 780, 780, 780, 780, 782, 783, 81, 81, 81, + 81, 784, 784, 784, 784, 784, 785, 785, 785, 785, 785, 785, 786, 81, 787, + 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 81, 81, + 81, 788, 788, 788, 788, 788, 788, 788, 789, 789, 789, 789, 789, 789, 789, + 789, 789, 789, 789, 789, 789, 789, 81, 81, 790, 790, 790, 790, 790, 790, + 790, 790, 791, 791, 791, 791, 791, 791, 791, 791, 791, 791, 791, 81, 81, + 81, 81, 81, 792, 792, 792, 792, 792, 792, 792, 792, 793, 793, 793, 793, + 793, 793, 793, 793, 793, 793, 81, 81, 81, 81, 81, 81, 81, 794, 794, 794, + 794, 81, 81, 81, 81, 795, 795, 795, 795, 795, 795, 795, 796, 796, 796, + 796, 796, 796, 796, 796, 796, 81, 81, 81, 81, 81, 81, 81, 797, 797, 797, + 797, 797, 797, 797, 797, 797, 797, 797, 81, 81, 81, 81, 81, 798, 798, + 798, 798, 798, 798, 798, 798, 798, 798, 798, 81, 81, 81, 81, 81, 81, 81, + 799, 799, 799, 799, 799, 799, 800, 800, 800, 800, 800, 800, 800, 800, + 800, 800, 800, 800, 800, 800, 800, 81, 801, 802, 801, 803, 803, 803, 803, + 803, 803, 803, 803, 803, 803, 803, 803, 803, 802, 802, 802, 802, 802, + 802, 802, 802, 802, 802, 802, 802, 802, 802, 804, 805, 805, 806, 806, + 806, 806, 806, 81, 81, 81, 81, 807, 807, 807, 807, 807, 807, 807, 807, + 807, 807, 807, 807, 807, 807, 807, 807, 807, 807, 807, 807, 808, 808, + 808, 808, 808, 808, 808, 808, 808, 808, 81, 81, 81, 81, 81, 81, 81, 804, + 809, 809, 810, 811, 811, 811, 811, 811, 811, 811, 811, 811, 811, 811, + 811, 811, 810, 810, 810, 809, 809, 809, 809, 810, 810, 812, 813, 814, + 814, 815, 816, 816, 816, 816, 81, 81, 81, 81, 81, 81, 817, 817, 817, 817, + 817, 817, 817, 817, 817, 81, 81, 81, 81, 81, 81, 81, 818, 818, 818, 818, + 818, 818, 818, 818, 818, 818, 81, 81, 81, 81, 81, 81, 819, 819, 819, 820, + 820, 820, 820, 820, 820, 820, 820, 820, 820, 820, 820, 820, 820, 820, + 820, 820, 820, 820, 820, 821, 821, 821, 821, 821, 822, 821, 821, 821, + 821, 821, 821, 823, 823, 81, 824, 824, 824, 824, 824, 824, 824, 824, 824, + 824, 825, 825, 825, 825, 81, 81, 81, 81, 826, 826, 826, 826, 826, 826, + 826, 826, 826, 826, 826, 827, 828, 829, 826, 81, 830, 830, 831, 832, 832, + 832, 832, 832, 832, 832, 832, 832, 832, 832, 832, 832, 832, 832, 832, + 831, 831, 831, 830, 830, 830, 830, 830, 830, 830, 830, 830, 831, 833, + 832, 832, 832, 832, 834, 834, 835, 834, 835, 836, 830, 830, 835, 81, 81, + 837, 837, 837, 837, 837, 837, 837, 837, 837, 837, 832, 838, 832, 834, + 834, 834, 81, 839, 839, 839, 839, 839, 839, 839, 839, 839, 839, 839, 839, + 839, 839, 839, 839, 839, 839, 839, 839, 81, 81, 81, 840, 840, 840, 840, + 840, 840, 840, 840, 840, 840, 81, 840, 840, 840, 840, 840, 840, 840, 840, + 840, 841, 841, 841, 842, 842, 842, 841, 841, 842, 843, 844, 842, 845, + 845, 846, 845, 845, 846, 842, 81, 847, 847, 847, 847, 847, 847, 847, 81, + 847, 81, 847, 847, 847, 847, 81, 847, 847, 847, 847, 847, 847, 847, 847, + 847, 847, 847, 847, 847, 847, 847, 81, 847, 847, 848, 81, 81, 81, 81, 81, + 81, 849, 849, 849, 849, 849, 849, 849, 849, 849, 849, 849, 849, 849, 849, + 849, 850, 851, 851, 851, 850, 850, 850, 850, 850, 850, 852, 853, 81, 81, + 81, 81, 81, 854, 854, 854, 854, 854, 854, 854, 854, 854, 854, 81, 81, 81, + 81, 81, 81, 855, 855, 856, 856, 81, 857, 857, 857, 857, 857, 857, 857, + 857, 81, 81, 857, 857, 81, 81, 857, 857, 857, 857, 857, 857, 857, 857, + 857, 857, 857, 857, 857, 857, 81, 857, 857, 857, 857, 857, 857, 857, 81, + 857, 857, 81, 857, 857, 857, 857, 857, 81, 81, 858, 857, 856, 856, 855, + 856, 856, 856, 856, 81, 81, 856, 856, 81, 81, 856, 856, 859, 81, 81, 857, + 81, 81, 81, 81, 81, 81, 856, 81, 81, 81, 81, 81, 857, 857, 857, 857, 857, + 856, 856, 81, 81, 860, 860, 860, 860, 860, 860, 860, 81, 81, 81, 861, + 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 861, 862, 862, + 862, 863, 863, 863, 863, 863, 863, 863, 863, 862, 862, 864, 863, 863, + 862, 865, 861, 861, 861, 861, 866, 866, 866, 866, 867, 868, 868, 868, + 868, 868, 868, 868, 868, 868, 868, 81, 866, 81, 867, 81, 81, 869, 869, + 869, 869, 869, 869, 869, 869, 870, 870, 870, 871, 871, 871, 871, 871, + 871, 870, 871, 870, 870, 870, 870, 871, 871, 870, 872, 873, 869, 869, + 874, 869, 875, 875, 875, 875, 875, 875, 875, 875, 875, 875, 81, 81, 81, + 81, 81, 81, 876, 876, 876, 876, 876, 876, 876, 876, 876, 876, 876, 876, + 876, 876, 876, 877, 877, 877, 878, 878, 878, 878, 81, 81, 877, 877, 877, + 877, 878, 878, 877, 879, 880, 881, 882, 882, 883, 883, 884, 884, 884, + 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, 882, + 882, 876, 876, 876, 876, 878, 878, 81, 81, 885, 885, 885, 885, 885, 885, + 885, 885, 886, 886, 886, 887, 887, 887, 887, 887, 887, 887, 887, 886, + 886, 887, 886, 888, 887, 889, 889, 890, 885, 81, 81, 81, 891, 891, 891, + 891, 891, 891, 891, 891, 891, 891, 81, 81, 81, 81, 81, 81, 892, 892, 892, + 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, 81, 81, 81, 893, 893, + 893, 893, 893, 893, 893, 893, 893, 893, 893, 894, 895, 894, 895, 895, + 894, 894, 894, 894, 894, 894, 896, 897, 898, 898, 898, 898, 898, 898, + 898, 898, 898, 898, 81, 81, 81, 81, 81, 81, 899, 899, 899, 899, 899, 899, + 899, 899, 899, 899, 81, 81, 81, 900, 900, 900, 901, 901, 900, 900, 900, + 900, 901, 900, 900, 900, 900, 902, 81, 81, 81, 81, 903, 903, 903, 903, + 903, 903, 903, 903, 903, 903, 904, 904, 905, 905, 905, 906, 907, 907, + 907, 907, 907, 907, 907, 907, 908, 908, 908, 908, 908, 908, 908, 908, + 909, 909, 909, 909, 909, 909, 909, 909, 909, 909, 910, 910, 910, 910, + 910, 910, 910, 910, 910, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, + 911, 912, 913, 913, 913, 913, 913, 913, 914, 914, 913, 913, 912, 912, + 912, 912, 912, 912, 912, 912, 912, 912, 912, 912, 912, 912, 912, 912, + 913, 915, 913, 913, 913, 913, 914, 912, 913, 913, 913, 913, 916, 917, + 918, 918, 918, 918, 916, 917, 915, 919, 920, 920, 920, 920, 920, 920, + 921, 921, 920, 920, 920, 919, 919, 919, 919, 919, 919, 919, 919, 919, + 919, 919, 919, 919, 919, 919, 919, 81, 81, 919, 919, 919, 919, 920, 920, + 920, 920, 920, 920, 920, 920, 920, 920, 920, 920, 920, 921, 920, 922, + 923, 923, 923, 81, 924, 924, 924, 923, 923, 81, 81, 81, 81, 81, 925, 925, + 925, 925, 925, 925, 925, 925, 925, 81, 81, 81, 81, 81, 81, 81, 926, 926, + 926, 926, 926, 926, 926, 926, 926, 81, 926, 926, 926, 926, 926, 926, 926, + 926, 926, 926, 926, 926, 926, 927, 928, 928, 928, 928, 928, 928, 928, 81, + 928, 928, 928, 928, 928, 928, 927, 929, 926, 930, 930, 930, 930, 930, 81, + 81, 931, 931, 931, 931, 931, 931, 931, 931, 931, 931, 932, 932, 932, 932, + 932, 932, 932, 932, 932, 932, 932, 932, 932, 932, 932, 932, 932, 932, + 932, 81, 81, 81, 933, 934, 935, 935, 935, 935, 935, 935, 935, 935, 935, + 935, 935, 935, 935, 935, 81, 81, 936, 936, 936, 936, 936, 936, 936, 936, + 936, 936, 936, 936, 936, 936, 81, 937, 936, 936, 936, 936, 936, 936, 936, + 937, 936, 936, 937, 936, 936, 81, 938, 938, 938, 938, 938, 938, 938, 81, + 938, 938, 81, 938, 938, 938, 938, 938, 938, 938, 938, 938, 938, 938, 938, + 938, 938, 939, 939, 939, 939, 939, 939, 81, 81, 81, 939, 81, 939, 939, + 81, 939, 939, 939, 940, 939, 941, 941, 938, 939, 942, 942, 942, 942, 942, + 942, 942, 942, 942, 942, 81, 81, 81, 81, 81, 81, 943, 943, 943, 943, 943, + 943, 943, 943, 943, 943, 81, 81, 81, 81, 81, 81, 944, 944, 944, 944, 944, + 944, 944, 944, 944, 944, 944, 944, 944, 944, 944, 81, 945, 945, 945, 945, + 945, 81, 81, 81, 943, 943, 943, 943, 81, 81, 81, 81, 946, 946, 946, 946, + 946, 946, 946, 946, 947, 947, 947, 948, 948, 948, 946, 946, 946, 946, + 948, 946, 946, 946, 947, 948, 947, 948, 946, 946, 946, 946, 946, 946, + 946, 947, 948, 948, 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, + 946, 81, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, 949, + 949, 950, 951, 949, 949, 949, 949, 949, 949, 949, 81, 605, 81, 81, 81, + 81, 81, 81, 81, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, + 952, 952, 952, 952, 81, 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, + 81, 81, 81, 81, 954, 954, 955, 955, 955, 955, 955, 955, 955, 955, 955, + 955, 955, 955, 955, 955, 81, 81, 956, 956, 956, 956, 956, 957, 81, 81, + 958, 958, 958, 958, 958, 958, 958, 958, 959, 959, 959, 959, 959, 959, + 959, 960, 960, 960, 961, 961, 962, 962, 962, 962, 963, 963, 963, 963, + 960, 962, 81, 81, 964, 964, 964, 964, 964, 964, 964, 964, 964, 964, 81, + 965, 965, 965, 965, 965, 965, 965, 81, 958, 958, 958, 958, 958, 81, 81, + 81, 81, 81, 958, 958, 958, 966, 966, 966, 966, 966, 966, 966, 966, 966, + 966, 966, 966, 966, 81, 81, 81, 966, 967, 967, 967, 967, 967, 967, 967, + 967, 967, 967, 967, 967, 967, 967, 967, 967, 967, 967, 967, 967, 967, + 967, 81, 81, 81, 81, 81, 81, 81, 81, 968, 968, 968, 968, 969, 969, 969, + 969, 969, 969, 969, 969, 969, 969, 969, 969, 969, 970, 971, 81, 81, 81, + 81, 81, 81, 972, 972, 972, 972, 972, 972, 972, 972, 972, 972, 972, 972, + 972, 81, 81, 81, 972, 972, 972, 81, 81, 81, 81, 81, 576, 571, 571, 571, + 571, 571, 571, 571, 571, 571, 571, 571, 571, 571, 571, 81, 973, 973, 973, + 973, 973, 973, 973, 973, 973, 973, 973, 973, 81, 81, 81, 81, 974, 974, + 974, 974, 974, 974, 974, 974, 974, 974, 974, 81, 81, 81, 81, 81, 974, + 974, 974, 974, 974, 81, 81, 81, 974, 81, 81, 81, 81, 81, 81, 81, 974, + 974, 81, 81, 975, 976, 977, 978, 499, 499, 499, 499, 81, 81, 81, 81, 313, + 313, 313, 313, 313, 313, 81, 81, 313, 313, 313, 313, 313, 313, 313, 81, + 81, 313, 313, 313, 313, 313, 313, 313, 313, 313, 313, 313, 313, 979, 979, + 447, 447, 447, 313, 313, 313, 980, 979, 979, 979, 979, 979, 499, 499, + 499, 499, 499, 499, 499, 499, 156, 156, 156, 156, 156, 156, 156, 156, + 313, 313, 96, 96, 96, 96, 96, 156, 156, 313, 313, 313, 313, 313, 313, 96, + 96, 96, 96, 313, 313, 313, 81, 81, 81, 81, 81, 81, 81, 721, 721, 981, + 981, 981, 721, 81, 81, 616, 616, 81, 81, 81, 81, 81, 81, 506, 506, 506, + 506, 506, 506, 506, 506, 506, 506, 49, 49, 49, 49, 49, 49, 49, 49, 49, + 49, 49, 49, 49, 49, 49, 49, 49, 49, 506, 506, 506, 506, 506, 506, 506, + 506, 506, 506, 49, 49, 49, 49, 49, 49, 49, 81, 49, 49, 49, 49, 49, 49, + 506, 81, 506, 506, 81, 81, 506, 81, 81, 506, 506, 81, 81, 506, 506, 506, + 506, 81, 506, 506, 49, 49, 81, 49, 81, 49, 49, 49, 49, 49, 49, 49, 81, + 49, 49, 49, 49, 49, 49, 49, 506, 506, 81, 506, 506, 506, 506, 81, 81, + 506, 506, 506, 506, 506, 506, 506, 506, 81, 506, 506, 506, 506, 506, 506, + 506, 81, 49, 49, 506, 506, 81, 506, 506, 506, 506, 81, 506, 506, 506, + 506, 506, 81, 506, 81, 81, 81, 506, 506, 506, 506, 506, 506, 506, 81, 49, + 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 81, 81, 506, 982, 49, 49, 49, + 49, 49, 49, 49, 49, 49, 492, 49, 49, 49, 49, 49, 49, 506, 506, 506, 506, + 506, 506, 506, 506, 506, 982, 49, 49, 49, 49, 49, 49, 49, 49, 49, 492, + 49, 49, 506, 506, 506, 506, 506, 982, 49, 49, 49, 49, 49, 49, 49, 49, 49, + 492, 49, 49, 49, 49, 49, 49, 506, 506, 506, 506, 506, 506, 506, 506, 506, + 982, 49, 492, 49, 49, 49, 49, 49, 49, 49, 49, 506, 49, 81, 81, 983, 983, + 983, 983, 983, 983, 983, 983, 983, 983, 984, 984, 984, 984, 984, 984, + 984, 984, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, 985, + 985, 985, 985, 984, 984, 984, 984, 985, 985, 985, 985, 985, 985, 985, + 985, 985, 985, 984, 984, 984, 984, 984, 984, 984, 984, 985, 984, 984, + 984, 984, 984, 984, 985, 984, 984, 986, 986, 986, 986, 987, 81, 81, 81, + 81, 81, 81, 81, 985, 985, 985, 985, 985, 81, 985, 985, 985, 985, 985, + 985, 985, 988, 988, 988, 988, 988, 988, 988, 81, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 81, 81, 988, 988, 988, 988, 988, 988, 988, 81, 988, + 988, 81, 988, 988, 988, 988, 988, 81, 81, 81, 81, 81, 989, 989, 989, 989, + 989, 989, 989, 989, 989, 989, 989, 989, 989, 81, 81, 990, 990, 990, 990, + 990, 990, 990, 990, 990, 991, 991, 991, 991, 991, 991, 991, 81, 992, 992, + 992, 992, 992, 992, 992, 992, 992, 992, 993, 993, 993, 993, 993, 993, + 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 993, 994, 994, + 994, 994, 994, 994, 995, 81, 81, 81, 81, 81, 996, 996, 996, 996, 996, + 996, 996, 996, 996, 996, 81, 81, 81, 81, 997, 997, 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, 525, 525, 525, 525, 521, 525, 525, 525, 525, 525, + 525, 525, 525, 525, 525, 525, 525, 525, 525, 525, 998, 998, 998, 998, + 998, 998, 998, 998, 998, 998, 998, 998, 525, 525, 525, 525, 525, 525, + 525, 998, 998, 525, 525, 525, 525, 525, 525, 525, 525, 525, 525, 525, + 525, 525, 525, 521, 525, 525, 525, 525, 525, 525, 998, 998, 47, 47, 47, + 515, 515, 998, 998, 998, 526, 526, 526, 526, 526, 526, 313, 998, 526, + 526, 40, 40, 998, 998, 998, 998, 526, 526, 526, 526, 526, 526, 999, 526, + 526, 999, 999, 999, 999, 999, 999, 999, 999, 999, 999, 526, 526, 526, + 526, 526, 526, 526, 526, 526, 526, 998, 998, 998, 998, 998, 998, 998, + 998, 998, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, + 1001, 582, 582, 998, 998, 998, 998, 998, 582, 582, 582, 582, 998, 998, + 998, 998, 582, 998, 998, 998, 998, 998, 998, 998, 582, 582, 998, 998, + 998, 998, 998, 998, 521, 521, 521, 521, 521, 521, 998, 998, 521, 525, + 525, 525, 525, 525, 525, 525, 525, 525, 525, 525, 525, 521, 521, 521, + 521, 521, 521, 521, 521, 521, 525, 521, 521, 521, 521, 521, 521, 525, + 521, 521, 521, 521, 521, 521, 521, 532, 521, 521, 521, 521, 521, 521, + 525, 525, 525, 525, 525, 525, 525, 525, 40, 40, 525, 525, 521, 521, 521, + 521, 521, 524, 524, 521, 521, 521, 521, 521, 524, 521, 521, 521, 521, + 521, 532, 532, 532, 521, 521, 532, 521, 521, 532, 530, 530, 525, 525, + 521, 521, 525, 525, 525, 521, 525, 525, 525, 521, 521, 521, 1002, 1002, + 1002, 1002, 1002, 521, 521, 521, 521, 521, 521, 521, 525, 521, 525, 532, + 532, 521, 521, 532, 532, 532, 532, 532, 532, 532, 532, 532, 532, 532, + 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 532, + 532, 532, 532, 521, 521, 521, 521, 532, 521, 532, 521, 521, 521, 532, + 521, 521, 521, 521, 532, 532, 532, 521, 532, 532, 532, 524, 521, 524, + 521, 524, 521, 521, 521, 521, 521, 532, 521, 521, 521, 521, 524, 521, + 524, 524, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, 525, 525, + 521, 524, 524, 524, 524, 524, 524, 524, 521, 521, 521, 521, 521, 521, + 521, 521, 524, 524, 524, 524, 524, 524, 521, 521, 521, 521, 521, 524, + 524, 524, 524, 524, 524, 524, 524, 524, 524, 524, 524, 40, 40, 40, 40, + 525, 521, 521, 521, 521, 525, 525, 525, 525, 525, 530, 530, 525, 525, + 525, 525, 532, 525, 525, 525, 525, 525, 530, 525, 525, 525, 525, 532, + 532, 525, 525, 525, 525, 525, 40, 40, 40, 40, 40, 40, 40, 40, 525, 525, + 525, 525, 40, 40, 525, 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, + 532, 532, 532, 521, 521, 521, 532, 532, 532, 532, 532, 40, 40, 40, 40, + 40, 40, 534, 534, 534, 1003, 1003, 1003, 40, 40, 40, 40, 521, 521, 521, + 532, 521, 521, 521, 521, 521, 521, 521, 521, 532, 532, 532, 521, 532, + 521, 521, 521, 521, 521, 525, 525, 525, 525, 525, 525, 532, 525, 525, + 525, 521, 521, 521, 525, 525, 998, 998, 998, 525, 525, 525, 521, 521, + 998, 998, 998, 525, 525, 525, 525, 521, 521, 521, 521, 521, 998, 998, + 998, 998, 998, 998, 998, 40, 40, 40, 40, 998, 998, 998, 998, 40, 40, 40, + 40, 40, 998, 998, 998, 40, 40, 998, 998, 998, 998, 998, 998, 40, 40, 40, + 40, 40, 40, 998, 998, 532, 532, 532, 532, 532, 521, 532, 532, 521, 521, + 521, 521, 521, 521, 532, 521, 532, 532, 521, 521, 521, 532, 532, 998, + 521, 521, 521, 521, 521, 998, 998, 998, 521, 521, 521, 521, 998, 998, + 998, 998, 521, 532, 532, 532, 532, 532, 532, 532, 532, 532, 532, 532, + 532, 532, 521, 521, 521, 521, 521, 521, 521, 521, 521, 998, 998, 998, + 998, 998, 998, 998, 81, 81, 589, 589, 589, 589, 589, 589, 589, 590, 589, + 589, 589, 589, 589, 590, 590, 590, 589, 590, 590, 590, 590, 590, 590, + 590, 590, 590, 590, 590, 590, 590, 81, 81, 81, 499, 81, 81, 81, 81, 81, + 81, 499, 499, 499, 499, 499, 499, 499, 499, 667, 667, 667, 667, 667, 667, + 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, 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, 0, 0, 0, 0, + 13082, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13085, 13088, 13091, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13093, 13095, 13097, 13099, 13101, + 13103, 13105, 13107, 13109, 13111, 13113, 13115, 13117, 13119, 13121, + 13123, 13125, 13127, 13129, 13131, 13133, 13135, 13137, 13139, 13141, + 13143, 13145, 13147, 13149, 13151, 13153, 13155, 13157, 13159, 13161, + 13163, 13165, 13167, 13169, 13171, 13173, 13175, 13177, 13179, 0, 0, 0, + 0, 13181, 13185, 13189, 13193, 13197, 13201, 13205, 13209, 13213, 0, 0, + 0, 0, 0, 0, 0, 13217, 13219, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 13221, 13223, 13225, 13227, 13230, 13232, 13234, 13236, 13238, 13240, + 13242, 13244, 13246, 13248, 13251, 13253, 13255, 13257, 13259, 13262, + 13264, 13266, 13268, 13271, 13273, 13275, 13277, 13279, 13281, 13284, + 13286, 13288, 13290, 13292, 13294, 13296, 13298, 13300, 13302, 13304, + 13306, 13308, 13310, 13312, 13314, 13316, 13318, 13320, 13322, 13324, + 13326, 13328, 13330, 13333, 13335, 13337, 13339, 13342, 13344, 13346, + 13348, 13350, 13352, 13354, 13356, 13358, 13360, 13362, 13364, 13366, + 13368, 13370, 13372, 13374, 13376, 13378, 13380, 13382, 13384, 13386, + 13388, 13390, 13392, 13394, 13396, 13398, 13400, 13402, 13404, 13406, + 13409, 13411, 13413, 13415, 13417, 13419, 13421, 13424, 13427, 13429, + 13431, 13433, 13435, 13437, 13439, 13441, 13443, 13445, 13447, 13450, + 13452, 13454, 13456, 13458, 13461, 13463, 13465, 13467, 13469, 13471, + 13473, 13475, 13477, 13479, 13482, 13484, 13487, 13489, 13491, 13493, + 13495, 13497, 13499, 13501, 13503, 13505, 13507, 13509, 13512, 13514, + 13516, 13518, 13520, 13522, 13525, 13527, 13530, 13533, 13535, 13537, + 13539, 13541, 13544, 13547, 13549, 13551, 13553, 13555, 13557, 13559, + 13561, 13563, 13565, 13567, 13569, 13572, 13574, 13576, 13578, 13580, + 13582, 13584, 13586, 13588, 13590, 13592, 13594, 13596, 13598, 13600, + 13602, 13604, 13606, 13608, 13610, 13613, 13615, 13617, 13619, 13621, + 13623, 13626, 13628, 13630, 13632, 13634, 13636, 13638, 13640, 13642, + 13644, 13646, 13648, 13651, 13653, 13655, 13657, 13659, 13661, 13663, + 13665, 13667, 13669, 13671, 13673, 13675, 13677, 13679, 13681, 13683, + 13685, 13687, 13690, 13692, 13694, 13696, 13698, 13700, 13703, 13705, + 13707, 13709, 13711, 13713, 13715, 13717, 13719, 13722, 13724, 13726, + 13728, 13731, 13733, 13735, 13737, 13739, 13741, 13743, 13746, 13749, + 13752, 13754, 13757, 13759, 13761, 13763, 13765, 13767, 13769, 13771, + 13773, 13775, 13777, 13780, 13782, 13784, 13786, 13788, 13790, 13792, + 13795, 13797, 13799, 13802, 13805, 13807, 13809, 13811, 13813, 13815, + 13817, 13819, 13821, 13823, 13826, 13828, 13831, 13833, 13836, 13838, + 13840, 13842, 13845, 13847, 13849, 13852, 13855, 13857, 13859, 13861, + 13863, 13865, 13867, 13869, 13871, 13873, 13875, 13877, 13879, 13881, + 13884, 13886, 13889, 13891, 13894, 13896, 13899, 13902, 13905, 13907, + 13909, 13911, 13914, 13917, 13920, 13923, 13925, 13927, 13929, 13931, + 13933, 13935, 13937, 13939, 13942, 13944, 13946, 13948, 13950, 13953, + 13955, 13958, 13961, 13963, 13965, 13967, 13969, 13971, 13973, 13976, + 13979, 13982, 13984, 13986, 13989, 13991, 13993, 13995, 13998, 14000, + 14002, 14004, 14006, 14008, 14011, 14013, 14015, 14017, 14019, 14021, + 14023, 14026, 14029, 14031, 14034, 14036, 14039, 14041, 14043, 14045, + 14048, 14051, 14053, 14056, 14058, 14061, 14063, 14065, 14067, 14069, + 14071, 14073, 14076, 14079, 14082, 14085, 14087, 14089, 14091, 14093, + 14095, 14097, 14099, 14101, 14103, 14105, 14107, 14109, 14112, 14114, + 14116, 14118, 14120, 14122, 14124, 14126, 14128, 14130, 14132, 14134, + 14136, 14139, 14142, 14145, 14147, 14149, 14151, 14153, 14156, 14158, + 14161, 14163, 14165, 14168, 14171, 14173, 14175, 14177, 14179, 14181, + 14183, 14185, 14187, 14189, 14191, 14193, 14195, 14197, 14199, 14201, + 14203, 14205, 14207, 14209, 14212, 14214, 14216, 14218, 14220, 14222, + 14225, 14228, 14230, 14232, 14234, 14236, 14238, 14240, 14243, 14245, + 14247, 14249, 14251, 14254, 14257, 14259, 14261, 14263, 14266, 14268, + 14270, 14273, 14276, 14278, 14280, 14282, 14285, 14287, 14289, 14291, + 14293, 14295, 14297, 14299, 14302, 14304, 14306, 14308, 14311, 14313, + 14315, 14317, 14319, 14322, 14325, 14327, 14329, 14331, 14334, 14336, + 14339, 14341, 14343, 14345, 14348, 14350, 14352, 14354, 14356, 14358, + 14360, 14362, 14365, 14367, 14369, 14371, 14373, 14375, 14377, 14380, + 14382, 14385, 14388, 14391, 14393, 14395, 14397, 14399, 14401, 14403, + 14405, 14407, 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, +}; + diff --git a/chromium/third_party/harfbuzz-ng/src/hb-unicode-private.hh b/chromium/third_party/harfbuzz-ng/src/src/hb-unicode-private.hh index 82bb9a4ddc7..82bb9a4ddc7 100644 --- a/chromium/third_party/harfbuzz-ng/src/hb-unicode-private.hh +++ b/chromium/third_party/harfbuzz-ng/src/src/hb-unicode-private.hh diff --git a/chromium/third_party/harfbuzz-ng/src/hb-unicode.cc b/chromium/third_party/harfbuzz-ng/src/src/hb-unicode.cc index 726baeb0f19..726baeb0f19 100644 --- a/chromium/third_party/harfbuzz-ng/src/hb-unicode.cc +++ b/chromium/third_party/harfbuzz-ng/src/src/hb-unicode.cc diff --git a/chromium/third_party/harfbuzz-ng/src/hb-unicode.h b/chromium/third_party/harfbuzz-ng/src/src/hb-unicode.h index 2657f481300..2657f481300 100644 --- a/chromium/third_party/harfbuzz-ng/src/hb-unicode.h +++ b/chromium/third_party/harfbuzz-ng/src/src/hb-unicode.h diff --git a/chromium/third_party/harfbuzz-ng/src/src/hb-uniscribe.cc b/chromium/third_party/harfbuzz-ng/src/src/hb-uniscribe.cc new file mode 100644 index 00000000000..cd25769db1a --- /dev/null +++ b/chromium/third_party/harfbuzz-ng/src/src/hb-uniscribe.cc @@ -0,0 +1,1039 @@ +/* + * Copyright © 2011,2012,2013 Google, Inc. + * + * This is part of HarfBuzz, a text shaping library. + * + * Permission is hereby granted, without written agreement and without + * license or royalty fees, to use, copy, modify, and distribute this + * software and its documentation for any purpose, provided that the + * above copyright notice and the following two paragraphs appear in + * all copies of this software. + * + * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR + * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES + * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN + * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, + * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS + * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO + * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + * + * Google Author(s): Behdad Esfahbod + */ + +#include "hb-private.hh" +#include "hb-debug.hh" +#define HB_SHAPER uniscribe +#include "hb-shaper-impl-private.hh" + +#include <windows.h> +#include <usp10.h> +#include <rpc.h> + +#include "hb-uniscribe.h" + +#include "hb-open-file-private.hh" +#include "hb-ot-name-table.hh" +#include "hb-ot-tag.h" + + +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, + int cMaxItems, + const SCRIPT_CONTROL *psControl, + const SCRIPT_STATE *psState, + SCRIPT_ITEM *pItems, + OPENTYPE_TAG *pScriptTags, + int *pcItems +); + +typedef HRESULT (WINAPI *SSOT) /*ScriptShapeOpenType*/( + HDC hdc, + SCRIPT_CACHE *psc, + SCRIPT_ANALYSIS *psa, + OPENTYPE_TAG tagScript, + OPENTYPE_TAG tagLangSys, + int *rcRangeChars, + TEXTRANGE_PROPERTIES **rpRangeProperties, + int cRanges, + const WCHAR *pwcChars, + int cChars, + int cMaxGlyphs, + WORD *pwLogClust, + SCRIPT_CHARPROP *pCharProps, + WORD *pwOutGlyphs, + SCRIPT_GLYPHPROP *pOutGlyphProps, + int *pcGlyphs +); + +typedef HRESULT (WINAPI *SPOT) /*ScriptPlaceOpenType*/( + HDC hdc, + SCRIPT_CACHE *psc, + SCRIPT_ANALYSIS *psa, + OPENTYPE_TAG tagScript, + OPENTYPE_TAG tagLangSys, + int *rcRangeChars, + TEXTRANGE_PROPERTIES **rpRangeProperties, + int cRanges, + const WCHAR *pwcChars, + WORD *pwLogClust, + SCRIPT_CHARPROP *pCharProps, + int cChars, + const WORD *pwGlyphs, + const SCRIPT_GLYPHPROP *pGlyphProps, + int cGlyphs, + int *piAdvance, + GOFFSET *pGoffset, + ABC *pABC +); + + +/* Fallback implementations. */ + +static HRESULT WINAPI +hb_ScriptItemizeOpenType( + const WCHAR *pwcInChars, + int cInChars, + int cMaxItems, + const SCRIPT_CONTROL *psControl, + const SCRIPT_STATE *psState, + SCRIPT_ITEM *pItems, + OPENTYPE_TAG *pScriptTags, + int *pcItems +) +{ +{ + return ScriptItemize (pwcInChars, + cInChars, + cMaxItems, + psControl, + psState, + pItems, + pcItems); +} +} + +static HRESULT WINAPI +hb_ScriptShapeOpenType( + HDC hdc, + SCRIPT_CACHE *psc, + SCRIPT_ANALYSIS *psa, + OPENTYPE_TAG tagScript, + OPENTYPE_TAG tagLangSys, + int *rcRangeChars, + TEXTRANGE_PROPERTIES **rpRangeProperties, + int cRanges, + const WCHAR *pwcChars, + int cChars, + int cMaxGlyphs, + WORD *pwLogClust, + SCRIPT_CHARPROP *pCharProps, + WORD *pwOutGlyphs, + SCRIPT_GLYPHPROP *pOutGlyphProps, + int *pcGlyphs +) +{ + SCRIPT_VISATTR *psva = (SCRIPT_VISATTR *) pOutGlyphProps; + return ScriptShape (hdc, + psc, + pwcChars, + cChars, + cMaxGlyphs, + psa, + pwOutGlyphs, + pwLogClust, + psva, + pcGlyphs); +} + +static HRESULT WINAPI +hb_ScriptPlaceOpenType( + HDC hdc, + SCRIPT_CACHE *psc, + SCRIPT_ANALYSIS *psa, + OPENTYPE_TAG tagScript, + OPENTYPE_TAG tagLangSys, + int *rcRangeChars, + TEXTRANGE_PROPERTIES **rpRangeProperties, + int cRanges, + const WCHAR *pwcChars, + WORD *pwLogClust, + SCRIPT_CHARPROP *pCharProps, + int cChars, + const WORD *pwGlyphs, + const SCRIPT_GLYPHPROP *pGlyphProps, + int cGlyphs, + int *piAdvance, + GOFFSET *pGoffset, + ABC *pABC +) +{ + SCRIPT_VISATTR *psva = (SCRIPT_VISATTR *) pGlyphProps; + return ScriptPlace (hdc, + psc, + pwGlyphs, + cGlyphs, + psva, + psa, + piAdvance, + pGoffset, + pABC); +} + + +struct hb_uniscribe_shaper_funcs_t { + SIOT ScriptItemizeOpenType; + SSOT ScriptShapeOpenType; + SPOT ScriptPlaceOpenType; + + inline void init (void) + { + HMODULE hinstLib; + this->ScriptItemizeOpenType = nullptr; + this->ScriptShapeOpenType = nullptr; + this->ScriptPlaceOpenType = nullptr; + + hinstLib = GetModuleHandle (TEXT ("usp10.dll")); + if (hinstLib) + { + this->ScriptItemizeOpenType = (SIOT) GetProcAddress (hinstLib, "ScriptItemizeOpenType"); + this->ScriptShapeOpenType = (SSOT) GetProcAddress (hinstLib, "ScriptShapeOpenType"); + this->ScriptPlaceOpenType = (SPOT) GetProcAddress (hinstLib, "ScriptPlaceOpenType"); + } + if (!this->ScriptItemizeOpenType || + !this->ScriptShapeOpenType || + !this->ScriptPlaceOpenType) + { + DEBUG_MSG (UNISCRIBE, nullptr, "OpenType versions of functions not found; falling back."); + this->ScriptItemizeOpenType = hb_ScriptItemizeOpenType; + this->ScriptShapeOpenType = hb_ScriptShapeOpenType; + this->ScriptPlaceOpenType = hb_ScriptPlaceOpenType; + } + } +}; +static hb_uniscribe_shaper_funcs_t *uniscribe_funcs; + +static inline void +free_uniscribe_funcs (void) +{ + free (uniscribe_funcs); +} + +static hb_uniscribe_shaper_funcs_t * +hb_uniscribe_shaper_get_funcs (void) +{ +retry: + hb_uniscribe_shaper_funcs_t *funcs = (hb_uniscribe_shaper_funcs_t *) hb_atomic_ptr_get (&uniscribe_funcs); + + if (unlikely (!funcs)) + { + funcs = (hb_uniscribe_shaper_funcs_t *) calloc (1, sizeof (hb_uniscribe_shaper_funcs_t)); + if (unlikely (!funcs)) + return nullptr; + + funcs->init (); + + if (!hb_atomic_ptr_cmpexch (&uniscribe_funcs, nullptr, funcs)) { + free (funcs); + goto retry; + } + +#ifdef HB_USE_ATEXIT + atexit (free_uniscribe_funcs); /* First person registers atexit() callback. */ +#endif + } + + return funcs; +} + + +struct active_feature_t { + OPENTYPE_FEATURE_RECORD rec; + unsigned int order; + + 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 : + a->order < b->order ? -1 : a->order > b->order ? 1 : + a->rec.lParameter < b->rec.lParameter ? -1 : a->rec.lParameter > b->rec.lParameter ? 1 : + 0; + } + bool operator== (const active_feature_t *f) { + return cmp (this, f) == 0; + } +}; + +struct feature_event_t { + unsigned int index; + bool start; + active_feature_t feature; + + static int cmp (const void *pa, const void *pb) { + const feature_event_t *a = (const feature_event_t *) pa; + const feature_event_t *b = (const feature_event_t *) pb; + return a->index < b->index ? -1 : a->index > b->index ? 1 : + a->start < b->start ? -1 : a->start > b->start ? 1 : + active_feature_t::cmp (&a->feature, &b->feature); + } +}; + +struct range_record_t { + TEXTRANGE_PROPERTIES props; + unsigned int index_first; /* == start */ + unsigned int index_last; /* == end - 1 */ +}; + +HB_SHAPER_DATA_ENSURE_DEFINE(uniscribe, face) +HB_SHAPER_DATA_ENSURE_DEFINE(uniscribe, font) + + +/* + * shaper face data + */ + +struct hb_uniscribe_shaper_face_data_t { + HANDLE fh; + hb_uniscribe_shaper_funcs_t *funcs; + wchar_t face_name[LF_FACESIZE]; +}; + +/* face_name should point to a wchar_t[LF_FACESIZE] object. */ +static void +_hb_generate_unique_face_name (wchar_t *face_name, unsigned int *plen) +{ + /* We'll create a private name for the font from a UUID using a simple, + * somewhat base64-like encoding scheme */ + const char *enc = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+-"; + UUID id; + UuidCreate ((UUID*) &id); + static_assert ((2 + 3 * (16/2) < LF_FACESIZE), ""); + unsigned int name_str_len = 0; + face_name[name_str_len++] = 'F'; + face_name[name_str_len++] = '_'; + unsigned char *p = (unsigned char *) &id; + for (unsigned int i = 0; i < 16; i += 2) + { + /* Spread the 16 bits from two bytes of the UUID across three chars of face_name, + * using the bits in groups of 5,5,6 to select chars from enc. + * This will generate 24 characters; with the 'F_' prefix we already provided, + * the name will be 26 chars (plus the NUL terminator), so will always fit within + * face_name (LF_FACESIZE = 32). */ + face_name[name_str_len++] = enc[p[i] >> 3]; + face_name[name_str_len++] = enc[((p[i] << 2) | (p[i + 1] >> 6)) & 0x1f]; + face_name[name_str_len++] = enc[p[i + 1] & 0x3f]; + } + face_name[name_str_len] = 0; + if (plen) + *plen = name_str_len; +} + +/* Destroys blob. */ +static hb_blob_t * +_hb_rename_font (hb_blob_t *blob, wchar_t *new_name) +{ + /* Create a copy of the font data, with the 'name' table replaced by a + * table that names the font with our private F_* name created above. + * For simplicity, we just append a new 'name' table and update the + * sfnt directory; the original table is left in place, but unused. + * + * The new table will contain just 5 name IDs: family, style, unique, + * full, PS. All of them point to the same name data with our unique name. + */ + + blob = OT::Sanitizer<OT::OpenTypeFontFile>().sanitize (blob); + + unsigned int length, new_length, name_str_len; + const char *orig_sfnt_data = hb_blob_get_data (blob, &length); + + _hb_generate_unique_face_name (new_name, &name_str_len); + + 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 */ + unsigned int name_table_offset = (length + 3) & ~3; + + new_length = name_table_offset + ((name_table_length + 3) & ~3); + void *new_sfnt_data = calloc (1, new_length); + if (!new_sfnt_data) + { + hb_blob_destroy (blob); + return nullptr; + } + + memcpy(new_sfnt_data, orig_sfnt_data, length); + + OT::name &name = OT::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 ()); + for (unsigned int i = 0; i < ARRAY_LENGTH (name_IDs); i++) + { + OT::NameRecord &record = name.nameRecord[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); + } + + /* Copy string data from new_name, converting wchar_t to UTF16BE. */ + unsigned char *p = &OT::StructAfter<unsigned char> (name); + for (unsigned int i = 0; i < name_str_len; i++) + { + *p++ = new_name[i] >> 8; + *p++ = new_name[i] & 0xff; + } + + /* Adjust name table entry to point to new name table */ + const OT::OpenTypeFontFile &file = * (OT::OpenTypeFontFile *) (new_sfnt_data); + unsigned int face_count = file.get_face_count (); + for (unsigned int face_index = 0; face_index < face_count; face_index++) + { + /* Note: doing multiple edits (ie. TTC) can be unsafe. There may be + * toe-stepping. But we don't really care. */ + const OT::OpenTypeFontFace &face = file.get_face (face_index); + unsigned int index; + if (face.find_table_index (HB_OT_TAG_name, &index)) + { + OT::TableRecord &record = const_cast<OT::TableRecord &> (face.get_table (index)); + record.checkSum.set_for_data (&name, name_table_length); + record.offset.set (name_table_offset); + record.length.set (name_table_length); + } + else if (face_index == 0) /* Fail if first face doesn't have 'name' table. */ + { + free (new_sfnt_data); + hb_blob_destroy (blob); + return nullptr; + } + } + + /* The checkSumAdjustment field in the 'head' table is now wrong, + * but that doesn't actually seem to cause any problems so we don't + * bother. */ + + hb_blob_destroy (blob); + return hb_blob_create ((const char *) new_sfnt_data, new_length, + HB_MEMORY_MODE_WRITABLE, nullptr, free); +} + +hb_uniscribe_shaper_face_data_t * +_hb_uniscribe_shaper_face_data_create (hb_face_t *face) +{ + hb_uniscribe_shaper_face_data_t *data = (hb_uniscribe_shaper_face_data_t *) calloc (1, sizeof (hb_uniscribe_shaper_face_data_t)); + if (unlikely (!data)) + return nullptr; + + data->funcs = hb_uniscribe_shaper_get_funcs (); + if (unlikely (!data->funcs)) + { + free (data); + return nullptr; + } + + hb_blob_t *blob = hb_face_reference_blob (face); + if (unlikely (!hb_blob_get_length (blob))) + DEBUG_MSG (UNISCRIBE, face, "Face has empty blob"); + + blob = _hb_rename_font (blob, data->face_name); + if (unlikely (!blob)) + { + free (data); + return nullptr; + } + + DWORD num_fonts_installed; + data->fh = AddFontMemResourceEx ((void *) hb_blob_get_data (blob, nullptr), + hb_blob_get_length (blob), + 0, &num_fonts_installed); + if (unlikely (!data->fh)) + { + DEBUG_MSG (UNISCRIBE, face, "Face AddFontMemResourceEx() failed"); + free (data); + return nullptr; + } + + return data; +} + +void +_hb_uniscribe_shaper_face_data_destroy (hb_uniscribe_shaper_face_data_t *data) +{ + RemoveFontMemResourceEx (data->fh); + free (data); +} + + +/* + * shaper font data + */ + +struct hb_uniscribe_shaper_font_data_t { + HDC hdc; + LOGFONTW log_font; + HFONT hfont; + SCRIPT_CACHE script_cache; + double x_mult, y_mult; /* From LOGFONT space to HB space. */ +}; + +static bool +populate_log_font (LOGFONTW *lf, + hb_font_t *font, + unsigned int font_size) +{ + memset (lf, 0, sizeof (*lf)); + lf->lfHeight = - (int) font_size; + lf->lfCharSet = DEFAULT_CHARSET; + + hb_face_t *face = font->face; + hb_uniscribe_shaper_face_data_t *face_data = HB_SHAPER_DATA_GET (face); + + memcpy (lf->lfFaceName, face_data->face_name, sizeof (lf->lfFaceName)); + + return true; +} + +hb_uniscribe_shaper_font_data_t * +_hb_uniscribe_shaper_font_data_create (hb_font_t *font) +{ + if (unlikely (!hb_uniscribe_shaper_face_data_ensure (font->face))) return nullptr; + + hb_uniscribe_shaper_font_data_t *data = (hb_uniscribe_shaper_font_data_t *) calloc (1, sizeof (hb_uniscribe_shaper_font_data_t)); + if (unlikely (!data)) + return nullptr; + + int font_size = font->face->get_upem (); /* Default... */ + /* No idea if the following is even a good idea. */ + if (font->y_ppem) + font_size = font->y_ppem; + + if (font_size < 0) + font_size = -font_size; + data->x_mult = (double) font->x_scale / font_size; + data->y_mult = (double) font->y_scale / font_size; + + data->hdc = GetDC (nullptr); + + if (unlikely (!populate_log_font (&data->log_font, font, font_size))) { + DEBUG_MSG (UNISCRIBE, font, "Font populate_log_font() failed"); + _hb_uniscribe_shaper_font_data_destroy (data); + return nullptr; + } + + data->hfont = CreateFontIndirectW (&data->log_font); + if (unlikely (!data->hfont)) { + DEBUG_MSG (UNISCRIBE, font, "Font CreateFontIndirectW() failed"); + _hb_uniscribe_shaper_font_data_destroy (data); + return nullptr; + } + + if (!SelectObject (data->hdc, data->hfont)) { + DEBUG_MSG (UNISCRIBE, font, "Font SelectObject() failed"); + _hb_uniscribe_shaper_font_data_destroy (data); + return nullptr; + } + + return data; +} + +void +_hb_uniscribe_shaper_font_data_destroy (hb_uniscribe_shaper_font_data_t *data) +{ + if (data->hdc) + ReleaseDC (nullptr, data->hdc); + if (data->hfont) + DeleteObject (data->hfont); + if (data->script_cache) + ScriptFreeCache (&data->script_cache); + free (data); +} + +LOGFONTW * +hb_uniscribe_font_get_logfontw (hb_font_t *font) +{ + if (unlikely (!hb_uniscribe_shaper_font_data_ensure (font))) return nullptr; + hb_uniscribe_shaper_font_data_t *font_data = HB_SHAPER_DATA_GET (font); + return &font_data->log_font; +} + +HFONT +hb_uniscribe_font_get_hfont (hb_font_t *font) +{ + if (unlikely (!hb_uniscribe_shaper_font_data_ensure (font))) return nullptr; + hb_uniscribe_shaper_font_data_t *font_data = HB_SHAPER_DATA_GET (font); + return font_data->hfont; +} + + +/* + * shaper shape_plan data + */ + +struct hb_uniscribe_shaper_shape_plan_data_t {}; + +hb_uniscribe_shaper_shape_plan_data_t * +_hb_uniscribe_shaper_shape_plan_data_create (hb_shape_plan_t *shape_plan HB_UNUSED, + const hb_feature_t *user_features HB_UNUSED, + unsigned int num_user_features HB_UNUSED, + const int *coords HB_UNUSED, + unsigned int num_coords HB_UNUSED) +{ + return (hb_uniscribe_shaper_shape_plan_data_t *) HB_SHAPER_DATA_SUCCEEDED; +} + +void +_hb_uniscribe_shaper_shape_plan_data_destroy (hb_uniscribe_shaper_shape_plan_data_t *data HB_UNUSED) +{ +} + + +/* + * shaper + */ + + +hb_bool_t +_hb_uniscribe_shape (hb_shape_plan_t *shape_plan, + hb_font_t *font, + hb_buffer_t *buffer, + const hb_feature_t *features, + unsigned int num_features) +{ + hb_face_t *face = font->face; + hb_uniscribe_shaper_face_data_t *face_data = HB_SHAPER_DATA_GET (face); + hb_uniscribe_shaper_font_data_t *font_data = HB_SHAPER_DATA_GET (font); + hb_uniscribe_shaper_funcs_t *funcs = face_data->funcs; + + /* + * Set up features. + */ + hb_auto_array_t<OPENTYPE_FEATURE_RECORD> feature_records; + hb_auto_array_t<range_record_t> range_records; + if (num_features) + { + /* Sort features by start/end events. */ + hb_auto_array_t<feature_event_t> feature_events; + for (unsigned int i = 0; i < num_features; i++) + { + active_feature_t feature; + feature.rec.tagFeature = hb_uint32_swap (features[i].tag); + feature.rec.lParameter = features[i].value; + feature.order = i; + + feature_event_t *event; + + event = feature_events.push (); + if (unlikely (!event)) + goto fail_features; + event->index = features[i].start; + event->start = true; + event->feature = feature; + + event = feature_events.push (); + if (unlikely (!event)) + goto fail_features; + event->index = features[i].end; + event->start = false; + event->feature = feature; + } + feature_events.qsort (); + /* Add a strategic final event. */ + { + active_feature_t feature; + feature.rec.tagFeature = 0; + feature.rec.lParameter = 0; + feature.order = num_features + 1; + + feature_event_t *event = feature_events.push (); + if (unlikely (!event)) + goto fail_features; + event->index = 0; /* This value does magic. */ + event->start = false; + event->feature = feature; + } + + /* Scan events and save features for each range. */ + hb_auto_array_t<active_feature_t> active_features; + unsigned int last_index = 0; + for (unsigned int i = 0; i < feature_events.len; i++) + { + feature_event_t *event = &feature_events[i]; + + if (event->index != last_index) + { + /* Save a snapshot of active features and the range. */ + range_record_t *range = range_records.push (); + if (unlikely (!range)) + goto fail_features; + + unsigned int offset = feature_records.len; + + active_features.qsort (); + for (unsigned int j = 0; j < active_features.len; j++) + { + if (!j || active_features[j].rec.tagFeature != feature_records[feature_records.len - 1].tagFeature) + { + OPENTYPE_FEATURE_RECORD *feature = feature_records.push (); + if (unlikely (!feature)) + goto fail_features; + *feature = active_features[j].rec; + } + else + { + /* Overrides value for existing feature. */ + feature_records[feature_records.len - 1].lParameter = active_features[j].rec.lParameter; + } + } + + /* Will convert to pointer after all is ready, since feature_records.array + * may move as we grow it. */ + range->props.potfRecords = reinterpret_cast<OPENTYPE_FEATURE_RECORD *> (offset); + range->props.cotfRecords = feature_records.len - offset; + range->index_first = last_index; + range->index_last = event->index - 1; + + last_index = event->index; + } + + if (event->start) { + active_feature_t *feature = active_features.push (); + if (unlikely (!feature)) + goto fail_features; + *feature = event->feature; + } else { + active_feature_t *feature = active_features.find (&event->feature); + if (feature) + active_features.remove (feature - active_features.array); + } + } + + if (!range_records.len) /* No active feature found. */ + goto fail_features; + + /* Fixup the pointers. */ + for (unsigned int i = 0; i < range_records.len; i++) + { + range_record_t *range = &range_records[i]; + range->props.potfRecords = feature_records.array + reinterpret_cast<uintptr_t> (range->props.potfRecords); + } + } + else + { + fail_features: + num_features = 0; + } + +#define FAIL(...) \ + HB_STMT_START { \ + DEBUG_MSG (UNISCRIBE, nullptr, __VA_ARGS__); \ + return false; \ + } HB_STMT_END; + + HRESULT hr; + +retry: + + unsigned int scratch_size; + hb_buffer_t::scratch_buffer_t *scratch = buffer->get_scratch_buffer (&scratch_size); + +#define ALLOCATE_ARRAY(Type, name, len) \ + Type *name = (Type *) scratch; \ + { \ + unsigned int _consumed = DIV_CEIL ((len) * sizeof (Type), sizeof (*scratch)); \ + assert (_consumed <= scratch_size); \ + scratch += _consumed; \ + scratch_size -= _consumed; \ + } + +#define utf16_index() var1.u32 + + ALLOCATE_ARRAY (WCHAR, pchars, buffer->len * 2); + + unsigned int chars_len = 0; + for (unsigned int i = 0; i < buffer->len; i++) + { + hb_codepoint_t c = buffer->info[i].codepoint; + buffer->info[i].utf16_index() = chars_len; + if (likely (c <= 0xFFFFu)) + pchars[chars_len++] = c; + else if (unlikely (c > 0x10FFFFu)) + pchars[chars_len++] = 0xFFFDu; + else { + pchars[chars_len++] = 0xD800u + ((c - 0x10000u) >> 10); + pchars[chars_len++] = 0xDC00u + ((c - 0x10000u) & ((1u << 10) - 1)); + } + } + + ALLOCATE_ARRAY (WORD, log_clusters, chars_len); + ALLOCATE_ARRAY (SCRIPT_CHARPROP, char_props, chars_len); + + if (num_features) + { + /* Need log_clusters to assign features. */ + chars_len = 0; + for (unsigned int i = 0; i < buffer->len; i++) + { + hb_codepoint_t c = buffer->info[i].codepoint; + unsigned int cluster = buffer->info[i].cluster; + log_clusters[chars_len++] = cluster; + if (hb_in_range (c, 0x10000u, 0x10FFFFu)) + log_clusters[chars_len++] = cluster; /* Surrogates. */ + } + } + + /* The -2 in the following is to compensate for possible + * alignment needed after the WORD array. sizeof(WORD) == 2. */ + unsigned int glyphs_size = (scratch_size * sizeof (int) - 2) + / (sizeof (WORD) + + sizeof (SCRIPT_GLYPHPROP) + + sizeof (int) + + sizeof (GOFFSET) + + sizeof (uint32_t)); + + ALLOCATE_ARRAY (WORD, glyphs, glyphs_size); + ALLOCATE_ARRAY (SCRIPT_GLYPHPROP, glyph_props, glyphs_size); + ALLOCATE_ARRAY (int, advances, glyphs_size); + ALLOCATE_ARRAY (GOFFSET, offsets, glyphs_size); + ALLOCATE_ARRAY (uint32_t, vis_clusters, glyphs_size); + + /* Note: + * We can't touch the contents of glyph_props. Our fallback + * implementations of Shape and Place functions use that buffer + * by casting it to a different type. It works because they + * both agree about it, but if we want to access it here we + * need address that issue first. + */ + +#undef ALLOCATE_ARRAY + +#define MAX_ITEMS 256 + + SCRIPT_ITEM items[MAX_ITEMS + 1]; + SCRIPT_CONTROL bidi_control = {0}; + SCRIPT_STATE bidi_state = {0}; + ULONG script_tags[MAX_ITEMS]; + int item_count; + + /* MinGW32 doesn't define fMergeNeutralItems, so we bruteforce */ + //bidi_control.fMergeNeutralItems = true; + *(uint32_t*)&bidi_control |= 1u<<24; + + bidi_state.uBidiLevel = HB_DIRECTION_IS_FORWARD (buffer->props.direction) ? 0 : 1; + bidi_state.fOverrideDirection = 1; + + hr = funcs->ScriptItemizeOpenType (pchars, + chars_len, + MAX_ITEMS, + &bidi_control, + &bidi_state, + items, + script_tags, + &item_count); + if (unlikely (FAILED (hr))) + FAIL ("ScriptItemizeOpenType() failed: 0x%08xL", hr); + +#undef MAX_ITEMS + + OPENTYPE_TAG language_tag = hb_uint32_swap (hb_ot_tag_from_language (buffer->props.language)); + hb_auto_array_t<TEXTRANGE_PROPERTIES*> range_properties; + hb_auto_array_t<int> range_char_counts; + + unsigned int glyphs_offset = 0; + unsigned int glyphs_len; + bool backward = HB_DIRECTION_IS_BACKWARD (buffer->props.direction); + for (int i = 0; i < item_count; i++) + { + unsigned int chars_offset = items[i].iCharPos; + unsigned int item_chars_len = items[i + 1].iCharPos - chars_offset; + + if (num_features) + { + range_properties.shrink (0); + range_char_counts.shrink (0); + + range_record_t *last_range = &range_records[0]; + + for (unsigned int k = chars_offset; k < chars_offset + item_chars_len; k++) + { + range_record_t *range = last_range; + while (log_clusters[k] < range->index_first) + range--; + while (log_clusters[k] > range->index_last) + range++; + if (!range_properties.len || + &range->props != range_properties[range_properties.len - 1]) + { + TEXTRANGE_PROPERTIES **props = range_properties.push (); + int *c = range_char_counts.push (); + if (unlikely (!props || !c)) + { + range_properties.shrink (0); + range_char_counts.shrink (0); + break; + } + *props = &range->props; + *c = 1; + } + else + { + range_char_counts[range_char_counts.len - 1]++; + } + + last_range = range; + } + } + + /* Asking for glyphs in logical order circumvents at least + * one bug in Uniscribe. */ + items[i].a.fLogicalOrder = true; + + retry_shape: + hr = funcs->ScriptShapeOpenType (font_data->hdc, + &font_data->script_cache, + &items[i].a, + script_tags[i], + language_tag, + range_char_counts.array, + range_properties.array, + range_properties.len, + pchars + chars_offset, + item_chars_len, + glyphs_size - glyphs_offset, + /* out */ + log_clusters + chars_offset, + char_props + chars_offset, + glyphs + glyphs_offset, + glyph_props + glyphs_offset, + (int *) &glyphs_len); + + if (unlikely (items[i].a.fNoGlyphIndex)) + FAIL ("ScriptShapeOpenType() set fNoGlyphIndex"); + if (unlikely (hr == E_OUTOFMEMORY || hr == E_NOT_SUFFICIENT_BUFFER)) + { + if (unlikely (!buffer->ensure (buffer->allocated * 2))) + FAIL ("Buffer resize failed"); + goto retry; + } + if (unlikely (hr == USP_E_SCRIPT_NOT_IN_FONT)) + { + if (items[i].a.eScript == SCRIPT_UNDEFINED) + FAIL ("ScriptShapeOpenType() failed: Font doesn't support script"); + items[i].a.eScript = SCRIPT_UNDEFINED; + goto retry_shape; + } + if (unlikely (FAILED (hr))) + { + FAIL ("ScriptShapeOpenType() failed: 0x%08xL", hr); + } + + for (unsigned int j = chars_offset; j < chars_offset + item_chars_len; j++) + log_clusters[j] += glyphs_offset; + + hr = funcs->ScriptPlaceOpenType (font_data->hdc, + &font_data->script_cache, + &items[i].a, + script_tags[i], + language_tag, + range_char_counts.array, + range_properties.array, + range_properties.len, + pchars + chars_offset, + log_clusters + chars_offset, + char_props + chars_offset, + item_chars_len, + glyphs + glyphs_offset, + glyph_props + glyphs_offset, + glyphs_len, + /* out */ + advances + glyphs_offset, + offsets + glyphs_offset, + nullptr); + if (unlikely (FAILED (hr))) + FAIL ("ScriptPlaceOpenType() failed: 0x%08xL", hr); + + if (DEBUG_ENABLED (UNISCRIBE)) + fprintf (stderr, "Item %d RTL %d LayoutRTL %d LogicalOrder %d ScriptTag %c%c%c%c\n", + i, + items[i].a.fRTL, + items[i].a.fLayoutRTL, + items[i].a.fLogicalOrder, + HB_UNTAG (hb_uint32_swap (script_tags[i]))); + + glyphs_offset += glyphs_len; + } + glyphs_len = glyphs_offset; + + /* Ok, we've got everything we need, now compose output buffer, + * very, *very*, carefully! */ + + /* Calculate visual-clusters. That's what we ship. */ + for (unsigned int i = 0; i < glyphs_len; i++) + vis_clusters[i] = -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); + } + for (unsigned int i = 1; i < glyphs_len; i++) + if (vis_clusters[i] == -1) + vis_clusters[i] = vis_clusters[i - 1]; + +#undef utf16_index + + if (unlikely (!buffer->ensure (glyphs_len))) + FAIL ("Buffer in error"); + +#undef FAIL + + /* Set glyph infos */ + buffer->len = 0; + for (unsigned int i = 0; i < glyphs_len; i++) + { + hb_glyph_info_t *info = &buffer->info[buffer->len++]; + + info->codepoint = glyphs[i]; + info->cluster = vis_clusters[i]; + + /* The rest is crap. Let's store position info there for now. */ + info->mask = advances[i]; + info->var1.i32 = offsets[i].du; + info->var2.i32 = offsets[i].dv; + } + + /* Set glyph positions */ + buffer->clear_positions (); + double x_mult = font_data->x_mult, y_mult = font_data->y_mult; + for (unsigned int i = 0; i < glyphs_len; i++) + { + hb_glyph_info_t *info = &buffer->info[i]; + hb_glyph_position_t *pos = &buffer->pos[i]; + + /* TODO vertical */ + pos->x_advance = x_mult * (int32_t) info->mask; + pos->x_offset = x_mult * (backward ? -info->var1.i32 : info->var1.i32); + pos->y_offset = y_mult * info->var2.i32; + } + + if (backward) + hb_buffer_reverse (buffer); + + buffer->unsafe_to_break_all (); + + /* Wow, done! */ + return true; +} + + diff --git a/chromium/third_party/harfbuzz-ng/src/src/hb-uniscribe.h b/chromium/third_party/harfbuzz-ng/src/src/hb-uniscribe.h new file mode 100644 index 00000000000..4e4ef9986a6 --- /dev/null +++ b/chromium/third_party/harfbuzz-ng/src/src/hb-uniscribe.h @@ -0,0 +1,46 @@ +/* + * Copyright © 2011 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_UNISCRIBE_H +#define HB_UNISCRIBE_H + +#include "hb.h" + +#include <windows.h> + +HB_BEGIN_DECLS + + +HB_EXTERN LOGFONTW * +hb_uniscribe_font_get_logfontw (hb_font_t *font); + +HB_EXTERN HFONT +hb_uniscribe_font_get_hfont (hb_font_t *font); + + +HB_END_DECLS + +#endif /* HB_UNISCRIBE_H */ diff --git a/chromium/third_party/harfbuzz-ng/src/hb-utf-private.hh b/chromium/third_party/harfbuzz-ng/src/src/hb-utf-private.hh index 211eb4dc023..211eb4dc023 100644 --- a/chromium/third_party/harfbuzz-ng/src/hb-utf-private.hh +++ b/chromium/third_party/harfbuzz-ng/src/src/hb-utf-private.hh diff --git a/chromium/third_party/harfbuzz-ng/src/hb-version.h b/chromium/third_party/harfbuzz-ng/src/src/hb-version.h index f0f5a1814e2..27509326061 100644 --- a/chromium/third_party/harfbuzz-ng/src/hb-version.h +++ b/chromium/third_party/harfbuzz-ng/src/src/hb-version.h @@ -38,9 +38,9 @@ HB_BEGIN_DECLS #define HB_VERSION_MAJOR 1 #define HB_VERSION_MINOR 7 -#define HB_VERSION_MICRO 5 +#define HB_VERSION_MICRO 6 -#define HB_VERSION_STRING "1.7.5" +#define HB_VERSION_STRING "1.7.6" #define HB_VERSION_ATLEAST(major,minor,micro) \ ((major)*10000+(minor)*100+(micro) <= \ diff --git a/chromium/third_party/harfbuzz-ng/src/src/hb-version.h.in b/chromium/third_party/harfbuzz-ng/src/src/hb-version.h.in new file mode 100644 index 00000000000..0ffd889b278 --- /dev/null +++ b/chromium/third_party/harfbuzz-ng/src/src/hb-version.h.in @@ -0,0 +1,66 @@ +/* + * Copyright © 2011 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_H_IN +#error "Include <hb.h> instead." +#endif + +#ifndef HB_VERSION_H +#define HB_VERSION_H + +#include "hb-common.h" + +HB_BEGIN_DECLS + + +#define HB_VERSION_MAJOR @HB_VERSION_MAJOR@ +#define HB_VERSION_MINOR @HB_VERSION_MINOR@ +#define HB_VERSION_MICRO @HB_VERSION_MICRO@ + +#define HB_VERSION_STRING "@HB_VERSION@" + +#define HB_VERSION_ATLEAST(major,minor,micro) \ + ((major)*10000+(minor)*100+(micro) <= \ + HB_VERSION_MAJOR*10000+HB_VERSION_MINOR*100+HB_VERSION_MICRO) + + +HB_EXTERN void +hb_version (unsigned int *major, + unsigned int *minor, + unsigned int *micro); + +HB_EXTERN const char * +hb_version_string (void); + +HB_EXTERN hb_bool_t +hb_version_atleast (unsigned int major, + unsigned int minor, + unsigned int micro); + + +HB_END_DECLS + +#endif /* HB_VERSION_H */ diff --git a/chromium/third_party/harfbuzz-ng/src/hb-warning.cc b/chromium/third_party/harfbuzz-ng/src/src/hb-warning.cc index 8f322bcb10d..8f322bcb10d 100644 --- a/chromium/third_party/harfbuzz-ng/src/hb-warning.cc +++ b/chromium/third_party/harfbuzz-ng/src/src/hb-warning.cc diff --git a/chromium/third_party/harfbuzz-ng/src/hb.h b/chromium/third_party/harfbuzz-ng/src/src/hb.h index 7402034f437..7402034f437 100644 --- a/chromium/third_party/harfbuzz-ng/src/hb.h +++ b/chromium/third_party/harfbuzz-ng/src/src/hb.h diff --git a/chromium/third_party/harfbuzz-ng/src/main.cc b/chromium/third_party/harfbuzz-ng/src/src/main.cc index d221e9da221..d221e9da221 100644 --- a/chromium/third_party/harfbuzz-ng/src/main.cc +++ b/chromium/third_party/harfbuzz-ng/src/src/main.cc diff --git a/chromium/third_party/harfbuzz-ng/src/src/sample.py b/chromium/third_party/harfbuzz-ng/src/src/sample.py new file mode 100755 index 00000000000..844fa4c8c56 --- /dev/null +++ b/chromium/third_party/harfbuzz-ng/src/src/sample.py @@ -0,0 +1,78 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- + +from __future__ import print_function +import sys +import array +from gi.repository import HarfBuzz as hb +from gi.repository import GLib + +# Python 2/3 compatibility +try: + unicode +except NameError: + unicode = str + +def tounicode(s, encoding='utf-8'): + if not isinstance(s, unicode): + return s.decode(encoding) + else: + return s + +fontdata = open (sys.argv[1], 'rb').read () +text = tounicode(sys.argv[2]) +# Need to create GLib.Bytes explicitly until this bug is fixed: +# https://bugzilla.gnome.org/show_bug.cgi?id=729541 +blob = hb.glib_blob_create (GLib.Bytes.new (fontdata)) +face = hb.face_create (blob, 0) +del blob +font = hb.font_create (face) +upem = hb.face_get_upem (face) +del face +hb.font_set_scale (font, upem, upem) +#hb.ft_font_set_funcs (font) +hb.ot_font_set_funcs (font) + +buf = hb.buffer_create () +class Debugger(object): + def message (self, buf, font, msg, data, _x_what_is_this): + print(msg) + return True +debugger = Debugger() +hb.buffer_set_message_func (buf, debugger.message, 1, 0) + +## +## Add text to buffer +## +# +# See https://github.com/harfbuzz/harfbuzz/pull/271 +# +if False: + # If you do not care about cluster values reflecting Python + # string indices, then this is quickest way to add text to + # buffer: + hb.buffer_add_utf8 (buf, text.encode('utf-8'), 0, -1) + # Otherwise, then following handles both narrow and wide + # Python builds: +elif sys.maxunicode == 0x10FFFF: + hb.buffer_add_utf32 (buf, array.array('I', text.encode('utf-32')), 0, -1) +else: + hb.buffer_add_utf16 (buf, array.array('H', text.encode('utf-16')), 0, -1) + + +hb.buffer_guess_segment_properties (buf) + +hb.shape (font, buf, []) +del font + +infos = hb.buffer_get_glyph_infos (buf) +positions = hb.buffer_get_glyph_positions (buf) + +for info,pos in zip(infos, positions): + gid = info.codepoint + cluster = info.cluster + x_advance = pos.x_advance + x_offset = pos.x_offset + y_offset = pos.y_offset + + print("gid%d=%d@%d,%d+%d" % (gid, cluster, x_advance, x_offset, y_offset)) diff --git a/chromium/third_party/harfbuzz-ng/src/test-buffer-serialize.cc b/chromium/third_party/harfbuzz-ng/src/src/test-buffer-serialize.cc index 636b0037542..636b0037542 100644 --- a/chromium/third_party/harfbuzz-ng/src/test-buffer-serialize.cc +++ b/chromium/third_party/harfbuzz-ng/src/src/test-buffer-serialize.cc diff --git a/chromium/third_party/harfbuzz-ng/src/test-size-params.cc b/chromium/third_party/harfbuzz-ng/src/src/test-size-params.cc index 9741b87ef88..9741b87ef88 100644 --- a/chromium/third_party/harfbuzz-ng/src/test-size-params.cc +++ b/chromium/third_party/harfbuzz-ng/src/src/test-size-params.cc diff --git a/chromium/third_party/harfbuzz-ng/src/src/test-unicode-ranges.cc b/chromium/third_party/harfbuzz-ng/src/src/test-unicode-ranges.cc new file mode 100644 index 00000000000..dbc5fa426de --- /dev/null +++ b/chromium/third_party/harfbuzz-ng/src/src/test-unicode-ranges.cc @@ -0,0 +1,67 @@ +/* + * 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-private.hh" + +#include "hb-ot-os2-unicode-ranges.hh" + +void +test (hb_codepoint_t cp, unsigned int bit) +{ + if (OT::hb_get_unicode_range_bit (cp) != bit) + { + fprintf (stderr, "got incorrect bit (%d) for cp 0x%X. Should have been %d.", + OT::hb_get_unicode_range_bit (cp), + cp, + bit); + abort(); + } +} + +void +test_get_unicode_range_bit (void) +{ + test (0x0000, 0); + test (0x0042, 0); + test (0x007F, 0); + test (0x0080, 1); + + test (0x30A0, 50); + test (0x30B1, 50); + test (0x30FF, 50); + + test (0x10FFFD, 90); + + test (0x30000, -1); + test (0x110000, -1); +} + +int +main (void) +{ + test_get_unicode_range_bit (); + return 0; +} diff --git a/chromium/third_party/harfbuzz-ng/src/test-would-substitute.cc b/chromium/third_party/harfbuzz-ng/src/src/test-would-substitute.cc index efebf2d069f..efebf2d069f 100644 --- a/chromium/third_party/harfbuzz-ng/src/test-would-substitute.cc +++ b/chromium/third_party/harfbuzz-ng/src/src/test-would-substitute.cc diff --git a/chromium/third_party/harfbuzz-ng/src/test.cc b/chromium/third_party/harfbuzz-ng/src/src/test.cc index 9592b379e9f..9592b379e9f 100644 --- a/chromium/third_party/harfbuzz-ng/src/test.cc +++ b/chromium/third_party/harfbuzz-ng/src/src/test.cc diff --git a/chromium/third_party/harfbuzz-ng/src/util/Makefile.am b/chromium/third_party/harfbuzz-ng/src/util/Makefile.am new file mode 100644 index 00000000000..d4ab9cdc5ff --- /dev/null +++ b/chromium/third_party/harfbuzz-ng/src/util/Makefile.am @@ -0,0 +1,75 @@ +# Process this file with automake to produce Makefile.in + +NULL = +EXTRA_DIST = +CLEANFILES = +DISTCLEANFILES = +MAINTAINERCLEANFILES = + +include Makefile.sources + +# Convenience targets: +lib: + @$(MAKE) $(AM_MAKEFLAGS) -C $(top_builddir)/src lib + +bin_PROGRAMS = + +AM_CPPFLAGS = \ + -DHB_DISABLE_DEPRECATED \ + -I$(top_srcdir)/src/ \ + -I$(top_builddir)/src/ \ + $(GLIB_CFLAGS) \ + $(FREETYPE_CFLAGS) \ + $(CAIRO_FT_CFLAGS) \ + $(NULL) +LDADD = \ + $(top_builddir)/src/libharfbuzz.la \ + -lm \ + $(GLIB_LIBS) \ + $(FREETYPE_LIBS) \ + $(NULL) + +if HAVE_GLIB + +if HAVE_FREETYPE +if HAVE_CAIRO_FT +hb_view_SOURCES = $(HB_VIEW_sources) +hb_view_LDADD = \ + $(LDADD) \ + $(CAIRO_LIBS) \ + $(CAIRO_FT_LIBS) \ + $(NULL) +bin_PROGRAMS += hb-view +endif # HAVE_CAIRO_FT +endif # HAVE_FREETYPE + +hb_shape_SOURCES = $(HB_SHAPE_sources) +bin_PROGRAMS += hb-shape + +hb_subset_SOURCES = $(HB_SUBSET_CLI_sources) +hb_subset_LDADD = $(LDADD) $(top_builddir)/src/libharfbuzz-subset.la +bin_PROGRAMS += hb-subset + +if HAVE_OT +hb_ot_shape_closure_SOURCES = $(HB_OT_SHAPE_CLOSURE_sources) +bin_PROGRAMS += hb-ot-shape-closure +endif # HAVE_OT + +endif # HAVE_GLIB + +#if HAVE_OT +#if HAVE_FONTCONFIG +#hb_fc_list_SOURCES = \ +# hb-fc.cc \ +# hb-fc.h \ +# hb-fc-list.c \ +# $(NULL) +#hb_fc_list_LDADD = \ +# $(LDADD) \ +# $(FONTCONFIG_LIBS) \ +# $(NULL) +#bin_PROGRAMS += hb-fc-list +#endif # HAVE_FONTCONFIG +#endif # HAVE_OT + +-include $(top_srcdir)/git.mk diff --git a/chromium/third_party/harfbuzz-ng/src/util/Makefile.sources b/chromium/third_party/harfbuzz-ng/src/util/Makefile.sources new file mode 100644 index 00000000000..6c815d26b0a --- /dev/null +++ b/chromium/third_party/harfbuzz-ng/src/util/Makefile.sources @@ -0,0 +1,37 @@ +HB_VIEW_sources = \ + 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 \ + helper-cairo-ansi.cc \ + helper-cairo-ansi.hh \ + view-cairo.cc \ + view-cairo.hh \ + $(NULL) + +HB_SHAPE_sources = \ + hb-shape.cc \ + options.cc \ + options.hh \ + main-font-text.hh \ + shape-consumer.hh \ + $(NULL) + +HB_OT_SHAPE_CLOSURE_sources = \ + hb-ot-shape-closure.cc \ + options.cc \ + options.hh \ + main-font-text.hh \ + $(NULL) + +HB_SUBSET_CLI_sources = \ + hb-subset.cc \ + options.cc \ + options.hh \ + main-font-text.hh \ + $(NULL) diff --git a/chromium/third_party/harfbuzz-ng/src/util/ansi-print.cc b/chromium/third_party/harfbuzz-ng/src/util/ansi-print.cc new file mode 100644 index 00000000000..0daee1f0205 --- /dev/null +++ b/chromium/third_party/harfbuzz-ng/src/util/ansi-print.cc @@ -0,0 +1,427 @@ +/* + * Copyright © 2012 Google, Inc. + * + * This is part of HarfBuzz, a text shaping library. + * + * Permission is hereby granted, without written agreement and without + * license or royalty fees, to use, copy, modify, and distribute this + * software and its documentation for any purpose, provided that the + * above copyright notice and the following two paragraphs appear in + * all copies of this software. + * + * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR + * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES + * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN + * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, + * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS + * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO + * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + * + * Google Author(s): Behdad Esfahbod + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "ansi-print.hh" + +#include <assert.h> +#include <stdlib.h> +#include <stddef.h> +#include <string.h> +#include <stdio.h> +#include <math.h> +#include <fcntl.h> +#ifdef HAVE_UNISTD_H +#include <unistd.h> /* for isatty() */ +#endif + +#if defined (_MSC_VER) && (_MSC_VER < 1800) +static inline long int +lround (double x) +{ + if (x >= 0) + return floor (x + 0.5); + else + return ceil (x - 0.5); +} +#endif + +#define ESC_E (char)27 + +#define MIN(a,b) ((a) < (b) ? (a) : (b)) + +#define CELL_W 8 +#define CELL_H (2 * CELL_W) + +struct color_diff_t +{ + int dot (const color_diff_t &o) + { return v[0]*o.v[0] + v[1]*o.v[1] + v[2]*o.v[2] + v[3]*o.v[3]; } + + int v[4]; +}; + +struct color_t +{ + static color_t from_ansi (unsigned int x) + { + color_t c = {(0xFF<<24) | ((0xFF*(x&1))<<16) | ((0xFF*((x >> 1)&1))<<8) | (0xFF*((x >> 2)&1))}; + return c; + } + unsigned int to_ansi (void) + { + return ((v >> 23) & 1) | ((v >> 14)&2) | ((v >> 5)&4); + } + + color_diff_t diff (const color_t &o) + { + color_diff_t d; + for (unsigned int i = 0; i < 4; i++) + d.v[i] = (int) ((v >> (i*8))&0xFF) - (int) ((o.v >> (i*8))&0xFF); + return d; + } + + uint32_t v; +}; + +struct image_t +{ + public: + + image_t (unsigned int width_, + unsigned int height_, + const uint32_t *data_, + unsigned int stride_) : + width (width_), + height (height_), + own_data (false), + data ((color_t *) data_), + stride (stride_) {} + image_t (unsigned int width_, + unsigned int height_) : + width (width_), + height (height_), + own_data (true), + data ((color_t *) malloc (sizeof (data[0]) * width * height)), + stride (width) {} + ~image_t (void) + { if (own_data) free (data); } + + color_t &operator () (unsigned int x, unsigned int y) + { return data[x + y * stride]; } + + color_t operator () (unsigned int x, unsigned int y) const + { return data[x + y * stride]; } + + void + copy_sub_image (const image_t &s, + unsigned int x, unsigned int y, + unsigned int w, unsigned int h) + { + assert (x < width); + assert (y < height); + for (unsigned int row = 0; row < h; row++) { + color_t *p = data + x + MIN (y + row, height - 1) * stride; + color_t *q = s.data + row * s.stride; + if (x + w <= width) + for (unsigned int col = 0; col < w; col++) + *q++ = *p++; + else { + unsigned int limit = width - x; + for (unsigned int col = 0; col < limit; col++) + *q++ = *p++; + p--; + for (unsigned int col = limit; col < w; col++) + *q++ = *p; + } + } + } + + const unsigned int width; + const unsigned int height; + + private: + bool own_data; + color_t * const data; + const unsigned int stride; +}; + +struct biimage_t +{ + public: + + biimage_t (unsigned int width, unsigned int height) : + width (width), + height (height), + bg (0), fg (0), unicolor (true), + data ((uint8_t *) malloc (sizeof (data[0]) * width * height)) {} + ~biimage_t (void) + { free (data); } + + void set (const image_t &image) + { + assert (image.width == width); + assert (image.height == height); + 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 ()]++; + } + bg = 0; + for (unsigned int i = 1; i < 8; i++) + if (freq[bg] < freq[i]) + bg = i; + fg = 0; + for (unsigned int i = 1; i < 8; i++) + if (i != bg && freq[fg] < freq[i]) + fg = i; + if (fg == bg || freq[fg] == 0) { + fg = bg; + unicolor = true; + } + else + unicolor = false; + + /* Set the data... */ + + if (unicolor) { + memset (data, 0, sizeof (data[0]) * width * height); + return; + } + + color_t bgc = color_t::from_ansi (bg); + color_t fgc = color_t::from_ansi (fg); + color_diff_t diff = fgc.diff (bgc); + 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)); + (*this)(x, y) = d < 0 ? 0 : d > dd ? 255 : lround (d * 255. / dd); + } + } + + uint8_t &operator () (unsigned int x, unsigned int y) + { return data[x + y * width]; } + + uint8_t operator () (unsigned int x, unsigned int y) const + { return data[x + y * width]; } + + const unsigned int width; + const unsigned int height; + unsigned int bg; + unsigned int fg; + bool unicolor; + + private: + uint8_t * const data; +}; + +const char * +block_best (const biimage_t &bi, bool *inverse) +{ + assert (bi.width <= CELL_W); + assert (bi.height <= CELL_H); + + unsigned int score = (unsigned int) -1; + unsigned int row_sum[CELL_H] = {0}; + unsigned int col_sum[CELL_W] = {0}; + unsigned int row_sum_i[CELL_H] = {0}; + unsigned int col_sum_i[CELL_W] = {0}; + unsigned int quad[2][2] = {{0}}; + unsigned int quad_i[2][2] = {{0}}; + unsigned int total = 0; + unsigned int total_i = 0; + for (unsigned int y = 0; y < bi.height; y++) + for (unsigned int x = 0; x < bi.width; x++) { + unsigned int c = bi (x, y); + unsigned int c_i = 255 - c; + row_sum[y] += c; + row_sum_i[y] += c_i; + col_sum[x] += c; + col_sum_i[x] += c_i; + quad[2 * y / bi.height][2 * x / bi.width] += c; + quad_i[2 * y / bi.height][2 * x / bi.width] += c_i; + total += c; + total_i += c_i; + } + + /* Make the sums cummulative */ + for (unsigned int i = 1; i < bi.height; i++) { + row_sum[i] += row_sum[i - 1]; + row_sum_i[i] += row_sum_i[i - 1]; + } + for (unsigned int i = 1; i < bi.width; i++) { + col_sum[i] += col_sum[i - 1]; + col_sum_i[i] += col_sum_i[i - 1]; + } + + const char *best_c = " "; + + /* Maybe empty is better! */ + if (total < score) { + score = total; + *inverse = false; + best_c = " "; + } + /* Maybe full is better! */ + if (total_i < score) { + score = total_i; + *inverse = true; + best_c = " "; + } + + /* Find best lower line */ + if (1) { + unsigned int best_s = (unsigned int) -1; + bool best_inv = false; + int best_i = 0; + for (unsigned int i = 0; i < bi.height - 1; i++) + { + unsigned int s; + s = row_sum[i] + total_i - row_sum_i[i]; + if (s < best_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_i = i; + best_inv = true; + } + } + if (best_s < score) { + static const char *lower[7] = {"▁", "▂", "▃", "▄", "▅", "▆", "▇"}; + unsigned int which = lround ((double) ((best_i + 1) * 8) / bi.height); + if (1 <= which && which <= 7) { + score = best_s; + *inverse = best_inv; + best_c = lower[7 - which]; + } + } + } + + /* Find best left line */ + if (1) { + unsigned int best_s = (unsigned int) -1; + bool best_inv = false; + int best_i = 0; + for (unsigned int i = 0; i < bi.width - 1; i++) + { + unsigned int s; + s = col_sum[i] + total_i - col_sum_i[i]; + if (s < best_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_i = i; + best_inv = false; + } + } + if (best_s < score) { + static const char *left [7] = {"▏", "▎", "▍", "▌", "▋", "▊", "▉"}; + unsigned int which = lround ((double) ((best_i + 1) * 8) / bi.width); + if (1 <= which && which <= 7) { + score = best_s; + *inverse = best_inv; + best_c = left[which - 1]; + } + } + } + + /* Find best quadrant */ + if (1) { + unsigned int q = 0; + unsigned int qs = 0; + for (unsigned int i = 0; i < 2; i++) + for (unsigned int j = 0; j < 2; j++) + if (quad[i][j] > quad_i[i][j]) { + q += 1 << (2 * i + j); + qs += quad_i[i][j]; + } else + qs += quad[i][j]; + if (qs < score) { + const char *c = nullptr; + bool inv = false; + switch (q) { + case 1: c = "▟"; inv = true; break; + case 2: c = "▙"; inv = true; break; + case 4: c = "▖"; inv = false; break; + case 8: c = "▗"; inv = false; break; + case 9: c = "▚"; inv = false; break; + case 6: c = "▞"; inv = false; break; + case 7: c = "▜"; inv = true; break; + case 11: c = "▜"; inv = true; break; + case 13: c = "▙"; inv = true; break; + case 14: c = "▟"; inv = true; break; + } + if (c) { + score = qs; + *inverse = inv; + best_c = c; + } + } + } + + return best_c; +} + +void +ansi_print_image_rgb24 (const uint32_t *data, + unsigned int width, + unsigned int height, + unsigned int stride) +{ + image_t image (width, height, data, stride); + + unsigned int rows = (height + CELL_H - 1) / CELL_H; + unsigned int cols = (width + CELL_W - 1) / CELL_W; + image_t cell (CELL_W, CELL_H); + biimage_t bi (CELL_W, CELL_H); + unsigned int last_bg = -1, last_fg = -1; + for (unsigned int row = 0; row < rows; row++) { + for (unsigned int col = 0; col < cols; col++) { + 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) { + printf ("%c[%dm", ESC_E, 40 + bi.bg); + last_bg = bi.bg; + } + printf (" "); + } else { + /* Figure out the closest character to the biimage */ + bool inverse = false; + 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); + last_bg = bi.fg; + last_fg = bi.bg; + } + } else { + if (last_bg != bi.bg || last_fg != bi.fg) { + printf ("%c[%d;%dm", ESC_E, 40 + bi.bg, 30 + bi.fg); + last_bg = bi.bg; + last_fg = bi.fg; + } + } + printf ("%s", c); + } + } + printf ("%c[0m\n", ESC_E); /* Reset */ + last_bg = last_fg = -1; + } +} diff --git a/chromium/third_party/harfbuzz-ng/src/util/ansi-print.hh b/chromium/third_party/harfbuzz-ng/src/util/ansi-print.hh new file mode 100644 index 00000000000..1ea5b374213 --- /dev/null +++ b/chromium/third_party/harfbuzz-ng/src/util/ansi-print.hh @@ -0,0 +1,40 @@ +/* + * Copyright © 2012 Google, Inc. + * + * This is part of HarfBuzz, a text shaping library. + * + * Permission is hereby granted, without written agreement and without + * license or royalty fees, to use, copy, modify, and distribute this + * software and its documentation for any purpose, provided that the + * above copyright notice and the following two paragraphs appear in + * all copies of this software. + * + * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR + * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES + * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN + * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, + * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS + * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO + * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + * + * Google Author(s): Behdad Esfahbod + */ + +#ifndef ANSI_PRINT_HH +#define ANSI_PRINT_HH + +#include "hb-private.hh" +#include <hb.h> /* for int types */ + +void +ansi_print_image_rgb24 (const uint32_t *data, + unsigned int width, + unsigned int height, + unsigned int stride); + + +#endif diff --git a/chromium/third_party/harfbuzz-ng/src/util/hb-fc-list.c b/chromium/third_party/harfbuzz-ng/src/util/hb-fc-list.c new file mode 100644 index 00000000000..573d11e7c5f --- /dev/null +++ b/chromium/third_party/harfbuzz-ng/src/util/hb-fc-list.c @@ -0,0 +1,222 @@ +/* + * Copyright © 2002 Keith Packard + * Copyright © 2014 Google, Inc. + * + * Permission to use, copy, modify, distribute, and sell this software and its + * documentation for any purpose is hereby granted without fee, provided that + * the above copyright notice appear in all copies and that both that + * copyright notice and this permission notice appear in supporting + * documentation, and that the name of the author(s) not be used in + * advertising or publicity pertaining to distribution of the software without + * specific, written prior permission. The authors make no + * representations about the suitability of this software for any purpose. It + * is provided "as is" without express or implied warranty. + * + * THE AUTHOR(S) DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + * EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY SPECIAL, 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. + * + * Google Author(s): Behdad Esfahbod + */ + +#define HAVE_GETOPT_LONG 1 /* XXX */ + +#include "hb-fc.h" + +#include <fontconfig/fontconfig.h> +#include <stdio.h> +#include <unistd.h> +#include <stdlib.h> +#include <string.h> +#ifdef HAVE_CONFIG_H +#include <config.h> +#else +#ifdef linux +#define HAVE_GETOPT_LONG 1 +#endif +#define HAVE_GETOPT 1 +#endif + +#ifndef HAVE_GETOPT +#define HAVE_GETOPT 0 +#endif +#ifndef HAVE_GETOPT_LONG +#define HAVE_GETOPT_LONG 0 +#endif + +#if HAVE_GETOPT_LONG +#undef _GNU_SOURCE +#define _GNU_SOURCE +#include <getopt.h> +const struct option longopts[] = { + {"verbose", 0, 0, 'v'}, + {"format", 1, 0, 'f'}, + {"quiet", 0, 0, 'q'}, + {"version", 0, 0, 'V'}, + {"help", 0, 0, 'h'}, + {NULL,0,0,0}, +}; +#else +#if HAVE_GETOPT +extern char *optarg; +extern int optind, opterr, optopt; +#endif +#endif + +static void +usage (char *program, int error) +{ + FILE *file = error ? stderr : stdout; +#if HAVE_GETOPT_LONG + fprintf (file, "usage: %s [-vqVh] [-f FORMAT] [--verbose] [--format=FORMAT] [--quiet] [--version] [--help] text [pattern] {element ...} \n", + program); +#else + fprintf (file, "usage: %s [-vqVh] [-f FORMAT] text [pattern] {element ...} \n", + program); +#endif + fprintf (file, "List fonts matching [pattern] that can render [text]\n"); + fprintf (file, "\n"); +#if HAVE_GETOPT_LONG + fprintf (file, " -v, --verbose display entire font pattern verbosely\n"); + fprintf (file, " -f, --format=FORMAT use the given output format\n"); + fprintf (file, " -q, --quiet suppress all normal output, exit 1 if no fonts matched\n"); + fprintf (file, " -V, --version display font config version and exit\n"); + fprintf (file, " -h, --help display this help and exit\n"); +#else + fprintf (file, " -v (verbose) display entire font pattern verbosely\n"); + fprintf (file, " -f FORMAT (format) use the given output format\n"); + fprintf (file, " -q, (quiet) suppress all normal output, exit 1 if no fonts matched\n"); + fprintf (file, " -V (version) display HarfBuzz version and exit\n"); + fprintf (file, " -h (help) display this help and exit\n"); +#endif + exit (error); +} + +int +main (int argc, char **argv) +{ + int verbose = 0; + int quiet = 0; + const FcChar8 *format = NULL; + int nfont = 0; + int i; + FcObjectSet *os = 0; + FcFontSet *fs; + FcPattern *pat; + const char *text; +#if HAVE_GETOPT_LONG || HAVE_GETOPT + int c; + +#if HAVE_GETOPT_LONG + while ((c = getopt_long (argc, argv, "vf:qVh", longopts, NULL)) != -1) +#else + while ((c = getopt (argc, argv, "vf:qVh")) != -1) +#endif + { + switch (c) { + case 'v': + verbose = 1; + break; + case 'f': + format = (FcChar8 *) strdup (optarg); + break; + case 'q': + quiet = 1; + break; + case 'V': + fprintf (stderr, "fontconfig version %d.%d.%d\n", + FC_MAJOR, FC_MINOR, FC_REVISION); + exit (0); + case 'h': + usage (argv[0], 0); + default: + usage (argv[0], 1); + } + } + i = optind; +#else + i = 1; +#endif + + if (!argv[i]) + usage (argv[0], 1); + + text = argv[i]; + i++; + + if (argv[i]) + { + pat = FcNameParse ((FcChar8 *) argv[i]); + if (!pat) + { + fputs ("Unable to parse the pattern\n", stderr); + return 1; + } + while (argv[++i]) + { + if (!os) + os = FcObjectSetCreate (); + FcObjectSetAdd (os, argv[i]); + } + } + else + pat = FcPatternCreate (); + if (quiet && !os) + os = FcObjectSetCreate (); + if (!verbose && !format && !os) + os = FcObjectSetBuild (FC_FAMILY, FC_STYLE, FC_FILE, (char *) 0); + FcObjectSetAdd (os, FC_CHARSET); + if (!format) + format = (const FcChar8 *) "%{=fclist}\n"; + fs = FcFontList (0, pat, os); + if (os) + FcObjectSetDestroy (os); + if (pat) + FcPatternDestroy (pat); + + if (!quiet && fs) + { + int j; + + for (j = 0; j < fs->nfont; j++) + { + hb_font_t *font = hb_fc_font_create (fs->fonts[j]); + hb_bool_t can_render = hb_fc_can_render (font, text); + hb_font_destroy (font); + + if (!can_render) + continue; + + FcPatternDel (fs->fonts[j], FC_CHARSET); + + if (verbose) + { + FcPatternPrint (fs->fonts[j]); + } + else + { + FcChar8 *s; + + s = FcPatternFormat (fs->fonts[j], format); + if (s) + { + printf ("%s", s); + FcStrFree (s); + } + } + } + } + + if (fs) { + nfont = fs->nfont; + FcFontSetDestroy (fs); + } + + FcFini (); + + return quiet ? (nfont == 0 ? 1 : 0) : 0; +} diff --git a/chromium/third_party/harfbuzz-ng/src/util/hb-fc.cc b/chromium/third_party/harfbuzz-ng/src/util/hb-fc.cc new file mode 100644 index 00000000000..cb899914c2d --- /dev/null +++ b/chromium/third_party/harfbuzz-ng/src/util/hb-fc.cc @@ -0,0 +1,149 @@ +/* + * Copyright © 2014 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 + */ + +#include <stdlib.h> +#include <stdio.h> + +#include "hb-fc.h" + +static hb_bool_t +hb_fc_get_glyph (hb_font_t *font /*HB_UNUSED*/, + void *font_data, + hb_codepoint_t unicode, + hb_codepoint_t variation_selector, + hb_codepoint_t *glyph, + void *user_data /*HB_UNUSED*/) + +{ + FcCharSet *cs = (FcCharSet *) font_data; + + if (variation_selector) + { + /* Fontconfig doesn't cache cmap-14 info. However: + * 1. If the font maps the variation_selector, assume it's + * supported, + * 2. If the font doesn't map it, still say it's supported, + * but return 0. This way, the caller will see the zero + * and reject. If we return unsupported here, then the + * variation selector will be hidden and ignored. + */ + if (FcCharSetHasChar (cs, unicode) && + FcCharSetHasChar (cs, variation_selector)) + { + unsigned int var_num = 0; + if (variation_selector - 0xFE00u < 16) + var_num = variation_selector - 0xFE00 + 1; + else if (variation_selector - 0xE0100u < (256 - 16)) + var_num = variation_selector - 0xE0100 + 17; + *glyph = (var_num << 21) | unicode; + } + else + { + *glyph = 0; + } + return true; + } + + *glyph = FcCharSetHasChar (cs, unicode) ? unicode : 0; + return *glyph != 0; +} + +static hb_font_funcs_t * +_hb_fc_get_font_funcs (void) +{ + static const hb_font_funcs_t *fc_ffuncs; + + const hb_font_funcs_t *ffuncs; + + if (!(ffuncs = fc_ffuncs)) + { + hb_font_funcs_t *newfuncs = hb_font_funcs_create (); + + hb_font_funcs_set_glyph_func (newfuncs, hb_fc_get_glyph, nullptr, nullptr); + + /* XXX MT-unsafe */ + if (fc_ffuncs) + hb_font_funcs_destroy (newfuncs); + else + fc_ffuncs = ffuncs = newfuncs; + } + + return const_cast<hb_font_funcs_t *> (fc_ffuncs); +} + + +hb_font_t * +hb_fc_font_create (FcPattern *fcfont) +{ + static hb_face_t *face; + hb_font_t *font; + + FcCharSet *cs; + if (FcResultMatch != FcPatternGetCharSet (fcfont, FC_CHARSET, 0, &cs)) + return hb_font_get_empty (); + + if (!face) /* XXX MT-unsafe */ + face = hb_face_create (hb_blob_get_empty (), 0); + + font = hb_font_create (face); + + hb_font_set_funcs (font, + _hb_fc_get_font_funcs (), + FcCharSetCopy (cs), + (hb_destroy_func_t) FcCharSetDestroy); + + return font; +} + +hb_bool_t +hb_fc_can_render (hb_font_t *font, const char *text) +{ + static const char *ot[] = {"ot", nullptr}; + + hb_buffer_t *buffer = hb_buffer_create (); + hb_buffer_add_utf8 (buffer, text, -1, 0, -1); + + /* XXX Do we need this? I think Arabic and Hangul shapers are the + * only one that make any use of this. The Hangul case is not really + * needed, and for Arabic we'll miss a very narrow set of fonts. + * Might be better to force generic shaper perhaps. */ + hb_buffer_guess_segment_properties (buffer); + + if (!hb_shape_full (font, buffer, nullptr, 0, ot)) + abort (); /* hb-ot shaper not enabled? */ + + unsigned int len; + hb_glyph_info_t *info = hb_buffer_get_glyph_infos (buffer, &len); + for (unsigned int i = 0; i < len; i++) + { + if (!info[i].codepoint) + { + return false; + } + } + + return true; +} diff --git a/chromium/third_party/harfbuzz-ng/src/util/hb-fc.h b/chromium/third_party/harfbuzz-ng/src/util/hb-fc.h new file mode 100644 index 00000000000..bb2f78a8237 --- /dev/null +++ b/chromium/third_party/harfbuzz-ng/src/util/hb-fc.h @@ -0,0 +1,46 @@ +/* + * Copyright © 2014 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_FC_H +#define HB_FC_H + +#include "hb.h" + +#include <fontconfig/fontconfig.h> + +HB_BEGIN_DECLS + + +hb_font_t * +hb_fc_font_create (FcPattern *font); + +hb_bool_t +hb_fc_can_render (hb_font_t *font, const char *text); + + +HB_END_DECLS + +#endif /* HB_FC_H */ diff --git a/chromium/third_party/harfbuzz-ng/src/util/hb-ot-shape-closure.cc b/chromium/third_party/harfbuzz-ng/src/util/hb-ot-shape-closure.cc new file mode 100644 index 00000000000..77ca2013509 --- /dev/null +++ b/chromium/third_party/harfbuzz-ng/src/util/hb-ot-shape-closure.cc @@ -0,0 +1,119 @@ +/* + * Copyright © 2012 Google, Inc. + * + * This is part of HarfBuzz, a text shaping library. + * + * Permission is hereby granted, without written agreement and without + * license or royalty fees, to use, copy, modify, and distribute this + * software and its documentation for any purpose, provided that the + * above copyright notice and the following two paragraphs appear in + * all copies of this software. + * + * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR + * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES + * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN + * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, + * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS + * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO + * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + * + * Google Author(s): Behdad Esfahbod + */ + +#include "main-font-text.hh" + +#ifdef HAVE_FREETYPE +#include <hb-ft.h> +#endif + +struct shape_closure_consumer_t : option_group_t +{ + shape_closure_consumer_t (option_parser_t *parser) : + shaper (parser), + show_glyph_names (true) + { + add_options (parser); + } + + void add_options (struct option_parser_t *parser) + { + GOptionEntry entries[] = + { + {"no-glyph-names", 0, G_OPTION_FLAG_REVERSE, G_OPTION_ARG_NONE, &this->show_glyph_names, "Use glyph indices instead of names", nullptr}, + {nullptr} + }; + parser->add_group (entries, + "format", + "Format options:", + "Options controlling output formatting", + this); + } + + void init (hb_buffer_t *buffer_, + const font_options_t *font_opts) + { + glyphs = hb_set_create (); + font = hb_font_reference (font_opts->get_font ()); + failed = false; + buffer = hb_buffer_reference (buffer_); + } + void consume_line (const char *text, + unsigned int text_len, + const char *text_before, + const char *text_after) + { + hb_set_clear (glyphs); + shaper.shape_closure (text, text_len, font, buffer, glyphs); + + if (hb_set_is_empty (glyphs)) + return; + + /* Print it out! */ + bool first = true; + for (hb_codepoint_t i = -1; hb_set_next (glyphs, &i);) + { + if (first) + first = false; + else + printf (" "); + if (show_glyph_names) + { + char glyph_name[64]; + hb_font_glyph_to_string (font, i, glyph_name, sizeof (glyph_name)); + printf ("%s", glyph_name); + } else + printf ("%u", i); + } + } + void finish (const font_options_t *font_opts) + { + printf ("\n"); + hb_font_destroy (font); + font = nullptr; + hb_set_destroy (glyphs); + glyphs = nullptr; + hb_buffer_destroy (buffer); + buffer = nullptr; + } + + bool failed; + + protected: + shape_options_t shaper; + hb_bool_t show_glyph_names; + + hb_set_t *glyphs; + hb_font_t *font; + hb_buffer_t *buffer; +}; + +int +main (int argc, char **argv) +{ + main_font_text_t<shape_closure_consumer_t, FONT_SIZE_NONE, 0> driver; + return driver.main (argc, argv); +} diff --git a/chromium/third_party/harfbuzz-ng/src/util/hb-shape.cc b/chromium/third_party/harfbuzz-ng/src/util/hb-shape.cc new file mode 100644 index 00000000000..337cd431908 --- /dev/null +++ b/chromium/third_party/harfbuzz-ng/src/util/hb-shape.cc @@ -0,0 +1,165 @@ +/* + * Copyright © 2010 Behdad Esfahbod + * Copyright © 2011,2012 Google, Inc. + * + * This is part of HarfBuzz, a text shaping library. + * + * Permission is hereby granted, without written agreement and without + * license or royalty fees, to use, copy, modify, and distribute this + * software and its documentation for any purpose, provided that the + * above copyright notice and the following two paragraphs appear in + * all copies of this software. + * + * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR + * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES + * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN + * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, + * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS + * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO + * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + * + * Google Author(s): Behdad Esfahbod + */ + +#include "main-font-text.hh" +#include "shape-consumer.hh" + +struct output_buffer_t +{ + output_buffer_t (option_parser_t *parser) + : options (parser, hb_buffer_serialize_list_formats ()), + format (parser), + gs (nullptr), + line_no (0), + font (nullptr), + output_format (HB_BUFFER_SERIALIZE_FORMAT_INVALID), + format_flags (HB_BUFFER_SERIALIZE_FLAG_DEFAULT) {} + + void init (hb_buffer_t *buffer, const font_options_t *font_opts) + { + options.get_file_handle (); + gs = g_string_new (nullptr); + line_no = 0; + font = hb_font_reference (font_opts->get_font ()); + + if (!options.output_format) + output_format = HB_BUFFER_SERIALIZE_FORMAT_TEXT; + else + output_format = hb_buffer_serialize_format_from_string (options.output_format, -1); + /* An empty "output_format" parameter basically skips output generating. + * Useful for benchmarking. */ + if ((!options.output_format || *options.output_format) && + !hb_buffer_serialize_format_to_string (output_format)) + { + if (options.explicit_output_format) + fail (false, "Unknown output format `%s'; supported formats are: %s", + options.output_format, + g_strjoinv ("/", const_cast<char**> (options.supported_formats))); + else + /* Just default to TEXT if not explicitly requested and the + * file extension is not recognized. */ + output_format = HB_BUFFER_SERIALIZE_FORMAT_TEXT; + } + + unsigned int flags = HB_BUFFER_SERIALIZE_FLAG_DEFAULT; + if (!format.show_glyph_names) + flags |= HB_BUFFER_SERIALIZE_FLAG_NO_GLYPH_NAMES; + if (!format.show_clusters) + flags |= HB_BUFFER_SERIALIZE_FLAG_NO_CLUSTERS; + if (!format.show_positions) + flags |= HB_BUFFER_SERIALIZE_FLAG_NO_POSITIONS; + if (!format.show_advances) + flags |= HB_BUFFER_SERIALIZE_FLAG_NO_ADVANCES; + if (format.show_extents) + flags |= HB_BUFFER_SERIALIZE_FLAG_GLYPH_EXTENTS; + if (format.show_flags) + flags |= HB_BUFFER_SERIALIZE_FLAG_GLYPH_FLAGS; + format_flags = (hb_buffer_serialize_flags_t) flags; + + if (format.trace) + hb_buffer_set_message_func (buffer, message_func, this, nullptr); + } + void new_line (void) + { + line_no++; + } + void consume_text (hb_buffer_t *buffer, + const char *text, + unsigned int text_len, + hb_bool_t utf8_clusters) + { + g_string_set_size (gs, 0); + format.serialize_buffer_of_text (buffer, line_no, text, text_len, font, gs); + fprintf (options.fp, "%s", gs->str); + } + void error (const char *message) + { + g_string_set_size (gs, 0); + format.serialize_message (line_no, "error", message, gs); + fprintf (options.fp, "%s", gs->str); + } + void consume_glyphs (hb_buffer_t *buffer, + const char *text, + unsigned int text_len, + hb_bool_t utf8_clusters) + { + g_string_set_size (gs, 0); + format.serialize_buffer_of_glyphs (buffer, line_no, text, text_len, font, + output_format, format_flags, gs); + fprintf (options.fp, "%s", gs->str); + } + void finish (hb_buffer_t *buffer, const font_options_t *font_opts) + { + hb_buffer_set_message_func (buffer, nullptr, nullptr, nullptr); + hb_font_destroy (font); + g_string_free (gs, true); + gs = nullptr; + font = nullptr; + } + + static hb_bool_t + message_func (hb_buffer_t *buffer, + hb_font_t *font, + const char *message, + void *user_data) + { + output_buffer_t *that = (output_buffer_t *) user_data; + that->trace (buffer, font, message); + return true; + } + + void + trace (hb_buffer_t *buffer, + hb_font_t *font, + const char *message) + { + g_string_set_size (gs, 0); + format.serialize_line_no (line_no, gs); + g_string_append_printf (gs, "trace: %s buffer: ", message); + format.serialize_glyphs (buffer, font, output_format, format_flags, gs); + g_string_append_c (gs, '\n'); + fprintf (options.fp, "%s", gs->str); + } + + + protected: + output_options_t options; + format_options_t format; + + GString *gs; + unsigned int line_no; + hb_font_t *font; + hb_buffer_serialize_format_t output_format; + hb_buffer_serialize_flags_t format_flags; +}; + +int +main (int argc, char **argv) +{ + main_font_text_t<shape_consumer_t<output_buffer_t>, FONT_SIZE_UPEM, 0> driver; + return driver.main (argc, argv); +} diff --git a/chromium/third_party/harfbuzz-ng/src/util/hb-subset.cc b/chromium/third_party/harfbuzz-ng/src/util/hb-subset.cc new file mode 100644 index 00000000000..20617554c3e --- /dev/null +++ b/chromium/third_party/harfbuzz-ng/src/util/hb-subset.cc @@ -0,0 +1,127 @@ +/* + * Copyright © 2010 Behdad Esfahbod + * Copyright © 2011,2012 Google, Inc. + * + * This is part of HarfBuzz, a text shaping library. + * + * Permission is hereby granted, without written agreement and without + * license or royalty fees, to use, copy, modify, and distribute this + * software and its documentation for any purpose, provided that the + * above copyright notice and the following two paragraphs appear in + * all copies of this software. + * + * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR + * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES + * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN + * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, + * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS + * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO + * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + * + * Google Author(s): Garret Rieger, Rod Sheeter + */ + +#include <stdio.h> + +#include "main-font-text.hh" +#include "hb-subset.h" +#include "hb-subset-private.hh" + +/* + * Command line interface to the harfbuzz font subsetter. + */ + +struct subset_consumer_t +{ + subset_consumer_t (option_parser_t *parser) + : failed (false), options (parser), subset_options (parser), font (nullptr), input (nullptr) {} + + void init (hb_buffer_t *buffer_, + const font_options_t *font_opts) + { + font = hb_font_reference (font_opts->get_font ()); + input = hb_subset_input_create_or_fail (); + } + + void consume_line (const char *text, + 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); + gchar *c = (gchar *)text; + do { + gunichar cp = g_utf8_get_char(c); + hb_codepoint_t hb_cp = cp; + hb_set_add (codepoints, hb_cp); + } while ((c = g_utf8_find_next_char(c, text + text_len)) != nullptr); + } + + hb_bool_t + write_file (const char *output_file, hb_blob_t *blob) { + unsigned int data_length; + const char* data = hb_blob_get_data (blob, &data_length); + + FILE *fp_out = fopen(output_file, "wb"); + if (fp_out == nullptr) { + fprintf(stderr, "Unable to open output file\n"); + return false; + } + int bytes_written = fwrite(data, 1, data_length, fp_out); + + fclose (fp_out); + + if (bytes_written == -1) { + fprintf(stderr, "Unable to write output file\n"); + return false; + } + if ((unsigned int) bytes_written != data_length) { + fprintf(stderr, "Expected %u bytes written, got %d\n", data_length, + bytes_written); + return false; + } + return true; + } + + void finish (const font_options_t *font_opts) + { + input->drop_hints = subset_options.drop_hints; + + hb_subset_profile_t *subset_profile = hb_subset_profile_create(); + hb_face_t *face = hb_font_get_face (font); + + hb_face_t *new_face = hb_subset(face, subset_profile, input); + hb_blob_t *result = hb_face_reference_blob (new_face); + + failed = !hb_blob_get_length (result); + if (!failed) + write_file (options.output_file, result); + + hb_subset_profile_destroy (subset_profile); + hb_subset_input_destroy (input); + hb_blob_destroy (result); + hb_face_destroy (new_face); + hb_font_destroy (font); + } + + public: + bool failed; + + private: + output_options_t options; + subset_options_t subset_options; + hb_font_t *font; + hb_subset_input_t *input; +}; + +int +main (int argc, char **argv) +{ + main_font_text_t<subset_consumer_t, 10, 0> driver; + return driver.main (argc, argv); +} diff --git a/chromium/third_party/harfbuzz-ng/src/util/hb-view.cc b/chromium/third_party/harfbuzz-ng/src/util/hb-view.cc new file mode 100644 index 00000000000..ef75e6da70e --- /dev/null +++ b/chromium/third_party/harfbuzz-ng/src/util/hb-view.cc @@ -0,0 +1,40 @@ +/* + * Copyright © 2010 Behdad Esfahbod + * Copyright © 2011,2012 Google, Inc. + * + * This is part of HarfBuzz, a text shaping library. + * + * Permission is hereby granted, without written agreement and without + * license or royalty fees, to use, copy, modify, and distribute this + * software and its documentation for any purpose, provided that the + * above copyright notice and the following two paragraphs appear in + * all copies of this software. + * + * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR + * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES + * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN + * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, + * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS + * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO + * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + * + * Google Author(s): Behdad Esfahbod + */ + +#include "main-font-text.hh" +#include "shape-consumer.hh" +#include "view-cairo.hh" + +#define DEFAULT_FONT_SIZE 256 +#define SUBPIXEL_BITS 8 + +int +main (int argc, char **argv) +{ + main_font_text_t<shape_consumer_t<view_cairo_t>, DEFAULT_FONT_SIZE, SUBPIXEL_BITS> driver; + return driver.main (argc, argv); +} diff --git a/chromium/third_party/harfbuzz-ng/src/util/helper-cairo-ansi.cc b/chromium/third_party/harfbuzz-ng/src/util/helper-cairo-ansi.cc new file mode 100644 index 00000000000..50f9eb4460c --- /dev/null +++ b/chromium/third_party/harfbuzz-ng/src/util/helper-cairo-ansi.cc @@ -0,0 +1,102 @@ +/* + * Copyright © 2012 Google, Inc. + * + * This is part of HarfBuzz, a text shaping library. + * + * Permission is hereby granted, without written agreement and without + * license or royalty fees, to use, copy, modify, and distribute this + * software and its documentation for any purpose, provided that the + * above copyright notice and the following two paragraphs appear in + * all copies of this software. + * + * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR + * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES + * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN + * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, + * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS + * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO + * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + * + * Google Author(s): Behdad Esfahbod + */ + +#include "helper-cairo-ansi.hh" +#include "options.hh" + +#include "ansi-print.hh" + + +cairo_status_t +helper_cairo_surface_write_to_ansi_stream (cairo_surface_t *surface, + cairo_write_func_t write_func, + void *closure) +{ + unsigned int width = cairo_image_surface_get_width (surface); + unsigned int height = cairo_image_surface_get_height (surface); + if (cairo_image_surface_get_format (surface) != CAIRO_FORMAT_RGB24) { + cairo_surface_t *new_surface = cairo_image_surface_create (CAIRO_FORMAT_RGB24, width, height); + cairo_t *cr = cairo_create (new_surface); + if (cairo_image_surface_get_format (surface) == CAIRO_FORMAT_A8) { + cairo_set_source_rgb (cr, 0., 0., 0.); + cairo_paint (cr); + cairo_set_source_rgb (cr, 1., 1., 1.); + cairo_mask_surface (cr, surface, 0, 0); + } else { + cairo_set_source_rgb (cr, 1., 1., 1.); + cairo_paint (cr); + cairo_set_source_surface (cr, surface, 0, 0); + cairo_paint (cr); + } + cairo_destroy (cr); + surface = new_surface; + } else + cairo_surface_reference (surface); + + unsigned int stride = cairo_image_surface_get_stride (surface); + const uint32_t *data = (uint32_t *) (void *) cairo_image_surface_get_data (surface); + + /* We don't have rows to spare on the terminal window... + * Find the tight image top/bottom and only print in between. */ + + /* Use corner color as background color. */ + uint32_t bg_color = data ? * (uint32_t *) data : 0; + + /* Drop first row while empty */ + while (height) + { + unsigned int i; + for (i = 0; i < width; i++) + if (data[i] != bg_color) + break; + if (i < width) + break; + data += stride / 4; + height--; + } + + /* Drop last row while empty */ + unsigned int orig_height = height; + while (height) + { + const uint32_t *row = data + (height - 1) * stride / 4; + unsigned int i; + for (i = 0; i < width; i++) + if (row[i] != bg_color) + break; + if (i < width) + break; + height--; + } + if (height < orig_height) + height++; /* Add one last blank row for padding. */ + + if (width && height) + ansi_print_image_rgb24 (data, width, height, stride / 4); + + cairo_surface_destroy (surface); + return CAIRO_STATUS_SUCCESS; +} diff --git a/chromium/third_party/harfbuzz-ng/src/util/helper-cairo-ansi.hh b/chromium/third_party/harfbuzz-ng/src/util/helper-cairo-ansi.hh new file mode 100644 index 00000000000..cf18ea4955d --- /dev/null +++ b/chromium/third_party/harfbuzz-ng/src/util/helper-cairo-ansi.hh @@ -0,0 +1,40 @@ +/* + * Copyright © 2012 Google, Inc. + * + * This is part of HarfBuzz, a text shaping library. + * + * Permission is hereby granted, without written agreement and without + * license or royalty fees, to use, copy, modify, and distribute this + * software and its documentation for any purpose, provided that the + * above copyright notice and the following two paragraphs appear in + * all copies of this software. + * + * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR + * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES + * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN + * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, + * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS + * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO + * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + * + * Google Author(s): Behdad Esfahbod + */ + +#ifndef HELPER_CAIRO_ANSI_HH +#define HELPER_CAIRO_ANSI_HH + +#include "hb-private.hh" + +#include <cairo.h> + +cairo_status_t +helper_cairo_surface_write_to_ansi_stream (cairo_surface_t *surface, + cairo_write_func_t write_func, + void *closure); + + +#endif diff --git a/chromium/third_party/harfbuzz-ng/src/util/helper-cairo.cc b/chromium/third_party/harfbuzz-ng/src/util/helper-cairo.cc new file mode 100644 index 00000000000..b9f498516f2 --- /dev/null +++ b/chromium/third_party/harfbuzz-ng/src/util/helper-cairo.cc @@ -0,0 +1,553 @@ +/* + * Copyright © 2011 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 + */ + +#include "helper-cairo.hh" + +#include <cairo-ft.h> +#include <hb-ft.h> +#include FT_MULTIPLE_MASTERS_H + +#include "helper-cairo-ansi.hh" +#ifdef CAIRO_HAS_SVG_SURFACE +# include <cairo-svg.h> +#endif +#ifdef CAIRO_HAS_PDF_SURFACE +# include <cairo-pdf.h> +#endif +#ifdef CAIRO_HAS_PS_SURFACE +# include <cairo-ps.h> +# if CAIRO_VERSION >= CAIRO_VERSION_ENCODE(1,6,0) +# define HAS_EPS 1 + +static cairo_surface_t * +_cairo_eps_surface_create_for_stream (cairo_write_func_t write_func, + void *closure, + double width, + double height) +{ + cairo_surface_t *surface; + + surface = cairo_ps_surface_create_for_stream (write_func, closure, width, height); + cairo_ps_surface_set_eps (surface, true); + + return surface; +} + +# else +# undef HAS_EPS +# endif +#endif + + +static FT_Library ft_library; + +static inline +void free_ft_library (void) +{ + FT_Done_FreeType (ft_library); +} + +cairo_scaled_font_t * +helper_cairo_create_scaled_font (const font_options_t *font_opts) +{ + hb_font_t *font = hb_font_reference (font_opts->get_font ()); + + cairo_font_face_t *cairo_face; + /* We cannot use the FT_Face from hb_font_t, as doing so will confuse hb_font_t because + * cairo will reset the face size. As such, create new face... + * TODO Perhaps add API to hb-ft to encapsulate this code. */ + FT_Face ft_face = nullptr;//hb_ft_font_get_face (font); + if (!ft_face) + { + if (!ft_library) + { + FT_Init_FreeType (&ft_library); +#ifdef HAVE_ATEXIT + atexit (free_ft_library); +#endif + } + FT_New_Face (ft_library, + font_opts->font_file, + font_opts->face_index, + &ft_face); + } + if (!ft_face) + { + /* This allows us to get some boxes at least... */ + cairo_face = cairo_toy_font_face_create ("@cairo:sans", + CAIRO_FONT_SLANT_NORMAL, + CAIRO_FONT_WEIGHT_NORMAL); + } + else + { +#ifdef HAVE_FT_SET_VAR_BLEND_COORDINATES + unsigned int num_coords; + const int *coords = hb_font_get_var_coords_normalized (font, &num_coords); + if (num_coords) + { + FT_Fixed *ft_coords = (FT_Fixed *) calloc (num_coords, sizeof (FT_Fixed)); + if (ft_coords) + { + for (unsigned int i = 0; i < num_coords; i++) + ft_coords[i] = coords[i] << 2; + FT_Set_Var_Blend_Coordinates (ft_face, num_coords, ft_coords); + free (ft_coords); + } + } +#endif + + cairo_face = cairo_ft_font_face_create_for_ft_face (ft_face, 0); + } + cairo_matrix_t ctm, font_matrix; + cairo_font_options_t *font_options; + + cairo_matrix_init_identity (&ctm); + cairo_matrix_init_scale (&font_matrix, + font_opts->font_size_x, + font_opts->font_size_y); + font_options = cairo_font_options_create (); + cairo_font_options_set_hint_style (font_options, CAIRO_HINT_STYLE_NONE); + cairo_font_options_set_hint_metrics (font_options, CAIRO_HINT_METRICS_OFF); + + cairo_scaled_font_t *scaled_font = cairo_scaled_font_create (cairo_face, + &font_matrix, + &ctm, + font_options); + + cairo_font_options_destroy (font_options); + cairo_font_face_destroy (cairo_face); + + static cairo_user_data_key_t key; + if (cairo_scaled_font_set_user_data (scaled_font, + &key, + (void *) font, + (cairo_destroy_func_t) hb_font_destroy)) + hb_font_destroy (font); + + return scaled_font; +} + +bool +helper_cairo_scaled_font_has_color (cairo_scaled_font_t *scaled_font) +{ + bool ret = false; +#ifdef FT_HAS_COLOR + FT_Face ft_face = cairo_ft_scaled_font_lock_face (scaled_font); + if (ft_face) + { + if (FT_HAS_COLOR (ft_face)) + ret = true; + cairo_ft_scaled_font_unlock_face (scaled_font); + } +#endif + return ret; +} + + +struct finalize_closure_t { + void (*callback)(finalize_closure_t *); + cairo_surface_t *surface; + cairo_write_func_t write_func; + void *closure; +}; +static cairo_user_data_key_t finalize_closure_key; + + +static void +finalize_ansi (finalize_closure_t *closure) +{ + cairo_status_t status; + status = helper_cairo_surface_write_to_ansi_stream (closure->surface, + closure->write_func, + closure->closure); + if (status != CAIRO_STATUS_SUCCESS) + fail (false, "Failed to write output: %s", + cairo_status_to_string (status)); +} + +static cairo_surface_t * +_cairo_ansi_surface_create_for_stream (cairo_write_func_t write_func, + void *closure, + double width, + double height, + cairo_content_t content) +{ + cairo_surface_t *surface; + int w = ceil (width); + int h = ceil (height); + + switch (content) { + case CAIRO_CONTENT_ALPHA: + surface = cairo_image_surface_create (CAIRO_FORMAT_A8, w, h); + break; + default: + case CAIRO_CONTENT_COLOR: + surface = cairo_image_surface_create (CAIRO_FORMAT_RGB24, w, h); + break; + case CAIRO_CONTENT_COLOR_ALPHA: + surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, w, h); + break; + } + cairo_status_t status = cairo_surface_status (surface); + if (status != CAIRO_STATUS_SUCCESS) + fail (false, "Failed to create cairo surface: %s", + cairo_status_to_string (status)); + + finalize_closure_t *ansi_closure = g_new0 (finalize_closure_t, 1); + ansi_closure->callback = finalize_ansi; + ansi_closure->surface = surface; + ansi_closure->write_func = write_func; + ansi_closure->closure = closure; + + if (cairo_surface_set_user_data (surface, + &finalize_closure_key, + (void *) ansi_closure, + (cairo_destroy_func_t) g_free)) + g_free ((void *) closure); + + return surface; +} + + +#ifdef CAIRO_HAS_PNG_FUNCTIONS + +static void +finalize_png (finalize_closure_t *closure) +{ + cairo_status_t status; + status = cairo_surface_write_to_png_stream (closure->surface, + closure->write_func, + closure->closure); + if (status != CAIRO_STATUS_SUCCESS) + fail (false, "Failed to write output: %s", + cairo_status_to_string (status)); +} + +static cairo_surface_t * +_cairo_png_surface_create_for_stream (cairo_write_func_t write_func, + void *closure, + double width, + double height, + cairo_content_t content) +{ + cairo_surface_t *surface; + int w = ceil (width); + int h = ceil (height); + + switch (content) { + case CAIRO_CONTENT_ALPHA: + surface = cairo_image_surface_create (CAIRO_FORMAT_A8, w, h); + break; + default: + case CAIRO_CONTENT_COLOR: + surface = cairo_image_surface_create (CAIRO_FORMAT_RGB24, w, h); + break; + case CAIRO_CONTENT_COLOR_ALPHA: + surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, w, h); + break; + } + cairo_status_t status = cairo_surface_status (surface); + if (status != CAIRO_STATUS_SUCCESS) + fail (false, "Failed to create cairo surface: %s", + cairo_status_to_string (status)); + + finalize_closure_t *png_closure = g_new0 (finalize_closure_t, 1); + png_closure->callback = finalize_png; + png_closure->surface = surface; + png_closure->write_func = write_func; + png_closure->closure = closure; + + if (cairo_surface_set_user_data (surface, + &finalize_closure_key, + (void *) png_closure, + (cairo_destroy_func_t) g_free)) + g_free ((void *) closure); + + return surface; +} + +#endif + +static cairo_status_t +stdio_write_func (void *closure, + const unsigned char *data, + unsigned int size) +{ + FILE *fp = (FILE *) closure; + + while (size) { + size_t ret = fwrite (data, 1, size, fp); + size -= ret; + data += ret; + if (size && ferror (fp)) + fail (false, "Failed to write output: %s", strerror (errno)); + } + + return CAIRO_STATUS_SUCCESS; +} + +const char *helper_cairo_supported_formats[] = +{ + "ansi", + #ifdef CAIRO_HAS_PNG_FUNCTIONS + "png", + #endif + #ifdef CAIRO_HAS_SVG_SURFACE + "svg", + #endif + #ifdef CAIRO_HAS_PDF_SURFACE + "pdf", + #endif + #ifdef CAIRO_HAS_PS_SURFACE + "ps", + #ifdef HAS_EPS + "eps", + #endif + #endif + nullptr +}; + +cairo_t * +helper_cairo_create_context (double w, double h, + view_options_t *view_opts, + output_options_t *out_opts, + cairo_content_t content) +{ + cairo_surface_t *(*constructor) (cairo_write_func_t write_func, + void *closure, + double width, + double height) = nullptr; + cairo_surface_t *(*constructor2) (cairo_write_func_t write_func, + void *closure, + double width, + double height, + cairo_content_t content) = nullptr; + + const char *extension = out_opts->output_format; + if (!extension) { +#if HAVE_ISATTY + if (isatty (fileno (out_opts->get_file_handle ()))) + extension = "ansi"; + else +#endif + { +#ifdef CAIRO_HAS_PNG_FUNCTIONS + extension = "png"; +#else + extension = "ansi"; +#endif + } + } + if (0) + ; + else if (0 == g_ascii_strcasecmp (extension, "ansi")) + constructor2 = _cairo_ansi_surface_create_for_stream; + #ifdef CAIRO_HAS_PNG_FUNCTIONS + else if (0 == g_ascii_strcasecmp (extension, "png")) + constructor2 = _cairo_png_surface_create_for_stream; + #endif + #ifdef CAIRO_HAS_SVG_SURFACE + else if (0 == g_ascii_strcasecmp (extension, "svg")) + constructor = cairo_svg_surface_create_for_stream; + #endif + #ifdef CAIRO_HAS_PDF_SURFACE + else if (0 == g_ascii_strcasecmp (extension, "pdf")) + constructor = cairo_pdf_surface_create_for_stream; + #endif + #ifdef CAIRO_HAS_PS_SURFACE + else if (0 == g_ascii_strcasecmp (extension, "ps")) + constructor = cairo_ps_surface_create_for_stream; + #ifdef HAS_EPS + else if (0 == g_ascii_strcasecmp (extension, "eps")) + constructor = _cairo_eps_surface_create_for_stream; + #endif + #endif + + + unsigned int fr, fg, fb, fa, br, bg, bb, ba; + const char *color; + br = bg = bb = 0; ba = 255; + color = view_opts->back ? view_opts->back : DEFAULT_BACK; + sscanf (color + (*color=='#'), "%2x%2x%2x%2x", &br, &bg, &bb, &ba); + fr = fg = fb = 0; fa = 255; + color = view_opts->fore ? view_opts->fore : DEFAULT_FORE; + sscanf (color + (*color=='#'), "%2x%2x%2x%2x", &fr, &fg, &fb, &fa); + + if (content == CAIRO_CONTENT_ALPHA) + { + if (view_opts->annotate || + br != bg || bg != bb || + fr != fg || fg != fb) + content = CAIRO_CONTENT_COLOR; + } + if (ba != 255) + content = CAIRO_CONTENT_COLOR_ALPHA; + + cairo_surface_t *surface; + FILE *f = out_opts->get_file_handle (); + if (constructor) + surface = constructor (stdio_write_func, f, w, h); + else if (constructor2) + surface = constructor2 (stdio_write_func, f, w, h, content); + else + fail (false, "Unknown output format `%s'; supported formats are: %s%s", + extension, + g_strjoinv ("/", const_cast<char**> (helper_cairo_supported_formats)), + out_opts->explicit_output_format ? "" : + "\nTry setting format using --output-format"); + + cairo_t *cr = cairo_create (surface); + content = cairo_surface_get_content (surface); + + switch (content) { + case CAIRO_CONTENT_ALPHA: + cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE); + cairo_set_source_rgba (cr, 1., 1., 1., br / 255.); + cairo_paint (cr); + cairo_set_source_rgba (cr, 1., 1., 1., + (fr / 255.) * (fa / 255.) + (br / 255) * (1 - (fa / 255.))); + break; + default: + case CAIRO_CONTENT_COLOR: + case CAIRO_CONTENT_COLOR_ALPHA: + cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE); + cairo_set_source_rgba (cr, br / 255., bg / 255., bb / 255., ba / 255.); + cairo_paint (cr); + cairo_set_operator (cr, CAIRO_OPERATOR_OVER); + cairo_set_source_rgba (cr, fr / 255., fg / 255., fb / 255., fa / 255.); + break; + } + + cairo_surface_destroy (surface); + return cr; +} + +void +helper_cairo_destroy_context (cairo_t *cr) +{ + finalize_closure_t *closure = (finalize_closure_t *) + cairo_surface_get_user_data (cairo_get_target (cr), + &finalize_closure_key); + if (closure) + closure->callback (closure); + + cairo_status_t status = cairo_status (cr); + if (status != CAIRO_STATUS_SUCCESS) + fail (false, "Failed: %s", + cairo_status_to_string (status)); + cairo_destroy (cr); +} + + +void +helper_cairo_line_from_buffer (helper_cairo_line_t *l, + hb_buffer_t *buffer, + const char *text, + unsigned int text_len, + int scale_bits, + hb_bool_t utf8_clusters) +{ + memset (l, 0, sizeof (*l)); + + l->num_glyphs = hb_buffer_get_length (buffer); + hb_glyph_info_t *hb_glyph = hb_buffer_get_glyph_infos (buffer, nullptr); + hb_glyph_position_t *hb_position = hb_buffer_get_glyph_positions (buffer, nullptr); + l->glyphs = cairo_glyph_allocate (l->num_glyphs + 1); + + if (text) { + l->utf8 = g_strndup (text, text_len); + l->utf8_len = text_len; + l->num_clusters = l->num_glyphs ? 1 : 0; + for (unsigned int i = 1; i < l->num_glyphs; i++) + if (hb_glyph[i].cluster != hb_glyph[i-1].cluster) + l->num_clusters++; + l->clusters = cairo_text_cluster_allocate (l->num_clusters); + } + + if ((l->num_glyphs && !l->glyphs) || + (l->utf8_len && !l->utf8) || + (l->num_clusters && !l->clusters)) + { + l->finish (); + return; + } + + hb_position_t x = 0, y = 0; + int i; + for (i = 0; i < (int) l->num_glyphs; i++) + { + l->glyphs[i].index = hb_glyph[i].codepoint; + l->glyphs[i].x = scalbn ((double) hb_position->x_offset + x, scale_bits); + l->glyphs[i].y = scalbn ((double) -hb_position->y_offset + y, scale_bits); + x += hb_position->x_advance; + y += -hb_position->y_advance; + + hb_position++; + } + l->glyphs[i].index = -1; + l->glyphs[i].x = scalbn ((double) x, scale_bits); + l->glyphs[i].y = scalbn ((double) y, scale_bits); + + if (l->num_clusters) { + memset ((void *) l->clusters, 0, l->num_clusters * sizeof (l->clusters[0])); + hb_bool_t backward = HB_DIRECTION_IS_BACKWARD (hb_buffer_get_direction (buffer)); + l->cluster_flags = backward ? CAIRO_TEXT_CLUSTER_FLAG_BACKWARD : (cairo_text_cluster_flags_t) 0; + unsigned int cluster = 0; + const char *start = l->utf8, *end; + l->clusters[cluster].num_glyphs++; + if (backward) { + for (i = l->num_glyphs - 2; i >= 0; i--) { + if (hb_glyph[i].cluster != hb_glyph[i+1].cluster) { + g_assert (hb_glyph[i].cluster > hb_glyph[i+1].cluster); + if (utf8_clusters) + end = start + hb_glyph[i].cluster - hb_glyph[i+1].cluster; + else + end = g_utf8_offset_to_pointer (start, hb_glyph[i].cluster - hb_glyph[i+1].cluster); + l->clusters[cluster].num_bytes = end - start; + start = end; + cluster++; + } + l->clusters[cluster].num_glyphs++; + } + l->clusters[cluster].num_bytes = l->utf8 + text_len - start; + } else { + for (i = 1; i < (int) l->num_glyphs; i++) { + if (hb_glyph[i].cluster != hb_glyph[i-1].cluster) { + g_assert (hb_glyph[i].cluster > hb_glyph[i-1].cluster); + if (utf8_clusters) + end = start + hb_glyph[i].cluster - hb_glyph[i-1].cluster; + else + end = g_utf8_offset_to_pointer (start, hb_glyph[i].cluster - hb_glyph[i-1].cluster); + l->clusters[cluster].num_bytes = end - start; + start = end; + cluster++; + } + l->clusters[cluster].num_glyphs++; + } + l->clusters[cluster].num_bytes = l->utf8 + text_len - start; + } + } +} diff --git a/chromium/third_party/harfbuzz-ng/src/util/helper-cairo.hh b/chromium/third_party/harfbuzz-ng/src/util/helper-cairo.hh new file mode 100644 index 00000000000..50bc0af0947 --- /dev/null +++ b/chromium/third_party/harfbuzz-ng/src/util/helper-cairo.hh @@ -0,0 +1,86 @@ +/* + * Copyright © 2011 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 HELPER_CAIRO_HH +#define HELPER_CAIRO_HH + +#include "hb-private.hh" +#include "options.hh" + +#include <cairo.h> + + +cairo_scaled_font_t * +helper_cairo_create_scaled_font (const font_options_t *font_opts); + +bool +helper_cairo_scaled_font_has_color (cairo_scaled_font_t *scaled_font); + +extern const char *helper_cairo_supported_formats[]; + +cairo_t * +helper_cairo_create_context (double w, double h, + view_options_t *view_opts, + output_options_t *out_opts, + cairo_content_t content); + +void +helper_cairo_destroy_context (cairo_t *cr); + + +struct helper_cairo_line_t { + cairo_glyph_t *glyphs; + unsigned int num_glyphs; + char *utf8; + unsigned int utf8_len; + cairo_text_cluster_t *clusters; + unsigned int num_clusters; + cairo_text_cluster_flags_t cluster_flags; + + void finish (void) { + if (glyphs) + cairo_glyph_free (glyphs); + if (clusters) + cairo_text_cluster_free (clusters); + if (utf8) + g_free (utf8); + } + + void get_advance (double *x_advance, double *y_advance) { + *x_advance = glyphs[num_glyphs].x; + *y_advance = glyphs[num_glyphs].y; + } +}; + +void +helper_cairo_line_from_buffer (helper_cairo_line_t *l, + hb_buffer_t *buffer, + const char *text, + unsigned int text_len, + int scale_bits, + hb_bool_t utf8_clusters); + +#endif diff --git a/chromium/third_party/harfbuzz-ng/src/util/main-font-text.hh b/chromium/third_party/harfbuzz-ng/src/util/main-font-text.hh new file mode 100644 index 00000000000..3390371c55e --- /dev/null +++ b/chromium/third_party/harfbuzz-ng/src/util/main-font-text.hh @@ -0,0 +1,96 @@ +/* + * Copyright © 2011,2012 Google, Inc. + * + * This is part of HarfBuzz, a text shaping library. + * + * Permission is hereby granted, without written agreement and without + * license or royalty fees, to use, copy, modify, and distribute this + * software and its documentation for any purpose, provided that the + * above copyright notice and the following two paragraphs appear in + * all copies of this software. + * + * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR + * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES + * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN + * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, + * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS + * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO + * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + * + * Google Author(s): Behdad Esfahbod + */ + +#ifndef HB_MAIN_FONT_TEXT_HH +#define HB_MAIN_FONT_TEXT_HH + +#include "hb-private.hh" +#include "options.hh" + +/* main() body for utilities taking font and processing text.*/ + +static char * +locale_to_utf8 (char *s) +{ + char *t; + GError *error = nullptr; + + t = g_locale_to_utf8 (s, -1, nullptr, nullptr, &error); + if (!t) + { + fail (true, "Failed converting text to UTF-8"); + } + + return t; +} + +template <typename consumer_t, int default_font_size, int subpixel_bits> +struct main_font_text_t +{ + main_font_text_t (void) + : options ("[FONT-FILE] [TEXT]"), + font_opts (&options, default_font_size, subpixel_bits), + input (&options), + consumer (&options) {} + + int + main (int argc, char **argv) + { + options.parse (&argc, &argv); + + argc--, argv++; + if (argc && !font_opts.font_file) font_opts.font_file = locale_to_utf8 (argv[0]), argc--, argv++; + if (argc && !input.text && !input.text_file) input.text = locale_to_utf8 (argv[0]), argc--, argv++; + if (argc) + fail (true, "Too many arguments on the command line"); + if (!font_opts.font_file) + options.usage (); + if (!input.text && !input.text_file) + input.text_file = g_strdup ("-"); + + hb_buffer_t *buffer = hb_buffer_create (); + consumer.init (buffer, &font_opts); + hb_buffer_destroy (buffer); + + unsigned int text_len; + const char *text; + while ((text = input.get_line (&text_len))) + consumer.consume_line (text, text_len, input.text_before, input.text_after); + + consumer.finish (&font_opts); + + return consumer.failed ? 1 : 0; + } + + protected: + option_parser_t options; + font_options_t font_opts; + text_options_t input; + consumer_t consumer; +}; + +#endif + diff --git a/chromium/third_party/harfbuzz-ng/src/util/options.cc b/chromium/third_party/harfbuzz-ng/src/util/options.cc new file mode 100644 index 00000000000..027d0b39623 --- /dev/null +++ b/chromium/third_party/harfbuzz-ng/src/util/options.cc @@ -0,0 +1,1014 @@ +/* + * Copyright © 2011,2012 Google, Inc. + * + * This is part of HarfBuzz, a text shaping library. + * + * Permission is hereby granted, without written agreement and without + * license or royalty fees, to use, copy, modify, and distribute this + * software and its documentation for any purpose, provided that the + * above copyright notice and the following two paragraphs appear in + * all copies of this software. + * + * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR + * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES + * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN + * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, + * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS + * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO + * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + * + * Google Author(s): Behdad Esfahbod + */ + +#include "options.hh" + +#ifdef HAVE_FREETYPE +#include <hb-ft.h> +#endif +#ifdef HAVE_OT +#include <hb-ot.h> +#endif + +struct supported_font_funcs_t { + char name[4]; + void (*func) (hb_font_t *); +} supported_font_funcs[] = +{ +#ifdef HAVE_FREETYPE + {"ft", hb_ft_font_set_funcs}, +#endif +#ifdef HAVE_OT + {"ot", hb_ot_font_set_funcs}, +#endif +}; + + +void +fail (hb_bool_t suggest_help, const char *format, ...) +{ + const char *msg; + + va_list vap; + va_start (vap, format); + msg = g_strdup_vprintf (format, vap); + va_end (vap); + const char *prgname = g_get_prgname (); + g_printerr ("%s: %s\n", prgname, msg); + if (suggest_help) + g_printerr ("Try `%s --help' for more information.\n", prgname); + + exit (1); +} + + +hb_bool_t debug = false; + +static gchar * +shapers_to_string (void) +{ + GString *shapers = g_string_new (nullptr); + const char **shaper_list = hb_shape_list_shapers (); + + for (; *shaper_list; shaper_list++) { + g_string_append (shapers, *shaper_list); + g_string_append_c (shapers, ','); + } + g_string_truncate (shapers, MAX (0, (gint)shapers->len - 1)); + + return g_string_free (shapers, false); +} + +static G_GNUC_NORETURN gboolean +show_version (const char *name G_GNUC_UNUSED, + const char *arg G_GNUC_UNUSED, + gpointer data G_GNUC_UNUSED, + GError **error G_GNUC_UNUSED) +{ + g_printf ("%s (%s) %s\n", g_get_prgname (), PACKAGE_NAME, PACKAGE_VERSION); + + char *shapers = shapers_to_string (); + g_printf ("Available shapers: %s\n", shapers); + g_free (shapers); + if (strcmp (HB_VERSION_STRING, hb_version_string ())) + g_printf ("Linked HarfBuzz library has a different version: %s\n", hb_version_string ()); + + exit(0); +} + + +void +option_parser_t::add_main_options (void) +{ + GOptionEntry entries[] = + { + {"version", 0, G_OPTION_FLAG_NO_ARG, + G_OPTION_ARG_CALLBACK, (gpointer) &show_version, "Show version numbers", nullptr}, + {"debug", 0, 0, G_OPTION_ARG_NONE, &debug, "Free all resources before exit", nullptr}, + {nullptr} + }; + g_option_context_add_main_entries (context, entries, nullptr); +} + +static gboolean +pre_parse (GOptionContext *context G_GNUC_UNUSED, + GOptionGroup *group G_GNUC_UNUSED, + gpointer data, + GError **error) +{ + option_group_t *option_group = (option_group_t *) data; + option_group->pre_parse (error); + return *error == nullptr; +} + +static gboolean +post_parse (GOptionContext *context G_GNUC_UNUSED, + GOptionGroup *group G_GNUC_UNUSED, + gpointer data, + GError **error) +{ + option_group_t *option_group = static_cast<option_group_t *>(data); + option_group->post_parse (error); + return *error == nullptr; +} + +void +option_parser_t::add_group (GOptionEntry *entries, + const gchar *name, + const gchar *description, + const gchar *help_description, + option_group_t *option_group) +{ + GOptionGroup *group = g_option_group_new (name, description, help_description, + static_cast<gpointer>(option_group), nullptr); + g_option_group_add_entries (group, entries); + g_option_group_set_parse_hooks (group, pre_parse, post_parse); + g_option_context_add_group (context, group); +} + +void +option_parser_t::parse (int *argc, char ***argv) +{ + setlocale (LC_ALL, ""); + + GError *parse_error = nullptr; + if (!g_option_context_parse (context, argc, argv, &parse_error)) + { + if (parse_error != nullptr) { + fail (true, "%s", parse_error->message); + //g_error_free (parse_error); + } else + fail (true, "Option parse error"); + } +} + + +static gboolean +parse_margin (const char *name G_GNUC_UNUSED, + const char *arg, + gpointer data, + GError **error G_GNUC_UNUSED) +{ + view_options_t *view_opts = (view_options_t *) data; + view_options_t::margin_t &m = view_opts->margin; + switch (sscanf (arg, "%lf%*[ ,]%lf%*[ ,]%lf%*[ ,]%lf", &m.t, &m.r, &m.b, &m.l)) { + case 1: m.r = m.t; + case 2: m.b = m.t; + case 3: m.l = m.r; + case 4: return true; + default: + g_set_error (error, G_OPTION_ERROR, G_OPTION_ERROR_BAD_VALUE, + "%s argument should be one to four space-separated numbers", + name); + return false; + } +} + + +static gboolean +parse_shapers (const char *name G_GNUC_UNUSED, + const char *arg, + gpointer data, + GError **error G_GNUC_UNUSED) +{ + shape_options_t *shape_opts = (shape_options_t *) data; + g_strfreev (shape_opts->shapers); + shape_opts->shapers = g_strsplit (arg, ",", 0); + return true; +} + +static G_GNUC_NORETURN gboolean +list_shapers (const char *name G_GNUC_UNUSED, + const char *arg G_GNUC_UNUSED, + gpointer data G_GNUC_UNUSED, + GError **error G_GNUC_UNUSED) +{ + for (const char **shaper = hb_shape_list_shapers (); *shaper; shaper++) + g_printf ("%s\n", *shaper); + + exit(0); +} + + +static gboolean +parse_features (const char *name 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; + char *p; + + shape_opts->num_features = 0; + g_free (shape_opts->features); + shape_opts->features = nullptr; + + if (!*s) + return true; + + /* count the features first, so we can allocate memory */ + p = s; + do { + shape_opts->num_features++; + p = strchr (p, ','); + if (p) + p++; + } while (p); + + shape_opts->features = (hb_feature_t *) calloc (shape_opts->num_features, sizeof (*shape_opts->features)); + if (!shape_opts->features) + return false; + + /* now do the actual parsing */ + p = s; + shape_opts->num_features = 0; + while (p && *p) { + char *end = strchr (p, ','); + if (hb_feature_from_string (p, end ? end - p : -1, &shape_opts->features[shape_opts->num_features])) + shape_opts->num_features++; + p = end ? end + 1 : nullptr; + } + + return true; +} + +static gboolean +parse_variations (const char *name 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; + char *p; + + font_opts->num_variations = 0; + g_free (font_opts->variations); + font_opts->variations = nullptr; + + if (!*s) + return true; + + /* count the variations first, so we can allocate memory */ + p = s; + do { + font_opts->num_variations++; + p = strchr (p, ','); + if (p) + p++; + } while (p); + + font_opts->variations = (hb_variation_t *) calloc (font_opts->num_variations, sizeof (*font_opts->variations)); + if (!font_opts->variations) + return false; + + /* now do the actual parsing */ + p = s; + font_opts->num_variations = 0; + while (p && *p) { + char *end = strchr (p, ','); + if (hb_variation_from_string (p, end ? end - p : -1, &font_opts->variations[font_opts->num_variations])) + font_opts->num_variations++; + p = end ? end + 1 : nullptr; + } + + return true; +} + +static gboolean +parse_text (const char *name G_GNUC_UNUSED, + const char *arg, + gpointer data, + GError **error G_GNUC_UNUSED) +{ + text_options_t *text_opts = (text_options_t *) data; + + if (text_opts->text) + { + g_set_error (error, G_OPTION_ERROR, G_OPTION_ERROR_BAD_VALUE, + "Either --text or --unicodes can be provided but not both"); + return false; + } + + text_opts->text = g_strdup (arg); + return true; +} + + +static gboolean +parse_unicodes (const char *name G_GNUC_UNUSED, + const char *arg, + gpointer data, + GError **error G_GNUC_UNUSED) +{ + text_options_t *text_opts = (text_options_t *) data; + + if (text_opts->text) + { + g_set_error (error, G_OPTION_ERROR, G_OPTION_ERROR_BAD_VALUE, + "Either --text or --unicodes can be provided but not both"); + return false; + } + + GString *gs = g_string_new (nullptr); + char *s = (char *) arg; + char *p; + + while (s && *s) + { + while (*s && strchr ("<+>{},;&#\\xXuUnNiI\n\t", *s)) + s++; + + errno = 0; + hb_codepoint_t u = strtoul (s, &p, 16); + if (errno || s == p) + { + g_set_error (error, G_OPTION_ERROR, G_OPTION_ERROR_BAD_VALUE, + "Failed parsing Unicode values at: '%s'", s); + return false; + } + + g_string_append_unichar (gs, u); + + s = p; + } + + text_opts->text = g_string_free (gs, FALSE); + return true; +} + + +void +view_options_t::add_options (option_parser_t *parser) +{ + GOptionEntry entries[] = + { + {"annotate", 0, 0, G_OPTION_ARG_NONE, &this->annotate, "Annotate output rendering", nullptr}, + {"background", 0, 0, G_OPTION_ARG_STRING, &this->back, "Set background color (default: " DEFAULT_BACK ")", "rrggbb/rrggbbaa"}, + {"foreground", 0, 0, G_OPTION_ARG_STRING, &this->fore, "Set foreground color (default: " DEFAULT_FORE ")", "rrggbb/rrggbbaa"}, + {"line-space", 0, 0, G_OPTION_ARG_DOUBLE, &this->line_space, "Set space between lines (default: 0)", "units"}, + {"margin", 0, 0, G_OPTION_ARG_CALLBACK, (gpointer) &parse_margin, "Margin around output (default: " G_STRINGIFY(DEFAULT_MARGIN) ")","one to four numbers"}, + {nullptr} + }; + parser->add_group (entries, + "view", + "View options:", + "Options for output rendering", + this); +} + +void +shape_options_t::add_options (option_parser_t *parser) +{ + GOptionEntry entries[] = + { + {"list-shapers", 0, G_OPTION_FLAG_NO_ARG, + G_OPTION_ARG_CALLBACK, (gpointer) &list_shapers, "List available shapers and quit", nullptr}, + {"shaper", 0, G_OPTION_FLAG_HIDDEN, + G_OPTION_ARG_CALLBACK, (gpointer) &parse_shapers, "Hidden duplicate of --shapers", nullptr}, + {"shapers", 0, 0, G_OPTION_ARG_CALLBACK, (gpointer) &parse_shapers, "Set comma-separated list of shapers to try","list"}, + {"direction", 0, 0, G_OPTION_ARG_STRING, &this->direction, "Set text direction (default: auto)", "ltr/rtl/ttb/btt"}, + {"language", 0, 0, G_OPTION_ARG_STRING, &this->language, "Set text language (default: $LANG)", "langstr"}, + {"script", 0, 0, G_OPTION_ARG_STRING, &this->script, "Set text script (default: auto)", "ISO-15924 tag"}, + {"bot", 0, 0, G_OPTION_ARG_NONE, &this->bot, "Treat text as beginning-of-paragraph", nullptr}, + {"eot", 0, 0, G_OPTION_ARG_NONE, &this->eot, "Treat text as end-of-paragraph", nullptr}, + {"preserve-default-ignorables",0, 0, G_OPTION_ARG_NONE, &this->preserve_default_ignorables, "Preserve Default-Ignorable characters", nullptr}, + {"remove-default-ignorables",0, 0, G_OPTION_ARG_NONE, &this->remove_default_ignorables, "Remove Default-Ignorable characters", nullptr}, + {"utf8-clusters", 0, 0, G_OPTION_ARG_NONE, &this->utf8_clusters, "Use UTF8 byte indices, not char indices", nullptr}, + {"cluster-level", 0, 0, G_OPTION_ARG_INT, &this->cluster_level, "Cluster merging level (default: 0)", "0/1/2"}, + {"normalize-glyphs",0, 0, G_OPTION_ARG_NONE, &this->normalize_glyphs, "Rearrange glyph clusters in nominal order", nullptr}, + {"verify", 0, 0, G_OPTION_ARG_NONE, &this->verify, "Perform sanity checks on shaping results", nullptr}, + {"num-iterations", 0, 0, G_OPTION_ARG_INT, &this->num_iterations, "Run shaper N times (default: 1)", "N"}, + {nullptr} + }; + parser->add_group (entries, + "shape", + "Shape options:", + "Options for the shaping process", + this); + + const gchar *features_help = "Comma-separated list of font features\n" + "\n" + " Features can be enabled or disabled, either globally or limited to\n" + " specific character ranges. The format for specifying feature settings\n" + " follows. All valid CSS font-feature-settings values other than 'normal'\n" + " and 'inherited' are also accepted, though, not documented below.\n" + "\n" + " The range indices refer to the positions between Unicode characters,\n" + " unless the --utf8-clusters is provided, in which case range indices\n" + " refer to UTF-8 byte indices. The position before the first character\n" + " is always 0.\n" + "\n" + " The format is Python-esque. Here is how it all works:\n" + "\n" + " Syntax: Value: Start: End:\n" + "\n" + " Setting value:\n" + " \"kern\" 1 0 ∞ # Turn feature on\n" + " \"+kern\" 1 0 ∞ # Turn feature on\n" + " \"-kern\" 0 0 ∞ # Turn feature off\n" + " \"kern=0\" 0 0 ∞ # Turn feature off\n" + " \"kern=1\" 1 0 ∞ # Turn feature on\n" + " \"aalt=2\" 2 0 ∞ # Choose 2nd alternate\n" + "\n" + " Setting index:\n" + " \"kern[]\" 1 0 ∞ # Turn feature on\n" + " \"kern[:]\" 1 0 ∞ # Turn feature on\n" + " \"kern[5:]\" 1 5 ∞ # Turn feature on, partial\n" + " \"kern[:5]\" 1 0 5 # Turn feature on, partial\n" + " \"kern[3:5]\" 1 3 5 # Turn feature on, range\n" + " \"kern[3]\" 1 3 3+1 # Turn feature on, single char\n" + "\n" + " Mixing it all:\n" + "\n" + " \"aalt[3:5]=2\" 2 3 5 # Turn 2nd alternate on for range"; + + GOptionEntry entries2[] = + { + {"features", 0, 0, G_OPTION_ARG_CALLBACK, (gpointer) &parse_features, features_help, "list"}, + {nullptr} + }; + parser->add_group (entries2, + "features", + "Features options:", + "Options for font features used", + this); +} + +static gboolean +parse_font_size (const char *name G_GNUC_UNUSED, + const char *arg, + gpointer data, + GError **error G_GNUC_UNUSED) +{ + font_options_t *font_opts = (font_options_t *) data; + if (0 == strcmp (arg, "upem")) + { + font_opts->font_size_y = font_opts->font_size_x = FONT_SIZE_UPEM; + return true; + } + switch (sscanf (arg, "%lf%*[ ,]%lf", &font_opts->font_size_x, &font_opts->font_size_y)) { + case 1: font_opts->font_size_y = font_opts->font_size_x; + case 2: return true; + default: + g_set_error (error, G_OPTION_ERROR, G_OPTION_ERROR_BAD_VALUE, + "%s argument should be one or two space-separated numbers", + name); + return false; + } +} + +static gboolean +parse_font_ppem (const char *name G_GNUC_UNUSED, + const char *arg, + gpointer data, + GError **error G_GNUC_UNUSED) +{ + font_options_t *font_opts = (font_options_t *) data; + switch (sscanf (arg, "%d%*[ ,]%d", &font_opts->x_ppem, &font_opts->y_ppem)) { + case 1: font_opts->y_ppem = font_opts->x_ppem; + case 2: return true; + default: + g_set_error (error, G_OPTION_ERROR, G_OPTION_ERROR_BAD_VALUE, + "%s argument should be one or two space-separated numbers", + name); + return false; + } +} + +void +font_options_t::add_options (option_parser_t *parser) +{ + char *text = nullptr; + + { + static_assert ((ARRAY_LENGTH_CONST (supported_font_funcs) > 0), + "No supported font-funcs found."); + GString *s = g_string_new (nullptr); + g_string_printf (s, "Set font functions implementation to use (default: %s)\n\n Supported font function implementations are: %s", + supported_font_funcs[0].name, + supported_font_funcs[0].name); + for (unsigned int i = 1; i < ARRAY_LENGTH (supported_font_funcs); i++) + { + g_string_append_c (s, '/'); + g_string_append (s, supported_font_funcs[i].name); + } + text = g_string_free (s, FALSE); + parser->free_later (text); + } + + char *font_size_text; + if (default_font_size == FONT_SIZE_UPEM) + font_size_text = (char *) "Font size (default: upem)"; + else + { + font_size_text = g_strdup_printf ("Font size (default: %d)", default_font_size); + parser->free_later (font_size_text); + } + + GOptionEntry entries[] = + { + {"font-file", 0, 0, G_OPTION_ARG_STRING, &this->font_file, "Set font file-name", "filename"}, + {"face-index", 0, 0, G_OPTION_ARG_INT, &this->face_index, "Set face index (default: 0)", "index"}, + {"font-size", 0, default_font_size ? 0 : G_OPTION_FLAG_HIDDEN, + G_OPTION_ARG_CALLBACK, (gpointer) &parse_font_size, font_size_text, "1/2 integers or 'upem'"}, + {"font-ppem", 0, 0, G_OPTION_ARG_CALLBACK, (gpointer) &parse_font_ppem, "Set x,y pixels per EM (default: 0; disabled)", "1/2 integers"}, + {"font-ptem", 0, 0, G_OPTION_ARG_DOUBLE, &this->ptem, "Set font point-size (default: 0; disabled)", "point-size"}, + {"font-funcs", 0, 0, G_OPTION_ARG_STRING, &this->font_funcs, text, "impl"}, + {nullptr} + }; + parser->add_group (entries, + "font", + "Font options:", + "Options for the font", + this); + + const gchar *variations_help = "Comma-separated list of font variations\n" + "\n" + " Variations are set globally. The format for specifying variation settings\n" + " follows. All valid CSS font-variation-settings values other than 'normal'\n" + " and 'inherited' are also accepted, though, not documented below.\n" + "\n" + " The format is a tag, optionally followed by an equals sign, followed by a\n" + " number. For example:\n" + "\n" + " \"wght=500\"\n" + " \"slnt=-7.5\"\n"; + + GOptionEntry entries2[] = + { + {"variations", 0, 0, G_OPTION_ARG_CALLBACK, (gpointer) &parse_variations, variations_help, "list"}, + {nullptr} + }; + parser->add_group (entries2, + "variations", + "Variations options:", + "Options for font variations used", + this); +} + +void +text_options_t::add_options (option_parser_t *parser) +{ + GOptionEntry entries[] = + { + {"text", 0, 0, G_OPTION_ARG_CALLBACK, (gpointer) &parse_text, "Set input text", "string"}, + {"text-file", 0, 0, G_OPTION_ARG_STRING, &this->text_file, "Set input text file-name\n\n If no text is provided, standard input is used for input.\n", "filename"}, + {"unicodes", 'u', 0, G_OPTION_ARG_CALLBACK, (gpointer) &parse_unicodes, "Set input Unicode codepoints", "list of hex numbers"}, + {"text-before", 0, 0, G_OPTION_ARG_STRING, &this->text_before, "Set text context before each line", "string"}, + {"text-after", 0, 0, G_OPTION_ARG_STRING, &this->text_after, "Set text context after each line", "string"}, + {nullptr} + }; + parser->add_group (entries, + "text", + "Text options:", + "Options for the input text", + this); +} + +void +output_options_t::add_options (option_parser_t *parser) +{ + const char *text; + + if (nullptr == supported_formats) + text = "Set output serialization format"; + else + { + char *items = g_strjoinv ("/", const_cast<char **> (supported_formats)); + text = g_strdup_printf ("Set output format\n\n Supported output formats are: %s", items); + g_free (items); + parser->free_later ((char *) text); + } + + GOptionEntry entries[] = + { + {"output-file", 'o', 0, G_OPTION_ARG_STRING, &this->output_file, "Set output file-name (default: stdout)","filename"}, + {"output-format", 'O', 0, G_OPTION_ARG_STRING, &this->output_format, text, "format"}, + {nullptr} + }; + parser->add_group (entries, + "output", + "Output destination & format options:", + "Options for the destination & form of the output", + this); +} + + + +hb_font_t * +font_options_t::get_font (void) const +{ + if (font) + return font; + + hb_blob_t *blob = nullptr; + + /* Create the blob */ + { + char *font_data; + unsigned int len = 0; + hb_destroy_func_t destroy; + void *user_data; + hb_memory_mode_t mm; + + /* This is a hell of a lot of code for just reading a file! */ + if (!font_file) + fail (true, "No font file set"); + + if (0 == strcmp (font_file, "-")) { + /* read it */ + GString *gs = g_string_new (nullptr); + char buf[BUFSIZ]; +#if defined(_WIN32) || defined(__CYGWIN__) + setmode (fileno (stdin), O_BINARY); +#endif + while (!feof (stdin)) { + size_t ret = fread (buf, 1, sizeof (buf), stdin); + if (ferror (stdin)) + fail (false, "Failed reading font from standard input: %s", + strerror (errno)); + g_string_append_len (gs, buf, ret); + } + len = gs->len; + font_data = g_string_free (gs, false); + user_data = font_data; + destroy = (hb_destroy_func_t) g_free; + mm = HB_MEMORY_MODE_WRITABLE; + } else { + GError *error = nullptr; + GMappedFile *mf = g_mapped_file_new (font_file, false, &error); + if (mf) { + font_data = g_mapped_file_get_contents (mf); + len = g_mapped_file_get_length (mf); + if (len) { + destroy = (hb_destroy_func_t) g_mapped_file_unref; + user_data = (void *) mf; + mm = HB_MEMORY_MODE_READONLY_MAY_MAKE_WRITABLE; + } else + g_mapped_file_unref (mf); + } else { + fail (false, "%s", error->message); + //g_error_free (error); + } + if (!len) { + /* GMappedFile is buggy, it doesn't fail if file isn't regular. + * Try reading. + * https://bugzilla.gnome.org/show_bug.cgi?id=659212 */ + GError *error = nullptr; + gsize l; + if (g_file_get_contents (font_file, &font_data, &l, &error)) { + len = l; + destroy = (hb_destroy_func_t) g_free; + user_data = (void *) font_data; + mm = HB_MEMORY_MODE_WRITABLE; + } else { + fail (false, "%s", error->message); + //g_error_free (error); + } + } + } + + if (debug) + mm = HB_MEMORY_MODE_DUPLICATE; + + blob = hb_blob_create (font_data, len, mm, user_data, destroy); + } + + /* Create the face */ + hb_face_t *face = hb_face_create (blob, face_index); + hb_blob_destroy (blob); + + + font = hb_font_create (face); + + if (font_size_x == FONT_SIZE_UPEM) + font_size_x = hb_face_get_upem (face); + if (font_size_y == FONT_SIZE_UPEM) + font_size_y = hb_face_get_upem (face); + + hb_font_set_ppem (font, x_ppem, y_ppem); + hb_font_set_ptem (font, ptem); + + int scale_x = (int) scalbnf (font_size_x, subpixel_bits); + int scale_y = (int) scalbnf (font_size_y, subpixel_bits); + hb_font_set_scale (font, scale_x, scale_y); + hb_face_destroy (face); + + hb_font_set_variations (font, variations, num_variations); + + void (*set_font_funcs) (hb_font_t *) = nullptr; + if (!font_funcs) + { + set_font_funcs = supported_font_funcs[0].func; + } + else + { + for (unsigned int i = 0; i < ARRAY_LENGTH (supported_font_funcs); i++) + if (0 == g_ascii_strcasecmp (font_funcs, supported_font_funcs[i].name)) + { + set_font_funcs = supported_font_funcs[i].func; + break; + } + if (!set_font_funcs) + { + GString *s = g_string_new (nullptr); + for (unsigned int i = 0; i < ARRAY_LENGTH (supported_font_funcs); i++) + { + if (i) + g_string_append_c (s, '/'); + g_string_append (s, supported_font_funcs[i].name); + } + char *p = g_string_free (s, FALSE); + fail (false, "Unknown font function implementation `%s'; supported values are: %s; default is %s", + font_funcs, + p, + supported_font_funcs[0].name); + //free (p); + } + } + set_font_funcs (font); + + return font; +} + + +const char * +text_options_t::get_line (unsigned int *len) +{ + if (text) { + if (!line) line = text; + if (line_len == (unsigned int) -1) + line_len = strlen (line); + + if (!line_len) { + *len = 0; + return nullptr; + } + + const char *ret = line; + const char *p = (const char *) memchr (line, '\n', line_len); + unsigned int ret_len; + if (!p) { + ret_len = line_len; + line += ret_len; + line_len = 0; + } else { + ret_len = p - ret; + line += ret_len + 1; + line_len -= ret_len + 1; + } + + *len = ret_len; + return ret; + } + + if (!fp) { + if (!text_file) + fail (true, "At least one of text or text-file must be set"); + + if (0 != strcmp (text_file, "-")) + fp = fopen (text_file, "r"); + else + fp = stdin; + + if (!fp) + fail (false, "Failed opening text file `%s': %s", + text_file, strerror (errno)); + + gs = g_string_new (nullptr); + } + + g_string_set_size (gs, 0); + char buf[BUFSIZ]; + while (fgets (buf, sizeof (buf), fp)) { + unsigned int bytes = strlen (buf); + if (bytes && buf[bytes - 1] == '\n') { + bytes--; + g_string_append_len (gs, buf, bytes); + break; + } + g_string_append_len (gs, buf, bytes); + } + if (ferror (fp)) + fail (false, "Failed reading text: %s", + strerror (errno)); + *len = gs->len; + return !*len && feof (fp) ? nullptr : gs->str; +} + + +FILE * +output_options_t::get_file_handle (void) +{ + if (fp) + return fp; + + if (output_file) + fp = fopen (output_file, "wb"); + else { +#if defined(_WIN32) || defined(__CYGWIN__) + setmode (fileno (stdout), O_BINARY); +#endif + fp = stdout; + } + if (!fp) + fail (false, "Cannot open output file `%s': %s", + g_filename_display_name (output_file), strerror (errno)); + + return fp; +} + +static gboolean +parse_verbose (const char *name G_GNUC_UNUSED, + const char *arg G_GNUC_UNUSED, + gpointer data G_GNUC_UNUSED, + GError **error G_GNUC_UNUSED) +{ + format_options_t *format_opts = (format_options_t *) data; + format_opts->show_text = format_opts->show_unicode = format_opts->show_line_num = true; + return true; +} + +static gboolean +parse_ned (const char *name G_GNUC_UNUSED, + const char *arg G_GNUC_UNUSED, + gpointer data G_GNUC_UNUSED, + GError **error G_GNUC_UNUSED) +{ + format_options_t *format_opts = (format_options_t *) data; + format_opts->show_clusters = format_opts->show_advances = false; + return true; +} + +void +format_options_t::add_options (option_parser_t *parser) +{ + GOptionEntry entries[] = + { + {"show-text", 0, 0, G_OPTION_ARG_NONE, &this->show_text, "Prefix each line of output with its corresponding input text", nullptr}, + {"show-unicode", 0, 0, G_OPTION_ARG_NONE, &this->show_unicode, "Prefix each line of output with its corresponding input codepoint(s)", nullptr}, + {"show-line-num", 0, 0, G_OPTION_ARG_NONE, &this->show_line_num, "Prefix each line of output with its corresponding input line number", nullptr}, + {"verbose", 'v', G_OPTION_FLAG_NO_ARG, + G_OPTION_ARG_CALLBACK, (gpointer) &parse_verbose, "Prefix each line of output with all of the above", nullptr}, + {"no-glyph-names", 0, G_OPTION_FLAG_REVERSE, + G_OPTION_ARG_NONE, &this->show_glyph_names, "Output glyph indices instead of names", nullptr}, + {"no-positions", 0, G_OPTION_FLAG_REVERSE, + G_OPTION_ARG_NONE, &this->show_positions, "Do not output glyph positions", nullptr}, + {"no-advances", 0, G_OPTION_FLAG_REVERSE, + G_OPTION_ARG_NONE, &this->show_advances, "Do not output glyph advances", nullptr}, + {"no-clusters", 0, G_OPTION_FLAG_REVERSE, + G_OPTION_ARG_NONE, &this->show_clusters, "Do not output cluster indices", nullptr}, + {"show-extents", 0, 0, G_OPTION_ARG_NONE, &this->show_extents, "Output glyph extents", nullptr}, + {"show-flags", 0, 0, G_OPTION_ARG_NONE, &this->show_flags, "Output glyph flags", nullptr}, + {"ned", 'v', G_OPTION_FLAG_NO_ARG, + G_OPTION_ARG_CALLBACK, (gpointer) &parse_ned, "No Extra Data; Do not output clusters or advances", nullptr}, + {"trace", 'V', 0, G_OPTION_ARG_NONE, &this->trace, "Output interim shaping results", nullptr}, + {nullptr} + }; + 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:", + "Options for the syntax of the output", + this); +} + +void +format_options_t::serialize_unicode (hb_buffer_t *buffer, + GString *gs) +{ + unsigned int num_glyphs = hb_buffer_get_length (buffer); + hb_glyph_info_t *info = hb_buffer_get_glyph_infos (buffer, nullptr); + + g_string_append_c (gs, '<'); + for (unsigned int i = 0; i < num_glyphs; i++) + { + if (i) + g_string_append_c (gs, ','); + g_string_append_printf (gs, "U+%04X", info->codepoint); + info++; + } + g_string_append_c (gs, '>'); +} + +void +format_options_t::serialize_glyphs (hb_buffer_t *buffer, + hb_font_t *font, + hb_buffer_serialize_format_t output_format, + hb_buffer_serialize_flags_t flags, + GString *gs) +{ + g_string_append_c (gs, '['); + unsigned int num_glyphs = hb_buffer_get_length (buffer); + unsigned int start = 0; + + while (start < num_glyphs) + { + char buf[1024]; + unsigned int consumed; + start += hb_buffer_serialize_glyphs (buffer, start, num_glyphs, + buf, sizeof (buf), &consumed, + font, output_format, flags); + if (!consumed) + break; + g_string_append (gs, buf); + } + g_string_append_c (gs, ']'); +} +void +format_options_t::serialize_line_no (unsigned int line_no, + GString *gs) +{ + if (show_line_num) + g_string_append_printf (gs, "%d: ", line_no); +} +void +format_options_t::serialize_buffer_of_text (hb_buffer_t *buffer, + unsigned int line_no, + const char *text, + unsigned int text_len, + hb_font_t *font, + GString *gs) +{ + if (show_text) + { + serialize_line_no (line_no, gs); + g_string_append_c (gs, '('); + g_string_append_len (gs, text, text_len); + g_string_append_c (gs, ')'); + g_string_append_c (gs, '\n'); + } + + if (show_unicode) + { + serialize_line_no (line_no, gs); + serialize_unicode (buffer, gs); + g_string_append_c (gs, '\n'); + } +} +void +format_options_t::serialize_message (unsigned int line_no, + const char *type, + const char *msg, + GString *gs) +{ + serialize_line_no (line_no, gs); + g_string_append_printf (gs, "%s: %s", type, msg); + g_string_append_c (gs, '\n'); +} +void +format_options_t::serialize_buffer_of_glyphs (hb_buffer_t *buffer, + unsigned int line_no, + const char *text, + unsigned int text_len, + hb_font_t *font, + hb_buffer_serialize_format_t output_format, + hb_buffer_serialize_flags_t format_flags, + GString *gs) +{ + serialize_line_no (line_no, gs); + 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[] = + { + {"no-hinting", 0, 0, G_OPTION_ARG_NONE, &this->drop_hints, "Whether to drop hints", nullptr}, + {nullptr} + }; + parser->add_group (entries, + "subset", + "Subset options:", + "Options subsetting", + this); +} diff --git a/chromium/third_party/harfbuzz-ng/src/util/options.hh b/chromium/third_party/harfbuzz-ng/src/util/options.hh new file mode 100644 index 00000000000..467350a929b --- /dev/null +++ b/chromium/third_party/harfbuzz-ng/src/util/options.hh @@ -0,0 +1,690 @@ +/* + * Copyright © 2011 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 OPTIONS_HH +#define OPTIONS_HH + +#include "hb-private.hh" + +#include <stdlib.h> +#include <stddef.h> +#include <string.h> +#include <stdio.h> +#include <assert.h> +#include <math.h> +#include <locale.h> +#include <errno.h> +#include <fcntl.h> +#ifdef HAVE_UNISTD_H +#include <unistd.h> /* for isatty() */ +#endif +#if defined(_WIN32) || defined(__CYGWIN__) +#include <io.h> /* for setmode() under Windows */ +#endif + +#include <hb.h> +#ifdef HAVE_OT +#include <hb-ot.h> +#endif +#include <glib.h> +#include <glib/gprintf.h> + +#if !GLIB_CHECK_VERSION (2, 22, 0) +# define g_mapped_file_unref g_mapped_file_free +#endif + +void fail (hb_bool_t suggest_help, const char *format, ...) G_GNUC_NORETURN G_GNUC_PRINTF (2, 3); + +extern hb_bool_t debug; + +struct option_group_t +{ + virtual void add_options (struct option_parser_t *parser) = 0; + + virtual void pre_parse (GError **error G_GNUC_UNUSED) {}; + virtual void post_parse (GError **error G_GNUC_UNUSED) {}; +}; + + +struct option_parser_t +{ + option_parser_t (const char *usage) { + memset (this, 0, sizeof (*this)); + usage_str = usage; + context = g_option_context_new (usage); + to_free = g_ptr_array_new (); + + add_main_options (); + } + ~option_parser_t (void) { + g_option_context_free (context); + g_ptr_array_foreach (to_free, (GFunc) g_free, nullptr); + g_ptr_array_free (to_free, TRUE); + } + + void add_main_options (void); + + void add_group (GOptionEntry *entries, + const gchar *name, + const gchar *description, + const gchar *help_description, + option_group_t *option_group); + + void free_later (char *p) { + g_ptr_array_add (to_free, p); + } + + void parse (int *argc, char ***argv); + + G_GNUC_NORETURN void usage (void) { + g_printerr ("Usage: %s [OPTION...] %s\n", g_get_prgname (), usage_str); + exit (1); + } + + private: + const char *usage_str; + GOptionContext *context; + GPtrArray *to_free; +}; + + +#define DEFAULT_MARGIN 16 +#define DEFAULT_FORE "#000000" +#define DEFAULT_BACK "#FFFFFF" +#define FONT_SIZE_UPEM 0x7FFFFFFF +#define FONT_SIZE_NONE 0 + +struct view_options_t : option_group_t +{ + view_options_t (option_parser_t *parser) { + annotate = false; + fore = nullptr; + back = nullptr; + line_space = 0; + margin.t = margin.r = margin.b = margin.l = DEFAULT_MARGIN; + + add_options (parser); + } + ~view_options_t (void) + { + g_free (fore); + g_free (back); + } + + void add_options (option_parser_t *parser); + + hb_bool_t annotate; + char *fore; + char *back; + double line_space; + struct margin_t { + double t, r, b, l; + } margin; +}; + + +struct shape_options_t : option_group_t +{ + shape_options_t (option_parser_t *parser) + { + direction = language = script = nullptr; + bot = eot = preserve_default_ignorables = remove_default_ignorables = false; + features = nullptr; + num_features = 0; + shapers = nullptr; + utf8_clusters = false; + cluster_level = HB_BUFFER_CLUSTER_LEVEL_DEFAULT; + normalize_glyphs = false; + verify = false; + num_iterations = 1; + + add_options (parser); + } + ~shape_options_t (void) + { + g_free (direction); + g_free (language); + g_free (script); + free (features); + g_strfreev (shapers); + } + + void add_options (option_parser_t *parser); + + void setup_buffer (hb_buffer_t *buffer) + { + hb_buffer_set_direction (buffer, hb_direction_from_string (direction, -1)); + hb_buffer_set_script (buffer, hb_script_from_string (script, -1)); + hb_buffer_set_language (buffer, hb_language_from_string (language, -1)); + hb_buffer_set_flags (buffer, (hb_buffer_flags_t) + (HB_BUFFER_FLAG_DEFAULT | + (bot ? HB_BUFFER_FLAG_BOT : 0) | + (eot ? HB_BUFFER_FLAG_EOT : 0) | + (preserve_default_ignorables ? HB_BUFFER_FLAG_PRESERVE_DEFAULT_IGNORABLES : 0) | + (remove_default_ignorables ? HB_BUFFER_FLAG_REMOVE_DEFAULT_IGNORABLES : 0) | + 0)); + hb_buffer_set_cluster_level (buffer, cluster_level); + hb_buffer_guess_segment_properties (buffer); + } + + static void copy_buffer_properties (hb_buffer_t *dst, hb_buffer_t *src) + { + hb_segment_properties_t props; + hb_buffer_get_segment_properties (src, &props); + hb_buffer_set_segment_properties (dst, &props); + hb_buffer_set_flags (dst, hb_buffer_get_flags (src)); + hb_buffer_set_cluster_level (dst, hb_buffer_get_cluster_level (src)); + } + + void populate_buffer (hb_buffer_t *buffer, const char *text, int text_len, + const char *text_before, const char *text_after) + { + hb_buffer_clear_contents (buffer); + if (text_before) { + unsigned int len = strlen (text_before); + hb_buffer_add_utf8 (buffer, text_before, len, len, 0); + } + hb_buffer_add_utf8 (buffer, text, text_len, 0, text_len); + if (text_after) { + hb_buffer_add_utf8 (buffer, text_after, -1, 0, 0); + } + + if (!utf8_clusters) { + /* Reset cluster values to refer to Unicode character index + * instead of UTF-8 index. */ + unsigned int num_glyphs = hb_buffer_get_length (buffer); + hb_glyph_info_t *info = hb_buffer_get_glyph_infos (buffer, nullptr); + for (unsigned int i = 0; i < num_glyphs; i++) + { + info->cluster = i; + info++; + } + } + + setup_buffer (buffer); + } + + hb_bool_t shape (hb_font_t *font, hb_buffer_t *buffer, const char **error=nullptr) + { + hb_buffer_t *text_buffer = nullptr; + if (verify) + { + text_buffer = hb_buffer_create (); + hb_buffer_append (text_buffer, buffer, 0, -1); + } + + if (!hb_shape_full (font, buffer, features, num_features, shapers)) + { + if (error) + *error = "all shapers failed."; + goto fail; + } + + if (normalize_glyphs) + hb_buffer_normalize_glyphs (buffer); + + if (verify && !verify_buffer (buffer, text_buffer, font, error)) + goto fail; + + if (text_buffer) + hb_buffer_destroy (text_buffer); + + return true; + + fail: + if (text_buffer) + hb_buffer_destroy (text_buffer); + + return false; + } + + bool verify_buffer (hb_buffer_t *buffer, + hb_buffer_t *text_buffer, + hb_font_t *font, + const char **error=nullptr) + { + if (!verify_buffer_monotone (buffer, error)) + return false; + if (!verify_buffer_safe_to_break (buffer, text_buffer, font, error)) + return false; + return true; + } + + bool verify_buffer_monotone (hb_buffer_t *buffer, const char **error=nullptr) + { + /* Check that clusters are monotone. */ + if (cluster_level == HB_BUFFER_CLUSTER_LEVEL_MONOTONE_GRAPHEMES || + cluster_level == HB_BUFFER_CLUSTER_LEVEL_MONOTONE_CHARACTERS) + { + bool is_forward = HB_DIRECTION_IS_FORWARD (hb_buffer_get_direction (buffer)); + + unsigned int num_glyphs; + hb_glyph_info_t *info = hb_buffer_get_glyph_infos (buffer, &num_glyphs); + + for (unsigned int i = 1; i < num_glyphs; i++) + if (info[i-1].cluster != info[i].cluster && + (info[i-1].cluster < info[i].cluster) != is_forward) + { + if (error) + *error = "clusters are not monotone."; + return false; + } + } + + return true; + } + + bool verify_buffer_safe_to_break (hb_buffer_t *buffer, + hb_buffer_t *text_buffer, + hb_font_t *font, + const char **error=nullptr) + { + if (cluster_level != HB_BUFFER_CLUSTER_LEVEL_MONOTONE_GRAPHEMES && + cluster_level != HB_BUFFER_CLUSTER_LEVEL_MONOTONE_CHARACTERS) + { + /* Cannot perform this check without monotone clusters. + * Then again, unsafe-to-break flag is much harder to use without + * monotone clusters. */ + return true; + } + + /* Check that breaking up shaping at safe-to-break is indeed safe. */ + + hb_buffer_t *fragment = hb_buffer_create (); + hb_buffer_t *reconstruction = hb_buffer_create (); + copy_buffer_properties (reconstruction, buffer); + + unsigned int num_glyphs; + hb_glyph_info_t *info = hb_buffer_get_glyph_infos (buffer, &num_glyphs); + + unsigned int num_chars; + hb_glyph_info_t *text = hb_buffer_get_glyph_infos (text_buffer, &num_chars); + + /* Chop text and shape fragments. */ + bool forward = HB_DIRECTION_IS_FORWARD (hb_buffer_get_direction (buffer)); + unsigned int start = 0; + unsigned int text_start = forward ? 0 : num_chars; + unsigned int text_end = text_start; + for (unsigned int end = 1; end < num_glyphs + 1; end++) + { + if (end < num_glyphs && + (info[end].cluster == info[end-1].cluster || + info[end-(forward?0:1)].mask & HB_GLYPH_FLAG_UNSAFE_TO_BREAK)) + continue; + + /* Shape segment corresponding to glyphs start..end. */ + if (end == num_glyphs) + { + if (forward) + text_end = num_chars; + else + text_start = 0; + } + else + { + if (forward) + { + unsigned int cluster = info[end].cluster; + while (text_end < num_chars && text[text_end].cluster < cluster) + text_end++; + } + else + { + unsigned int cluster = info[end - 1].cluster; + while (text_start && text[text_start - 1].cluster >= cluster) + text_start--; + } + } + assert (text_start < text_end); + + if (0) + printf("start %d end %d text start %d end %d\n", start, end, text_start, text_end); + + hb_buffer_clear_contents (fragment); + copy_buffer_properties (fragment, buffer); + + /* 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); + if (text_end < num_chars) + 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); + if (!hb_shape_full (font, fragment, features, num_features, shapers)) + { + if (error) + *error = "all shapers failed while shaping fragment."; + hb_buffer_destroy (reconstruction); + hb_buffer_destroy (fragment); + return false; + } + hb_buffer_append (reconstruction, fragment, 0, -1); + + start = end; + if (forward) + text_start = text_end; + else + text_end = text_start; + } + + bool ret = true; + hb_buffer_diff_flags_t diff = hb_buffer_diff (reconstruction, buffer, (hb_codepoint_t) -1, 0); + if (diff) + { + if (error) + *error = "Safe-to-break test failed."; + ret = false; + + /* Return the reconstructed result instead so it can be inspected. */ + hb_buffer_set_length (buffer, 0); + hb_buffer_append (buffer, reconstruction, 0, -1); + } + + hb_buffer_destroy (reconstruction); + hb_buffer_destroy (fragment); + + return ret; + } + + void shape_closure (const char *text, int text_len, + hb_font_t *font, hb_buffer_t *buffer, + hb_set_t *glyphs) + { + hb_buffer_reset (buffer); + hb_buffer_add_utf8 (buffer, text, text_len, 0, text_len); + setup_buffer (buffer); + hb_ot_shape_glyphs_closure (font, buffer, features, num_features, glyphs); + } + + /* Buffer properties */ + char *direction; + char *language; + char *script; + + /* Buffer flags */ + hb_bool_t bot; + hb_bool_t eot; + hb_bool_t preserve_default_ignorables; + hb_bool_t remove_default_ignorables; + + hb_feature_t *features; + unsigned int num_features; + char **shapers; + hb_bool_t utf8_clusters; + hb_buffer_cluster_level_t cluster_level; + hb_bool_t normalize_glyphs; + hb_bool_t verify; + unsigned int num_iterations; +}; + + +struct font_options_t : option_group_t +{ + font_options_t (option_parser_t *parser, + int default_font_size_, + unsigned int subpixel_bits_) + { + variations = nullptr; + num_variations = 0; + default_font_size = default_font_size_; + x_ppem = 0; + y_ppem = 0; + ptem = 0.; + subpixel_bits = subpixel_bits_; + font_file = nullptr; + face_index = 0; + font_size_x = font_size_y = default_font_size; + font_funcs = nullptr; + + font = nullptr; + + add_options (parser); + } + ~font_options_t (void) { + g_free (font_file); + free (variations); + g_free (font_funcs); + hb_font_destroy (font); + } + + void add_options (option_parser_t *parser); + + hb_font_t *get_font (void) const; + + char *font_file; + int face_index; + hb_variation_t *variations; + unsigned int num_variations; + int default_font_size; + int x_ppem; + int y_ppem; + double ptem; + unsigned int subpixel_bits; + mutable double font_size_x; + mutable double font_size_y; + char *font_funcs; + + private: + mutable hb_font_t *font; +}; + + +struct text_options_t : option_group_t +{ + text_options_t (option_parser_t *parser) { + text_before = nullptr; + text_after = nullptr; + + text = nullptr; + text_file = nullptr; + + fp = nullptr; + gs = nullptr; + line = nullptr; + line_len = (unsigned int) -1; + + add_options (parser); + } + ~text_options_t (void) { + g_free (text_before); + g_free (text_after); + g_free (text); + g_free (text_file); + if (gs) + g_string_free (gs, true); + if (fp) + fclose (fp); + } + + void add_options (option_parser_t *parser); + + void post_parse (GError **error G_GNUC_UNUSED) { + if (text && text_file) + g_set_error (error, + G_OPTION_ERROR, G_OPTION_ERROR_BAD_VALUE, + "Only one of text and text-file can be set"); + }; + + const char *get_line (unsigned int *len); + + char *text_before; + char *text_after; + + char *text; + char *text_file; + + private: + FILE *fp; + GString *gs; + char *line; + unsigned int line_len; +}; + +struct output_options_t : option_group_t +{ + output_options_t (option_parser_t *parser, + const char **supported_formats_ = nullptr) { + output_file = nullptr; + output_format = nullptr; + supported_formats = supported_formats_; + explicit_output_format = false; + + fp = nullptr; + + add_options (parser); + } + ~output_options_t (void) { + g_free (output_file); + g_free (output_format); + if (fp) + fclose (fp); + } + + void add_options (option_parser_t *parser); + + void post_parse (GError **error G_GNUC_UNUSED) + { + if (output_format) + explicit_output_format = true; + + if (output_file && !output_format) { + output_format = strrchr (output_file, '.'); + if (output_format) + { + output_format++; /* skip the dot */ + output_format = strdup (output_format); + } + } + + if (output_file && 0 == strcmp (output_file, "-")) + output_file = nullptr; /* STDOUT */ + } + + FILE *get_file_handle (void); + + char *output_file; + char *output_format; + const char **supported_formats; + bool explicit_output_format; + + mutable FILE *fp; +}; + +struct format_options_t : option_group_t +{ + format_options_t (option_parser_t *parser) { + show_glyph_names = true; + show_positions = true; + show_advances = true; + show_clusters = true; + show_text = false; + show_unicode = false; + show_line_num = false; + show_extents = false; + show_flags = false; + trace = false; + + add_options (parser); + } + + void add_options (option_parser_t *parser); + + void serialize_unicode (hb_buffer_t *buffer, + GString *gs); + void serialize_glyphs (hb_buffer_t *buffer, + hb_font_t *font, + hb_buffer_serialize_format_t format, + hb_buffer_serialize_flags_t flags, + GString *gs); + void serialize_line_no (unsigned int line_no, + GString *gs); + void serialize_buffer_of_text (hb_buffer_t *buffer, + unsigned int line_no, + const char *text, + unsigned int text_len, + hb_font_t *font, + GString *gs); + void serialize_message (unsigned int line_no, + const char *type, + const char *msg, + GString *gs); + void serialize_buffer_of_glyphs (hb_buffer_t *buffer, + unsigned int line_no, + const char *text, + unsigned int text_len, + hb_font_t *font, + hb_buffer_serialize_format_t output_format, + hb_buffer_serialize_flags_t format_flags, + GString *gs); + + + hb_bool_t show_glyph_names; + hb_bool_t show_positions; + hb_bool_t show_advances; + hb_bool_t show_clusters; + hb_bool_t show_text; + hb_bool_t show_unicode; + hb_bool_t show_line_num; + hb_bool_t show_extents; + hb_bool_t show_flags; + hb_bool_t trace; +}; + +struct subset_options_t : option_group_t +{ + subset_options_t (option_parser_t *parser) + { + drop_hints = false; + + add_options (parser); + } + + void add_options (option_parser_t *parser); + + hb_bool_t drop_hints; +}; + +/* fallback implementation for scalbn()/scalbnf() for pre-2013 MSVC */ +#if defined (_MSC_VER) && (_MSC_VER < 1800) + +#ifndef FLT_RADIX +#define FLT_RADIX 2 +#endif + +__inline long double scalbn (long double x, int exp) +{ + return x * (pow ((long double) FLT_RADIX, exp)); +} + +__inline float scalbnf (float x, int exp) +{ + return x * (pow ((float) FLT_RADIX, exp)); +} +#endif + +#endif diff --git a/chromium/third_party/harfbuzz-ng/src/util/shape-consumer.hh b/chromium/third_party/harfbuzz-ng/src/util/shape-consumer.hh new file mode 100644 index 00000000000..fa419f185f2 --- /dev/null +++ b/chromium/third_party/harfbuzz-ng/src/util/shape-consumer.hh @@ -0,0 +1,101 @@ +/* + * Copyright © 2011,2012 Google, Inc. + * + * This is part of HarfBuzz, a text shaping library. + * + * Permission is hereby granted, without written agreement and without + * license or royalty fees, to use, copy, modify, and distribute this + * software and its documentation for any purpose, provided that the + * above copyright notice and the following two paragraphs appear in + * all copies of this software. + * + * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR + * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES + * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN + * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, + * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS + * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO + * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + * + * Google Author(s): Behdad Esfahbod + */ + +#ifndef HB_SHAPE_CONSUMER_HH +#define HB_SHAPE_CONSUMER_HH + +#include "hb-private.hh" +#include "options.hh" + + +template <typename output_t> +struct shape_consumer_t +{ + shape_consumer_t (option_parser_t *parser) + : failed (false), + shaper (parser), + output (parser), + font (nullptr), + buffer (nullptr) {} + + void init (hb_buffer_t *buffer_, + const font_options_t *font_opts) + { + font = hb_font_reference (font_opts->get_font ()); + failed = false; + buffer = hb_buffer_reference (buffer_); + + output.init (buffer, font_opts); + } + void consume_line (const char *text, + unsigned int text_len, + const char *text_before, + const char *text_after) + { + output.new_line (); + + for (unsigned int n = shaper.num_iterations; n; n--) + { + const char *error = nullptr; + + shaper.populate_buffer (buffer, text, text_len, text_before, text_after); + if (n == 1) + output.consume_text (buffer, text, text_len, shaper.utf8_clusters); + if (!shaper.shape (font, buffer, &error)) + { + failed = true; + output.error (error); + if (hb_buffer_get_content_type (buffer) == HB_BUFFER_CONTENT_TYPE_GLYPHS) + break; + else + return; + } + } + + output.consume_glyphs (buffer, text, text_len, shaper.utf8_clusters); + } + void finish (const font_options_t *font_opts) + { + output.finish (buffer, font_opts); + hb_font_destroy (font); + font = nullptr; + hb_buffer_destroy (buffer); + buffer = nullptr; + } + + public: + bool failed; + + protected: + shape_options_t shaper; + output_t output; + + hb_font_t *font; + hb_buffer_t *buffer; +}; + + +#endif diff --git a/chromium/third_party/harfbuzz-ng/src/util/view-cairo.cc b/chromium/third_party/harfbuzz-ng/src/util/view-cairo.cc new file mode 100644 index 00000000000..f4f2bc50683 --- /dev/null +++ b/chromium/third_party/harfbuzz-ng/src/util/view-cairo.cc @@ -0,0 +1,133 @@ +/* + * Copyright © 2011 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 + */ + +#include "view-cairo.hh" + +#include <assert.h> + + +void +view_cairo_t::render (const font_options_t *font_opts) +{ + bool vertical = HB_DIRECTION_IS_VERTICAL (direction); + int vert = vertical ? 1 : 0; + int horiz = vertical ? 0 : 1; + + int x_sign = font_opts->font_size_x < 0 ? -1 : +1; + int y_sign = font_opts->font_size_y < 0 ? -1 : +1; + + hb_font_t *font = font_opts->get_font(); + hb_font_extents_t extents; + hb_font_get_extents_for_direction (font, direction, &extents); + + double ascent = y_sign * scalbn ((double) extents.ascender, scale_bits); + double descent = y_sign * -scalbn ((double) extents.descender, scale_bits); + double font_height = y_sign * scalbn ((double) extents.ascender - extents.descender + extents.line_gap, scale_bits); + double leading = font_height + view_options.line_space; + + /* Calculate surface size. */ + double w, h; + (vertical ? w : h) = (int) lines->len * leading - view_options.line_space; + (vertical ? h : w) = 0; + for (unsigned int i = 0; i < lines->len; i++) { + helper_cairo_line_t &line = g_array_index (lines, helper_cairo_line_t, i); + double x_advance, y_advance; + line.get_advance (&x_advance, &y_advance); + if (vertical) + h = MAX (h, y_sign * y_advance); + else + w = MAX (w, x_sign * x_advance); + } + + cairo_scaled_font_t *scaled_font = helper_cairo_create_scaled_font (font_opts); + + /* See if font needs color. */ + cairo_content_t content = CAIRO_CONTENT_ALPHA; + if (helper_cairo_scaled_font_has_color (scaled_font)) + content = CAIRO_CONTENT_COLOR; + + /* Create surface. */ + cairo_t *cr = helper_cairo_create_context (w + view_options.margin.l + view_options.margin.r, + h + view_options.margin.t + view_options.margin.b, + &view_options, &output_options, content); + cairo_set_scaled_font (cr, scaled_font); + + /* Setup coordinate system. */ + cairo_translate (cr, view_options.margin.l, view_options.margin.t); + if (vertical) + cairo_translate (cr, + w /* We stack lines right to left */ + -font_height * .5 /* "ascent" for vertical */, + y_sign < 0 ? h : 0); + else + { + cairo_translate (cr, + x_sign < 0 ? w : 0, + y_sign < 0 ? descent : ascent); + } + + /* Draw. */ + cairo_translate (cr, +vert * leading, -horiz * leading); + for (unsigned int i = 0; i < lines->len; i++) + { + helper_cairo_line_t &l = g_array_index (lines, helper_cairo_line_t, i); + + cairo_translate (cr, -vert * leading, +horiz * leading); + + if (view_options.annotate) { + cairo_save (cr); + + /* Draw actual glyph origins */ + cairo_set_source_rgba (cr, 1., 0., 0., .5); + cairo_set_line_width (cr, 5); + cairo_set_line_cap (cr, CAIRO_LINE_CAP_ROUND); + for (unsigned i = 0; i < l.num_glyphs; i++) { + cairo_move_to (cr, l.glyphs[i].x, l.glyphs[i].y); + cairo_rel_line_to (cr, 0, 0); + } + cairo_stroke (cr); + + cairo_restore (cr); + } + + if (0 && cairo_surface_get_type (cairo_get_target (cr)) == CAIRO_SURFACE_TYPE_IMAGE) { + /* cairo_show_glyphs() doesn't support subpixel positioning */ + cairo_glyph_path (cr, l.glyphs, l.num_glyphs); + cairo_fill (cr); + } else if (l.num_clusters) + cairo_show_text_glyphs (cr, + l.utf8, l.utf8_len, + l.glyphs, l.num_glyphs, + l.clusters, l.num_clusters, + l.cluster_flags); + else + cairo_show_glyphs (cr, l.glyphs, l.num_glyphs); + } + + /* Clean up. */ + helper_cairo_destroy_context (cr); + cairo_scaled_font_destroy (scaled_font); +} diff --git a/chromium/third_party/harfbuzz-ng/src/util/view-cairo.hh b/chromium/third_party/harfbuzz-ng/src/util/view-cairo.hh new file mode 100644 index 00000000000..d28c3cd16a4 --- /dev/null +++ b/chromium/third_party/harfbuzz-ng/src/util/view-cairo.hh @@ -0,0 +1,102 @@ +/* + * Copyright © 2011 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 VIEW_CAIRO_HH +#define VIEW_CAIRO_HH + +#include "hb-private.hh" +#include "options.hh" +#include "helper-cairo.hh" + + +struct view_cairo_t +{ + view_cairo_t (option_parser_t *parser) + : output_options (parser, helper_cairo_supported_formats), + view_options (parser), + direction (HB_DIRECTION_INVALID), + lines (0), scale_bits (0) {} + ~view_cairo_t (void) { + if (debug) + cairo_debug_reset_static_data (); + } + + void init (hb_buffer_t *buffer, const font_options_t *font_opts) + { + lines = g_array_new (false, false, sizeof (helper_cairo_line_t)); + scale_bits = -font_opts->subpixel_bits; + } + void new_line (void) + { + } + void consume_text (hb_buffer_t *buffer, + const char *text, + unsigned int text_len, + hb_bool_t utf8_clusters) + { + } + void error (const char *message) + { + g_printerr ("%s: %s\n", g_get_prgname (), message); + } + void consume_glyphs (hb_buffer_t *buffer, + const char *text, + unsigned int text_len, + hb_bool_t utf8_clusters) + { + direction = hb_buffer_get_direction (buffer); + helper_cairo_line_t l; + helper_cairo_line_from_buffer (&l, buffer, text, text_len, scale_bits, utf8_clusters); + g_array_append_val (lines, l); + } + void finish (hb_buffer_t *buffer, const font_options_t *font_opts) + { + render (font_opts); + + for (unsigned int i = 0; i < lines->len; i++) { + helper_cairo_line_t &line = g_array_index (lines, helper_cairo_line_t, i); + line.finish (); + } +#if GLIB_CHECK_VERSION (2, 22, 0) + g_array_unref (lines); +#else + g_array_free (lines, TRUE); +#endif + } + + protected: + + output_options_t output_options; + view_options_t view_options; + + void render (const font_options_t *font_opts); + + hb_direction_t direction; // Remove this, make segment_properties accessible + GArray *lines; + int scale_bits; +}; + +#endif |