diff options
author | André Fabian Silva Delgado <emulatorman@parabola.nu> | 2016-12-03 14:21:36 -0300 |
---|---|---|
committer | André Fabian Silva Delgado <emulatorman@parabola.nu> | 2016-12-04 01:12:54 -0300 |
commit | b8c1a2f78a819a1b484cce6d2ba878db9e80fa2f (patch) | |
tree | 7d87d04cc040a31df1e91a76c280a24779487fd9 /unmaintained | |
parent | dafd37bb0307e11a5b55b719e9473da95862d7f8 (diff) |
icecat-45.5.1_gnu1-1: updating version
Diffstat (limited to 'unmaintained')
-rw-r--r-- | unmaintained/icecat/PKGBUILD | 193 | ||||
-rw-r--r-- | unmaintained/icecat/disable-crypto-hardening-settings.patch | 54 | ||||
-rw-r--r-- | unmaintained/icecat/disable-spoofSource-referer.patch | 26 | ||||
-rw-r--r-- | unmaintained/icecat/firefox-gcc-6.0.patch | 26 | ||||
-rw-r--r-- | unmaintained/icecat/gcc6-fix-compilation-for-IceCat.patch | 37 | ||||
-rw-r--r-- | unmaintained/icecat/gnu_headshadow.png | bin | 6785 -> 0 bytes | |||
-rw-r--r-- | unmaintained/icecat/harfbuzz-1.1.3.patch | 27038 | ||||
-rw-r--r-- | unmaintained/icecat/icecat-fixed-loading-icon.png | bin | 12184 -> 0 bytes | |||
-rw-r--r-- | unmaintained/icecat/icecat-install-dir.patch | 12 | ||||
-rw-r--r-- | unmaintained/icecat/icecat.desktop | 352 | ||||
-rw-r--r-- | unmaintained/icecat/icecat.install | 13 | ||||
-rw-r--r-- | unmaintained/icecat/libre.patch | 890 | ||||
-rw-r--r-- | unmaintained/icecat/mozconfig | 40 | ||||
-rw-r--r-- | unmaintained/icecat/mozilla-1228540-1.patch | 84 | ||||
-rw-r--r-- | unmaintained/icecat/remove-google-play-services-support.patch | 64 | ||||
-rw-r--r-- | unmaintained/icecat/vendor.js | 28 |
16 files changed, 0 insertions, 28857 deletions
diff --git a/unmaintained/icecat/PKGBUILD b/unmaintained/icecat/PKGBUILD deleted file mode 100644 index e44a520db..000000000 --- a/unmaintained/icecat/PKGBUILD +++ /dev/null @@ -1,193 +0,0 @@ -# Maintainer: André Silva <emulatorman@parabola.nu> -# Contributor: Márcio Silva <coadde@parabola.nu> -# Contributor (ConnochaetOS): Henry Jensen <hjensen@connochaetos.org> -# Contributor: Luke Shumaker <lukeshu@sbcglobal.net> -# Contributor: fauno <fauno@kiwwwi.com.ar> -# Contributor: vando <facundo@esdebian.org> -# Contributor (Arch): Jakub Schmidtke <sjakub@gmail.com> -# Contributor: Figue <ffigue at gmail> -# Thank you very much to the older contributors: -# Contributor: evr <evanroman at gmail> -# Contributor: Muhammad 'MJ' Jassim <UnbreakableMJ@gmail.com> - -_pgo=true - -pkgname=icecat -_pkgver=38.8.0-gnu2 -pkgver=${_pkgver//-/_} -pkgrel=2 - -pkgdesc="GNU IceCat, the standalone web browser based on Mozilla Firefox." -arch=(i686 x86_64) -license=(MPL GPL LGPL) -depends=(alsa-lib dbus-glib ffmpeg gtk2 hunspell icu=57.1 libevent libvpx=1.6.0 libxt mime-types mozilla-common mozilla-searchplugins nss sqlite startup-notification ttf-font) -makedepends=(diffutils gst-plugins-base-libs imake inetutils libpulse mesa python2 unzip yasm zip) -options=(!emptydirs !makeflags debug) -if $_pgo; then - makedepends+=(xorg-server-xvfb) - options+=(!ccache) -fi -optdepends=('networkmanager: Location detection via available WiFi networks' - 'gst-plugins-good: h.264 video' - 'gst-libav: h.264 video' - 'upower: Battery API') -url="http://www.gnu.org/software/gnuzilla/" -install=$pkgname.install -source=(http://ftp.gnu.org/gnu/gnuzilla/$_pkgver/$pkgname-$_pkgver.tar.bz2{,.sig} -#mksource=(http://jenkins.trisquel.info/$pkgname/$pkgname-$_pkgver.tar.bz2) -#source=(https://repo.parabola.nu/other/$pkgname/$pkgname-$_pkgver.tar.bz2{,.sig} - mozconfig - libre.patch - gnu_headshadow.png - $pkgname.desktop - $pkgname-install-dir.patch - firefox-gcc-6.0.patch gcc6-fix-compilation-for-IceCat.patch harfbuzz-1.1.3.patch mozilla-1228540-1.patch - vendor.js - $pkgname-fixed-loading-icon.png - remove-google-play-services-support.patch - disable-crypto-hardening-settings.patch - disable-spoofSource-referer.patch) -sha256sums=('0b0a323c7e167c3d23df9c1d33d2ca2d8c5deaca3f43841f4b2a5fac7f5067f9' - 'SKIP' - 'ced9ddfe6458524cf4f26f86d9bda8f0bcb747c233dc161df6af9ab56dd166ef' - 'dd173c9283babb8a04bf55274de05e823161f7d13adb8c5e21dd5a9c0dc549a2' - '93e3001ce152e1d142619e215a9ef07dd429943b99d21726c25da9ceb31e31cd' - '52df9ffeb52166ed4abd9a132ee4a9017b9c4980f0725ba383610ccfb06d4745' - '5bdab2de5520fb4d3dbc453d9f73d20e0e077bf652bc780fc17184ba6c718a47' - '4d1e1ddabc9e975ed39f49e134559a29e01cd49439e358233f1ede43bf5a52bf' - '329cf6753d29ae64a4336a8a76ee71f0d331a39132159401e4d11de65b708a07' - '8a17454d2be90e94694818a1d1a6bdb615eced4d3a7a75af42080c99ce942f2f' - 'd1ccbaf0973615c57f7893355e5cd3a89efb4e91071d0ec376e429b50cf6ed19' - '977aa49b940f1da049cefa2878a63ac6669a78e63e9d55bb11db7b8f8fb64c33' - '68e3a5b47c6d175cc95b98b069a15205f027cab83af9e075818d38610feb6213' - '9e651b0f7e7d9d663e8b24077d52bad15f011871747743aff60d6e2d7a45ae5b' - '0166aa368420f0bf0aab064b2188e3d852b241efeeb27dee66df2bc15e84b83a' - 'c50043266e69f5844e6dce9ea7193af79587dcaa66806932d7867281a176f03e') -validpgpkeys=( - 'A57369A8BABC2542B5A0368C3C76EED7D7E04784' # Ruben Rodriguez - 'C92BAA713B8D53D3CAE63FC9E6974752F9704456' # André Silva -) - -prepare() { - export GNU_BUILD="gnuzilla-release" - - mv $pkgname-${pkgver%_*} "$srcdir/$GNU_BUILD" - cd "$srcdir/$GNU_BUILD" - - # Put gnu_headshadow.png on the source code - install -m644 "$srcdir/gnu_headshadow.png" \ - browser/base/content/abouthome - - # Install to /usr/lib/$pkgname - patch -Np1 -i "$srcdir/$pkgname-install-dir.patch" - - # Compilation fix (FS#49243 and FS#49363), internet and Icedove package - patch -Np1 -i $srcdir/gcc6-fix-compilation-for-IceCat.patch - patch -Np1 -i $srcdir/firefox-gcc-6.0.patch - - # Update to harfbuzz 1.1.3 (following Icedove in [libre]) - patch -Np0 -i $srcdir/harfbuzz-1.1.3.patch - patch -Np1 -i $srcdir/mozilla-1228540-1.patch - - # Patch and remove anything that's left - patch -Np1 -i "$srcdir/libre.patch" - patch -Np1 -i "$srcdir/remove-google-play-services-support.patch" - rm -v browser/base/content/abouthome/snippet*.png || true - sed -i '\|abouthome/snippet|d - ' browser/base/jar.mn - - # Load our build config, disable SafeSearch - cp "$srcdir/mozconfig" .mozconfig - - mkdir "$srcdir/path" - - # WebRTC build tries to execute "python" and expects Python 2 - ln -s /usr/bin/python2 "$srcdir/path/python" - - # Configure script misdetects the preprocessor without an optimization level - # https://bugs.archlinux.org/task/34644 - sed -i '/ac_cpp=/s/$CPPFLAGS/& -O2/' configure - - # Fix tab loading icon (doesn't work with libpng 1.6) - # https://bugzilla.mozilla.org/show_bug.cgi?id=841734 - cp "$srcdir/$pkgname-fixed-loading-icon.png" \ - browser/themes/linux/tabbrowser/loading.png - - # Disable crypto hardening settings for now - # https://lists.parabola.nu/pipermail/assist/2015-October/000534.html - # https://labs.parabola.nu/issues/842 - patch -Np1 -i "$srcdir/disable-crypto-hardening-settings.patch" - - # Disable spoofSource referer since it breaks referer function used by some sites - # https://labs.parabola.nu/issues/1073 - patch -Np1 -i "$srcdir/disable-spoofSource-referer.patch" -} - -build() { - export GNU_BUILD="gnuzilla-release" - - cd "$srcdir/$GNU_BUILD" - - # _FORTIFY_SOURCE causes configure failures - CPPFLAGS+=" -O2" - - # Hardening - LDFLAGS+=" -Wl,-z,now" - - # GCC 6 - CFLAGS+=" -fno-delete-null-pointer-checks -fno-lifetime-dse -fno-schedule-insns2" - CXXFLAGS+=" -fno-delete-null-pointer-checks -fno-lifetime-dse -fno-schedule-insns2" - - export PATH="$srcdir/path:$PATH" - export PYTHON="/usr/bin/python2" - - if $_pgo; then - # Do PGO - xvfb-run -a -s "-extension GLX -screen 0 1280x1024x24" \ - make -f client.mk build MOZ_PGO=1 - else - make -f client.mk build - fi -} - -package() { - export GNU_BUILD="gnuzilla-release" - - cd "$srcdir/$GNU_BUILD" - make -f client.mk DESTDIR="$pkgdir" INSTALL_SDK= install - - install -Dm644 ../vendor.js "$pkgdir/usr/lib/$pkgname/browser/defaults/preferences/vendor.js" - - - brandingdir=browser/branding/official - icondir="$pkgdir/usr/share/icons/hicolor" - for i in 16 22 24 32 48 256; do - install -Dm644 "$brandingdir/default$i.png" \ - "$icondir/${i}x${i}/apps/$pkgname.png" - done - install -Dm644 "$brandingdir/content/icon64.png" \ - "$icondir/64x64/apps/$pkgname.png" - install -Dm644 "$brandingdir/mozicon128.png" \ - "$icondir/128x128/apps/$pkgname.png" - install -Dm644 "$brandingdir/content/about-logo.png" \ - "$icondir/192x192/apps/$pkgname.png" - install -Dm644 "$brandingdir/content/about-logo@2x.png" \ - "$icondir/384x384/apps/$pkgname.png" - - install -d "$pkgdir/usr/share/applications" - install -m644 "$srcdir/$pkgname.desktop" \ - "$pkgdir/usr/share/applications" - - # Use system-provided dictionaries - rm -rf "$pkgdir/usr/lib/$pkgname/"{dictionaries,hyphenation} - ln -s /usr/share/hunspell "$pkgdir/usr/lib/$pkgname/dictionaries" - ln -s /usr/share/hyphen "$pkgdir/usr/lib/$pkgname/hyphenation" - - rm -rf "$pkgdir/usr/lib/$pkgname/browser/"{searchplugins,plugins} - ln -sf /usr/lib/mozilla/plugins "$pkgdir/usr/lib/$pkgname/browser/plugins" - ln -sf /usr/lib/mozilla/searchplugins "$pkgdir/usr/lib/$pkgname/browser/searchplugins" - - # Workaround for now: - # https://bugzilla.mozilla.org/show_bug.cgi?id=658850 - ln -sf $pkgname "$pkgdir/usr/lib/$pkgname/$pkgname-bin" -} diff --git a/unmaintained/icecat/disable-crypto-hardening-settings.patch b/unmaintained/icecat/disable-crypto-hardening-settings.patch deleted file mode 100644 index 3c7dedd77..000000000 --- a/unmaintained/icecat/disable-crypto-hardening-settings.patch +++ /dev/null @@ -1,54 +0,0 @@ -diff --git a/browser/app/profile/icecat.js b/browser/app/profile/icecat.js -index 3308a22..6b81444 100644 ---- a/browser/app/profile/icecat.js -+++ b/browser/app/profile/icecat.js -@@ -2035,14 +2035,14 @@ pref("network.http.speculative-parallel-limit", 0); - // Crypto hardening - // https://gist.github.com/haasn/69e19fc2fe0e25f3cff5 - //General settings --pref("security.tls.unrestricted_rc4_fallback", false); --pref("security.tls.insecure_fallback_hosts.use_static_list", false); --pref("security.tls.version.min", 1); --pref("security.ssl.require_safe_negotiation", true); --pref("security.ssl.treat_unsafe_negotiation_as_broken", true); --pref("security.ssl3.rsa_seed_sha", true); --pref("security.OCSP.enabled", 1); --pref("security.OCSP.require", true); -+//pref("security.tls.unrestricted_rc4_fallback", false); -+//pref("security.tls.insecure_fallback_hosts.use_static_list", false); -+//pref("security.tls.version.min", 1); -+//pref("security.ssl.require_safe_negotiation", true); -+//pref("security.ssl.treat_unsafe_negotiation_as_broken", true); -+//pref("security.ssl3.rsa_seed_sha", true); -+//pref("security.OCSP.enabled", 1); -+//pref("security.OCSP.require", true); - - // Disable channel updates - pref("app.update.enabled", false); -diff --git a/mobile/android/app/mobile.js b/mobile/android/app/mobile.js -index bfc6cba..cfdeb22 100644 ---- a/mobile/android/app/mobile.js -+++ b/mobile/android/app/mobile.js -@@ -997,14 +997,14 @@ pref("network.http.speculative-parallel-limit", 0); - // Crypto hardening - // https://gist.github.com/haasn/69e19fc2fe0e25f3cff5 - //General settings --pref("security.tls.unrestricted_rc4_fallback", false); --pref("security.tls.insecure_fallback_hosts.use_static_list", false); --pref("security.tls.version.min", 1); --pref("security.ssl.require_safe_negotiation", true); --pref("security.ssl.treat_unsafe_negotiation_as_broken", true); --pref("security.ssl3.rsa_seed_sha", true); --pref("security.OCSP.enabled", 1); --pref("security.OCSP.require", true); -+//pref("security.tls.unrestricted_rc4_fallback", false); -+//pref("security.tls.insecure_fallback_hosts.use_static_list", false); -+//pref("security.tls.version.min", 1); -+//pref("security.ssl.require_safe_negotiation", true); -+//pref("security.ssl.treat_unsafe_negotiation_as_broken", true); -+//pref("security.ssl3.rsa_seed_sha", true); -+//pref("security.OCSP.enabled", 1); -+//pref("security.OCSP.require", true); - - // Disable channel updates - pref("app.update.enabled", false); diff --git a/unmaintained/icecat/disable-spoofSource-referer.patch b/unmaintained/icecat/disable-spoofSource-referer.patch deleted file mode 100644 index d239b02f1..000000000 --- a/unmaintained/icecat/disable-spoofSource-referer.patch +++ /dev/null @@ -1,26 +0,0 @@ -diff --git a/browser/app/profile/icecat.js b/browser/app/profile/icecat.js -index 6b81444..42dd5ed 100644 ---- a/browser/app/profile/icecat.js -+++ b/browser/app/profile/icecat.js -@@ -2011,7 +2011,7 @@ pref("datareporting.policy.dataSubmissionEnabled", false); - pref("datareporting.healthreport.service.enabled", false); - pref("browser.slowStartup.notificationDisabled", true); - pref("network.http.sendRefererHeader", 2); --pref("network.http.referer.spoofSource", true); -+//pref("network.http.referer.spoofSource", true); - //http://grack.com/blog/2010/01/06/3rd-party-cookies-dom-storage-and-privacy/ - //pref("dom.storage.enabled", false); - pref("dom.event.clipboardevents.enabled",false); -diff --git a/mobile/android/app/mobile.js b/mobile/android/app/mobile.js -index cfdeb22..f5845d4 100644 ---- a/mobile/android/app/mobile.js -+++ b/mobile/android/app/mobile.js -@@ -973,7 +973,7 @@ pref("datareporting.policy.dataSubmissionEnabled", false); - pref("datareporting.healthreport.service.enabled", false); - pref("browser.slowStartup.notificationDisabled", true); - pref("network.http.sendRefererHeader", 2); --pref("network.http.referer.spoofSource", true); -+//pref("network.http.referer.spoofSource", true); - //http://grack.com/blog/2010/01/06/3rd-party-cookies-dom-storage-and-privacy/ - //pref("dom.storage.enabled", false); - pref("dom.event.clipboardevents.enabled",false); diff --git a/unmaintained/icecat/firefox-gcc-6.0.patch b/unmaintained/icecat/firefox-gcc-6.0.patch deleted file mode 100644 index 0a74d3616..000000000 --- a/unmaintained/icecat/firefox-gcc-6.0.patch +++ /dev/null @@ -1,26 +0,0 @@ -diff -up firefox-44.0/nsprpub/config/make-system-wrappers.pl.back firefox-44.0/nsprpub/config/make-system-wrappers.pl ---- firefox-44.0/nsprpub/config/make-system-wrappers.pl.back 2016-01-24 00:23:49.000000000 +0100 -+++ firefox-44.0/nsprpub/config/make-system-wrappers.pl 2016-02-02 14:58:45.064112655 +0100 -@@ -19,7 +19,9 @@ while (<STDIN>) { - open OUT, ">$output_dir/$_"; - print OUT "#pragma GCC system_header\n"; # suppress include_next warning - print OUT "#pragma GCC visibility push(default)\n"; -+ print OUT "#define _GLIBCXX_INCLUDE_NEXT_C_HEADERS\n"; - print OUT "#include_next \<$_\>\n"; -+ print OUT "#undef _GLIBCXX_INCLUDE_NEXT_C_HEADERS\n"; - print OUT "#pragma GCC visibility pop\n"; - close OUT; - } -diff -up firefox-44.0/mozglue/build/arm.cpp.old firefox-44.0/mozglue/build/arm.cpp ---- firefox-44.0/mozglue/build/arm.cpp.old 2016-02-03 10:07:29.879526500 +0100 -+++ firefox-44.0/mozglue/build/arm.cpp 2016-02-03 10:08:11.062697517 +0100 -@@ -104,7 +104,9 @@ check_neon(void) - - # elif defined(__linux__) || defined(ANDROID) - # include <stdio.h> -+#define _GLIBCXX_INCLUDE_NEXT_C_HEADERS - # include <stdlib.h> -+#undef _GLIBCXX_INCLUDE_NEXT_C_HEADERS - # include <string.h> - - enum{ diff --git a/unmaintained/icecat/gcc6-fix-compilation-for-IceCat.patch b/unmaintained/icecat/gcc6-fix-compilation-for-IceCat.patch deleted file mode 100644 index 2c291567c..000000000 --- a/unmaintained/icecat/gcc6-fix-compilation-for-IceCat.patch +++ /dev/null @@ -1,37 +0,0 @@ ---- a/config/gcc-stl-wrapper.template.h 2016-05-10 22:26:46.000000000 +0200 -+++ b/config/gcc-stl-wrapper.template.h 2016-05-23 23:48:21.137431360 +0200 -@@ -22,6 +22,11 @@ - #define NOMINMAX 1 - #endif - -+// Don't include mozalloc for cstdlib. See bug 1245076. -+#ifndef moz_dont_include_mozalloc_for_cstdlib -+# define moz_dont_include_mozalloc_for_cstdlib -+#endif -+#ifndef moz_dont_include_mozalloc_for_${HEADER} - // mozalloc.h wants <new>; break the cycle by always explicitly - // including <new> here. NB: this is a tad sneaky. Sez the gcc docs: - // -@@ -30,15 +35,17 @@ - // same name as the current file. It simply looks for the file - // named, starting with the directory in the search path after the - // one where the current file was found. --#include_next <new> -+# include_next <new> - - // See if we're in code that can use mozalloc. NB: this duplicates - // code in nscore.h because nscore.h pulls in prtypes.h, and chromium - // can't build with that being included before base/basictypes.h. --#if !defined(XPCOM_GLUE) && !defined(NS_NO_XPCOM) && !defined(MOZ_NO_MOZALLOC) --# include "mozilla/mozalloc.h" --#else --# error "STL code can only be used with infallible ::operator new()" -+# if !defined(XPCOM_GLUE) && !defined(NS_NO_XPCOM) && !defined(MOZ_NO_MOZALLOC) -+# include "mozilla/mozalloc.h" -+# else -+# error "STL code can only be used with infallible ::operator new()" -+# endif -+ - #endif - - #if defined(DEBUG) && !defined(_GLIBCXX_DEBUG) diff --git a/unmaintained/icecat/gnu_headshadow.png b/unmaintained/icecat/gnu_headshadow.png Binary files differdeleted file mode 100644 index e0f73a3bf..000000000 --- a/unmaintained/icecat/gnu_headshadow.png +++ /dev/null diff --git a/unmaintained/icecat/harfbuzz-1.1.3.patch b/unmaintained/icecat/harfbuzz-1.1.3.patch deleted file mode 100644 index 98e25914d..000000000 --- a/unmaintained/icecat/harfbuzz-1.1.3.patch +++ /dev/null @@ -1,27038 +0,0 @@ -diff -uN gfx/harfbuzz/src_old/check-defs.sh gfx/harfbuzz/src/check-defs.sh ---- gfx/harfbuzz/src_old/check-defs.sh 1970-01-01 01:00:00.000000000 +0100 -+++ gfx/harfbuzz/src/check-defs.sh 2016-06-05 23:47:59.650463392 +0200 -@@ -0,0 +1,44 @@ -+#!/bin/sh -+ -+LC_ALL=C -+export LC_ALL -+ -+test -z "$srcdir" && srcdir=. -+test -z "$MAKE" && MAKE=make -+stat=0 -+ -+if which nm 2>/dev/null >/dev/null; then -+ : -+else -+ echo "check-defs.sh: 'nm' not found; skipping test" -+ exit 77 -+fi -+ -+defs="harfbuzz.def" -+$MAKE $defs > /dev/null -+tested=false -+for def in $defs; do -+ lib=`echo "$def" | sed 's/[.]def$//;s@.*/@@'` -+ so=.libs/lib${lib}.so -+ -+ EXPORTED_SYMBOLS="`nm "$so" | grep ' [BCDGINRSTVW] ' | grep -v ' _fini\>\| _init\>\| _fdata\>\| _ftext\>\| _fbss\>\| __bss_start\>\| __bss_start__\>\| __bss_end__\>\| _edata\>\| _end\>\| _bss_end__\>\| __end__\>\| __gcov_flush\>\| llvm_' | cut -d' ' -f3`" -+ -+ if test -f "$so"; then -+ -+ echo "Checking that $so has the same symbol list as $def" -+ { -+ echo EXPORTS -+ echo "$EXPORTED_SYMBOLS" -+ # cheat: copy the last line from the def file! -+ tail -n1 "$def" -+ } | diff "$def" - >&2 || stat=1 -+ -+ tested=true -+ fi -+done -+if ! $tested; then -+ echo "check-defs.sh: libharfbuzz shared library not found; skipping test" -+ exit 77 -+fi -+ -+exit $stat -diff -uN gfx/harfbuzz/src_old/check-header-guards.sh gfx/harfbuzz/src/check-header-guards.sh ---- gfx/harfbuzz/src_old/check-header-guards.sh 2016-05-10 22:26:55.000000000 +0200 -+++ gfx/harfbuzz/src/check-header-guards.sh 2016-06-05 23:48:00.885456341 +0200 -@@ -9,13 +9,12 @@ - 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'` - -- - for x in $HBHEADERS $HBSOURCES; do - test -f "$srcdir/$x" && x="$srcdir/$x" -- echo "$x" | grep '[^h]$' -q && continue; -+ echo "$x" | grep -q '[^h]$' && continue; - xx=`echo "$x" | sed 's@.*/@@'` - tag=`echo "$xx" | tr 'a-z.-' 'A-Z_'` -- lines=`grep "\<$tag\>" "$x" | wc -l | sed 's/[ ]*//g'` -+ 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 -diff -uN gfx/harfbuzz/src_old/check-libstdc++.sh gfx/harfbuzz/src/check-libstdc++.sh ---- gfx/harfbuzz/src_old/check-libstdc++.sh 2016-05-10 22:26:55.000000000 +0200 -+++ gfx/harfbuzz/src/check-libstdc++.sh 2016-06-05 23:48:03.413441951 +0200 -@@ -19,9 +19,9 @@ - so=.libs/libharfbuzz.$suffix - if ! test -f "$so"; then continue; fi - -- echo "Checking that we are not linking to libstdc++" -- if ldd $so | grep 'libstdc[+][+]'; then -- echo "Ouch, linked to libstdc++" -+ echo "Checking that we are not linking to libstdc++ or libc++" -+ if ldd $so | grep 'libstdc[+][+]\|libc[+][+]'; then -+ echo "Ouch, linked to libstdc++ or libc++" - stat=1 - fi - tested=true -diff -uN gfx/harfbuzz/src_old/gen-indic-table.py gfx/harfbuzz/src/gen-indic-table.py ---- gfx/harfbuzz/src_old/gen-indic-table.py 2016-05-10 22:26:56.000000000 +0200 -+++ gfx/harfbuzz/src/gen-indic-table.py 2016-06-05 23:48:08.239414549 +0200 -@@ -91,6 +91,7 @@ - "Visarga": 'Vs', - "Vowel": 'Vo', - "Vowel_Dependent": 'M', -+ "Consonant_Prefixed": 'CPrf', - "Other": 'x', - },{ - "Not_Applicable": 'x', -@@ -209,7 +210,7 @@ - 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 (u, 0x%04Xu, 0x%04Xu)) return indic_table[u - 0x%04Xu + %s];" % (start, end, start, offset) -+ print " if (hb_in_range (u, 0x%04Xu, 0x%04Xu)) return indic_table[u - 0x%04Xu + %s];" % (start, end-1, start, offset) - 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]]) -diff -uN gfx/harfbuzz/src_old/gen-use-table.py gfx/harfbuzz/src/gen-use-table.py ---- gfx/harfbuzz/src_old/gen-use-table.py 1970-01-01 01:00:00.000000000 +0100 -+++ gfx/harfbuzz/src/gen-use-table.py 2016-06-05 23:48:09.467407592 +0200 -@@ -0,0 +1,476 @@ -+#!/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] -+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_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-OUTDATED Consonant_Placeholder, -+ Tone_Letter] or -+ (UGC == Lo and UISC in [Avagraha, Bindu, Consonant_Final, Consonant_Medial, -+ Consonant_Subjoined, Vowel, Vowel_Dependent])) -+def is_BASE_VOWEL(U, UISC, UGC): -+ return UISC == Vowel_Independent -+def is_BASE_IND(U, UISC, UGC): -+ #SPEC-BROKEN return (UISC in [Consonant_Dead, Modifying_Letter] or UGC == Po) -+ return (UISC in [Consonant_Dead, Modifying_Letter] or -+ (UGC == Po and not is_BASE_OTHER(U, UISC, UGC))) # for 104E -+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-OUTDATED -+ return U in [0x00A0, 0x00D7, 0x2015, 0x2022, 0x25CC, -+ 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-OUTDATED 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-OUTDATED return UISC == Consonant_Subjoined -+ return UISC == Consonant_Subjoined and UGC != Lo -+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 == Consonant_Preceding_Repha -+ #SPEC-OUTDATED hack to categorize Consonant_With_Stacker and Consonant_Prefixed -+ return UISC in [Consonant_Preceding_Repha, Consonant_With_Stacker, Consonant_Prefixed] -+def is_SYM(U, UISC, UGC): -+ if U == 0x25CC: return False #SPEC-OUTDATED -+ #SPEC-OUTDATED 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): -+ return (UISC == Pure_Killer or -+ (UGC != Lo and UISC in [Vowel, Vowel_Dependent])) -+def is_VOWEL_MOD(U, UISC, UGC): -+ return (UISC in [Tone_Mark, Cantillation_Mark, Register_Shifter, Visarga] or -+ (UGC != Lo and UISC == Bindu)) -+ -+use_mapping = { -+ 'B': is_BASE, -+ 'IV': is_BASE_VOWEL, -+ '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, -+ '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], -+ '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: 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 -+ -+ evals = [(k, v(U,UISC,UGC)) for k,v in items] -+ values = [k for k,v in evals if v] -+ 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) -+ -+# Remove the outliers -+singles = {} -+for u in [0x034F, 0x25CC, 0x1107F]: -+ singles[u] = data[u] -+ del data[u] -+ -+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_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 (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 (u, 0x%04Xu, 0x%04Xu)) return use_table[u - 0x%04Xu + %s];" % (start, end-1, start, offset) -+ for u,d in singles.items (): -+ if p != u>>page_bits: continue -+ print " if (unlikely (u == 0x%04Xu)) return %s;" % (u, d[0]) -+ 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 -uN gfx/harfbuzz/src_old/harfbuzz-icu.pc gfx/harfbuzz/src/harfbuzz-icu.pc ---- gfx/harfbuzz/src_old/harfbuzz-icu.pc 1970-01-01 01:00:00.000000000 +0100 -+++ gfx/harfbuzz/src/harfbuzz-icu.pc 2016-06-05 23:48:12.049392976 +0200 -@@ -0,0 +1,13 @@ -+prefix=/usr/local -+exec_prefix=/usr/local -+libdir=/usr/local/lib -+includedir=/usr/local/include -+ -+Name: harfbuzz -+Description: HarfBuzz text shaping library ICU integration -+Version: 1.0.1 -+ -+Requires: harfbuzz -+Requires.private: icu-uc -+Libs: -L${libdir} -lharfbuzz-icu -+Cflags: -I${includedir}/harfbuzz -diff -uN gfx/harfbuzz/src_old/harfbuzz.pc gfx/harfbuzz/src/harfbuzz.pc ---- gfx/harfbuzz/src_old/harfbuzz.pc 1970-01-01 01:00:00.000000000 +0100 -+++ gfx/harfbuzz/src/harfbuzz.pc 2016-06-05 23:48:14.499379160 +0200 -@@ -0,0 +1,11 @@ -+prefix=/usr/local -+exec_prefix=/usr/local -+libdir=/usr/local/lib -+includedir=/usr/local/include -+ -+Name: harfbuzz -+Description: HarfBuzz text shaping library -+Version: 1.0.1 -+ -+Libs: -L${libdir} -lharfbuzz -+Cflags: -I${includedir}/harfbuzz -diff -uN gfx/harfbuzz/src_old/harfbuzz.pc.in gfx/harfbuzz/src/harfbuzz.pc.in ---- gfx/harfbuzz/src_old/harfbuzz.pc.in 2016-05-10 22:26:55.000000000 +0200 -+++ gfx/harfbuzz/src/harfbuzz.pc.in 2016-06-05 23:48:15.731372204 +0200 -@@ -8,4 +8,6 @@ - Version: %VERSION% - - Libs: -L${libdir} -lharfbuzz -+Libs.private: %libs_private% -+Requires.private: %requires_private% - Cflags: -I${includedir}/harfbuzz -diff -uN gfx/harfbuzz/src_old/hb-atomic-private.hh gfx/harfbuzz/src/hb-atomic-private.hh ---- gfx/harfbuzz/src_old/hb-atomic-private.hh 2016-05-10 22:26:56.000000000 +0200 -+++ gfx/harfbuzz/src/hb-atomic-private.hh 2016-06-05 23:48:16.918365513 +0200 -@@ -39,7 +39,11 @@ - - /* We need external help for these */ - --#if 0 -+#if defined(hb_atomic_int_impl_add) \ -+ && defined(hb_atomic_ptr_impl_get) \ -+ && defined(hb_atomic_ptr_impl_cmpexch) -+ -+/* Defined externally, i.e. in config.h; must have typedef'ed hb_atomic_int_impl_t as well. */ - - - #elif !defined(HB_NO_MT) && (defined(_WIN32) || defined(__CYGWIN__)) -@@ -58,11 +62,12 @@ - #endif - } - --typedef LONG hb_atomic_int_t; --#define hb_atomic_int_add(AI, V) InterlockedExchangeAdd (&(AI), (V)) -+typedef LONG hb_atomic_int_impl_t; -+#define HB_ATOMIC_INT_IMPL_INIT(V) (V) -+#define hb_atomic_int_impl_add(AI, V) InterlockedExchangeAdd (&(AI), (V)) - --#define hb_atomic_ptr_get(P) (_HBMemoryBarrier (), (void *) *(P)) --#define hb_atomic_ptr_cmpexch(P,O,N) (InterlockedCompareExchangePointer ((void **) (P), (void *) (N), (void *) (O)) == (void *) (O)) -+#define hb_atomic_ptr_impl_get(P) (_HBMemoryBarrier (), (void *) *(P)) -+#define hb_atomic_ptr_impl_cmpexch(P,O,N) (InterlockedCompareExchangePointer ((void **) (P), (void *) (N), (void *) (O)) == (void *) (O)) - - - #elif !defined(HB_NO_MT) && defined(__APPLE__) -@@ -74,28 +79,31 @@ - #include <Availability.h> - #endif - --typedef int32_t hb_atomic_int_t; --#define hb_atomic_int_add(AI, V) (OSAtomicAdd32Barrier ((V), &(AI)) - (V)) - --#define hb_atomic_ptr_get(P) (OSMemoryBarrier (), (void *) *(P)) -+typedef int32_t hb_atomic_int_impl_t; -+#define HB_ATOMIC_INT_IMPL_INIT(V) (V) -+#define hb_atomic_int_impl_add(AI, V) (OSAtomicAdd32Barrier ((V), &(AI)) - (V)) -+ -+#define hb_atomic_ptr_impl_get(P) (OSMemoryBarrier (), (void *) *(P)) - #if (MAC_OS_X_VERSION_MIN_REQUIRED > MAC_OS_X_VERSION_10_4 || __IPHONE_VERSION_MIN_REQUIRED >= 20100) --#define hb_atomic_ptr_cmpexch(P,O,N) OSAtomicCompareAndSwapPtrBarrier ((void *) (O), (void *) (N), (void **) (P)) -+#define hb_atomic_ptr_impl_cmpexch(P,O,N) OSAtomicCompareAndSwapPtrBarrier ((void *) (O), (void *) (N), (void **) (P)) - #else - #if __ppc64__ || __x86_64__ || __aarch64__ --#define hb_atomic_ptr_cmpexch(P,O,N) OSAtomicCompareAndSwap64Barrier ((int64_t) (O), (int64_t) (N), (int64_t*) (P)) -+#define hb_atomic_ptr_impl_cmpexch(P,O,N) OSAtomicCompareAndSwap64Barrier ((int64_t) (O), (int64_t) (N), (int64_t*) (P)) - #else --#define hb_atomic_ptr_cmpexch(P,O,N) OSAtomicCompareAndSwap32Barrier ((int32_t) (O), (int32_t) (N), (int32_t*) (P)) -+#define hb_atomic_ptr_impl_cmpexch(P,O,N) OSAtomicCompareAndSwap32Barrier ((int32_t) (O), (int32_t) (N), (int32_t*) (P)) - #endif - #endif - - - #elif !defined(HB_NO_MT) && defined(HAVE_INTEL_ATOMIC_PRIMITIVES) - --typedef int hb_atomic_int_t; --#define hb_atomic_int_add(AI, V) __sync_fetch_and_add (&(AI), (V)) -+typedef int hb_atomic_int_impl_t; -+#define HB_ATOMIC_INT_IMPL_INIT(V) (V) -+#define hb_atomic_int_impl_add(AI, V) __sync_fetch_and_add (&(AI), (V)) - --#define hb_atomic_ptr_get(P) (void *) (__sync_synchronize (), *(P)) --#define hb_atomic_ptr_cmpexch(P,O,N) __sync_bool_compare_and_swap ((P), (O), (N)) -+#define hb_atomic_ptr_impl_get(P) (void *) (__sync_synchronize (), *(P)) -+#define hb_atomic_ptr_impl_cmpexch(P,O,N) __sync_bool_compare_and_swap ((P), (O), (N)) - - - #elif !defined(HB_NO_MT) && defined(HAVE_SOLARIS_ATOMIC_OPS) -@@ -103,33 +111,79 @@ - #include <atomic.h> - #include <mbarrier.h> - --typedef unsigned int hb_atomic_int_t; --#define hb_atomic_int_add(AI, V) ( ({__machine_rw_barrier ();}), atomic_add_int_nv (&(AI), (V)) - (V)) -+typedef unsigned int hb_atomic_int_impl_t; -+#define HB_ATOMIC_INT_IMPL_INIT(V) (V) -+#define hb_atomic_int_impl_add(AI, V) ( ({__machine_rw_barrier ();}), atomic_add_int_nv (&(AI), (V)) - (V)) -+ -+#define hb_atomic_ptr_impl_get(P) ( ({__machine_rw_barrier ();}), (void *) *(P)) -+#define hb_atomic_ptr_impl_cmpexch(P,O,N) ( ({__machine_rw_barrier ();}), atomic_cas_ptr ((void **) (P), (void *) (O), (void *) (N)) == (void *) (O) ? true : false) -+ -+ -+#elif !defined(HB_NO_MT) && defined(_AIX) && defined(__IBMCPP__) -+ -+#include <builtins.h> -+ -+ -+static inline int hb_fetch_and_add(volatile int* AI, unsigned int V) { -+ __lwsync(); -+ int result = __fetch_and_add(AI, V); -+ __isync(); -+ return result; -+} -+static inline int hb_compare_and_swaplp(volatile long* P, long O, long N) { -+ __sync(); -+ int result = __compare_and_swaplp (P, &O, N); -+ __sync(); -+ return result; -+} - --#define hb_atomic_ptr_get(P) ( ({__machine_rw_barrier ();}), (void *) *(P)) --#define hb_atomic_ptr_cmpexch(P,O,N) ( ({__machine_rw_barrier ();}), atomic_cas_ptr ((void **) (P), (void *) (O), (void *) (N)) == (void *) (O) ? true : false) -+typedef int hb_atomic_int_impl_t; -+#define HB_ATOMIC_INT_IMPL_INIT(V) (V) -+#define hb_atomic_int_impl_add(AI, V) hb_fetch_and_add (&(AI), (V)) - -+#define hb_atomic_ptr_impl_get(P) (__sync(), (void *) *(P)) -+#define hb_atomic_ptr_impl_cmpexch(P,O,N) hb_compare_and_swaplp ((long*)(P), (long)(O), (long)(N)) - - #elif !defined(HB_NO_MT) - - #define HB_ATOMIC_INT_NIL 1 /* Warn that fallback implementation is in use. */ --typedef volatile int hb_atomic_int_t; --#define hb_atomic_int_add(AI, V) (((AI) += (V)) - (V)) - --#define hb_atomic_ptr_get(P) ((void *) *(P)) --#define hb_atomic_ptr_cmpexch(P,O,N) (* (void * volatile *) (P) == (void *) (O) ? (* (void * volatile *) (P) = (void *) (N), true) : false) -+typedef volatile int hb_atomic_int_impl_t; -+#define HB_ATOMIC_INT_IMPL_INIT(V) (V) -+#define hb_atomic_int_impl_add(AI, V) (((AI) += (V)) - (V)) -+ -+#define hb_atomic_ptr_impl_get(P) ((void *) *(P)) -+#define hb_atomic_ptr_impl_cmpexch(P,O,N) (* (void * volatile *) (P) == (void *) (O) ? (* (void * volatile *) (P) = (void *) (N), true) : false) - - - #else /* HB_NO_MT */ - --typedef int hb_atomic_int_t; --#define hb_atomic_int_add(AI, V) (((AI) += (V)) - (V)) -+typedef int hb_atomic_int_impl_t; -+#define HB_ATOMIC_INT_IMPL_INIT(V) (V) -+#define hb_atomic_int_impl_add(AI, V) (((AI) += (V)) - (V)) -+ -+#define hb_atomic_ptr_impl_get(P) ((void *) *(P)) -+#define hb_atomic_ptr_impl_cmpexch(P,O,N) (* (void **) (P) == (void *) (O) ? (* (void **) (P) = (void *) (N), true) : false) - --#define hb_atomic_ptr_get(P) ((void *) *(P)) --#define hb_atomic_ptr_cmpexch(P,O,N) (* (void **) (P) == (void *) (O) ? (* (void **) (P) = (void *) (N), true) : false) - - #endif - --/* TODO Add tracing. */ -+ -+#define HB_ATOMIC_INT_INIT(V) {HB_ATOMIC_INT_IMPL_INIT(V)} -+ -+struct hb_atomic_int_t -+{ -+ hb_atomic_int_impl_t v; -+ -+ inline void set_unsafe (int v_) { v = v_; } -+ inline int get_unsafe (void) const { return v; } -+ inline int inc (void) { return hb_atomic_int_impl_add (const_cast<hb_atomic_int_impl_t &> (v), 1); } -+ inline int dec (void) { return hb_atomic_int_impl_add (const_cast<hb_atomic_int_impl_t &> (v), -1); } -+}; -+ -+ -+#define hb_atomic_ptr_get(P) hb_atomic_ptr_impl_get(P) -+#define hb_atomic_ptr_cmpexch(P,O,N) hb_atomic_ptr_impl_cmpexch((P),(O),(N)) -+ - - #endif /* HB_ATOMIC_PRIVATE_HH */ -diff -uN gfx/harfbuzz/src_old/hb-blob.cc gfx/harfbuzz/src/hb-blob.cc ---- gfx/harfbuzz/src_old/hb-blob.cc 2016-05-10 22:26:55.000000000 +0200 -+++ gfx/harfbuzz/src/hb-blob.cc 2016-06-05 23:48:18.064359059 +0200 -@@ -78,8 +78,8 @@ - } - - /** -- * hb_blob_create: (Xconstructor) -- * @data: (array length=length) (closure user_data) (destroy destroy) (scope notified) (transfer none): Pointer to blob data. -+ * hb_blob_create: (skip) -+ * @data: Pointer to blob data. - * @length: Length of @data in bytes. - * @mode: Memory mode for @data. - * @user_data: Data parameter to pass to @destroy. -@@ -91,7 +91,7 @@ - * Return value: New blob, or the empty blob if something failed or if @length is - * zero. Destroy with hb_blob_destroy(). - * -- * Since: 1.0 -+ * Since: 0.9.2 - **/ - hb_blob_t * - hb_blob_create (const char *data, -@@ -147,7 +147,7 @@ - * @length is zero or @offset is beyond the end of @parent's data. Destroy - * with hb_blob_destroy(). - * -- * Since: 1.0 -+ * Since: 0.9.2 - **/ - hb_blob_t * - hb_blob_create_sub_blob (hb_blob_t *parent, -@@ -179,7 +179,7 @@ - * - * Return value: (transfer full): the empty blob. - * -- * Since: 1.0 -+ * Since: 0.9.2 - **/ - hb_blob_t * - hb_blob_get_empty (void) -@@ -210,7 +210,7 @@ - * - * Return value: @blob. - * -- * Since: 1.0 -+ * Since: 0.9.2 - **/ - hb_blob_t * - hb_blob_reference (hb_blob_t *blob) -@@ -228,7 +228,7 @@ - * - * See TODO:link object types for more information. - * -- * Since: 1.0 -+ * Since: 0.9.2 - **/ - void - hb_blob_destroy (hb_blob_t *blob) -@@ -250,7 +250,7 @@ - * - * Return value: - * -- * Since: 1.0 -+ * Since: 0.9.2 - **/ - hb_bool_t - hb_blob_set_user_data (hb_blob_t *blob, -@@ -271,7 +271,7 @@ - * - * Return value: (transfer none): - * -- * Since: 1.0 -+ * Since: 0.9.2 - **/ - void * - hb_blob_get_user_data (hb_blob_t *blob, -@@ -287,7 +287,7 @@ - * - * - * -- * Since: 1.0 -+ * Since: 0.9.2 - **/ - void - hb_blob_make_immutable (hb_blob_t *blob) -@@ -306,7 +306,7 @@ - * - * Return value: TODO - * -- * Since: 1.0 -+ * Since: 0.9.2 - **/ - hb_bool_t - hb_blob_is_immutable (hb_blob_t *blob) -@@ -323,7 +323,7 @@ - * - * Return value: the length of blob data in bytes. - * -- * Since: 1.0 -+ * Since: 0.9.2 - **/ - unsigned int - hb_blob_get_length (hb_blob_t *blob) -@@ -340,7 +340,7 @@ - * - * Returns: (transfer none) (array length=length): - * -- * Since: 1.0 -+ * Since: 0.9.2 - **/ - const char * - hb_blob_get_data (hb_blob_t *blob, unsigned int *length) -@@ -365,7 +365,7 @@ - * Returns: (transfer none) (array length=length): Writable blob data, - * or %NULL if failed. - * -- * Since: 1.0 -+ * Since: 0.9.2 - **/ - char * - hb_blob_get_data_writable (hb_blob_t *blob, unsigned int *length) -diff -uN gfx/harfbuzz/src_old/hb-blob.h gfx/harfbuzz/src/hb-blob.h ---- gfx/harfbuzz/src_old/hb-blob.h 2016-05-10 22:26:56.000000000 +0200 -+++ gfx/harfbuzz/src/hb-blob.h 2016-06-05 23:48:19.231352500 +0200 -@@ -64,7 +64,7 @@ - - typedef struct hb_blob_t hb_blob_t; - --hb_blob_t * -+HB_EXTERN hb_blob_t * - hb_blob_create (const char *data, - unsigned int length, - hb_memory_mode_t mode, -@@ -77,21 +77,21 @@ - * modify the parent data as that data may be - * shared among multiple sub-blobs. - */ --hb_blob_t * -+HB_EXTERN hb_blob_t * - hb_blob_create_sub_blob (hb_blob_t *parent, - unsigned int offset, - unsigned int length); - --hb_blob_t * -+HB_EXTERN hb_blob_t * - hb_blob_get_empty (void); - --hb_blob_t * -+HB_EXTERN hb_blob_t * - hb_blob_reference (hb_blob_t *blob); - --void -+HB_EXTERN void - hb_blob_destroy (hb_blob_t *blob); - --hb_bool_t -+HB_EXTERN hb_bool_t - hb_blob_set_user_data (hb_blob_t *blob, - hb_user_data_key_t *key, - void * data, -@@ -99,25 +99,25 @@ - hb_bool_t replace); - - --void * -+HB_EXTERN void * - hb_blob_get_user_data (hb_blob_t *blob, - hb_user_data_key_t *key); - - --void -+HB_EXTERN void - hb_blob_make_immutable (hb_blob_t *blob); - --hb_bool_t -+HB_EXTERN hb_bool_t - hb_blob_is_immutable (hb_blob_t *blob); - - --unsigned int -+HB_EXTERN unsigned int - hb_blob_get_length (hb_blob_t *blob); - --const char * -+HB_EXTERN const char * - hb_blob_get_data (hb_blob_t *blob, unsigned int *length); - --char * -+HB_EXTERN char * - hb_blob_get_data_writable (hb_blob_t *blob, unsigned int *length); - - -diff -uN gfx/harfbuzz/src_old/hb-buffer.cc gfx/harfbuzz/src/hb-buffer.cc ---- gfx/harfbuzz/src_old/hb-buffer.cc 2016-05-10 22:26:55.000000000 +0200 -+++ gfx/harfbuzz/src/hb-buffer.cc 2016-06-05 23:48:28.261301901 +0200 -@@ -35,7 +35,28 @@ - #define HB_DEBUG_BUFFER (HB_DEBUG+0) - #endif - -+/** -+ * SECTION: hb-buffer -+ * @title: Buffers -+ * @short_description: Input and output buffers -+ * @include: hb.h -+ * -+ * Buffers serve dual role in HarfBuzz; they hold the input characters that are -+ * passed hb_shape(), and after shaping they hold the output glyphs. -+ **/ - -+/** -+ * hb_segment_properties_equal: -+ * @a: first #hb_segment_properties_t to compare. -+ * @b: second #hb_segment_properties_t to compare. -+ * -+ * Checks the equality of two #hb_segment_properties_t's. -+ * -+ * Return value: (transfer full): -+ * %true if all properties of @a equal those of @b, false otherwise. -+ * -+ * Since: 0.9.7 -+ **/ - hb_bool_t - hb_segment_properties_equal (const hb_segment_properties_t *a, - const hb_segment_properties_t *b) -@@ -48,6 +69,17 @@ - - } - -+/** -+ * hb_segment_properties_hash: -+ * @p: #hb_segment_properties_t to hash. -+ * -+ * Creates a hash representing @p. -+ * -+ * Return value: -+ * A hash of @p. -+ * -+ * Since: 0.9.7 -+ **/ - unsigned int - hb_segment_properties_hash (const hb_segment_properties_t *p) - { -@@ -85,6 +117,11 @@ - { - if (unlikely (in_error)) - return false; -+ if (unlikely (size > max_len)) -+ { -+ in_error = true; -+ return false; -+ } - - unsigned int new_allocated = allocated; - hb_glyph_position_t *new_pos = NULL; -@@ -192,6 +229,7 @@ - - hb_segment_properties_t default_props = HB_SEGMENT_PROPERTIES_DEFAULT; - props = default_props; -+ scratch_flags = HB_BUFFER_SCRATCH_FLAG_DEFAULT; - - content_type = HB_BUFFER_CONTENT_TYPE_INVALID; - in_error = false; -@@ -443,7 +481,7 @@ - { - unsigned int i, j; - -- if (start == end - 1) -+ if (end - start < 2) - return; - - for (i = start, j = end - 1; i < j; i++, j--) { -@@ -454,7 +492,7 @@ - info[j] = t; - } - -- if (pos) { -+ if (have_positions) { - for (i = start, j = end - 1; i < j; i++, j--) { - hb_glyph_position_t t; - -@@ -498,14 +536,10 @@ - } - - void --hb_buffer_t::merge_clusters (unsigned int start, -- unsigned int end) -+hb_buffer_t::merge_clusters_impl (unsigned int start, -+ unsigned int end) - { --#ifdef HB_NO_MERGE_CLUSTERS -- return; --#endif -- -- if (unlikely (end - start < 2)) -+ if (cluster_level == HB_BUFFER_CLUSTER_LEVEL_CHARACTERS) - return; - - unsigned int cluster = info[start].cluster; -@@ -523,7 +557,7 @@ - - /* If we hit the start of buffer, continue in out-buffer. */ - if (idx == start) -- for (unsigned i = out_len; i && out_info[i - 1].cluster == info[start].cluster; i--) -+ for (unsigned int i = out_len; i && out_info[i - 1].cluster == info[start].cluster; i--) - out_info[i - 1].cluster = cluster; - - for (unsigned int i = start; i < end; i++) -@@ -533,9 +567,8 @@ - hb_buffer_t::merge_out_clusters (unsigned int start, - unsigned int end) - { --#ifdef HB_NO_MERGE_CLUSTERS -- return; --#endif -+ if (cluster_level == HB_BUFFER_CLUSTER_LEVEL_CHARACTERS) -+ return; - - if (unlikely (end - start < 2)) - return; -@@ -555,12 +588,44 @@ - - /* If we hit the end of out-buffer, continue in buffer. */ - if (end == out_len) -- for (unsigned i = idx; i < len && info[i].cluster == out_info[end - 1].cluster; i++) -+ for (unsigned int i = idx; i < len && info[i].cluster == out_info[end - 1].cluster; i++) - info[i].cluster = cluster; - - for (unsigned int i = start; i < end; i++) - out_info[i].cluster = cluster; - } -+void -+hb_buffer_t::delete_glyph () -+{ -+ unsigned int cluster = info[idx].cluster; -+ if (idx + 1 < len && cluster == info[idx + 1].cluster) -+ { -+ /* Cluster survives; do nothing. */ -+ goto done; -+ } -+ -+ if (out_len) -+ { -+ /* Merge cluster backward. */ -+ if (cluster < out_info[out_len - 1].cluster) -+ { -+ unsigned int old_cluster = out_info[out_len - 1].cluster; -+ for (unsigned i = out_len; i && out_info[i - 1].cluster == old_cluster; i--) -+ out_info[i - 1].cluster = cluster; -+ } -+ goto done; -+ } -+ -+ if (idx + 1 < len) -+ { -+ /* Merge cluster forward. */ -+ merge_clusters (idx, idx + 2); -+ goto done; -+ } -+ -+done: -+ skip_glyph (); -+} - - void - hb_buffer_t::guess_segment_properties (void) -@@ -667,11 +732,16 @@ - /** - * hb_buffer_create: (Xconstructor) - * -- * -+ * Creates a new #hb_buffer_t with all properties to defaults. - * -- * Return value: (transfer full) -+ * Return value: (transfer full): -+ * A newly allocated #hb_buffer_t with a reference count of 1. The initial -+ * reference count should be released with hb_buffer_destroy() when you are done -+ * using the #hb_buffer_t. This function never returns %NULL. If memory cannot -+ * be allocated, a special #hb_buffer_t object will be returned on which -+ * hb_buffer_allocation_successful() returns %false. - * -- * Since: 1.0 -+ * Since: 0.9.2 - **/ - hb_buffer_t * - hb_buffer_create (void) -@@ -681,6 +751,8 @@ - if (!(buffer = hb_object_create<hb_buffer_t> ())) - return hb_buffer_get_empty (); - -+ buffer->max_len = HB_BUFFER_MAX_LEN_DEFAULT; -+ - buffer->reset (); - - return buffer; -@@ -693,7 +765,7 @@ - * - * Return value: (transfer full): - * -- * Since: 1.0 -+ * Since: 0.9.2 - **/ - hb_buffer_t * - hb_buffer_get_empty (void) -@@ -703,7 +775,10 @@ - - const_cast<hb_unicode_funcs_t *> (&_hb_unicode_funcs_nil), - HB_BUFFER_FLAG_DEFAULT, -+ HB_BUFFER_CLUSTER_LEVEL_DEFAULT, - HB_BUFFER_REPLACEMENT_CODEPOINT_DEFAULT, -+ HB_BUFFER_SCRATCH_FLAG_DEFAULT, -+ HB_BUFFER_MAX_LEN_DEFAULT, - - HB_BUFFER_CONTENT_TYPE_INVALID, - HB_SEGMENT_PROPERTIES_DEFAULT, -@@ -719,13 +794,15 @@ - - /** - * hb_buffer_reference: (skip) -- * @buffer: a buffer. -+ * @buffer: an #hb_buffer_t. - * -- * -+ * Increases the reference count on @buffer by one. This prevents @buffer from -+ * being destroyed until a matching call to hb_buffer_destroy() is made. - * - * Return value: (transfer full): -+ * The referenced #hb_buffer_t. - * -- * Since: 1.0 -+ * Since: 0.9.2 - **/ - hb_buffer_t * - hb_buffer_reference (hb_buffer_t *buffer) -@@ -735,11 +812,13 @@ - - /** - * hb_buffer_destroy: (skip) -- * @buffer: a buffer. -+ * @buffer: an #hb_buffer_t. - * -- * -+ * Deallocate the @buffer. -+ * Decreases the reference count on @buffer by one. If the result is zero, then -+ * @buffer and all associated resources are freed. See hb_buffer_reference(). - * -- * Since: 1.0 -+ * Since: 0.9.2 - **/ - void - hb_buffer_destroy (hb_buffer_t *buffer) -@@ -750,13 +829,15 @@ - - free (buffer->info); - free (buffer->pos); -+ if (buffer->message_destroy) -+ buffer->message_destroy (buffer->message_data); - - free (buffer); - } - - /** - * hb_buffer_set_user_data: (skip) -- * @buffer: a buffer. -+ * @buffer: an #hb_buffer_t. - * @key: - * @data: - * @destroy: -@@ -766,7 +847,7 @@ - * - * Return value: - * -- * Since: 1.0 -+ * Since: 0.9.2 - **/ - hb_bool_t - hb_buffer_set_user_data (hb_buffer_t *buffer, -@@ -780,14 +861,14 @@ - - /** - * hb_buffer_get_user_data: (skip) -- * @buffer: a buffer. -+ * @buffer: an #hb_buffer_t. - * @key: - * - * - * - * Return value: - * -- * Since: 1.0 -+ * Since: 0.9.2 - **/ - void * - hb_buffer_get_user_data (hb_buffer_t *buffer, -@@ -799,12 +880,13 @@ - - /** - * hb_buffer_set_content_type: -- * @buffer: a buffer. -- * @content_type: -+ * @buffer: an #hb_buffer_t. -+ * @content_type: the type of buffer contents to set - * -- * -+ * Sets the type of @buffer contents, buffers are either empty, contain -+ * characters (before shaping) or glyphs (the result of shaping). - * -- * Since: 1.0 -+ * Since: 0.9.5 - **/ - void - hb_buffer_set_content_type (hb_buffer_t *buffer, -@@ -815,13 +897,14 @@ - - /** - * hb_buffer_get_content_type: -- * @buffer: a buffer. -+ * @buffer: an #hb_buffer_t. - * -- * -+ * see hb_buffer_set_content_type(). - * -- * Return value: -+ * Return value: -+ * The type of @buffer contents. - * -- * Since: 1.0 -+ * Since: 0.9.5 - **/ - hb_buffer_content_type_t - hb_buffer_get_content_type (hb_buffer_t *buffer) -@@ -832,12 +915,12 @@ - - /** - * hb_buffer_set_unicode_funcs: -- * @buffer: a buffer. -+ * @buffer: an #hb_buffer_t. - * @unicode_funcs: - * - * - * -- * Since: 1.0 -+ * Since: 0.9.2 - **/ - void - hb_buffer_set_unicode_funcs (hb_buffer_t *buffer, -@@ -857,13 +940,13 @@ - - /** - * hb_buffer_get_unicode_funcs: -- * @buffer: a buffer. -+ * @buffer: an #hb_buffer_t. - * - * - * - * Return value: - * -- * Since: 1.0 -+ * Since: 0.9.2 - **/ - hb_unicode_funcs_t * - hb_buffer_get_unicode_funcs (hb_buffer_t *buffer) -@@ -873,12 +956,18 @@ - - /** - * hb_buffer_set_direction: -- * @buffer: a buffer. -- * @direction: -+ * @buffer: an #hb_buffer_t. -+ * @direction: the #hb_direction_t of the @buffer - * -- * -+ * Set the text flow direction of the buffer. No shaping can happen without -+ * setting @buffer direction, and it controls the visual direction for the -+ * output glyphs; for RTL direction the glyphs will be reversed. Many layout -+ * features depend on the proper setting of the direction, for example, -+ * reversing RTL text before shaping, then shaping with LTR direction is not -+ * the same as keeping the text in logical order and shaping with RTL -+ * direction. - * -- * Since: 1.0 -+ * Since: 0.9.2 - **/ - void - hb_buffer_set_direction (hb_buffer_t *buffer, -@@ -893,13 +982,14 @@ - - /** - * hb_buffer_get_direction: -- * @buffer: a buffer. -+ * @buffer: an #hb_buffer_t. - * -- * -+ * See hb_buffer_set_direction() - * -- * Return value: -+ * Return value: -+ * The direction of the @buffer. - * -- * Since: 1.0 -+ * Since: 0.9.2 - **/ - hb_direction_t - hb_buffer_get_direction (hb_buffer_t *buffer) -@@ -909,12 +999,20 @@ - - /** - * hb_buffer_set_script: -- * @buffer: a buffer. -- * @script: -+ * @buffer: an #hb_buffer_t. -+ * @script: an #hb_script_t to set. - * -- * -+ * Sets the script of @buffer to @script. - * -- * Since: 1.0 -+ * Script is crucial for choosing the proper shaping behaviour for scripts that -+ * require it (e.g. Arabic) and the which OpenType features defined in the font -+ * to be applied. -+ * -+ * You can pass one of the predefined #hb_script_t values, or use -+ * hb_script_from_string() or hb_script_from_iso15924_tag() to get the -+ * corresponding script from an ISO 15924 script tag. -+ * -+ * Since: 0.9.2 - **/ - void - hb_buffer_set_script (hb_buffer_t *buffer, -@@ -928,13 +1026,14 @@ - - /** - * hb_buffer_get_script: -- * @buffer: a buffer. -+ * @buffer: an #hb_buffer_t. - * -- * -+ * See hb_buffer_set_script(). - * -- * Return value: -+ * Return value: -+ * The #hb_script_t of the @buffer. - * -- * Since: 1.0 -+ * Since: 0.9.2 - **/ - hb_script_t - hb_buffer_get_script (hb_buffer_t *buffer) -@@ -944,12 +1043,20 @@ - - /** - * hb_buffer_set_language: -- * @buffer: a buffer. -- * @language: -+ * @buffer: an #hb_buffer_t. -+ * @language: an hb_language_t to set. - * -- * -+ * Sets the language of @buffer to @language. -+ * -+ * Languages are crucial for selecting which OpenType feature to apply to the -+ * buffer which can result in applying language-specific behaviour. Languages -+ * are orthogonal to the scripts, and though they are related, they are -+ * different concepts and should not be confused with each other. -+ * -+ * Use hb_language_from_string() to convert from ISO 639 language codes to -+ * #hb_language_t. - * -- * Since: 1.0 -+ * Since: 0.9.2 - **/ - void - hb_buffer_set_language (hb_buffer_t *buffer, -@@ -963,13 +1070,14 @@ - - /** - * hb_buffer_get_language: -- * @buffer: a buffer. -+ * @buffer: an #hb_buffer_t. - * -- * -+ * See hb_buffer_set_language(). - * -- * Return value: -+ * Return value: (transfer none): -+ * The #hb_language_t of the buffer. Must not be freed by the caller. - * -- * Since: 1.0 -+ * Since: 0.9.2 - **/ - hb_language_t - hb_buffer_get_language (hb_buffer_t *buffer) -@@ -979,12 +1087,14 @@ - - /** - * hb_buffer_set_segment_properties: -- * @buffer: a buffer. -- * @props: -+ * @buffer: an #hb_buffer_t. -+ * @props: an #hb_segment_properties_t to use. - * -- * -+ * Sets the segment properties of the buffer, a shortcut for calling -+ * hb_buffer_set_direction(), hb_buffer_set_script() and -+ * hb_buffer_set_language() individually. - * -- * Since: 1.0 -+ * Since: 0.9.7 - **/ - void - hb_buffer_set_segment_properties (hb_buffer_t *buffer, -@@ -998,12 +1108,12 @@ - - /** - * hb_buffer_get_segment_properties: -- * @buffer: a buffer. -- * @props: -+ * @buffer: an #hb_buffer_t. -+ * @props: (out): the output #hb_segment_properties_t. - * -- * -+ * Sets @props to the #hb_segment_properties_t of @buffer. - * -- * Since: 1.0 -+ * Since: 0.9.7 - **/ - void - hb_buffer_get_segment_properties (hb_buffer_t *buffer, -@@ -1015,12 +1125,12 @@ - - /** - * hb_buffer_set_flags: -- * @buffer: a buffer. -- * @flags: -+ * @buffer: an #hb_buffer_t. -+ * @flags: the buffer flags to set. - * -- * -+ * Sets @buffer flags to @flags. See #hb_buffer_flags_t. - * -- * Since: 1.0 -+ * Since: 0.9.7 - **/ - void - hb_buffer_set_flags (hb_buffer_t *buffer, -@@ -1034,13 +1144,14 @@ - - /** - * hb_buffer_get_flags: -- * @buffer: a buffer. -+ * @buffer: an #hb_buffer_t. - * -- * -+ * See hb_buffer_set_flags(). - * - * Return value: -+ * The @buffer flags. - * -- * Since: 1.0 -+ * Since: 0.9.7 - **/ - hb_buffer_flags_t - hb_buffer_get_flags (hb_buffer_t *buffer) -@@ -1048,15 +1159,53 @@ - return buffer->flags; - } - -+/** -+ * hb_buffer_set_cluster_level: -+ * @buffer: an #hb_buffer_t. -+ * @cluster_level: -+ * -+ * -+ * -+ * Since: 0.9.42 -+ **/ -+void -+hb_buffer_set_cluster_level (hb_buffer_t *buffer, -+ hb_buffer_cluster_level_t cluster_level) -+{ -+ if (unlikely (hb_object_is_inert (buffer))) -+ return; -+ -+ buffer->cluster_level = cluster_level; -+} -+ -+/** -+ * hb_buffer_get_cluster_level: -+ * @buffer: an #hb_buffer_t. -+ * -+ * -+ * -+ * Return value: -+ * -+ * Since: 0.9.42 -+ **/ -+hb_buffer_cluster_level_t -+hb_buffer_get_cluster_level (hb_buffer_t *buffer) -+{ -+ return buffer->cluster_level; -+} -+ - - /** - * hb_buffer_set_replacement_codepoint: -- * @buffer: a buffer. -- * @replacement: -+ * @buffer: an #hb_buffer_t. -+ * @replacement: the replacement #hb_codepoint_t - * -- * -+ * Sets the #hb_codepoint_t that replaces invalid entries for a given encoding -+ * when adding text to @buffer. - * -- * Since: 1.0 -+ * Default is %HB_BUFFER_REPLACEMENT_CODEPOINT_DEFAULT. -+ * -+ * Since: 0.9.31 - **/ - void - hb_buffer_set_replacement_codepoint (hb_buffer_t *buffer, -@@ -1070,13 +1219,14 @@ - - /** - * hb_buffer_get_replacement_codepoint: -- * @buffer: a buffer. -+ * @buffer: an #hb_buffer_t. - * -- * -+ * See hb_buffer_set_replacement_codepoint(). - * - * Return value: -+ * The @buffer replacement #hb_codepoint_t. - * -- * Since: 1.0 -+ * Since: 0.9.31 - **/ - hb_codepoint_t - hb_buffer_get_replacement_codepoint (hb_buffer_t *buffer) -@@ -1087,11 +1237,12 @@ - - /** - * hb_buffer_reset: -- * @buffer: a buffer. -+ * @buffer: an #hb_buffer_t. - * -- * -+ * Resets the buffer to its initial status, as if it was just newly created -+ * with hb_buffer_create(). - * -- * Since: 1.0 -+ * Since: 0.9.2 - **/ - void - hb_buffer_reset (hb_buffer_t *buffer) -@@ -1101,11 +1252,12 @@ - - /** - * hb_buffer_clear_contents: -- * @buffer: a buffer. -+ * @buffer: an #hb_buffer_t. - * -- * -+ * Similar to hb_buffer_reset(), but does not clear the Unicode functions and -+ * the replacement code point. - * -- * Since: 1.0 -+ * Since: 0.9.11 - **/ - void - hb_buffer_clear_contents (hb_buffer_t *buffer) -@@ -1115,14 +1267,15 @@ - - /** - * hb_buffer_pre_allocate: -- * @buffer: a buffer. -- * @size: -+ * @buffer: an #hb_buffer_t. -+ * @size: number of items to pre allocate. - * -- * -+ * Pre allocates memory for @buffer to fit at least @size number of items. - * -- * Return value: -+ * Return value: -+ * %true if @buffer memory allocation succeeded, %false otherwise. - * -- * Since: 1.0 -+ * Since: 0.9.2 - **/ - hb_bool_t - hb_buffer_pre_allocate (hb_buffer_t *buffer, unsigned int size) -@@ -1132,13 +1285,14 @@ - - /** - * hb_buffer_allocation_successful: -- * @buffer: a buffer. -+ * @buffer: an #hb_buffer_t. - * -- * -+ * Check if allocating memory for the buffer succeeded. - * -- * Return value: -+ * Return value: -+ * %true if @buffer memory allocation succeeded, %false otherwise. - * -- * Since: 1.0 -+ * Since: 0.9.2 - **/ - hb_bool_t - hb_buffer_allocation_successful (hb_buffer_t *buffer) -@@ -1148,13 +1302,20 @@ - - /** - * hb_buffer_add: -- * @buffer: a buffer. -- * @codepoint: -- * @cluster: -+ * @buffer: an #hb_buffer_t. -+ * @codepoint: a Unicode code point. -+ * @cluster: the cluster value of @codepoint. -+ * -+ * Appends a character with the Unicode value of @codepoint to @buffer, and -+ * gives it the initial cluster value of @cluster. Clusters can be any thing -+ * the client wants, they are usually used to refer to the index of the -+ * character in the input text stream and are output in -+ * #hb_glyph_info_t.cluster field. - * -- * -+ * This function does not check the validity of @codepoint, it is up to the -+ * caller to ensure it is a valid Unicode code point. - * -- * Since: 1.0 -+ * Since: 0.9.7 - **/ - void - hb_buffer_add (hb_buffer_t *buffer, -@@ -1167,14 +1328,16 @@ - - /** - * hb_buffer_set_length: -- * @buffer: a buffer. -- * @length: -+ * @buffer: an #hb_buffer_t. -+ * @length: the new length of @buffer. - * -- * -+ * Similar to hb_buffer_pre_allocate(), but clears any new items added at the -+ * end. - * - * Return value: -+ * %true if @buffer memory allocation succeeded, %false otherwise. - * -- * Since: 1.0 -+ * Since: 0.9.2 - **/ - hb_bool_t - hb_buffer_set_length (hb_buffer_t *buffer, -@@ -1207,13 +1370,15 @@ - - /** - * hb_buffer_get_length: -- * @buffer: a buffer. -+ * @buffer: an #hb_buffer_t. - * - * Returns the number of items in the buffer. - * -- * Return value: buffer length. -+ * Return value: -+ * The @buffer length. -+ * The value valid as long as buffer has not been modified. - * -- * Since: 1.0 -+ * Since: 0.9.2 - **/ - unsigned int - hb_buffer_get_length (hb_buffer_t *buffer) -@@ -1223,15 +1388,17 @@ - - /** - * hb_buffer_get_glyph_infos: -- * @buffer: a buffer. -+ * @buffer: an #hb_buffer_t. - * @length: (out): output array length. - * -- * Returns buffer glyph information array. Returned pointer -- * is valid as long as buffer contents are not modified. -+ * Returns @buffer glyph information array. Returned pointer -+ * is valid as long as @buffer contents are not modified. - * -- * Return value: (transfer none) (array length=length): buffer glyph information array. -+ * Return value: (transfer none) (array length=length): -+ * The @buffer glyph information array. -+ * The value valid as long as buffer has not been modified. - * -- * Since: 1.0 -+ * Since: 0.9.2 - **/ - hb_glyph_info_t * - hb_buffer_get_glyph_infos (hb_buffer_t *buffer, -@@ -1245,15 +1412,17 @@ - - /** - * hb_buffer_get_glyph_positions: -- * @buffer: a buffer. -+ * @buffer: an #hb_buffer_t. - * @length: (out): output length. - * -- * Returns buffer glyph position array. Returned pointer -- * is valid as long as buffer contents are not modified. -+ * Returns @buffer glyph position array. Returned pointer -+ * is valid as long as @buffer contents are not modified. - * -- * Return value: (transfer none) (array length=length): buffer glyph position array. -+ * Return value: (transfer none) (array length=length): -+ * The @buffer glyph position array. -+ * The value valid as long as buffer has not been modified. - * -- * Since: 1.0 -+ * Since: 0.9.2 - **/ - hb_glyph_position_t * - hb_buffer_get_glyph_positions (hb_buffer_t *buffer, -@@ -1270,11 +1439,11 @@ - - /** - * hb_buffer_reverse: -- * @buffer: a buffer. -+ * @buffer: an #hb_buffer_t. - * - * Reverses buffer contents. - * -- * Since: 1.0 -+ * Since: 0.9.2 - **/ - void - hb_buffer_reverse (hb_buffer_t *buffer) -@@ -1283,14 +1452,31 @@ - } - - /** -+ * hb_buffer_reverse_range: -+ * @buffer: an #hb_buffer_t. -+ * @start: start index. -+ * @end: end index. -+ * -+ * Reverses buffer contents between start to end. -+ * -+ * Since: 0.9.41 -+ **/ -+void -+hb_buffer_reverse_range (hb_buffer_t *buffer, -+ unsigned int start, unsigned int end) -+{ -+ buffer->reverse_range (start, end); -+} -+ -+/** - * hb_buffer_reverse_clusters: -- * @buffer: a buffer. -+ * @buffer: an #hb_buffer_t. - * - * Reverses buffer clusters. That is, the buffer contents are - * reversed, then each cluster (consecutive items having the - * same cluster number) are reversed again. - * -- * Since: 1.0 -+ * Since: 0.9.2 - **/ - void - hb_buffer_reverse_clusters (hb_buffer_t *buffer) -@@ -1300,7 +1486,7 @@ - - /** - * hb_buffer_guess_segment_properties: -- * @buffer: a buffer. -+ * @buffer: an #hb_buffer_t. - * - * Sets unset buffer segment properties based on buffer Unicode - * contents. If buffer is not empty, it must have content type -@@ -1320,7 +1506,7 @@ - * hb_language_get_default(). This may change in the future by - * taking buffer script into consideration when choosing a language. - * -- * Since: 1.0 -+ * Since: 0.9.7 - **/ - void - hb_buffer_guess_segment_properties (hb_buffer_t *buffer) -@@ -1328,15 +1514,15 @@ - buffer->guess_segment_properties (); - } - --template <bool validate, typename T> -+template <typename utf_t> - static inline void - hb_buffer_add_utf (hb_buffer_t *buffer, -- const T *text, -+ const typename utf_t::codepoint_t *text, - int text_length, - unsigned int item_offset, - int item_length) - { -- typedef hb_utf_t<T, true> utf_t; -+ typedef typename utf_t::codepoint_t T; - const hb_codepoint_t replacement = buffer->replacement; - - assert (buffer->content_type == HB_BUFFER_CONTENT_TYPE_UNICODE || -@@ -1399,15 +1585,20 @@ - - /** - * hb_buffer_add_utf8: -- * @buffer: a buffer. -- * @text: (array length=text_length): -- * @text_length: -- * @item_offset: -- * @item_length: -+ * @buffer: an #hb_buffer_t. -+ * @text: (array length=text_length) (element-type uint8_t): an array of UTF-8 -+ * characters to append. -+ * @text_length: the length of the @text, or -1 if it is %NULL terminated. -+ * @item_offset: the offset of the first character to add to the @buffer. -+ * @item_length: the number of characters to add to the @buffer, or -1 for the -+ * end of @text (assuming it is %NULL terminated). - * -- * -+ * See hb_buffer_add_codepoints(). - * -- * Since: 1.0 -+ * Replaces invalid UTF-8 characters with the @buffer replacement code point, -+ * see hb_buffer_set_replacement_codepoint(). -+ * -+ * Since: 0.9.2 - **/ - void - hb_buffer_add_utf8 (hb_buffer_t *buffer, -@@ -1416,20 +1607,24 @@ - unsigned int item_offset, - int item_length) - { -- hb_buffer_add_utf<true> (buffer, (const uint8_t *) text, text_length, item_offset, item_length); -+ hb_buffer_add_utf<hb_utf8_t> (buffer, (const uint8_t *) text, text_length, item_offset, item_length); - } - - /** - * hb_buffer_add_utf16: -- * @buffer: a buffer. -- * @text: (array length=text_length): -- * @text_length: -- * @item_offset: -- * @item_length: -+ * @buffer: an #hb_buffer_t. -+ * @text: (array length=text_length): an array of UTF-16 characters to append. -+ * @text_length: the length of the @text, or -1 if it is %NULL terminated. -+ * @item_offset: the offset of the first character to add to the @buffer. -+ * @item_length: the number of characters to add to the @buffer, or -1 for the -+ * end of @text (assuming it is %NULL terminated). - * -- * -+ * See hb_buffer_add_codepoints(). - * -- * Since: 1.0 -+ * Replaces invalid UTF-16 characters with the @buffer replacement code point, -+ * see hb_buffer_set_replacement_codepoint(). -+ * -+ * Since: 0.9.2 - **/ - void - hb_buffer_add_utf16 (hb_buffer_t *buffer, -@@ -1438,20 +1633,24 @@ - unsigned int item_offset, - int item_length) - { -- hb_buffer_add_utf<true> (buffer, text, text_length, item_offset, item_length); -+ hb_buffer_add_utf<hb_utf16_t> (buffer, text, text_length, item_offset, item_length); - } - - /** - * hb_buffer_add_utf32: -- * @buffer: a buffer. -- * @text: (array length=text_length): -- * @text_length: -- * @item_offset: -- * @item_length: -+ * @buffer: an #hb_buffer_t. -+ * @text: (array length=text_length): an array of UTF-32 characters to append. -+ * @text_length: the length of the @text, or -1 if it is %NULL terminated. -+ * @item_offset: the offset of the first character to add to the @buffer. -+ * @item_length: the number of characters to add to the @buffer, or -1 for the -+ * end of @text (assuming it is %NULL terminated). - * -- * -+ * See hb_buffer_add_codepoints(). - * -- * Since: 1.0 -+ * Replaces invalid UTF-32 characters with the @buffer replacement code point, -+ * see hb_buffer_set_replacement_codepoint(). -+ * -+ * Since: 0.9.2 - **/ - void - hb_buffer_add_utf32 (hb_buffer_t *buffer, -@@ -1460,20 +1659,59 @@ - unsigned int item_offset, - int item_length) - { -- hb_buffer_add_utf<true> (buffer, text, text_length, item_offset, item_length); -+ hb_buffer_add_utf<hb_utf32_t<> > (buffer, text, text_length, item_offset, item_length); -+} -+ -+/** -+ * hb_buffer_add_latin1: -+ * @buffer: an #hb_buffer_t. -+ * @text: (array length=text_length) (element-type uint8_t): an array of UTF-8 -+ * characters to append. -+ * @text_length: the length of the @text, or -1 if it is %NULL terminated. -+ * @item_offset: the offset of the first character to add to the @buffer. -+ * @item_length: the number of characters to add to the @buffer, or -1 for the -+ * end of @text (assuming it is %NULL terminated). -+ * -+ * Similar to hb_buffer_add_codepoints(), but allows only access to first 256 -+ * Unicode code points that can fit in 8-bit strings. -+ * -+ * <note>Has nothing to do with non-Unicode Latin-1 encoding.</note> -+ * -+ * Since: 0.9.39 -+ **/ -+void -+hb_buffer_add_latin1 (hb_buffer_t *buffer, -+ const uint8_t *text, -+ int text_length, -+ unsigned int item_offset, -+ int item_length) -+{ -+ hb_buffer_add_utf<hb_latin1_t> (buffer, text, text_length, item_offset, item_length); - } - - /** - * hb_buffer_add_codepoints: -- * @buffer: a buffer. -- * @text: (array length=text_length): -- * @text_length: -- * @item_offset: -- * @item_length: -+ * @buffer: a #hb_buffer_t to append characters to. -+ * @text: (array length=text_length): an array of Unicode code points to append. -+ * @text_length: the length of the @text, or -1 if it is %NULL terminated. -+ * @item_offset: the offset of the first code point to add to the @buffer. -+ * @item_length: the number of code points to add to the @buffer, or -1 for the -+ * end of @text (assuming it is %NULL terminated). -+ * -+ * Appends characters from @text array to @buffer. The @item_offset is the -+ * position of the first character from @text that will be appended, and -+ * @item_length is the number of character. When shaping part of a larger text -+ * (e.g. a run of text from a paragraph), instead of passing just the substring -+ * corresponding to the run, it is preferable to pass the whole -+ * paragraph and specify the run start and length as @item_offset and -+ * @item_length, respectively, to give HarfBuzz the full context to be able, -+ * for example, to do cross-run Arabic shaping or properly handle combining -+ * marks at stat of run. - * -- * -+ * This function does not check the validity of @text, it is up to the caller -+ * to ensure it contains a valid Unicode code points. - * -- * Since: 1.0 -+ * Since: 0.9.31 - **/ - void - hb_buffer_add_codepoints (hb_buffer_t *buffer, -@@ -1482,7 +1720,7 @@ - unsigned int item_offset, - int item_length) - { -- hb_buffer_add_utf<false> (buffer, text, text_length, item_offset, item_length); -+ hb_buffer_add_utf<hb_utf32_t<false> > (buffer, text, text_length, item_offset, item_length); - } - - -@@ -1528,7 +1766,7 @@ - pos[end - 1].x_advance = total_x_advance; - pos[end - 1].y_advance = total_y_advance; - -- hb_bubble_sort (buffer->info + start, end - start - 1, compare_info_codepoint, buffer->pos + start); -+ hb_stable_sort (buffer->info + start, end - start - 1, compare_info_codepoint, buffer->pos + start); - } else { - /* Transfer all cluster advance to the first glyph. */ - pos[start].x_advance += total_x_advance; -@@ -1537,17 +1775,20 @@ - pos[i].x_offset -= total_x_advance; - pos[i].y_offset -= total_y_advance; - } -- hb_bubble_sort (buffer->info + start + 1, end - start - 1, compare_info_codepoint, buffer->pos + start + 1); -+ hb_stable_sort (buffer->info + start + 1, end - start - 1, compare_info_codepoint, buffer->pos + start + 1); - } - } - - /** - * hb_buffer_normalize_glyphs: -- * @buffer: a buffer. -+ * @buffer: an #hb_buffer_t. - * -- * -+ * Reorders a glyph buffer to have canonical in-cluster glyph order / position. -+ * The resulting clusters should behave identical to pre-reordering clusters. - * -- * Since: 1.0 -+ * <note>This has nothing to do with Unicode normalization.</note> -+ * -+ * Since: 0.9.2 - **/ - void - hb_buffer_normalize_glyphs (hb_buffer_t *buffer) -@@ -1570,3 +1811,66 @@ - } - normalize_glyphs_cluster (buffer, start, end, backward); - } -+ -+void -+hb_buffer_t::sort (unsigned int start, unsigned int end, int(*compar)(const hb_glyph_info_t *, const hb_glyph_info_t *)) -+{ -+ assert (!have_positions); -+ for (unsigned int i = start + 1; i < end; i++) -+ { -+ unsigned int j = i; -+ while (j > start && compar (&info[j - 1], &info[i]) > 0) -+ j--; -+ if (i == j) -+ continue; -+ /* Move item i to occupy place for item j, shift what's in between. */ -+ merge_clusters (j, i + 1); -+ { -+ hb_glyph_info_t t = info[i]; -+ memmove (&info[j + 1], &info[j], (i - j) * sizeof (hb_glyph_info_t)); -+ info[j] = t; -+ } -+ } -+} -+ -+/* -+ * Debugging. -+ */ -+ -+/** -+ * hb_buffer_set_message_func: -+ * @buffer: an #hb_buffer_t. -+ * @func: (closure user_data) (destroy destroy) (scope notified): -+ * @user_data: -+ * @destroy: -+ * -+ * -+ * -+ * Since: 1.1.3 -+ **/ -+void -+hb_buffer_set_message_func (hb_buffer_t *buffer, -+ hb_buffer_message_func_t func, -+ void *user_data, hb_destroy_func_t destroy) -+{ -+ if (buffer->message_destroy) -+ buffer->message_destroy (buffer->message_data); -+ -+ if (func) { -+ buffer->message_func = func; -+ buffer->message_data = user_data; -+ buffer->message_destroy = destroy; -+ } else { -+ buffer->message_func = NULL; -+ buffer->message_data = NULL; -+ buffer->message_destroy = NULL; -+ } -+} -+ -+bool -+hb_buffer_t::message_impl (hb_font_t *font, const char *fmt, va_list ap) -+{ -+ char buf[100]; -+ vsnprintf (buf, sizeof (buf), fmt, ap); -+ return (bool) this->message_func (this, font, buf, this->message_data); -+} -diff -uN gfx/harfbuzz/src_old/hb-buffer-deserialize-json.hh gfx/harfbuzz/src/hb-buffer-deserialize-json.hh ---- gfx/harfbuzz/src_old/hb-buffer-deserialize-json.hh 2016-05-10 22:26:56.000000000 +0200 -+++ gfx/harfbuzz/src/hb-buffer-deserialize-json.hh 2016-06-05 23:48:20.553345078 +0200 -@@ -1,5 +1,5 @@ - --#line 1 "../../src/hb-buffer-deserialize-json.rl" -+#line 1 "hb-buffer-deserialize-json.rl" - /* - * Copyright © 2013 Google, Inc. - * -@@ -32,7 +32,7 @@ - #include "hb-private.hh" - - --#line 36 "hb-buffer-deserialize-json.hh.tmp" -+#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, -@@ -435,7 +435,7 @@ - static const int deserialize_json_en_main = 1; - - --#line 97 "../../src/hb-buffer-deserialize-json.rl" -+#line 97 "hb-buffer-deserialize-json.rl" - - - static hb_bool_t -@@ -459,15 +459,15 @@ - - const char *tok = NULL; - int cs; -- hb_glyph_info_t info; -- hb_glyph_position_t pos; -+ hb_glyph_info_t info = {0}; -+ hb_glyph_position_t pos = {0}; - --#line 466 "hb-buffer-deserialize-json.hh.tmp" -+#line 466 "hb-buffer-deserialize-json.hh" - { - cs = deserialize_json_start; - } - --#line 471 "hb-buffer-deserialize-json.hh.tmp" -+#line 471 "hb-buffer-deserialize-json.hh" - { - int _slen; - int _trans; -@@ -493,14 +493,14 @@ - - switch ( _deserialize_json_trans_actions[_trans] ) { - case 1: --#line 38 "../../src/hb-buffer-deserialize-json.rl" -+#line 38 "hb-buffer-deserialize-json.rl" - { - memset (&info, 0, sizeof (info)); - memset (&pos , 0, sizeof (pos )); - } - break; - case 5: --#line 43 "../../src/hb-buffer-deserialize-json.rl" -+#line 43 "hb-buffer-deserialize-json.rl" - { - buffer->add_info (info); - if (buffer->in_error) -@@ -510,13 +510,13 @@ - } - break; - case 2: --#line 51 "../../src/hb-buffer-deserialize-json.rl" -+#line 51 "hb-buffer-deserialize-json.rl" - { - tok = p; - } - break; - case 14: --#line 55 "../../src/hb-buffer-deserialize-json.rl" -+#line 55 "hb-buffer-deserialize-json.rl" - { - if (!hb_font_glyph_from_string (font, - tok, p - tok, -@@ -525,33 +525,33 @@ - } - break; - case 15: --#line 62 "../../src/hb-buffer-deserialize-json.rl" -+#line 62 "hb-buffer-deserialize-json.rl" - { if (!parse_uint (tok, p, &info.codepoint)) return false; } - break; - case 8: --#line 63 "../../src/hb-buffer-deserialize-json.rl" -+#line 63 "hb-buffer-deserialize-json.rl" - { if (!parse_uint (tok, p, &info.cluster )) return false; } - break; - case 10: --#line 64 "../../src/hb-buffer-deserialize-json.rl" -+#line 64 "hb-buffer-deserialize-json.rl" - { if (!parse_int (tok, p, &pos.x_offset )) return false; } - break; - case 12: --#line 65 "../../src/hb-buffer-deserialize-json.rl" -+#line 65 "hb-buffer-deserialize-json.rl" - { if (!parse_int (tok, p, &pos.y_offset )) return false; } - break; - case 3: --#line 66 "../../src/hb-buffer-deserialize-json.rl" -+#line 66 "hb-buffer-deserialize-json.rl" - { if (!parse_int (tok, p, &pos.x_advance)) return false; } - break; - case 6: --#line 67 "../../src/hb-buffer-deserialize-json.rl" -+#line 67 "hb-buffer-deserialize-json.rl" - { if (!parse_int (tok, p, &pos.y_advance)) return false; } - break; - case 16: --#line 62 "../../src/hb-buffer-deserialize-json.rl" -+#line 62 "hb-buffer-deserialize-json.rl" - { if (!parse_uint (tok, p, &info.codepoint)) return false; } --#line 43 "../../src/hb-buffer-deserialize-json.rl" -+#line 43 "hb-buffer-deserialize-json.rl" - { - buffer->add_info (info); - if (buffer->in_error) -@@ -561,9 +561,9 @@ - } - break; - case 9: --#line 63 "../../src/hb-buffer-deserialize-json.rl" -+#line 63 "hb-buffer-deserialize-json.rl" - { if (!parse_uint (tok, p, &info.cluster )) return false; } --#line 43 "../../src/hb-buffer-deserialize-json.rl" -+#line 43 "hb-buffer-deserialize-json.rl" - { - buffer->add_info (info); - if (buffer->in_error) -@@ -573,9 +573,9 @@ - } - break; - case 11: --#line 64 "../../src/hb-buffer-deserialize-json.rl" -+#line 64 "hb-buffer-deserialize-json.rl" - { if (!parse_int (tok, p, &pos.x_offset )) return false; } --#line 43 "../../src/hb-buffer-deserialize-json.rl" -+#line 43 "hb-buffer-deserialize-json.rl" - { - buffer->add_info (info); - if (buffer->in_error) -@@ -585,9 +585,9 @@ - } - break; - case 13: --#line 65 "../../src/hb-buffer-deserialize-json.rl" -+#line 65 "hb-buffer-deserialize-json.rl" - { if (!parse_int (tok, p, &pos.y_offset )) return false; } --#line 43 "../../src/hb-buffer-deserialize-json.rl" -+#line 43 "hb-buffer-deserialize-json.rl" - { - buffer->add_info (info); - if (buffer->in_error) -@@ -597,9 +597,9 @@ - } - break; - case 4: --#line 66 "../../src/hb-buffer-deserialize-json.rl" -+#line 66 "hb-buffer-deserialize-json.rl" - { if (!parse_int (tok, p, &pos.x_advance)) return false; } --#line 43 "../../src/hb-buffer-deserialize-json.rl" -+#line 43 "hb-buffer-deserialize-json.rl" - { - buffer->add_info (info); - if (buffer->in_error) -@@ -609,9 +609,9 @@ - } - break; - case 7: --#line 67 "../../src/hb-buffer-deserialize-json.rl" -+#line 67 "hb-buffer-deserialize-json.rl" - { if (!parse_int (tok, p, &pos.y_advance)) return false; } --#line 43 "../../src/hb-buffer-deserialize-json.rl" -+#line 43 "hb-buffer-deserialize-json.rl" - { - buffer->add_info (info); - if (buffer->in_error) -@@ -620,7 +620,7 @@ - *end_ptr = p; - } - break; --#line 624 "hb-buffer-deserialize-json.hh.tmp" -+#line 624 "hb-buffer-deserialize-json.hh" - } - - _again: -@@ -632,7 +632,7 @@ - _out: {} - } - --#line 125 "../../src/hb-buffer-deserialize-json.rl" -+#line 125 "hb-buffer-deserialize-json.rl" - - - *end_ptr = p; -diff -uN gfx/harfbuzz/src_old/hb-buffer-deserialize-text.hh gfx/harfbuzz/src/hb-buffer-deserialize-text.hh ---- gfx/harfbuzz/src_old/hb-buffer-deserialize-text.hh 2016-05-10 22:26:56.000000000 +0200 -+++ gfx/harfbuzz/src/hb-buffer-deserialize-text.hh 2016-06-05 23:48:23.120330665 +0200 -@@ -1,5 +1,5 @@ - --#line 1 "../../src/hb-buffer-deserialize-text.rl" -+#line 1 "hb-buffer-deserialize-text.rl" - /* - * Copyright © 2013 Google, Inc. - * -@@ -32,7 +32,7 @@ - #include "hb-private.hh" - - --#line 36 "hb-buffer-deserialize-text.hh.tmp" -+#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, -@@ -312,7 +312,7 @@ - static const int deserialize_text_en_main = 1; - - --#line 91 "../../src/hb-buffer-deserialize-text.rl" -+#line 91 "hb-buffer-deserialize-text.rl" - - - static hb_bool_t -@@ -336,15 +336,15 @@ - - const char *eof = pe, *tok = NULL; - int cs; -- hb_glyph_info_t info; -- hb_glyph_position_t pos; -+ hb_glyph_info_t info = {0}; -+ hb_glyph_position_t pos = {0}; - --#line 343 "hb-buffer-deserialize-text.hh.tmp" -+#line 343 "hb-buffer-deserialize-text.hh" - { - cs = deserialize_text_start; - } - --#line 348 "hb-buffer-deserialize-text.hh.tmp" -+#line 348 "hb-buffer-deserialize-text.hh" - { - int _slen; - int _trans; -@@ -370,13 +370,13 @@ - - switch ( _deserialize_text_trans_actions[_trans] ) { - case 2: --#line 51 "../../src/hb-buffer-deserialize-text.rl" -+#line 51 "hb-buffer-deserialize-text.rl" - { - tok = p; - } - break; - case 5: --#line 55 "../../src/hb-buffer-deserialize-text.rl" -+#line 55 "hb-buffer-deserialize-text.rl" - { - if (!hb_font_glyph_from_string (font, - tok, p - tok, -@@ -385,41 +385,41 @@ - } - break; - case 10: --#line 62 "../../src/hb-buffer-deserialize-text.rl" -+#line 62 "hb-buffer-deserialize-text.rl" - { if (!parse_uint (tok, p, &info.cluster )) return false; } - break; - case 3: --#line 63 "../../src/hb-buffer-deserialize-text.rl" -+#line 63 "hb-buffer-deserialize-text.rl" - { if (!parse_int (tok, p, &pos.x_offset )) return false; } - break; - case 12: --#line 64 "../../src/hb-buffer-deserialize-text.rl" -+#line 64 "hb-buffer-deserialize-text.rl" - { if (!parse_int (tok, p, &pos.y_offset )) return false; } - break; - case 7: --#line 65 "../../src/hb-buffer-deserialize-text.rl" -+#line 65 "hb-buffer-deserialize-text.rl" - { if (!parse_int (tok, p, &pos.x_advance)) return false; } - break; - case 1: --#line 38 "../../src/hb-buffer-deserialize-text.rl" -+#line 38 "hb-buffer-deserialize-text.rl" - { - memset (&info, 0, sizeof (info)); - memset (&pos , 0, sizeof (pos )); - } --#line 51 "../../src/hb-buffer-deserialize-text.rl" -+#line 51 "hb-buffer-deserialize-text.rl" - { - tok = p; - } - break; - case 4: --#line 55 "../../src/hb-buffer-deserialize-text.rl" -+#line 55 "hb-buffer-deserialize-text.rl" - { - if (!hb_font_glyph_from_string (font, - tok, p - tok, - &info.codepoint)) - return false; - } --#line 43 "../../src/hb-buffer-deserialize-text.rl" -+#line 43 "hb-buffer-deserialize-text.rl" - { - buffer->add_info (info); - if (buffer->in_error) -@@ -429,9 +429,9 @@ - } - break; - case 9: --#line 62 "../../src/hb-buffer-deserialize-text.rl" -+#line 62 "hb-buffer-deserialize-text.rl" - { if (!parse_uint (tok, p, &info.cluster )) return false; } --#line 43 "../../src/hb-buffer-deserialize-text.rl" -+#line 43 "hb-buffer-deserialize-text.rl" - { - buffer->add_info (info); - if (buffer->in_error) -@@ -441,9 +441,9 @@ - } - break; - case 11: --#line 64 "../../src/hb-buffer-deserialize-text.rl" -+#line 64 "hb-buffer-deserialize-text.rl" - { if (!parse_int (tok, p, &pos.y_offset )) return false; } --#line 43 "../../src/hb-buffer-deserialize-text.rl" -+#line 43 "hb-buffer-deserialize-text.rl" - { - buffer->add_info (info); - if (buffer->in_error) -@@ -453,9 +453,9 @@ - } - break; - case 6: --#line 65 "../../src/hb-buffer-deserialize-text.rl" -+#line 65 "hb-buffer-deserialize-text.rl" - { if (!parse_int (tok, p, &pos.x_advance)) return false; } --#line 43 "../../src/hb-buffer-deserialize-text.rl" -+#line 43 "hb-buffer-deserialize-text.rl" - { - buffer->add_info (info); - if (buffer->in_error) -@@ -465,9 +465,9 @@ - } - break; - case 8: --#line 66 "../../src/hb-buffer-deserialize-text.rl" -+#line 66 "hb-buffer-deserialize-text.rl" - { if (!parse_int (tok, p, &pos.y_advance)) return false; } --#line 43 "../../src/hb-buffer-deserialize-text.rl" -+#line 43 "hb-buffer-deserialize-text.rl" - { - buffer->add_info (info); - if (buffer->in_error) -@@ -476,7 +476,7 @@ - *end_ptr = p; - } - break; --#line 480 "hb-buffer-deserialize-text.hh.tmp" -+#line 480 "hb-buffer-deserialize-text.hh" - } - - _again: -@@ -489,14 +489,14 @@ - { - switch ( _deserialize_text_eof_actions[cs] ) { - case 4: --#line 55 "../../src/hb-buffer-deserialize-text.rl" -+#line 55 "hb-buffer-deserialize-text.rl" - { - if (!hb_font_glyph_from_string (font, - tok, p - tok, - &info.codepoint)) - return false; - } --#line 43 "../../src/hb-buffer-deserialize-text.rl" -+#line 43 "hb-buffer-deserialize-text.rl" - { - buffer->add_info (info); - if (buffer->in_error) -@@ -506,9 +506,9 @@ - } - break; - case 9: --#line 62 "../../src/hb-buffer-deserialize-text.rl" -+#line 62 "hb-buffer-deserialize-text.rl" - { if (!parse_uint (tok, p, &info.cluster )) return false; } --#line 43 "../../src/hb-buffer-deserialize-text.rl" -+#line 43 "hb-buffer-deserialize-text.rl" - { - buffer->add_info (info); - if (buffer->in_error) -@@ -518,9 +518,9 @@ - } - break; - case 11: --#line 64 "../../src/hb-buffer-deserialize-text.rl" -+#line 64 "hb-buffer-deserialize-text.rl" - { if (!parse_int (tok, p, &pos.y_offset )) return false; } --#line 43 "../../src/hb-buffer-deserialize-text.rl" -+#line 43 "hb-buffer-deserialize-text.rl" - { - buffer->add_info (info); - if (buffer->in_error) -@@ -530,9 +530,9 @@ - } - break; - case 6: --#line 65 "../../src/hb-buffer-deserialize-text.rl" -+#line 65 "hb-buffer-deserialize-text.rl" - { if (!parse_int (tok, p, &pos.x_advance)) return false; } --#line 43 "../../src/hb-buffer-deserialize-text.rl" -+#line 43 "hb-buffer-deserialize-text.rl" - { - buffer->add_info (info); - if (buffer->in_error) -@@ -542,9 +542,9 @@ - } - break; - case 8: --#line 66 "../../src/hb-buffer-deserialize-text.rl" -+#line 66 "hb-buffer-deserialize-text.rl" - { if (!parse_int (tok, p, &pos.y_advance)) return false; } --#line 43 "../../src/hb-buffer-deserialize-text.rl" -+#line 43 "hb-buffer-deserialize-text.rl" - { - buffer->add_info (info); - if (buffer->in_error) -@@ -553,14 +553,14 @@ - *end_ptr = p; - } - break; --#line 557 "hb-buffer-deserialize-text.hh.tmp" -+#line 557 "hb-buffer-deserialize-text.hh" - } - } - - _out: {} - } - --#line 119 "../../src/hb-buffer-deserialize-text.rl" -+#line 119 "hb-buffer-deserialize-text.rl" - - - *end_ptr = p; -diff -uN gfx/harfbuzz/src_old/hb-buffer-deserialize-text.rl gfx/harfbuzz/src/hb-buffer-deserialize-text.rl ---- gfx/harfbuzz/src_old/hb-buffer-deserialize-text.rl 2016-05-10 22:26:55.000000000 +0200 -+++ gfx/harfbuzz/src/hb-buffer-deserialize-text.rl 2016-06-05 23:48:24.307324017 +0200 -@@ -111,8 +111,8 @@ - - const char *eof = pe, *tok = NULL; - int cs; -- hb_glyph_info_t info; -- hb_glyph_position_t pos; -+ hb_glyph_info_t info = {0}; -+ hb_glyph_position_t pos = {0}; - %%{ - write init; - write exec; -diff -uN gfx/harfbuzz/src_old/hb-buffer.h gfx/harfbuzz/src/hb-buffer.h ---- gfx/harfbuzz/src_old/hb-buffer.h 2016-05-10 22:26:56.000000000 +0200 -+++ gfx/harfbuzz/src/hb-buffer.h 2016-06-05 23:48:29.670294025 +0200 -@@ -40,7 +40,27 @@ - - HB_BEGIN_DECLS - -- -+/** -+ * hb_glyph_info_t: -+ * @codepoint: either a Unicode code point (before shaping) or a glyph index -+ * (after shaping). -+ * @mask: -+ * @cluster: the index of the character in the original text that corresponds -+ * to this #hb_glyph_info_t, or whatever the client passes to -+ * hb_buffer_add(). More than one #hb_glyph_info_t can have the same -+ * @cluster value, if they resulted from the same character (e.g. one -+ * to many glyph substitution), and when more than one character gets -+ * merged in the same glyph (e.g. many to one glyph substitution) the -+ * #hb_glyph_info_t will have the smallest cluster value of them. -+ * By default some characters are merged into the same cluster -+ * (e.g. combining marks have the same cluster as their bases) -+ * even if they are separate glyphs, hb_buffer_set_cluster_level() -+ * allow selecting more fine-grained cluster handling. -+ * -+ * The #hb_glyph_info_t is the structure that holds information about the -+ * glyphs and their relation to input text. -+ * -+ */ - typedef struct hb_glyph_info_t { - hb_codepoint_t codepoint; - hb_mask_t mask; -@@ -51,6 +71,22 @@ - hb_var_int_t var2; - } hb_glyph_info_t; - -+/** -+ * hb_glyph_position_t: -+ * @x_advance: how much the line advances after drawing this glyph when setting -+ * text in horizontal direction. -+ * @y_advance: how much the line advances after drawing this glyph when setting -+ * text in vertical direction. -+ * @x_offset: how much the glyph moves on the X-axis before drawing it, this -+ * should not affect how much the line advances. -+ * @y_offset: how much the glyph moves on the Y-axis before drawing it, this -+ * should not affect how much the line advances. -+ * -+ * The #hb_glyph_position_t is the structure that holds the positions of the -+ * glyph in both horizontal and vertical directions. All positions in -+ * #hb_glyph_position_t are relative to the current point. -+ * -+ */ - typedef struct hb_glyph_position_t { - hb_position_t x_advance; - hb_position_t y_advance; -@@ -61,7 +97,16 @@ - hb_var_int_t var; - } hb_glyph_position_t; - -- -+/** -+ * hb_segment_properties_t: -+ * @direction: the #hb_direction_t of the buffer, see hb_buffer_set_direction(). -+ * @script: the #hb_script_t of the buffer, see hb_buffer_set_script(). -+ * @language: the #hb_language_t of the buffer, see hb_buffer_set_language(). -+ * -+ * The structure that holds various text properties of an #hb_buffer_t. Can be -+ * set and retrieved using hb_buffer_set_segment_properties() and -+ * hb_buffer_get_segment_properties(), respectively. -+ */ - typedef struct hb_segment_properties_t { - hb_direction_t direction; - hb_script_t script; -@@ -77,100 +122,127 @@ - NULL, \ - NULL} - --hb_bool_t -+HB_EXTERN hb_bool_t - hb_segment_properties_equal (const hb_segment_properties_t *a, - const hb_segment_properties_t *b); - --unsigned int -+HB_EXTERN unsigned int - hb_segment_properties_hash (const hb_segment_properties_t *p); - - - --/* -- * hb_buffer_t -+/** -+ * hb_buffer_t: -+ * -+ * The main structure holding the input text and its properties before shaping, -+ * and output glyphs and their information after shaping. - */ - - typedef struct hb_buffer_t hb_buffer_t; - --hb_buffer_t * -+HB_EXTERN hb_buffer_t * - hb_buffer_create (void); - --hb_buffer_t * -+HB_EXTERN hb_buffer_t * - hb_buffer_get_empty (void); - --hb_buffer_t * -+HB_EXTERN hb_buffer_t * - hb_buffer_reference (hb_buffer_t *buffer); - --void -+HB_EXTERN void - hb_buffer_destroy (hb_buffer_t *buffer); - --hb_bool_t -+HB_EXTERN hb_bool_t - hb_buffer_set_user_data (hb_buffer_t *buffer, - hb_user_data_key_t *key, - void * data, - hb_destroy_func_t destroy, - hb_bool_t replace); - --void * -+HB_EXTERN void * - hb_buffer_get_user_data (hb_buffer_t *buffer, - hb_user_data_key_t *key); - -- -+/** -+ * hb_buffer_content_type_t: -+ * @HB_BUFFER_CONTENT_TYPE_INVALID: Initial value for new buffer. -+ * @HB_BUFFER_CONTENT_TYPE_UNICODE: The buffer contains input characters (before shaping). -+ * @HB_BUFFER_CONTENT_TYPE_GLYPHS: The buffer contains output glyphs (after shaping). -+ */ - typedef enum { - HB_BUFFER_CONTENT_TYPE_INVALID = 0, - HB_BUFFER_CONTENT_TYPE_UNICODE, - HB_BUFFER_CONTENT_TYPE_GLYPHS - } hb_buffer_content_type_t; - --void -+HB_EXTERN void - hb_buffer_set_content_type (hb_buffer_t *buffer, - hb_buffer_content_type_t content_type); - --hb_buffer_content_type_t -+HB_EXTERN hb_buffer_content_type_t - hb_buffer_get_content_type (hb_buffer_t *buffer); - - --void -+HB_EXTERN void - hb_buffer_set_unicode_funcs (hb_buffer_t *buffer, - hb_unicode_funcs_t *unicode_funcs); - --hb_unicode_funcs_t * -+HB_EXTERN hb_unicode_funcs_t * - hb_buffer_get_unicode_funcs (hb_buffer_t *buffer); - --void -+HB_EXTERN void - hb_buffer_set_direction (hb_buffer_t *buffer, - hb_direction_t direction); - --hb_direction_t -+HB_EXTERN hb_direction_t - hb_buffer_get_direction (hb_buffer_t *buffer); - --void -+HB_EXTERN void - hb_buffer_set_script (hb_buffer_t *buffer, - hb_script_t script); - --hb_script_t -+HB_EXTERN hb_script_t - hb_buffer_get_script (hb_buffer_t *buffer); - --void -+HB_EXTERN void - hb_buffer_set_language (hb_buffer_t *buffer, - hb_language_t language); - - --hb_language_t -+HB_EXTERN hb_language_t - hb_buffer_get_language (hb_buffer_t *buffer); - --void -+HB_EXTERN void - hb_buffer_set_segment_properties (hb_buffer_t *buffer, - const hb_segment_properties_t *props); - --void -+HB_EXTERN void - hb_buffer_get_segment_properties (hb_buffer_t *buffer, - hb_segment_properties_t *props); - --void -+HB_EXTERN void - hb_buffer_guess_segment_properties (hb_buffer_t *buffer); - - -+/** -+ * hb_buffer_flags_t: -+ * @HB_BUFFER_FLAG_DEFAULT: the default buffer flag. -+ * @HB_BUFFER_FLAG_BOT: flag indicating that special handling of the beginning -+ * of text paragraph can be applied to this buffer. Should usually -+ * be set, unless you are passing to the buffer only part -+ * of the text without the full context. -+ * @HB_BUFFER_FLAG_EOT: flag indicating that special handling of the end of text -+ * paragraph can be applied to this buffer, similar to -+ * @HB_BUFFER_FLAG_EOT. -+ * @HB_BUFFER_FLAG_PRESERVE_DEFAULT_IGNORABLES: -+ * flag indication that character with Default_Ignorable -+ * Unicode property should use the corresponding glyph -+ * from the font, instead of hiding them (currently done -+ * by replacing them with the space glyph and zeroing the -+ * advance width.) -+ * -+ * Since: 0.9.20 -+ */ - typedef enum { /*< flags >*/ - HB_BUFFER_FLAG_DEFAULT = 0x00000000u, - HB_BUFFER_FLAG_BOT = 0x00000001u, /* Beginning-of-text */ -@@ -178,83 +250,109 @@ - HB_BUFFER_FLAG_PRESERVE_DEFAULT_IGNORABLES = 0x00000004u - } hb_buffer_flags_t; - --void -+HB_EXTERN void - hb_buffer_set_flags (hb_buffer_t *buffer, - hb_buffer_flags_t flags); - --hb_buffer_flags_t -+HB_EXTERN hb_buffer_flags_t - hb_buffer_get_flags (hb_buffer_t *buffer); - -- -- -+/* -+ * Since: 0.9.42 -+ */ -+typedef enum { -+ HB_BUFFER_CLUSTER_LEVEL_MONOTONE_GRAPHEMES = 0, -+ HB_BUFFER_CLUSTER_LEVEL_MONOTONE_CHARACTERS = 1, -+ HB_BUFFER_CLUSTER_LEVEL_CHARACTERS = 2, -+ HB_BUFFER_CLUSTER_LEVEL_DEFAULT = HB_BUFFER_CLUSTER_LEVEL_MONOTONE_GRAPHEMES -+} hb_buffer_cluster_level_t; -+ -+HB_EXTERN void -+hb_buffer_set_cluster_level (hb_buffer_t *buffer, -+ hb_buffer_cluster_level_t cluster_level); -+ -+HB_EXTERN hb_buffer_cluster_level_t -+hb_buffer_get_cluster_level (hb_buffer_t *buffer); -+ -+/** -+ * HB_BUFFER_REPLACEMENT_CODEPOINT_DEFAULT: -+ * -+ * The default code point for replacing invalid characters in a given encoding. -+ * Set to U+FFFD REPLACEMENT CHARACTER. -+ * -+ * Since: 0.9.31 -+ */ - #define HB_BUFFER_REPLACEMENT_CODEPOINT_DEFAULT 0xFFFDu - --/* Sets codepoint used to replace invalid UTF-8/16/32 entries. -- * Default is 0xFFFDu. */ --void -+HB_EXTERN void - hb_buffer_set_replacement_codepoint (hb_buffer_t *buffer, - hb_codepoint_t replacement); - --hb_codepoint_t -+HB_EXTERN hb_codepoint_t - hb_buffer_get_replacement_codepoint (hb_buffer_t *buffer); - - --/* Resets the buffer. Afterwards it's as if it was just created, -- * except that it has a larger buffer allocated perhaps... */ --void -+HB_EXTERN void - hb_buffer_reset (hb_buffer_t *buffer); - --/* Like reset, but does NOT clear unicode_funcs and replacement_codepoint. */ --void -+HB_EXTERN void - hb_buffer_clear_contents (hb_buffer_t *buffer); - --/* Returns false if allocation failed */ --hb_bool_t -+HB_EXTERN hb_bool_t - hb_buffer_pre_allocate (hb_buffer_t *buffer, - unsigned int size); - - --/* Returns false if allocation has failed before */ --hb_bool_t -+HB_EXTERN hb_bool_t - hb_buffer_allocation_successful (hb_buffer_t *buffer); - --void -+HB_EXTERN void - hb_buffer_reverse (hb_buffer_t *buffer); - --void -+HB_EXTERN void -+hb_buffer_reverse_range (hb_buffer_t *buffer, -+ unsigned int start, unsigned int end); -+ -+HB_EXTERN void - hb_buffer_reverse_clusters (hb_buffer_t *buffer); - - - /* Filling the buffer in */ - --void -+HB_EXTERN void - hb_buffer_add (hb_buffer_t *buffer, - hb_codepoint_t codepoint, - unsigned int cluster); - --void -+HB_EXTERN void - hb_buffer_add_utf8 (hb_buffer_t *buffer, - const char *text, - int text_length, - unsigned int item_offset, - int item_length); - --void -+HB_EXTERN void - hb_buffer_add_utf16 (hb_buffer_t *buffer, - const uint16_t *text, - int text_length, - unsigned int item_offset, - int item_length); - --void -+HB_EXTERN void - hb_buffer_add_utf32 (hb_buffer_t *buffer, - const uint32_t *text, - int text_length, - unsigned int item_offset, - int item_length); - --/* Like add_utf32 but does NOT check for invalid Unicode codepoints. */ --void -+HB_EXTERN void -+hb_buffer_add_latin1 (hb_buffer_t *buffer, -+ const uint8_t *text, -+ int text_length, -+ unsigned int item_offset, -+ int item_length); -+ -+HB_EXTERN void - hb_buffer_add_codepoints (hb_buffer_t *buffer, - const hb_codepoint_t *text, - int text_length, -@@ -262,32 +360,25 @@ - int item_length); - - --/* Clears any new items added at the end */ --hb_bool_t -+HB_EXTERN hb_bool_t - hb_buffer_set_length (hb_buffer_t *buffer, - unsigned int length); - --/* Return value valid as long as buffer not modified */ --unsigned int -+HB_EXTERN unsigned int - hb_buffer_get_length (hb_buffer_t *buffer); - - /* Getting glyphs out of the buffer */ - --/* Return value valid as long as buffer not modified */ --hb_glyph_info_t * -+HB_EXTERN hb_glyph_info_t * - hb_buffer_get_glyph_infos (hb_buffer_t *buffer, - unsigned int *length); - --/* Return value valid as long as buffer not modified */ --hb_glyph_position_t * -+HB_EXTERN hb_glyph_position_t * - hb_buffer_get_glyph_positions (hb_buffer_t *buffer, - unsigned int *length); - - --/* Reorders a glyph buffer to have canonical in-cluster glyph order / position. -- * The resulting clusters should behave identical to pre-reordering clusters. -- * NOTE: This has nothing to do with Unicode normalization. */ --void -+HB_EXTERN void - hb_buffer_normalize_glyphs (hb_buffer_t *buffer); - - -@@ -295,50 +386,87 @@ - * Serialize - */ - -+/** -+ * hb_buffer_serialize_flags_t: -+ * @HB_BUFFER_SERIALIZE_FLAG_DEFAULT: serialize glyph names, clusters and positions. -+ * @HB_BUFFER_SERIALIZE_FLAG_NO_CLUSTERS: do not serialize glyph cluster. -+ * @HB_BUFFER_SERIALIZE_FLAG_NO_POSITIONS: do not serialize glyph position information. -+ * @HB_BUFFER_SERIALIZE_FLAG_NO_GLYPH_NAMES: do no serialize glyph name. -+ * @HB_BUFFER_SERIALIZE_FLAG_GLYPH_EXTENTS: serialize glyph extents. -+ * -+ * Flags that control what glyph information are serialized in hb_buffer_serialize_glyphs(). -+ * -+ * Since: 0.9.20 -+ */ - typedef enum { /*< flags >*/ - HB_BUFFER_SERIALIZE_FLAG_DEFAULT = 0x00000000u, - HB_BUFFER_SERIALIZE_FLAG_NO_CLUSTERS = 0x00000001u, - HB_BUFFER_SERIALIZE_FLAG_NO_POSITIONS = 0x00000002u, -- HB_BUFFER_SERIALIZE_FLAG_NO_GLYPH_NAMES = 0x00000004u -+ HB_BUFFER_SERIALIZE_FLAG_NO_GLYPH_NAMES = 0x00000004u, -+ HB_BUFFER_SERIALIZE_FLAG_GLYPH_EXTENTS = 0x00000008u - } hb_buffer_serialize_flags_t; - -+/** -+ * hb_buffer_serialize_format_t: -+ * @HB_BUFFER_SERIALIZE_FORMAT_TEXT: a human-readable, plain text format. -+ * @HB_BUFFER_SERIALIZE_FORMAT_JSON: a machine-readable JSON format. -+ * @HB_BUFFER_SERIALIZE_FORMAT_INVALID: invalid format. -+ * -+ * The buffer serialization and de-serialization format used in -+ * hb_buffer_serialize_glyphs() and hb_buffer_deserialize_glyphs(). -+ * -+ * Since: 0.9.2 -+ */ - typedef enum { - HB_BUFFER_SERIALIZE_FORMAT_TEXT = HB_TAG('T','E','X','T'), - HB_BUFFER_SERIALIZE_FORMAT_JSON = HB_TAG('J','S','O','N'), - HB_BUFFER_SERIALIZE_FORMAT_INVALID = HB_TAG_NONE - } hb_buffer_serialize_format_t; - --/* len=-1 means str is NUL-terminated. */ --hb_buffer_serialize_format_t -+HB_EXTERN hb_buffer_serialize_format_t - hb_buffer_serialize_format_from_string (const char *str, int len); - --const char * -+HB_EXTERN const char * - hb_buffer_serialize_format_to_string (hb_buffer_serialize_format_t format); - --const char ** -+HB_EXTERN const char ** - hb_buffer_serialize_list_formats (void); - --/* Returns number of items, starting at start, that were serialized. */ --unsigned int -+HB_EXTERN unsigned int - hb_buffer_serialize_glyphs (hb_buffer_t *buffer, - unsigned int start, - unsigned int end, - char *buf, - unsigned int buf_size, -- unsigned int *buf_consumed, /* May be NULL */ -- hb_font_t *font, /* May be NULL */ -+ unsigned int *buf_consumed, -+ hb_font_t *font, - hb_buffer_serialize_format_t format, - hb_buffer_serialize_flags_t flags); - --hb_bool_t -+HB_EXTERN hb_bool_t - hb_buffer_deserialize_glyphs (hb_buffer_t *buffer, - const char *buf, -- int buf_len, /* -1 means nul-terminated */ -- const char **end_ptr, /* May be NULL */ -- hb_font_t *font, /* May be NULL */ -+ int buf_len, -+ const char **end_ptr, -+ hb_font_t *font, - hb_buffer_serialize_format_t format); - - -+/* -+ * Debugging. -+ */ -+ -+typedef hb_bool_t (*hb_buffer_message_func_t) (hb_buffer_t *buffer, -+ hb_font_t *font, -+ const char *message, -+ void *user_data); -+ -+HB_EXTERN void -+hb_buffer_set_message_func (hb_buffer_t *buffer, -+ hb_buffer_message_func_t func, -+ void *user_data, hb_destroy_func_t destroy); -+ -+ - HB_END_DECLS - - #endif /* HB_BUFFER_H */ -diff -uN gfx/harfbuzz/src_old/hb-buffer-private.hh gfx/harfbuzz/src/hb-buffer-private.hh ---- gfx/harfbuzz/src_old/hb-buffer-private.hh 2016-05-10 22:26:56.000000000 +0200 -+++ gfx/harfbuzz/src/hb-buffer-private.hh 2016-06-05 23:48:25.604316742 +0200 -@@ -35,9 +35,37 @@ - #include "hb-unicode-private.hh" - - -+#ifndef HB_BUFFER_MAX_EXPANSION_FACTOR -+#define HB_BUFFER_MAX_EXPANSION_FACTOR 32 -+#endif -+#ifndef HB_BUFFER_MAX_LEN_MIN -+#define HB_BUFFER_MAX_LEN_MIN 8192 -+#endif -+#ifndef HB_BUFFER_MAX_LEN_DEFAULT -+#define HB_BUFFER_MAX_LEN_DEFAULT 0x3FFFFFFF /* Shaping more than a billion chars? Let us know! */ -+#endif -+ - ASSERT_STATIC (sizeof (hb_glyph_info_t) == 20); - ASSERT_STATIC (sizeof (hb_glyph_info_t) == sizeof (hb_glyph_position_t)); - -+HB_MARK_AS_FLAG_T (hb_buffer_flags_t); -+HB_MARK_AS_FLAG_T (hb_buffer_serialize_flags_t); -+ -+enum hb_buffer_scratch_flags_t { -+ HB_BUFFER_SCRATCH_FLAG_DEFAULT = 0x00000000u, -+ HB_BUFFER_SCRATCH_FLAG_HAS_NON_ASCII = 0x00000001u, -+ HB_BUFFER_SCRATCH_FLAG_HAS_DEFAULT_IGNORABLES = 0x00000002u, -+ HB_BUFFER_SCRATCH_FLAG_HAS_SPACE_FALLBACK = 0x00000004u, -+ HB_BUFFER_SCRATCH_FLAG_HAS_GPOS_CURSIVE = 0x00000008u, -+ HB_BUFFER_SCRATCH_FLAG_HAS_GPOS_ATTACHMENT = 0x00000010u, -+ /* Reserved for complex shapers' internal use. */ -+ HB_BUFFER_SCRATCH_FLAG_COMPLEX0 = 0x01000000u, -+ HB_BUFFER_SCRATCH_FLAG_COMPLEX1 = 0x02000000u, -+ HB_BUFFER_SCRATCH_FLAG_COMPLEX2 = 0x04000000u, -+ HB_BUFFER_SCRATCH_FLAG_COMPLEX3 = 0x08000000u, -+}; -+HB_MARK_AS_FLAG_T (hb_buffer_scratch_flags_t); -+ - - /* - * hb_buffer_t -@@ -50,7 +78,10 @@ - /* Information about how the text in the buffer should be treated */ - hb_unicode_funcs_t *unicode; /* Unicode functions */ - hb_buffer_flags_t flags; /* BOT / EOT / etc. */ -+ hb_buffer_cluster_level_t cluster_level; - hb_codepoint_t replacement; /* U+FFFD or something else. */ -+ hb_buffer_scratch_flags_t scratch_flags; /* Have space-flallback, etc. */ -+ unsigned int max_len; /* Maximum allowed len. */ - - /* Buffer contents */ - hb_buffer_content_type_t content_type; -@@ -75,8 +106,8 @@ - inline hb_glyph_position_t &cur_pos (unsigned int i = 0) { return pos[idx + i]; } - inline hb_glyph_position_t cur_pos (unsigned int i = 0) const { return pos[idx + i]; } - -- inline hb_glyph_info_t &prev (void) { return out_info[out_len - 1]; } -- inline hb_glyph_info_t prev (void) const { return info[out_len - 1]; } -+ inline hb_glyph_info_t &prev (void) { return out_info[out_len ? out_len - 1 : 0]; } -+ inline hb_glyph_info_t prev (void) const { return out_info[out_len ? out_len - 1 : 0]; } - - inline bool has_separate_output (void) const { return info != out_info; } - -@@ -93,6 +124,11 @@ - hb_codepoint_t context[2][CONTEXT_LENGTH]; - unsigned int context_len[2]; - -+ /* Debugging */ -+ hb_buffer_message_func_t message_func; -+ void *message_data; -+ hb_destroy_func_t message_destroy; -+ - - /* Methods */ - -@@ -171,9 +207,18 @@ - unsigned int cluster_end); - - HB_INTERNAL void merge_clusters (unsigned int start, -- unsigned int end); -+ unsigned int end) -+ { -+ if (end - start < 2) -+ return; -+ merge_clusters_impl (start, end); -+ } -+ HB_INTERNAL void merge_clusters_impl (unsigned int start, -+ unsigned int end); - HB_INTERNAL void merge_out_clusters (unsigned int start, - unsigned int end); -+ /* Merge clusters for deleting current glyph, and skip it. */ -+ HB_INTERNAL void delete_glyph (void); - - /* Internal methods */ - HB_INTERNAL bool enlarge (unsigned int size); -@@ -191,6 +236,21 @@ - HB_INTERNAL scratch_buffer_t *get_scratch_buffer (unsigned int *size); - - inline void clear_context (unsigned int side) { context_len[side] = 0; } -+ -+ HB_INTERNAL void sort (unsigned int start, unsigned int end, int(*compar)(const hb_glyph_info_t *, const hb_glyph_info_t *)); -+ -+ inline bool messaging (void) { return unlikely (message_func); } -+ inline bool message (hb_font_t *font, const char *fmt, ...) HB_PRINTF_FUNC(3, 4) -+ { -+ if (!messaging ()) -+ return true; -+ va_list ap; -+ va_start (ap, fmt); -+ bool ret = message_impl (font, fmt, ap); -+ va_end (ap); -+ return ret; -+ } -+ HB_INTERNAL bool message_impl (hb_font_t *font, const char *fmt, va_list ap) HB_PRINTF_FUNC(3, 0); - }; - - -diff -uN gfx/harfbuzz/src_old/hb-buffer-serialize.cc gfx/harfbuzz/src/hb-buffer-serialize.cc ---- gfx/harfbuzz/src_old/hb-buffer-serialize.cc 2016-05-10 22:26:56.000000000 +0200 -+++ gfx/harfbuzz/src/hb-buffer-serialize.cc 2016-06-05 23:48:26.782310166 +0200 -@@ -36,11 +36,12 @@ - /** - * hb_buffer_serialize_list_formats: - * -- * -+ * Returns a list of supported buffer serialization formats. - * - * Return value: (transfer none): -+ * A string array of buffer serialization formats. Should not be freed. - * -- * Since: 1.0 -+ * Since: 0.9.7 - **/ - const char ** - hb_buffer_serialize_list_formats (void) -@@ -50,14 +51,17 @@ - - /** - * hb_buffer_serialize_format_from_string: -- * @str: -- * @len: -+ * @str: (array length=len) (element-type uint8_t): a string to parse -+ * @len: length of @str, or -1 if string is %NULL terminated - * -- * -+ * Parses a string into an #hb_buffer_serialize_format_t. Does not check if -+ * @str is a valid buffer serialization format, use -+ * hb_buffer_serialize_list_formats() to get the list of supported formats. - * - * Return value: -+ * The parsed #hb_buffer_serialize_format_t. - * -- * Since: 1.0 -+ * Since: 0.9.7 - **/ - hb_buffer_serialize_format_t - hb_buffer_serialize_format_from_string (const char *str, int len) -@@ -68,13 +72,15 @@ - - /** - * hb_buffer_serialize_format_to_string: -- * @format: -+ * @format: an #hb_buffer_serialize_format_t to convert. - * -- * -+ * Converts @format to the string corresponding it, or %NULL if it is not a valid -+ * #hb_buffer_serialize_format_t. - * -- * Return value: -+ * Return value: (transfer none): -+ * A %NULL terminated string corresponding to @format. Should not be freed. - * -- * Since: 1.0 -+ * Since: 0.9.7 - **/ - const char * - hb_buffer_serialize_format_to_string (hb_buffer_serialize_format_t format) -@@ -99,7 +105,8 @@ - hb_buffer_serialize_flags_t flags) - { - hb_glyph_info_t *info = hb_buffer_get_glyph_infos (buffer, NULL); -- hb_glyph_position_t *pos = hb_buffer_get_glyph_positions (buffer, NULL); -+ hb_glyph_position_t *pos = (flags & HB_BUFFER_SERIALIZE_FLAG_NO_POSITIONS) ? -+ NULL : hb_buffer_get_glyph_positions (buffer, NULL); - - *buf_consumed = 0; - for (unsigned int i = start; i < end; i++) -@@ -144,6 +151,16 @@ - pos[i].x_advance, pos[i].y_advance); - } - -+ if (flags & HB_BUFFER_SERIALIZE_FLAG_GLYPH_EXTENTS) -+ { -+ hb_glyph_extents_t extents; -+ hb_font_get_glyph_extents(font, info[i].codepoint, &extents); -+ p += MAX (0, snprintf (p, ARRAY_LENGTH (b) - (p - b), ",\"xb\":%d,\"yb\":%d", -+ extents.x_bearing, extents.y_bearing)); -+ p += MAX (0, snprintf (p, ARRAY_LENGTH (b) - (p - b), ",\"w\":%d,\"h\":%d", -+ extents.width, extents.height)); -+ } -+ - *p++ = '}'; - - unsigned int l = p - b; -@@ -172,7 +189,8 @@ - hb_buffer_serialize_flags_t flags) - { - hb_glyph_info_t *info = hb_buffer_get_glyph_infos (buffer, NULL); -- hb_glyph_position_t *pos = hb_buffer_get_glyph_positions (buffer, NULL); -+ hb_glyph_position_t *pos = (flags & HB_BUFFER_SERIALIZE_FLAG_NO_POSITIONS) ? -+ NULL : hb_buffer_get_glyph_positions (buffer, NULL); - - *buf_consumed = 0; - for (unsigned int i = start; i < end; i++) -@@ -208,6 +226,13 @@ - p += MAX (0, snprintf (p, ARRAY_LENGTH (b) - (p - b), ",%d", pos[i].y_advance)); - } - -+ if (flags & HB_BUFFER_SERIALIZE_FLAG_GLYPH_EXTENTS) -+ { -+ hb_glyph_extents_t extents; -+ hb_font_get_glyph_extents(font, info[i].codepoint, &extents); -+ p += MAX (0, snprintf (p, ARRAY_LENGTH (b) - (p - b), "<%d,%d,%d,%d>", extents.x_bearing, extents.y_bearing, extents.width, extents.height)); -+ } -+ - unsigned int l = p - b; - if (buf_size > l) - { -@@ -223,24 +248,51 @@ - return end - start; - } - --/* Returns number of items, starting at start, that were serialized. */ - /** - * hb_buffer_serialize_glyphs: -- * @buffer: a buffer. -- * @start: -- * @end: -- * @buf: (array length=buf_size): -- * @buf_size: -- * @buf_consumed: (out): -- * @font: -- * @format: -- * @flags: -+ * @buffer: an #hb_buffer_t buffer. -+ * @start: the first item in @buffer to serialize. -+ * @end: the last item in @buffer to serialize. -+ * @buf: (out) (array length=buf_size) (element-type uint8_t): output string to -+ * write serialized buffer into. -+ * @buf_size: the size of @buf. -+ * @buf_consumed: (out) (allow-none): if not %NULL, will be set to the number of byes written into @buf. -+ * @font: (allow-none): the #hb_font_t used to shape this buffer, needed to -+ * read glyph names and extents. If %NULL, and empty font will be used. -+ * @format: the #hb_buffer_serialize_format_t to use for formatting the output. -+ * @flags: the #hb_buffer_serialize_flags_t that control what glyph properties -+ * to serialize. -+ * -+ * Serializes @buffer into a textual representation of its glyph content, -+ * useful for showing the contents of the buffer, for example during debugging. -+ * There are currently two supported serialization formats: -+ * -+ * ## text -+ * A human-readable, plain text format. -+ * The serialized glyphs will look something like: -+ * -+ * ``` -+ * [uni0651=0@518,0+0|uni0628=0+1897] -+ * ``` -+ * - The serialized glyphs are delimited with `[` and `]`. -+ * - Glyphs are separated with `|` -+ * - Each glyph starts with glyph name, or glyph index if -+ * #HB_BUFFER_SERIALIZE_FLAG_NO_GLYPH_NAMES flag is set. Then, -+ * - If #HB_BUFFER_SERIALIZE_FLAG_NO_CLUSTERS is not set, `=` then #hb_glyph_info_t.cluster. -+ * - If #HB_BUFFER_SERIALIZE_FLAG_NO_POSITIONS is not set, the #hb_glyph_position_t in the format: -+ * - If both #hb_glyph_position_t.x_offset and #hb_glyph_position_t.y_offset are not 0, `@x_offset,y_offset`. Then, -+ * - `+x_advance`, then `,y_advance` if #hb_glyph_position_t.y_advance is not 0. Then, -+ * - If #HB_BUFFER_SERIALIZE_FLAG_GLYPH_EXTENTS is set, the -+ * #hb_glyph_extents_t in the format -+ * `<x_bearing,y_bearing,width,height>` - * -- * -+ * ## json -+ * TODO. - * - * Return value: -+ * The number of serialized items. - * -- * Since: 1.0 -+ * Since: 0.9.7 - **/ - unsigned int - hb_buffer_serialize_glyphs (hb_buffer_t *buffer, -@@ -248,8 +300,8 @@ - unsigned int end, - char *buf, - unsigned int buf_size, -- unsigned int *buf_consumed, /* May be NULL */ -- hb_font_t *font, /* May be NULL */ -+ unsigned int *buf_consumed, -+ hb_font_t *font, - hb_buffer_serialize_format_t format, - hb_buffer_serialize_flags_t flags) - { -@@ -263,6 +315,9 @@ - assert ((!buffer->len && buffer->content_type == HB_BUFFER_CONTENT_TYPE_INVALID) || - buffer->content_type == HB_BUFFER_CONTENT_TYPE_GLYPHS); - -+ if (!buffer->have_positions) -+ flags |= HB_BUFFER_SERIALIZE_FLAG_NO_POSITIONS; -+ - if (unlikely (start == end)) - return 0; - -@@ -336,7 +391,7 @@ - - /** - * hb_buffer_deserialize_glyphs: -- * @buffer: a buffer. -+ * @buffer: an #hb_buffer_t buffer. - * @buf: (array length=buf_len): - * @buf_len: - * @end_ptr: (out): -@@ -347,7 +402,7 @@ - * - * Return value: - * -- * Since: 1.0 -+ * Since: 0.9.7 - **/ - hb_bool_t - hb_buffer_deserialize_glyphs (hb_buffer_t *buffer, -diff -uN gfx/harfbuzz/src_old/hb-common.cc gfx/harfbuzz/src/hb-common.cc ---- gfx/harfbuzz/src_old/hb-common.cc 2016-05-10 22:26:56.000000000 +0200 -+++ gfx/harfbuzz/src/hb-common.cc 2016-06-05 23:48:32.151280204 +0200 -@@ -57,14 +57,14 @@ - - /** - * hb_tag_from_string: -- * @str: (array length=len): -+ * @str: (array length=len) (element-type uint8_t): - * @len: - * - * - * - * Return value: - * -- * Since: 1.0 -+ * Since: 0.9.2 - **/ - hb_tag_t - hb_tag_from_string (const char *str, int len) -@@ -92,7 +92,7 @@ - * - * - * -- * Since: 1.0 -+ * Since: 0.9.5 - **/ - void - hb_tag_to_string (hb_tag_t tag, char *buf) -@@ -115,14 +115,14 @@ - - /** - * hb_direction_from_string: -- * @str: (array length=len): -+ * @str: (array length=len) (element-type uint8_t): - * @len: - * - * - * - * Return value: - * -- * Since: 1.0 -+ * Since: 0.9.2 - **/ - hb_direction_t - hb_direction_from_string (const char *str, int len) -@@ -149,7 +149,7 @@ - * - * Return value: (transfer none): - * -- * Since: 1.0 -+ * Since: 0.9.2 - **/ - const char * - hb_direction_to_string (hb_direction_t direction) -@@ -179,7 +179,7 @@ - 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', 0, 0, 0, 0, 0 - }; - --static hb_bool_t -+static bool - lang_equal (hb_language_t v1, - const void *v2) - { -@@ -235,7 +235,7 @@ - static hb_language_item_t *langs; - - #ifdef HB_USE_ATEXIT --static inline -+static - void free_langs (void) - { - while (langs) { -@@ -265,6 +265,7 @@ - *lang = key; - - if (!hb_atomic_ptr_cmpexch (&langs, first_lang, lang)) { -+ lang->finish (); - free (lang); - goto retry; - } -@@ -280,46 +281,51 @@ - - /** - * hb_language_from_string: -- * @str: (array length=len): -- * @len: -+ * @str: (array length=len) (element-type uint8_t): a string representing -+ * ISO 639 language code -+ * @len: length of the @str, or -1 if it is %NULL-terminated. - * -- * -+ * Converts @str representing an ISO 639 language code to the corresponding -+ * #hb_language_t. - * -- * Return value: -+ * Return value: (transfer none): -+ * The #hb_language_t corresponding to the ISO 639 language code. - * -- * Since: 1.0 -+ * Since: 0.9.2 - **/ - hb_language_t - hb_language_from_string (const char *str, int len) - { -- char strbuf[64]; -- - if (!str || !len || !*str) - return HB_LANGUAGE_INVALID; - -+ hb_language_item_t *item = NULL; - if (len >= 0) - { - /* NUL-terminate it. */ -+ char strbuf[64]; - len = MIN (len, (int) sizeof (strbuf) - 1); - memcpy (strbuf, str, len); - strbuf[len] = '\0'; -- str = strbuf; -+ item = lang_find_or_insert (strbuf); - } -- -- hb_language_item_t *item = lang_find_or_insert (str); -+ else -+ item = lang_find_or_insert (str); - - return likely (item) ? item->lang : HB_LANGUAGE_INVALID; - } - - /** - * hb_language_to_string: -- * @language: -+ * @language: an #hb_language_t to convert. - * -- * -+ * See hb_language_from_string(). - * -- * Return value: (transfer none): -+ * Return value: (transfer none): -+ * A %NULL-terminated string representing the @language. Must not be freed by -+ * the caller. - * -- * Since: 1.0 -+ * Since: 0.9.2 - **/ - const char * - hb_language_to_string (hb_language_t language) -@@ -333,9 +339,9 @@ - * - * - * -- * Return value: -+ * Return value: (transfer none): - * -- * Since: 1.0 -+ * Since: 0.9.2 - **/ - hb_language_t - hb_language_get_default (void) -@@ -345,7 +351,7 @@ - hb_language_t language = (hb_language_t) hb_atomic_ptr_get (&default_language); - if (unlikely (language == HB_LANGUAGE_INVALID)) { - language = hb_language_from_string (setlocale (LC_CTYPE, NULL), -1); -- hb_atomic_ptr_cmpexch (&default_language, HB_LANGUAGE_INVALID, language); -+ (void) hb_atomic_ptr_cmpexch (&default_language, HB_LANGUAGE_INVALID, language); - } - - return default_language; -@@ -356,13 +362,14 @@ - - /** - * hb_script_from_iso15924_tag: -- * @tag: -+ * @tag: an #hb_tag_t representing an ISO 15924 tag. - * -- * -+ * Converts an ISO 15924 script tag to a corresponding #hb_script_t. - * - * Return value: -+ * An #hb_script_t corresponding to the ISO 15924 tag. - * -- * Since: 1.0 -+ * Since: 0.9.2 - **/ - hb_script_t - hb_script_from_iso15924_tag (hb_tag_t tag) -@@ -400,30 +407,35 @@ - - /** - * hb_script_from_string: -- * @s: (array length=len): -- * @len: -- * -- * -+ * @str: (array length=len) (element-type uint8_t): a string representing an -+ * ISO 15924 tag. -+ * @len: length of the @str, or -1 if it is %NULL-terminated. -+ * -+ * Converts a string @str representing an ISO 15924 script tag to a -+ * corresponding #hb_script_t. Shorthand for hb_tag_from_string() then -+ * hb_script_from_iso15924_tag(). - * - * Return value: -+ * An #hb_script_t corresponding to the ISO 15924 tag. - * -- * Since: 1.0 -+ * Since: 0.9.2 - **/ - hb_script_t --hb_script_from_string (const char *s, int len) -+hb_script_from_string (const char *str, int len) - { -- return hb_script_from_iso15924_tag (hb_tag_from_string (s, len)); -+ return hb_script_from_iso15924_tag (hb_tag_from_string (str, len)); - } - - /** - * hb_script_to_iso15924_tag: -- * @script: -+ * @script: an #hb_script_ to convert. - * -- * -+ * See hb_script_from_iso15924_tag(). - * -- * Return value: -+ * Return value: -+ * An #hb_tag_t representing an ISO 15924 script tag. - * -- * Since: 1.0 -+ * Since: 0.9.2 - **/ - hb_tag_t - hb_script_to_iso15924_tag (hb_script_t script) -@@ -439,7 +451,7 @@ - * - * Return value: - * -- * Since: 1.0 -+ * Since: 0.9.2 - **/ - hb_direction_t - hb_script_get_horizontal_direction (hb_script_t script) -@@ -492,6 +504,9 @@ - case HB_SCRIPT_PALMYRENE: - case HB_SCRIPT_PSALTER_PAHLAVI: - -+ /* Unicode-8.0 additions */ -+ case HB_SCRIPT_OLD_HUNGARIAN: -+ - return HB_DIRECTION_RTL; - } - -@@ -517,7 +532,7 @@ - } - } - hb_user_data_item_t item = {key, data, destroy}; -- bool ret = !!items.replace_or_insert (item, lock, replace); -+ bool ret = !!items.replace_or_insert (item, lock, (bool) replace); - - return ret; - } -@@ -541,7 +556,7 @@ - * - * Returns library version as three integer components. - * -- * Since: 1.0 -+ * Since: 0.9.2 - **/ - void - hb_version (unsigned int *major, -@@ -560,7 +575,7 @@ - * - * Return value: library version string. - * -- * Since: 1.0 -+ * Since: 0.9.2 - **/ - const char * - hb_version_string (void) -@@ -578,7 +593,7 @@ - * - * Return value: - * -- * Since: 1.0 -+ * Since: 0.9.30 - **/ - hb_bool_t - hb_version_atleast (unsigned int major, -diff -uN gfx/harfbuzz/src_old/hb-common.h gfx/harfbuzz/src/hb-common.h ---- gfx/harfbuzz/src_old/hb-common.h 2016-05-10 22:26:56.000000000 +0200 -+++ gfx/harfbuzz/src/hb-common.h 2016-06-05 23:48:33.399273253 +0200 -@@ -98,16 +98,22 @@ - #define HB_TAG_MAX_SIGNED HB_TAG(0x7f,0xff,0xff,0xff) - - /* len=-1 means str is NUL-terminated. */ --hb_tag_t -+HB_EXTERN hb_tag_t - hb_tag_from_string (const char *str, int len); - - /* buf should have 4 bytes. */ --void -+HB_EXTERN void - hb_tag_to_string (hb_tag_t tag, char *buf); - - --/* hb_direction_t */ -- -+/** -+ * hb_direction_t: -+ * @HB_DIRECTION_INVALID: Initial, unset direction. -+ * @HB_DIRECTION_LTR: Text is set horizontally from left to right. -+ * @HB_DIRECTION_RTL: Text is set horizontally from right to left. -+ * @HB_DIRECTION_TTB: Text is set vertically from top to bottom. -+ * @HB_DIRECTION_BTT: Text is set vertically from bottom to top. -+ */ - typedef enum { - HB_DIRECTION_INVALID = 0, - HB_DIRECTION_LTR = 4, -@@ -117,10 +123,10 @@ - } hb_direction_t; - - /* len=-1 means str is NUL-terminated */ --hb_direction_t -+HB_EXTERN hb_direction_t - hb_direction_from_string (const char *str, int len); - --const char * -+HB_EXTERN const char * - hb_direction_to_string (hb_direction_t direction); - - #define HB_DIRECTION_IS_VALID(dir) ((((unsigned int) (dir)) & ~3U) == 4) -@@ -136,16 +142,15 @@ - - typedef const struct hb_language_impl_t *hb_language_t; - --/* len=-1 means str is NUL-terminated */ --hb_language_t -+HB_EXTERN hb_language_t - hb_language_from_string (const char *str, int len); - --const char * -+HB_EXTERN const char * - hb_language_to_string (hb_language_t language); - - #define HB_LANGUAGE_INVALID ((hb_language_t) NULL) - --hb_language_t -+HB_EXTERN hb_language_t - hb_language_get_default (void); - - -@@ -272,6 +277,9 @@ - /*6.1*/ HB_SCRIPT_SORA_SOMPENG = HB_TAG ('S','o','r','a'), - /*6.1*/ HB_SCRIPT_TAKRI = HB_TAG ('T','a','k','r'), - -+ /* -+ * Since: 0.9.30 -+ */ - /*7.0*/ HB_SCRIPT_BASSA_VAH = HB_TAG ('B','a','s','s'), - /*7.0*/ HB_SCRIPT_CAUCASIAN_ALBANIAN = HB_TAG ('A','g','h','b'), - /*7.0*/ HB_SCRIPT_DUPLOYAN = HB_TAG ('D','u','p','l'), -@@ -296,6 +304,13 @@ - /*7.0*/ HB_SCRIPT_TIRHUTA = HB_TAG ('T','i','r','h'), - /*7.0*/ HB_SCRIPT_WARANG_CITI = HB_TAG ('W','a','r','a'), - -+ /*8.0*/ HB_SCRIPT_AHOM = HB_TAG ('A','h','o','m'), -+ /*8.0*/ HB_SCRIPT_ANATOLIAN_HIEROGLYPHS = HB_TAG ('H','l','u','w'), -+ /*8.0*/ HB_SCRIPT_HATRAN = HB_TAG ('H','a','t','r'), -+ /*8.0*/ HB_SCRIPT_MULTANI = HB_TAG ('M','u','l','t'), -+ /*8.0*/ HB_SCRIPT_OLD_HUNGARIAN = HB_TAG ('H','u','n','g'), -+ /*8.0*/ HB_SCRIPT_SIGNWRITING = HB_TAG ('S','g','n','w'), -+ - /* No script set. */ - HB_SCRIPT_INVALID = HB_TAG_NONE, - -@@ -314,18 +329,16 @@ - - /* Script functions */ - --hb_script_t -+HB_EXTERN hb_script_t - hb_script_from_iso15924_tag (hb_tag_t tag); - --/* sugar for tag_from_string() then script_from_iso15924_tag */ --/* len=-1 means s is NUL-terminated */ --hb_script_t --hb_script_from_string (const char *s, int len); -+HB_EXTERN hb_script_t -+hb_script_from_string (const char *str, int len); - --hb_tag_t -+HB_EXTERN hb_tag_t - hb_script_to_iso15924_tag (hb_script_t script); - --hb_direction_t -+HB_EXTERN hb_direction_t - hb_script_get_horizontal_direction (hb_script_t script); - - -diff -uN gfx/harfbuzz/src_old/hb-coretext.cc gfx/harfbuzz/src/hb-coretext.cc ---- gfx/harfbuzz/src_old/hb-coretext.cc 2016-05-10 22:26:56.000000000 +0200 -+++ gfx/harfbuzz/src/hb-coretext.cc 2016-06-05 23:48:34.938264688 +0200 -@@ -22,7 +22,7 @@ - * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO - * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. - * -- * GNU Author(s): Jonathan Kew -+ * Mozilla Author(s): Jonathan Kew - * Google Author(s): Behdad Esfahbod - */ - -@@ -125,6 +125,9 @@ - CFRelease (data); - } - -+/* -+ * Since: 0.9.10 -+ */ - CGFontRef - hb_coretext_face_get_cg_font (hb_face_t *face) - { -@@ -140,6 +143,7 @@ - - struct hb_coretext_shaper_font_data_t { - CTFontRef ct_font; -+ CGFloat x_mult, y_mult; /* From CT space to HB space. */ - }; - - hb_coretext_shaper_font_data_t * -@@ -154,7 +158,55 @@ - hb_face_t *face = font->face; - hb_coretext_shaper_face_data_t *face_data = HB_SHAPER_DATA_GET (face); - -- data->ct_font = CTFontCreateWithGraphicsFont (face_data, font->y_scale, NULL, NULL); -+ /* Choose a CoreText font size and calculate multipliers to convert to HarfBuzz space. */ -+ /* TODO: use upem instead of 36? */ -+ CGFloat font_size = 36.; /* 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 = (CGFloat) font->x_scale / font_size; -+ data->y_mult = (CGFloat) font->y_scale / font_size; -+ data->ct_font = CTFontCreateWithGraphicsFont (face_data, font_size, NULL, NULL); -+ if (unlikely (!data->ct_font)) { -+ DEBUG_MSG (CORETEXT, font, "Font CTFontCreateWithGraphicsFont() failed"); -+ free (data); -+ return NULL; -+ } -+ -+ /* Create font copy with cascade list that has LastResort first; this speeds up CoreText -+ * font fallback which we don't need anyway. */ -+ { -+ // TODO Handle allocation failures? -+ CTFontDescriptorRef last_resort = CTFontDescriptorCreateWithNameAndSize(CFSTR("LastResort"), 0); -+ CFArrayRef cascade_list = CFArrayCreate (kCFAllocatorDefault, -+ (const void **) &last_resort, -+ 1, -+ &kCFTypeArrayCallBacks); -+ CFRelease (last_resort); -+ CFDictionaryRef attributes = CFDictionaryCreate (kCFAllocatorDefault, -+ (const void **) &kCTFontCascadeListAttribute, -+ (const void **) &cascade_list, -+ 1, -+ &kCFTypeDictionaryKeyCallBacks, -+ &kCFTypeDictionaryValueCallBacks); -+ CFRelease (cascade_list); -+ -+ CTFontDescriptorRef new_font_desc = CTFontDescriptorCreateWithAttributes (attributes); -+ CFRelease (attributes); -+ -+ CTFontRef new_ct_font = CTFontCreateCopyWithAttributes (data->ct_font, 0.0, NULL, new_font_desc); -+ if (new_ct_font) -+ { -+ CFRelease (data->ct_font); -+ data->ct_font = new_ct_font; -+ } -+ else -+ DEBUG_MSG (CORETEXT, font, "Font copy with empty cascade list failed"); -+ } -+ - if (unlikely (!data->ct_font)) { - DEBUG_MSG (CORETEXT, font, "Font CTFontCreateWithGraphicsFont() failed"); - free (data); -@@ -678,7 +730,6 @@ - scratch += old_scratch_used; - scratch_size -= old_scratch_used; - } --retry: - { - string_ref = CFStringCreateWithCharactersNoCopy (NULL, - pchars, chars_len, -@@ -776,6 +827,18 @@ - - buffer->len = 0; - uint32_t status_and = ~0, status_or = 0; -+ double advances_so_far = 0; -+ /* For right-to-left runs, CoreText returns the glyphs positioned such that -+ * any trailing whitespace is to the left of (0,0). Adjust coordinate system -+ * to fix for that. Test with any RTL string with trailing spaces. -+ * https://code.google.com/p/chromium/issues/detail?id=469028 -+ */ -+ if (HB_DIRECTION_IS_BACKWARD (buffer->props.direction)) -+ { -+ advances_so_far -= CTLineGetTrailingWhitespaceWidth (line); -+ if (HB_DIRECTION_IS_VERTICAL (buffer->props.direction)) -+ advances_so_far = -advances_so_far; -+ } - - const CFRange range_all = CFRangeMake (0, 0); - -@@ -786,6 +849,10 @@ - status_or |= run_status; - status_and &= run_status; - DEBUG_MSG (CORETEXT, run, "CTRunStatus: %x", run_status); -+ double run_advance = CTRunGetTypographicBounds (run, range_all, NULL, NULL, NULL); -+ if (HB_DIRECTION_IS_VERTICAL (buffer->props.direction)) -+ run_advance = -run_advance; -+ DEBUG_MSG (CORETEXT, run, "Run advance: %g", run_advance); - - /* CoreText does automatic font fallback (AKA "cascading") for characters - * not supported by the requested font, and provides no way to turn it off, -@@ -817,11 +884,9 @@ - * However, even that wouldn't work if we were passed in the CGFont to - * begin with. - * -- * Webkit uses a slightly different approach: it installs LastResort -- * as fallback chain, and then checks PS name of used font against -- * LastResort. That one is safe for any font except for LastResort, -- * as opposed to ours, which can fail if we are using any uninstalled -- * font that has the same name as an installed font. -+ * We might switch to checking PS name against "LastResort". That would -+ * be safe for all fonts except for those named "Last Resort". Might be -+ * better than what we have right now. - * - * See: http://github.com/behdad/harfbuzz/pull/36 - */ -@@ -860,8 +925,14 @@ - goto resize_and_retry; - hb_glyph_info_t *info = buffer->info + buffer->len; - -- CGGlyph notdef = 0; -- double advance = CTFontGetAdvancesForGlyphs (font_data->ct_font, kCTFontHorizontalOrientation, ¬def, NULL, 1); -+ hb_codepoint_t notdef = 0; -+ hb_direction_t dir = buffer->props.direction; -+ hb_position_t x_advance, y_advance, x_offset, y_offset; -+ hb_font_get_glyph_advance_for_direction (font, notdef, dir, &x_advance, &y_advance); -+ hb_font_get_glyph_origin_for_direction (font, notdef, dir, &x_offset, &y_offset); -+ hb_position_t advance = x_advance + y_advance; -+ x_offset = -x_offset; -+ y_offset = -y_offset; - - unsigned int old_len = buffer->len; - for (CFIndex j = range.location; j < range.location + range.length; j++) -@@ -875,19 +946,22 @@ - * for this one. */ - continue; - } -+ if (buffer->unicode->is_default_ignorable (ch)) -+ continue; - - info->codepoint = notdef; - info->cluster = log_clusters[j]; - - info->mask = advance; -- info->var1.u32 = 0; -- info->var2.u32 = 0; -+ info->var1.i32 = x_offset; -+ info->var2.i32 = y_offset; - - info++; - buffer->len++; - } - if (HB_DIRECTION_IS_BACKWARD (buffer->props.direction)) - buffer->reverse_range (old_len, buffer->len); -+ advances_so_far += run_advance; - continue; - } - } -@@ -917,7 +991,7 @@ - scratch_size = scratch_size_saved; \ - scratch = scratch_saved; - -- { -+ { /* Setup glyphs */ - SCRATCH_SAVE(); - const CGGlyph* glyphs = USE_PTR ? CTRunGetGlyphsPtr (run) : NULL; - if (!glyphs) { -@@ -941,6 +1015,11 @@ - SCRATCH_RESTORE(); - } - { -+ /* Setup positions. -+ * Note that CoreText does not return advances for glyphs. As such, -+ * for all but last glyph, we use the delta position to next glyph as -+ * advance (in the advance direction only), and for last glyph we set -+ * whatever is needed to make the whole run's advance add up. */ - SCRATCH_SAVE(); - const CGPoint* positions = USE_PTR ? CTRunGetPositionsPtr (run) : NULL; - if (!positions) { -@@ -948,33 +1027,42 @@ - CTRunGetPositions (run, range_all, position_buf); - positions = position_buf; - } -- double run_advance = CTRunGetTypographicBounds (run, range_all, NULL, NULL, NULL); -- DEBUG_MSG (CORETEXT, run, "Run advance: %g", run_advance); - hb_glyph_info_t *info = run_info; -+ CGFloat x_mult = font_data->x_mult, y_mult = font_data->y_mult; - if (HB_DIRECTION_IS_HORIZONTAL (buffer->props.direction)) - { -+ hb_position_t x_offset = (positions[0].x - advances_so_far) * x_mult; - for (unsigned int j = 0; j < num_glyphs; j++) - { -- double advance = (j + 1 < num_glyphs ? positions[j + 1].x : positions[0].x + run_advance) - positions[j].x; -- info->mask = advance; -- info->var1.u32 = positions[0].x; /* Yes, zero. */ -- info->var2.u32 = positions[j].y; -+ double advance; -+ if (likely (j + 1 < num_glyphs)) -+ advance = positions[j + 1].x - positions[j].x; -+ else /* last glyph */ -+ advance = run_advance - (positions[j].x - positions[0].x); -+ info->mask = advance * x_mult; -+ info->var1.i32 = x_offset; -+ info->var2.i32 = positions[j].y * y_mult; - info++; - } - } - else - { -- run_advance = -run_advance; -+ hb_position_t y_offset = (positions[0].y - advances_so_far) * y_mult; - for (unsigned int j = 0; j < num_glyphs; j++) - { -- double advance = (j + 1 < num_glyphs ? positions[j + 1].y : positions[0].y + run_advance) - positions[j].y; -- info->mask = advance; -- info->var1.u32 = positions[j].x; -- info->var2.u32 = positions[0].y; /* Yes, zero. */ -+ double advance; -+ if (likely (j + 1 < num_glyphs)) -+ advance = positions[j + 1].y - positions[j].y; -+ else /* last glyph */ -+ advance = run_advance - (positions[j].y - positions[0].y); -+ info->mask = advance * y_mult; -+ info->var1.i32 = positions[j].x * x_mult; -+ info->var2.i32 = y_offset; - info++; - } - } - SCRATCH_RESTORE(); -+ advances_so_far += run_advance; - } - #undef SCRATCH_RESTORE - #undef SCRATCH_SAVE -@@ -984,10 +1072,20 @@ - buffer->len += num_glyphs; - } - -- /* Make sure all runs had the expected direction. */ -- bool backward = HB_DIRECTION_IS_BACKWARD (buffer->props.direction); -- assert (bool (status_and & kCTRunStatusRightToLeft) == backward); -- assert (bool (status_or & kCTRunStatusRightToLeft) == backward); -+ /* Mac OS 10.6 doesn't have kCTTypesetterOptionForcedEmbeddingLevel, -+ * or if it does, it doesn't resepct it. So we get runs with wrong -+ * directions. As such, disable the assert... It wouldn't crash, but -+ * cursoring will be off... -+ * -+ * http://crbug.com/419769 -+ */ -+ if (0) -+ { -+ /* Make sure all runs had the expected direction. */ -+ bool backward = HB_DIRECTION_IS_BACKWARD (buffer->props.direction); -+ assert (bool (status_and & kCTRunStatusRightToLeft) == backward); -+ assert (bool (status_or & kCTRunStatusRightToLeft) == backward); -+ } - - buffer->clear_positions (); - -@@ -998,16 +1096,16 @@ - for (unsigned int i = 0; i < count; i++) - { - pos->x_advance = info->mask; -- pos->x_offset = info->var1.u32; -- pos->y_offset = info->var2.u32; -+ pos->x_offset = info->var1.i32; -+ pos->y_offset = info->var2.i32; - info++, pos++; - } - else - for (unsigned int i = 0; i < count; i++) - { - pos->y_advance = info->mask; -- pos->x_offset = info->var1.u32; -- pos->y_offset = info->var2.u32; -+ pos->x_offset = info->var1.i32; -+ pos->y_offset = info->var2.i32; - info++, pos++; - } - -@@ -1065,10 +1163,6 @@ - * AAT shaper - */ - --HB_SHAPER_DATA_ENSURE_DECLARE(coretext_aat, face) --HB_SHAPER_DATA_ENSURE_DECLARE(coretext_aat, font) -- -- - /* - * shaper face data - */ -diff -uN gfx/harfbuzz/src_old/hb-coretext.h gfx/harfbuzz/src/hb-coretext.h ---- gfx/harfbuzz/src_old/hb-coretext.h 2016-05-10 22:26:56.000000000 +0200 -+++ gfx/harfbuzz/src/hb-coretext.h 2016-06-05 23:48:36.098258246 +0200 -@@ -21,7 +21,7 @@ - * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO - * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. - * -- * GNU Author(s): Jonathan Kew -+ * Mozilla Author(s): Jonathan Kew - */ - - #ifndef HB_CORETEXT_H -@@ -44,14 +44,14 @@ - #define HB_CORETEXT_TAG_MORX HB_TAG('m','o','r','x') - - --hb_face_t * -+HB_EXTERN hb_face_t * - hb_coretext_face_create (CGFontRef cg_font); - - --CGFontRef -+HB_EXTERN CGFontRef - hb_coretext_face_get_cg_font (hb_face_t *face); - --CTFontRef -+HB_EXTERN CTFontRef - hb_coretext_font_get_ct_font (hb_font_t *font); - - -diff -uN gfx/harfbuzz/src_old/hb-directwrite.cc gfx/harfbuzz/src/hb-directwrite.cc ---- gfx/harfbuzz/src_old/hb-directwrite.cc 1970-01-01 01:00:00.000000000 +0100 -+++ gfx/harfbuzz/src/hb-directwrite.cc 2016-06-05 23:48:38.757243479 +0200 -@@ -0,0 +1,827 @@ -+/* -+ * 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. -+ */ -+ -+#define HB_SHAPER directwrite -+#include "hb-shaper-impl-private.hh" -+ -+#include <dwrite.h> -+ -+#include "hb-directwrite.h" -+ -+#include "hb-open-file-private.hh" -+#include "hb-ot-name-table.hh" -+#include "hb-ot-tag.h" -+ -+ -+#ifndef HB_DEBUG_DIRECTWRITE -+#define HB_DEBUG_DIRECTWRITE (HB_DEBUG+0) -+#endif -+ -+HB_SHAPER_DATA_ENSURE_DECLARE(directwrite, face) -+HB_SHAPER_DATA_ENSURE_DECLARE(directwrite, font) -+ -+/* -+* shaper face data -+*/ -+ -+struct hb_directwrite_shaper_face_data_t { -+ HANDLE fh; -+ 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); -+ ASSERT_STATIC (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 NULL; -+ } -+ -+ 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 NULL; -+ } -+ } -+ -+ /* 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, NULL, free); -+} -+ -+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 *)calloc(1, sizeof (hb_directwrite_shaper_face_data_t)); -+ if (unlikely (!data)) -+ return NULL; -+ -+ hb_blob_t *blob = hb_face_reference_blob (face); -+ if (unlikely (!hb_blob_get_length (blob))) -+ DEBUG_MSG(DIRECTWRITE, face, "Face has empty blob"); -+ -+ blob = _hb_rename_font (blob, data->face_name); -+ if (unlikely (!blob)) -+ { -+ free(data); -+ return NULL; -+ } -+ -+ DWORD num_fonts_installed; -+ data->fh = AddFontMemResourceEx ((void *)hb_blob_get_data(blob, NULL), -+ hb_blob_get_length (blob), -+ 0, &num_fonts_installed); -+ if (unlikely (!data->fh)) -+ { -+ DEBUG_MSG (DIRECTWRITE, face, "Face AddFontMemResourceEx() failed"); -+ free (data); -+ return NULL; -+ } -+ -+ return data; -+} -+ -+void -+_hb_directwrite_shaper_face_data_destroy(hb_directwrite_shaper_face_data_t *data) -+{ -+ RemoveFontMemResourceEx(data->fh); -+ free(data); -+} -+ -+ -+/* -+ * shaper font data -+ */ -+ -+struct hb_directwrite_shaper_font_data_t { -+ HDC hdc; -+ LOGFONTW log_font; -+ HFONT hfont; -+}; -+ -+static bool -+populate_log_font (LOGFONTW *lf, -+ hb_font_t *font) -+{ -+ memset (lf, 0, sizeof (*lf)); -+ lf->lfHeight = -font->y_scale; -+ lf->lfCharSet = DEFAULT_CHARSET; -+ -+ hb_face_t *face = font->face; -+ hb_directwrite_shaper_face_data_t *face_data = HB_SHAPER_DATA_GET (face); -+ -+ memcpy (lf->lfFaceName, face_data->face_name, sizeof (lf->lfFaceName)); -+ -+ return true; -+} -+ -+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 NULL; -+ -+ hb_directwrite_shaper_font_data_t *data = (hb_directwrite_shaper_font_data_t *) calloc (1, sizeof (hb_directwrite_shaper_font_data_t)); -+ if (unlikely (!data)) -+ return NULL; -+ -+ data->hdc = GetDC (NULL); -+ -+ if (unlikely (!populate_log_font (&data->log_font, font))) { -+ DEBUG_MSG (DIRECTWRITE, font, "Font populate_log_font() failed"); -+ _hb_directwrite_shaper_font_data_destroy (data); -+ return NULL; -+ } -+ -+ data->hfont = CreateFontIndirectW (&data->log_font); -+ if (unlikely (!data->hfont)) { -+ DEBUG_MSG (DIRECTWRITE, font, "Font CreateFontIndirectW() failed"); -+ _hb_directwrite_shaper_font_data_destroy (data); -+ return NULL; -+ } -+ -+ if (!SelectObject (data->hdc, data->hfont)) { -+ DEBUG_MSG (DIRECTWRITE, font, "Font SelectObject() failed"); -+ _hb_directwrite_shaper_font_data_destroy (data); -+ return NULL; -+ } -+ -+ return data; -+} -+ -+void -+_hb_directwrite_shaper_font_data_destroy (hb_directwrite_shaper_font_data_t *data) -+{ -+ if (data->hdc) -+ ReleaseDC (NULL, data->hdc); -+ if (data->hfont) -+ DeleteObject (data->hfont); -+ free (data); -+} -+ -+LOGFONTW * -+hb_directwrite_font_get_logfontw (hb_font_t *font) -+{ -+ if (unlikely (!hb_directwrite_shaper_font_data_ensure (font))) return NULL; -+ hb_directwrite_shaper_font_data_t *font_data = HB_SHAPER_DATA_GET (font); -+ return &font_data->log_font; -+} -+ -+HFONT -+hb_directwrite_font_get_hfont (hb_font_t *font) -+{ -+ if (unlikely (!hb_directwrite_shaper_font_data_ensure (font))) return NULL; -+ hb_directwrite_shaper_font_data_t *font_data = HB_SHAPER_DATA_GET (font); -+ return font_data->hfont; -+} -+ -+ -+/* -+ * 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) -+{ -+ 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 here 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 mTextStart; // starting text position of this run -+ UINT32 mTextLength; // number of contiguous code units covered -+ UINT32 mGlyphStart; // starting glyph in the glyphs array -+ UINT32 mGlyphCount; // number of glyphs associated with this run of -+ // text -+ DWRITE_SCRIPT_ANALYSIS mScript; -+ UINT8 mBidiLevel; -+ bool mIsSideways; -+ -+ inline bool ContainsTextPosition(UINT32 aTextPosition) const -+ { -+ return aTextPosition >= mTextStart -+ && aTextPosition < mTextStart + mTextLength; -+ } -+ -+ Run *nextRun; -+ }; -+ -+public: -+ TextAnalysis(const wchar_t* text, -+ UINT32 textLength, -+ const wchar_t* localeName, -+ DWRITE_READING_DIRECTION readingDirection) -+ : mText(text) -+ , mTextLength(textLength) -+ , mLocaleName(localeName) -+ , mReadingDirection(readingDirection) -+ , mCurrentRun(NULL) { }; -+ -+ ~TextAnalysis() { -+ // delete runs, except mRunHead which is part of the TextAnalysis object -+ for (Run *run = mRunHead.nextRun; run;) { -+ Run *origRun = run; -+ run = run->nextRun; -+ delete 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 = NULL; -+ 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 textPosition, -+ OUT WCHAR const** textString, -+ OUT UINT32* textLength) -+ { -+ if (textPosition >= mTextLength) { -+ // No text at this position, valid query though. -+ *textString = NULL; -+ *textLength = 0; -+ } -+ else { -+ *textString = mText + textPosition; -+ *textLength = mTextLength - textPosition; -+ } -+ return S_OK; -+ } -+ -+ IFACEMETHODIMP GetTextBeforePosition(UINT32 textPosition, -+ OUT WCHAR const** textString, -+ OUT UINT32* 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 thouh. -+ *textString = NULL; -+ *textLength = 0; -+ } -+ else { -+ *textString = mText; -+ *textLength = textPosition; -+ } -+ return S_OK; -+ } -+ -+ IFACEMETHODIMP_(DWRITE_READING_DIRECTION) -+ GetParagraphReadingDirection() { return mReadingDirection; } -+ -+ IFACEMETHODIMP GetLocaleName(UINT32 textPosition, -+ UINT32* textLength, -+ WCHAR const** localeName) { -+ return S_OK; -+ } -+ -+ IFACEMETHODIMP -+ GetNumberSubstitution(UINT32 textPosition, -+ OUT UINT32* textLength, -+ OUT IDWriteNumberSubstitution** numberSubstitution) -+ { -+ // We do not support number substitution. -+ *numberSubstitution = NULL; -+ *textLength = mTextLength - textPosition; -+ -+ return S_OK; -+ } -+ -+ // IDWriteTextAnalysisSink implementation -+ -+ IFACEMETHODIMP -+ SetScriptAnalysis(UINT32 textPosition, -+ UINT32 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 textPosition, -+ UINT32 textLength, -+ const DWRITE_LINE_BREAKPOINT* lineBreakpoints) { return S_OK; } -+ -+ IFACEMETHODIMP SetBidiLevel(UINT32 textPosition, -+ UINT32 textLength, -+ UINT8 explicitLevel, -+ UINT8 resolvedLevel) { return S_OK; } -+ -+ IFACEMETHODIMP -+ SetNumberSubstitution(UINT32 textPosition, -+ UINT32 textLength, -+ IDWriteNumberSubstitution* numberSubstitution) { return S_OK; } -+ -+protected: -+ Run *FetchNextRun(IN OUT UINT32* 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 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 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 = new 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 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 mTextLength; -+ const WCHAR* mText; -+ const WCHAR* mLocaleName; -+ DWRITE_READING_DIRECTION mReadingDirection; -+ -+ // Current processing state. -+ Run *mCurrentRun; -+ -+ // Output is a list of runs starting here -+ Run mRunHead; -+}; -+ -+ -+/* -+ * shaper -+ */ -+ -+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) -+{ -+ 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); -+ -+ // factory probably should be cached -+ IDWriteFactory* dwriteFactory; -+ DWriteCreateFactory( -+ DWRITE_FACTORY_TYPE_SHARED, -+ __uuidof(IDWriteFactory), -+ reinterpret_cast<IUnknown**>(&dwriteFactory) -+ ); -+ -+ IDWriteGdiInterop *gdiInterop; -+ dwriteFactory->GetGdiInterop (&gdiInterop); -+ IDWriteFontFace* fontFace; -+ gdiInterop->CreateFontFaceFromHdc (font_data->hdc, &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, 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) & ((1 << 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. */ -+ } -+ } -+ -+ HRESULT hr; -+ // 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 length = buffer->len; -+ -+ TextAnalysis analysis(pchars, length, NULL, readingDirection); -+ TextAnalysis::Run *runHead; -+ hr = analysis.GenerateResults(analyzer, &runHead); -+ -+ if (FAILED(hr)) { -+ //NS_WARNING("Analyzer failed to generate results."); -+ return false; -+ } -+ -+ UINT32 maxGlyphs = 3 * length / 2 + 16; -+ -+#define INITIAL_GLYPH_SIZE 400 -+ UINT16* clusters = (UINT16*)malloc(INITIAL_GLYPH_SIZE * sizeof(UINT16)); -+ UINT16* glyphs = (UINT16*)malloc(INITIAL_GLYPH_SIZE * sizeof(UINT16)); -+ DWRITE_SHAPING_TEXT_PROPERTIES* textProperties = (DWRITE_SHAPING_TEXT_PROPERTIES*) -+ malloc(INITIAL_GLYPH_SIZE * sizeof(DWRITE_SHAPING_TEXT_PROPERTIES)); -+ DWRITE_SHAPING_GLYPH_PROPERTIES* glyphProperties = (DWRITE_SHAPING_GLYPH_PROPERTIES*) -+ malloc(INITIAL_GLYPH_SIZE * sizeof(DWRITE_SHAPING_GLYPH_PROPERTIES)); -+ -+ UINT32 actualGlyphs; -+ -+ bool backward = HB_DIRECTION_IS_BACKWARD(buffer->props.direction); -+ -+ wchar_t lang[4]; -+ mbstowcs(lang, hb_language_to_string(buffer->props.language), 4); -+ hr = analyzer->GetGlyphs(pchars, length, -+ fontFace, FALSE, -+ buffer->props.direction, -+ &runHead->mScript, (const wchar_t*)lang, NULL, NULL, NULL, 0, -+ maxGlyphs, clusters, textProperties, -+ glyphs, glyphProperties, &actualGlyphs); -+ -+ if (hr == HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER)) { -+ free(clusters); -+ free(glyphs); -+ free(textProperties); -+ free(glyphProperties); -+ -+ clusters = (UINT16*)malloc(INITIAL_GLYPH_SIZE * sizeof(UINT16)); -+ glyphs = (UINT16*)malloc(INITIAL_GLYPH_SIZE * sizeof(UINT16)); -+ textProperties = (DWRITE_SHAPING_TEXT_PROPERTIES*) -+ malloc(INITIAL_GLYPH_SIZE * sizeof(DWRITE_SHAPING_TEXT_PROPERTIES)); -+ glyphProperties = (DWRITE_SHAPING_GLYPH_PROPERTIES*) -+ malloc(INITIAL_GLYPH_SIZE * sizeof(DWRITE_SHAPING_GLYPH_PROPERTIES)); -+ -+ hr = analyzer->GetGlyphs(pchars, length, -+ fontFace, FALSE, -+ buffer->props.direction, -+ &runHead->mScript, (const wchar_t*)lang, NULL, NULL, NULL, 0, -+ maxGlyphs, clusters, textProperties, -+ glyphs, glyphProperties, &actualGlyphs); -+ } -+ if (FAILED(hr)) { -+ //NS_WARNING("Analyzer failed to get glyphs."); -+ return false; -+ } -+ -+ FLOAT advances[400]; -+ DWRITE_GLYPH_OFFSET offsets[400]; -+ -+ -+ /* 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) + -+ 4 + // sizeof (SCRIPT_GLYPHPROP) + -+ sizeof (int) + -+ 8 + // sizeof (GOFFSET) + -+ sizeof (uint32_t)); -+ ALLOCATE_ARRAY(uint32_t, vis_clusters, glyphs_size); -+ -+#undef ALLOCATE_ARRAY -+ -+ hr = analyzer->GetGlyphPlacements(pchars, -+ clusters, -+ textProperties, -+ length, -+ glyphs, -+ glyphProperties, -+ actualGlyphs, -+ fontFace, -+ face->get_upem(), -+ FALSE, -+ FALSE, -+ &runHead->mScript, -+ NULL, -+ NULL, -+ NULL, -+ 0, -+ advances, -+ offsets); -+ -+ if (FAILED(hr)) { -+ //NS_WARNING("Analyzer failed to get glyph placements."); -+ return false; -+ } -+ -+ unsigned int glyphs_len = actualGlyphs; -+ -+ /* 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.u32 = offsets[i].ascenderOffset; -+ info->var2.u32 = -offsets[i].advanceOffset; -+ } -+ -+ free(clusters); -+ free(glyphs); -+ free(textProperties); -+ free(glyphProperties); -+ -+ /* Set glyph positions */ -+ buffer->clear_positions (); -+ 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 = info->mask; -+ pos->x_offset = backward ? -info->var1.u32 : info->var1.u32; -+ pos->y_offset = info->var2.u32; -+ } -+ -+ if (backward) -+ hb_buffer_reverse (buffer); -+ -+ /* Wow, done! */ -+ return true; -+} -diff -uN gfx/harfbuzz/src_old/hb-directwrite.h gfx/harfbuzz/src/hb-directwrite.h ---- gfx/harfbuzz/src_old/hb-directwrite.h 1970-01-01 01:00:00.000000000 +0100 -+++ gfx/harfbuzz/src/hb-directwrite.h 2016-06-05 23:48:40.059236276 +0200 -@@ -0,0 +1,34 @@ -+/* -+ * 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_END_DECLS -+ -+#endif /* HB_UNISCRIBE_H */ -diff -uN gfx/harfbuzz/src_old/hb-face.cc gfx/harfbuzz/src/hb-face.cc ---- gfx/harfbuzz/src_old/hb-face.cc 2016-05-10 22:26:55.000000000 +0200 -+++ gfx/harfbuzz/src/hb-face.cc 2016-06-05 23:48:42.449223049 +0200 -@@ -77,7 +77,7 @@ - * - * Return value: (transfer full) - * -- * Since: 1.0 -+ * Since: 0.9.2 - **/ - hb_face_t * - hb_face_create_for_tables (hb_reference_table_func_t reference_table_func, -@@ -113,7 +113,7 @@ - { - hb_face_for_data_closure_t *closure; - -- closure = (hb_face_for_data_closure_t *) malloc (sizeof (hb_face_for_data_closure_t)); -+ closure = (hb_face_for_data_closure_t *) calloc (1, sizeof (hb_face_for_data_closure_t)); - if (unlikely (!closure)) - return NULL; - -@@ -157,7 +157,7 @@ - * - * Return value: (transfer full): - * -- * Since: 1.0 -+ * Since: 0.9.2 - **/ - hb_face_t * - hb_face_create (hb_blob_t *blob, -@@ -165,8 +165,8 @@ - { - hb_face_t *face; - -- if (unlikely (!blob || !hb_blob_get_length (blob))) -- return hb_face_get_empty (); -+ if (unlikely (!blob)) -+ blob = hb_blob_get_empty (); - - hb_face_for_data_closure_t *closure = _hb_face_for_data_closure_create (OT::Sanitizer<OT::OpenTypeFontFile>::sanitize (hb_blob_reference (blob)), index); - -@@ -189,7 +189,7 @@ - * - * Return value: (transfer full) - * -- * Since: 1.0 -+ * Since: 0.9.2 - **/ - hb_face_t * - hb_face_get_empty (void) -@@ -206,7 +206,7 @@ - * - * Return value: - * -- * Since: 1.0 -+ * Since: 0.9.2 - **/ - hb_face_t * - hb_face_reference (hb_face_t *face) -@@ -220,7 +220,7 @@ - * - * - * -- * Since: 1.0 -+ * Since: 0.9.2 - **/ - void - hb_face_destroy (hb_face_t *face) -@@ -257,7 +257,7 @@ - * - * Return value: - * -- * Since: 1.0 -+ * Since: 0.9.2 - **/ - hb_bool_t - hb_face_set_user_data (hb_face_t *face, -@@ -278,7 +278,7 @@ - * - * Return value: (transfer none): - * -- * Since: 1.0 -+ * Since: 0.9.2 - **/ - void * - hb_face_get_user_data (hb_face_t *face, -@@ -293,7 +293,7 @@ - * - * - * -- * Since: 1.0 -+ * Since: 0.9.2 - **/ - void - hb_face_make_immutable (hb_face_t *face) -@@ -312,7 +312,7 @@ - * - * Return value: - * -- * Since: 1.0 -+ * Since: 0.9.2 - **/ - hb_bool_t - hb_face_is_immutable (hb_face_t *face) -@@ -330,7 +330,7 @@ - * - * Return value: (transfer full): - * -- * Since: 1.0 -+ * Since: 0.9.2 - **/ - hb_blob_t * - hb_face_reference_table (hb_face_t *face, -@@ -347,7 +347,7 @@ - * - * Return value: (transfer full): - * -- * Since: 1.0 -+ * Since: 0.9.2 - **/ - hb_blob_t * - hb_face_reference_blob (hb_face_t *face) -@@ -362,7 +362,7 @@ - * - * - * -- * Since: 1.0 -+ * Since: 0.9.2 - **/ - void - hb_face_set_index (hb_face_t *face, -@@ -382,7 +382,7 @@ - * - * Return value: - * -- * Since: 1.0 -+ * Since: 0.9.2 - **/ - unsigned int - hb_face_get_index (hb_face_t *face) -@@ -397,7 +397,7 @@ - * - * - * -- * Since: 1.0 -+ * Since: 0.9.2 - **/ - void - hb_face_set_upem (hb_face_t *face, -@@ -417,7 +417,7 @@ - * - * Return value: - * -- * Since: 1.0 -+ * Since: 0.9.2 - **/ - unsigned int - hb_face_get_upem (hb_face_t *face) -@@ -441,7 +441,7 @@ - * - * - * -- * Since: 1.0 -+ * Since: 0.9.7 - **/ - void - hb_face_set_glyph_count (hb_face_t *face, -@@ -461,7 +461,7 @@ - * - * Return value: - * -- * Since: 1.0 -+ * Since: 0.9.7 - **/ - unsigned int - hb_face_get_glyph_count (hb_face_t *face) -diff -uN gfx/harfbuzz/src_old/hb-face.h gfx/harfbuzz/src/hb-face.h ---- gfx/harfbuzz/src_old/hb-face.h 2016-05-10 22:26:56.000000000 +0200 -+++ gfx/harfbuzz/src/hb-face.h 2016-06-05 23:48:43.669216308 +0200 -@@ -43,28 +43,28 @@ - - typedef struct hb_face_t hb_face_t; - --hb_face_t * -+HB_EXTERN hb_face_t * - hb_face_create (hb_blob_t *blob, - unsigned int index); - - typedef hb_blob_t * (*hb_reference_table_func_t) (hb_face_t *face, hb_tag_t tag, void *user_data); - - /* calls destroy() when not needing user_data anymore */ --hb_face_t * -+HB_EXTERN hb_face_t * - hb_face_create_for_tables (hb_reference_table_func_t reference_table_func, - void *user_data, - hb_destroy_func_t destroy); - --hb_face_t * -+HB_EXTERN hb_face_t * - hb_face_get_empty (void); - --hb_face_t * -+HB_EXTERN hb_face_t * - hb_face_reference (hb_face_t *face); - --void -+HB_EXTERN void - hb_face_destroy (hb_face_t *face); - --hb_bool_t -+HB_EXTERN hb_bool_t - hb_face_set_user_data (hb_face_t *face, - hb_user_data_key_t *key, - void * data, -@@ -72,43 +72,43 @@ - hb_bool_t replace); - - --void * -+HB_EXTERN void * - hb_face_get_user_data (hb_face_t *face, - hb_user_data_key_t *key); - --void -+HB_EXTERN void - hb_face_make_immutable (hb_face_t *face); - --hb_bool_t -+HB_EXTERN hb_bool_t - hb_face_is_immutable (hb_face_t *face); - - --hb_blob_t * -+HB_EXTERN hb_blob_t * - hb_face_reference_table (hb_face_t *face, - hb_tag_t tag); - --hb_blob_t * -+HB_EXTERN hb_blob_t * - hb_face_reference_blob (hb_face_t *face); - --void -+HB_EXTERN void - hb_face_set_index (hb_face_t *face, - unsigned int index); - --unsigned int -+HB_EXTERN unsigned int - hb_face_get_index (hb_face_t *face); - --void -+HB_EXTERN void - hb_face_set_upem (hb_face_t *face, - unsigned int upem); - --unsigned int -+HB_EXTERN unsigned int - hb_face_get_upem (hb_face_t *face); - --void -+HB_EXTERN void - hb_face_set_glyph_count (hb_face_t *face, - unsigned int glyph_count); - --unsigned int -+HB_EXTERN unsigned int - hb_face_get_glyph_count (hb_face_t *face); - - -diff -uN gfx/harfbuzz/src_old/hb-fallback-shape.cc gfx/harfbuzz/src/hb-fallback-shape.cc ---- gfx/harfbuzz/src_old/hb-fallback-shape.cc 2016-05-10 22:26:56.000000000 +0200 -+++ gfx/harfbuzz/src/hb-fallback-shape.cc 2016-06-05 23:48:44.900209512 +0200 -@@ -106,7 +106,7 @@ - */ - - hb_codepoint_t space; -- bool has_space = font->get_glyph (' ', 0, &space); -+ bool has_space = (bool) font->get_glyph (' ', 0, &space); - - buffer->clear_positions (); - -diff -uN gfx/harfbuzz/src_old/hb-font.cc gfx/harfbuzz/src/hb-font.cc ---- gfx/harfbuzz/src_old/hb-font.cc 2016-05-10 22:26:56.000000000 +0200 -+++ gfx/harfbuzz/src/hb-font.cc 2016-06-05 23:48:47.920192879 +0200 -@@ -45,130 +45,224 @@ - */ - - static hb_bool_t --hb_font_get_glyph_nil (hb_font_t *font, -+hb_font_get_font_h_extents_nil (hb_font_t *font, -+ void *font_data HB_UNUSED, -+ hb_font_extents_t *metrics, -+ void *user_data HB_UNUSED) -+{ -+ memset (metrics, 0, sizeof (*metrics)); -+ return false; -+} -+static hb_bool_t -+hb_font_get_font_h_extents_parent (hb_font_t *font, -+ void *font_data HB_UNUSED, -+ hb_font_extents_t *metrics, -+ void *user_data HB_UNUSED) -+{ -+ hb_bool_t ret = font->parent->get_font_h_extents (metrics); -+ if (ret) { -+ metrics->ascender = font->parent_scale_y_distance (metrics->ascender); -+ metrics->descender = font->parent_scale_y_distance (metrics->descender); -+ metrics->line_gap = font->parent_scale_y_distance (metrics->line_gap); -+ } -+ return ret; -+} -+ -+static hb_bool_t -+hb_font_get_font_v_extents_nil (hb_font_t *font, -+ void *font_data HB_UNUSED, -+ hb_font_extents_t *metrics, -+ void *user_data HB_UNUSED) -+{ -+ memset (metrics, 0, sizeof (*metrics)); -+ return false; -+} -+static hb_bool_t -+hb_font_get_font_v_extents_parent (hb_font_t *font, -+ void *font_data HB_UNUSED, -+ hb_font_extents_t *metrics, -+ void *user_data HB_UNUSED) -+{ -+ hb_bool_t ret = font->parent->get_font_v_extents (metrics); -+ if (ret) { -+ metrics->ascender = font->parent_scale_x_distance (metrics->ascender); -+ metrics->descender = font->parent_scale_x_distance (metrics->descender); -+ metrics->line_gap = font->parent_scale_x_distance (metrics->line_gap); -+ } -+ return ret; -+} -+ -+static hb_bool_t -+hb_font_get_glyph_nil (hb_font_t *font HB_UNUSED, - void *font_data HB_UNUSED, - hb_codepoint_t unicode, - hb_codepoint_t variation_selector, - hb_codepoint_t *glyph, - void *user_data HB_UNUSED) - { -- if (font->parent) -- return font->parent->get_glyph (unicode, variation_selector, glyph); -- - *glyph = 0; - return false; - } -+static hb_bool_t -+hb_font_get_glyph_parent (hb_font_t *font, -+ void *font_data HB_UNUSED, -+ hb_codepoint_t unicode, -+ hb_codepoint_t variation_selector, -+ hb_codepoint_t *glyph, -+ void *user_data HB_UNUSED) -+{ -+ return font->parent->get_glyph (unicode, variation_selector, glyph); -+} - - static hb_position_t --hb_font_get_glyph_h_advance_nil (hb_font_t *font, -+hb_font_get_glyph_h_advance_nil (hb_font_t *font HB_UNUSED, - void *font_data HB_UNUSED, - hb_codepoint_t glyph, - void *user_data HB_UNUSED) - { -- if (font->parent) -- return font->parent_scale_x_distance (font->parent->get_glyph_h_advance (glyph)); -- - return font->x_scale; - } -+static hb_position_t -+hb_font_get_glyph_h_advance_parent (hb_font_t *font, -+ void *font_data HB_UNUSED, -+ hb_codepoint_t glyph, -+ void *user_data HB_UNUSED) -+{ -+ return font->parent_scale_x_distance (font->parent->get_glyph_h_advance (glyph)); -+} - - static hb_position_t --hb_font_get_glyph_v_advance_nil (hb_font_t *font, -+hb_font_get_glyph_v_advance_nil (hb_font_t *font HB_UNUSED, - void *font_data HB_UNUSED, - hb_codepoint_t glyph, - void *user_data HB_UNUSED) - { -- if (font->parent) -- return font->parent_scale_y_distance (font->parent->get_glyph_v_advance (glyph)); -- - return font->y_scale; - } -+static hb_position_t -+hb_font_get_glyph_v_advance_parent (hb_font_t *font, -+ void *font_data HB_UNUSED, -+ hb_codepoint_t glyph, -+ void *user_data HB_UNUSED) -+{ -+ return font->parent_scale_y_distance (font->parent->get_glyph_v_advance (glyph)); -+} - - static hb_bool_t --hb_font_get_glyph_h_origin_nil (hb_font_t *font, -+hb_font_get_glyph_h_origin_nil (hb_font_t *font HB_UNUSED, - void *font_data HB_UNUSED, - hb_codepoint_t glyph, - hb_position_t *x, - hb_position_t *y, - void *user_data HB_UNUSED) - { -- if (font->parent) { -- hb_bool_t ret = font->parent->get_glyph_h_origin (glyph, x, y); -- if (ret) -- font->parent_scale_position (x, y); -- return ret; -- } -- - *x = *y = 0; -- return false; -+ return true; -+} -+static hb_bool_t -+hb_font_get_glyph_h_origin_parent (hb_font_t *font, -+ void *font_data HB_UNUSED, -+ hb_codepoint_t glyph, -+ hb_position_t *x, -+ hb_position_t *y, -+ void *user_data HB_UNUSED) -+{ -+ hb_bool_t ret = font->parent->get_glyph_h_origin (glyph, x, y); -+ if (ret) -+ font->parent_scale_position (x, y); -+ return ret; - } - - static hb_bool_t --hb_font_get_glyph_v_origin_nil (hb_font_t *font, -+hb_font_get_glyph_v_origin_nil (hb_font_t *font HB_UNUSED, - void *font_data HB_UNUSED, - hb_codepoint_t glyph, - hb_position_t *x, - hb_position_t *y, - void *user_data HB_UNUSED) - { -- if (font->parent) { -- hb_bool_t ret = font->parent->get_glyph_v_origin (glyph, x, y); -- if (ret) -- font->parent_scale_position (x, y); -- return ret; -- } -- - *x = *y = 0; - return false; - } -+static hb_bool_t -+hb_font_get_glyph_v_origin_parent (hb_font_t *font, -+ void *font_data HB_UNUSED, -+ hb_codepoint_t glyph, -+ hb_position_t *x, -+ hb_position_t *y, -+ void *user_data HB_UNUSED) -+{ -+ hb_bool_t ret = font->parent->get_glyph_v_origin (glyph, x, y); -+ if (ret) -+ font->parent_scale_position (x, y); -+ return ret; -+} - - static hb_position_t --hb_font_get_glyph_h_kerning_nil (hb_font_t *font, -+hb_font_get_glyph_h_kerning_nil (hb_font_t *font HB_UNUSED, - void *font_data HB_UNUSED, - hb_codepoint_t left_glyph, - hb_codepoint_t right_glyph, - void *user_data HB_UNUSED) - { -- if (font->parent) -- return font->parent_scale_x_distance (font->parent->get_glyph_h_kerning (left_glyph, right_glyph)); -- - return 0; - } -+static hb_position_t -+hb_font_get_glyph_h_kerning_parent (hb_font_t *font, -+ void *font_data HB_UNUSED, -+ hb_codepoint_t left_glyph, -+ hb_codepoint_t right_glyph, -+ void *user_data HB_UNUSED) -+{ -+ return font->parent_scale_x_distance (font->parent->get_glyph_h_kerning (left_glyph, right_glyph)); -+} - - static hb_position_t --hb_font_get_glyph_v_kerning_nil (hb_font_t *font, -+hb_font_get_glyph_v_kerning_nil (hb_font_t *font HB_UNUSED, - void *font_data HB_UNUSED, - hb_codepoint_t top_glyph, - hb_codepoint_t bottom_glyph, - void *user_data HB_UNUSED) - { -- if (font->parent) -- return font->parent_scale_y_distance (font->parent->get_glyph_v_kerning (top_glyph, bottom_glyph)); -- - return 0; - } -+static hb_position_t -+hb_font_get_glyph_v_kerning_parent (hb_font_t *font, -+ void *font_data HB_UNUSED, -+ hb_codepoint_t top_glyph, -+ hb_codepoint_t bottom_glyph, -+ void *user_data HB_UNUSED) -+{ -+ return font->parent_scale_y_distance (font->parent->get_glyph_v_kerning (top_glyph, bottom_glyph)); -+} - - static hb_bool_t --hb_font_get_glyph_extents_nil (hb_font_t *font, -+hb_font_get_glyph_extents_nil (hb_font_t *font HB_UNUSED, - void *font_data HB_UNUSED, - hb_codepoint_t glyph, - hb_glyph_extents_t *extents, - void *user_data HB_UNUSED) - { -- if (font->parent) { -- hb_bool_t ret = font->parent->get_glyph_extents (glyph, extents); -- if (ret) { -- font->parent_scale_position (&extents->x_bearing, &extents->y_bearing); -- font->parent_scale_distance (&extents->width, &extents->height); -- } -- return ret; -- } -- - memset (extents, 0, sizeof (*extents)); - return false; - } -+static hb_bool_t -+hb_font_get_glyph_extents_parent (hb_font_t *font, -+ void *font_data HB_UNUSED, -+ hb_codepoint_t glyph, -+ hb_glyph_extents_t *extents, -+ void *user_data HB_UNUSED) -+{ -+ hb_bool_t ret = font->parent->get_glyph_extents (glyph, extents); -+ if (ret) { -+ font->parent_scale_position (&extents->x_bearing, &extents->y_bearing); -+ font->parent_scale_distance (&extents->width, &extents->height); -+ } -+ return ret; -+} - - static hb_bool_t --hb_font_get_glyph_contour_point_nil (hb_font_t *font, -+hb_font_get_glyph_contour_point_nil (hb_font_t *font HB_UNUSED, - void *font_data HB_UNUSED, - hb_codepoint_t glyph, - unsigned int point_index, -@@ -176,45 +270,63 @@ - hb_position_t *y, - void *user_data HB_UNUSED) - { -- if (font->parent) { -- hb_bool_t ret = font->parent->get_glyph_contour_point (glyph, point_index, x, y); -- if (ret) -- font->parent_scale_position (x, y); -- return ret; -- } -- - *x = *y = 0; - return false; - } -+static hb_bool_t -+hb_font_get_glyph_contour_point_parent (hb_font_t *font, -+ void *font_data HB_UNUSED, -+ hb_codepoint_t glyph, -+ unsigned int point_index, -+ hb_position_t *x, -+ hb_position_t *y, -+ void *user_data HB_UNUSED) -+{ -+ hb_bool_t ret = font->parent->get_glyph_contour_point (glyph, point_index, x, y); -+ if (ret) -+ font->parent_scale_position (x, y); -+ return ret; -+} - - static hb_bool_t --hb_font_get_glyph_name_nil (hb_font_t *font, -+hb_font_get_glyph_name_nil (hb_font_t *font HB_UNUSED, - void *font_data HB_UNUSED, - hb_codepoint_t glyph, - char *name, unsigned int size, - void *user_data HB_UNUSED) - { -- if (font->parent) -- return font->parent->get_glyph_name (glyph, name, size); -- - if (size) *name = '\0'; - return false; - } -+static hb_bool_t -+hb_font_get_glyph_name_parent (hb_font_t *font, -+ void *font_data HB_UNUSED, -+ hb_codepoint_t glyph, -+ char *name, unsigned int size, -+ void *user_data HB_UNUSED) -+{ -+ return font->parent->get_glyph_name (glyph, name, size); -+} - - static hb_bool_t --hb_font_get_glyph_from_name_nil (hb_font_t *font, -+hb_font_get_glyph_from_name_nil (hb_font_t *font HB_UNUSED, - void *font_data HB_UNUSED, - const char *name, int len, /* -1 means nul-terminated */ - hb_codepoint_t *glyph, - void *user_data HB_UNUSED) - { -- if (font->parent) -- return font->parent->get_glyph_from_name (name, len, glyph); -- - *glyph = 0; - return false; - } -- -+static hb_bool_t -+hb_font_get_glyph_from_name_parent (hb_font_t *font, -+ void *font_data HB_UNUSED, -+ const char *name, int len, /* -1 means nul-terminated */ -+ hb_codepoint_t *glyph, -+ void *user_data HB_UNUSED) -+{ -+ return font->parent->get_glyph_from_name (name, len, glyph); -+} - - static const hb_font_funcs_t _hb_font_funcs_nil = { - HB_OBJECT_HEADER_STATIC, -@@ -222,9 +334,44 @@ - true, /* immutable */ - - { -+#define HB_FONT_FUNC_IMPLEMENT(name) NULL, -+ HB_FONT_FUNCS_IMPLEMENT_CALLBACKS -+#undef HB_FONT_FUNC_IMPLEMENT -+ }, -+ { -+#define HB_FONT_FUNC_IMPLEMENT(name) NULL, -+ HB_FONT_FUNCS_IMPLEMENT_CALLBACKS -+#undef HB_FONT_FUNC_IMPLEMENT -+ }, -+ { -+ { - #define HB_FONT_FUNC_IMPLEMENT(name) hb_font_get_##name##_nil, -+ HB_FONT_FUNCS_IMPLEMENT_CALLBACKS -+#undef HB_FONT_FUNC_IMPLEMENT -+ } -+ } -+}; -+static const hb_font_funcs_t _hb_font_funcs_parent = { -+ HB_OBJECT_HEADER_STATIC, -+ -+ true, /* immutable */ -+ -+ { -+#define HB_FONT_FUNC_IMPLEMENT(name) NULL, -+ HB_FONT_FUNCS_IMPLEMENT_CALLBACKS -+#undef HB_FONT_FUNC_IMPLEMENT -+ }, -+ { -+#define HB_FONT_FUNC_IMPLEMENT(name) NULL, - HB_FONT_FUNCS_IMPLEMENT_CALLBACKS - #undef HB_FONT_FUNC_IMPLEMENT -+ }, -+ { -+ { -+#define HB_FONT_FUNC_IMPLEMENT(name) hb_font_get_##name##_parent, -+ HB_FONT_FUNCS_IMPLEMENT_CALLBACKS -+#undef HB_FONT_FUNC_IMPLEMENT -+ } - } - }; - -@@ -236,7 +383,7 @@ - * - * Return value: (transfer full): - * -- * Since: 1.0 -+ * Since: 0.9.2 - **/ - hb_font_funcs_t * - hb_font_funcs_create (void) -@@ -246,7 +393,7 @@ - if (!(ffuncs = hb_object_create<hb_font_funcs_t> ())) - return hb_font_funcs_get_empty (); - -- ffuncs->get = _hb_font_funcs_nil.get; -+ ffuncs->get = _hb_font_funcs_parent.get; - - return ffuncs; - } -@@ -258,12 +405,12 @@ - * - * Return value: (transfer full): - * -- * Since: 1.0 -+ * Since: 0.9.2 - **/ - hb_font_funcs_t * - hb_font_funcs_get_empty (void) - { -- return const_cast<hb_font_funcs_t *> (&_hb_font_funcs_nil); -+ return const_cast<hb_font_funcs_t *> (&_hb_font_funcs_parent); - } - - /** -@@ -274,7 +421,7 @@ - * - * Return value: - * -- * Since: 1.0 -+ * Since: 0.9.2 - **/ - hb_font_funcs_t * - hb_font_funcs_reference (hb_font_funcs_t *ffuncs) -@@ -288,7 +435,7 @@ - * - * - * -- * Since: 1.0 -+ * Since: 0.9.2 - **/ - void - hb_font_funcs_destroy (hb_font_funcs_t *ffuncs) -@@ -315,7 +462,7 @@ - * - * Return value: - * -- * Since: 1.0 -+ * Since: 0.9.2 - **/ - hb_bool_t - hb_font_funcs_set_user_data (hb_font_funcs_t *ffuncs, -@@ -336,7 +483,7 @@ - * - * Return value: (transfer none): - * -- * Since: 1.0 -+ * Since: 0.9.2 - **/ - void * - hb_font_funcs_get_user_data (hb_font_funcs_t *ffuncs, -@@ -352,7 +499,7 @@ - * - * - * -- * Since: 1.0 -+ * Since: 0.9.2 - **/ - void - hb_font_funcs_make_immutable (hb_font_funcs_t *ffuncs) -@@ -371,7 +518,7 @@ - * - * Return value: - * -- * Since: 1.0 -+ * Since: 0.9.2 - **/ - hb_bool_t - hb_font_funcs_is_immutable (hb_font_funcs_t *ffuncs) -@@ -398,11 +545,11 @@ - ffuncs->destroy.name (ffuncs->user_data.name); \ - \ - if (func) { \ -- ffuncs->get.name = func; \ -+ ffuncs->get.f.name = func; \ - ffuncs->user_data.name = user_data; \ - ffuncs->destroy.name = destroy; \ - } else { \ -- ffuncs->get.name = hb_font_get_##name##_nil; \ -+ ffuncs->get.f.name = hb_font_get_##name##_parent; \ - ffuncs->user_data.name = NULL; \ - ffuncs->destroy.name = NULL; \ - } \ -@@ -411,10 +558,53 @@ - HB_FONT_FUNCS_IMPLEMENT_CALLBACKS - #undef HB_FONT_FUNC_IMPLEMENT - -+bool -+hb_font_t::has_func (unsigned int i) -+{ -+ if (parent && parent != hb_font_get_empty () && parent->has_func (i)) -+ return true; -+ return this->klass->get.array[i] != _hb_font_funcs_parent.get.array[i]; -+} - - /* Public getters */ - - /** -+ * hb_font_get_h_extents: -+ * @font: a font. -+ * @extents: (out): -+ * -+ * -+ * -+ * Return value: -+ * -+ * Since: 1.1.3 -+ **/ -+hb_bool_t -+hb_font_get_h_extents (hb_font_t *font, -+ hb_font_extents_t *extents) -+{ -+ return font->get_font_h_extents (extents); -+} -+ -+/** -+ * hb_font_get_v_extents: -+ * @font: a font. -+ * @extents: (out): -+ * -+ * -+ * -+ * Return value: -+ * -+ * Since: 1.1.3 -+ **/ -+hb_bool_t -+hb_font_get_v_extents (hb_font_t *font, -+ hb_font_extents_t *extents) -+{ -+ return font->get_font_v_extents (extents); -+} -+ -+/** - * hb_font_get_glyph: - * @font: a font. - * @unicode: -@@ -425,7 +615,7 @@ - * - * Return value: - * -- * Since: 1.0 -+ * Since: 0.9.2 - **/ - hb_bool_t - hb_font_get_glyph (hb_font_t *font, -@@ -444,7 +634,7 @@ - * - * Return value: - * -- * Since: 1.0 -+ * Since: 0.9.2 - **/ - hb_position_t - hb_font_get_glyph_h_advance (hb_font_t *font, -@@ -462,7 +652,7 @@ - * - * Return value: - * -- * Since: 1.0 -+ * Since: 0.9.2 - **/ - hb_position_t - hb_font_get_glyph_v_advance (hb_font_t *font, -@@ -482,7 +672,7 @@ - * - * Return value: - * -- * Since: 1.0 -+ * Since: 0.9.2 - **/ - hb_bool_t - hb_font_get_glyph_h_origin (hb_font_t *font, -@@ -503,7 +693,7 @@ - * - * Return value: - * -- * Since: 1.0 -+ * Since: 0.9.2 - **/ - hb_bool_t - hb_font_get_glyph_v_origin (hb_font_t *font, -@@ -523,7 +713,7 @@ - * - * Return value: - * -- * Since: 1.0 -+ * Since: 0.9.2 - **/ - hb_position_t - hb_font_get_glyph_h_kerning (hb_font_t *font, -@@ -542,7 +732,7 @@ - * - * Return value: - * -- * Since: 1.0 -+ * Since: 0.9.2 - **/ - hb_position_t - hb_font_get_glyph_v_kerning (hb_font_t *font, -@@ -561,7 +751,7 @@ - * - * Return value: - * -- * Since: 1.0 -+ * Since: 0.9.2 - **/ - hb_bool_t - hb_font_get_glyph_extents (hb_font_t *font, -@@ -583,7 +773,7 @@ - * - * Return value: - * -- * Since: 1.0 -+ * Since: 0.9.2 - **/ - hb_bool_t - hb_font_get_glyph_contour_point (hb_font_t *font, -@@ -604,7 +794,7 @@ - * - * Return value: - * -- * Since: 1.0 -+ * Since: 0.9.2 - **/ - hb_bool_t - hb_font_get_glyph_name (hb_font_t *font, -@@ -625,7 +815,7 @@ - * - * Return value: - * -- * Since: 1.0 -+ * Since: 0.9.2 - **/ - hb_bool_t - hb_font_get_glyph_from_name (hb_font_t *font, -@@ -639,6 +829,23 @@ - /* A bit higher-level, and with fallback */ - - /** -+ * hb_font_get_extents_for_direction: -+ * @font: a font. -+ * @direction: -+ * @extents: -+ * -+ * -+ * -+ * Since: 1.1.3 -+ **/ -+void -+hb_font_get_extents_for_direction (hb_font_t *font, -+ hb_direction_t direction, -+ hb_font_extents_t *extents) -+{ -+ return font->get_extents_for_direction (direction, extents); -+} -+/** - * hb_font_get_glyph_advance_for_direction: - * @font: a font. - * @glyph: -@@ -648,7 +855,7 @@ - * - * - * -- * Since: 1.0 -+ * Since: 0.9.2 - **/ - void - hb_font_get_glyph_advance_for_direction (hb_font_t *font, -@@ -669,7 +876,7 @@ - * - * - * -- * Since: 1.0 -+ * Since: 0.9.2 - **/ - void - hb_font_get_glyph_origin_for_direction (hb_font_t *font, -@@ -690,7 +897,7 @@ - * - * - * -- * Since: 1.0 -+ * Since: 0.9.2 - **/ - void - hb_font_add_glyph_origin_for_direction (hb_font_t *font, -@@ -711,7 +918,7 @@ - * - * - * -- * Since: 1.0 -+ * Since: 0.9.2 - **/ - void - hb_font_subtract_glyph_origin_for_direction (hb_font_t *font, -@@ -733,7 +940,7 @@ - * - * - * -- * Since: 1.0 -+ * Since: 0.9.2 - **/ - void - hb_font_get_glyph_kerning_for_direction (hb_font_t *font, -@@ -755,7 +962,7 @@ - * - * Return value: - * -- * Since: 1.0 -+ * Since: 0.9.2 - **/ - hb_bool_t - hb_font_get_glyph_extents_for_origin (hb_font_t *font, -@@ -779,7 +986,7 @@ - * - * Return value: - * -- * Since: 1.0 -+ * Since: 0.9.2 - **/ - hb_bool_t - hb_font_get_glyph_contour_point_for_origin (hb_font_t *font, -@@ -800,7 +1007,7 @@ - * - * - * -- * Since: 1.0 -+ * Since: 0.9.2 - **/ - void - hb_font_glyph_to_string (hb_font_t *font, -@@ -814,7 +1021,7 @@ - /** - * hb_font_glyph_from_string: - * @font: a font. -- * @s: (array length=len): -+ * @s: (array length=len) (element-type uint8_t): - * @len: - * @glyph: (out): - * -@@ -822,7 +1029,7 @@ - * - * Return value: - * -- * Since: 1.0 -+ * Since: 0.9.2 - **/ - hb_bool_t - hb_font_glyph_from_string (hb_font_t *font, -@@ -845,7 +1052,7 @@ - * - * Return value: (transfer full): - * -- * Since: 1.0 -+ * Since: 0.9.2 - **/ - hb_font_t * - hb_font_create (hb_face_t *face) -@@ -854,15 +1061,16 @@ - - if (unlikely (!face)) - face = hb_face_get_empty (); -- if (unlikely (hb_object_is_inert (face))) -- return hb_font_get_empty (); - if (!(font = hb_object_create<hb_font_t> ())) - return hb_font_get_empty (); - - hb_face_make_immutable (face); -+ font->parent = hb_font_get_empty (); - font->face = hb_face_reference (face); - font->klass = hb_font_funcs_get_empty (); - -+ font->x_scale = font->y_scale = hb_face_get_upem (face); -+ - return font; - } - -@@ -874,20 +1082,19 @@ - * - * Return value: (transfer full): - * -- * Since: 1.0 -+ * Since: 0.9.2 - **/ - hb_font_t * - hb_font_create_sub_font (hb_font_t *parent) - { - if (unlikely (!parent)) -- return hb_font_get_empty (); -+ parent = hb_font_get_empty (); - - hb_font_t *font = hb_font_create (parent->face); - - if (unlikely (hb_object_is_inert (font))) - return font; - -- hb_font_make_immutable (parent); - font->parent = hb_font_reference (parent); - - font->x_scale = parent->x_scale; -@@ -905,7 +1112,7 @@ - * - * Return value: (transfer full) - * -- * Since: 1.0 -+ * Since: 0.9.2 - **/ - hb_font_t * - hb_font_get_empty (void) -@@ -918,8 +1125,8 @@ - NULL, /* parent */ - const_cast<hb_face_t *> (&_hb_face_nil), - -- 0, /* x_scale */ -- 0, /* y_scale */ -+ 1000, /* x_scale */ -+ 1000, /* y_scale */ - - 0, /* x_ppem */ - 0, /* y_ppem */ -@@ -946,7 +1153,7 @@ - * - * Return value: (transfer full): - * -- * Since: 1.0 -+ * Since: 0.9.2 - **/ - hb_font_t * - hb_font_reference (hb_font_t *font) -@@ -960,7 +1167,7 @@ - * - * - * -- * Since: 1.0 -+ * Since: 0.9.2 - **/ - void - hb_font_destroy (hb_font_t *font) -@@ -993,7 +1200,7 @@ - * - * Return value: - * -- * Since: 1.0 -+ * Since: 0.9.2 - **/ - hb_bool_t - hb_font_set_user_data (hb_font_t *font, -@@ -1014,7 +1221,7 @@ - * - * Return value: (transfer none): - * -- * Since: 1.0 -+ * Since: 0.9.2 - **/ - void * - hb_font_get_user_data (hb_font_t *font, -@@ -1029,7 +1236,7 @@ - * - * - * -- * Since: 1.0 -+ * Since: 0.9.2 - **/ - void - hb_font_make_immutable (hb_font_t *font) -@@ -1037,6 +1244,9 @@ - if (unlikely (hb_object_is_inert (font))) - return; - -+ if (font->parent) -+ hb_font_make_immutable (font->parent); -+ - font->immutable = true; - } - -@@ -1048,7 +1258,7 @@ - * - * Return value: - * -- * Since: 1.0 -+ * Since: 0.9.2 - **/ - hb_bool_t - hb_font_is_immutable (hb_font_t *font) -@@ -1057,6 +1267,32 @@ - } - - /** -+ * hb_font_set_parent: -+ * @font: a font. -+ * @parent: new parent. -+ * -+ * Sets parent font of @font. -+ * -+ * Since: 1.0.5 -+ **/ -+void -+hb_font_set_parent (hb_font_t *font, -+ hb_font_t *parent) -+{ -+ if (font->immutable) -+ return; -+ -+ if (!parent) -+ parent = hb_font_get_empty (); -+ -+ hb_font_t *old = font->parent; -+ -+ font->parent = hb_font_reference (parent); -+ -+ hb_font_destroy (old); -+} -+ -+/** - * hb_font_get_parent: - * @font: a font. - * -@@ -1064,7 +1300,7 @@ - * - * Return value: (transfer none): - * -- * Since: 1.0 -+ * Since: 0.9.2 - **/ - hb_font_t * - hb_font_get_parent (hb_font_t *font) -@@ -1080,7 +1316,7 @@ - * - * Return value: (transfer none): - * -- * Since: 1.0 -+ * Since: 0.9.2 - **/ - hb_face_t * - hb_font_get_face (hb_font_t *font) -@@ -1098,7 +1334,7 @@ - * - * - * -- * Since: 1.0 -+ * Since: 0.9.2 - **/ - void - hb_font_set_funcs (hb_font_t *font, -@@ -1133,7 +1369,7 @@ - * - * - * -- * Since: 1.0 -+ * Since: 0.9.2 - **/ - void - hb_font_set_funcs_data (hb_font_t *font, -@@ -1163,7 +1399,7 @@ - * - * - * -- * Since: 1.0 -+ * Since: 0.9.2 - **/ - void - hb_font_set_scale (hb_font_t *font, -@@ -1185,7 +1421,7 @@ - * - * - * -- * Since: 1.0 -+ * Since: 0.9.2 - **/ - void - hb_font_get_scale (hb_font_t *font, -@@ -1204,7 +1440,7 @@ - * - * - * -- * Since: 1.0 -+ * Since: 0.9.2 - **/ - void - hb_font_set_ppem (hb_font_t *font, -@@ -1226,7 +1462,7 @@ - * - * - * -- * Since: 1.0 -+ * Since: 0.9.2 - **/ - void - hb_font_get_ppem (hb_font_t *font, -diff -uN gfx/harfbuzz/src_old/hb-font.h gfx/harfbuzz/src/hb-font.h ---- gfx/harfbuzz/src_old/hb-font.h 2016-05-10 22:26:56.000000000 +0200 -+++ gfx/harfbuzz/src/hb-font.h 2016-06-05 23:48:49.311185210 +0200 -@@ -46,19 +46,19 @@ - - typedef struct hb_font_funcs_t hb_font_funcs_t; - --hb_font_funcs_t * -+HB_EXTERN hb_font_funcs_t * - hb_font_funcs_create (void); - --hb_font_funcs_t * -+HB_EXTERN hb_font_funcs_t * - hb_font_funcs_get_empty (void); - --hb_font_funcs_t * -+HB_EXTERN hb_font_funcs_t * - hb_font_funcs_reference (hb_font_funcs_t *ffuncs); - --void -+HB_EXTERN void - hb_font_funcs_destroy (hb_font_funcs_t *ffuncs); - --hb_bool_t -+HB_EXTERN hb_bool_t - hb_font_funcs_set_user_data (hb_font_funcs_t *ffuncs, - hb_user_data_key_t *key, - void * data, -@@ -66,31 +66,56 @@ - hb_bool_t replace); - - --void * -+HB_EXTERN void * - hb_font_funcs_get_user_data (hb_font_funcs_t *ffuncs, - hb_user_data_key_t *key); - - --void -+HB_EXTERN void - hb_font_funcs_make_immutable (hb_font_funcs_t *ffuncs); - --hb_bool_t -+HB_EXTERN hb_bool_t - hb_font_funcs_is_immutable (hb_font_funcs_t *ffuncs); - - --/* glyph extents */ -+/* font and glyph extents */ - -+/* Note that typically ascender is positive and descender negative in coordinate systems that grow up. */ -+typedef struct hb_font_extents_t -+{ -+ hb_position_t ascender; /* typographic ascender. */ -+ hb_position_t descender; /* typographic descender. */ -+ hb_position_t line_gap; /* suggested line spacing gap. */ -+ /*< private >*/ -+ hb_position_t reserved9; -+ hb_position_t reserved8; -+ hb_position_t reserved7; -+ hb_position_t reserved6; -+ hb_position_t reserved5; -+ hb_position_t reserved4; -+ hb_position_t reserved3; -+ hb_position_t reserved2; -+ hb_position_t reserved1; -+} hb_font_extents_t; -+ -+/* Note that height is negative in coordinate systems that grow up. */ - typedef struct hb_glyph_extents_t - { -- hb_position_t x_bearing; -- hb_position_t y_bearing; -- hb_position_t width; -- hb_position_t height; -+ hb_position_t x_bearing; /* left side of glyph from origin. */ -+ hb_position_t y_bearing; /* top side of glyph from origin. */ -+ hb_position_t width; /* distance from left to right side. */ -+ hb_position_t height; /* distance from top to bottom side. */ - } hb_glyph_extents_t; - -- - /* func types */ - -+typedef hb_bool_t (*hb_font_get_font_extents_func_t) (hb_font_t *font, void *font_data, -+ hb_font_extents_t *metrics, -+ void *user_data); -+typedef hb_font_get_font_extents_func_t hb_font_get_font_h_extents_func_t; -+typedef hb_font_get_font_extents_func_t hb_font_get_font_v_extents_func_t; -+ -+ - typedef hb_bool_t (*hb_font_get_glyph_func_t) (hb_font_t *font, void *font_data, - hb_codepoint_t unicode, hb_codepoint_t variation_selector, - hb_codepoint_t *glyph, -@@ -140,6 +165,38 @@ - /* func setters */ - - /** -+ * hb_font_funcs_set_font_h_extents_func: -+ * @ffuncs: font functions. -+ * @func: (closure user_data) (destroy destroy) (scope notified): -+ * @user_data: -+ * @destroy: -+ * -+ * -+ * -+ * Since: 1.1.2 -+ **/ -+HB_EXTERN void -+hb_font_funcs_set_font_h_extents_func (hb_font_funcs_t *ffuncs, -+ hb_font_get_font_h_extents_func_t func, -+ void *user_data, hb_destroy_func_t destroy); -+ -+/** -+ * hb_font_funcs_set_font_v_extents_func: -+ * @ffuncs: font functions. -+ * @func: (closure user_data) (destroy destroy) (scope notified): -+ * @user_data: -+ * @destroy: -+ * -+ * -+ * -+ * Since: 1.1.2 -+ **/ -+HB_EXTERN void -+hb_font_funcs_set_font_v_extents_func (hb_font_funcs_t *ffuncs, -+ hb_font_get_font_v_extents_func_t func, -+ void *user_data, hb_destroy_func_t destroy); -+ -+/** - * hb_font_funcs_set_glyph_func: - * @ffuncs: font functions. - * @func: (closure user_data) (destroy destroy) (scope notified): -@@ -148,9 +205,9 @@ - * - * - * -- * Since: 1.0 -+ * Since: 0.9.2 - **/ --void -+HB_EXTERN void - hb_font_funcs_set_glyph_func (hb_font_funcs_t *ffuncs, - hb_font_get_glyph_func_t func, - void *user_data, hb_destroy_func_t destroy); -@@ -164,9 +221,9 @@ - * - * - * -- * Since: 1.0 -+ * Since: 0.9.2 - **/ --void -+HB_EXTERN void - hb_font_funcs_set_glyph_h_advance_func (hb_font_funcs_t *ffuncs, - hb_font_get_glyph_h_advance_func_t func, - void *user_data, hb_destroy_func_t destroy); -@@ -180,9 +237,9 @@ - * - * - * -- * Since: 1.0 -+ * Since: 0.9.2 - **/ --void -+HB_EXTERN void - hb_font_funcs_set_glyph_v_advance_func (hb_font_funcs_t *ffuncs, - hb_font_get_glyph_v_advance_func_t func, - void *user_data, hb_destroy_func_t destroy); -@@ -196,9 +253,9 @@ - * - * - * -- * Since: 1.0 -+ * Since: 0.9.2 - **/ --void -+HB_EXTERN void - hb_font_funcs_set_glyph_h_origin_func (hb_font_funcs_t *ffuncs, - hb_font_get_glyph_h_origin_func_t func, - void *user_data, hb_destroy_func_t destroy); -@@ -212,9 +269,9 @@ - * - * - * -- * Since: 1.0 -+ * Since: 0.9.2 - **/ --void -+HB_EXTERN void - hb_font_funcs_set_glyph_v_origin_func (hb_font_funcs_t *ffuncs, - hb_font_get_glyph_v_origin_func_t func, - void *user_data, hb_destroy_func_t destroy); -@@ -228,9 +285,9 @@ - * - * - * -- * Since: 1.0 -+ * Since: 0.9.2 - **/ --void -+HB_EXTERN void - hb_font_funcs_set_glyph_h_kerning_func (hb_font_funcs_t *ffuncs, - hb_font_get_glyph_h_kerning_func_t func, - void *user_data, hb_destroy_func_t destroy); -@@ -244,9 +301,9 @@ - * - * - * -- * Since: 1.0 -+ * Since: 0.9.2 - **/ --void -+HB_EXTERN void - hb_font_funcs_set_glyph_v_kerning_func (hb_font_funcs_t *ffuncs, - hb_font_get_glyph_v_kerning_func_t func, - void *user_data, hb_destroy_func_t destroy); -@@ -260,9 +317,9 @@ - * - * - * -- * Since: 1.0 -+ * Since: 0.9.2 - **/ --void -+HB_EXTERN void - hb_font_funcs_set_glyph_extents_func (hb_font_funcs_t *ffuncs, - hb_font_get_glyph_extents_func_t func, - void *user_data, hb_destroy_func_t destroy); -@@ -276,9 +333,9 @@ - * - * - * -- * Since: 1.0 -+ * Since: 0.9.2 - **/ --void -+HB_EXTERN void - hb_font_funcs_set_glyph_contour_point_func (hb_font_funcs_t *ffuncs, - hb_font_get_glyph_contour_point_func_t func, - void *user_data, hb_destroy_func_t destroy); -@@ -292,9 +349,9 @@ - * - * - * -- * Since: 1.0 -+ * Since: 0.9.2 - **/ --void -+HB_EXTERN void - hb_font_funcs_set_glyph_name_func (hb_font_funcs_t *ffuncs, - hb_font_get_glyph_name_func_t func, - void *user_data, hb_destroy_func_t destroy); -@@ -308,59 +365,65 @@ - * - * - * -- * Since: 1.0 -+ * Since: 0.9.2 - **/ --void -+HB_EXTERN void - hb_font_funcs_set_glyph_from_name_func (hb_font_funcs_t *ffuncs, - hb_font_get_glyph_from_name_func_t func, - void *user_data, hb_destroy_func_t destroy); - -- - /* func dispatch */ - --hb_bool_t -+HB_EXTERN hb_bool_t -+hb_font_get_h_extents (hb_font_t *font, -+ hb_font_extents_t *extents); -+HB_EXTERN hb_bool_t -+hb_font_get_v_extents (hb_font_t *font, -+ hb_font_extents_t *extents); -+ -+HB_EXTERN hb_bool_t - hb_font_get_glyph (hb_font_t *font, - hb_codepoint_t unicode, hb_codepoint_t variation_selector, - hb_codepoint_t *glyph); - --hb_position_t -+HB_EXTERN hb_position_t - hb_font_get_glyph_h_advance (hb_font_t *font, - hb_codepoint_t glyph); --hb_position_t -+HB_EXTERN hb_position_t - hb_font_get_glyph_v_advance (hb_font_t *font, - hb_codepoint_t glyph); - --hb_bool_t -+HB_EXTERN hb_bool_t - hb_font_get_glyph_h_origin (hb_font_t *font, - hb_codepoint_t glyph, - hb_position_t *x, hb_position_t *y); --hb_bool_t -+HB_EXTERN hb_bool_t - hb_font_get_glyph_v_origin (hb_font_t *font, - hb_codepoint_t glyph, - hb_position_t *x, hb_position_t *y); - --hb_position_t -+HB_EXTERN hb_position_t - hb_font_get_glyph_h_kerning (hb_font_t *font, - hb_codepoint_t left_glyph, hb_codepoint_t right_glyph); --hb_position_t -+HB_EXTERN hb_position_t - hb_font_get_glyph_v_kerning (hb_font_t *font, - hb_codepoint_t top_glyph, hb_codepoint_t bottom_glyph); - --hb_bool_t -+HB_EXTERN hb_bool_t - hb_font_get_glyph_extents (hb_font_t *font, - hb_codepoint_t glyph, - hb_glyph_extents_t *extents); - --hb_bool_t -+HB_EXTERN hb_bool_t - hb_font_get_glyph_contour_point (hb_font_t *font, - hb_codepoint_t glyph, unsigned int point_index, - hb_position_t *x, hb_position_t *y); - --hb_bool_t -+HB_EXTERN hb_bool_t - hb_font_get_glyph_name (hb_font_t *font, - hb_codepoint_t glyph, - char *name, unsigned int size); --hb_bool_t -+HB_EXTERN hb_bool_t - hb_font_get_glyph_from_name (hb_font_t *font, - const char *name, int len, /* -1 means nul-terminated */ - hb_codepoint_t *glyph); -@@ -368,52 +431,56 @@ - - /* high-level funcs, with fallback */ - --void -+HB_EXTERN void -+hb_font_get_extents_for_direction (hb_font_t *font, -+ hb_direction_t direction, -+ hb_font_extents_t *extents); -+HB_EXTERN void - hb_font_get_glyph_advance_for_direction (hb_font_t *font, - hb_codepoint_t glyph, - hb_direction_t direction, - hb_position_t *x, hb_position_t *y); --void -+HB_EXTERN void - hb_font_get_glyph_origin_for_direction (hb_font_t *font, - hb_codepoint_t glyph, - hb_direction_t direction, - hb_position_t *x, hb_position_t *y); --void -+HB_EXTERN void - hb_font_add_glyph_origin_for_direction (hb_font_t *font, - hb_codepoint_t glyph, - hb_direction_t direction, - hb_position_t *x, hb_position_t *y); --void -+HB_EXTERN void - hb_font_subtract_glyph_origin_for_direction (hb_font_t *font, - hb_codepoint_t glyph, - hb_direction_t direction, - hb_position_t *x, hb_position_t *y); - --void -+HB_EXTERN void - hb_font_get_glyph_kerning_for_direction (hb_font_t *font, - hb_codepoint_t first_glyph, hb_codepoint_t second_glyph, - hb_direction_t direction, - hb_position_t *x, hb_position_t *y); - --hb_bool_t -+HB_EXTERN hb_bool_t - hb_font_get_glyph_extents_for_origin (hb_font_t *font, - hb_codepoint_t glyph, - hb_direction_t direction, - hb_glyph_extents_t *extents); - --hb_bool_t -+HB_EXTERN hb_bool_t - hb_font_get_glyph_contour_point_for_origin (hb_font_t *font, - hb_codepoint_t glyph, unsigned int point_index, - hb_direction_t direction, - hb_position_t *x, hb_position_t *y); - - /* Generates gidDDD if glyph has no name. */ --void -+HB_EXTERN void - hb_font_glyph_to_string (hb_font_t *font, - hb_codepoint_t glyph, - char *s, unsigned int size); - /* Parses gidDDD and uniUUUU strings automatically. */ --hb_bool_t -+HB_EXTERN hb_bool_t - hb_font_glyph_from_string (hb_font_t *font, - const char *s, int len, /* -1 means nul-terminated */ - hb_codepoint_t *glyph); -@@ -425,22 +492,22 @@ - - /* Fonts are very light-weight objects */ - --hb_font_t * -+HB_EXTERN hb_font_t * - hb_font_create (hb_face_t *face); - --hb_font_t * -+HB_EXTERN hb_font_t * - hb_font_create_sub_font (hb_font_t *parent); - --hb_font_t * -+HB_EXTERN hb_font_t * - hb_font_get_empty (void); - --hb_font_t * -+HB_EXTERN hb_font_t * - hb_font_reference (hb_font_t *font); - --void -+HB_EXTERN void - hb_font_destroy (hb_font_t *font); - --hb_bool_t -+HB_EXTERN hb_bool_t - hb_font_set_user_data (hb_font_t *font, - hb_user_data_key_t *key, - void * data, -@@ -448,42 +515,46 @@ - hb_bool_t replace); - - --void * -+HB_EXTERN void * - hb_font_get_user_data (hb_font_t *font, - hb_user_data_key_t *key); - --void -+HB_EXTERN void - hb_font_make_immutable (hb_font_t *font); - --hb_bool_t -+HB_EXTERN hb_bool_t - hb_font_is_immutable (hb_font_t *font); - --hb_font_t * -+HB_EXTERN void -+hb_font_set_parent (hb_font_t *font, -+ hb_font_t *parent); -+ -+HB_EXTERN hb_font_t * - hb_font_get_parent (hb_font_t *font); - --hb_face_t * -+HB_EXTERN hb_face_t * - hb_font_get_face (hb_font_t *font); - - --void -+HB_EXTERN void - hb_font_set_funcs (hb_font_t *font, - hb_font_funcs_t *klass, - void *font_data, - hb_destroy_func_t destroy); - - /* Be *very* careful with this function! */ --void -+HB_EXTERN void - hb_font_set_funcs_data (hb_font_t *font, - void *font_data, - hb_destroy_func_t destroy); - - --void -+HB_EXTERN void - hb_font_set_scale (hb_font_t *font, - int x_scale, - int y_scale); - --void -+HB_EXTERN void - hb_font_get_scale (hb_font_t *font, - int *x_scale, - int *y_scale); -@@ -491,12 +562,12 @@ - /* - * A zero value means "no hinting in that direction" - */ --void -+HB_EXTERN void - hb_font_set_ppem (hb_font_t *font, - unsigned int x_ppem, - unsigned int y_ppem); - --void -+HB_EXTERN void - hb_font_get_ppem (hb_font_t *font, - unsigned int *x_ppem, - unsigned int *y_ppem); -diff -uN gfx/harfbuzz/src_old/hb-font-private.hh gfx/harfbuzz/src/hb-font-private.hh ---- gfx/harfbuzz/src_old/hb-font-private.hh 2016-05-10 22:26:55.000000000 +0200 -+++ gfx/harfbuzz/src/hb-font-private.hh 2016-06-05 23:48:46.442201028 +0200 -@@ -42,6 +42,8 @@ - */ - - #define HB_FONT_FUNCS_IMPLEMENT_CALLBACKS \ -+ HB_FONT_FUNC_IMPLEMENT (font_h_extents) \ -+ HB_FONT_FUNC_IMPLEMENT (font_v_extents) \ - HB_FONT_FUNC_IMPLEMENT (glyph) \ - HB_FONT_FUNC_IMPLEMENT (glyph_h_advance) \ - HB_FONT_FUNC_IMPLEMENT (glyph_v_advance) \ -@@ -61,14 +63,6 @@ - - hb_bool_t immutable; - -- /* Don't access these directly. Call hb_font_get_*() instead. */ -- -- struct { --#define HB_FONT_FUNC_IMPLEMENT(name) hb_font_get_##name##_func_t name; -- HB_FONT_FUNCS_IMPLEMENT_CALLBACKS --#undef HB_FONT_FUNC_IMPLEMENT -- } get; -- - struct { - #define HB_FONT_FUNC_IMPLEMENT(name) void *name; - HB_FONT_FUNCS_IMPLEMENT_CALLBACKS -@@ -80,6 +74,16 @@ - HB_FONT_FUNCS_IMPLEMENT_CALLBACKS - #undef HB_FONT_FUNC_IMPLEMENT - } destroy; -+ -+ /* Don't access these directly. Call font->get_*() instead. */ -+ union get_t { -+ struct get_funcs_t { -+#define HB_FONT_FUNC_IMPLEMENT(name) hb_font_get_##name##_func_t name; -+ HB_FONT_FUNCS_IMPLEMENT_CALLBACKS -+#undef HB_FONT_FUNC_IMPLEMENT -+ } f; -+ void (*array[VAR]) (void); -+ } get; - }; - - -@@ -144,7 +148,36 @@ - - /* Public getters */ - -- inline hb_bool_t has_glyph (hb_codepoint_t unicode) -+ HB_INTERNAL bool has_func (unsigned int i); -+ -+ /* has_* ... */ -+#define HB_FONT_FUNC_IMPLEMENT(name) \ -+ bool \ -+ has_##name##_func (void) \ -+ { \ -+ hb_font_funcs_t *funcs = this->klass; \ -+ unsigned int i = offsetof (hb_font_funcs_t::get_t::get_funcs_t, name) / sizeof (funcs->get.array[0]); \ -+ return has_func (i); \ -+ } -+ HB_FONT_FUNCS_IMPLEMENT_CALLBACKS -+#undef HB_FONT_FUNC_IMPLEMENT -+ -+ inline hb_bool_t get_font_h_extents (hb_font_extents_t *extents) -+ { -+ memset (extents, 0, sizeof (*extents)); -+ return klass->get.f.font_h_extents (this, user_data, -+ extents, -+ klass->user_data.font_h_extents); -+ } -+ inline hb_bool_t get_font_v_extents (hb_font_extents_t *extents) -+ { -+ memset (extents, 0, sizeof (*extents)); -+ return klass->get.f.font_v_extents (this, user_data, -+ extents, -+ klass->user_data.font_v_extents); -+ } -+ -+ inline bool has_glyph (hb_codepoint_t unicode) - { - hb_codepoint_t glyph; - return get_glyph (unicode, 0, &glyph); -@@ -154,85 +187,85 @@ - hb_codepoint_t *glyph) - { - *glyph = 0; -- return klass->get.glyph (this, user_data, -- unicode, variation_selector, glyph, -- klass->user_data.glyph); -+ return klass->get.f.glyph (this, user_data, -+ unicode, variation_selector, glyph, -+ klass->user_data.glyph); - } - - inline hb_position_t get_glyph_h_advance (hb_codepoint_t glyph) - { -- return klass->get.glyph_h_advance (this, user_data, -- glyph, -- klass->user_data.glyph_h_advance); -+ return klass->get.f.glyph_h_advance (this, user_data, -+ glyph, -+ klass->user_data.glyph_h_advance); - } - - inline hb_position_t get_glyph_v_advance (hb_codepoint_t glyph) - { -- return klass->get.glyph_v_advance (this, user_data, -- glyph, -- klass->user_data.glyph_v_advance); -+ return klass->get.f.glyph_v_advance (this, user_data, -+ glyph, -+ klass->user_data.glyph_v_advance); - } - - inline hb_bool_t get_glyph_h_origin (hb_codepoint_t glyph, - hb_position_t *x, hb_position_t *y) - { - *x = *y = 0; -- return klass->get.glyph_h_origin (this, user_data, -- glyph, x, y, -- klass->user_data.glyph_h_origin); -+ return klass->get.f.glyph_h_origin (this, user_data, -+ glyph, x, y, -+ klass->user_data.glyph_h_origin); - } - - inline hb_bool_t get_glyph_v_origin (hb_codepoint_t glyph, - hb_position_t *x, hb_position_t *y) - { - *x = *y = 0; -- return klass->get.glyph_v_origin (this, user_data, -- glyph, x, y, -- klass->user_data.glyph_v_origin); -+ return klass->get.f.glyph_v_origin (this, user_data, -+ glyph, x, y, -+ klass->user_data.glyph_v_origin); - } - - inline hb_position_t get_glyph_h_kerning (hb_codepoint_t left_glyph, hb_codepoint_t right_glyph) - { -- return klass->get.glyph_h_kerning (this, user_data, -- left_glyph, right_glyph, -- klass->user_data.glyph_h_kerning); -+ return klass->get.f.glyph_h_kerning (this, user_data, -+ left_glyph, right_glyph, -+ klass->user_data.glyph_h_kerning); - } - - inline hb_position_t get_glyph_v_kerning (hb_codepoint_t top_glyph, hb_codepoint_t bottom_glyph) - { -- return klass->get.glyph_v_kerning (this, user_data, -- top_glyph, bottom_glyph, -- klass->user_data.glyph_v_kerning); -+ return klass->get.f.glyph_v_kerning (this, user_data, -+ top_glyph, bottom_glyph, -+ klass->user_data.glyph_v_kerning); - } - - inline hb_bool_t get_glyph_extents (hb_codepoint_t glyph, - hb_glyph_extents_t *extents) - { - memset (extents, 0, sizeof (*extents)); -- return klass->get.glyph_extents (this, user_data, -- glyph, -- extents, -- klass->user_data.glyph_extents); -+ return klass->get.f.glyph_extents (this, user_data, -+ glyph, -+ extents, -+ klass->user_data.glyph_extents); - } - - inline hb_bool_t get_glyph_contour_point (hb_codepoint_t glyph, unsigned int point_index, - hb_position_t *x, hb_position_t *y) - { - *x = *y = 0; -- return klass->get.glyph_contour_point (this, user_data, -- glyph, point_index, -- x, y, -- klass->user_data.glyph_contour_point); -+ return klass->get.f.glyph_contour_point (this, user_data, -+ glyph, point_index, -+ x, y, -+ klass->user_data.glyph_contour_point); - } - - inline hb_bool_t get_glyph_name (hb_codepoint_t glyph, - char *name, unsigned int size) - { - if (size) *name = '\0'; -- return klass->get.glyph_name (this, user_data, -- glyph, -- name, size, -- klass->user_data.glyph_name); -+ return klass->get.f.glyph_name (this, user_data, -+ glyph, -+ name, size, -+ klass->user_data.glyph_name); - } - - inline hb_bool_t get_glyph_from_name (const char *name, int len, /* -1 means nul-terminated */ -@@ -240,15 +273,35 @@ - { - *glyph = 0; - if (len == -1) len = strlen (name); -- return klass->get.glyph_from_name (this, user_data, -- name, len, -- glyph, -- klass->user_data.glyph_from_name); -+ return klass->get.f.glyph_from_name (this, user_data, -+ name, len, -+ glyph, -+ klass->user_data.glyph_from_name); - } - - - /* A bit higher-level, and with fallback */ - -+ inline void get_extents_for_direction (hb_direction_t direction, -+ hb_font_extents_t *extents) -+ { -+ if (likely (HB_DIRECTION_IS_HORIZONTAL (direction))) { -+ if (!get_font_h_extents (extents)) -+ { -+ extents->ascender = y_scale * .8; -+ extents->descender = y_scale - extents->ascender; -+ extents->line_gap = 0; -+ } -+ } else { -+ if (!get_font_v_extents (extents)) -+ { -+ extents->ascender = x_scale / 2; -+ extents->descender = x_scale - extents->ascender; -+ extents->line_gap = 0; -+ } -+ } -+ } -+ - inline void get_glyph_advance_for_direction (hb_codepoint_t glyph, - hb_direction_t direction, - hb_position_t *x, hb_position_t *y) -@@ -268,7 +321,7 @@ - { - *x = get_glyph_h_advance (glyph) / 2; - -- /* TODO use font_metics.ascent */ -+ /* TODO use font_extents.ascender */ - *y = y_scale; - } - -@@ -298,6 +351,26 @@ - } - } - -+ inline void add_glyph_h_origin (hb_codepoint_t glyph, -+ hb_position_t *x, hb_position_t *y) -+ { -+ hb_position_t origin_x, origin_y; -+ -+ get_glyph_h_origin (glyph, &origin_x, &origin_y); -+ -+ *x += origin_x; -+ *y += origin_y; -+ } -+ inline void add_glyph_v_origin (hb_codepoint_t glyph, -+ hb_position_t *x, hb_position_t *y) -+ { -+ hb_position_t origin_x, origin_y; -+ -+ get_glyph_v_origin (glyph, &origin_x, &origin_y); -+ -+ *x += origin_x; -+ *y += origin_y; -+ } - inline void add_glyph_origin_for_direction (hb_codepoint_t glyph, - hb_direction_t direction, - hb_position_t *x, hb_position_t *y) -@@ -310,6 +383,26 @@ - *y += origin_y; - } - -+ inline void subtract_glyph_h_origin (hb_codepoint_t glyph, -+ hb_position_t *x, hb_position_t *y) -+ { -+ hb_position_t origin_x, origin_y; -+ -+ get_glyph_h_origin (glyph, &origin_x, &origin_y); -+ -+ *x -= origin_x; -+ *y -= origin_y; -+ } -+ inline void subtract_glyph_v_origin (hb_codepoint_t glyph, -+ hb_position_t *x, hb_position_t *y) -+ { -+ hb_position_t origin_x, origin_y; -+ -+ get_glyph_v_origin (glyph, &origin_x, &origin_y); -+ -+ *x -= origin_x; -+ *y -= origin_y; -+ } - inline void subtract_glyph_origin_for_direction (hb_codepoint_t glyph, - hb_direction_t direction, - hb_position_t *x, hb_position_t *y) -diff -uN gfx/harfbuzz/src_old/hb-ft.cc gfx/harfbuzz/src/hb-ft.cc ---- gfx/harfbuzz/src_old/hb-ft.cc 2016-05-10 22:26:56.000000000 +0200 -+++ gfx/harfbuzz/src/hb-ft.cc 2016-06-05 23:48:50.916176399 +0200 -@@ -1,6 +1,7 @@ - /* - * Copyright © 2009 Red Hat, Inc. - * Copyright © 2009 Keith Stribley -+ * Copyright © 2015 Google, Inc. - * - * This is part of HarfBuzz, a text shaping library. - * -@@ -23,6 +24,7 @@ - * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. - * - * Red Hat Author(s): Behdad Esfahbod -+ * Google Author(s): Behdad Esfahbod - */ - - #include "hb-private.hh" -@@ -46,10 +48,15 @@ - * In general, this file does a fine job of what it's supposed to do. - * There are, however, things that need more work: - * -- * - We don't handle any load_flags. That definitely has API implications. :( -- * I believe hb_ft_font_create() should take load_flags input. -- * In particular, FT_Get_Advance() without the NO_HINTING flag seems to be -- * buggy. -+ * - I remember seeing FT_Get_Advance() without the NO_HINTING flag to be buggy. -+ * Have not investigated. -+ * -+ * - FreeType works in 26.6 mode. Clients can decide to use that mode, and everything -+ * would work fine. However, we also abuse this API for performing in font-space, -+ * but don't pass the correct flags to FreeType. We just abuse the no-hinting mode -+ * for that, such that no rounding etc happens. As such, we don't set ppem, and -+ * pass NO_HINTING as load_flags. Would be much better to use NO_SCALE, and scale -+ * ourselves, like we do in uniscribe, etc. - * - * - We don't handle / allow for emboldening / obliqueing. - * -@@ -59,6 +66,94 @@ - */ - - -+struct hb_ft_font_t -+{ -+ FT_Face ft_face; -+ int load_flags; -+ bool unref; /* Whether to destroy ft_face when done. */ -+}; -+ -+static hb_ft_font_t * -+_hb_ft_font_create (FT_Face ft_face, bool unref) -+{ -+ hb_ft_font_t *ft_font = (hb_ft_font_t *) calloc (1, sizeof (hb_ft_font_t)); -+ -+ if (unlikely (!ft_font)) -+ return NULL; -+ -+ ft_font->ft_face = ft_face; -+ ft_font->unref = unref; -+ -+ ft_font->load_flags = FT_LOAD_DEFAULT | FT_LOAD_NO_HINTING; -+ -+ return ft_font; -+} -+ -+static void -+_hb_ft_font_destroy (hb_ft_font_t *ft_font) -+{ -+ if (ft_font->unref) -+ FT_Done_Face (ft_font->ft_face); -+ -+ free (ft_font); -+} -+ -+/** -+ * hb_ft_font_set_load_flags: -+ * @font: -+ * @load_flags: -+ * -+ * -+ * -+ * Since: 1.0.5 -+ **/ -+void -+hb_ft_font_set_load_flags (hb_font_t *font, int load_flags) -+{ -+ if (font->immutable) -+ return; -+ -+ if (font->destroy != (hb_destroy_func_t) _hb_ft_font_destroy) -+ return; -+ -+ hb_ft_font_t *ft_font = (hb_ft_font_t *) font->user_data; -+ -+ ft_font->load_flags = load_flags; -+} -+ -+/** -+ * hb_ft_font_get_load_flags: -+ * @font: -+ * -+ * -+ * -+ * Return value: -+ * Since: 1.0.5 -+ **/ -+int -+hb_ft_font_get_load_flags (hb_font_t *font) -+{ -+ if (font->destroy != (hb_destroy_func_t) _hb_ft_font_destroy) -+ return 0; -+ -+ const hb_ft_font_t *ft_font = (const hb_ft_font_t *) font->user_data; -+ -+ return ft_font->load_flags; -+} -+ -+FT_Face -+hb_ft_font_get_face (hb_font_t *font) -+{ -+ if (font->destroy != (hb_destroy_func_t) _hb_ft_font_destroy) -+ return NULL; -+ -+ const hb_ft_font_t *ft_font = (const hb_ft_font_t *) font->user_data; -+ -+ return ft_font->ft_face; -+} -+ -+ -+ - static hb_bool_t - hb_ft_get_glyph (hb_font_t *font HB_UNUSED, - void *font_data, -@@ -68,17 +163,19 @@ - void *user_data HB_UNUSED) - - { -- FT_Face ft_face = (FT_Face) font_data; -+ const hb_ft_font_t *ft_font = (const hb_ft_font_t *) font_data; -+ unsigned int g; - --#ifdef HAVE_FT_FACE_GETCHARVARIANTINDEX -- if (unlikely (variation_selector)) { -- *glyph = FT_Face_GetCharVariantIndex (ft_face, unicode, variation_selector); -- return *glyph != 0; -- } --#endif -+ if (likely (!variation_selector)) -+ g = FT_Get_Char_Index (ft_font->ft_face, unicode); -+ else -+ g = FT_Face_GetCharVariantIndex (ft_font->ft_face, unicode, variation_selector); - -- *glyph = FT_Get_Char_Index (ft_face, unicode); -- return *glyph != 0; -+ if (unlikely (!g)) -+ return false; -+ -+ *glyph = g; -+ return true; - } - - static hb_position_t -@@ -87,13 +184,15 @@ - hb_codepoint_t glyph, - void *user_data HB_UNUSED) - { -- FT_Face ft_face = (FT_Face) font_data; -- int load_flags = FT_LOAD_DEFAULT | FT_LOAD_NO_HINTING; -+ const hb_ft_font_t *ft_font = (const hb_ft_font_t *) font_data; - FT_Fixed v; - -- if (unlikely (FT_Get_Advance (ft_face, glyph, load_flags, &v))) -+ if (unlikely (FT_Get_Advance (ft_font->ft_face, glyph, ft_font->load_flags, &v))) - return 0; - -+ if (font->x_scale < 0) -+ v = -v; -+ - return (v + (1<<9)) >> 10; - } - -@@ -103,31 +202,21 @@ - hb_codepoint_t glyph, - void *user_data HB_UNUSED) - { -- FT_Face ft_face = (FT_Face) font_data; -- int load_flags = FT_LOAD_DEFAULT | FT_LOAD_NO_HINTING | FT_LOAD_VERTICAL_LAYOUT; -+ const hb_ft_font_t *ft_font = (const hb_ft_font_t *) font_data; - FT_Fixed v; - -- if (unlikely (FT_Get_Advance (ft_face, glyph, load_flags, &v))) -+ if (unlikely (FT_Get_Advance (ft_font->ft_face, glyph, ft_font->load_flags | FT_LOAD_VERTICAL_LAYOUT, &v))) - return 0; - -+ if (font->y_scale < 0) -+ v = -v; -+ - /* Note: FreeType's vertical metrics grows downward while other FreeType coordinates - * have a Y growing upward. Hence the extra negation. */ - return (-v + (1<<9)) >> 10; - } - - static hb_bool_t --hb_ft_get_glyph_h_origin (hb_font_t *font HB_UNUSED, -- void *font_data HB_UNUSED, -- hb_codepoint_t glyph HB_UNUSED, -- hb_position_t *x HB_UNUSED, -- hb_position_t *y HB_UNUSED, -- void *user_data HB_UNUSED) --{ -- /* We always work in the horizontal coordinates. */ -- return true; --} -- --static hb_bool_t - hb_ft_get_glyph_v_origin (hb_font_t *font HB_UNUSED, - void *font_data, - hb_codepoint_t glyph, -@@ -135,10 +224,10 @@ - hb_position_t *y, - void *user_data HB_UNUSED) - { -- FT_Face ft_face = (FT_Face) font_data; -- int load_flags = FT_LOAD_DEFAULT | FT_LOAD_NO_HINTING; -+ const hb_ft_font_t *ft_font = (const hb_ft_font_t *) font_data; -+ FT_Face ft_face = ft_font->ft_face; - -- if (unlikely (FT_Load_Glyph (ft_face, glyph, load_flags))) -+ if (unlikely (FT_Load_Glyph (ft_face, glyph, ft_font->load_flags))) - return false; - - /* Note: FreeType's vertical metrics grows downward while other FreeType coordinates -@@ -146,6 +235,11 @@ - *x = ft_face->glyph->metrics.horiBearingX - ft_face->glyph->metrics.vertBearingX; - *y = ft_face->glyph->metrics.horiBearingY - (-ft_face->glyph->metrics.vertBearingY); - -+ if (font->x_scale < 0) -+ *x = -*x; -+ if (font->y_scale < 0) -+ *y = -*y; -+ - return true; - } - -@@ -156,27 +250,16 @@ - hb_codepoint_t right_glyph, - void *user_data HB_UNUSED) - { -- FT_Face ft_face = (FT_Face) font_data; -+ const hb_ft_font_t *ft_font = (const hb_ft_font_t *) font_data; - FT_Vector kerningv; - - FT_Kerning_Mode mode = font->x_ppem ? FT_KERNING_DEFAULT : FT_KERNING_UNFITTED; -- if (FT_Get_Kerning (ft_face, left_glyph, right_glyph, mode, &kerningv)) -+ if (FT_Get_Kerning (ft_font->ft_face, left_glyph, right_glyph, mode, &kerningv)) - return 0; - - return kerningv.x; - } - --static hb_position_t --hb_ft_get_glyph_v_kerning (hb_font_t *font HB_UNUSED, -- void *font_data HB_UNUSED, -- hb_codepoint_t top_glyph HB_UNUSED, -- hb_codepoint_t bottom_glyph HB_UNUSED, -- void *user_data HB_UNUSED) --{ -- /* FreeType API doesn't support vertical kerning */ -- return 0; --} -- - static hb_bool_t - hb_ft_get_glyph_extents (hb_font_t *font HB_UNUSED, - void *font_data, -@@ -184,16 +267,26 @@ - hb_glyph_extents_t *extents, - void *user_data HB_UNUSED) - { -- FT_Face ft_face = (FT_Face) font_data; -- int load_flags = FT_LOAD_DEFAULT | FT_LOAD_NO_HINTING; -+ const hb_ft_font_t *ft_font = (const hb_ft_font_t *) font_data; -+ FT_Face ft_face = ft_font->ft_face; - -- if (unlikely (FT_Load_Glyph (ft_face, glyph, load_flags))) -+ if (unlikely (FT_Load_Glyph (ft_face, glyph, ft_font->load_flags))) - return false; - - extents->x_bearing = ft_face->glyph->metrics.horiBearingX; - extents->y_bearing = ft_face->glyph->metrics.horiBearingY; - extents->width = ft_face->glyph->metrics.width; - extents->height = -ft_face->glyph->metrics.height; -+ if (font->x_scale < 0) -+ { -+ extents->x_bearing = -extents->x_bearing; -+ extents->width = -extents->width; -+ } -+ if (font->y_scale < 0) -+ { -+ extents->y_bearing = -extents->y_bearing; -+ extents->height = -extents->height; -+ } - return true; - } - -@@ -206,10 +299,10 @@ - hb_position_t *y, - void *user_data HB_UNUSED) - { -- FT_Face ft_face = (FT_Face) font_data; -- int load_flags = FT_LOAD_DEFAULT; -+ const hb_ft_font_t *ft_font = (const hb_ft_font_t *) font_data; -+ FT_Face ft_face = ft_font->ft_face; - -- if (unlikely (FT_Load_Glyph (ft_face, glyph, load_flags))) -+ if (unlikely (FT_Load_Glyph (ft_face, glyph, ft_font->load_flags))) - return false; - - if (unlikely (ft_face->glyph->format != FT_GLYPH_FORMAT_OUTLINE)) -@@ -231,9 +324,9 @@ - char *name, unsigned int size, - void *user_data HB_UNUSED) - { -- FT_Face ft_face = (FT_Face) font_data; -+ const hb_ft_font_t *ft_font = (const hb_ft_font_t *) font_data; - -- hb_bool_t ret = !FT_Get_Glyph_Name (ft_face, glyph, name, size); -+ hb_bool_t ret = !FT_Get_Glyph_Name (ft_font->ft_face, glyph, name, size); - if (ret && (size && !*name)) - ret = false; - -@@ -247,7 +340,8 @@ - hb_codepoint_t *glyph, - void *user_data HB_UNUSED) - { -- FT_Face ft_face = (FT_Face) font_data; -+ const hb_ft_font_t *ft_font = (const hb_ft_font_t *) font_data; -+ FT_Face ft_face = ft_font->ft_face; - - if (len < 0) - *glyph = FT_Get_Name_Index (ft_face, (FT_String *) name); -@@ -272,23 +366,76 @@ - return *glyph != 0; - } - -+static hb_bool_t -+hb_ft_get_font_h_extents (hb_font_t *font HB_UNUSED, -+ void *font_data, -+ hb_font_extents_t *metrics, -+ void *user_data HB_UNUSED) -+{ -+ const hb_ft_font_t *ft_font = (const hb_ft_font_t *) font_data; -+ FT_Face ft_face = ft_font->ft_face; -+ metrics->ascender = ft_face->size->metrics.ascender; -+ metrics->descender = ft_face->size->metrics.descender; -+ metrics->line_gap = ft_face->size->metrics.height - (ft_face->size->metrics.ascender - ft_face->size->metrics.descender); -+ if (font->y_scale < 0) -+ { -+ metrics->ascender = -metrics->ascender; -+ metrics->descender = -metrics->descender; -+ metrics->line_gap = -metrics->line_gap; -+ } -+ return true; -+} -+ -+static hb_font_funcs_t *static_ft_funcs = NULL; -+ -+#ifdef HB_USE_ATEXIT -+static -+void free_static_ft_funcs (void) -+{ -+ hb_font_funcs_destroy (static_ft_funcs); -+} -+#endif - --static hb_font_funcs_t * --_hb_ft_get_font_funcs (void) -+static void -+_hb_ft_font_set_funcs (hb_font_t *font, FT_Face ft_face, bool unref) - { -- static const hb_font_funcs_t ft_ffuncs = { -- HB_OBJECT_HEADER_STATIC, -+retry: -+ hb_font_funcs_t *funcs = (hb_font_funcs_t *) hb_atomic_ptr_get (&static_ft_funcs); -+ -+ if (unlikely (!funcs)) -+ { -+ funcs = hb_font_funcs_create (); -+ -+ hb_font_funcs_set_font_h_extents_func (funcs, hb_ft_get_font_h_extents, NULL, NULL); -+ //hb_font_funcs_set_font_v_extents_func (funcs, hb_ft_get_font_v_extents, NULL, NULL); -+ hb_font_funcs_set_glyph_func (funcs, hb_ft_get_glyph, NULL, NULL); -+ hb_font_funcs_set_glyph_h_advance_func (funcs, hb_ft_get_glyph_h_advance, NULL, NULL); -+ hb_font_funcs_set_glyph_v_advance_func (funcs, hb_ft_get_glyph_v_advance, NULL, NULL); -+ //hb_font_funcs_set_glyph_h_origin_func (funcs, hb_ft_get_glyph_h_origin, NULL, NULL); -+ hb_font_funcs_set_glyph_v_origin_func (funcs, hb_ft_get_glyph_v_origin, NULL, NULL); -+ hb_font_funcs_set_glyph_h_kerning_func (funcs, hb_ft_get_glyph_h_kerning, NULL, NULL); -+ //hb_font_funcs_set_glyph_v_kerning_func (funcs, hb_ft_get_glyph_v_kerning, NULL, NULL); -+ hb_font_funcs_set_glyph_extents_func (funcs, hb_ft_get_glyph_extents, NULL, NULL); -+ hb_font_funcs_set_glyph_contour_point_func (funcs, hb_ft_get_glyph_contour_point, NULL, NULL); -+ hb_font_funcs_set_glyph_name_func (funcs, hb_ft_get_glyph_name, NULL, NULL); -+ hb_font_funcs_set_glyph_from_name_func (funcs, hb_ft_get_glyph_from_name, NULL, NULL); - -- true, /* immutable */ -+ hb_font_funcs_make_immutable (funcs); - -- { --#define HB_FONT_FUNC_IMPLEMENT(name) hb_ft_get_##name, -- HB_FONT_FUNCS_IMPLEMENT_CALLBACKS --#undef HB_FONT_FUNC_IMPLEMENT -+ if (!hb_atomic_ptr_cmpexch (&static_ft_funcs, NULL, funcs)) { -+ hb_font_funcs_destroy (funcs); -+ goto retry; - } -+ -+#ifdef HB_USE_ATEXIT -+ atexit (free_static_ft_funcs); /* First person registers atexit() callback. */ -+#endif - }; - -- return const_cast<hb_font_funcs_t *> (&ft_ffuncs); -+ hb_font_set_funcs (font, -+ funcs, -+ _hb_ft_font_create (ft_face, unref), -+ (hb_destroy_func_t) _hb_ft_font_destroy); - } - - -@@ -327,7 +474,7 @@ - * - * - * Return value: (transfer full): -- * Since: 1.0 -+ * Since: 0.9.2 - **/ - hb_face_t * - hb_ft_face_create (FT_Face ft_face, -@@ -340,11 +487,7 @@ - - blob = hb_blob_create ((const char *) ft_face->stream->base, - (unsigned int) ft_face->stream->size, -- /* TODO: We assume that it's mmap()'ed, but FreeType code -- * suggests that there are cases we reach here but font is -- * not mmapped. For example, when mmap() fails. No idea -- * how to deal with it better here. */ -- HB_MEMORY_MODE_READONLY_MAY_MAKE_WRITABLE, -+ HB_MEMORY_MODE_READONLY, - ft_face, destroy); - face = hb_face_create (blob, ft_face->face_index); - hb_blob_destroy (blob); -@@ -358,6 +501,22 @@ - return face; - } - -+/** -+ * hb_ft_face_create_referenced: -+ * @ft_face: -+ * -+ * -+ * -+ * Return value: (transfer full): -+ * Since: 0.9.38 -+ **/ -+hb_face_t * -+hb_ft_face_create_referenced (FT_Face ft_face) -+{ -+ FT_Reference_Face (ft_face); -+ return hb_ft_face_create (ft_face, (hb_destroy_func_t) FT_Done_Face); -+} -+ - static void - hb_ft_face_finalize (FT_Face ft_face) - { -@@ -371,7 +530,7 @@ - * - * - * Return value: (transfer full): -- * Since: 1.0 -+ * Since: 0.9.2 - **/ - hb_face_t * - hb_ft_face_create_cached (FT_Face ft_face) -@@ -388,11 +547,6 @@ - return hb_face_reference ((hb_face_t *) ft_face->generic.data); - } - --static void --_do_nothing (void) --{ --} -- - - /** - * hb_ft_font_create: -@@ -402,7 +556,7 @@ - * - * - * Return value: (transfer full): -- * Since: 1.0 -+ * Since: 0.9.2 - **/ - hb_font_t * - hb_ft_font_create (FT_Face ft_face, -@@ -414,29 +568,47 @@ - face = hb_ft_face_create (ft_face, destroy); - font = hb_font_create (face); - hb_face_destroy (face); -- hb_font_set_funcs (font, -- _hb_ft_get_font_funcs (), -- ft_face, (hb_destroy_func_t) _do_nothing); -+ _hb_ft_font_set_funcs (font, ft_face, false); - hb_font_set_scale (font, - (int) (((uint64_t) ft_face->size->metrics.x_scale * (uint64_t) ft_face->units_per_EM + (1<<15)) >> 16), - (int) (((uint64_t) ft_face->size->metrics.y_scale * (uint64_t) ft_face->units_per_EM + (1<<15)) >> 16)); -+#if 0 /* hb-ft works in no-hinting model */ - hb_font_set_ppem (font, - ft_face->size->metrics.x_ppem, - ft_face->size->metrics.y_ppem); -+#endif - - return font; - } - -+/** -+ * hb_ft_font_create_referenced: -+ * @ft_face: -+ * -+ * -+ * -+ * Return value: (transfer full): -+ * Since: 0.9.38 -+ **/ -+hb_font_t * -+hb_ft_font_create_referenced (FT_Face ft_face) -+{ -+ FT_Reference_Face (ft_face); -+ return hb_ft_font_create (ft_face, (hb_destroy_func_t) FT_Done_Face); -+} -+ - - /* Thread-safe, lock-free, FT_Library */ - - static FT_Library ft_library; - --static inline -+#ifdef HB_USE_ATEXIT -+static - void free_ft_library (void) - { - FT_Done_FreeType (ft_library); - } -+#endif - - static FT_Library - get_ft_library (void) -@@ -493,30 +665,23 @@ - - FT_Select_Charmap (ft_face, FT_ENCODING_UNICODE); - -- assert (font->y_scale >= 0); - FT_Set_Char_Size (ft_face, -- font->x_scale, font->y_scale, -+ abs (font->x_scale), abs (font->y_scale), - 0, 0); - #if 0 - font->x_ppem * 72 * 64 / font->x_scale, - font->y_ppem * 72 * 64 / font->y_scale); - #endif -+ if (font->x_scale < 0 || font->y_scale < 0) -+ { -+ FT_Matrix matrix = { font->x_scale < 0 ? -1 : +1, 0, -+ 0, font->y_scale < 0 ? -1 : +1}; -+ FT_Set_Transform (ft_face, &matrix, NULL); -+ } - - ft_face->generic.data = blob; - ft_face->generic.finalizer = (FT_Generic_Finalizer) _release_blob; - -- hb_font_set_funcs (font, -- _hb_ft_get_font_funcs (), -- ft_face, -- (hb_destroy_func_t) FT_Done_Face); --} -- --FT_Face --hb_ft_font_get_face (hb_font_t *font) --{ -- if (font->destroy == (hb_destroy_func_t) FT_Done_Face || -- font->destroy == (hb_destroy_func_t) _do_nothing) -- return (FT_Face) font->user_data; -- -- return NULL; -+ _hb_ft_font_set_funcs (font, ft_face, true); -+ hb_ft_font_set_load_flags (font, FT_LOAD_DEFAULT | FT_LOAD_NO_HINTING); - } -diff -uN gfx/harfbuzz/src_old/hb-ft.h gfx/harfbuzz/src/hb-ft.h ---- gfx/harfbuzz/src_old/hb-ft.h 2016-05-10 22:26:56.000000000 +0200 -+++ gfx/harfbuzz/src/hb-ft.h 2016-06-05 23:48:52.044170188 +0200 -@@ -1,5 +1,6 @@ - /* - * Copyright © 2009 Red Hat, Inc. -+ * Copyright © 2015 Google, Inc. - * - * This is part of HarfBuzz, a text shaping library. - * -@@ -22,6 +23,7 @@ - * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. - * - * Red Hat Author(s): Behdad Esfahbod -+ * Google Author(s): Behdad Esfahbod - */ - - #ifndef HB_FT_H -@@ -34,28 +36,90 @@ - - HB_BEGIN_DECLS - --/* Note: FreeType is not thread-safe. Hence, these functions are not either. */ -+/* -+ * Note: FreeType is not thread-safe. -+ * Hence, these functions are not either. -+ */ - --hb_face_t * -+/* -+ * hb-face from ft-face. -+ */ -+ -+/* This one creates a new hb-face for given ft-face. -+ * When the returned hb-face is destroyed, the destroy -+ * callback is called (if not NULL), with the ft-face passed -+ * to it. -+ * -+ * The client is responsible to make sure that ft-face is -+ * destroyed after hb-face is destroyed. -+ * -+ * Most often you don't want this function. You should use either -+ * hb_ft_face_create_cached(), or hb_ft_face_create_referenced(). -+ * In particular, if you are going to pass NULL as destroy, you -+ * probably should use (the more recent) hb_ft_face_create_referenced() -+ * instead. -+ */ -+HB_EXTERN hb_face_t * - hb_ft_face_create (FT_Face ft_face, - hb_destroy_func_t destroy); - --hb_face_t * -+/* This version is like hb_ft_face_create(), except that it caches -+ * the hb-face using the generic pointer of the ft-face. This means -+ * that subsequent calls to this function with the same ft-face will -+ * return the same hb-face (correctly referenced). -+ * -+ * Client is still responsible for making sure that ft-face is destroyed -+ * after hb-face is. -+ */ -+HB_EXTERN hb_face_t * - hb_ft_face_create_cached (FT_Face ft_face); - --hb_font_t * -+/* This version is like hb_ft_face_create(), except that it calls -+ * FT_Reference_Face() on ft-face, as such keeping ft-face alive -+ * as long as the hb-face is. -+ * -+ * This is the most convenient version to use. Use it unless you have -+ * very good reasons not to. -+ */ -+HB_EXTERN hb_face_t * -+hb_ft_face_create_referenced (FT_Face ft_face); -+ -+ -+/* -+ * hb-font from ft-face. -+ */ -+ -+/* -+ * Note: -+ * -+ * Set face size on ft-face before creating hb-font from it. -+ * Otherwise hb-ft would NOT pick up the font size correctly. -+ */ -+ -+/* See notes on hb_ft_face_create(). Same issues re lifecycle-management -+ * apply here. Use hb_ft_font_create_referenced() if you can. */ -+HB_EXTERN hb_font_t * - hb_ft_font_create (FT_Face ft_face, - hb_destroy_func_t destroy); - -+/* See notes on hb_ft_face_create_referenced() re lifecycle-management -+ * issues. */ -+HB_EXTERN hb_font_t * -+hb_ft_font_create_referenced (FT_Face ft_face); -+ -+HB_EXTERN FT_Face -+hb_ft_font_get_face (hb_font_t *font); -+ -+HB_EXTERN void -+hb_ft_font_set_load_flags (hb_font_t *font, int load_flags); - -+HB_EXTERN int -+hb_ft_font_get_load_flags (hb_font_t *font); - - /* Makes an hb_font_t use FreeType internally to implement font functions. */ --void -+HB_EXTERN void - hb_ft_font_set_funcs (hb_font_t *font); - --FT_Face --hb_ft_font_get_face (hb_font_t *font); -- - - HB_END_DECLS - -diff -uN gfx/harfbuzz/src_old/hb-glib.cc gfx/harfbuzz/src/hb-glib.cc ---- gfx/harfbuzz/src_old/hb-glib.cc 2016-05-10 22:26:55.000000000 +0200 -+++ gfx/harfbuzz/src/hb-glib.cc 2016-06-05 23:48:53.244163610 +0200 -@@ -382,3 +382,19 @@ - return const_cast<hb_unicode_funcs_t *> (&_hb_glib_unicode_funcs); - } - -+/** -+ * hb_glib_blob_create: -+ * -+ * Since: 0.9.38 -+ **/ -+hb_blob_t * -+hb_glib_blob_create (GBytes *gbytes) -+{ -+ gsize size = 0; -+ gconstpointer data = g_bytes_get_data (gbytes, &size); -+ return hb_blob_create ((const char *) data, -+ size, -+ HB_MEMORY_MODE_READONLY, -+ g_bytes_ref (gbytes), -+ (hb_destroy_func_t) g_bytes_unref); -+} -diff -uN gfx/harfbuzz/src_old/hb-glib.h gfx/harfbuzz/src/hb-glib.h ---- gfx/harfbuzz/src_old/hb-glib.h 2016-05-10 22:26:56.000000000 +0200 -+++ gfx/harfbuzz/src/hb-glib.h 2016-06-05 23:48:54.401157255 +0200 -@@ -36,16 +36,19 @@ - HB_BEGIN_DECLS - - --hb_script_t -+HB_EXTERN hb_script_t - hb_glib_script_to_script (GUnicodeScript script); - --GUnicodeScript -+HB_EXTERN GUnicodeScript - hb_glib_script_from_script (hb_script_t script); - - --hb_unicode_funcs_t * -+HB_EXTERN hb_unicode_funcs_t * - hb_glib_get_unicode_funcs (void); - -+HB_EXTERN hb_blob_t * -+hb_glib_blob_create (GBytes *gbytes); -+ - - HB_END_DECLS - -diff -uN gfx/harfbuzz/src_old/hb-gobject-enums.h.tmpl gfx/harfbuzz/src/hb-gobject-enums.h.tmpl ---- gfx/harfbuzz/src_old/hb-gobject-enums.h.tmpl 2016-05-10 22:26:56.000000000 +0200 -+++ gfx/harfbuzz/src/hb-gobject-enums.h.tmpl 2016-06-05 23:48:57.189141987 +0200 -@@ -42,7 +42,7 @@ - /*** END file-header ***/ - - /*** BEGIN value-header ***/ --GType @enum_name@_get_type (void) G_GNUC_CONST; -+HB_EXTERN GType @enum_name@_get_type (void) G_GNUC_CONST; - #define @ENUMPREFIX@_TYPE_@ENUMSHORT@ (@enum_name@_get_type ()) - - /*** END value-header ***/ -diff -uN gfx/harfbuzz/src_old/hb-gobject-structs.cc gfx/harfbuzz/src/hb-gobject-structs.cc ---- gfx/harfbuzz/src_old/hb-gobject-structs.cc 2016-05-10 22:26:56.000000000 +0200 -+++ gfx/harfbuzz/src/hb-gobject-structs.cc 2016-06-05 23:48:58.408135321 +0200 -@@ -54,6 +54,17 @@ - #define HB_DEFINE_OBJECT_TYPE(name) \ - HB_DEFINE_BOXED_TYPE (name, hb_##name##_reference, hb_##name##_destroy); - -+#define HB_DEFINE_VALUE_TYPE(name) \ -+ static hb_##name##_t *_hb_##name##_reference (const hb_##name##_t *l) \ -+ { \ -+ hb_##name##_t *c = (hb_##name##_t *) calloc (1, sizeof (hb_##name##_t)); \ -+ if (unlikely (!c)) return NULL; \ -+ *c = *l; \ -+ return c; \ -+ } \ -+ static void _hb_##name##_destroy (hb_##name##_t *l) { free (l); } \ -+ HB_DEFINE_BOXED_TYPE (name, _hb_##name##_reference, _hb_##name##_destroy); -+ - HB_DEFINE_OBJECT_TYPE (buffer) - HB_DEFINE_OBJECT_TYPE (blob) - HB_DEFINE_OBJECT_TYPE (face) -@@ -62,59 +73,8 @@ - HB_DEFINE_OBJECT_TYPE (set) - HB_DEFINE_OBJECT_TYPE (shape_plan) - HB_DEFINE_OBJECT_TYPE (unicode_funcs) -- -- --static hb_feature_t *feature_reference (hb_feature_t *g) --{ -- hb_feature_t *c = (hb_feature_t *) calloc (1, sizeof (hb_feature_t)); -- if (unlikely (!c)) return NULL; -- *c = *g; -- return c; --} --static void feature_destroy (hb_feature_t *g) { free (g); } --HB_DEFINE_BOXED_TYPE (feature, feature_reference, feature_destroy) -- --static hb_glyph_info_t *glyph_info_reference (hb_glyph_info_t *g) --{ -- hb_glyph_info_t *c = (hb_glyph_info_t *) calloc (1, sizeof (hb_glyph_info_t)); -- if (unlikely (!c)) return NULL; -- *c = *g; -- return c; --} --static void glyph_info_destroy (hb_glyph_info_t *g) { free (g); } --HB_DEFINE_BOXED_TYPE (glyph_info, glyph_info_reference, glyph_info_destroy) -- --static hb_glyph_position_t *glyph_position_reference (hb_glyph_position_t *g) --{ -- hb_glyph_position_t *c = (hb_glyph_position_t *) calloc (1, sizeof (hb_glyph_position_t)); -- if (unlikely (!c)) return NULL; -- *c = *g; -- return c; --} --static void glyph_position_destroy (hb_glyph_position_t *g) { free (g); } --HB_DEFINE_BOXED_TYPE (glyph_position, glyph_position_reference, glyph_position_destroy) -- --static hb_segment_properties_t *segment_properties_reference (hb_segment_properties_t *g) --{ -- hb_segment_properties_t *c = (hb_segment_properties_t *) calloc (1, sizeof (hb_segment_properties_t)); -- if (unlikely (!c)) return NULL; -- *c = *g; -- return c; --} --static void segment_properties_destroy (hb_segment_properties_t *g) { free (g); } --HB_DEFINE_BOXED_TYPE (segment_properties, segment_properties_reference, segment_properties_destroy) -- --static hb_user_data_key_t user_data_key_reference (hb_user_data_key_t l) { return l; } --static void user_data_key_destroy (hb_user_data_key_t l) { } --HB_DEFINE_BOXED_TYPE (user_data_key, user_data_key_reference, user_data_key_destroy) -- -- --static hb_language_t *language_reference (hb_language_t *l) --{ -- hb_language_t *c = (hb_language_t *) calloc (1, sizeof (hb_language_t)); -- if (unlikely (!c)) return NULL; -- *c = *l; -- return c; --} --static void language_destroy (hb_language_t *l) { free (l); } --HB_DEFINE_BOXED_TYPE (language, language_reference, language_destroy) -+HB_DEFINE_VALUE_TYPE (feature) -+HB_DEFINE_VALUE_TYPE (glyph_info) -+HB_DEFINE_VALUE_TYPE (glyph_position) -+HB_DEFINE_VALUE_TYPE (segment_properties) -+HB_DEFINE_VALUE_TYPE (user_data_key) -diff -uN gfx/harfbuzz/src_old/hb-gobject-structs.h gfx/harfbuzz/src/hb-gobject-structs.h ---- gfx/harfbuzz/src_old/hb-gobject-structs.h 2016-05-10 22:26:56.000000000 +0200 -+++ gfx/harfbuzz/src/hb-gobject-structs.h 2016-06-05 23:48:59.577128929 +0200 -@@ -40,55 +40,65 @@ - - /* Object types */ - --GType hb_gobject_blob_get_type (void); -+/** -+ * Since: 0.9.2 -+ **/ -+HB_EXTERN GType hb_gobject_blob_get_type (void); - #define HB_GOBJECT_TYPE_BLOB (hb_gobject_blob_get_type ()) - --GType hb_gobject_buffer_get_type (void); -+/** -+ * Since: 0.9.2 -+ **/ -+HB_EXTERN GType hb_gobject_buffer_get_type (void); - #define HB_GOBJECT_TYPE_BUFFER (hb_gobject_buffer_get_type ()) - --GType hb_gobject_face_get_type (void); -+/** -+ * Since: 0.9.2 -+ **/ -+HB_EXTERN GType hb_gobject_face_get_type (void); - #define HB_GOBJECT_TYPE_FACE (hb_gobject_face_get_type ()) - --GType hb_gobject_font_get_type (void); -+/** -+ * Since: 0.9.2 -+ **/ -+HB_EXTERN GType hb_gobject_font_get_type (void); - #define HB_GOBJECT_TYPE_FONT (hb_gobject_font_get_type ()) - --GType hb_gobject_font_funcs_get_type (void); -+/** -+ * Since: 0.9.2 -+ **/ -+HB_EXTERN GType hb_gobject_font_funcs_get_type (void); - #define HB_GOBJECT_TYPE_FONT_FUNCS (hb_gobject_font_funcs_get_type ()) - --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 ()) - --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 ()) - --GType hb_gobject_unicode_funcs_get_type (void); -+/** -+ * Since: 0.9.2 -+ **/ -+HB_EXTERN GType hb_gobject_unicode_funcs_get_type (void); - #define HB_GOBJECT_TYPE_UNICODE_FUNCS (hb_gobject_unicode_funcs_get_type ()) - - /* Value types */ - --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 ()) - --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 ()) - --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 ()) - --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 ()) - --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 ()) - --/* Currently gobject-introspection doesn't understand that hb_language_t -- * can be passed by-value. As such we box it up. May remove in the -- * future. -- * -- * https://bugzilla.gnome.org/show_bug.cgi?id=707656 -- */ --GType hb_gobject_language_get_type (void); --#define HB_GOBJECT_TYPE_LANGUAGE (hb_gobject_language_get_type ()) - - HB_END_DECLS - -diff -uN gfx/harfbuzz/src_old/hb-graphite2.cc gfx/harfbuzz/src/hb-graphite2.cc ---- gfx/harfbuzz/src_old/hb-graphite2.cc 2016-05-10 22:26:55.000000000 +0200 -+++ gfx/harfbuzz/src/hb-graphite2.cc 2016-06-05 23:49:01.899116257 +0200 -@@ -138,6 +138,9 @@ - free (data); - } - -+/* -+ * Since: 0.9.10 -+ */ - gr_face * - hb_graphite2_face_get_gr_face (hb_face_t *face) - { -@@ -172,6 +175,9 @@ - gr_font_destroy (data); - } - -+/* -+ * Since: 0.9.10 -+ */ - gr_font * - hb_graphite2_font_get_gr_font (hb_font_t *font) - { -@@ -228,12 +234,11 @@ - int lang_len = lang_end ? lang_end - lang : -1; - gr_feature_val *feats = gr_face_featureval_for_lang (grface, lang ? hb_tag_from_string (lang, lang_len) : 0); - -- while (num_features--) -+ for (unsigned int i = 0; i < num_features; i++) - { -- const gr_feature_ref *fref = gr_face_find_fref (grface, features->tag); -+ const gr_feature_ref *fref = gr_face_find_fref (grface, features[i].tag); - if (fref) -- gr_fref_set_feature_value (fref, features->value, feats); -- features++; -+ gr_fref_set_feature_value (fref, features[i].value, feats); - } - - gr_segment *seg = NULL; -@@ -249,6 +254,8 @@ - for (unsigned int i = 0; i < buffer->len; ++i) - chars[i] = buffer->info[i].codepoint; - -+ /* TODO ensure_native_direction. */ -+ - hb_tag_t script_tag[2]; - hb_ot_tags_from_script (hb_buffer_get_script (buffer), &script_tag[0], &script_tag[1]); - -@@ -267,9 +274,11 @@ - if (unlikely (!glyph_count)) { - if (feats) gr_featureval_destroy (feats); - gr_seg_destroy (seg); -- return false; -+ buffer->len = 0; -+ return true; - } - -+ buffer->ensure (glyph_count); - scratch = buffer->get_scratch_buffer (&scratch_size); - while ((DIV_CEIL (sizeof (hb_graphite2_cluster_t) * buffer->len, sizeof (*scratch)) + - DIV_CEIL (sizeof (hb_codepoint_t) * glyph_count, sizeof (*scratch))) > scratch_size) -@@ -331,7 +340,6 @@ - } - ci++; - -- //buffer->clear_output (); - for (unsigned int i = 0; i < ci; ++i) - { - for (unsigned int j = 0; j < clusters[i].num_glyphs; ++j) -@@ -342,32 +350,58 @@ - } - } - buffer->len = glyph_count; -- //buffer->swap_buffers (); -- -- if (HB_DIRECTION_IS_BACKWARD(buffer->props.direction)) -- curradvx = gr_seg_advance_X(seg); - -- hb_glyph_position_t *pPos; -- for (pPos = hb_buffer_get_glyph_positions (buffer, NULL), is = gr_seg_first_slot (seg); -- is; pPos++, is = gr_slot_next_in_segment (is)) -- { -- pPos->x_offset = gr_slot_origin_X (is) - curradvx; -- pPos->y_offset = gr_slot_origin_Y (is) - curradvy; -- pPos->x_advance = gr_slot_advance_X (is, grface, grfont); -- pPos->y_advance = gr_slot_advance_Y (is, grface, grfont); -- if (HB_DIRECTION_IS_BACKWARD (buffer->props.direction)) -- curradvx -= pPos->x_advance; -- pPos->x_offset = gr_slot_origin_X (is) - curradvx; -- if (!HB_DIRECTION_IS_BACKWARD (buffer->props.direction)) -+ float yscale = font->y_scale / font->x_scale; -+ /* Positioning. */ -+ if (!HB_DIRECTION_IS_BACKWARD(buffer->props.direction)) -+ { -+ hb_glyph_position_t *pPos; -+ for (pPos = hb_buffer_get_glyph_positions (buffer, NULL), is = gr_seg_first_slot (seg); -+ is; pPos++, is = gr_slot_next_in_segment (is)) -+ { -+ pPos->x_offset = gr_slot_origin_X (is) - curradvx; -+ pPos->y_offset = gr_slot_origin_Y (is) * yscale - curradvy; -+ pPos->x_advance = gr_slot_advance_X (is, grface, grfont); -+ pPos->y_advance = gr_slot_advance_Y (is, grface, grfont) * yscale; - curradvx += pPos->x_advance; -- pPos->y_offset = gr_slot_origin_Y (is) - curradvy; -- curradvy += pPos->y_advance; -- } -- if (!HB_DIRECTION_IS_BACKWARD (buffer->props.direction)) -+ curradvy += pPos->y_advance; -+ } - pPos[-1].x_advance += gr_seg_advance_X(seg) - curradvx; -- -- if (HB_DIRECTION_IS_BACKWARD (buffer->props.direction)) -+ } -+ else -+ { -+ hb_glyph_position_t *pPos = hb_buffer_get_glyph_positions (buffer, NULL) + buffer->len - 1; -+ const hb_glyph_info_t *info = buffer->info + buffer->len - 1; -+ const hb_glyph_info_t *tinfo; -+ const gr_slot *tis; -+ int currclus = -1; -+ float clusx = 0., clusy = 0.; -+ for (is = gr_seg_last_slot (seg); is; pPos--, info--, is = gr_slot_prev_in_segment (is)) -+ { -+ if (info->cluster != currclus) -+ { -+ curradvx += clusx; -+ curradvy += clusy; -+ currclus = info->cluster; -+ clusx = 0.; -+ clusy = 0.; -+ for (tis = is, tinfo = info; tis && tinfo->cluster == currclus; tis = gr_slot_prev_in_segment (tis), tinfo--) -+ { -+ clusx += gr_slot_advance_X (tis, grface, grfont); -+ clusy += gr_slot_advance_Y (tis, grface, grfont) * yscale; -+ } -+ curradvx += clusx; -+ curradvy += clusy; -+ } -+ pPos->x_advance = gr_slot_advance_X (is, grface, grfont); -+ pPos->y_advance = gr_slot_advance_Y (is, grface, grfont) * yscale; -+ curradvx -= pPos->x_advance; -+ curradvy -= pPos->y_advance; -+ pPos->x_offset = gr_slot_origin_X (is) - curradvx; -+ pPos->y_offset = gr_slot_origin_Y (is) * yscale - curradvy; -+ } - hb_buffer_reverse_clusters (buffer); -+ } - - if (feats) gr_featureval_destroy (feats); - gr_seg_destroy (seg); -diff -uN gfx/harfbuzz/src_old/hb-graphite2.h gfx/harfbuzz/src/hb-graphite2.h ---- gfx/harfbuzz/src_old/hb-graphite2.h 2016-05-10 22:26:56.000000000 +0200 -+++ gfx/harfbuzz/src/hb-graphite2.h 2016-06-05 23:49:03.057109946 +0200 -@@ -36,10 +36,10 @@ - #define HB_GRAPHITE2_TAG_SILF HB_TAG('S','i','l','f') - - --gr_face * -+HB_EXTERN gr_face * - hb_graphite2_face_get_gr_face (hb_face_t *face); - --gr_font * -+HB_EXTERN gr_font * - hb_graphite2_font_get_gr_font (hb_font_t *font); - - -diff -uN gfx/harfbuzz/src_old/hb.h gfx/harfbuzz/src/hb.h ---- gfx/harfbuzz/src_old/hb.h 2016-05-10 22:26:56.000000000 +0200 -+++ gfx/harfbuzz/src/hb.h 2016-06-05 23:50:56.057516793 +0200 -@@ -28,6 +28,10 @@ - #define HB_H - #define HB_H_IN - -+#ifndef HB_EXTERN -+#define HB_EXTERN extern -+#endif -+ - #include "hb-blob.h" - #include "hb-buffer.h" - #include "hb-common.h" -diff -uN gfx/harfbuzz/src_old/hb-icu.cc gfx/harfbuzz/src/hb-icu.cc ---- gfx/harfbuzz/src_old/hb-icu.cc 2016-05-10 22:26:55.000000000 +0200 -+++ gfx/harfbuzz/src/hb-icu.cc 2016-06-05 23:49:04.387102711 +0200 -@@ -363,10 +363,8 @@ - if (!hb_atomic_ptr_get (&normalizer)) { - UErrorCode icu_err = U_ZERO_ERROR; - /* We ignore failure in getNFCInstace(). */ -- hb_atomic_ptr_cmpexch (&normalizer, NULL, unorm2_getNFCInstance (&icu_err)); -+ (void) hb_atomic_ptr_cmpexch (&normalizer, NULL, unorm2_getNFCInstance (&icu_err)); - } - #endif - return const_cast<hb_unicode_funcs_t *> (&_hb_icu_unicode_funcs); - } -- -- -diff -uN gfx/harfbuzz/src_old/hb-icu.h gfx/harfbuzz/src/hb-icu.h ---- gfx/harfbuzz/src_old/hb-icu.h 2016-05-10 22:26:55.000000000 +0200 -+++ gfx/harfbuzz/src/hb-icu.h 2016-06-05 23:49:05.565096299 +0200 -@@ -36,14 +36,14 @@ - HB_BEGIN_DECLS - - --hb_script_t -+HB_EXTERN hb_script_t - hb_icu_script_to_script (UScriptCode script); - --UScriptCode -+HB_EXTERN UScriptCode - hb_icu_script_from_script (hb_script_t script); - - --hb_unicode_funcs_t * -+HB_EXTERN hb_unicode_funcs_t * - hb_icu_get_unicode_funcs (void); - - -diff -uN gfx/harfbuzz/src_old/hb-mutex-private.hh gfx/harfbuzz/src/hb-mutex-private.hh ---- gfx/harfbuzz/src_old/hb-mutex-private.hh 2016-05-10 22:26:55.000000000 +0200 -+++ gfx/harfbuzz/src/hb-mutex-private.hh 2016-06-05 23:49:06.735089929 +0200 -@@ -39,7 +39,13 @@ - - /* We need external help for these */ - --#if 0 -+#if defined(HB_MUTEX_IMPL_INIT) \ -+ && defined(hb_mutex_impl_init) \ -+ && defined(hb_mutex_impl_lock) \ -+ && defined(hb_mutex_impl_unlock) \ -+ && defined(hb_mutex_impl_finish) -+ -+/* Defined externally, i.e. in config.h; must have typedef'ed hb_mutex_impl_t as well. */ - - - #elif !defined(HB_NO_MT) && (defined(_WIN32) || defined(__CYGWIN__)) -@@ -47,7 +53,11 @@ - #include <windows.h> - typedef CRITICAL_SECTION hb_mutex_impl_t; - #define HB_MUTEX_IMPL_INIT {0} -+#if defined(WINAPI_FAMILY) && (WINAPI_FAMILY==WINAPI_FAMILY_PC_APP || WINAPI_FAMILY==WINAPI_FAMILY_PHONE_APP) -+#define hb_mutex_impl_init(M) InitializeCriticalSectionEx (M, 0, 0) -+#else - #define hb_mutex_impl_init(M) InitializeCriticalSection (M) -+#endif - #define hb_mutex_impl_lock(M) EnterCriticalSection (M) - #define hb_mutex_impl_unlock(M) LeaveCriticalSection (M) - #define hb_mutex_impl_finish(M) DeleteCriticalSection (M) -@@ -109,10 +119,12 @@ - #define hb_mutex_impl_unlock(M) HB_STMT_START {} HB_STMT_END - #define hb_mutex_impl_finish(M) HB_STMT_START {} HB_STMT_END - -+ - #endif - - - #define HB_MUTEX_INIT {HB_MUTEX_IMPL_INIT} -+ - struct hb_mutex_t - { - /* TODO Add tracing. */ -diff -uN gfx/harfbuzz/src_old/hb-object-private.hh gfx/harfbuzz/src/hb-object-private.hh ---- gfx/harfbuzz/src_old/hb-object-private.hh 2016-05-10 22:26:55.000000000 +0200 -+++ gfx/harfbuzz/src/hb-object-private.hh 2016-06-05 23:49:07.940083385 +0200 -@@ -47,19 +47,22 @@ - - /* reference_count */ - --#define HB_REFERENCE_COUNT_INVALID_VALUE ((hb_atomic_int_t) -1) --#define HB_REFERENCE_COUNT_INVALID {HB_REFERENCE_COUNT_INVALID_VALUE} -+#define HB_REFERENCE_COUNT_INERT_VALUE -1 -+#define HB_REFERENCE_COUNT_POISON_VALUE -0x0000DEAD -+#define HB_REFERENCE_COUNT_INIT {HB_ATOMIC_INT_INIT(HB_REFERENCE_COUNT_INERT_VALUE)} -+ - struct hb_reference_count_t - { - hb_atomic_int_t ref_count; - -- inline void init (int v) { ref_count = v; } -- inline int inc (void) { return hb_atomic_int_add (const_cast<hb_atomic_int_t &> (ref_count), 1); } -- inline int dec (void) { return hb_atomic_int_add (const_cast<hb_atomic_int_t &> (ref_count), -1); } -- inline void finish (void) { ref_count = HB_REFERENCE_COUNT_INVALID_VALUE; } -- -- inline bool is_invalid (void) const { return ref_count == HB_REFERENCE_COUNT_INVALID_VALUE; } -+ inline void init (int v) { ref_count.set_unsafe (v); } -+ inline int get_unsafe (void) const { return ref_count.get_unsafe (); } -+ inline int inc (void) { return ref_count.inc (); } -+ inline int dec (void) { return ref_count.dec (); } -+ inline void finish (void) { ref_count.set_unsafe (HB_REFERENCE_COUNT_POISON_VALUE); } - -+ inline bool is_inert (void) const { return ref_count.get_unsafe () == HB_REFERENCE_COUNT_INERT_VALUE; } -+ inline bool is_valid (void) const { return ref_count.get_unsafe () > 0; } - }; - - -@@ -102,7 +105,7 @@ - hb_reference_count_t ref_count; - hb_user_data_array_t user_data; - --#define HB_OBJECT_HEADER_STATIC {HB_REFERENCE_COUNT_INVALID, HB_USER_DATA_ARRAY_INIT} -+#define HB_OBJECT_HEADER_STATIC {HB_REFERENCE_COUNT_INIT, HB_USER_DATA_ARRAY_INIT} - - private: - ASSERT_POD (); -@@ -117,7 +120,7 @@ - DEBUG_MSG (OBJECT, (void *) obj, - "%s refcount=%d", - function, -- obj ? obj->header.ref_count.ref_count : 0); -+ obj ? obj->header.ref_count.get_unsafe () : 0); - } - - template <typename Type> -@@ -141,7 +144,12 @@ - template <typename Type> - static inline bool hb_object_is_inert (const Type *obj) - { -- return unlikely (obj->header.ref_count.is_invalid ()); -+ return unlikely (obj->header.ref_count.is_inert ()); -+} -+template <typename Type> -+static inline bool hb_object_is_valid (const Type *obj) -+{ -+ return likely (obj->header.ref_count.is_valid ()); - } - template <typename Type> - static inline Type *hb_object_reference (Type *obj) -@@ -149,6 +157,7 @@ - hb_object_trace (obj, HB_FUNC); - if (unlikely (!obj || hb_object_is_inert (obj))) - return obj; -+ assert (hb_object_is_valid (obj)); - obj->header.ref_count.inc (); - return obj; - } -@@ -158,6 +167,7 @@ - hb_object_trace (obj, HB_FUNC); - if (unlikely (!obj || hb_object_is_inert (obj))) - return false; -+ assert (hb_object_is_valid (obj)); - if (obj->header.ref_count.dec () != 1) - return false; - -@@ -174,6 +184,7 @@ - { - if (unlikely (!obj || hb_object_is_inert (obj))) - return false; -+ assert (hb_object_is_valid (obj)); - return obj->header.user_data.set (key, data, destroy, replace); - } - -@@ -183,6 +194,7 @@ - { - if (unlikely (!obj || hb_object_is_inert (obj))) - return NULL; -+ assert (hb_object_is_valid (obj)); - return obj->header.user_data.get (key); - } - -diff -uN gfx/harfbuzz/src_old/hb-open-file-private.hh gfx/harfbuzz/src/hb-open-file-private.hh ---- gfx/harfbuzz/src_old/hb-open-file-private.hh 2016-05-10 22:26:56.000000000 +0200 -+++ gfx/harfbuzz/src/hb-open-file-private.hh 2016-06-05 23:49:09.207076516 +0200 -@@ -53,9 +53,10 @@ - - typedef struct TableRecord - { -- inline bool sanitize (hb_sanitize_context_t *c) { -+ inline bool sanitize (hb_sanitize_context_t *c) const -+ { - TRACE_SANITIZE (this); -- return TRACE_RETURN (c->check_struct (this)); -+ return_trace (c->check_struct (this)); - } - - Tag tag; /* 4-byte identifier. */ -@@ -102,9 +103,10 @@ - } - - public: -- inline bool sanitize (hb_sanitize_context_t *c) { -+ inline bool sanitize (hb_sanitize_context_t *c) const -+ { - TRACE_SANITIZE (this); -- return TRACE_RETURN (c->check_struct (this) && c->check_array (tables, TableRecord::static_size, numTables)); -+ return_trace (c->check_struct (this) && c->check_array (tables, TableRecord::static_size, numTables)); - } - - protected: -@@ -130,9 +132,10 @@ - inline unsigned int get_face_count (void) const { return table.len; } - inline const OpenTypeFontFace& get_face (unsigned int i) const { return this+table[i]; } - -- inline bool sanitize (hb_sanitize_context_t *c) { -+ inline bool sanitize (hb_sanitize_context_t *c) const -+ { - TRACE_SANITIZE (this); -- return TRACE_RETURN (table.sanitize (c, this)); -+ return_trace (table.sanitize (c, this)); - } - - protected: -@@ -169,13 +172,14 @@ - } - } - -- inline bool sanitize (hb_sanitize_context_t *c) { -+ inline bool sanitize (hb_sanitize_context_t *c) const -+ { - TRACE_SANITIZE (this); -- if (unlikely (!u.header.version.sanitize (c))) return TRACE_RETURN (false); -+ if (unlikely (!u.header.version.sanitize (c))) return_trace (false); - switch (u.header.version.major) { - case 2: /* version 2 is compatible with version 1 */ -- case 1: return TRACE_RETURN (u.version1.sanitize (c)); -- default:return TRACE_RETURN (true); -+ case 1: return_trace (u.version1.sanitize (c)); -+ default:return_trace (true); - } - } - -@@ -233,16 +237,17 @@ - } - } - -- inline bool sanitize (hb_sanitize_context_t *c) { -+ inline bool sanitize (hb_sanitize_context_t *c) const -+ { - TRACE_SANITIZE (this); -- if (unlikely (!u.tag.sanitize (c))) return TRACE_RETURN (false); -+ if (unlikely (!u.tag.sanitize (c))) return_trace (false); - switch (u.tag) { - case CFFTag: /* All the non-collection tags */ - case TrueTag: - case Typ1Tag: -- case TrueTypeTag: return TRACE_RETURN (u.fontFace.sanitize (c)); -- case TTCTag: return TRACE_RETURN (u.ttcHeader.sanitize (c)); -- default: return TRACE_RETURN (true); -+ case TrueTypeTag: return_trace (u.fontFace.sanitize (c)); -+ case TTCTag: return_trace (u.ttcHeader.sanitize (c)); -+ default: return_trace (true); - } - } - -diff -uN gfx/harfbuzz/src_old/hb-open-type-private.hh gfx/harfbuzz/src/hb-open-type-private.hh ---- gfx/harfbuzz/src_old/hb-open-type-private.hh 2016-05-10 22:26:56.000000000 +0200 -+++ gfx/harfbuzz/src/hb-open-type-private.hh 2016-06-05 23:49:10.574069085 +0200 -@@ -103,9 +103,6 @@ - static const unsigned int static_size = (size); \ - static const unsigned int min_size = (size) - --/* Size signifying variable-sized array */ --#define VAR 1 -- - #define DEFINE_SIZE_UNION(size, _member) \ - DEFINE_INSTANCE_ASSERTION (this->u._member.static_size == (size)); \ - static const unsigned int min_size = (size) -@@ -154,6 +151,20 @@ - #define Null(Type) Null<Type>() - - -+/* -+ * Dispatch -+ */ -+ -+template <typename Context, typename Return, unsigned int MaxDebugDepth> -+struct hb_dispatch_context_t -+{ -+ static const unsigned int max_debug_depth = MaxDebugDepth; -+ typedef Return return_t; -+ template <typename T, typename F> -+ inline bool may_dispatch (const T *obj, const F *format) { return true; } -+ static return_t no_dispatch_return_value (void) { return Context::default_return_value (); } -+}; -+ - - /* - * Sanitize -@@ -171,18 +182,27 @@ - - /* This limits sanitizing time on really broken fonts. */ - #ifndef HB_SANITIZE_MAX_EDITS --#define HB_SANITIZE_MAX_EDITS 100 -+#define HB_SANITIZE_MAX_EDITS 32 - #endif - --struct hb_sanitize_context_t -+struct hb_sanitize_context_t : -+ hb_dispatch_context_t<hb_sanitize_context_t, bool, HB_DEBUG_SANITIZE> - { -+ inline hb_sanitize_context_t (void) : -+ debug_depth (0), -+ start (NULL), end (NULL), -+ writable (false), edit_count (0), -+ blob (NULL) {} -+ - inline const char *get_name (void) { return "SANITIZE"; } -- static const unsigned int max_debug_depth = HB_DEBUG_SANITIZE; -- typedef bool return_t; -+ template <typename T, typename F> -+ inline bool may_dispatch (const T *obj, const F *format) -+ { return format->sanitize (this); } - template <typename T> - inline return_t dispatch (const T &obj) { return obj.sanitize (this); } - static return_t default_return_value (void) { return true; } -- bool stop_sublookup_iteration (const return_t r HB_UNUSED) const { return false; } -+ static return_t no_dispatch_return_value (void) { return false; } -+ bool stop_sublookup_iteration (const return_t r) const { return !r; } - - inline void init (hb_blob_t *b) - { -@@ -270,9 +290,9 @@ - } - - template <typename Type, typename ValueType> -- inline bool try_set (Type *obj, const ValueType &v) { -+ inline bool try_set (const Type *obj, const ValueType &v) { - if (this->may_edit (obj, obj->static_size)) { -- obj->set (v); -+ const_cast<Type *> (obj)->set (v); - return true; - } - return false; -@@ -292,7 +312,7 @@ - struct Sanitizer - { - static hb_blob_t *sanitize (hb_blob_t *blob) { -- hb_sanitize_context_t c[1] = {{0, NULL, NULL, false, 0, NULL}}; -+ hb_sanitize_context_t c[1]; - bool sane; - - /* TODO is_sane() stuff */ -@@ -376,9 +396,9 @@ - - struct hb_serialize_context_t - { -- inline hb_serialize_context_t (void *start, unsigned int size) -+ inline hb_serialize_context_t (void *start_, unsigned int size) - { -- this->start = (char *) start; -+ this->start = (char *) start_; - this->end = this->start + size; - - this->ran_out_of_room = false; -@@ -472,10 +492,10 @@ - return reinterpret_cast<Type *> (&obj); - } - -- inline void truncate (void *head) -+ inline void truncate (void *new_head) - { -- assert (this->start < head && head <= this->head); -- this->head = (char *) head; -+ assert (this->start < new_head && new_head <= this->head); -+ this->head = (char *) new_head; - } - - unsigned int debug_depth; -@@ -533,6 +553,20 @@ - template <typename Type, int Bytes> struct BEInt; - - template <typename Type> -+struct BEInt<Type, 1> -+{ -+ public: -+ inline void set (Type V) -+ { -+ v = V; -+ } -+ inline operator Type (void) const -+ { -+ return v; -+ } -+ private: uint8_t v; -+}; -+template <typename Type> - struct BEInt<Type, 2> - { - public: -@@ -546,12 +580,6 @@ - return (v[0] << 8) - + (v[1] ); - } -- inline bool operator == (const BEInt<Type, 2>& o) const -- { -- return v[0] == o.v[0] -- && v[1] == o.v[1]; -- } -- inline bool operator != (const BEInt<Type, 2>& o) const { return !(*this == o); } - private: uint8_t v[2]; - }; - template <typename Type> -@@ -570,13 +598,6 @@ - + (v[1] << 8) - + (v[2] ); - } -- inline bool operator == (const BEInt<Type, 3>& o) const -- { -- return v[0] == o.v[0] -- && v[1] == o.v[1] -- && v[2] == o.v[2]; -- } -- inline bool operator != (const BEInt<Type, 3>& o) const { return !(*this == o); } - private: uint8_t v[3]; - }; - template <typename Type> -@@ -597,14 +618,6 @@ - + (v[2] << 8) - + (v[3] ); - } -- inline bool operator == (const BEInt<Type, 4>& o) const -- { -- return v[0] == o.v[0] -- && v[1] == o.v[1] -- && v[2] == o.v[2] -- && v[3] == o.v[3]; -- } -- inline bool operator != (const BEInt<Type, 4>& o) const { return !(*this == o); } - private: uint8_t v[4]; - }; - -@@ -614,14 +627,21 @@ - { - inline void set (Type i) { v.set (i); } - inline operator Type(void) const { return v; } -- inline bool operator == (const IntType<Type,Size> &o) const { return v == o.v; } -- inline bool operator != (const IntType<Type,Size> &o) const { return v != o.v; } -+ inline bool operator == (const IntType<Type,Size> &o) const { return (Type) v == (Type) o.v; } -+ inline bool operator != (const IntType<Type,Size> &o) const { return !(*this == o); } - static inline int cmp (const IntType<Type,Size> *a, const IntType<Type,Size> *b) { return b->cmp (*a); } -- inline int cmp (IntType<Type,Size> va) const { Type a = va; Type b = v; return a < b ? -1 : a == b ? 0 : +1; } -- inline int cmp (Type a) const { Type b = v; return a < b ? -1 : a == b ? 0 : +1; } -- inline bool sanitize (hb_sanitize_context_t *c) { -+ inline int cmp (Type a) const -+ { -+ Type b = v; -+ if (sizeof (Type) < sizeof (int)) -+ return (int) a - (int) b; -+ else -+ return a < b ? -1 : a == b ? 0 : +1; -+ } -+ inline bool sanitize (hb_sanitize_context_t *c) const -+ { - TRACE_SANITIZE (this); -- return TRACE_RETURN (likely (c->check_struct (this))); -+ return_trace (likely (c->check_struct (this))); - } - protected: - BEInt<Type, Size> v; -@@ -629,7 +649,7 @@ - DEFINE_SIZE_STATIC (Size); - }; - --typedef uint8_t BYTE; /* 8-bit unsigned integer. */ -+typedef IntType<uint8_t , 1> BYTE; /* 8-bit unsigned integer. */ - typedef IntType<uint16_t, 2> USHORT; /* 16-bit unsigned integer. */ - typedef IntType<int16_t, 2> SHORT; /* 16-bit signed integer. */ - typedef IntType<uint32_t, 4> ULONG; /* 32-bit unsigned integer. */ -@@ -646,9 +666,10 @@ - * 1904. The value is represented as a signed 64-bit integer. */ - struct LONGDATETIME - { -- inline bool sanitize (hb_sanitize_context_t *c) { -+ inline bool sanitize (hb_sanitize_context_t *c) const -+ { - TRACE_SANITIZE (this); -- return TRACE_RETURN (likely (c->check_struct (this))); -+ return_trace (likely (c->check_struct (this))); - } - protected: - LONG major; -@@ -670,7 +691,10 @@ - DEFINE_NULL_DATA (Tag, " "); - - /* Glyph index number, same as uint16 (length = 16 bits) */ --typedef USHORT GlyphID; -+struct GlyphID : USHORT { -+ static inline int cmp (const GlyphID *a, const GlyphID *b) { return b->USHORT::cmp (*a); } -+ inline int cmp (hb_codepoint_t a) const { return (int) a - (int) *this; } -+}; - - /* Script/language-system/feature index */ - struct Index : USHORT { -@@ -719,9 +743,10 @@ - { - inline uint32_t to_int (void) const { return (major << 16) + minor; } - -- inline bool sanitize (hb_sanitize_context_t *c) { -+ inline bool sanitize (hb_sanitize_context_t *c) const -+ { - TRACE_SANITIZE (this); -- return TRACE_RETURN (c->check_struct (this)); -+ return_trace (c->check_struct (this)); - } - - USHORT major; -@@ -747,33 +772,35 @@ - return StructAtOffset<Type> (base, offset); - } - -- inline Type& serialize (hb_serialize_context_t *c, void *base) -+ inline Type& serialize (hb_serialize_context_t *c, const void *base) - { - Type *t = c->start_embed<Type> (); - this->set ((char *) t - (char *) base); /* TODO(serialize) Overflow? */ - return *t; - } - -- inline bool sanitize (hb_sanitize_context_t *c, void *base) { -+ inline bool sanitize (hb_sanitize_context_t *c, const void *base) const -+ { - TRACE_SANITIZE (this); -- if (unlikely (!c->check_struct (this))) return TRACE_RETURN (false); -+ if (unlikely (!c->check_struct (this))) return_trace (false); - unsigned int offset = *this; -- if (unlikely (!offset)) return TRACE_RETURN (true); -- Type &obj = StructAtOffset<Type> (base, offset); -- return TRACE_RETURN (likely (obj.sanitize (c)) || neuter (c)); -+ if (unlikely (!offset)) return_trace (true); -+ const Type &obj = StructAtOffset<Type> (base, offset); -+ return_trace (likely (obj.sanitize (c)) || neuter (c)); - } - template <typename T> -- inline bool sanitize (hb_sanitize_context_t *c, void *base, T user_data) { -+ inline bool sanitize (hb_sanitize_context_t *c, const void *base, T user_data) const -+ { - TRACE_SANITIZE (this); -- if (unlikely (!c->check_struct (this))) return TRACE_RETURN (false); -+ if (unlikely (!c->check_struct (this))) return_trace (false); - unsigned int offset = *this; -- if (unlikely (!offset)) return TRACE_RETURN (true); -- Type &obj = StructAtOffset<Type> (base, offset); -- return TRACE_RETURN (likely (obj.sanitize (c, user_data)) || neuter (c)); -+ if (unlikely (!offset)) return_trace (true); -+ const Type &obj = StructAtOffset<Type> (base, offset); -+ return_trace (likely (obj.sanitize (c, user_data)) || neuter (c)); - } - - /* Set the offset to Null */ -- inline bool neuter (hb_sanitize_context_t *c) { -+ inline bool neuter (hb_sanitize_context_t *c) const { - return c->try_set (this, 0); - } - DEFINE_SIZE_STATIC (sizeof(OffsetType)); -@@ -820,10 +847,10 @@ - unsigned int items_len) - { - TRACE_SERIALIZE (this); -- if (unlikely (!c->extend_min (*this))) return TRACE_RETURN (false); -+ if (unlikely (!c->extend_min (*this))) return_trace (false); - len.set (items_len); /* TODO(serialize) Overflow? */ -- if (unlikely (!c->extend (*this))) return TRACE_RETURN (false); -- return TRACE_RETURN (true); -+ if (unlikely (!c->extend (*this))) return_trace (false); -+ return_trace (true); - } - - inline bool serialize (hb_serialize_context_t *c, -@@ -831,16 +858,17 @@ - unsigned int items_len) - { - TRACE_SERIALIZE (this); -- if (unlikely (!serialize (c, items_len))) return TRACE_RETURN (false); -+ if (unlikely (!serialize (c, items_len))) return_trace (false); - for (unsigned int i = 0; i < items_len; i++) - array[i] = items[i]; - items.advance (items_len); -- return TRACE_RETURN (true); -+ return_trace (true); - } - -- inline bool sanitize (hb_sanitize_context_t *c) { -+ inline bool sanitize (hb_sanitize_context_t *c) const -+ { - TRACE_SANITIZE (this); -- if (unlikely (!sanitize_shallow (c))) return TRACE_RETURN (false); -+ 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 -@@ -851,26 +879,28 @@ - */ - (void) (false && array[0].sanitize (c)); - -- return TRACE_RETURN (true); -+ return_trace (true); - } -- inline bool sanitize (hb_sanitize_context_t *c, void *base) { -+ inline bool sanitize (hb_sanitize_context_t *c, const void *base) const -+ { - TRACE_SANITIZE (this); -- if (unlikely (!sanitize_shallow (c))) return TRACE_RETURN (false); -+ if (unlikely (!sanitize_shallow (c))) return_trace (false); - unsigned int count = len; - for (unsigned int i = 0; i < count; i++) - if (unlikely (!array[i].sanitize (c, base))) -- return TRACE_RETURN (false); -- return TRACE_RETURN (true); -+ return_trace (false); -+ return_trace (true); - } - template <typename T> -- inline bool sanitize (hb_sanitize_context_t *c, void *base, T user_data) { -+ inline bool sanitize (hb_sanitize_context_t *c, const void *base, T user_data) const -+ { - TRACE_SANITIZE (this); -- if (unlikely (!sanitize_shallow (c))) return TRACE_RETURN (false); -+ if (unlikely (!sanitize_shallow (c))) return_trace (false); - unsigned int count = len; - for (unsigned int i = 0; i < count; i++) - if (unlikely (!array[i].sanitize (c, base, user_data))) -- return TRACE_RETURN (false); -- return TRACE_RETURN (true); -+ return_trace (false); -+ return_trace (true); - } - - template <typename SearchType> -@@ -884,9 +914,10 @@ - } - - private: -- inline bool sanitize_shallow (hb_sanitize_context_t *c) { -+ inline bool sanitize_shallow (hb_sanitize_context_t *c) const -+ { - TRACE_SANITIZE (this); -- return TRACE_RETURN (c->check_struct (this) && c->check_array (this, Type::static_size, len)); -+ return_trace (c->check_struct (this) && c->check_array (array, Type::static_size, len)); - } - - public: -@@ -910,14 +941,16 @@ - return this+this->array[i]; - } - -- inline bool sanitize (hb_sanitize_context_t *c) { -+ inline bool sanitize (hb_sanitize_context_t *c) const -+ { - TRACE_SANITIZE (this); -- return TRACE_RETURN (OffsetArrayOf<Type>::sanitize (c, this)); -+ return_trace (OffsetArrayOf<Type>::sanitize (c, this)); - } - template <typename T> -- inline bool sanitize (hb_sanitize_context_t *c, T user_data) { -+ inline bool sanitize (hb_sanitize_context_t *c, T user_data) const -+ { - TRACE_SANITIZE (this); -- return TRACE_RETURN (OffsetArrayOf<Type>::sanitize (c, this, user_data)); -+ return_trace (OffsetArrayOf<Type>::sanitize (c, this, user_data)); - } - }; - -@@ -939,24 +972,26 @@ - unsigned int items_len) - { - TRACE_SERIALIZE (this); -- if (unlikely (!c->extend_min (*this))) return TRACE_RETURN (false); -+ if (unlikely (!c->extend_min (*this))) return_trace (false); - len.set (items_len); /* TODO(serialize) Overflow? */ -- if (unlikely (!items_len)) return TRACE_RETURN (true); -- if (unlikely (!c->extend (*this))) return TRACE_RETURN (false); -+ if (unlikely (!items_len)) return_trace (true); -+ if (unlikely (!c->extend (*this))) return_trace (false); - for (unsigned int i = 0; i < items_len - 1; i++) - array[i] = items[i]; - items.advance (items_len - 1); -- return TRACE_RETURN (true); -+ return_trace (true); - } - -- inline bool sanitize_shallow (hb_sanitize_context_t *c) { -+ inline bool sanitize_shallow (hb_sanitize_context_t *c) const -+ { - return c->check_struct (this) - && c->check_array (this, Type::static_size, len); - } - -- inline bool sanitize (hb_sanitize_context_t *c) { -+ inline bool sanitize (hb_sanitize_context_t *c) const -+ { - TRACE_SANITIZE (this); -- if (unlikely (!sanitize_shallow (c))) return TRACE_RETURN (false); -+ 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 -@@ -967,7 +1002,7 @@ - */ - (void) (false && array[0].sanitize (c)); - -- return TRACE_RETURN (true); -+ return_trace (true); - } - - LenType len; -diff -uN gfx/harfbuzz/src_old/hb-ot-cmap-table.hh gfx/harfbuzz/src/hb-ot-cmap-table.hh ---- gfx/harfbuzz/src_old/hb-ot-cmap-table.hh 2016-05-10 22:26:56.000000000 +0200 -+++ gfx/harfbuzz/src/hb-ot-cmap-table.hh 2016-06-05 23:49:11.982061464 +0200 -@@ -51,9 +51,10 @@ - return true; - } - -- inline bool sanitize (hb_sanitize_context_t *c) { -+ inline bool sanitize (hb_sanitize_context_t *c) const -+ { - TRACE_SANITIZE (this); -- return TRACE_RETURN (c->check_struct (this)); -+ return_trace (c->check_struct (this)); - } - - protected: -@@ -125,11 +126,11 @@ - return true; - } - -- inline bool sanitize (hb_sanitize_context_t *c) -+ inline bool sanitize (hb_sanitize_context_t *c) const - { - TRACE_SANITIZE (this); - if (unlikely (!c->check_struct (this))) -- return TRACE_RETURN (false); -+ return_trace (false); - - if (unlikely (!c->check_range (this, length))) - { -@@ -140,10 +141,10 @@ - (uintptr_t) (c->end - - (char *) this)); - if (!c->try_set (&length, new_length)) -- return TRACE_RETURN (false); -+ return_trace (false); - } - -- return TRACE_RETURN (16 + 4 * (unsigned int) segCountX2 <= length); -+ return_trace (16 + 4 * (unsigned int) segCountX2 <= length); - } - - protected: -@@ -183,9 +184,10 @@ - return 0; - } - -- inline bool sanitize (hb_sanitize_context_t *c) { -+ inline bool sanitize (hb_sanitize_context_t *c) const -+ { - TRACE_SANITIZE (this); -- return TRACE_RETURN (c->check_struct (this)); -+ return_trace (c->check_struct (this)); - } - - private: -@@ -210,9 +212,10 @@ - return true; - } - -- inline bool sanitize (hb_sanitize_context_t *c) { -+ inline bool sanitize (hb_sanitize_context_t *c) const -+ { - TRACE_SANITIZE (this); -- return TRACE_RETURN (c->check_struct (this) && glyphIdArray.sanitize (c)); -+ return_trace (c->check_struct (this) && glyphIdArray.sanitize (c)); - } - - protected: -@@ -242,9 +245,10 @@ - return true; - } - -- inline bool sanitize (hb_sanitize_context_t *c) { -+ inline bool sanitize (hb_sanitize_context_t *c) const -+ { - TRACE_SANITIZE (this); -- return TRACE_RETURN (c->check_struct (this) && groups.sanitize (c)); -+ return_trace (c->check_struct (this) && groups.sanitize (c)); - } - - protected: -@@ -288,9 +292,10 @@ - return 0; - } - -- inline bool sanitize (hb_sanitize_context_t *c) { -+ inline bool sanitize (hb_sanitize_context_t *c) const -+ { - TRACE_SANITIZE (this); -- return TRACE_RETURN (c->check_struct (this)); -+ return_trace (c->check_struct (this)); - } - - UINT24 startUnicodeValue; /* First value in this range. */ -@@ -309,9 +314,10 @@ - return unicodeValue.cmp (codepoint); - } - -- inline bool sanitize (hb_sanitize_context_t *c) { -+ inline bool sanitize (hb_sanitize_context_t *c) const -+ { - TRACE_SANITIZE (this); -- return TRACE_RETURN (c->check_struct (this)); -+ return_trace (c->check_struct (this)); - } - - UINT24 unicodeValue; /* Base Unicode value of the UVS */ -@@ -348,11 +354,12 @@ - return varSelector.cmp (variation_selector); - } - -- inline bool sanitize (hb_sanitize_context_t *c, void *base) { -+ inline bool sanitize (hb_sanitize_context_t *c, const void *base) const -+ { - TRACE_SANITIZE (this); -- return TRACE_RETURN (c->check_struct (this) && -- defaultUVS.sanitize (c, base) && -- nonDefaultUVS.sanitize (c, base)); -+ return_trace (c->check_struct (this) && -+ defaultUVS.sanitize (c, base) && -+ nonDefaultUVS.sanitize (c, base)); - } - - UINT24 varSelector; /* Variation selector. */ -@@ -373,10 +380,11 @@ - return record[record.bsearch(variation_selector)].get_glyph (codepoint, glyph, this); - } - -- inline bool sanitize (hb_sanitize_context_t *c) { -+ inline bool sanitize (hb_sanitize_context_t *c) const -+ { - TRACE_SANITIZE (this); -- return TRACE_RETURN (c->check_struct (this) && -- record.sanitize (c, this)); -+ return_trace (c->check_struct (this) && -+ record.sanitize (c, this)); - } - - protected: -@@ -418,18 +426,19 @@ - } - } - -- inline bool sanitize (hb_sanitize_context_t *c) { -+ inline bool sanitize (hb_sanitize_context_t *c) const -+ { - TRACE_SANITIZE (this); -- if (!u.format.sanitize (c)) return TRACE_RETURN (false); -+ if (!u.format.sanitize (c)) return_trace (false); - switch (u.format) { -- case 0: return TRACE_RETURN (u.format0 .sanitize (c)); -- case 4: return TRACE_RETURN (u.format4 .sanitize (c)); -- case 6: return TRACE_RETURN (u.format6 .sanitize (c)); -- case 10: return TRACE_RETURN (u.format10.sanitize (c)); -- case 12: return TRACE_RETURN (u.format12.sanitize (c)); -- case 13: return TRACE_RETURN (u.format13.sanitize (c)); -- case 14: return TRACE_RETURN (u.format14.sanitize (c)); -- default:return TRACE_RETURN (true); -+ case 0: return_trace (u.format0 .sanitize (c)); -+ case 4: return_trace (u.format4 .sanitize (c)); -+ case 6: return_trace (u.format6 .sanitize (c)); -+ case 10: return_trace (u.format10.sanitize (c)); -+ case 12: return_trace (u.format12.sanitize (c)); -+ case 13: return_trace (u.format13.sanitize (c)); -+ case 14: return_trace (u.format14.sanitize (c)); -+ default:return_trace (true); - } - } - -@@ -461,10 +470,11 @@ - return 0; - } - -- inline bool sanitize (hb_sanitize_context_t *c, void *base) { -+ inline bool sanitize (hb_sanitize_context_t *c, const void *base) const -+ { - TRACE_SANITIZE (this); -- return TRACE_RETURN (c->check_struct (this) && -- subtable.sanitize (c, base)); -+ return_trace (c->check_struct (this) && -+ subtable.sanitize (c, base)); - } - - USHORT platformID; /* Platform ID. */ -@@ -496,11 +506,12 @@ - return &(this+encodingRecord[result].subtable); - } - -- inline bool sanitize (hb_sanitize_context_t *c) { -+ inline bool sanitize (hb_sanitize_context_t *c) const -+ { - TRACE_SANITIZE (this); -- return TRACE_RETURN (c->check_struct (this) && -- likely (version == 0) && -- encodingRecord.sanitize (c, this)); -+ return_trace (c->check_struct (this) && -+ likely (version == 0) && -+ encodingRecord.sanitize (c, this)); - } - - USHORT version; /* Table version number (0). */ -diff -uN gfx/harfbuzz/src_old/hb-ot-font.cc gfx/harfbuzz/src/hb-ot-font.cc ---- gfx/harfbuzz/src_old/hb-ot-font.cc 2016-05-10 22:26:56.000000000 +0200 -+++ gfx/harfbuzz/src/hb-ot-font.cc 2016-06-05 23:49:13.433053614 +0200 -@@ -31,8 +31,11 @@ - #include "hb-font-private.hh" - - #include "hb-ot-cmap-table.hh" -+#include "hb-ot-glyf-table.hh" -+#include "hb-ot-head-table.hh" - #include "hb-ot-hhea-table.hh" - #include "hb-ot-hmtx-table.hh" -+#include "hb-ot-os2-table.hh" - - - struct hb_ot_face_metrics_accelerator_t -@@ -40,24 +43,58 @@ - unsigned int num_metrics; - unsigned int num_advances; - unsigned int default_advance; -+ unsigned short ascender; -+ unsigned short descender; -+ unsigned short line_gap; -+ - const OT::_mtx *table; - hb_blob_t *blob; - - inline void init (hb_face_t *face, -- hb_tag_t _hea_tag, hb_tag_t _mtx_tag, -- unsigned int default_advance) -+ hb_tag_t _hea_tag, -+ hb_tag_t _mtx_tag, -+ hb_tag_t os2_tag) - { -- this->default_advance = default_advance; -- this->num_metrics = face->get_num_glyphs (); -+ this->default_advance = face->get_upem (); -+ -+ bool got_font_extents = false; -+ if (os2_tag) -+ { -+ hb_blob_t *os2_blob = OT::Sanitizer<OT::os2>::sanitize (face->reference_table (os2_tag)); -+ const OT::os2 *os2 = OT::Sanitizer<OT::os2>::lock_instance (os2_blob); -+#define USE_TYPO_METRICS (1u<<7) -+ if (0 != (os2->fsSelection & USE_TYPO_METRICS)) -+ { -+ this->ascender = os2->sTypoAscender; -+ this->descender = os2->sTypoDescender; -+ this->line_gap = os2->sTypoLineGap; -+ got_font_extents = (this->ascender | this->descender) != 0; -+ } -+ hb_blob_destroy (os2_blob); -+ } - - hb_blob_t *_hea_blob = OT::Sanitizer<OT::_hea>::sanitize (face->reference_table (_hea_tag)); - const OT::_hea *_hea = OT::Sanitizer<OT::_hea>::lock_instance (_hea_blob); - this->num_advances = _hea->numberOfLongMetrics; -+ if (!got_font_extents) -+ { -+ this->ascender = _hea->ascender; -+ this->descender = _hea->descender; -+ this->line_gap = _hea->lineGap; -+ } - hb_blob_destroy (_hea_blob); - - this->blob = OT::Sanitizer<OT::_mtx>::sanitize (face->reference_table (_mtx_tag)); -- if (unlikely (!this->num_advances || -- 2 * (this->num_advances + this->num_metrics) < hb_blob_get_length (this->blob))) -+ -+ /* Cap num_metrics() and num_advances() based on table length. */ -+ unsigned int len = hb_blob_get_length (this->blob); -+ if (unlikely (this->num_advances * 4 > len)) -+ this->num_advances = len / 4; -+ this->num_metrics = this->num_advances + (len - 4 * this->num_advances) / 2; -+ -+ /* We MUST set num_metrics to zero if num_advances is zero. -+ * Our get_advance() depends on that. */ -+ if (unlikely (!this->num_advances)) - { - this->num_metrics = this->num_advances = 0; - hb_blob_destroy (this->blob); -@@ -76,8 +113,8 @@ - if (unlikely (glyph >= this->num_metrics)) - { - /* If this->num_metrics is zero, it means we don't have the metrics table -- * for this direction: return one EM. Otherwise, it means that the glyph -- * index is out of bound: return zero. */ -+ * for this direction: return default advance. Otherwise, it means that the -+ * glyph index is out of bound: return zero. */ - if (this->num_metrics) - return 0; - else -@@ -91,6 +128,79 @@ - } - }; - -+struct hb_ot_face_glyf_accelerator_t -+{ -+ bool short_offset; -+ unsigned int num_glyphs; -+ const OT::loca *loca; -+ const OT::glyf *glyf; -+ hb_blob_t *loca_blob; -+ hb_blob_t *glyf_blob; -+ unsigned int glyf_len; -+ -+ inline void init (hb_face_t *face) -+ { -+ hb_blob_t *head_blob = OT::Sanitizer<OT::head>::sanitize (face->reference_table (HB_OT_TAG_head)); -+ const OT::head *head = OT::Sanitizer<OT::head>::lock_instance (head_blob); -+ if ((unsigned int) head->indexToLocFormat > 1 || head->glyphDataFormat != 0) -+ { -+ /* Unknown format. Leave num_glyphs=0, that takes care of disabling us. */ -+ hb_blob_destroy (head_blob); -+ return; -+ } -+ this->short_offset = 0 == head->indexToLocFormat; -+ hb_blob_destroy (head_blob); -+ -+ this->loca_blob = OT::Sanitizer<OT::loca>::sanitize (face->reference_table (HB_OT_TAG_loca)); -+ this->loca = OT::Sanitizer<OT::loca>::lock_instance (this->loca_blob); -+ this->glyf_blob = OT::Sanitizer<OT::glyf>::sanitize (face->reference_table (HB_OT_TAG_glyf)); -+ this->glyf = OT::Sanitizer<OT::glyf>::lock_instance (this->glyf_blob); -+ -+ this->num_glyphs = MAX (1u, hb_blob_get_length (this->loca_blob) / (this->short_offset ? 2 : 4)) - 1; -+ this->glyf_len = hb_blob_get_length (this->glyf_blob); -+ } -+ -+ inline void fini (void) -+ { -+ hb_blob_destroy (this->loca_blob); -+ hb_blob_destroy (this->glyf_blob); -+ } -+ -+ inline bool get_extents (hb_codepoint_t glyph, -+ hb_glyph_extents_t *extents) const -+ { -+ if (unlikely (glyph >= this->num_glyphs)) -+ return false; -+ -+ unsigned int start_offset, end_offset; -+ if (this->short_offset) -+ { -+ start_offset = 2 * this->loca->u.shortsZ[glyph]; -+ end_offset = 2 * this->loca->u.shortsZ[glyph + 1]; -+ } -+ else -+ { -+ start_offset = this->loca->u.longsZ[glyph]; -+ end_offset = this->loca->u.longsZ[glyph + 1]; -+ } -+ -+ if (start_offset > end_offset || end_offset > this->glyf_len) -+ return false; -+ -+ if (end_offset - start_offset < OT::glyfGlyphHeader::static_size) -+ return true; /* Empty glyph; zero extents. */ -+ -+ const OT::glyfGlyphHeader &glyph_header = OT::StructAtOffset<OT::glyfGlyphHeader> (this->glyf, start_offset); -+ -+ extents->x_bearing = MIN (glyph_header.xMin, glyph_header.xMax); -+ extents->y_bearing = MAX (glyph_header.yMin, glyph_header.yMax); -+ extents->width = MAX (glyph_header.xMin, glyph_header.xMax) - extents->x_bearing; -+ extents->height = MIN (glyph_header.yMin, glyph_header.yMax) - extents->y_bearing; -+ -+ return true; -+ } -+}; -+ - struct hb_ot_face_cmap_accelerator_t - { - const OT::CmapSubtable *table; -@@ -114,6 +224,7 @@ - if (!subtable) subtable = cmap->find_subtable (0, 2); - if (!subtable) subtable = cmap->find_subtable (0, 1); - if (!subtable) subtable = cmap->find_subtable (0, 0); -+ if (!subtable) subtable = cmap->find_subtable (3, 0); - /* Meh. */ - if (!subtable) subtable = &OT::Null(OT::CmapSubtable); - -@@ -157,23 +268,22 @@ - hb_ot_face_cmap_accelerator_t cmap; - hb_ot_face_metrics_accelerator_t h_metrics; - hb_ot_face_metrics_accelerator_t v_metrics; -+ hb_ot_face_glyf_accelerator_t glyf; - }; - - - static hb_ot_font_t * --_hb_ot_font_create (hb_font_t *font) -+_hb_ot_font_create (hb_face_t *face) - { - hb_ot_font_t *ot_font = (hb_ot_font_t *) calloc (1, sizeof (hb_ot_font_t)); -- hb_face_t *face = font->face; - - if (unlikely (!ot_font)) - return NULL; - -- unsigned int upem = face->get_upem (); -- - ot_font->cmap.init (face); -- ot_font->h_metrics.init (face, HB_OT_TAG_hhea, HB_OT_TAG_hmtx, upem>>1); -- ot_font->v_metrics.init (face, HB_OT_TAG_vhea, HB_OT_TAG_vmtx, upem); /* TODO Can we do this lazily? */ -+ ot_font->h_metrics.init (face, HB_OT_TAG_hhea, HB_OT_TAG_hmtx, HB_OT_TAG_os2); -+ ot_font->v_metrics.init (face, HB_OT_TAG_vhea, HB_OT_TAG_vmtx, HB_TAG_NONE); /* TODO Can we do this lazily? */ -+ ot_font->glyf.init (face); - - return ot_font; - } -@@ -184,6 +294,7 @@ - ot_font->cmap.fini (); - ot_font->h_metrics.fini (); - ot_font->v_metrics.fini (); -+ ot_font->glyf.fini (); - - free (ot_font); - } -@@ -219,53 +330,7 @@ - void *user_data HB_UNUSED) - { - const hb_ot_font_t *ot_font = (const hb_ot_font_t *) font_data; -- return font->em_scale_y (-ot_font->v_metrics.get_advance (glyph)); --} -- --static hb_bool_t --hb_ot_get_glyph_h_origin (hb_font_t *font HB_UNUSED, -- void *font_data HB_UNUSED, -- hb_codepoint_t glyph HB_UNUSED, -- hb_position_t *x HB_UNUSED, -- hb_position_t *y HB_UNUSED, -- void *user_data HB_UNUSED) --{ -- /* We always work in the horizontal coordinates. */ -- return true; --} -- --static hb_bool_t --hb_ot_get_glyph_v_origin (hb_font_t *font HB_UNUSED, -- void *font_data, -- hb_codepoint_t glyph, -- hb_position_t *x, -- hb_position_t *y, -- void *user_data HB_UNUSED) --{ -- /* TODO */ -- return false; --} -- --static hb_position_t --hb_ot_get_glyph_h_kerning (hb_font_t *font, -- void *font_data, -- hb_codepoint_t left_glyph, -- hb_codepoint_t right_glyph, -- void *user_data HB_UNUSED) --{ -- /* TODO */ -- return 0; --} -- --static hb_position_t --hb_ot_get_glyph_v_kerning (hb_font_t *font HB_UNUSED, -- void *font_data HB_UNUSED, -- hb_codepoint_t top_glyph HB_UNUSED, -- hb_codepoint_t bottom_glyph HB_UNUSED, -- void *user_data HB_UNUSED) --{ -- /* OpenType doesn't have vertical-kerning other than GPOS. */ -- return 0; -+ return font->em_scale_y (-(int) ot_font->v_metrics.get_advance (glyph)); - } - - static hb_bool_t -@@ -275,69 +340,100 @@ - hb_glyph_extents_t *extents, - void *user_data HB_UNUSED) - { -- /* TODO */ -- return false; -+ const hb_ot_font_t *ot_font = (const hb_ot_font_t *) font_data; -+ bool ret = ot_font->glyf.get_extents (glyph, extents); -+ extents->x_bearing = font->em_scale_x (extents->x_bearing); -+ extents->y_bearing = font->em_scale_y (extents->y_bearing); -+ extents->width = font->em_scale_x (extents->width); -+ extents->height = font->em_scale_y (extents->height); -+ return ret; - } - - static hb_bool_t --hb_ot_get_glyph_contour_point (hb_font_t *font HB_UNUSED, -- void *font_data, -- hb_codepoint_t glyph, -- unsigned int point_index, -- hb_position_t *x, -- hb_position_t *y, -- void *user_data HB_UNUSED) -+hb_ot_get_font_h_extents (hb_font_t *font HB_UNUSED, -+ void *font_data, -+ hb_font_extents_t *metrics, -+ void *user_data HB_UNUSED) - { -- /* TODO */ -- return false; -+ const hb_ot_font_t *ot_font = (const hb_ot_font_t *) font_data; -+ metrics->ascender = font->em_scale_y (ot_font->h_metrics.ascender); -+ metrics->descender = font->em_scale_y (ot_font->h_metrics.descender); -+ metrics->line_gap = font->em_scale_y (ot_font->h_metrics.line_gap); -+ return true; - } - - static hb_bool_t --hb_ot_get_glyph_name (hb_font_t *font HB_UNUSED, -- void *font_data, -- hb_codepoint_t glyph, -- char *name, unsigned int size, -- void *user_data HB_UNUSED) -+hb_ot_get_font_v_extents (hb_font_t *font HB_UNUSED, -+ void *font_data, -+ hb_font_extents_t *metrics, -+ void *user_data HB_UNUSED) - { -- /* TODO */ -- return false; -+ const hb_ot_font_t *ot_font = (const hb_ot_font_t *) font_data; -+ metrics->ascender = font->em_scale_x (ot_font->v_metrics.ascender); -+ metrics->descender = font->em_scale_x (ot_font->v_metrics.descender); -+ metrics->line_gap = font->em_scale_x (ot_font->v_metrics.line_gap); -+ return true; - } - --static hb_bool_t --hb_ot_get_glyph_from_name (hb_font_t *font HB_UNUSED, -- void *font_data, -- const char *name, int len, /* -1 means nul-terminated */ -- hb_codepoint_t *glyph, -- void *user_data HB_UNUSED) -+static hb_font_funcs_t *static_ot_funcs = NULL; -+ -+#ifdef HB_USE_ATEXIT -+static -+void free_static_ot_funcs (void) - { -- /* TODO */ -- return false; -+ hb_font_funcs_destroy (static_ot_funcs); - } -- -+#endif - - static hb_font_funcs_t * - _hb_ot_get_font_funcs (void) - { -- static const hb_font_funcs_t ot_ffuncs = { -- HB_OBJECT_HEADER_STATIC, -+retry: -+ hb_font_funcs_t *funcs = (hb_font_funcs_t *) hb_atomic_ptr_get (&static_ot_funcs); - -- true, /* immutable */ -+ if (unlikely (!funcs)) -+ { -+ funcs = hb_font_funcs_create (); - -- { --#define HB_FONT_FUNC_IMPLEMENT(name) hb_ot_get_##name, -- HB_FONT_FUNCS_IMPLEMENT_CALLBACKS --#undef HB_FONT_FUNC_IMPLEMENT -+ hb_font_funcs_set_font_h_extents_func (funcs, hb_ot_get_font_h_extents, NULL, NULL); -+ hb_font_funcs_set_font_v_extents_func (funcs, hb_ot_get_font_v_extents, NULL, NULL); -+ hb_font_funcs_set_glyph_func (funcs, hb_ot_get_glyph, NULL, NULL); -+ hb_font_funcs_set_glyph_h_advance_func (funcs, hb_ot_get_glyph_h_advance, NULL, NULL); -+ hb_font_funcs_set_glyph_v_advance_func (funcs, hb_ot_get_glyph_v_advance, NULL, NULL); -+ //hb_font_funcs_set_glyph_h_origin_func (funcs, hb_ot_get_glyph_h_origin, NULL, NULL); -+ //hb_font_funcs_set_glyph_v_origin_func (funcs, hb_ot_get_glyph_v_origin, NULL, NULL); -+ //hb_font_funcs_set_glyph_h_kerning_func (funcs, hb_ot_get_glyph_h_kerning, NULL, NULL); TODO -+ //hb_font_funcs_set_glyph_v_kerning_func (funcs, hb_ot_get_glyph_v_kerning, NULL, NULL); -+ hb_font_funcs_set_glyph_extents_func (funcs, hb_ot_get_glyph_extents, NULL, NULL); -+ //hb_font_funcs_set_glyph_contour_point_func (funcs, hb_ot_get_glyph_contour_point, NULL, NULL); TODO -+ //hb_font_funcs_set_glyph_name_func (funcs, hb_ot_get_glyph_name, NULL, NULL); TODO -+ //hb_font_funcs_set_glyph_from_name_func (funcs, hb_ot_get_glyph_from_name, NULL, NULL); TODO -+ -+ hb_font_funcs_make_immutable (funcs); -+ -+ if (!hb_atomic_ptr_cmpexch (&static_ot_funcs, NULL, funcs)) { -+ hb_font_funcs_destroy (funcs); -+ goto retry; - } -+ -+#ifdef HB_USE_ATEXIT -+ atexit (free_static_ot_funcs); /* First person registers atexit() callback. */ -+#endif - }; - -- return const_cast<hb_font_funcs_t *> (&ot_ffuncs); -+ return funcs; - } - - -+/** -+ * hb_ot_font_set_funcs: -+ * -+ * Since: 0.9.28 -+ **/ - void - hb_ot_font_set_funcs (hb_font_t *font) - { -- hb_ot_font_t *ot_font = _hb_ot_font_create (font); -+ hb_ot_font_t *ot_font = _hb_ot_font_create (font->face); - if (unlikely (!ot_font)) - return; - -diff -uN gfx/harfbuzz/src_old/hb-ot-font.h gfx/harfbuzz/src/hb-ot-font.h ---- gfx/harfbuzz/src_old/hb-ot-font.h 2016-05-10 22:26:56.000000000 +0200 -+++ gfx/harfbuzz/src/hb-ot-font.h 2016-06-05 23:49:14.679046863 +0200 -@@ -24,6 +24,10 @@ - * Google Author(s): Behdad Esfahbod, Roozbeh Pournader - */ - -+#ifndef HB_OT_H_IN -+#error "Include <hb-ot.h> instead." -+#endif -+ - #ifndef HB_OT_FONT_H - #define HB_OT_FONT_H - -@@ -32,7 +36,7 @@ - HB_BEGIN_DECLS - - --void -+HB_EXTERN void - hb_ot_font_set_funcs (hb_font_t *font); - - -diff -uN gfx/harfbuzz/src_old/hb-ot-glyf-table.hh gfx/harfbuzz/src/hb-ot-glyf-table.hh ---- gfx/harfbuzz/src_old/hb-ot-glyf-table.hh 1970-01-01 01:00:00.000000000 +0100 -+++ gfx/harfbuzz/src/hb-ot-glyf-table.hh 2016-06-05 23:49:15.900040281 +0200 -@@ -0,0 +1,104 @@ -+/* -+ * 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. -+ * -+ * Google Author(s): Behdad Esfahbod -+ */ -+ -+#ifndef HB_OT_GLYF_TABLE_HH -+#define HB_OT_GLYF_TABLE_HH -+ -+#include "hb-open-type-private.hh" -+ -+ -+namespace OT { -+ -+ -+/* -+ * loca -- Index to Location -+ */ -+ -+#define HB_OT_TAG_loca HB_TAG('l','o','c','a') -+ -+ -+struct loca -+{ -+ static const hb_tag_t tableTag = HB_OT_TAG_loca; -+ -+ inline bool sanitize (hb_sanitize_context_t *c) const -+ { -+ TRACE_SANITIZE (this); -+ return_trace (true); -+ } -+ -+ public: -+ union { -+ USHORT shortsZ[VAR]; /* Location offset divided by 2. */ -+ ULONG longsZ[VAR]; /* Location offset. */ -+ } u; -+ DEFINE_SIZE_ARRAY (0, u.longsZ); -+}; -+ -+ -+/* -+ * glyf -- TrueType Glyph Data -+ */ -+ -+#define HB_OT_TAG_glyf HB_TAG('g','l','y','f') -+ -+ -+struct glyf -+{ -+ static const hb_tag_t tableTag = HB_OT_TAG_glyf; -+ -+ inline bool sanitize (hb_sanitize_context_t *c) const -+ { -+ TRACE_SANITIZE (this); -+ /* We don't check for anything specific here. The users of the -+ * struct do all the hard work... */ -+ return_trace (true); -+ } -+ -+ public: -+ BYTE dataX[VAR]; /* Glyphs data. */ -+ -+ DEFINE_SIZE_ARRAY (0, dataX); -+}; -+ -+struct glyfGlyphHeader -+{ -+ SHORT numberOfContours; /* If the number of contours is -+ * greater than or equal to zero, -+ * this is a simple glyph; if negative, -+ * this is a composite glyph. */ -+ SHORT xMin; /* Minimum x for coordinate data. */ -+ SHORT yMin; /* Minimum y for coordinate data. */ -+ SHORT xMax; /* Maximum x for coordinate data. */ -+ SHORT yMax; /* Maximum y for coordinate data. */ -+ -+ DEFINE_SIZE_STATIC (10); -+}; -+ -+} /* namespace OT */ -+ -+ -+#endif /* HB_OT_GLYF_TABLE_HH */ -diff -uN gfx/harfbuzz/src_old/hb-ot-head-table.hh gfx/harfbuzz/src/hb-ot-head-table.hh ---- gfx/harfbuzz/src_old/hb-ot-head-table.hh 2016-05-10 22:26:55.000000000 +0200 -+++ gfx/harfbuzz/src/hb-ot-head-table.hh 2016-06-05 23:49:17.080033892 +0200 -@@ -45,15 +45,19 @@ - { - static const hb_tag_t tableTag = HB_OT_TAG_head; - -- inline unsigned int get_upem (void) const { -+ inline unsigned int get_upem (void) const -+ { - unsigned int upem = unitsPerEm; - /* If no valid head table found, assume 1000, which matches typical Type1 usage. */ - return 16 <= upem && upem <= 16384 ? upem : 1000; - } - -- inline bool sanitize (hb_sanitize_context_t *c) { -+ inline bool sanitize (hb_sanitize_context_t *c) const -+ { - TRACE_SANITIZE (this); -- return TRACE_RETURN (c->check_struct (this) && likely (version.major == 1)); -+ return_trace (c->check_struct (this) && -+ version.major == 1 && -+ magicNumber == 0x5F0F3CF5u); - } - - protected: -@@ -136,9 +140,10 @@ - * 2: Like 1 but also contains neutrals; - * -1: Only strongly right to left; - * -2: Like -1 but also contains neutrals. */ -+ public: - SHORT indexToLocFormat; /* 0 for short offsets, 1 for long. */ - SHORT glyphDataFormat; /* 0 for current format. */ -- public: -+ - DEFINE_SIZE_STATIC (54); - }; - -diff -uN gfx/harfbuzz/src_old/hb-ot-hhea-table.hh gfx/harfbuzz/src/hb-ot-hhea-table.hh ---- gfx/harfbuzz/src_old/hb-ot-hhea-table.hh 2016-05-10 22:26:56.000000000 +0200 -+++ gfx/harfbuzz/src/hb-ot-hhea-table.hh 2016-06-05 23:49:18.320027217 +0200 -@@ -49,9 +49,10 @@ - static const hb_tag_t hheaTag = HB_OT_TAG_hhea; - static const hb_tag_t vheaTag = HB_OT_TAG_vhea; - -- inline bool sanitize (hb_sanitize_context_t *c) { -+ inline bool sanitize (hb_sanitize_context_t *c) const -+ { - TRACE_SANITIZE (this); -- return TRACE_RETURN (c->check_struct (this) && likely (version.major == 1)); -+ return_trace (c->check_struct (this) && likely (version.major == 1)); - } - - public: -diff -uN gfx/harfbuzz/src_old/hb-ot-hmtx-table.hh gfx/harfbuzz/src/hb-ot-hmtx-table.hh ---- gfx/harfbuzz/src_old/hb-ot-hmtx-table.hh 2016-05-10 22:26:56.000000000 +0200 -+++ gfx/harfbuzz/src/hb-ot-hmtx-table.hh 2016-06-05 23:49:19.601020309 +0200 -@@ -57,11 +57,12 @@ - static const hb_tag_t hmtxTag = HB_OT_TAG_hmtx; - static const hb_tag_t vmtxTag = HB_OT_TAG_vmtx; - -- inline bool sanitize (hb_sanitize_context_t *c) { -+ inline bool sanitize (hb_sanitize_context_t *c) const -+ { - TRACE_SANITIZE (this); - /* We don't check for anything specific here. The users of the - * struct do all the hard work... */ -- return TRACE_RETURN (true); -+ return_trace (true); - } - - public: -diff -uN gfx/harfbuzz/src_old/hb-ot-layout.cc gfx/harfbuzz/src/hb-ot-layout.cc ---- gfx/harfbuzz/src_old/hb-ot-layout.cc 2016-05-10 22:26:56.000000000 +0200 -+++ gfx/harfbuzz/src/hb-ot-layout.cc 2016-06-05 23:49:31.325957413 +0200 -@@ -28,6 +28,7 @@ - * Google Author(s): Behdad Esfahbod - */ - -+#include "hb-open-type-private.hh" - #include "hb-ot-layout-private.hh" - - #include "hb-ot-layout-gdef-table.hh" -@@ -84,9 +85,9 @@ - _hb_ot_layout_destroy (hb_ot_layout_t *layout) - { - for (unsigned int i = 0; i < layout->gsub_lookup_count; i++) -- layout->gsub_accels[i].fini (layout->gsub->get_lookup (i)); -+ layout->gsub_accels[i].fini (); - for (unsigned int i = 0; i < layout->gpos_lookup_count; i++) -- layout->gpos_accels[i].fini (layout->gpos->get_lookup (i)); -+ layout->gpos_accels[i].fini (); - - free (layout->gsub_accels); - free (layout->gpos_accels); -@@ -128,6 +129,11 @@ - return _get_gdef (face).has_glyph_classes (); - } - -+/** -+ * hb_ot_layout_get_glyph_class: -+ * -+ * Since: 0.9.7 -+ **/ - hb_ot_layout_glyph_class_t - hb_ot_layout_get_glyph_class (hb_face_t *face, - hb_codepoint_t glyph) -@@ -135,6 +141,11 @@ - return (hb_ot_layout_glyph_class_t) _get_gdef (face).get_glyph_class (glyph); - } - -+/** -+ * hb_ot_layout_get_glyphs_in_class: -+ * -+ * Since: 0.9.7 -+ **/ - void - hb_ot_layout_get_glyphs_in_class (hb_face_t *face, - hb_ot_layout_glyph_class_t klass, -@@ -285,6 +296,28 @@ - return g.get_feature_tags (start_offset, feature_count, feature_tags); - } - -+hb_bool_t -+hb_ot_layout_table_find_feature (hb_face_t *face, -+ hb_tag_t table_tag, -+ hb_tag_t feature_tag, -+ unsigned int *feature_index) -+{ -+ ASSERT_STATIC (OT::Index::NOT_FOUND_INDEX == HB_OT_LAYOUT_NO_FEATURE_INDEX); -+ const OT::GSUBGPOS &g = get_gsubgpos_table (face, table_tag); -+ -+ unsigned int num_features = g.get_feature_count (); -+ for (unsigned int i = 0; i < num_features; i++) -+ { -+ if (feature_tag == g.get_feature_tag (i)) { -+ if (feature_index) *feature_index = i; -+ return true; -+ } -+ } -+ -+ if (feature_index) *feature_index = HB_OT_LAYOUT_NO_FEATURE_INDEX; -+ return false; -+} -+ - - unsigned int - hb_ot_layout_script_get_language_tags (hb_face_t *face, -@@ -335,6 +368,11 @@ - NULL); - } - -+/** -+ * hb_ot_layout_language_get_required_feature: -+ * -+ * Since: 0.9.30 -+ **/ - hb_bool_t - hb_ot_layout_language_get_required_feature (hb_face_t *face, - hb_tag_t table_tag, -@@ -419,6 +457,11 @@ - return false; - } - -+/** -+ * hb_ot_layout_feature_get_lookups: -+ * -+ * Since: 0.9.7 -+ **/ - unsigned int - hb_ot_layout_feature_get_lookups (hb_face_t *face, - hb_tag_t table_tag, -@@ -433,6 +476,11 @@ - return f.get_lookup_indexes (start_offset, lookup_count, lookup_indexes); - } - -+/** -+ * hb_ot_layout_table_get_lookup_count: -+ * -+ * Since: 0.9.22 -+ **/ - unsigned int - hb_ot_layout_table_get_lookup_count (hb_face_t *face, - hb_tag_t table_tag) -@@ -590,6 +638,11 @@ - } - } - -+/** -+ * hb_ot_layout_collect_lookups: -+ * -+ * Since: 0.9.8 -+ **/ - void - hb_ot_layout_collect_lookups (hb_face_t *face, - hb_tag_t table_tag, -@@ -631,6 +684,11 @@ - } - } - -+/** -+ * hb_ot_layout_lookup_collect_glyphs: -+ * -+ * Since: 0.9.7 -+ **/ - void - hb_ot_layout_lookup_collect_glyphs (hb_face_t *face, - hb_tag_t table_tag, -@@ -676,6 +734,11 @@ - return &_get_gsub (face) != &OT::Null(OT::GSUB); - } - -+/** -+ * hb_ot_layout_lookup_would_substitute: -+ * -+ * Since: 0.9.7 -+ **/ - hb_bool_t - hb_ot_layout_lookup_would_substitute (hb_face_t *face, - unsigned int lookup_index, -@@ -695,11 +758,11 @@ - hb_bool_t zero_context) - { - if (unlikely (lookup_index >= hb_ot_layout_from_face (face)->gsub_lookup_count)) return false; -- OT::hb_would_apply_context_t c (face, glyphs, glyphs_length, zero_context); -+ OT::hb_would_apply_context_t c (face, glyphs, glyphs_length, (bool) zero_context); - - const OT::SubstLookup& l = hb_ot_layout_from_face (face)->gsub->get_lookup (lookup_index); - -- return l.would_apply (&c, &hb_ot_layout_from_face (face)->gsub_accels[lookup_index].digest); -+ return l.would_apply (&c, &hb_ot_layout_from_face (face)->gsub_accels[lookup_index]); - } - - void -@@ -714,6 +777,11 @@ - OT::GSUB::substitute_finish (font, buffer); - } - -+/** -+ * hb_ot_layout_lookup_substitute_closure: -+ * -+ * Since: 0.9.7 -+ **/ - void - hb_ot_layout_lookup_substitute_closure (hb_face_t *face, - unsigned int lookup_index, -@@ -748,6 +816,11 @@ - OT::GPOS::position_finish (font, buffer); - } - -+/** -+ * hb_ot_layout_get_size_params: -+ * -+ * Since: 0.9.10 -+ **/ - hb_bool_t - hb_ot_layout_get_size_params (hb_face_t *face, - unsigned int *design_size, /* OUT. May be NULL */ -@@ -829,28 +902,82 @@ - }; - - --template <typename Lookup> --static inline bool apply_once (OT::hb_apply_context_t *c, -- const Lookup &lookup) -+template <typename Obj> -+static inline bool -+apply_forward (OT::hb_apply_context_t *c, -+ const Obj &obj, -+ const hb_ot_layout_lookup_accelerator_t &accel) - { -- if (!c->check_glyph_property (&c->buffer->cur(), c->lookup_props)) -- return false; -- return lookup.dispatch (c); -+ bool ret = false; -+ hb_buffer_t *buffer = c->buffer; -+ while (buffer->idx < buffer->len && !buffer->in_error) -+ { -+ if (accel.may_have (buffer->cur().codepoint) && -+ (buffer->cur().mask & c->lookup_mask) && -+ c->check_glyph_property (&buffer->cur(), c->lookup_props) && -+ obj.apply (c)) -+ ret = true; -+ else -+ buffer->next_glyph (); -+ } -+ return ret; - } - --template <typename Proxy> -+template <typename Obj> - static inline bool -+apply_backward (OT::hb_apply_context_t *c, -+ const Obj &obj, -+ const hb_ot_layout_lookup_accelerator_t &accel) -+{ -+ bool ret = false; -+ hb_buffer_t *buffer = c->buffer; -+ do -+ { -+ if (accel.may_have (buffer->cur().codepoint) && -+ (buffer->cur().mask & c->lookup_mask) && -+ c->check_glyph_property (&buffer->cur(), c->lookup_props) && -+ obj.apply (c)) -+ ret = true; -+ /* The reverse lookup doesn't "advance" cursor (for good reason). */ -+ buffer->idx--; -+ -+ } -+ while ((int) buffer->idx >= 0); -+ return ret; -+} -+ -+struct hb_apply_forward_context_t : -+ OT::hb_dispatch_context_t<hb_apply_forward_context_t, bool, HB_DEBUG_APPLY> -+{ -+ inline const char *get_name (void) { return "APPLY_FWD"; } -+ template <typename T> -+ inline return_t dispatch (const T &obj) { return apply_forward (c, obj, accel); } -+ static return_t default_return_value (void) { return false; } -+ bool stop_sublookup_iteration (return_t r HB_UNUSED) const { return true; } -+ -+ hb_apply_forward_context_t (OT::hb_apply_context_t *c_, -+ const hb_ot_layout_lookup_accelerator_t &accel_) : -+ c (c_), -+ accel (accel_), -+ debug_depth (0) {} -+ -+ OT::hb_apply_context_t *c; -+ const hb_ot_layout_lookup_accelerator_t &accel; -+ unsigned int debug_depth; -+}; -+ -+template <typename Proxy> -+static inline void - apply_string (OT::hb_apply_context_t *c, - const typename Proxy::Lookup &lookup, - const hb_ot_layout_lookup_accelerator_t &accel) - { -- bool ret = false; - hb_buffer_t *buffer = c->buffer; - - if (unlikely (!buffer->len || !c->lookup_mask)) -- return false; -+ return; - -- c->set_lookup (lookup); -+ c->set_lookup_props (lookup.get_props ()); - - if (likely (!lookup.is_reverse ())) - { -@@ -859,21 +986,20 @@ - buffer->clear_output (); - buffer->idx = 0; - -- while (buffer->idx < buffer->len) -+ bool ret; -+ if (lookup.get_subtable_count () == 1) - { -- if (accel.digest.may_have (buffer->cur().codepoint) && -- (buffer->cur().mask & c->lookup_mask) && -- apply_once (c, lookup)) -- ret = true; -- else -- buffer->next_glyph (); -+ hb_apply_forward_context_t c_forward (c, accel); -+ ret = lookup.dispatch (&c_forward); - } -+ else -+ ret = apply_forward (c, lookup, accel); - if (ret) - { - if (!Proxy::inplace) - buffer->swap_buffers (); - else -- assert (!buffer->has_separate_output ()); -+ assert (!buffer->has_separate_output ()); - } - } - else -@@ -882,20 +1008,9 @@ - if (Proxy::table_index == 0) - buffer->remove_output (); - buffer->idx = buffer->len - 1; -- do -- { -- if (accel.digest.may_have (buffer->cur().codepoint) && -- (buffer->cur().mask & c->lookup_mask) && -- apply_once (c, lookup)) -- ret = true; -- /* The reverse lookup doesn't "advance" cursor (for good reason). */ -- buffer->idx--; - -- } -- while ((int) buffer->idx >= 0); -+ apply_backward (c, lookup, accel); - } -- -- return ret; - } - - template <typename Proxy> -@@ -914,11 +1029,14 @@ - for (; i < stage->last_lookup; i++) - { - unsigned int lookup_index = lookups[table_index][i].index; -+ if (!buffer->message (font, "start lookup %d", lookup_index)) continue; -+ c.set_lookup_index (lookup_index); - c.set_lookup_mask (lookups[table_index][i].mask); - c.set_auto_zwj (lookups[table_index][i].auto_zwj); - apply_string<Proxy> (&c, - proxy.table.get_lookup (lookup_index), - proxy.accels[lookup_index]); -+ (void) buffer->message (font, "end lookup %d", lookup_index); - } - - if (stage->pause_func) -diff -uN gfx/harfbuzz/src_old/hb-ot-layout-common-private.hh gfx/harfbuzz/src/hb-ot-layout-common-private.hh ---- gfx/harfbuzz/src_old/hb-ot-layout-common-private.hh 2016-05-10 22:26:56.000000000 +0200 -+++ gfx/harfbuzz/src/hb-ot-layout-common-private.hh 2016-06-05 23:49:21.127012094 +0200 -@@ -34,12 +34,24 @@ - #include "hb-set-private.hh" - - -+#ifndef HB_MAX_NESTING_LEVEL -+#define HB_MAX_NESTING_LEVEL 6 -+#endif -+#ifndef HB_MAX_CONTEXT_LENGTH -+#define HB_MAX_CONTEXT_LENGTH 64 -+#endif -+ -+ - namespace OT { - - -+#define TRACE_DISPATCH(this, format) \ -+ hb_auto_trace_t<context_t::max_debug_depth, typename context_t::return_t> trace \ -+ (&c->debug_depth, c->get_name (), this, HB_FUNC, \ -+ "format %d", (int) format); -+ -+ - #define NOT_COVERED ((unsigned int) -1) --#define MAX_NESTING_LEVEL 8 --#define MAX_CONTEXT_LENGTH 64 - - - -@@ -63,12 +75,13 @@ - - struct sanitize_closure_t { - hb_tag_t tag; -- void *list_base; -+ const void *list_base; - }; -- inline bool sanitize (hb_sanitize_context_t *c, void *base) { -+ inline bool sanitize (hb_sanitize_context_t *c, const void *base) const -+ { - TRACE_SANITIZE (this); - const sanitize_closure_t closure = {tag, base}; -- return TRACE_RETURN (c->check_struct (this) && offset.sanitize (c, base, &closure)); -+ return_trace (c->check_struct (this) && offset.sanitize (c, base, &closure)); - } - - Tag tag; /* 4-byte Tag identifier */ -@@ -121,9 +134,10 @@ - inline const Type& operator [] (unsigned int i) const - { return this+RecordArrayOf<Type>::operator [](i).offset; } - -- inline bool sanitize (hb_sanitize_context_t *c) { -+ inline bool sanitize (hb_sanitize_context_t *c) const -+ { - TRACE_SANITIZE (this); -- return TRACE_RETURN (RecordArrayOf<Type>::sanitize (c, this)); -+ return_trace (RecordArrayOf<Type>::sanitize (c, this)); - } - }; - -@@ -134,9 +148,10 @@ - return g < start ? -1 : g <= end ? 0 : +1 ; - } - -- inline bool sanitize (hb_sanitize_context_t *c) { -+ inline bool sanitize (hb_sanitize_context_t *c) const -+ { - TRACE_SANITIZE (this); -- return TRACE_RETURN (c->check_struct (this)); -+ return_trace (c->check_struct (this)); - } - - inline bool intersects (const hb_set_t *glyphs) const { -@@ -199,9 +214,10 @@ - } - - inline bool sanitize (hb_sanitize_context_t *c, -- const Record<LangSys>::sanitize_closure_t * = NULL) { -+ const Record<LangSys>::sanitize_closure_t * = NULL) const -+ { - TRACE_SANITIZE (this); -- return TRACE_RETURN (c->check_struct (this) && featureIndex.sanitize (c)); -+ return_trace (c->check_struct (this) && featureIndex.sanitize (c)); - } - - Offset<> lookupOrderZ; /* = Null (reserved for an offset to a -@@ -238,9 +254,10 @@ - inline const LangSys& get_default_lang_sys (void) const { return this+defaultLangSys; } - - inline bool sanitize (hb_sanitize_context_t *c, -- const Record<Script>::sanitize_closure_t * = NULL) { -+ const Record<Script>::sanitize_closure_t * = NULL) const -+ { - TRACE_SANITIZE (this); -- return TRACE_RETURN (defaultLangSys.sanitize (c, this) && langSys.sanitize (c, this)); -+ return_trace (defaultLangSys.sanitize (c, this) && langSys.sanitize (c, this)); - } - - protected: -@@ -260,9 +277,10 @@ - /* http://www.microsoft.com/typography/otspec/features_pt.htm#size */ - struct FeatureParamsSize - { -- inline bool sanitize (hb_sanitize_context_t *c) { -+ inline bool sanitize (hb_sanitize_context_t *c) const -+ { - TRACE_SANITIZE (this); -- if (unlikely (!c->check_struct (this))) return TRACE_RETURN (false); -+ if (unlikely (!c->check_struct (this))) return_trace (false); - - /* This subtable has some "history", if you will. Some earlier versions of - * Adobe tools calculated the offset of the FeatureParams sutable from the -@@ -314,19 +332,19 @@ - */ - - if (!designSize) -- return TRACE_RETURN (false); -+ return_trace (false); - else if (subfamilyID == 0 && - subfamilyNameID == 0 && - rangeStart == 0 && - rangeEnd == 0) -- return TRACE_RETURN (true); -+ return_trace (true); - else if (designSize < rangeStart || - designSize > rangeEnd || - subfamilyNameID < 256 || - subfamilyNameID > 32767) -- return TRACE_RETURN (false); -+ return_trace (false); - else -- return TRACE_RETURN (true); -+ return_trace (true); - } - - USHORT designSize; /* Represents the design size in 720/inch -@@ -371,11 +389,12 @@ - /* http://www.microsoft.com/typography/otspec/features_pt.htm#ssxx */ - struct FeatureParamsStylisticSet - { -- inline bool sanitize (hb_sanitize_context_t *c) { -+ inline bool sanitize (hb_sanitize_context_t *c) const -+ { - TRACE_SANITIZE (this); - /* Right now minorVersion is at zero. Which means, any table supports - * the uiNameID field. */ -- return TRACE_RETURN (c->check_struct (this)); -+ return_trace (c->check_struct (this)); - } - - USHORT version; /* (set to 0): This corresponds to a “minor” -@@ -404,10 +423,11 @@ - /* http://www.microsoft.com/typography/otspec/features_ae.htm#cv01-cv99 */ - struct FeatureParamsCharacterVariants - { -- inline bool sanitize (hb_sanitize_context_t *c) { -+ inline bool sanitize (hb_sanitize_context_t *c) const -+ { - TRACE_SANITIZE (this); -- return TRACE_RETURN (c->check_struct (this) && -- characters.sanitize (c)); -+ return_trace (c->check_struct (this) && -+ characters.sanitize (c)); - } - - USHORT format; /* Format number is set to 0. */ -@@ -444,15 +464,16 @@ - - struct FeatureParams - { -- inline bool sanitize (hb_sanitize_context_t *c, hb_tag_t tag) { -+ inline bool sanitize (hb_sanitize_context_t *c, hb_tag_t tag) const -+ { - TRACE_SANITIZE (this); - if (tag == HB_TAG ('s','i','z','e')) -- return TRACE_RETURN (u.size.sanitize (c)); -+ return_trace (u.size.sanitize (c)); - if ((tag & 0xFFFF0000u) == HB_TAG ('s','s','\0','\0')) /* ssXX */ -- return TRACE_RETURN (u.stylisticSet.sanitize (c)); -+ return_trace (u.stylisticSet.sanitize (c)); - if ((tag & 0xFFFF0000u) == HB_TAG ('c','v','\0','\0')) /* cvXX */ -- return TRACE_RETURN (u.characterVariants.sanitize (c)); -- return TRACE_RETURN (true); -+ return_trace (u.characterVariants.sanitize (c)); -+ return_trace (true); - } - - inline const FeatureParamsSize& get_size_params (hb_tag_t tag) const -@@ -486,10 +507,11 @@ - { return this+featureParams; } - - inline bool sanitize (hb_sanitize_context_t *c, -- const Record<Feature>::sanitize_closure_t *closure) { -+ const Record<Feature>::sanitize_closure_t *closure) const -+ { - TRACE_SANITIZE (this); - if (unlikely (!(c->check_struct (this) && lookupIndex.sanitize (c)))) -- return TRACE_RETURN (false); -+ return_trace (false); - - /* Some earlier versions of Adobe tools calculated the offset of the - * FeatureParams subtable from the beginning of the FeatureList table! -@@ -504,10 +526,10 @@ - - OffsetTo<FeatureParams> orig_offset = featureParams; - if (unlikely (!featureParams.sanitize (c, this, closure ? closure->tag : HB_TAG_NONE))) -- return TRACE_RETURN (false); -+ return_trace (false); - - if (likely (orig_offset.is_null ())) -- return TRACE_RETURN (true); -+ return_trace (true); - - if (featureParams == 0 && closure && - closure->tag == HB_TAG ('s','i','z','e') && -@@ -522,10 +544,13 @@ - if (new_offset == new_offset_int && - c->try_set (&featureParams, new_offset) && - !featureParams.sanitize (c, this, closure ? closure->tag : HB_TAG_NONE)) -- return TRACE_RETURN (false); -+ return_trace (false); -+ -+ if (c->edit_count > 1) -+ c->edit_count--; /* This was a "legitimate" edit; don't contribute to error count. */ - } - -- return TRACE_RETURN (true); -+ return_trace (true); - } - - OffsetTo<FeatureParams> -@@ -557,10 +582,26 @@ - DEFINE_SIZE_STATIC (2); - }; - -+} /* namespace OT */ -+/* This has to be outside the namespace. */ -+HB_MARK_AS_FLAG_T (OT::LookupFlag::Flags); -+namespace OT { -+ - struct Lookup - { - inline unsigned int get_subtable_count (void) const { return subTable.len; } - -+ template <typename SubTableType> -+ inline const SubTableType& get_subtable (unsigned int i) const -+ { return this+CastR<OffsetArrayOf<SubTableType> > (subTable)[i]; } -+ -+ template <typename SubTableType> -+ inline const OffsetArrayOf<SubTableType>& get_subtables (void) const -+ { return CastR<OffsetArrayOf<SubTableType> > (subTable); } -+ template <typename SubTableType> -+ inline OffsetArrayOf<SubTableType>& get_subtables (void) -+ { return CastR<OffsetArrayOf<SubTableType> > (subTable); } -+ - inline unsigned int get_type (void) const { return lookupType; } - - /* lookup_props is a 32-bit integer where the lower 16-bit is LookupFlag and -@@ -577,36 +618,52 @@ - return flag; - } - -+ template <typename SubTableType, typename context_t> -+ inline typename context_t::return_t dispatch (context_t *c) const -+ { -+ unsigned int lookup_type = get_type (); -+ TRACE_DISPATCH (this, lookup_type); -+ unsigned int count = get_subtable_count (); -+ for (unsigned int i = 0; i < count; i++) { -+ typename context_t::return_t r = get_subtable<SubTableType> (i).dispatch (c, lookup_type); -+ if (c->stop_sublookup_iteration (r)) -+ return_trace (r); -+ } -+ return_trace (c->default_return_value ()); -+ } -+ - inline bool serialize (hb_serialize_context_t *c, - unsigned int lookup_type, - uint32_t lookup_props, - unsigned int num_subtables) - { - TRACE_SERIALIZE (this); -- if (unlikely (!c->extend_min (*this))) return TRACE_RETURN (false); -+ if (unlikely (!c->extend_min (*this))) return_trace (false); - lookupType.set (lookup_type); - lookupFlag.set (lookup_props & 0xFFFFu); -- if (unlikely (!subTable.serialize (c, num_subtables))) return TRACE_RETURN (false); -+ if (unlikely (!subTable.serialize (c, num_subtables))) return_trace (false); - if (lookupFlag & LookupFlag::UseMarkFilteringSet) - { - USHORT &markFilteringSet = StructAfter<USHORT> (subTable); - markFilteringSet.set (lookup_props >> 16); - } -- return TRACE_RETURN (true); -+ return_trace (true); - } - -- inline bool sanitize (hb_sanitize_context_t *c) { -+ inline bool sanitize (hb_sanitize_context_t *c) const -+ { - TRACE_SANITIZE (this); - /* Real sanitize of the subtables is done by GSUB/GPOS/... */ -- if (!(c->check_struct (this) && subTable.sanitize (c))) return TRACE_RETURN (false); -+ if (!(c->check_struct (this) && subTable.sanitize (c))) return_trace (false); - if (lookupFlag & LookupFlag::UseMarkFilteringSet) - { -- USHORT &markFilteringSet = StructAfter<USHORT> (subTable); -- if (!markFilteringSet.sanitize (c)) return TRACE_RETURN (false); -+ const USHORT &markFilteringSet = StructAfter<USHORT> (subTable); -+ if (!markFilteringSet.sanitize (c)) return_trace (false); - } -- return TRACE_RETURN (true); -+ return_trace (true); - } - -+ private: - USHORT lookupType; /* Different enumerations for GSUB and GPOS */ - USHORT lookupFlag; /* Lookup qualifiers */ - ArrayOf<Offset<> > -@@ -642,18 +699,19 @@ - unsigned int num_glyphs) - { - TRACE_SERIALIZE (this); -- if (unlikely (!c->extend_min (*this))) return TRACE_RETURN (false); -+ if (unlikely (!c->extend_min (*this))) return_trace (false); - glyphArray.len.set (num_glyphs); -- if (unlikely (!c->extend (glyphArray))) return TRACE_RETURN (false); -+ if (unlikely (!c->extend (glyphArray))) return_trace (false); - for (unsigned int i = 0; i < num_glyphs; i++) - glyphArray[i] = glyphs[i]; - glyphs.advance (num_glyphs); -- return TRACE_RETURN (true); -+ return_trace (true); - } - -- inline bool sanitize (hb_sanitize_context_t *c) { -+ inline bool sanitize (hb_sanitize_context_t *c) const -+ { - TRACE_SANITIZE (this); -- return TRACE_RETURN (glyphArray.sanitize (c)); -+ return_trace (glyphArray.sanitize (c)); - } - - inline bool intersects_coverage (const hb_set_t *glyphs, unsigned int index) const { -@@ -710,16 +768,16 @@ - unsigned int num_glyphs) - { - TRACE_SERIALIZE (this); -- if (unlikely (!c->extend_min (*this))) return TRACE_RETURN (false); -+ if (unlikely (!c->extend_min (*this))) return_trace (false); - -- if (unlikely (!num_glyphs)) return TRACE_RETURN (true); -+ if (unlikely (!num_glyphs)) return_trace (true); - - unsigned int num_ranges = 1; - for (unsigned int i = 1; i < num_glyphs; i++) - if (glyphs[i - 1] + 1 != glyphs[i]) - num_ranges++; - rangeRecord.len.set (num_ranges); -- if (unlikely (!c->extend (rangeRecord))) return TRACE_RETURN (false); -+ if (unlikely (!c->extend (rangeRecord))) return_trace (false); - - unsigned int range = 0; - rangeRecord[range].start = glyphs[0]; -@@ -734,12 +792,13 @@ - rangeRecord[range].end = glyphs[i]; - } - glyphs.advance (num_glyphs); -- return TRACE_RETURN (true); -+ return_trace (true); - } - -- inline bool sanitize (hb_sanitize_context_t *c) { -+ inline bool sanitize (hb_sanitize_context_t *c) const -+ { - TRACE_SANITIZE (this); -- return TRACE_RETURN (rangeRecord.sanitize (c)); -+ return_trace (rangeRecord.sanitize (c)); - } - - inline bool intersects_coverage (const hb_set_t *glyphs, unsigned int index) const { -@@ -819,26 +878,27 @@ - unsigned int num_glyphs) - { - TRACE_SERIALIZE (this); -- if (unlikely (!c->extend_min (*this))) return TRACE_RETURN (false); -+ if (unlikely (!c->extend_min (*this))) return_trace (false); - unsigned int num_ranges = 1; - for (unsigned int i = 1; i < num_glyphs; i++) - if (glyphs[i - 1] + 1 != glyphs[i]) - num_ranges++; - u.format.set (num_glyphs * 2 < num_ranges * 3 ? 1 : 2); - switch (u.format) { -- case 1: return TRACE_RETURN (u.format1.serialize (c, glyphs, num_glyphs)); -- case 2: return TRACE_RETURN (u.format2.serialize (c, glyphs, num_glyphs)); -- default:return TRACE_RETURN (false); -+ case 1: return_trace (u.format1.serialize (c, glyphs, num_glyphs)); -+ case 2: return_trace (u.format2.serialize (c, glyphs, num_glyphs)); -+ default:return_trace (false); - } - } - -- inline bool sanitize (hb_sanitize_context_t *c) { -+ inline bool sanitize (hb_sanitize_context_t *c) const -+ { - TRACE_SANITIZE (this); -- if (!u.format.sanitize (c)) return TRACE_RETURN (false); -+ if (!u.format.sanitize (c)) return_trace (false); - switch (u.format) { -- case 1: return TRACE_RETURN (u.format1.sanitize (c)); -- case 2: return TRACE_RETURN (u.format2.sanitize (c)); -- default:return TRACE_RETURN (true); -+ case 1: return_trace (u.format1.sanitize (c)); -+ case 2: return_trace (u.format2.sanitize (c)); -+ default:return_trace (true); - } - } - -@@ -938,14 +998,16 @@ - private: - inline unsigned int get_class (hb_codepoint_t glyph_id) const - { -- if (unlikely ((unsigned int) (glyph_id - startGlyph) < classValue.len)) -- return classValue[glyph_id - startGlyph]; -+ unsigned int i = (unsigned int) (glyph_id - startGlyph); -+ if (unlikely (i < classValue.len)) -+ return classValue[i]; - return 0; - } - -- inline bool sanitize (hb_sanitize_context_t *c) { -+ inline bool sanitize (hb_sanitize_context_t *c) const -+ { - TRACE_SANITIZE (this); -- return TRACE_RETURN (c->check_struct (this) && classValue.sanitize (c)); -+ return_trace (c->check_struct (this) && classValue.sanitize (c)); - } - - template <typename set_t> -@@ -994,14 +1056,15 @@ - inline unsigned int get_class (hb_codepoint_t glyph_id) const - { - int i = rangeRecord.bsearch (glyph_id); -- if (i != -1) -+ if (unlikely (i != -1)) - return rangeRecord[i].value; - return 0; - } - -- inline bool sanitize (hb_sanitize_context_t *c) { -+ inline bool sanitize (hb_sanitize_context_t *c) const -+ { - TRACE_SANITIZE (this); -- return TRACE_RETURN (rangeRecord.sanitize (c)); -+ return_trace (rangeRecord.sanitize (c)); - } - - template <typename set_t> -@@ -1056,13 +1119,14 @@ - } - } - -- inline bool sanitize (hb_sanitize_context_t *c) { -+ inline bool sanitize (hb_sanitize_context_t *c) const -+ { - TRACE_SANITIZE (this); -- if (!u.format.sanitize (c)) return TRACE_RETURN (false); -+ if (!u.format.sanitize (c)) return_trace (false); - switch (u.format) { -- case 1: return TRACE_RETURN (u.format1.sanitize (c)); -- case 2: return TRACE_RETURN (u.format2.sanitize (c)); -- default:return TRACE_RETURN (true); -+ case 1: return_trace (u.format1.sanitize (c)); -+ case 2: return_trace (u.format2.sanitize (c)); -+ default:return_trace (true); - } - } - -@@ -1148,9 +1212,10 @@ - return USHORT::static_size * (4 + ((endSize - startSize) >> (4 - f))); - } - -- inline bool sanitize (hb_sanitize_context_t *c) { -+ inline bool sanitize (hb_sanitize_context_t *c) const -+ { - TRACE_SANITIZE (this); -- return TRACE_RETURN (c->check_struct (this) && c->check_range (this, this->get_size ())); -+ return_trace (c->check_struct (this) && c->check_range (this, this->get_size ())); - } - - protected: -diff -uN gfx/harfbuzz/src_old/hb-ot-layout-gdef-table.hh gfx/harfbuzz/src/hb-ot-layout-gdef-table.hh ---- gfx/harfbuzz/src_old/hb-ot-layout-gdef-table.hh 2016-05-10 22:26:55.000000000 +0200 -+++ gfx/harfbuzz/src/hb-ot-layout-gdef-table.hh 2016-06-05 23:49:22.476004876 +0200 -@@ -71,9 +71,10 @@ - return points.len; - } - -- inline bool sanitize (hb_sanitize_context_t *c) { -+ inline bool sanitize (hb_sanitize_context_t *c) const -+ { - TRACE_SANITIZE (this); -- return TRACE_RETURN (coverage.sanitize (c, this) && attachPoint.sanitize (c, this)); -+ return_trace (coverage.sanitize (c, this) && attachPoint.sanitize (c, this)); - } - - protected: -@@ -101,9 +102,10 @@ - return HB_DIRECTION_IS_HORIZONTAL (direction) ? font->em_scale_x (coordinate) : font->em_scale_y (coordinate); - } - -- inline bool sanitize (hb_sanitize_context_t *c) { -+ inline bool sanitize (hb_sanitize_context_t *c) const -+ { - TRACE_SANITIZE (this); -- return TRACE_RETURN (c->check_struct (this)); -+ return_trace (c->check_struct (this)); - } - - protected: -@@ -127,9 +129,10 @@ - return 0; - } - -- inline bool sanitize (hb_sanitize_context_t *c) { -+ inline bool sanitize (hb_sanitize_context_t *c) const -+ { - TRACE_SANITIZE (this); -- return TRACE_RETURN (c->check_struct (this)); -+ return_trace (c->check_struct (this)); - } - - protected: -@@ -150,9 +153,10 @@ - font->em_scale_y (coordinate) + (this+deviceTable).get_y_delta (font); - } - -- inline bool sanitize (hb_sanitize_context_t *c) { -+ inline bool sanitize (hb_sanitize_context_t *c) const -+ { - TRACE_SANITIZE (this); -- return TRACE_RETURN (c->check_struct (this) && deviceTable.sanitize (c, this)); -+ return_trace (c->check_struct (this) && deviceTable.sanitize (c, this)); - } - - protected: -@@ -178,14 +182,15 @@ - } - } - -- inline bool sanitize (hb_sanitize_context_t *c) { -+ inline bool sanitize (hb_sanitize_context_t *c) const -+ { - TRACE_SANITIZE (this); -- if (!u.format.sanitize (c)) return TRACE_RETURN (false); -+ if (!u.format.sanitize (c)) return_trace (false); - switch (u.format) { -- case 1: return TRACE_RETURN (u.format1.sanitize (c)); -- case 2: return TRACE_RETURN (u.format2.sanitize (c)); -- case 3: return TRACE_RETURN (u.format3.sanitize (c)); -- default:return TRACE_RETURN (true); -+ case 1: return_trace (u.format1.sanitize (c)); -+ case 2: return_trace (u.format2.sanitize (c)); -+ case 3: return_trace (u.format3.sanitize (c)); -+ default:return_trace (true); - } - } - -@@ -219,9 +224,10 @@ - return carets.len; - } - -- inline bool sanitize (hb_sanitize_context_t *c) { -+ inline bool sanitize (hb_sanitize_context_t *c) const -+ { - TRACE_SANITIZE (this); -- return TRACE_RETURN (carets.sanitize (c, this)); -+ return_trace (carets.sanitize (c, this)); - } - - protected: -@@ -253,9 +259,10 @@ - return lig_glyph.get_lig_carets (font, direction, glyph_id, start_offset, caret_count, caret_array); - } - -- inline bool sanitize (hb_sanitize_context_t *c) { -+ inline bool sanitize (hb_sanitize_context_t *c) const -+ { - TRACE_SANITIZE (this); -- return TRACE_RETURN (coverage.sanitize (c, this) && ligGlyph.sanitize (c, this)); -+ return_trace (coverage.sanitize (c, this) && ligGlyph.sanitize (c, this)); - } - - protected: -@@ -275,9 +282,10 @@ - inline bool covers (unsigned int set_index, hb_codepoint_t glyph_id) const - { return (this+coverage[set_index]).get_coverage (glyph_id) != NOT_COVERED; } - -- inline bool sanitize (hb_sanitize_context_t *c) { -+ inline bool sanitize (hb_sanitize_context_t *c) const -+ { - TRACE_SANITIZE (this); -- return TRACE_RETURN (coverage.sanitize (c, this)); -+ return_trace (coverage.sanitize (c, this)); - } - - protected: -@@ -299,12 +307,13 @@ - } - } - -- inline bool sanitize (hb_sanitize_context_t *c) { -+ inline bool sanitize (hb_sanitize_context_t *c) const -+ { - TRACE_SANITIZE (this); -- if (!u.format.sanitize (c)) return TRACE_RETURN (false); -+ if (!u.format.sanitize (c)) return_trace (false); - switch (u.format) { -- case 1: return TRACE_RETURN (u.format1.sanitize (c)); -- default:return TRACE_RETURN (true); -+ case 1: return_trace (u.format1.sanitize (c)); -+ default:return_trace (true); - } - } - -@@ -364,15 +373,16 @@ - inline bool mark_set_covers (unsigned int set_index, hb_codepoint_t glyph_id) const - { return version.to_int () >= 0x00010002u && (this+markGlyphSetsDef[0]).covers (set_index, glyph_id); } - -- inline bool sanitize (hb_sanitize_context_t *c) { -+ inline bool sanitize (hb_sanitize_context_t *c) const -+ { - TRACE_SANITIZE (this); -- return TRACE_RETURN (version.sanitize (c) && -- likely (version.major == 1) && -- glyphClassDef.sanitize (c, this) && -- attachList.sanitize (c, this) && -- ligCaretList.sanitize (c, this) && -- markAttachClassDef.sanitize (c, this) && -- (version.to_int () < 0x00010002u || markGlyphSetsDef[0].sanitize (c, this))); -+ return_trace (version.sanitize (c) && -+ likely (version.major == 1) && -+ glyphClassDef.sanitize (c, this) && -+ attachList.sanitize (c, this) && -+ ligCaretList.sanitize (c, this) && -+ markAttachClassDef.sanitize (c, this) && -+ (version.to_int () < 0x00010002u || markGlyphSetsDef[0].sanitize (c, this))); - } - - -diff -uN gfx/harfbuzz/src_old/hb-ot-layout-gpos-table.hh gfx/harfbuzz/src/hb-ot-layout-gpos-table.hh ---- gfx/harfbuzz/src_old/hb-ot-layout-gpos-table.hh 2016-05-10 22:26:56.000000000 +0200 -+++ gfx/harfbuzz/src/hb-ot-layout-gpos-table.hh 2016-06-05 23:49:23.921997102 +0200 -@@ -146,7 +146,8 @@ - } - - private: -- inline bool sanitize_value_devices (hb_sanitize_context_t *c, void *base, Value *values) { -+ inline bool sanitize_value_devices (hb_sanitize_context_t *c, const void *base, const Value *values) const -+ { - unsigned int format = *this; - - if (format & xPlacement) values++; -@@ -177,41 +178,44 @@ - return (format & devices) != 0; - } - -- inline bool sanitize_value (hb_sanitize_context_t *c, void *base, Value *values) { -+ inline bool sanitize_value (hb_sanitize_context_t *c, const void *base, const Value *values) const -+ { - TRACE_SANITIZE (this); -- return TRACE_RETURN (c->check_range (values, get_size ()) && (!has_device () || sanitize_value_devices (c, base, values))); -+ return_trace (c->check_range (values, get_size ()) && (!has_device () || sanitize_value_devices (c, base, values))); - } - -- inline bool sanitize_values (hb_sanitize_context_t *c, void *base, Value *values, unsigned int count) { -+ inline bool sanitize_values (hb_sanitize_context_t *c, const void *base, const Value *values, unsigned int count) const -+ { - TRACE_SANITIZE (this); - unsigned int len = get_len (); - -- if (!c->check_array (values, get_size (), count)) return TRACE_RETURN (false); -+ if (!c->check_array (values, get_size (), count)) return_trace (false); - -- if (!has_device ()) return TRACE_RETURN (true); -+ if (!has_device ()) return_trace (true); - - for (unsigned int i = 0; i < count; i++) { - if (!sanitize_value_devices (c, base, values)) -- return TRACE_RETURN (false); -+ return_trace (false); - values += len; - } - -- return TRACE_RETURN (true); -+ return_trace (true); - } - - /* Just sanitize referenced Device tables. Doesn't check the values themselves. */ -- inline bool sanitize_values_stride_unsafe (hb_sanitize_context_t *c, void *base, Value *values, unsigned int count, unsigned int stride) { -+ inline bool sanitize_values_stride_unsafe (hb_sanitize_context_t *c, const void *base, const Value *values, unsigned int count, unsigned int stride) const -+ { - TRACE_SANITIZE (this); - -- if (!has_device ()) return TRACE_RETURN (true); -+ if (!has_device ()) return_trace (true); - - for (unsigned int i = 0; i < count; i++) { - if (!sanitize_value_devices (c, base, values)) -- return TRACE_RETURN (false); -+ return_trace (false); - values += stride; - } - -- return TRACE_RETURN (true); -+ return_trace (true); - } - }; - -@@ -225,9 +229,10 @@ - *y = font->em_scale_y (yCoordinate); - } - -- inline bool sanitize (hb_sanitize_context_t *c) { -+ inline bool sanitize (hb_sanitize_context_t *c) const -+ { - TRACE_SANITIZE (this); -- return TRACE_RETURN (c->check_struct (this)); -+ return_trace (c->check_struct (this)); - } - - protected: -@@ -254,9 +259,10 @@ - *y = ret && y_ppem ? cy : font->em_scale_y (yCoordinate); - } - -- inline bool sanitize (hb_sanitize_context_t *c) { -+ inline bool sanitize (hb_sanitize_context_t *c) const -+ { - TRACE_SANITIZE (this); -- return TRACE_RETURN (c->check_struct (this)); -+ return_trace (c->check_struct (this)); - } - - protected: -@@ -282,9 +288,10 @@ - *y += (this+yDeviceTable).get_x_delta (font); - } - -- inline bool sanitize (hb_sanitize_context_t *c) { -+ inline bool sanitize (hb_sanitize_context_t *c) const -+ { - TRACE_SANITIZE (this); -- return TRACE_RETURN (c->check_struct (this) && xDeviceTable.sanitize (c, this) && yDeviceTable.sanitize (c, this)); -+ return_trace (c->check_struct (this) && xDeviceTable.sanitize (c, this) && yDeviceTable.sanitize (c, this)); - } - - protected: -@@ -317,14 +324,15 @@ - } - } - -- inline bool sanitize (hb_sanitize_context_t *c) { -+ inline bool sanitize (hb_sanitize_context_t *c) const -+ { - TRACE_SANITIZE (this); -- if (!u.format.sanitize (c)) return TRACE_RETURN (false); -+ if (!u.format.sanitize (c)) return_trace (false); - switch (u.format) { -- case 1: return TRACE_RETURN (u.format1.sanitize (c)); -- case 2: return TRACE_RETURN (u.format2.sanitize (c)); -- case 3: return TRACE_RETURN (u.format3.sanitize (c)); -- default:return TRACE_RETURN (true); -+ case 1: return_trace (u.format1.sanitize (c)); -+ case 2: return_trace (u.format2.sanitize (c)); -+ case 3: return_trace (u.format3.sanitize (c)); -+ default:return_trace (true); - } - } - -@@ -349,15 +357,16 @@ - return this+matrixZ[row * cols + col]; - } - -- inline bool sanitize (hb_sanitize_context_t *c, unsigned int cols) { -+ inline bool sanitize (hb_sanitize_context_t *c, unsigned int cols) const -+ { - TRACE_SANITIZE (this); -- if (!c->check_struct (this)) return TRACE_RETURN (false); -- if (unlikely (rows > 0 && cols >= ((unsigned int) -1) / rows)) return TRACE_RETURN (false); -+ if (!c->check_struct (this)) return_trace (false); -+ if (unlikely (rows > 0 && cols >= ((unsigned int) -1) / rows)) return_trace (false); - unsigned int count = rows * cols; -- if (!c->check_array (matrixZ, matrixZ[0].static_size, count)) return TRACE_RETURN (false); -+ if (!c->check_array (matrixZ, matrixZ[0].static_size, count)) return_trace (false); - for (unsigned int i = 0; i < count; i++) -- if (!matrixZ[i].sanitize (c, this)) return TRACE_RETURN (false); -- return TRACE_RETURN (true); -+ if (!matrixZ[i].sanitize (c, this)) return_trace (false); -+ return_trace (true); - } - - USHORT rows; /* Number of rows */ -@@ -374,9 +383,10 @@ - { - friend struct MarkArray; - -- inline bool sanitize (hb_sanitize_context_t *c, void *base) { -+ inline bool sanitize (hb_sanitize_context_t *c, const void *base) const -+ { - TRACE_SANITIZE (this); -- return TRACE_RETURN (c->check_struct (this) && markAnchor.sanitize (c, base)); -+ return_trace (c->check_struct (this) && markAnchor.sanitize (c, base)); - } - - protected: -@@ -405,7 +415,7 @@ - const Anchor& glyph_anchor = anchors.get_anchor (glyph_index, mark_class, class_count, &found); - /* If this subtable doesn't have an anchor for this base and this class, - * return false such that the subsequent subtables have a chance at it. */ -- if (unlikely (!found)) return TRACE_RETURN (false); -+ if (unlikely (!found)) return_trace (false); - - hb_position_t mark_x, mark_y, base_x, base_y; - -@@ -416,14 +426,16 @@ - o.x_offset = base_x - mark_x; - o.y_offset = base_y - mark_y; - o.attach_lookback() = buffer->idx - glyph_pos; -+ buffer->scratch_flags |= HB_BUFFER_SCRATCH_FLAG_HAS_GPOS_ATTACHMENT; - - buffer->idx++; -- return TRACE_RETURN (true); -+ return_trace (true); - } - -- inline bool sanitize (hb_sanitize_context_t *c) { -+ inline bool sanitize (hb_sanitize_context_t *c) const -+ { - TRACE_SANITIZE (this); -- return TRACE_RETURN (ArrayOf<MarkRecord>::sanitize (c, this)); -+ return_trace (ArrayOf<MarkRecord>::sanitize (c, this)); - } - }; - -@@ -448,18 +460,21 @@ - TRACE_APPLY (this); - hb_buffer_t *buffer = c->buffer; - unsigned int index = (this+coverage).get_coverage (buffer->cur().codepoint); -- if (likely (index == NOT_COVERED)) return TRACE_RETURN (false); -+ if (likely (index == NOT_COVERED)) return_trace (false); - - valueFormat.apply_value (c->font, c->direction, this, - values, buffer->cur_pos()); - - buffer->idx++; -- return TRACE_RETURN (true); -+ return_trace (true); - } - -- inline bool sanitize (hb_sanitize_context_t *c) { -+ inline bool sanitize (hb_sanitize_context_t *c) const -+ { - TRACE_SANITIZE (this); -- return TRACE_RETURN (c->check_struct (this) && coverage.sanitize (c, this) && valueFormat.sanitize_value (c, this, values)); -+ return_trace (c->check_struct (this) && -+ coverage.sanitize (c, this) && -+ valueFormat.sanitize_value (c, this, values)); - } - - protected: -@@ -494,21 +509,24 @@ - TRACE_APPLY (this); - hb_buffer_t *buffer = c->buffer; - unsigned int index = (this+coverage).get_coverage (buffer->cur().codepoint); -- if (likely (index == NOT_COVERED)) return TRACE_RETURN (false); -+ if (likely (index == NOT_COVERED)) return_trace (false); - -- if (likely (index >= valueCount)) return TRACE_RETURN (false); -+ if (likely (index >= valueCount)) return_trace (false); - - valueFormat.apply_value (c->font, c->direction, this, - &values[index * valueFormat.get_len ()], - buffer->cur_pos()); - - buffer->idx++; -- return TRACE_RETURN (true); -+ return_trace (true); - } - -- inline bool sanitize (hb_sanitize_context_t *c) { -+ inline bool sanitize (hb_sanitize_context_t *c) const -+ { - TRACE_SANITIZE (this); -- return TRACE_RETURN (c->check_struct (this) && coverage.sanitize (c, this) && valueFormat.sanitize_values (c, this, values, valueCount)); -+ return_trace (c->check_struct (this) && -+ coverage.sanitize (c, this) && -+ valueFormat.sanitize_values (c, this, values, valueCount)); - } - - protected: -@@ -531,20 +549,11 @@ - inline typename context_t::return_t dispatch (context_t *c) const - { - TRACE_DISPATCH (this, u.format); -+ if (unlikely (!c->may_dispatch (this, &u.format))) return_trace (c->no_dispatch_return_value ()); - switch (u.format) { -- case 1: return TRACE_RETURN (c->dispatch (u.format1)); -- case 2: return TRACE_RETURN (c->dispatch (u.format2)); -- default:return TRACE_RETURN (c->default_return_value ()); -- } -- } -- -- inline bool sanitize (hb_sanitize_context_t *c) { -- TRACE_SANITIZE (this); -- if (!u.format.sanitize (c)) return TRACE_RETURN (false); -- switch (u.format) { -- case 1: return TRACE_RETURN (u.format1.sanitize (c)); -- case 2: return TRACE_RETURN (u.format2.sanitize (c)); -- default:return TRACE_RETURN (true); -+ case 1: return_trace (c->dispatch (u.format1)); -+ case 2: return_trace (c->dispatch (u.format2)); -+ default:return_trace (c->default_return_value ()); - } - } - -@@ -602,12 +611,24 @@ - unsigned int len2 = valueFormats[1].get_len (); - unsigned int record_size = USHORT::static_size * (1 + len1 + len2); - -- const PairValueRecord *record = CastP<PairValueRecord> (arrayZ); -+ const PairValueRecord *record_array = CastP<PairValueRecord> (arrayZ); - unsigned int count = len; -- for (unsigned int i = 0; i < count; i++) -+ -+ /* Hand-coded bsearch. */ -+ if (unlikely (!count)) -+ return_trace (false); -+ hb_codepoint_t x = buffer->info[pos].codepoint; -+ int min = 0, max = (int) count - 1; -+ while (min <= max) - { -- /* TODO bsearch */ -- if (buffer->info[pos].codepoint == record->secondGlyph) -+ int mid = (min + max) / 2; -+ const PairValueRecord *record = &StructAtOffset<PairValueRecord> (record_array, record_size * mid); -+ hb_codepoint_t mid_x = record->secondGlyph; -+ if (x < mid_x) -+ max = mid - 1; -+ else if (x > mid_x) -+ min = mid + 1; -+ else - { - valueFormats[0].apply_value (c->font, c->direction, this, - &record->values[0], buffer->cur_pos()); -@@ -616,30 +637,30 @@ - if (len2) - pos++; - buffer->idx = pos; -- return TRACE_RETURN (true); -+ return_trace (true); - } -- record = &StructAtOffset<PairValueRecord> (record, record_size); - } - -- return TRACE_RETURN (false); -+ return_trace (false); - } - - struct sanitize_closure_t { -- void *base; -- ValueFormat *valueFormats; -+ const void *base; -+ const ValueFormat *valueFormats; - unsigned int len1; /* valueFormats[0].get_len() */ - unsigned int stride; /* 1 + len1 + len2 */ - }; - -- inline bool sanitize (hb_sanitize_context_t *c, const sanitize_closure_t *closure) { -+ inline bool sanitize (hb_sanitize_context_t *c, const sanitize_closure_t *closure) const -+ { - TRACE_SANITIZE (this); - if (!(c->check_struct (this) -- && c->check_array (arrayZ, USHORT::static_size * closure->stride, len))) return TRACE_RETURN (false); -+ && c->check_array (arrayZ, USHORT::static_size * closure->stride, len))) return_trace (false); - - unsigned int count = len; -- PairValueRecord *record = CastP<PairValueRecord> (arrayZ); -- return TRACE_RETURN (closure->valueFormats[0].sanitize_values_stride_unsafe (c, closure->base, &record->values[0], count, closure->stride) -- && closure->valueFormats[1].sanitize_values_stride_unsafe (c, closure->base, &record->values[closure->len1], count, closure->stride)); -+ const PairValueRecord *record = CastP<PairValueRecord> (arrayZ); -+ return_trace (closure->valueFormats[0].sanitize_values_stride_unsafe (c, closure->base, &record->values[0], count, closure->stride) && -+ closure->valueFormats[1].sanitize_values_stride_unsafe (c, closure->base, &record->values[closure->len1], count, closure->stride)); - } - - protected: -@@ -670,20 +691,22 @@ - { - TRACE_APPLY (this); - hb_buffer_t *buffer = c->buffer; -- hb_apply_context_t::skipping_forward_iterator_t skippy_iter (c, buffer->idx, 1); -- if (skippy_iter.has_no_chance ()) return TRACE_RETURN (false); -- - unsigned int index = (this+coverage).get_coverage (buffer->cur().codepoint); -- if (likely (index == NOT_COVERED)) return TRACE_RETURN (false); -+ if (likely (index == NOT_COVERED)) return_trace (false); - -- if (!skippy_iter.next ()) return TRACE_RETURN (false); -+ hb_apply_context_t::skipping_iterator_t &skippy_iter = c->iter_input; -+ skippy_iter.reset (buffer->idx, 1); -+ if (!skippy_iter.next ()) return_trace (false); - -- return TRACE_RETURN ((this+pairSet[index]).apply (c, &valueFormat1, skippy_iter.idx)); -+ return_trace ((this+pairSet[index]).apply (c, &valueFormat1, skippy_iter.idx)); - } - -- inline bool sanitize (hb_sanitize_context_t *c) { -+ inline bool sanitize (hb_sanitize_context_t *c) const -+ { - TRACE_SANITIZE (this); - -+ if (!c->check_struct (this)) return_trace (false); -+ - unsigned int len1 = valueFormat1.get_len (); - unsigned int len2 = valueFormat2.get_len (); - PairSet::sanitize_closure_t closure = { -@@ -693,7 +716,7 @@ - 1 + len1 + len2 - }; - -- return TRACE_RETURN (c->check_struct (this) && coverage.sanitize (c, this) && pairSet.sanitize (c, this, &closure)); -+ return_trace (coverage.sanitize (c, this) && pairSet.sanitize (c, this, &closure)); - } - - protected: -@@ -719,7 +742,7 @@ - inline void collect_glyphs (hb_collect_glyphs_context_t *c) const - { - TRACE_COLLECT_GLYPHS (this); -- /* (this+coverage).add_coverage (c->input); // Don't need this. */ -+ (this+coverage).add_coverage (c->input); - - unsigned int count1 = class1Count; - const ClassDef &klass1 = this+classDef1; -@@ -741,13 +764,12 @@ - { - TRACE_APPLY (this); - hb_buffer_t *buffer = c->buffer; -- hb_apply_context_t::skipping_forward_iterator_t skippy_iter (c, buffer->idx, 1); -- if (skippy_iter.has_no_chance ()) return TRACE_RETURN (false); -- - unsigned int index = (this+coverage).get_coverage (buffer->cur().codepoint); -- if (likely (index == NOT_COVERED)) return TRACE_RETURN (false); -+ if (likely (index == NOT_COVERED)) return_trace (false); - -- if (!skippy_iter.next ()) return TRACE_RETURN (false); -+ hb_apply_context_t::skipping_iterator_t &skippy_iter = c->iter_input; -+ skippy_iter.reset (buffer->idx, 1); -+ if (!skippy_iter.next ()) return_trace (false); - - unsigned int len1 = valueFormat1.get_len (); - unsigned int len2 = valueFormat2.get_len (); -@@ -755,7 +777,7 @@ - - unsigned int klass1 = (this+classDef1).get_class (buffer->cur().codepoint); - unsigned int klass2 = (this+classDef2).get_class (buffer->info[skippy_iter.idx].codepoint); -- if (unlikely (klass1 >= class1Count || klass2 >= class2Count)) return TRACE_RETURN (false); -+ if (unlikely (klass1 >= class1Count || klass2 >= class2Count)) return_trace (false); - - const Value *v = &values[record_len * (klass1 * class2Count + klass2)]; - valueFormat1.apply_value (c->font, c->direction, this, -@@ -767,24 +789,25 @@ - if (len2) - buffer->idx++; - -- return TRACE_RETURN (true); -+ return_trace (true); - } - -- inline bool sanitize (hb_sanitize_context_t *c) { -+ inline bool sanitize (hb_sanitize_context_t *c) const -+ { - TRACE_SANITIZE (this); - if (!(c->check_struct (this) - && coverage.sanitize (c, this) - && classDef1.sanitize (c, this) -- && classDef2.sanitize (c, this))) return TRACE_RETURN (false); -+ && classDef2.sanitize (c, this))) return_trace (false); - - unsigned int len1 = valueFormat1.get_len (); - unsigned int len2 = valueFormat2.get_len (); - unsigned int stride = len1 + len2; - unsigned int record_size = valueFormat1.get_size () + valueFormat2.get_size (); - unsigned int count = (unsigned int) class1Count * (unsigned int) class2Count; -- return TRACE_RETURN (c->check_array (values, record_size, count) && -- valueFormat1.sanitize_values_stride_unsafe (c, this, &values[0], count, stride) && -- valueFormat2.sanitize_values_stride_unsafe (c, this, &values[len1], count, stride)); -+ return_trace (c->check_array (values, record_size, count) && -+ valueFormat1.sanitize_values_stride_unsafe (c, this, &values[0], count, stride) && -+ valueFormat2.sanitize_values_stride_unsafe (c, this, &values[len1], count, stride)); - } - - protected: -@@ -823,20 +846,11 @@ - inline typename context_t::return_t dispatch (context_t *c) const - { - TRACE_DISPATCH (this, u.format); -+ if (unlikely (!c->may_dispatch (this, &u.format))) return_trace (c->no_dispatch_return_value ()); - switch (u.format) { -- case 1: return TRACE_RETURN (c->dispatch (u.format1)); -- case 2: return TRACE_RETURN (c->dispatch (u.format2)); -- default:return TRACE_RETURN (c->default_return_value ()); -- } -- } -- -- inline bool sanitize (hb_sanitize_context_t *c) { -- TRACE_SANITIZE (this); -- if (!u.format.sanitize (c)) return TRACE_RETURN (false); -- switch (u.format) { -- case 1: return TRACE_RETURN (u.format1.sanitize (c)); -- case 2: return TRACE_RETURN (u.format2.sanitize (c)); -- default:return TRACE_RETURN (true); -+ case 1: return_trace (c->dispatch (u.format1)); -+ case 2: return_trace (c->dispatch (u.format2)); -+ default:return_trace (c->default_return_value ()); - } - } - -@@ -853,9 +867,10 @@ - { - friend struct CursivePosFormat1; - -- inline bool sanitize (hb_sanitize_context_t *c, void *base) { -+ inline bool sanitize (hb_sanitize_context_t *c, const void *base) const -+ { - TRACE_SANITIZE (this); -- return TRACE_RETURN (entryAnchor.sanitize (c, base) && exitAnchor.sanitize (c, base)); -+ return_trace (entryAnchor.sanitize (c, base) && exitAnchor.sanitize (c, base)); - } - - protected: -@@ -871,6 +886,9 @@ - DEFINE_SIZE_STATIC (4); - }; - -+static void -+reverse_cursive_minor_offset (hb_glyph_position_t *pos, unsigned int i, hb_direction_t direction, unsigned int new_parent); -+ - struct CursivePosFormat1 - { - inline void collect_glyphs (hb_collect_glyphs_context_t *c) const -@@ -890,18 +908,17 @@ - hb_buffer_t *buffer = c->buffer; - - /* We don't handle mark glyphs here. */ -- if (unlikely (_hb_glyph_info_is_mark (&buffer->cur()))) return TRACE_RETURN (false); -- -- hb_apply_context_t::skipping_forward_iterator_t skippy_iter (c, buffer->idx, 1); -- if (skippy_iter.has_no_chance ()) return TRACE_RETURN (false); -+ if (unlikely (_hb_glyph_info_is_mark (&buffer->cur()))) return_trace (false); - - const EntryExitRecord &this_record = entryExitRecord[(this+coverage).get_coverage (buffer->cur().codepoint)]; -- if (!this_record.exitAnchor) return TRACE_RETURN (false); -+ if (!this_record.exitAnchor) return_trace (false); - -- if (!skippy_iter.next ()) return TRACE_RETURN (false); -+ hb_apply_context_t::skipping_iterator_t &skippy_iter = c->iter_input; -+ skippy_iter.reset (buffer->idx, 1); -+ if (!skippy_iter.next ()) return_trace (false); - - const EntryExitRecord &next_record = entryExitRecord[(this+coverage).get_coverage (buffer->info[skippy_iter.idx].codepoint)]; -- if (!next_record.entryAnchor) return TRACE_RETURN (false); -+ if (!next_record.entryAnchor) return_trace (false); - - unsigned int i = buffer->idx; - unsigned int j = skippy_iter.idx; -@@ -949,27 +966,48 @@ - } - - /* Cross-direction adjustment */ -- if (c->lookup_props & LookupFlag::RightToLeft) { -- pos[i].cursive_chain() = j - i; -- if (likely (HB_DIRECTION_IS_HORIZONTAL (c->direction))) -- pos[i].y_offset = entry_y - exit_y; -- else -- pos[i].x_offset = entry_x - exit_x; -- } else { -- pos[j].cursive_chain() = i - j; -- if (likely (HB_DIRECTION_IS_HORIZONTAL (c->direction))) -- pos[j].y_offset = exit_y - entry_y; -- else -- pos[j].x_offset = exit_x - entry_x; -- } -+ -+ /* We attach child to parent (think graph theory and rooted trees whereas -+ * the root stays on baseline and each node aligns itself against its -+ * parent. -+ * -+ * Optimize things for the case of RightToLeft, as that's most common in -+ * Arabinc. */ -+ unsigned int child = i; -+ unsigned int parent = j; -+ hb_position_t x_offset = entry_x - exit_x; -+ hb_position_t y_offset = entry_y - exit_y; -+ if (!(c->lookup_props & LookupFlag::RightToLeft)) -+ { -+ unsigned int k = child; -+ child = parent; -+ parent = k; -+ x_offset = -x_offset; -+ y_offset = -y_offset; -+ } -+ -+ /* If child was already connected to someone else, walk through its old -+ * chain and reverse the link direction, such that the whole tree of its -+ * previous connection now attaches to new parent. Watch out for case -+ * where new parent is on the path from old chain... -+ */ -+ reverse_cursive_minor_offset (pos, child, c->direction, parent); -+ -+ pos[child].cursive_chain() = parent - child; -+ buffer->scratch_flags |= HB_BUFFER_SCRATCH_FLAG_HAS_GPOS_CURSIVE; -+ if (likely (HB_DIRECTION_IS_HORIZONTAL (c->direction))) -+ pos[child].y_offset = y_offset; -+ else -+ pos[child].x_offset = x_offset; - - buffer->idx = j; -- return TRACE_RETURN (true); -+ return_trace (true); - } - -- inline bool sanitize (hb_sanitize_context_t *c) { -+ inline bool sanitize (hb_sanitize_context_t *c) const -+ { - TRACE_SANITIZE (this); -- return TRACE_RETURN (coverage.sanitize (c, this) && entryExitRecord.sanitize (c, this)); -+ return_trace (coverage.sanitize (c, this) && entryExitRecord.sanitize (c, this)); - } - - protected: -@@ -990,18 +1028,10 @@ - inline typename context_t::return_t dispatch (context_t *c) const - { - TRACE_DISPATCH (this, u.format); -+ if (unlikely (!c->may_dispatch (this, &u.format))) return_trace (c->no_dispatch_return_value ()); - switch (u.format) { -- case 1: return TRACE_RETURN (c->dispatch (u.format1)); -- default:return TRACE_RETURN (c->default_return_value ()); -- } -- } -- -- inline bool sanitize (hb_sanitize_context_t *c) { -- TRACE_SANITIZE (this); -- if (!u.format.sanitize (c)) return TRACE_RETURN (false); -- switch (u.format) { -- case 1: return TRACE_RETURN (u.format1.sanitize (c)); -- default:return TRACE_RETURN (true); -+ case 1: return_trace (c->dispatch (u.format1)); -+ default:return_trace (c->default_return_value ()); - } - } - -@@ -1037,31 +1067,36 @@ - TRACE_APPLY (this); - hb_buffer_t *buffer = c->buffer; - unsigned int mark_index = (this+markCoverage).get_coverage (buffer->cur().codepoint); -- if (likely (mark_index == NOT_COVERED)) return TRACE_RETURN (false); -+ if (likely (mark_index == NOT_COVERED)) return_trace (false); - - /* now we search backwards for a non-mark glyph */ -- hb_apply_context_t::skipping_backward_iterator_t skippy_iter (c, buffer->idx, 1); -+ hb_apply_context_t::skipping_iterator_t &skippy_iter = c->iter_input; -+ skippy_iter.reset (buffer->idx, 1); - skippy_iter.set_lookup_props (LookupFlag::IgnoreMarks); - do { -- if (!skippy_iter.prev ()) return TRACE_RETURN (false); -+ if (!skippy_iter.prev ()) return_trace (false); - /* We only want to attach to the first of a MultipleSubst sequence. Reject others. */ - if (0 == _hb_glyph_info_get_lig_comp (&buffer->info[skippy_iter.idx])) break; - skippy_iter.reject (); - } while (1); - - /* Checking that matched glyph is actually a base glyph by GDEF is too strong; disabled */ -- if (!_hb_glyph_info_is_base_glyph (&buffer->info[skippy_iter.idx])) { /*return TRACE_RETURN (false);*/ } -+ if (!_hb_glyph_info_is_base_glyph (&buffer->info[skippy_iter.idx])) { /*return_trace (false);*/ } - - unsigned int base_index = (this+baseCoverage).get_coverage (buffer->info[skippy_iter.idx].codepoint); -- if (base_index == NOT_COVERED) return TRACE_RETURN (false); -+ if (base_index == NOT_COVERED) return_trace (false); - -- return TRACE_RETURN ((this+markArray).apply (c, mark_index, base_index, this+baseArray, classCount, skippy_iter.idx)); -+ return_trace ((this+markArray).apply (c, mark_index, base_index, this+baseArray, classCount, skippy_iter.idx)); - } - -- inline bool sanitize (hb_sanitize_context_t *c) { -+ inline bool sanitize (hb_sanitize_context_t *c) const -+ { - TRACE_SANITIZE (this); -- return TRACE_RETURN (c->check_struct (this) && markCoverage.sanitize (c, this) && baseCoverage.sanitize (c, this) && -- markArray.sanitize (c, this) && baseArray.sanitize (c, this, (unsigned int) classCount)); -+ return_trace (c->check_struct (this) && -+ markCoverage.sanitize (c, this) && -+ baseCoverage.sanitize (c, this) && -+ markArray.sanitize (c, this) && -+ baseArray.sanitize (c, this, (unsigned int) classCount)); - } - - protected: -@@ -1089,18 +1124,10 @@ - inline typename context_t::return_t dispatch (context_t *c) const - { - TRACE_DISPATCH (this, u.format); -+ if (unlikely (!c->may_dispatch (this, &u.format))) return_trace (c->no_dispatch_return_value ()); - switch (u.format) { -- case 1: return TRACE_RETURN (c->dispatch (u.format1)); -- default:return TRACE_RETURN (c->default_return_value ()); -- } -- } -- -- inline bool sanitize (hb_sanitize_context_t *c) { -- TRACE_SANITIZE (this); -- if (!u.format.sanitize (c)) return TRACE_RETURN (false); -- switch (u.format) { -- case 1: return TRACE_RETURN (u.format1.sanitize (c)); -- default:return TRACE_RETURN (true); -+ case 1: return_trace (c->dispatch (u.format1)); -+ default:return_trace (c->default_return_value ()); - } - } - -@@ -1141,26 +1168,27 @@ - TRACE_APPLY (this); - hb_buffer_t *buffer = c->buffer; - unsigned int mark_index = (this+markCoverage).get_coverage (buffer->cur().codepoint); -- if (likely (mark_index == NOT_COVERED)) return TRACE_RETURN (false); -+ if (likely (mark_index == NOT_COVERED)) return_trace (false); - - /* now we search backwards for a non-mark glyph */ -- hb_apply_context_t::skipping_backward_iterator_t skippy_iter (c, buffer->idx, 1); -+ hb_apply_context_t::skipping_iterator_t &skippy_iter = c->iter_input; -+ skippy_iter.reset (buffer->idx, 1); - skippy_iter.set_lookup_props (LookupFlag::IgnoreMarks); -- if (!skippy_iter.prev ()) return TRACE_RETURN (false); -+ if (!skippy_iter.prev ()) return_trace (false); - - /* Checking that matched glyph is actually a ligature by GDEF is too strong; disabled */ -- if (!_hb_glyph_info_is_ligature (&buffer->info[skippy_iter.idx])) { /*return TRACE_RETURN (false);*/ } -+ if (!_hb_glyph_info_is_ligature (&buffer->info[skippy_iter.idx])) { /*return_trace (false);*/ } - - unsigned int j = skippy_iter.idx; - unsigned int lig_index = (this+ligatureCoverage).get_coverage (buffer->info[j].codepoint); -- if (lig_index == NOT_COVERED) return TRACE_RETURN (false); -+ if (lig_index == NOT_COVERED) return_trace (false); - - const LigatureArray& lig_array = this+ligatureArray; - const LigatureAttach& lig_attach = lig_array[lig_index]; - - /* Find component to attach to */ - unsigned int comp_count = lig_attach.rows; -- if (unlikely (!comp_count)) return TRACE_RETURN (false); -+ if (unlikely (!comp_count)) return_trace (false); - - /* We must now check whether the ligature ID of the current mark glyph - * is identical to the ligature ID of the found ligature. If yes, we -@@ -1175,13 +1203,17 @@ - else - comp_index = comp_count - 1; - -- return TRACE_RETURN ((this+markArray).apply (c, mark_index, comp_index, lig_attach, classCount, j)); -+ return_trace ((this+markArray).apply (c, mark_index, comp_index, lig_attach, classCount, j)); - } - -- inline bool sanitize (hb_sanitize_context_t *c) { -+ inline bool sanitize (hb_sanitize_context_t *c) const -+ { - TRACE_SANITIZE (this); -- return TRACE_RETURN (c->check_struct (this) && markCoverage.sanitize (c, this) && ligatureCoverage.sanitize (c, this) && -- markArray.sanitize (c, this) && ligatureArray.sanitize (c, this, (unsigned int) classCount)); -+ return_trace (c->check_struct (this) && -+ markCoverage.sanitize (c, this) && -+ ligatureCoverage.sanitize (c, this) && -+ markArray.sanitize (c, this) && -+ ligatureArray.sanitize (c, this, (unsigned int) classCount)); - } - - protected: -@@ -1210,18 +1242,10 @@ - inline typename context_t::return_t dispatch (context_t *c) const - { - TRACE_DISPATCH (this, u.format); -+ if (unlikely (!c->may_dispatch (this, &u.format))) return_trace (c->no_dispatch_return_value ()); - switch (u.format) { -- case 1: return TRACE_RETURN (c->dispatch (u.format1)); -- default:return TRACE_RETURN (c->default_return_value ()); -- } -- } -- -- inline bool sanitize (hb_sanitize_context_t *c) { -- TRACE_SANITIZE (this); -- if (!u.format.sanitize (c)) return TRACE_RETURN (false); -- switch (u.format) { -- case 1: return TRACE_RETURN (u.format1.sanitize (c)); -- default:return TRACE_RETURN (true); -+ case 1: return_trace (c->dispatch (u.format1)); -+ default:return_trace (c->default_return_value ()); - } - } - -@@ -1257,14 +1281,15 @@ - TRACE_APPLY (this); - hb_buffer_t *buffer = c->buffer; - unsigned int mark1_index = (this+mark1Coverage).get_coverage (buffer->cur().codepoint); -- if (likely (mark1_index == NOT_COVERED)) return TRACE_RETURN (false); -+ if (likely (mark1_index == NOT_COVERED)) return_trace (false); - - /* now we search backwards for a suitable mark glyph until a non-mark glyph */ -- hb_apply_context_t::skipping_backward_iterator_t skippy_iter (c, buffer->idx, 1); -+ hb_apply_context_t::skipping_iterator_t &skippy_iter = c->iter_input; -+ skippy_iter.reset (buffer->idx, 1); - skippy_iter.set_lookup_props (c->lookup_props & ~LookupFlag::IgnoreFlags); -- if (!skippy_iter.prev ()) return TRACE_RETURN (false); -+ if (!skippy_iter.prev ()) return_trace (false); - -- if (!_hb_glyph_info_is_mark (&buffer->info[skippy_iter.idx])) { return TRACE_RETURN (false); } -+ if (!_hb_glyph_info_is_mark (&buffer->info[skippy_iter.idx])) { return_trace (false); } - - unsigned int j = skippy_iter.idx; - -@@ -1286,20 +1311,23 @@ - } - - /* Didn't match. */ -- return TRACE_RETURN (false); -+ return_trace (false); - - good: - unsigned int mark2_index = (this+mark2Coverage).get_coverage (buffer->info[j].codepoint); -- if (mark2_index == NOT_COVERED) return TRACE_RETURN (false); -+ if (mark2_index == NOT_COVERED) return_trace (false); - -- return TRACE_RETURN ((this+mark1Array).apply (c, mark1_index, mark2_index, this+mark2Array, classCount, j)); -+ return_trace ((this+mark1Array).apply (c, mark1_index, mark2_index, this+mark2Array, classCount, j)); - } - -- inline bool sanitize (hb_sanitize_context_t *c) { -+ inline bool sanitize (hb_sanitize_context_t *c) const -+ { - TRACE_SANITIZE (this); -- return TRACE_RETURN (c->check_struct (this) && mark1Coverage.sanitize (c, this) && -- mark2Coverage.sanitize (c, this) && mark1Array.sanitize (c, this) -- && mark2Array.sanitize (c, this, (unsigned int) classCount)); -+ return_trace (c->check_struct (this) && -+ mark1Coverage.sanitize (c, this) && -+ mark2Coverage.sanitize (c, this) && -+ mark1Array.sanitize (c, this) && -+ mark2Array.sanitize (c, this, (unsigned int) classCount)); - } - - protected: -@@ -1329,18 +1357,10 @@ - inline typename context_t::return_t dispatch (context_t *c) const - { - TRACE_DISPATCH (this, u.format); -+ if (unlikely (!c->may_dispatch (this, &u.format))) return_trace (c->no_dispatch_return_value ()); - switch (u.format) { -- case 1: return TRACE_RETURN (c->dispatch (u.format1)); -- default:return TRACE_RETURN (c->default_return_value ()); -- } -- } -- -- inline bool sanitize (hb_sanitize_context_t *c) { -- TRACE_SANITIZE (this); -- if (!u.format.sanitize (c)) return TRACE_RETURN (false); -- switch (u.format) { -- case 1: return TRACE_RETURN (u.format1.sanitize (c)); -- default:return TRACE_RETURN (true); -+ case 1: return_trace (c->dispatch (u.format1)); -+ default:return_trace (c->default_return_value ()); - } - } - -@@ -1388,43 +1408,24 @@ - inline typename context_t::return_t dispatch (context_t *c, unsigned int lookup_type) const - { - TRACE_DISPATCH (this, lookup_type); -+ if (unlikely (!c->may_dispatch (this, &u.sub_format))) return_trace (c->no_dispatch_return_value ()); - switch (lookup_type) { -- case Single: return TRACE_RETURN (u.single.dispatch (c)); -- case Pair: return TRACE_RETURN (u.pair.dispatch (c)); -- case Cursive: return TRACE_RETURN (u.cursive.dispatch (c)); -- case MarkBase: return TRACE_RETURN (u.markBase.dispatch (c)); -- case MarkLig: return TRACE_RETURN (u.markLig.dispatch (c)); -- case MarkMark: return TRACE_RETURN (u.markMark.dispatch (c)); -- case Context: return TRACE_RETURN (u.context.dispatch (c)); -- case ChainContext: return TRACE_RETURN (u.chainContext.dispatch (c)); -- case Extension: return TRACE_RETURN (u.extension.dispatch (c)); -- default: return TRACE_RETURN (c->default_return_value ()); -- } -- } -- -- inline bool sanitize (hb_sanitize_context_t *c, unsigned int lookup_type) { -- TRACE_SANITIZE (this); -- if (!u.header.sub_format.sanitize (c)) -- return TRACE_RETURN (false); -- switch (lookup_type) { -- case Single: return TRACE_RETURN (u.single.sanitize (c)); -- case Pair: return TRACE_RETURN (u.pair.sanitize (c)); -- case Cursive: return TRACE_RETURN (u.cursive.sanitize (c)); -- case MarkBase: return TRACE_RETURN (u.markBase.sanitize (c)); -- case MarkLig: return TRACE_RETURN (u.markLig.sanitize (c)); -- case MarkMark: return TRACE_RETURN (u.markMark.sanitize (c)); -- case Context: return TRACE_RETURN (u.context.sanitize (c)); -- case ChainContext: return TRACE_RETURN (u.chainContext.sanitize (c)); -- case Extension: return TRACE_RETURN (u.extension.sanitize (c)); -- default: return TRACE_RETURN (true); -+ case Single: return_trace (u.single.dispatch (c)); -+ case Pair: return_trace (u.pair.dispatch (c)); -+ case Cursive: return_trace (u.cursive.dispatch (c)); -+ case MarkBase: return_trace (u.markBase.dispatch (c)); -+ case MarkLig: return_trace (u.markLig.dispatch (c)); -+ case MarkMark: return_trace (u.markMark.dispatch (c)); -+ case Context: return_trace (u.context.dispatch (c)); -+ case ChainContext: return_trace (u.chainContext.dispatch (c)); -+ case Extension: return_trace (u.extension.dispatch (c)); -+ default: return_trace (c->default_return_value ()); - } - } - - protected: - union { -- struct { -- USHORT sub_format; -- } header; -+ USHORT sub_format; - SinglePos single; - PairPos pair; - CursivePos cursive; -@@ -1436,48 +1437,37 @@ - ExtensionPos extension; - } u; - public: -- DEFINE_SIZE_UNION (2, header.sub_format); -+ DEFINE_SIZE_UNION (2, sub_format); - }; - - - struct PosLookup : Lookup - { - inline const PosLookupSubTable& get_subtable (unsigned int i) const -- { return this+CastR<OffsetArrayOf<PosLookupSubTable> > (subTable)[i]; } -+ { return Lookup::get_subtable<PosLookupSubTable> (i); } - - inline bool is_reverse (void) const - { - return false; - } - -+ inline bool apply (hb_apply_context_t *c) const -+ { -+ TRACE_APPLY (this); -+ return_trace (dispatch (c)); -+ } -+ - inline hb_collect_glyphs_context_t::return_t collect_glyphs (hb_collect_glyphs_context_t *c) const - { - TRACE_COLLECT_GLYPHS (this); -- c->set_recurse_func (NULL); -- return TRACE_RETURN (dispatch (c)); -+ return_trace (dispatch (c)); - } - - template <typename set_t> - inline void add_coverage (set_t *glyphs) const - { -- hb_get_coverage_context_t c; -- const Coverage *last = NULL; -- unsigned int count = get_subtable_count (); -- for (unsigned int i = 0; i < count; i++) { -- const Coverage *coverage = &get_subtable (i).dispatch (&c, get_type ()); -- if (coverage != last) { -- coverage->add_coverage (glyphs); -- last = coverage; -- } -- } -- } -- -- inline bool apply_once (hb_apply_context_t *c) const -- { -- TRACE_APPLY (this); -- if (!c->check_glyph_property (&c->buffer->cur(), c->lookup_props)) -- return TRACE_RETURN (false); -- return TRACE_RETURN (dispatch (c)); -+ hb_add_coverage_context_t<set_t> c (glyphs); -+ dispatch (&c); - } - - static bool apply_recurse_func (hb_apply_context_t *c, unsigned int lookup_index); -@@ -1487,23 +1477,13 @@ - - template <typename context_t> - inline typename context_t::return_t dispatch (context_t *c) const -- { -- unsigned int lookup_type = get_type (); -- TRACE_DISPATCH (this, lookup_type); -- unsigned int count = get_subtable_count (); -- for (unsigned int i = 0; i < count; i++) { -- typename context_t::return_t r = get_subtable (i).dispatch (c, lookup_type); -- if (c->stop_sublookup_iteration (r)) -- return TRACE_RETURN (r); -- } -- return TRACE_RETURN (c->default_return_value ()); -- } -+ { return Lookup::dispatch<PosLookupSubTable> (c); } - -- inline bool sanitize (hb_sanitize_context_t *c) { -+ inline bool sanitize (hb_sanitize_context_t *c) const -+ { - TRACE_SANITIZE (this); -- if (unlikely (!Lookup::sanitize (c))) return TRACE_RETURN (false); -- OffsetArrayOf<PosLookupSubTable> &list = CastR<OffsetArrayOf<PosLookupSubTable> > (subTable); -- return TRACE_RETURN (list.sanitize (c, this, get_type ())); -+ if (unlikely (!Lookup::sanitize (c))) return_trace (false); -+ return_trace (dispatch (c)); - } - }; - -@@ -1523,11 +1503,12 @@ - static inline void position_start (hb_font_t *font, hb_buffer_t *buffer); - static inline void position_finish (hb_font_t *font, hb_buffer_t *buffer); - -- inline bool sanitize (hb_sanitize_context_t *c) { -+ inline bool sanitize (hb_sanitize_context_t *c) const -+ { - TRACE_SANITIZE (this); -- if (unlikely (!GSUBGPOS::sanitize (c))) return TRACE_RETURN (false); -- OffsetTo<PosLookupList> &list = CastR<OffsetTo<PosLookupList> > (lookupList); -- return TRACE_RETURN (list.sanitize (c, this)); -+ if (unlikely (!GSUBGPOS::sanitize (c))) return_trace (false); -+ const OffsetTo<PosLookupList> &list = CastR<OffsetTo<PosLookupList> > (lookupList); -+ return_trace (list.sanitize (c, this)); - } - public: - DEFINE_SIZE_STATIC (10); -@@ -1535,6 +1516,30 @@ - - - static void -+reverse_cursive_minor_offset (hb_glyph_position_t *pos, unsigned int i, hb_direction_t direction, unsigned int new_parent) -+{ -+ unsigned int j = pos[i].cursive_chain(); -+ if (likely (!j)) -+ return; -+ -+ j += i; -+ -+ pos[i].cursive_chain() = 0; -+ -+ /* Stop if we see new parent in the chain. */ -+ if (j == new_parent) -+ return; -+ -+ reverse_cursive_minor_offset (pos, j, direction, new_parent); -+ -+ if (HB_DIRECTION_IS_HORIZONTAL (direction)) -+ pos[j].y_offset = -pos[i].y_offset; -+ else -+ pos[j].x_offset = -pos[i].x_offset; -+ -+ pos[j].cursive_chain() = i - j; -+} -+static void - fix_cursive_minor_offset (hb_glyph_position_t *pos, unsigned int i, hb_direction_t direction) - { - unsigned int j = pos[i].cursive_chain(); -@@ -1596,12 +1601,14 @@ - hb_direction_t direction = buffer->props.direction; - - /* Handle cursive connections */ -- for (unsigned int i = 0; i < len; i++) -- fix_cursive_minor_offset (pos, i, direction); -+ if (buffer->scratch_flags & HB_BUFFER_SCRATCH_FLAG_HAS_GPOS_CURSIVE) -+ for (unsigned int i = 0; i < len; i++) -+ fix_cursive_minor_offset (pos, i, direction); - - /* Handle attachments */ -- for (unsigned int i = 0; i < len; i++) -- fix_mark_attachment (pos, i, direction); -+ if (buffer->scratch_flags & HB_BUFFER_SCRATCH_FLAG_HAS_GPOS_ATTACHMENT) -+ for (unsigned int i = 0; i < len; i++) -+ fix_mark_attachment (pos, i, direction); - } - - -@@ -1620,9 +1627,12 @@ - const GPOS &gpos = *(hb_ot_layout_from_face (c->face)->gpos); - const PosLookup &l = gpos.get_lookup (lookup_index); - unsigned int saved_lookup_props = c->lookup_props; -- c->set_lookup (l); -- bool ret = l.apply_once (c); -- c->lookup_props = saved_lookup_props; -+ unsigned int saved_lookup_index = c->lookup_index; -+ c->set_lookup_index (lookup_index); -+ c->set_lookup_props (l.get_props ()); -+ bool ret = l.dispatch (c); -+ c->set_lookup_index (saved_lookup_index); -+ c->set_lookup_props (saved_lookup_props); - return ret; - } - -diff -uN gfx/harfbuzz/src_old/hb-ot-layout-gsubgpos-private.hh gfx/harfbuzz/src/hb-ot-layout-gsubgpos-private.hh ---- gfx/harfbuzz/src_old/hb-ot-layout-gsubgpos-private.hh 2016-05-10 22:26:55.000000000 +0200 -+++ gfx/harfbuzz/src/hb-ot-layout-gsubgpos-private.hh 2016-06-05 23:49:27.351978674 +0200 -@@ -37,12 +37,6 @@ - namespace OT { - - -- --#define TRACE_DISPATCH(this, format) \ -- hb_auto_trace_t<context_t::max_debug_depth, typename context_t::return_t> trace \ -- (&c->debug_depth, c->get_name (), this, HB_FUNC, \ -- "format %d", (int) format); -- - #ifndef HB_DEBUG_CLOSURE - #define HB_DEBUG_CLOSURE (HB_DEBUG+0) - #endif -@@ -52,11 +46,10 @@ - (&c->debug_depth, c->get_name (), this, HB_FUNC, \ - ""); - --struct hb_closure_context_t -+struct hb_closure_context_t : -+ hb_dispatch_context_t<hb_closure_context_t, hb_void_t, HB_DEBUG_CLOSURE> - { - inline const char *get_name (void) { return "CLOSURE"; } -- static const unsigned int max_debug_depth = HB_DEBUG_CLOSURE; -- typedef hb_void_t return_t; - typedef return_t (*recurse_func_t) (hb_closure_context_t *c, unsigned int lookup_index); - template <typename T> - inline return_t dispatch (const T &obj) { obj.closure (this); return HB_VOID; } -@@ -81,7 +74,7 @@ - - hb_closure_context_t (hb_face_t *face_, - hb_set_t *glyphs_, -- unsigned int nesting_level_left_ = MAX_NESTING_LEVEL) : -+ unsigned int nesting_level_left_ = HB_MAX_NESTING_LEVEL) : - face (face_), - glyphs (glyphs_), - recurse_func (NULL), -@@ -102,11 +95,10 @@ - (&c->debug_depth, c->get_name (), this, HB_FUNC, \ - "%d glyphs", c->len); - --struct hb_would_apply_context_t -+struct hb_would_apply_context_t : -+ hb_dispatch_context_t<hb_would_apply_context_t, bool, HB_DEBUG_WOULD_APPLY> - { - inline const char *get_name (void) { return "WOULD_APPLY"; } -- static const unsigned int max_debug_depth = HB_DEBUG_WOULD_APPLY; -- typedef bool return_t; - template <typename T> - inline return_t dispatch (const T &obj) { return obj.would_apply (this); } - static return_t default_return_value (void) { return false; } -@@ -140,11 +132,10 @@ - (&c->debug_depth, c->get_name (), this, HB_FUNC, \ - ""); - --struct hb_collect_glyphs_context_t -+struct hb_collect_glyphs_context_t : -+ hb_dispatch_context_t<hb_collect_glyphs_context_t, hb_void_t, HB_DEBUG_COLLECT_GLYPHS> - { - inline const char *get_name (void) { return "COLLECT_GLYPHS"; } -- static const unsigned int max_debug_depth = HB_DEBUG_COLLECT_GLYPHS; -- typedef hb_void_t return_t; - typedef return_t (*recurse_func_t) (hb_collect_glyphs_context_t *c, unsigned int lookup_index); - template <typename T> - inline return_t dispatch (const T &obj) { obj.collect_glyphs (this); return HB_VOID; } -@@ -205,7 +196,7 @@ - hb_set_t *glyphs_input, /* OUT. May be NULL */ - hb_set_t *glyphs_after, /* OUT. May be NULL */ - hb_set_t *glyphs_output, /* OUT. May be NULL */ -- unsigned int nesting_level_left_ = MAX_NESTING_LEVEL) : -+ unsigned int nesting_level_left_ = HB_MAX_NESTING_LEVEL) : - face (face_), - before (glyphs_before ? glyphs_before : hb_set_get_empty ()), - input (glyphs_input ? glyphs_input : hb_set_get_empty ()), -@@ -232,18 +223,28 @@ - #define HB_DEBUG_GET_COVERAGE (HB_DEBUG+0) - #endif - --struct hb_get_coverage_context_t -+/* XXX Can we remove this? */ -+ -+template <typename set_t> -+struct hb_add_coverage_context_t : -+ hb_dispatch_context_t<hb_add_coverage_context_t<set_t>, const Coverage &, HB_DEBUG_GET_COVERAGE> - { - inline const char *get_name (void) { return "GET_COVERAGE"; } -- static const unsigned int max_debug_depth = HB_DEBUG_GET_COVERAGE; - typedef const Coverage &return_t; - template <typename T> - inline return_t dispatch (const T &obj) { return obj.get_coverage (); } - static return_t default_return_value (void) { return Null(Coverage); } -+ bool stop_sublookup_iteration (return_t r) const -+ { -+ r.add_coverage (set); -+ return false; -+ } - -- hb_get_coverage_context_t (void) : -+ hb_add_coverage_context_t (set_t *set_) : -+ set (set_), - debug_depth (0) {} - -+ set_t *set; - unsigned int debug_depth; - }; - -@@ -256,65 +257,12 @@ - #define TRACE_APPLY(this) \ - hb_auto_trace_t<HB_DEBUG_APPLY, bool> trace \ - (&c->debug_depth, c->get_name (), this, HB_FUNC, \ -- "idx %d codepoint %u", c->buffer->idx, c->buffer->cur().codepoint); -+ "idx %d gid %u lookup %d", \ -+ c->buffer->idx, c->buffer->cur().codepoint, (int) c->lookup_index); - --struct hb_apply_context_t -+struct hb_apply_context_t : -+ hb_dispatch_context_t<hb_apply_context_t, bool, HB_DEBUG_APPLY> - { -- inline const char *get_name (void) { return "APPLY"; } -- static const unsigned int max_debug_depth = HB_DEBUG_APPLY; -- typedef bool return_t; -- typedef return_t (*recurse_func_t) (hb_apply_context_t *c, unsigned int lookup_index); -- 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; } -- return_t recurse (unsigned int lookup_index) -- { -- if (unlikely (nesting_level_left == 0 || !recurse_func)) -- return default_return_value (); -- -- nesting_level_left--; -- bool ret = recurse_func (this, lookup_index); -- nesting_level_left++; -- return ret; -- } -- -- unsigned int table_index; /* GSUB/GPOS */ -- hb_font_t *font; -- hb_face_t *face; -- hb_buffer_t *buffer; -- hb_direction_t direction; -- hb_mask_t lookup_mask; -- bool auto_zwj; -- recurse_func_t recurse_func; -- unsigned int nesting_level_left; -- unsigned int lookup_props; -- const GDEF &gdef; -- bool has_glyph_classes; -- unsigned int debug_depth; -- -- -- hb_apply_context_t (unsigned int table_index_, -- hb_font_t *font_, -- hb_buffer_t *buffer_) : -- table_index (table_index_), -- font (font_), face (font->face), buffer (buffer_), -- direction (buffer_->props.direction), -- lookup_mask (1), -- auto_zwj (true), -- recurse_func (NULL), -- nesting_level_left (MAX_NESTING_LEVEL), -- lookup_props (0), -- gdef (*hb_ot_layout_from_face (face)->gdef), -- has_glyph_classes (gdef.has_glyph_classes ()), -- debug_depth (0) {} -- -- inline void set_lookup_mask (hb_mask_t mask) { lookup_mask = mask; } -- inline void set_auto_zwj (bool auto_zwj_) { auto_zwj = auto_zwj_; } -- inline void set_recurse_func (recurse_func_t func) { recurse_func = func; } -- inline void set_lookup_props (unsigned int lookup_props_) { lookup_props = lookup_props_; } -- inline void set_lookup (const Lookup &l) { lookup_props = l.get_props (); } -- - struct matcher_t - { - inline matcher_t (void) : -@@ -373,8 +321,7 @@ - - if (unlikely (_hb_glyph_info_is_default_ignorable (&info) && - (ignore_zwnj || !_hb_glyph_info_is_zwnj (&info)) && -- (ignore_zwj || !_hb_glyph_info_is_zwj (&info)) && -- !_hb_glyph_info_ligated (&info))) -+ (ignore_zwj || !_hb_glyph_info_is_zwj (&info)))) - return SKIP_MAYBE; - - return SKIP_NO; -@@ -390,43 +337,47 @@ - const void *match_data; - }; - -- struct skipping_forward_iterator_t -+ struct skipping_iterator_t - { -- inline skipping_forward_iterator_t (hb_apply_context_t *c_, -- unsigned int start_index_, -- unsigned int num_items_, -- bool context_match = false) : -- idx (start_index_), -- c (c_), -- match_glyph_data (NULL), -- num_items (num_items_), -- end (c->buffer->len) -+ inline void init (hb_apply_context_t *c_, bool context_match = false) - { -+ c = c_; -+ match_glyph_data = NULL, -+ matcher.set_match_func (NULL, NULL); - matcher.set_lookup_props (c->lookup_props); - /* Ignore ZWNJ if we are matching GSUB context, or matching GPOS. */ - matcher.set_ignore_zwnj (context_match || c->table_index == 1); - /* Ignore ZWJ if we are matching GSUB context, or matching GPOS, or if asked to. */ - matcher.set_ignore_zwj (context_match || c->table_index == 1 || c->auto_zwj); -- if (!context_match) -- matcher.set_mask (c->lookup_mask); -- matcher.set_syllable (start_index_ == c->buffer->idx ? c->buffer->cur().syllable () : 0); -+ matcher.set_mask (context_match ? -1 : c->lookup_mask); - } -- inline void set_lookup_props (unsigned int lookup_props) { matcher.set_lookup_props (lookup_props); } -- inline void set_syllable (unsigned int syllable) { matcher.set_syllable (syllable); } -- inline void set_match_func (matcher_t::match_func_t match_func, -- const void *match_data, -+ inline void set_lookup_props (unsigned int lookup_props) -+ { -+ matcher.set_lookup_props (lookup_props); -+ } -+ inline void set_match_func (matcher_t::match_func_t match_func_, -+ const void *match_data_, - const USHORT glyph_data[]) - { -- matcher.set_match_func (match_func, match_data); -+ matcher.set_match_func (match_func_, match_data_); - match_glyph_data = glyph_data; - } - -- inline bool has_no_chance (void) const { return unlikely (num_items && idx + num_items >= end); } -+ inline void reset (unsigned int start_index_, -+ unsigned int num_items_) -+ { -+ idx = start_index_; -+ num_items = num_items_; -+ end = c->buffer->len; -+ matcher.set_syllable (start_index_ == c->buffer->idx ? c->buffer->cur().syllable () : 0); -+ } -+ - inline void reject (void) { num_items++; match_glyph_data--; } -+ - inline bool next (void) - { - assert (num_items > 0); -- while (!has_no_chance ()) -+ while (idx + num_items < end) - { - idx++; - const hb_glyph_info_t &info = c->buffer->info[idx]; -@@ -450,53 +401,10 @@ - } - return false; - } -- -- unsigned int idx; -- protected: -- hb_apply_context_t *c; -- matcher_t matcher; -- const USHORT *match_glyph_data; -- -- unsigned int num_items; -- unsigned int end; -- }; -- -- struct skipping_backward_iterator_t -- { -- inline skipping_backward_iterator_t (hb_apply_context_t *c_, -- unsigned int start_index_, -- unsigned int num_items_, -- bool context_match = false) : -- idx (start_index_), -- c (c_), -- match_glyph_data (NULL), -- num_items (num_items_) -- { -- matcher.set_lookup_props (c->lookup_props); -- /* Ignore ZWNJ if we are matching GSUB context, or matching GPOS. */ -- matcher.set_ignore_zwnj (context_match || c->table_index == 1); -- /* Ignore ZWJ if we are matching GSUB context, or matching GPOS, or if asked to. */ -- matcher.set_ignore_zwj (context_match || c->table_index == 1 || c->auto_zwj); -- if (!context_match) -- matcher.set_mask (c->lookup_mask); -- matcher.set_syllable (start_index_ == c->buffer->idx ? c->buffer->cur().syllable () : 0); -- } -- inline void set_lookup_props (unsigned int lookup_props) { matcher.set_lookup_props (lookup_props); } -- inline void set_syllable (unsigned int syllable) { matcher.set_syllable (syllable); } -- inline void set_match_func (matcher_t::match_func_t match_func, -- const void *match_data, -- const USHORT glyph_data[]) -- { -- matcher.set_match_func (match_func, match_data); -- match_glyph_data = glyph_data; -- } -- -- inline bool has_no_chance (void) const { return unlikely (idx < num_items); } -- inline void reject (void) { num_items++; } - inline bool prev (void) - { - assert (num_items > 0); -- while (!has_no_chance ()) -+ while (idx >= num_items) - { - idx--; - const hb_glyph_info_t &info = c->buffer->out_info[idx]; -@@ -528,44 +436,109 @@ - const USHORT *match_glyph_data; - - unsigned int num_items; -+ unsigned int end; - }; - -+ -+ inline const char *get_name (void) { return "APPLY"; } -+ typedef return_t (*recurse_func_t) (hb_apply_context_t *c, unsigned int lookup_index); -+ 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; } -+ return_t recurse (unsigned int lookup_index) -+ { -+ if (unlikely (nesting_level_left == 0 || !recurse_func)) -+ return default_return_value (); -+ -+ nesting_level_left--; -+ bool ret = recurse_func (this, lookup_index); -+ nesting_level_left++; -+ return ret; -+ } -+ -+ unsigned int table_index; /* GSUB/GPOS */ -+ hb_font_t *font; -+ hb_face_t *face; -+ hb_buffer_t *buffer; -+ hb_direction_t direction; -+ hb_mask_t lookup_mask; -+ bool auto_zwj; -+ recurse_func_t recurse_func; -+ unsigned int nesting_level_left; -+ unsigned int lookup_props; -+ const GDEF &gdef; -+ bool has_glyph_classes; -+ skipping_iterator_t iter_input, iter_context; -+ unsigned int lookup_index; -+ unsigned int debug_depth; -+ -+ -+ hb_apply_context_t (unsigned int table_index_, -+ hb_font_t *font_, -+ hb_buffer_t *buffer_) : -+ table_index (table_index_), -+ font (font_), face (font->face), buffer (buffer_), -+ direction (buffer_->props.direction), -+ lookup_mask (1), -+ auto_zwj (true), -+ recurse_func (NULL), -+ nesting_level_left (HB_MAX_NESTING_LEVEL), -+ lookup_props (0), -+ gdef (*hb_ot_layout_from_face (face)->gdef), -+ has_glyph_classes (gdef.has_glyph_classes ()), -+ iter_input (), -+ iter_context (), -+ lookup_index ((unsigned int) -1), -+ debug_depth (0) {} -+ -+ inline void set_lookup_mask (hb_mask_t mask) { lookup_mask = mask; } -+ inline void set_auto_zwj (bool auto_zwj_) { auto_zwj = auto_zwj_; } -+ inline void set_recurse_func (recurse_func_t func) { recurse_func = func; } -+ inline void set_lookup_index (unsigned int lookup_index_) { lookup_index = lookup_index_; } -+ inline void set_lookup_props (unsigned int lookup_props_) -+ { -+ lookup_props = lookup_props_; -+ iter_input.init (this, false); -+ iter_context.init (this, true); -+ } -+ - inline bool - match_properties_mark (hb_codepoint_t glyph, - unsigned int glyph_props, -- unsigned int lookup_props) const -+ unsigned int match_props) const - { - /* If using mark filtering sets, the high short of -- * lookup_props has the set index. -+ * match_props has the set index. - */ -- if (lookup_props & LookupFlag::UseMarkFilteringSet) -- return gdef.mark_set_covers (lookup_props >> 16, glyph); -+ if (match_props & LookupFlag::UseMarkFilteringSet) -+ return gdef.mark_set_covers (match_props >> 16, glyph); - -- /* The second byte of lookup_props has the meaning -+ /* The second byte of match_props has the meaning - * "ignore marks of attachment type different than - * the attachment type specified." - */ -- if (lookup_props & LookupFlag::MarkAttachmentType) -- return (lookup_props & LookupFlag::MarkAttachmentType) == (glyph_props & LookupFlag::MarkAttachmentType); -+ if (match_props & LookupFlag::MarkAttachmentType) -+ return (match_props & LookupFlag::MarkAttachmentType) == (glyph_props & LookupFlag::MarkAttachmentType); - - return true; - } - - inline bool - check_glyph_property (const hb_glyph_info_t *info, -- unsigned int lookup_props) const -+ unsigned int match_props) const - { - hb_codepoint_t glyph = info->codepoint; - unsigned int glyph_props = _hb_glyph_info_get_glyph_props (info); - - /* Not covered, if, for example, glyph class is ligature and -- * lookup_props includes LookupFlags::IgnoreLigatures -+ * match_props includes LookupFlags::IgnoreLigatures - */ -- if (glyph_props & lookup_props & LookupFlag::IgnoreFlags) -+ if (glyph_props & match_props & LookupFlag::IgnoreFlags) - return false; - - if (unlikely (glyph_props & HB_OT_LAYOUT_GLYPH_PROPS_MARK)) -- return match_properties_mark (glyph, glyph_props, lookup_props); -+ return match_properties_mark (glyph, glyph_props, match_props); - - return true; - } -@@ -731,19 +704,19 @@ - match_func_t match_func, - const void *match_data, - unsigned int *end_offset, -- unsigned int match_positions[MAX_CONTEXT_LENGTH], -+ unsigned int match_positions[HB_MAX_CONTEXT_LENGTH], - bool *p_is_mark_ligature = NULL, - unsigned int *p_total_component_count = NULL) - { - TRACE_APPLY (NULL); - -- if (unlikely (count > MAX_CONTEXT_LENGTH)) TRACE_RETURN (false); -+ if (unlikely (count > HB_MAX_CONTEXT_LENGTH)) return_trace (false); - - hb_buffer_t *buffer = c->buffer; - -- hb_apply_context_t::skipping_forward_iterator_t skippy_iter (c, buffer->idx, count - 1); -+ hb_apply_context_t::skipping_iterator_t &skippy_iter = c->iter_input; -+ skippy_iter.reset (buffer->idx, count - 1); - skippy_iter.set_match_func (match_func, match_data, input); -- if (skippy_iter.has_no_chance ()) return TRACE_RETURN (false); - - /* - * This is perhaps the trickiest part of OpenType... Remarks: -@@ -774,7 +747,7 @@ - match_positions[0] = buffer->idx; - for (unsigned int i = 1; i < count; i++) - { -- if (!skippy_iter.next ()) return TRACE_RETURN (false); -+ if (!skippy_iter.next ()) return_trace (false); - - match_positions[i] = skippy_iter.idx; - -@@ -786,13 +759,13 @@ - * all subsequent components should be attached to the same ligature - * component, otherwise we shouldn't ligate them. */ - if (first_lig_id != this_lig_id || first_lig_comp != this_lig_comp) -- return TRACE_RETURN (false); -+ return_trace (false); - } else { - /* If first component was NOT attached to a previous ligature component, - * all subsequent components should also NOT be attached to any ligature - * component, unless they are attached to the first component itself! */ - if (this_lig_id && this_lig_comp && (this_lig_id != first_lig_id)) -- return TRACE_RETURN (false); -+ return_trace (false); - } - - is_mark_ligature = is_mark_ligature && _hb_glyph_info_is_mark (&buffer->info[skippy_iter.idx]); -@@ -807,11 +780,11 @@ - if (p_total_component_count) - *p_total_component_count = total_component_count; - -- return TRACE_RETURN (true); -+ return_trace (true); - } --static inline void ligate_input (hb_apply_context_t *c, -+static inline bool ligate_input (hb_apply_context_t *c, - unsigned int count, /* Including the first glyph */ -- unsigned int match_positions[MAX_CONTEXT_LENGTH], /* Including the first glyph */ -+ unsigned int match_positions[HB_MAX_CONTEXT_LENGTH], /* Including the first glyph */ - unsigned int match_length, - hb_codepoint_t lig_glyph, - bool is_mark_ligature, -@@ -863,19 +836,21 @@ - if (_hb_glyph_info_get_general_category (&buffer->cur()) == HB_UNICODE_GENERAL_CATEGORY_NON_SPACING_MARK) - { - _hb_glyph_info_set_general_category (&buffer->cur(), HB_UNICODE_GENERAL_CATEGORY_OTHER_LETTER); -- _hb_glyph_info_set_modified_combining_class (&buffer->cur(), 0); - } - } - c->replace_glyph_with_ligature (lig_glyph, klass); - - for (unsigned int i = 1; i < count; i++) - { -- while (buffer->idx < match_positions[i]) -+ while (buffer->idx < match_positions[i] && !buffer->in_error) - { - if (!is_mark_ligature) { -+ unsigned int this_comp = _hb_glyph_info_get_lig_comp (&buffer->cur()); -+ if (this_comp == 0) -+ this_comp = last_num_components; - unsigned int new_lig_comp = components_so_far - last_num_components + -- MIN (MAX (_hb_glyph_info_get_lig_comp (&buffer->cur()), 1u), last_num_components); -- _hb_glyph_info_set_lig_props_for_mark (&buffer->cur(), lig_id, new_lig_comp); -+ MIN (this_comp, last_num_components); -+ _hb_glyph_info_set_lig_props_for_mark (&buffer->cur(), lig_id, new_lig_comp); - } - buffer->next_glyph (); - } -@@ -892,14 +867,17 @@ - /* Re-adjust components for any marks following. */ - for (unsigned int i = buffer->idx; i < buffer->len; i++) { - if (last_lig_id == _hb_glyph_info_get_lig_id (&buffer->info[i])) { -+ unsigned int this_comp = _hb_glyph_info_get_lig_comp (&buffer->info[i]); -+ if (!this_comp) -+ break; - unsigned int new_lig_comp = components_so_far - last_num_components + -- MIN (MAX (_hb_glyph_info_get_lig_comp (&buffer->info[i]), 1u), last_num_components); -+ MIN (this_comp, last_num_components); - _hb_glyph_info_set_lig_props_for_mark (&buffer->info[i], lig_id, new_lig_comp); - } else - break; - } - } -- TRACE_RETURN (true); -+ return_trace (true); - } - - static inline bool match_backtrack (hb_apply_context_t *c, -@@ -910,15 +888,15 @@ - { - TRACE_APPLY (NULL); - -- hb_apply_context_t::skipping_backward_iterator_t skippy_iter (c, c->buffer->backtrack_len (), count, true); -+ hb_apply_context_t::skipping_iterator_t &skippy_iter = c->iter_context; -+ skippy_iter.reset (c->buffer->backtrack_len (), count); - skippy_iter.set_match_func (match_func, match_data, backtrack); -- if (skippy_iter.has_no_chance ()) return TRACE_RETURN (false); - - for (unsigned int i = 0; i < count; i++) - if (!skippy_iter.prev ()) -- return TRACE_RETURN (false); -+ return_trace (false); - -- return TRACE_RETURN (true); -+ return_trace (true); - } - - static inline bool match_lookahead (hb_apply_context_t *c, -@@ -930,24 +908,25 @@ - { - TRACE_APPLY (NULL); - -- hb_apply_context_t::skipping_forward_iterator_t skippy_iter (c, c->buffer->idx + offset - 1, count, true); -+ hb_apply_context_t::skipping_iterator_t &skippy_iter = c->iter_context; -+ skippy_iter.reset (c->buffer->idx + offset - 1, count); - skippy_iter.set_match_func (match_func, match_data, lookahead); -- if (skippy_iter.has_no_chance ()) return TRACE_RETURN (false); - - for (unsigned int i = 0; i < count; i++) - if (!skippy_iter.next ()) -- return TRACE_RETURN (false); -+ return_trace (false); - -- return TRACE_RETURN (true); -+ return_trace (true); - } - - - - struct LookupRecord - { -- inline bool sanitize (hb_sanitize_context_t *c) { -+ inline bool sanitize (hb_sanitize_context_t *c) const -+ { - TRACE_SANITIZE (this); -- return TRACE_RETURN (c->check_struct (this)); -+ return_trace (c->check_struct (this)); - } - - USHORT sequenceIndex; /* Index into current glyph -@@ -970,7 +949,7 @@ - - static inline bool apply_lookup (hb_apply_context_t *c, - unsigned int count, /* Including the first glyph */ -- unsigned int match_positions[MAX_CONTEXT_LENGTH], /* Including the first glyph */ -+ unsigned int match_positions[HB_MAX_CONTEXT_LENGTH], /* Including the first glyph */ - unsigned int lookupCount, - const LookupRecord lookupRecord[], /* Array of LookupRecords--in design order */ - unsigned int match_length) -@@ -998,6 +977,11 @@ - if (idx >= count) - continue; - -+ /* Don't recurse to ourself at same position. -+ * Note that this test is too naive, it doesn't catch longer loops. */ -+ if (idx == 0 && lookupRecord[i].lookupListIndex == c->lookup_index) -+ continue; -+ - buffer->move_to (match_positions[idx]); - - unsigned int orig_len = buffer->backtrack_len () + buffer->lookahead_len (); -@@ -1015,13 +999,13 @@ - /* end can't go back past the current match position. - * Note: this is only true because we do NOT allow MultipleSubst - * with zero sequence len. */ -- end = MAX ((int) match_positions[idx] + 1, int (end) + delta); -+ end = MAX (MIN((int) match_positions[idx] + 1, (int) new_len), int (end) + delta); - - unsigned int next = idx + 1; /* next now is the position after the recursed lookup. */ - - if (delta > 0) - { -- if (unlikely (delta + count > MAX_CONTEXT_LENGTH)) -+ if (unlikely (delta + count > HB_MAX_CONTEXT_LENGTH)) - break; - } - else -@@ -1048,7 +1032,7 @@ - - buffer->move_to (end); - -- return TRACE_RETURN (true); -+ return_trace (true); - } - - -@@ -1120,7 +1104,7 @@ - ContextApplyLookupContext &lookup_context) - { - unsigned int match_length = 0; -- unsigned int match_positions[MAX_CONTEXT_LENGTH]; -+ unsigned int match_positions[HB_MAX_CONTEXT_LENGTH]; - return match_input (c, - inputCount, input, - lookup_context.funcs.match, lookup_context.match_data, -@@ -1157,18 +1141,19 @@ - { - TRACE_WOULD_APPLY (this); - const LookupRecord *lookupRecord = &StructAtOffset<LookupRecord> (inputZ, inputZ[0].static_size * (inputCount ? inputCount - 1 : 0)); -- return TRACE_RETURN (context_would_apply_lookup (c, inputCount, inputZ, lookupCount, lookupRecord, lookup_context)); -+ return_trace (context_would_apply_lookup (c, inputCount, inputZ, lookupCount, lookupRecord, lookup_context)); - } - - inline bool apply (hb_apply_context_t *c, ContextApplyLookupContext &lookup_context) const - { - TRACE_APPLY (this); - const LookupRecord *lookupRecord = &StructAtOffset<LookupRecord> (inputZ, inputZ[0].static_size * (inputCount ? inputCount - 1 : 0)); -- return TRACE_RETURN (context_apply_lookup (c, inputCount, inputZ, lookupCount, lookupRecord, lookup_context)); -+ return_trace (context_apply_lookup (c, inputCount, inputZ, lookupCount, lookupRecord, lookup_context)); - } - - public: -- inline bool sanitize (hb_sanitize_context_t *c) { -+ inline bool sanitize (hb_sanitize_context_t *c) const -+ { - TRACE_SANITIZE (this); - return inputCount.sanitize (c) - && lookupCount.sanitize (c) -@@ -1215,9 +1200,9 @@ - for (unsigned int i = 0; i < num_rules; i++) - { - if ((this+rule[i]).would_apply (c, lookup_context)) -- return TRACE_RETURN (true); -+ return_trace (true); - } -- return TRACE_RETURN (false); -+ return_trace (false); - } - - inline bool apply (hb_apply_context_t *c, ContextApplyLookupContext &lookup_context) const -@@ -1227,14 +1212,15 @@ - for (unsigned int i = 0; i < num_rules; i++) - { - if ((this+rule[i]).apply (c, lookup_context)) -- return TRACE_RETURN (true); -+ return_trace (true); - } -- return TRACE_RETURN (false); -+ return_trace (false); - } - -- inline bool sanitize (hb_sanitize_context_t *c) { -+ inline bool sanitize (hb_sanitize_context_t *c) const -+ { - TRACE_SANITIZE (this); -- return TRACE_RETURN (rule.sanitize (c, this)); -+ return_trace (rule.sanitize (c, this)); - } - - protected: -@@ -1291,7 +1277,7 @@ - {match_glyph}, - NULL - }; -- return TRACE_RETURN (rule_set.would_apply (c, lookup_context)); -+ return_trace (rule_set.would_apply (c, lookup_context)); - } - - inline const Coverage &get_coverage (void) const -@@ -1304,19 +1290,20 @@ - TRACE_APPLY (this); - unsigned int index = (this+coverage).get_coverage (c->buffer->cur().codepoint); - if (likely (index == NOT_COVERED)) -- return TRACE_RETURN (false); -+ return_trace (false); - - const RuleSet &rule_set = this+ruleSet[index]; - struct ContextApplyLookupContext lookup_context = { - {match_glyph}, - NULL - }; -- return TRACE_RETURN (rule_set.apply (c, lookup_context)); -+ return_trace (rule_set.apply (c, lookup_context)); - } - -- inline bool sanitize (hb_sanitize_context_t *c) { -+ inline bool sanitize (hb_sanitize_context_t *c) const -+ { - TRACE_SANITIZE (this); -- return TRACE_RETURN (coverage.sanitize (c, this) && ruleSet.sanitize (c, this)); -+ return_trace (coverage.sanitize (c, this) && ruleSet.sanitize (c, this)); - } - - protected: -@@ -1382,7 +1369,7 @@ - {match_class}, - &class_def - }; -- return TRACE_RETURN (rule_set.would_apply (c, lookup_context)); -+ return_trace (rule_set.would_apply (c, lookup_context)); - } - - inline const Coverage &get_coverage (void) const -@@ -1394,7 +1381,7 @@ - { - TRACE_APPLY (this); - unsigned int index = (this+coverage).get_coverage (c->buffer->cur().codepoint); -- if (likely (index == NOT_COVERED)) return TRACE_RETURN (false); -+ if (likely (index == NOT_COVERED)) return_trace (false); - - const ClassDef &class_def = this+classDef; - index = class_def.get_class (c->buffer->cur().codepoint); -@@ -1403,12 +1390,13 @@ - {match_class}, - &class_def - }; -- return TRACE_RETURN (rule_set.apply (c, lookup_context)); -+ return_trace (rule_set.apply (c, lookup_context)); - } - -- inline bool sanitize (hb_sanitize_context_t *c) { -+ inline bool sanitize (hb_sanitize_context_t *c) const -+ { - TRACE_SANITIZE (this); -- return TRACE_RETURN (coverage.sanitize (c, this) && classDef.sanitize (c, this) && ruleSet.sanitize (c, this)); -+ return_trace (coverage.sanitize (c, this) && classDef.sanitize (c, this) && ruleSet.sanitize (c, this)); - } - - protected: -@@ -1472,7 +1460,7 @@ - {match_coverage}, - this - }; -- return TRACE_RETURN (context_would_apply_lookup (c, glyphCount, (const USHORT *) (coverageZ + 1), lookupCount, lookupRecord, lookup_context)); -+ return_trace (context_would_apply_lookup (c, glyphCount, (const USHORT *) (coverageZ + 1), lookupCount, lookupRecord, lookup_context)); - } - - inline const Coverage &get_coverage (void) const -@@ -1484,26 +1472,27 @@ - { - TRACE_APPLY (this); - unsigned int index = (this+coverageZ[0]).get_coverage (c->buffer->cur().codepoint); -- if (likely (index == NOT_COVERED)) return TRACE_RETURN (false); -+ if (likely (index == NOT_COVERED)) return_trace (false); - - const LookupRecord *lookupRecord = &StructAtOffset<LookupRecord> (coverageZ, coverageZ[0].static_size * glyphCount); - struct ContextApplyLookupContext lookup_context = { - {match_coverage}, - this - }; -- return TRACE_RETURN (context_apply_lookup (c, glyphCount, (const USHORT *) (coverageZ + 1), lookupCount, lookupRecord, lookup_context)); -+ return_trace (context_apply_lookup (c, glyphCount, (const USHORT *) (coverageZ + 1), lookupCount, lookupRecord, lookup_context)); - } - -- inline bool sanitize (hb_sanitize_context_t *c) { -+ inline bool sanitize (hb_sanitize_context_t *c) const -+ { - TRACE_SANITIZE (this); -- if (!c->check_struct (this)) return TRACE_RETURN (false); -+ if (!c->check_struct (this)) return_trace (false); - unsigned int count = glyphCount; -- if (!count) return TRACE_RETURN (false); /* We want to access coverageZ[0] freely. */ -- if (!c->check_array (coverageZ, coverageZ[0].static_size, count)) return TRACE_RETURN (false); -+ if (!count) return_trace (false); /* We want to access coverageZ[0] freely. */ -+ if (!c->check_array (coverageZ, coverageZ[0].static_size, count)) return_trace (false); - for (unsigned int i = 0; i < count; i++) -- if (!coverageZ[i].sanitize (c, this)) return TRACE_RETURN (false); -- LookupRecord *lookupRecord = &StructAtOffset<LookupRecord> (coverageZ, coverageZ[0].static_size * count); -- return TRACE_RETURN (c->check_array (lookupRecord, lookupRecord[0].static_size, lookupCount)); -+ if (!coverageZ[i].sanitize (c, this)) return_trace (false); -+ const LookupRecord *lookupRecord = &StructAtOffset<LookupRecord> (coverageZ, coverageZ[0].static_size * count); -+ return_trace (c->check_array (lookupRecord, lookupRecord[0].static_size, lookupCount)); - } - - protected: -@@ -1526,22 +1515,12 @@ - inline typename context_t::return_t dispatch (context_t *c) const - { - TRACE_DISPATCH (this, u.format); -+ if (unlikely (!c->may_dispatch (this, &u.format))) return_trace (c->no_dispatch_return_value ()); - switch (u.format) { -- case 1: return TRACE_RETURN (c->dispatch (u.format1)); -- case 2: return TRACE_RETURN (c->dispatch (u.format2)); -- case 3: return TRACE_RETURN (c->dispatch (u.format3)); -- default:return TRACE_RETURN (c->default_return_value ()); -- } -- } -- -- inline bool sanitize (hb_sanitize_context_t *c) { -- TRACE_SANITIZE (this); -- if (!u.format.sanitize (c)) return TRACE_RETURN (false); -- switch (u.format) { -- case 1: return TRACE_RETURN (u.format1.sanitize (c)); -- case 2: return TRACE_RETURN (u.format2.sanitize (c)); -- case 3: return TRACE_RETURN (u.format3.sanitize (c)); -- default:return TRACE_RETURN (true); -+ case 1: return_trace (c->dispatch (u.format1)); -+ case 2: return_trace (c->dispatch (u.format2)); -+ case 3: return_trace (c->dispatch (u.format3)); -+ default:return_trace (c->default_return_value ()); - } - } - -@@ -1652,7 +1631,7 @@ - ChainContextApplyLookupContext &lookup_context) - { - unsigned int match_length = 0; -- unsigned int match_positions[MAX_CONTEXT_LENGTH]; -+ unsigned int match_positions[HB_MAX_CONTEXT_LENGTH]; - return match_input (c, - inputCount, input, - lookup_context.funcs.match, lookup_context.match_data[1], -@@ -1706,11 +1685,11 @@ - const HeadlessArrayOf<USHORT> &input = StructAfter<HeadlessArrayOf<USHORT> > (backtrack); - const ArrayOf<USHORT> &lookahead = StructAfter<ArrayOf<USHORT> > (input); - const ArrayOf<LookupRecord> &lookup = StructAfter<ArrayOf<LookupRecord> > (lookahead); -- return TRACE_RETURN (chain_context_would_apply_lookup (c, -- backtrack.len, backtrack.array, -- input.len, input.array, -- lookahead.len, lookahead.array, lookup.len, -- lookup.array, lookup_context)); -+ return_trace (chain_context_would_apply_lookup (c, -+ backtrack.len, backtrack.array, -+ input.len, input.array, -+ lookahead.len, lookahead.array, lookup.len, -+ lookup.array, lookup_context)); - } - - inline bool apply (hb_apply_context_t *c, ChainContextApplyLookupContext &lookup_context) const -@@ -1719,22 +1698,23 @@ - const HeadlessArrayOf<USHORT> &input = StructAfter<HeadlessArrayOf<USHORT> > (backtrack); - const ArrayOf<USHORT> &lookahead = StructAfter<ArrayOf<USHORT> > (input); - const ArrayOf<LookupRecord> &lookup = StructAfter<ArrayOf<LookupRecord> > (lookahead); -- return TRACE_RETURN (chain_context_apply_lookup (c, -- backtrack.len, backtrack.array, -- input.len, input.array, -- lookahead.len, lookahead.array, lookup.len, -- lookup.array, lookup_context)); -+ return_trace (chain_context_apply_lookup (c, -+ backtrack.len, backtrack.array, -+ input.len, input.array, -+ lookahead.len, lookahead.array, lookup.len, -+ lookup.array, lookup_context)); - } - -- inline bool sanitize (hb_sanitize_context_t *c) { -+ inline bool sanitize (hb_sanitize_context_t *c) const -+ { - TRACE_SANITIZE (this); -- if (!backtrack.sanitize (c)) return TRACE_RETURN (false); -- HeadlessArrayOf<USHORT> &input = StructAfter<HeadlessArrayOf<USHORT> > (backtrack); -- if (!input.sanitize (c)) return TRACE_RETURN (false); -- ArrayOf<USHORT> &lookahead = StructAfter<ArrayOf<USHORT> > (input); -- if (!lookahead.sanitize (c)) return TRACE_RETURN (false); -- ArrayOf<LookupRecord> &lookup = StructAfter<ArrayOf<LookupRecord> > (lookahead); -- return TRACE_RETURN (lookup.sanitize (c)); -+ if (!backtrack.sanitize (c)) return_trace (false); -+ const HeadlessArrayOf<USHORT> &input = StructAfter<HeadlessArrayOf<USHORT> > (backtrack); -+ if (!input.sanitize (c)) return_trace (false); -+ const ArrayOf<USHORT> &lookahead = StructAfter<ArrayOf<USHORT> > (input); -+ if (!lookahead.sanitize (c)) return_trace (false); -+ const ArrayOf<LookupRecord> &lookup = StructAfter<ArrayOf<LookupRecord> > (lookahead); -+ return_trace (lookup.sanitize (c)); - } - - protected: -@@ -1779,9 +1759,9 @@ - unsigned int num_rules = rule.len; - for (unsigned int i = 0; i < num_rules; i++) - if ((this+rule[i]).would_apply (c, lookup_context)) -- return TRACE_RETURN (true); -+ return_trace (true); - -- return TRACE_RETURN (false); -+ return_trace (false); - } - - inline bool apply (hb_apply_context_t *c, ChainContextApplyLookupContext &lookup_context) const -@@ -1790,14 +1770,15 @@ - unsigned int num_rules = rule.len; - for (unsigned int i = 0; i < num_rules; i++) - if ((this+rule[i]).apply (c, lookup_context)) -- return TRACE_RETURN (true); -+ return_trace (true); - -- return TRACE_RETURN (false); -+ return_trace (false); - } - -- inline bool sanitize (hb_sanitize_context_t *c) { -+ inline bool sanitize (hb_sanitize_context_t *c) const -+ { - TRACE_SANITIZE (this); -- return TRACE_RETURN (rule.sanitize (c, this)); -+ return_trace (rule.sanitize (c, this)); - } - - protected: -@@ -1852,7 +1833,7 @@ - {match_glyph}, - {NULL, NULL, NULL} - }; -- return TRACE_RETURN (rule_set.would_apply (c, lookup_context)); -+ return_trace (rule_set.would_apply (c, lookup_context)); - } - - inline const Coverage &get_coverage (void) const -@@ -1864,19 +1845,20 @@ - { - TRACE_APPLY (this); - unsigned int index = (this+coverage).get_coverage (c->buffer->cur().codepoint); -- if (likely (index == NOT_COVERED)) return TRACE_RETURN (false); -+ if (likely (index == NOT_COVERED)) return_trace (false); - - const ChainRuleSet &rule_set = this+ruleSet[index]; - struct ChainContextApplyLookupContext lookup_context = { - {match_glyph}, - {NULL, NULL, NULL} - }; -- return TRACE_RETURN (rule_set.apply (c, lookup_context)); -+ return_trace (rule_set.apply (c, lookup_context)); - } - -- inline bool sanitize (hb_sanitize_context_t *c) { -+ inline bool sanitize (hb_sanitize_context_t *c) const -+ { - TRACE_SANITIZE (this); -- return TRACE_RETURN (coverage.sanitize (c, this) && ruleSet.sanitize (c, this)); -+ return_trace (coverage.sanitize (c, this) && ruleSet.sanitize (c, this)); - } - - protected: -@@ -1955,7 +1937,7 @@ - &input_class_def, - &lookahead_class_def} - }; -- return TRACE_RETURN (rule_set.would_apply (c, lookup_context)); -+ return_trace (rule_set.would_apply (c, lookup_context)); - } - - inline const Coverage &get_coverage (void) const -@@ -1967,7 +1949,7 @@ - { - TRACE_APPLY (this); - unsigned int index = (this+coverage).get_coverage (c->buffer->cur().codepoint); -- if (likely (index == NOT_COVERED)) return TRACE_RETURN (false); -+ if (likely (index == NOT_COVERED)) return_trace (false); - - const ClassDef &backtrack_class_def = this+backtrackClassDef; - const ClassDef &input_class_def = this+inputClassDef; -@@ -1981,14 +1963,17 @@ - &input_class_def, - &lookahead_class_def} - }; -- return TRACE_RETURN (rule_set.apply (c, lookup_context)); -+ return_trace (rule_set.apply (c, lookup_context)); - } - -- inline bool sanitize (hb_sanitize_context_t *c) { -+ inline bool sanitize (hb_sanitize_context_t *c) const -+ { - TRACE_SANITIZE (this); -- return TRACE_RETURN (coverage.sanitize (c, this) && backtrackClassDef.sanitize (c, this) && -- inputClassDef.sanitize (c, this) && lookaheadClassDef.sanitize (c, this) && -- ruleSet.sanitize (c, this)); -+ return_trace (coverage.sanitize (c, this) && -+ backtrackClassDef.sanitize (c, this) && -+ inputClassDef.sanitize (c, this) && -+ lookaheadClassDef.sanitize (c, this) && -+ ruleSet.sanitize (c, this)); - } - - protected: -@@ -2071,11 +2056,11 @@ - {match_coverage}, - {this, this, this} - }; -- return TRACE_RETURN (chain_context_would_apply_lookup (c, -- backtrack.len, (const USHORT *) backtrack.array, -- input.len, (const USHORT *) input.array + 1, -- lookahead.len, (const USHORT *) lookahead.array, -- lookup.len, lookup.array, lookup_context)); -+ return_trace (chain_context_would_apply_lookup (c, -+ backtrack.len, (const USHORT *) backtrack.array, -+ input.len, (const USHORT *) input.array + 1, -+ lookahead.len, (const USHORT *) lookahead.array, -+ lookup.len, lookup.array, lookup_context)); - } - - inline const Coverage &get_coverage (void) const -@@ -2090,7 +2075,7 @@ - const OffsetArrayOf<Coverage> &input = StructAfter<OffsetArrayOf<Coverage> > (backtrack); - - unsigned int index = (this+input[0]).get_coverage (c->buffer->cur().codepoint); -- if (likely (index == NOT_COVERED)) return TRACE_RETURN (false); -+ if (likely (index == NOT_COVERED)) return_trace (false); - - const OffsetArrayOf<Coverage> &lookahead = StructAfter<OffsetArrayOf<Coverage> > (input); - const ArrayOf<LookupRecord> &lookup = StructAfter<ArrayOf<LookupRecord> > (lookahead); -@@ -2098,23 +2083,24 @@ - {match_coverage}, - {this, this, this} - }; -- return TRACE_RETURN (chain_context_apply_lookup (c, -- backtrack.len, (const USHORT *) backtrack.array, -- input.len, (const USHORT *) input.array + 1, -- lookahead.len, (const USHORT *) lookahead.array, -- lookup.len, lookup.array, lookup_context)); -+ return_trace (chain_context_apply_lookup (c, -+ backtrack.len, (const USHORT *) backtrack.array, -+ input.len, (const USHORT *) input.array + 1, -+ lookahead.len, (const USHORT *) lookahead.array, -+ lookup.len, lookup.array, lookup_context)); - } - -- inline bool sanitize (hb_sanitize_context_t *c) { -+ inline bool sanitize (hb_sanitize_context_t *c) const -+ { - TRACE_SANITIZE (this); -- if (!backtrack.sanitize (c, this)) return TRACE_RETURN (false); -- OffsetArrayOf<Coverage> &input = StructAfter<OffsetArrayOf<Coverage> > (backtrack); -- if (!input.sanitize (c, this)) return TRACE_RETURN (false); -- if (!input.len) return TRACE_RETURN (false); /* To be consistent with Context. */ -- OffsetArrayOf<Coverage> &lookahead = StructAfter<OffsetArrayOf<Coverage> > (input); -- if (!lookahead.sanitize (c, this)) return TRACE_RETURN (false); -- ArrayOf<LookupRecord> &lookup = StructAfter<ArrayOf<LookupRecord> > (lookahead); -- return TRACE_RETURN (lookup.sanitize (c)); -+ if (!backtrack.sanitize (c, this)) return_trace (false); -+ const OffsetArrayOf<Coverage> &input = StructAfter<OffsetArrayOf<Coverage> > (backtrack); -+ if (!input.sanitize (c, this)) return_trace (false); -+ if (!input.len) return_trace (false); /* To be consistent with Context. */ -+ const OffsetArrayOf<Coverage> &lookahead = StructAfter<OffsetArrayOf<Coverage> > (input); -+ if (!lookahead.sanitize (c, this)) return_trace (false); -+ const ArrayOf<LookupRecord> &lookup = StructAfter<ArrayOf<LookupRecord> > (lookahead); -+ return_trace (lookup.sanitize (c)); - } - - protected: -@@ -2144,22 +2130,12 @@ - inline typename context_t::return_t dispatch (context_t *c) const - { - TRACE_DISPATCH (this, u.format); -+ if (unlikely (!c->may_dispatch (this, &u.format))) return_trace (c->no_dispatch_return_value ()); - switch (u.format) { -- case 1: return TRACE_RETURN (c->dispatch (u.format1)); -- case 2: return TRACE_RETURN (c->dispatch (u.format2)); -- case 3: return TRACE_RETURN (c->dispatch (u.format3)); -- default:return TRACE_RETURN (c->default_return_value ()); -- } -- } -- -- inline bool sanitize (hb_sanitize_context_t *c) { -- TRACE_SANITIZE (this); -- if (!u.format.sanitize (c)) return TRACE_RETURN (false); -- switch (u.format) { -- case 1: return TRACE_RETURN (u.format1.sanitize (c)); -- case 2: return TRACE_RETURN (u.format2.sanitize (c)); -- case 3: return TRACE_RETURN (u.format3.sanitize (c)); -- default:return TRACE_RETURN (true); -+ case 1: return_trace (c->dispatch (u.format1)); -+ case 2: return_trace (c->dispatch (u.format2)); -+ case 3: return_trace (c->dispatch (u.format3)); -+ default:return_trace (c->default_return_value ()); - } - } - -@@ -2173,14 +2149,32 @@ - }; - - -+template <typename T> - struct ExtensionFormat1 - { - inline unsigned int get_type (void) const { return extensionLookupType; } -- inline unsigned int get_offset (void) const { return extensionOffset; } - -- inline bool sanitize (hb_sanitize_context_t *c) { -+ template <typename X> -+ inline const X& get_subtable (void) const -+ { -+ unsigned int offset = extensionOffset; -+ if (unlikely (!offset)) return Null(typename T::LookupSubTable); -+ return StructAtOffset<typename T::LookupSubTable> (this, offset); -+ } -+ -+ template <typename context_t> -+ inline typename context_t::return_t dispatch (context_t *c) const -+ { -+ TRACE_DISPATCH (this, format); -+ if (unlikely (!c->may_dispatch (this, this))) return_trace (c->no_dispatch_return_value ()); -+ return_trace (get_subtable<typename T::LookupSubTable> ().dispatch (c, get_type ())); -+ } -+ -+ /* This is called from may_dispatch() above with hb_sanitize_context_t. */ -+ inline bool sanitize (hb_sanitize_context_t *c) const -+ { - TRACE_SANITIZE (this); -- return TRACE_RETURN (c->check_struct (this)); -+ return_trace (c->check_struct (this) && extensionOffset != 0); - } - - protected: -@@ -2204,49 +2198,30 @@ - default:return 0; - } - } -- inline unsigned int get_offset (void) const -- { -- switch (u.format) { -- case 1: return u.format1.get_offset (); -- default:return 0; -- } -- } -- - template <typename X> - inline const X& get_subtable (void) const - { -- unsigned int offset = get_offset (); -- if (unlikely (!offset)) return Null(typename T::LookupSubTable); -- return StructAtOffset<typename T::LookupSubTable> (this, offset); -+ switch (u.format) { -+ case 1: return u.format1.template get_subtable<typename T::LookupSubTable> (); -+ default:return Null(typename T::LookupSubTable); -+ } - } - - template <typename context_t> - inline typename context_t::return_t dispatch (context_t *c) const - { -- return get_subtable<typename T::LookupSubTable> ().dispatch (c, get_type ()); -- } -- -- inline bool sanitize_self (hb_sanitize_context_t *c) { -- TRACE_SANITIZE (this); -- if (!u.format.sanitize (c)) return TRACE_RETURN (false); -+ TRACE_DISPATCH (this, u.format); -+ if (unlikely (!c->may_dispatch (this, &u.format))) return_trace (c->no_dispatch_return_value ()); - switch (u.format) { -- case 1: return TRACE_RETURN (u.format1.sanitize (c)); -- default:return TRACE_RETURN (true); -+ case 1: return_trace (u.format1.dispatch (c)); -+ default:return_trace (c->default_return_value ()); - } - } - -- inline bool sanitize (hb_sanitize_context_t *c) { -- TRACE_SANITIZE (this); -- if (!sanitize_self (c)) return TRACE_RETURN (false); -- unsigned int offset = get_offset (); -- if (unlikely (!offset)) return TRACE_RETURN (true); -- return TRACE_RETURN (StructAtOffset<typename T::LookupSubTable> (this, offset).sanitize (c, get_type ())); -- } -- - protected: - union { - USHORT format; /* Format identifier */ -- ExtensionFormat1 format1; -+ ExtensionFormat1<T> format1; - } u; - }; - -@@ -2291,12 +2266,14 @@ - inline const Lookup& get_lookup (unsigned int i) const - { return (this+lookupList)[i]; } - -- inline bool sanitize (hb_sanitize_context_t *c) { -+ inline bool sanitize (hb_sanitize_context_t *c) const -+ { - TRACE_SANITIZE (this); -- return TRACE_RETURN (version.sanitize (c) && likely (version.major == 1) && -- scriptList.sanitize (c, this) && -- featureList.sanitize (c, this) && -- lookupList.sanitize (c, this)); -+ return_trace (version.sanitize (c) && -+ likely (version.major == 1) && -+ scriptList.sanitize (c, this) && -+ featureList.sanitize (c, this) && -+ lookupList.sanitize (c, this)); - } - - protected: -diff -uN gfx/harfbuzz/src_old/hb-ot-layout-gsub-table.hh gfx/harfbuzz/src/hb-ot-layout-gsub-table.hh ---- gfx/harfbuzz/src_old/hb-ot-layout-gsub-table.hh 2016-05-10 22:26:55.000000000 +0200 -+++ gfx/harfbuzz/src/hb-ot-layout-gsub-table.hh 2016-06-05 23:49:25.602988064 +0200 -@@ -67,7 +67,7 @@ - inline bool would_apply (hb_would_apply_context_t *c) const - { - TRACE_WOULD_APPLY (this); -- return TRACE_RETURN (c->len == 1 && (this+coverage).get_coverage (c->glyphs[0]) != NOT_COVERED); -+ return_trace (c->len == 1 && (this+coverage).get_coverage (c->glyphs[0]) != NOT_COVERED); - } - - inline bool apply (hb_apply_context_t *c) const -@@ -75,14 +75,14 @@ - TRACE_APPLY (this); - hb_codepoint_t glyph_id = c->buffer->cur().codepoint; - unsigned int index = (this+coverage).get_coverage (glyph_id); -- if (likely (index == NOT_COVERED)) return TRACE_RETURN (false); -+ if (likely (index == NOT_COVERED)) return_trace (false); - - /* According to the Adobe Annotated OpenType Suite, result is always - * limited to 16bit. */ - glyph_id = (glyph_id + deltaGlyphID) & 0xFFFFu; - c->replace_glyph (glyph_id); - -- return TRACE_RETURN (true); -+ return_trace (true); - } - - inline bool serialize (hb_serialize_context_t *c, -@@ -91,15 +91,16 @@ - int delta) - { - TRACE_SERIALIZE (this); -- if (unlikely (!c->extend_min (*this))) return TRACE_RETURN (false); -- if (unlikely (!coverage.serialize (c, this).serialize (c, glyphs, num_glyphs))) return TRACE_RETURN (false); -+ if (unlikely (!c->extend_min (*this))) return_trace (false); -+ if (unlikely (!coverage.serialize (c, this).serialize (c, glyphs, num_glyphs))) return_trace (false); - deltaGlyphID.set (delta); /* TODO(serilaize) overflow? */ -- return TRACE_RETURN (true); -+ return_trace (true); - } - -- inline bool sanitize (hb_sanitize_context_t *c) { -+ inline bool sanitize (hb_sanitize_context_t *c) const -+ { - TRACE_SANITIZE (this); -- return TRACE_RETURN (coverage.sanitize (c, this) && deltaGlyphID.sanitize (c)); -+ return_trace (coverage.sanitize (c, this) && deltaGlyphID.sanitize (c)); - } - - protected: -@@ -143,7 +144,7 @@ - inline bool would_apply (hb_would_apply_context_t *c) const - { - TRACE_WOULD_APPLY (this); -- return TRACE_RETURN (c->len == 1 && (this+coverage).get_coverage (c->glyphs[0]) != NOT_COVERED); -+ return_trace (c->len == 1 && (this+coverage).get_coverage (c->glyphs[0]) != NOT_COVERED); - } - - inline bool apply (hb_apply_context_t *c) const -@@ -151,14 +152,14 @@ - TRACE_APPLY (this); - hb_codepoint_t glyph_id = c->buffer->cur().codepoint; - unsigned int index = (this+coverage).get_coverage (glyph_id); -- if (likely (index == NOT_COVERED)) return TRACE_RETURN (false); -+ if (likely (index == NOT_COVERED)) return_trace (false); - -- if (unlikely (index >= substitute.len)) return TRACE_RETURN (false); -+ if (unlikely (index >= substitute.len)) return_trace (false); - - glyph_id = substitute[index]; - c->replace_glyph (glyph_id); - -- return TRACE_RETURN (true); -+ return_trace (true); - } - - inline bool serialize (hb_serialize_context_t *c, -@@ -167,15 +168,16 @@ - unsigned int num_glyphs) - { - TRACE_SERIALIZE (this); -- if (unlikely (!c->extend_min (*this))) return TRACE_RETURN (false); -- if (unlikely (!substitute.serialize (c, substitutes, num_glyphs))) return TRACE_RETURN (false); -- if (unlikely (!coverage.serialize (c, this).serialize (c, glyphs, num_glyphs))) return TRACE_RETURN (false); -- return TRACE_RETURN (true); -+ if (unlikely (!c->extend_min (*this))) return_trace (false); -+ if (unlikely (!substitute.serialize (c, substitutes, num_glyphs))) return_trace (false); -+ if (unlikely (!coverage.serialize (c, this).serialize (c, glyphs, num_glyphs))) return_trace (false); -+ return_trace (true); - } - -- inline bool sanitize (hb_sanitize_context_t *c) { -+ inline bool sanitize (hb_sanitize_context_t *c) const -+ { - TRACE_SANITIZE (this); -- return TRACE_RETURN (coverage.sanitize (c, this) && substitute.sanitize (c)); -+ return_trace (coverage.sanitize (c, this) && substitute.sanitize (c)); - } - - protected: -@@ -198,7 +200,7 @@ - unsigned int num_glyphs) - { - TRACE_SERIALIZE (this); -- if (unlikely (!c->extend_min (u.format))) return TRACE_RETURN (false); -+ if (unlikely (!c->extend_min (u.format))) return_trace (false); - unsigned int format = 2; - int delta = 0; - if (num_glyphs) { -@@ -213,9 +215,9 @@ - } - u.format.set (format); - switch (u.format) { -- case 1: return TRACE_RETURN (u.format1.serialize (c, glyphs, num_glyphs, delta)); -- case 2: return TRACE_RETURN (u.format2.serialize (c, glyphs, substitutes, num_glyphs)); -- default:return TRACE_RETURN (false); -+ case 1: return_trace (u.format1.serialize (c, glyphs, num_glyphs, delta)); -+ case 2: return_trace (u.format2.serialize (c, glyphs, substitutes, num_glyphs)); -+ default:return_trace (false); - } - } - -@@ -223,20 +225,11 @@ - inline typename context_t::return_t dispatch (context_t *c) const - { - TRACE_DISPATCH (this, u.format); -+ if (unlikely (!c->may_dispatch (this, &u.format))) return_trace (c->no_dispatch_return_value ()); - switch (u.format) { -- case 1: return TRACE_RETURN (c->dispatch (u.format1)); -- case 2: return TRACE_RETURN (c->dispatch (u.format2)); -- default:return TRACE_RETURN (c->default_return_value ()); -- } -- } -- -- inline bool sanitize (hb_sanitize_context_t *c) { -- TRACE_SANITIZE (this); -- if (!u.format.sanitize (c)) return TRACE_RETURN (false); -- switch (u.format) { -- case 1: return TRACE_RETURN (u.format1.sanitize (c)); -- case 2: return TRACE_RETURN (u.format2.sanitize (c)); -- default:return TRACE_RETURN (true); -+ case 1: return_trace (c->dispatch (u.format1)); -+ case 2: return_trace (c->dispatch (u.format2)); -+ default:return_trace (c->default_return_value ()); - } - } - -@@ -280,14 +273,14 @@ - * buffer->move_to() makes assumptions about this too. Perhaps fix - * in the future after figuring out what to do with the clusters. - */ -- if (unlikely (!count)) return TRACE_RETURN (false); -+ if (unlikely (!count)) return_trace (false); - - /* Special-case to make it in-place and not consider this - * as a "multiplied" substitution. */ - if (unlikely (count == 1)) - { - c->replace_glyph (substitute.array[0]); -- return TRACE_RETURN (true); -+ return_trace (true); - } - - unsigned int klass = _hb_glyph_info_is_ligature (&c->buffer->cur()) ? -@@ -299,7 +292,7 @@ - } - c->buffer->skip_glyph (); - -- return TRACE_RETURN (true); -+ return_trace (true); - } - - inline bool serialize (hb_serialize_context_t *c, -@@ -307,14 +300,15 @@ - unsigned int num_glyphs) - { - TRACE_SERIALIZE (this); -- if (unlikely (!c->extend_min (*this))) return TRACE_RETURN (false); -- if (unlikely (!substitute.serialize (c, glyphs, num_glyphs))) return TRACE_RETURN (false); -- return TRACE_RETURN (true); -+ if (unlikely (!c->extend_min (*this))) return_trace (false); -+ if (unlikely (!substitute.serialize (c, glyphs, num_glyphs))) return_trace (false); -+ return_trace (true); - } - -- inline bool sanitize (hb_sanitize_context_t *c) { -+ inline bool sanitize (hb_sanitize_context_t *c) const -+ { - TRACE_SANITIZE (this); -- return TRACE_RETURN (substitute.sanitize (c)); -+ return_trace (substitute.sanitize (c)); - } - - protected: -@@ -353,7 +347,7 @@ - inline bool would_apply (hb_would_apply_context_t *c) const - { - TRACE_WOULD_APPLY (this); -- return TRACE_RETURN (c->len == 1 && (this+coverage).get_coverage (c->glyphs[0]) != NOT_COVERED); -+ return_trace (c->len == 1 && (this+coverage).get_coverage (c->glyphs[0]) != NOT_COVERED); - } - - inline bool apply (hb_apply_context_t *c) const -@@ -361,9 +355,9 @@ - TRACE_APPLY (this); - - unsigned int index = (this+coverage).get_coverage (c->buffer->cur().codepoint); -- if (likely (index == NOT_COVERED)) return TRACE_RETURN (false); -+ if (likely (index == NOT_COVERED)) return_trace (false); - -- return TRACE_RETURN ((this+sequence[index]).apply (c)); -+ return_trace ((this+sequence[index]).apply (c)); - } - - inline bool serialize (hb_serialize_context_t *c, -@@ -373,20 +367,21 @@ - Supplier<GlyphID> &substitute_glyphs_list) - { - TRACE_SERIALIZE (this); -- if (unlikely (!c->extend_min (*this))) return TRACE_RETURN (false); -- if (unlikely (!sequence.serialize (c, num_glyphs))) return TRACE_RETURN (false); -+ if (unlikely (!c->extend_min (*this))) return_trace (false); -+ if (unlikely (!sequence.serialize (c, num_glyphs))) return_trace (false); - for (unsigned int i = 0; i < num_glyphs; i++) - if (unlikely (!sequence[i].serialize (c, this).serialize (c, - substitute_glyphs_list, -- substitute_len_list[i]))) return TRACE_RETURN (false); -+ substitute_len_list[i]))) return_trace (false); - substitute_len_list.advance (num_glyphs); -- if (unlikely (!coverage.serialize (c, this).serialize (c, glyphs, num_glyphs))) return TRACE_RETURN (false); -- return TRACE_RETURN (true); -+ if (unlikely (!coverage.serialize (c, this).serialize (c, glyphs, num_glyphs))) return_trace (false); -+ return_trace (true); - } - -- inline bool sanitize (hb_sanitize_context_t *c) { -+ inline bool sanitize (hb_sanitize_context_t *c) const -+ { - TRACE_SANITIZE (this); -- return TRACE_RETURN (coverage.sanitize (c, this) && sequence.sanitize (c, this)); -+ return_trace (coverage.sanitize (c, this) && sequence.sanitize (c, this)); - } - - protected: -@@ -410,12 +405,12 @@ - Supplier<GlyphID> &substitute_glyphs_list) - { - TRACE_SERIALIZE (this); -- if (unlikely (!c->extend_min (u.format))) return TRACE_RETURN (false); -+ if (unlikely (!c->extend_min (u.format))) return_trace (false); - unsigned int format = 1; - u.format.set (format); - switch (u.format) { -- case 1: return TRACE_RETURN (u.format1.serialize (c, glyphs, substitute_len_list, num_glyphs, substitute_glyphs_list)); -- default:return TRACE_RETURN (false); -+ case 1: return_trace (u.format1.serialize (c, glyphs, substitute_len_list, num_glyphs, substitute_glyphs_list)); -+ default:return_trace (false); - } - } - -@@ -423,18 +418,10 @@ - inline typename context_t::return_t dispatch (context_t *c) const - { - TRACE_DISPATCH (this, u.format); -+ if (unlikely (!c->may_dispatch (this, &u.format))) return_trace (c->no_dispatch_return_value ()); - switch (u.format) { -- case 1: return TRACE_RETURN (c->dispatch (u.format1)); -- default:return TRACE_RETURN (c->default_return_value ()); -- } -- } -- -- inline bool sanitize (hb_sanitize_context_t *c) { -- TRACE_SANITIZE (this); -- if (!u.format.sanitize (c)) return TRACE_RETURN (false); -- switch (u.format) { -- case 1: return TRACE_RETURN (u.format1.sanitize (c)); -- default:return TRACE_RETURN (true); -+ case 1: return_trace (c->dispatch (u.format1)); -+ default:return_trace (c->default_return_value ()); - } - } - -@@ -486,7 +473,7 @@ - inline bool would_apply (hb_would_apply_context_t *c) const - { - TRACE_WOULD_APPLY (this); -- return TRACE_RETURN (c->len == 1 && (this+coverage).get_coverage (c->glyphs[0]) != NOT_COVERED); -+ return_trace (c->len == 1 && (this+coverage).get_coverage (c->glyphs[0]) != NOT_COVERED); - } - - inline bool apply (hb_apply_context_t *c) const -@@ -495,11 +482,11 @@ - hb_codepoint_t glyph_id = c->buffer->cur().codepoint; - - unsigned int index = (this+coverage).get_coverage (glyph_id); -- if (likely (index == NOT_COVERED)) return TRACE_RETURN (false); -+ if (likely (index == NOT_COVERED)) return_trace (false); - - const AlternateSet &alt_set = this+alternateSet[index]; - -- if (unlikely (!alt_set.len)) return TRACE_RETURN (false); -+ if (unlikely (!alt_set.len)) return_trace (false); - - hb_mask_t glyph_mask = c->buffer->cur().mask; - hb_mask_t lookup_mask = c->lookup_mask; -@@ -508,13 +495,13 @@ - unsigned int shift = _hb_ctz (lookup_mask); - unsigned int alt_index = ((lookup_mask & glyph_mask) >> shift); - -- if (unlikely (alt_index > alt_set.len || alt_index == 0)) return TRACE_RETURN (false); -+ if (unlikely (alt_index > alt_set.len || alt_index == 0)) return_trace (false); - - glyph_id = alt_set[alt_index - 1]; - - c->replace_glyph (glyph_id); - -- return TRACE_RETURN (true); -+ return_trace (true); - } - - inline bool serialize (hb_serialize_context_t *c, -@@ -524,20 +511,21 @@ - Supplier<GlyphID> &alternate_glyphs_list) - { - TRACE_SERIALIZE (this); -- if (unlikely (!c->extend_min (*this))) return TRACE_RETURN (false); -- if (unlikely (!alternateSet.serialize (c, num_glyphs))) return TRACE_RETURN (false); -+ if (unlikely (!c->extend_min (*this))) return_trace (false); -+ if (unlikely (!alternateSet.serialize (c, num_glyphs))) return_trace (false); - for (unsigned int i = 0; i < num_glyphs; i++) - if (unlikely (!alternateSet[i].serialize (c, this).serialize (c, - alternate_glyphs_list, -- alternate_len_list[i]))) return TRACE_RETURN (false); -+ alternate_len_list[i]))) return_trace (false); - alternate_len_list.advance (num_glyphs); -- if (unlikely (!coverage.serialize (c, this).serialize (c, glyphs, num_glyphs))) return TRACE_RETURN (false); -- return TRACE_RETURN (true); -+ if (unlikely (!coverage.serialize (c, this).serialize (c, glyphs, num_glyphs))) return_trace (false); -+ return_trace (true); - } - -- inline bool sanitize (hb_sanitize_context_t *c) { -+ inline bool sanitize (hb_sanitize_context_t *c) const -+ { - TRACE_SANITIZE (this); -- return TRACE_RETURN (coverage.sanitize (c, this) && alternateSet.sanitize (c, this)); -+ return_trace (coverage.sanitize (c, this) && alternateSet.sanitize (c, this)); - } - - protected: -@@ -561,12 +549,12 @@ - Supplier<GlyphID> &alternate_glyphs_list) - { - TRACE_SERIALIZE (this); -- if (unlikely (!c->extend_min (u.format))) return TRACE_RETURN (false); -+ if (unlikely (!c->extend_min (u.format))) return_trace (false); - unsigned int format = 1; - u.format.set (format); - switch (u.format) { -- case 1: return TRACE_RETURN (u.format1.serialize (c, glyphs, alternate_len_list, num_glyphs, alternate_glyphs_list)); -- default:return TRACE_RETURN (false); -+ case 1: return_trace (u.format1.serialize (c, glyphs, alternate_len_list, num_glyphs, alternate_glyphs_list)); -+ default:return_trace (false); - } - } - -@@ -574,18 +562,10 @@ - inline typename context_t::return_t dispatch (context_t *c) const - { - TRACE_DISPATCH (this, u.format); -+ if (unlikely (!c->may_dispatch (this, &u.format))) return_trace (c->no_dispatch_return_value ()); - switch (u.format) { -- case 1: return TRACE_RETURN (c->dispatch (u.format1)); -- default:return TRACE_RETURN (c->default_return_value ()); -- } -- } -- -- inline bool sanitize (hb_sanitize_context_t *c) { -- TRACE_SANITIZE (this); -- if (!u.format.sanitize (c)) return TRACE_RETURN (false); -- switch (u.format) { -- case 1: return TRACE_RETURN (u.format1.sanitize (c)); -- default:return TRACE_RETURN (true); -+ case 1: return_trace (c->dispatch (u.format1)); -+ default:return_trace (c->default_return_value ()); - } - } - -@@ -622,13 +602,13 @@ - { - TRACE_WOULD_APPLY (this); - if (c->len != component.len) -- return TRACE_RETURN (false); -+ return_trace (false); - - for (unsigned int i = 1; i < c->len; i++) - if (likely (c->glyphs[i] != component[i])) -- return TRACE_RETURN (false); -+ return_trace (false); - -- return TRACE_RETURN (true); -+ return_trace (true); - } - - inline bool apply (hb_apply_context_t *c) const -@@ -636,21 +616,21 @@ - TRACE_APPLY (this); - unsigned int count = component.len; - -- if (unlikely (!count)) return TRACE_RETURN (false); -+ if (unlikely (!count)) return_trace (false); - - /* Special-case to make it in-place and not consider this - * as a "ligated" substitution. */ - if (unlikely (count == 1)) - { - c->replace_glyph (ligGlyph); -- return TRACE_RETURN (true); -+ return_trace (true); - } - - bool is_mark_ligature = false; - unsigned int total_component_count = 0; - - unsigned int match_length = 0; -- unsigned int match_positions[MAX_CONTEXT_LENGTH]; -+ unsigned int match_positions[HB_MAX_CONTEXT_LENGTH]; - - if (likely (!match_input (c, count, - &component[1], -@@ -660,7 +640,7 @@ - match_positions, - &is_mark_ligature, - &total_component_count))) -- return TRACE_RETURN (false); -+ return_trace (false); - - ligate_input (c, - count, -@@ -670,7 +650,7 @@ - is_mark_ligature, - total_component_count); - -- return TRACE_RETURN (true); -+ return_trace (true); - } - - inline bool serialize (hb_serialize_context_t *c, -@@ -679,16 +659,17 @@ - unsigned int num_components /* Including first component */) - { - TRACE_SERIALIZE (this); -- if (unlikely (!c->extend_min (*this))) return TRACE_RETURN (false); -+ if (unlikely (!c->extend_min (*this))) return_trace (false); - ligGlyph = ligature; -- if (unlikely (!component.serialize (c, components, num_components))) return TRACE_RETURN (false); -- return TRACE_RETURN (true); -+ if (unlikely (!component.serialize (c, components, num_components))) return_trace (false); -+ return_trace (true); - } - - public: -- inline bool sanitize (hb_sanitize_context_t *c) { -+ inline bool sanitize (hb_sanitize_context_t *c) const -+ { - TRACE_SANITIZE (this); -- return TRACE_RETURN (ligGlyph.sanitize (c) && component.sanitize (c)); -+ return_trace (ligGlyph.sanitize (c) && component.sanitize (c)); - } - - protected: -@@ -727,9 +708,9 @@ - { - const Ligature &lig = this+ligature[i]; - if (lig.would_apply (c)) -- return TRACE_RETURN (true); -+ return_trace (true); - } -- return TRACE_RETURN (false); -+ return_trace (false); - } - - inline bool apply (hb_apply_context_t *c) const -@@ -739,10 +720,10 @@ - for (unsigned int i = 0; i < num_ligs; i++) - { - const Ligature &lig = this+ligature[i]; -- if (lig.apply (c)) return TRACE_RETURN (true); -+ if (lig.apply (c)) return_trace (true); - } - -- return TRACE_RETURN (false); -+ return_trace (false); - } - - inline bool serialize (hb_serialize_context_t *c, -@@ -752,21 +733,22 @@ - Supplier<GlyphID> &component_list /* Starting from second for each ligature */) - { - TRACE_SERIALIZE (this); -- if (unlikely (!c->extend_min (*this))) return TRACE_RETURN (false); -- if (unlikely (!ligature.serialize (c, num_ligatures))) return TRACE_RETURN (false); -+ if (unlikely (!c->extend_min (*this))) return_trace (false); -+ if (unlikely (!ligature.serialize (c, num_ligatures))) return_trace (false); - for (unsigned int i = 0; i < num_ligatures; i++) - if (unlikely (!ligature[i].serialize (c, this).serialize (c, - ligatures[i], - component_list, -- component_count_list[i]))) return TRACE_RETURN (false); -+ component_count_list[i]))) return_trace (false); - ligatures.advance (num_ligatures); - component_count_list.advance (num_ligatures); -- return TRACE_RETURN (true); -+ return_trace (true); - } - -- inline bool sanitize (hb_sanitize_context_t *c) { -+ inline bool sanitize (hb_sanitize_context_t *c) const -+ { - TRACE_SANITIZE (this); -- return TRACE_RETURN (ligature.sanitize (c, this)); -+ return_trace (ligature.sanitize (c, this)); - } - - protected: -@@ -808,10 +790,10 @@ - { - TRACE_WOULD_APPLY (this); - unsigned int index = (this+coverage).get_coverage (c->glyphs[0]); -- if (likely (index == NOT_COVERED)) return TRACE_RETURN (false); -+ if (likely (index == NOT_COVERED)) return_trace (false); - - const LigatureSet &lig_set = this+ligatureSet[index]; -- return TRACE_RETURN (lig_set.would_apply (c)); -+ return_trace (lig_set.would_apply (c)); - } - - inline bool apply (hb_apply_context_t *c) const -@@ -820,10 +802,10 @@ - hb_codepoint_t glyph_id = c->buffer->cur().codepoint; - - unsigned int index = (this+coverage).get_coverage (glyph_id); -- if (likely (index == NOT_COVERED)) return TRACE_RETURN (false); -+ if (likely (index == NOT_COVERED)) return_trace (false); - - const LigatureSet &lig_set = this+ligatureSet[index]; -- return TRACE_RETURN (lig_set.apply (c)); -+ return_trace (lig_set.apply (c)); - } - - inline bool serialize (hb_serialize_context_t *c, -@@ -835,22 +817,23 @@ - Supplier<GlyphID> &component_list /* Starting from second for each ligature */) - { - TRACE_SERIALIZE (this); -- if (unlikely (!c->extend_min (*this))) return TRACE_RETURN (false); -- if (unlikely (!ligatureSet.serialize (c, num_first_glyphs))) return TRACE_RETURN (false); -+ if (unlikely (!c->extend_min (*this))) return_trace (false); -+ if (unlikely (!ligatureSet.serialize (c, num_first_glyphs))) return_trace (false); - for (unsigned int i = 0; i < num_first_glyphs; i++) - if (unlikely (!ligatureSet[i].serialize (c, this).serialize (c, - ligatures_list, - component_count_list, - ligature_per_first_glyph_count_list[i], -- component_list))) return TRACE_RETURN (false); -+ component_list))) return_trace (false); - ligature_per_first_glyph_count_list.advance (num_first_glyphs); -- if (unlikely (!coverage.serialize (c, this).serialize (c, first_glyphs, num_first_glyphs))) return TRACE_RETURN (false); -- return TRACE_RETURN (true); -+ if (unlikely (!coverage.serialize (c, this).serialize (c, first_glyphs, num_first_glyphs))) return_trace (false); -+ return_trace (true); - } - -- inline bool sanitize (hb_sanitize_context_t *c) { -+ inline bool sanitize (hb_sanitize_context_t *c) const -+ { - TRACE_SANITIZE (this); -- return TRACE_RETURN (coverage.sanitize (c, this) && ligatureSet.sanitize (c, this)); -+ return_trace (coverage.sanitize (c, this) && ligatureSet.sanitize (c, this)); - } - - protected: -@@ -876,13 +859,18 @@ - Supplier<GlyphID> &component_list /* Starting from second for each ligature */) - { - TRACE_SERIALIZE (this); -- if (unlikely (!c->extend_min (u.format))) return TRACE_RETURN (false); -+ if (unlikely (!c->extend_min (u.format))) return_trace (false); - unsigned int format = 1; - u.format.set (format); - switch (u.format) { -- case 1: return TRACE_RETURN (u.format1.serialize (c, first_glyphs, ligature_per_first_glyph_count_list, num_first_glyphs, -- ligatures_list, component_count_list, component_list)); -- default:return TRACE_RETURN (false); -+ case 1: return_trace (u.format1.serialize (c, -+ first_glyphs, -+ ligature_per_first_glyph_count_list, -+ num_first_glyphs, -+ ligatures_list, -+ component_count_list, -+ component_list)); -+ default:return_trace (false); - } - } - -@@ -890,18 +878,10 @@ - inline typename context_t::return_t dispatch (context_t *c) const - { - TRACE_DISPATCH (this, u.format); -+ if (unlikely (!c->may_dispatch (this, &u.format))) return_trace (c->no_dispatch_return_value ()); - switch (u.format) { -- case 1: return TRACE_RETURN (c->dispatch (u.format1)); -- default:return TRACE_RETURN (c->default_return_value ()); -- } -- } -- -- inline bool sanitize (hb_sanitize_context_t *c) { -- TRACE_SANITIZE (this); -- if (!u.format.sanitize (c)) return TRACE_RETURN (false); -- switch (u.format) { -- case 1: return TRACE_RETURN (u.format1.sanitize (c)); -- default:return TRACE_RETURN (true); -+ case 1: return_trace (c->dispatch (u.format1)); -+ default:return_trace (c->default_return_value ()); - } - } - -@@ -984,17 +964,17 @@ - inline bool would_apply (hb_would_apply_context_t *c) const - { - TRACE_WOULD_APPLY (this); -- return TRACE_RETURN (c->len == 1 && (this+coverage).get_coverage (c->glyphs[0]) != NOT_COVERED); -+ return_trace (c->len == 1 && (this+coverage).get_coverage (c->glyphs[0]) != NOT_COVERED); - } - - inline bool apply (hb_apply_context_t *c) const - { - TRACE_APPLY (this); -- if (unlikely (c->nesting_level_left != MAX_NESTING_LEVEL)) -- return TRACE_RETURN (false); /* No chaining to this type */ -+ if (unlikely (c->nesting_level_left != HB_MAX_NESTING_LEVEL)) -+ return_trace (false); /* No chaining to this type */ - - unsigned int index = (this+coverage).get_coverage (c->buffer->cur().codepoint); -- if (likely (index == NOT_COVERED)) return TRACE_RETURN (false); -+ if (likely (index == NOT_COVERED)) return_trace (false); - - const OffsetArrayOf<Coverage> &lookahead = StructAfter<OffsetArrayOf<Coverage> > (backtrack); - const ArrayOf<GlyphID> &substitute = StructAfter<ArrayOf<GlyphID> > (lookahead); -@@ -1011,21 +991,22 @@ - /* Note: We DON'T decrease buffer->idx. The main loop does it - * for us. This is useful for preventing surprises if someone - * calls us through a Context lookup. */ -- return TRACE_RETURN (true); -+ return_trace (true); - } - -- return TRACE_RETURN (false); -+ return_trace (false); - } - -- inline bool sanitize (hb_sanitize_context_t *c) { -+ inline bool sanitize (hb_sanitize_context_t *c) const -+ { - TRACE_SANITIZE (this); - if (!(coverage.sanitize (c, this) && backtrack.sanitize (c, this))) -- return TRACE_RETURN (false); -- OffsetArrayOf<Coverage> &lookahead = StructAfter<OffsetArrayOf<Coverage> > (backtrack); -+ return_trace (false); -+ const OffsetArrayOf<Coverage> &lookahead = StructAfter<OffsetArrayOf<Coverage> > (backtrack); - if (!lookahead.sanitize (c, this)) -- return TRACE_RETURN (false); -- ArrayOf<GlyphID> &substitute = StructAfter<ArrayOf<GlyphID> > (lookahead); -- return TRACE_RETURN (substitute.sanitize (c)); -+ return_trace (false); -+ const ArrayOf<GlyphID> &substitute = StructAfter<ArrayOf<GlyphID> > (lookahead); -+ return_trace (substitute.sanitize (c)); - } - - protected: -@@ -1054,18 +1035,10 @@ - inline typename context_t::return_t dispatch (context_t *c) const - { - TRACE_DISPATCH (this, u.format); -+ if (unlikely (!c->may_dispatch (this, &u.format))) return_trace (c->no_dispatch_return_value ()); - switch (u.format) { -- case 1: return TRACE_RETURN (c->dispatch (u.format1)); -- default:return TRACE_RETURN (c->default_return_value ()); -- } -- } -- -- inline bool sanitize (hb_sanitize_context_t *c) { -- TRACE_SANITIZE (this); -- if (!u.format.sanitize (c)) return TRACE_RETURN (false); -- switch (u.format) { -- case 1: return TRACE_RETURN (u.format1.sanitize (c)); -- default:return TRACE_RETURN (true); -+ case 1: return_trace (c->dispatch (u.format1)); -+ default:return_trace (c->default_return_value ()); - } - } - -@@ -1101,41 +1074,23 @@ - inline typename context_t::return_t dispatch (context_t *c, unsigned int lookup_type) const - { - TRACE_DISPATCH (this, lookup_type); -+ if (unlikely (!c->may_dispatch (this, &u.sub_format))) return_trace (c->no_dispatch_return_value ()); - switch (lookup_type) { -- case Single: return TRACE_RETURN (u.single.dispatch (c)); -- case Multiple: return TRACE_RETURN (u.multiple.dispatch (c)); -- case Alternate: return TRACE_RETURN (u.alternate.dispatch (c)); -- case Ligature: return TRACE_RETURN (u.ligature.dispatch (c)); -- case Context: return TRACE_RETURN (u.context.dispatch (c)); -- case ChainContext: return TRACE_RETURN (u.chainContext.dispatch (c)); -- case Extension: return TRACE_RETURN (u.extension.dispatch (c)); -- case ReverseChainSingle: return TRACE_RETURN (u.reverseChainContextSingle.dispatch (c)); -- default: return TRACE_RETURN (c->default_return_value ()); -- } -- } -- -- inline bool sanitize (hb_sanitize_context_t *c, unsigned int lookup_type) { -- TRACE_SANITIZE (this); -- if (!u.header.sub_format.sanitize (c)) -- return TRACE_RETURN (false); -- switch (lookup_type) { -- case Single: return TRACE_RETURN (u.single.sanitize (c)); -- case Multiple: return TRACE_RETURN (u.multiple.sanitize (c)); -- case Alternate: return TRACE_RETURN (u.alternate.sanitize (c)); -- case Ligature: return TRACE_RETURN (u.ligature.sanitize (c)); -- case Context: return TRACE_RETURN (u.context.sanitize (c)); -- case ChainContext: return TRACE_RETURN (u.chainContext.sanitize (c)); -- case Extension: return TRACE_RETURN (u.extension.sanitize (c)); -- case ReverseChainSingle: return TRACE_RETURN (u.reverseChainContextSingle.sanitize (c)); -- default: return TRACE_RETURN (true); -+ case Single: return_trace (u.single.dispatch (c)); -+ case Multiple: return_trace (u.multiple.dispatch (c)); -+ case Alternate: return_trace (u.alternate.dispatch (c)); -+ case Ligature: return_trace (u.ligature.dispatch (c)); -+ case Context: return_trace (u.context.dispatch (c)); -+ case ChainContext: return_trace (u.chainContext.dispatch (c)); -+ case Extension: return_trace (u.extension.dispatch (c)); -+ case ReverseChainSingle: return_trace (u.reverseChainContextSingle.dispatch (c)); -+ default: return_trace (c->default_return_value ()); - } - } - - protected: - union { -- struct { -- USHORT sub_format; -- } header; -+ USHORT sub_format; - SingleSubst single; - MultipleSubst multiple; - AlternateSubst alternate; -@@ -1146,14 +1101,14 @@ - ReverseChainSingleSubst reverseChainContextSingle; - } u; - public: -- DEFINE_SIZE_UNION (2, header.sub_format); -+ DEFINE_SIZE_UNION (2, sub_format); - }; - - - struct SubstLookup : Lookup - { - inline const SubstLookupSubTable& get_subtable (unsigned int i) const -- { return this+CastR<OffsetArrayOf<SubstLookupSubTable> > (subTable)[i]; } -+ { return Lookup::get_subtable<SubstLookupSubTable> (i); } - - inline static bool lookup_type_is_reverse (unsigned int lookup_type) - { return lookup_type == SubstLookupSubTable::ReverseChainSingle; } -@@ -1166,56 +1121,47 @@ - return lookup_type_is_reverse (type); - } - -+ inline bool apply (hb_apply_context_t *c) const -+ { -+ TRACE_APPLY (this); -+ return_trace (dispatch (c)); -+ } -+ - inline hb_closure_context_t::return_t closure (hb_closure_context_t *c) const - { - TRACE_CLOSURE (this); - c->set_recurse_func (dispatch_recurse_func<hb_closure_context_t>); -- return TRACE_RETURN (dispatch (c)); -+ return_trace (dispatch (c)); - } - - inline hb_collect_glyphs_context_t::return_t collect_glyphs (hb_collect_glyphs_context_t *c) const - { - TRACE_COLLECT_GLYPHS (this); - c->set_recurse_func (dispatch_recurse_func<hb_collect_glyphs_context_t>); -- return TRACE_RETURN (dispatch (c)); -+ return_trace (dispatch (c)); - } - - template <typename set_t> - inline void add_coverage (set_t *glyphs) const - { -- hb_get_coverage_context_t c; -- const Coverage *last = NULL; -- unsigned int count = get_subtable_count (); -- for (unsigned int i = 0; i < count; i++) { -- const Coverage *coverage = &get_subtable (i).dispatch (&c, get_type ()); -- if (coverage != last) { -- coverage->add_coverage (glyphs); -- last = coverage; -- } -- } -+ hb_add_coverage_context_t<set_t> c (glyphs); -+ dispatch (&c); - } - -- inline bool would_apply (hb_would_apply_context_t *c, const hb_set_digest_t *digest) const -+ inline bool would_apply (hb_would_apply_context_t *c, -+ const hb_ot_layout_lookup_accelerator_t *accel) const - { - TRACE_WOULD_APPLY (this); -- if (unlikely (!c->len)) return TRACE_RETURN (false); -- if (!digest->may_have (c->glyphs[0])) return TRACE_RETURN (false); -- return TRACE_RETURN (dispatch (c)); -- } -- -- inline bool apply_once (hb_apply_context_t *c) const -- { -- TRACE_APPLY (this); -- if (!c->check_glyph_property (&c->buffer->cur(), c->lookup_props)) -- return TRACE_RETURN (false); -- return TRACE_RETURN (dispatch (c)); -+ if (unlikely (!c->len)) return_trace (false); -+ if (!accel->may_have (c->glyphs[0])) return_trace (false); -+ return_trace (dispatch (c)); - } - - static bool apply_recurse_func (hb_apply_context_t *c, unsigned int lookup_index); - - inline SubstLookupSubTable& serialize_subtable (hb_serialize_context_t *c, - unsigned int i) -- { return CastR<OffsetArrayOf<SubstLookupSubTable> > (subTable)[i].serialize (c, this); } -+ { return get_subtables<SubstLookupSubTable> ()[i].serialize (c, this); } - - inline bool serialize_single (hb_serialize_context_t *c, - uint32_t lookup_props, -@@ -1224,8 +1170,8 @@ - unsigned int num_glyphs) - { - TRACE_SERIALIZE (this); -- if (unlikely (!Lookup::serialize (c, SubstLookupSubTable::Single, lookup_props, 1))) return TRACE_RETURN (false); -- return TRACE_RETURN (serialize_subtable (c, 0).u.single.serialize (c, glyphs, substitutes, num_glyphs)); -+ if (unlikely (!Lookup::serialize (c, SubstLookupSubTable::Single, lookup_props, 1))) return_trace (false); -+ return_trace (serialize_subtable (c, 0).u.single.serialize (c, glyphs, substitutes, num_glyphs)); - } - - inline bool serialize_multiple (hb_serialize_context_t *c, -@@ -1236,9 +1182,12 @@ - Supplier<GlyphID> &substitute_glyphs_list) - { - TRACE_SERIALIZE (this); -- if (unlikely (!Lookup::serialize (c, SubstLookupSubTable::Multiple, lookup_props, 1))) return TRACE_RETURN (false); -- return TRACE_RETURN (serialize_subtable (c, 0).u.multiple.serialize (c, glyphs, substitute_len_list, num_glyphs, -- substitute_glyphs_list)); -+ if (unlikely (!Lookup::serialize (c, SubstLookupSubTable::Multiple, lookup_props, 1))) return_trace (false); -+ return_trace (serialize_subtable (c, 0).u.multiple.serialize (c, -+ glyphs, -+ substitute_len_list, -+ num_glyphs, -+ substitute_glyphs_list)); - } - - inline bool serialize_alternate (hb_serialize_context_t *c, -@@ -1249,9 +1198,12 @@ - Supplier<GlyphID> &alternate_glyphs_list) - { - TRACE_SERIALIZE (this); -- if (unlikely (!Lookup::serialize (c, SubstLookupSubTable::Alternate, lookup_props, 1))) return TRACE_RETURN (false); -- return TRACE_RETURN (serialize_subtable (c, 0).u.alternate.serialize (c, glyphs, alternate_len_list, num_glyphs, -- alternate_glyphs_list)); -+ if (unlikely (!Lookup::serialize (c, SubstLookupSubTable::Alternate, lookup_props, 1))) return_trace (false); -+ return_trace (serialize_subtable (c, 0).u.alternate.serialize (c, -+ glyphs, -+ alternate_len_list, -+ num_glyphs, -+ alternate_glyphs_list)); - } - - inline bool serialize_ligature (hb_serialize_context_t *c, -@@ -1264,9 +1216,14 @@ - Supplier<GlyphID> &component_list /* Starting from second for each ligature */) - { - TRACE_SERIALIZE (this); -- if (unlikely (!Lookup::serialize (c, SubstLookupSubTable::Ligature, lookup_props, 1))) return TRACE_RETURN (false); -- return TRACE_RETURN (serialize_subtable (c, 0).u.ligature.serialize (c, first_glyphs, ligature_per_first_glyph_count_list, num_first_glyphs, -- ligatures_list, component_count_list, component_list)); -+ if (unlikely (!Lookup::serialize (c, SubstLookupSubTable::Ligature, lookup_props, 1))) return_trace (false); -+ return_trace (serialize_subtable (c, 0).u.ligature.serialize (c, -+ first_glyphs, -+ ligature_per_first_glyph_count_list, -+ num_first_glyphs, -+ ligatures_list, -+ component_count_list, -+ component_list)); - } - - template <typename context_t> -@@ -1274,24 +1231,13 @@ - - template <typename context_t> - inline typename context_t::return_t dispatch (context_t *c) const -- { -- unsigned int lookup_type = get_type (); -- TRACE_DISPATCH (this, lookup_type); -- unsigned int count = get_subtable_count (); -- for (unsigned int i = 0; i < count; i++) { -- typename context_t::return_t r = get_subtable (i).dispatch (c, lookup_type); -- if (c->stop_sublookup_iteration (r)) -- return TRACE_RETURN (r); -- } -- return TRACE_RETURN (c->default_return_value ()); -- } -+ { return Lookup::dispatch<SubstLookupSubTable> (c); } - -- inline bool sanitize (hb_sanitize_context_t *c) -+ inline bool sanitize (hb_sanitize_context_t *c) const - { - TRACE_SANITIZE (this); -- if (unlikely (!Lookup::sanitize (c))) return TRACE_RETURN (false); -- OffsetArrayOf<SubstLookupSubTable> &list = CastR<OffsetArrayOf<SubstLookupSubTable> > (subTable); -- if (unlikely (!list.sanitize (c, this, get_type ()))) return TRACE_RETURN (false); -+ if (unlikely (!Lookup::sanitize (c))) return_trace (false); -+ if (unlikely (!dispatch (c))) return_trace (false); - - if (unlikely (get_type () == SubstLookupSubTable::Extension)) - { -@@ -1302,9 +1248,9 @@ - unsigned int count = get_subtable_count (); - for (unsigned int i = 1; i < count; i++) - if (get_subtable (i).u.extension.get_type () != type) -- return TRACE_RETURN (false); -+ return_trace (false); - } -- return TRACE_RETURN (true); -+ return_trace (true); - } - }; - -@@ -1324,11 +1270,12 @@ - static inline void substitute_start (hb_font_t *font, hb_buffer_t *buffer); - static inline void substitute_finish (hb_font_t *font, hb_buffer_t *buffer); - -- inline bool sanitize (hb_sanitize_context_t *c) { -+ inline bool sanitize (hb_sanitize_context_t *c) const -+ { - TRACE_SANITIZE (this); -- if (unlikely (!GSUBGPOS::sanitize (c))) return TRACE_RETURN (false); -- OffsetTo<SubstLookupList> &list = CastR<OffsetTo<SubstLookupList> > (lookupList); -- return TRACE_RETURN (list.sanitize (c, this)); -+ if (unlikely (!GSUBGPOS::sanitize (c))) return_trace (false); -+ const OffsetTo<SubstLookupList> &list = CastR<OffsetTo<SubstLookupList> > (lookupList); -+ return_trace (list.sanitize (c, this)); - } - public: - DEFINE_SIZE_STATIC (10); -@@ -1362,7 +1309,7 @@ - { - unsigned int type = get_type (); - if (unlikely (type == SubstLookupSubTable::Extension)) -- return CastR<ExtensionSubst> (get_subtable<SubstLookupSubTable>()).is_reverse (); -+ return CastR<ExtensionSubst> (get_subtable<LookupSubTable>()).is_reverse (); - return SubstLookup::lookup_type_is_reverse (type); - } - -@@ -1379,9 +1326,12 @@ - const GSUB &gsub = *(hb_ot_layout_from_face (c->face)->gsub); - const SubstLookup &l = gsub.get_lookup (lookup_index); - unsigned int saved_lookup_props = c->lookup_props; -- c->set_lookup (l); -- bool ret = l.apply_once (c); -- c->lookup_props = saved_lookup_props; -+ unsigned int saved_lookup_index = c->lookup_index; -+ c->set_lookup_index (lookup_index); -+ c->set_lookup_props (l.get_props ()); -+ bool ret = l.dispatch (c); -+ c->set_lookup_index (saved_lookup_index); -+ c->set_lookup_props (saved_lookup_props); - return ret; - } - -diff -uN gfx/harfbuzz/src_old/hb-ot-layout.h gfx/harfbuzz/src/hb-ot-layout.h ---- gfx/harfbuzz/src_old/hb-ot-layout.h 2016-05-10 22:26:56.000000000 +0200 -+++ gfx/harfbuzz/src/hb-ot-layout.h 2016-06-05 23:49:32.503951121 +0200 -@@ -48,7 +48,7 @@ - * GDEF - */ - --hb_bool_t -+HB_EXTERN hb_bool_t - hb_ot_layout_has_glyph_classes (hb_face_t *face); - - typedef enum { -@@ -59,11 +59,11 @@ - HB_OT_LAYOUT_GLYPH_CLASS_COMPONENT = 4 - } hb_ot_layout_glyph_class_t; - --hb_ot_layout_glyph_class_t -+HB_EXTERN hb_ot_layout_glyph_class_t - hb_ot_layout_get_glyph_class (hb_face_t *face, - hb_codepoint_t glyph); - --void -+HB_EXTERN void - hb_ot_layout_get_glyphs_in_class (hb_face_t *face, - hb_ot_layout_glyph_class_t klass, - hb_set_t *glyphs /* OUT */); -@@ -71,7 +71,7 @@ - - /* Not that useful. Provides list of attach points for a glyph that a - * client may want to cache */ --unsigned int -+HB_EXTERN unsigned int - hb_ot_layout_get_attach_points (hb_face_t *face, - hb_codepoint_t glyph, - unsigned int start_offset, -@@ -79,7 +79,7 @@ - unsigned int *point_array /* OUT */); - - /* Ligature caret positions */ --unsigned int -+HB_EXTERN unsigned int - hb_ot_layout_get_ligature_carets (hb_font_t *font, - hb_direction_t direction, - hb_codepoint_t glyph, -@@ -96,35 +96,35 @@ - #define HB_OT_LAYOUT_NO_FEATURE_INDEX 0xFFFFu - #define HB_OT_LAYOUT_DEFAULT_LANGUAGE_INDEX 0xFFFFu - --unsigned int -+HB_EXTERN unsigned int - hb_ot_layout_table_get_script_tags (hb_face_t *face, - hb_tag_t table_tag, - unsigned int start_offset, - unsigned int *script_count /* IN/OUT */, - hb_tag_t *script_tags /* OUT */); - --hb_bool_t -+HB_EXTERN hb_bool_t - hb_ot_layout_table_find_script (hb_face_t *face, - hb_tag_t table_tag, - hb_tag_t script_tag, - unsigned int *script_index); - - /* Like find_script, but takes zero-terminated array of scripts to test */ --hb_bool_t -+HB_EXTERN hb_bool_t - hb_ot_layout_table_choose_script (hb_face_t *face, - hb_tag_t table_tag, - const hb_tag_t *script_tags, - unsigned int *script_index, - hb_tag_t *chosen_script); - --unsigned int -+HB_EXTERN unsigned int - hb_ot_layout_table_get_feature_tags (hb_face_t *face, - hb_tag_t table_tag, - unsigned int start_offset, - unsigned int *feature_count /* IN/OUT */, - hb_tag_t *feature_tags /* OUT */); - --unsigned int -+HB_EXTERN unsigned int - hb_ot_layout_script_get_language_tags (hb_face_t *face, - hb_tag_t table_tag, - unsigned int script_index, -@@ -132,21 +132,21 @@ - unsigned int *language_count /* IN/OUT */, - hb_tag_t *language_tags /* OUT */); - --hb_bool_t -+HB_EXTERN hb_bool_t - hb_ot_layout_script_find_language (hb_face_t *face, - hb_tag_t table_tag, - unsigned int script_index, - hb_tag_t language_tag, - unsigned int *language_index); - --hb_bool_t -+HB_EXTERN hb_bool_t - hb_ot_layout_language_get_required_feature_index (hb_face_t *face, - hb_tag_t table_tag, - unsigned int script_index, - unsigned int language_index, - unsigned int *feature_index); - --hb_bool_t -+HB_EXTERN hb_bool_t - hb_ot_layout_language_get_required_feature (hb_face_t *face, - hb_tag_t table_tag, - unsigned int script_index, -@@ -154,7 +154,7 @@ - unsigned int *feature_index, - hb_tag_t *feature_tag); - --unsigned int -+HB_EXTERN unsigned int - hb_ot_layout_language_get_feature_indexes (hb_face_t *face, - hb_tag_t table_tag, - unsigned int script_index, -@@ -163,7 +163,7 @@ - unsigned int *feature_count /* IN/OUT */, - unsigned int *feature_indexes /* OUT */); - --unsigned int -+HB_EXTERN unsigned int - hb_ot_layout_language_get_feature_tags (hb_face_t *face, - hb_tag_t table_tag, - unsigned int script_index, -@@ -172,7 +172,7 @@ - unsigned int *feature_count /* IN/OUT */, - hb_tag_t *feature_tags /* OUT */); - --hb_bool_t -+HB_EXTERN hb_bool_t - hb_ot_layout_language_find_feature (hb_face_t *face, - hb_tag_t table_tag, - unsigned int script_index, -@@ -180,7 +180,7 @@ - hb_tag_t feature_tag, - unsigned int *feature_index); - --unsigned int -+HB_EXTERN unsigned int - hb_ot_layout_feature_get_lookups (hb_face_t *face, - hb_tag_t table_tag, - unsigned int feature_index, -@@ -188,12 +188,12 @@ - unsigned int *lookup_count /* IN/OUT */, - unsigned int *lookup_indexes /* OUT */); - --unsigned int -+HB_EXTERN unsigned int - hb_ot_layout_table_get_lookup_count (hb_face_t *face, - hb_tag_t table_tag); - - --void -+HB_EXTERN void - hb_ot_layout_collect_lookups (hb_face_t *face, - hb_tag_t table_tag, - const hb_tag_t *scripts, -@@ -201,7 +201,7 @@ - const hb_tag_t *features, - hb_set_t *lookup_indexes /* OUT */); - --void -+HB_EXTERN void - hb_ot_layout_lookup_collect_glyphs (hb_face_t *face, - hb_tag_t table_tag, - unsigned int lookup_index, -@@ -228,7 +228,7 @@ - const hb_ot_layout_glyph_sequence_t *sequence, - void *user_data); - --void -+HB_EXTERN void - Xhb_ot_layout_lookup_enumerate_sequences (hb_face_t *face, - hb_tag_t table_tag, - unsigned int lookup_index, -@@ -241,17 +241,17 @@ - * GSUB - */ - --hb_bool_t -+HB_EXTERN hb_bool_t - hb_ot_layout_has_substitution (hb_face_t *face); - --hb_bool_t -+HB_EXTERN hb_bool_t - hb_ot_layout_lookup_would_substitute (hb_face_t *face, - unsigned int lookup_index, - const hb_codepoint_t *glyphs, - unsigned int glyphs_length, - hb_bool_t zero_context); - --void -+HB_EXTERN void - hb_ot_layout_lookup_substitute_closure (hb_face_t *face, - unsigned int lookup_index, - hb_set_t *glyphs -@@ -259,7 +259,7 @@ - - #ifdef HB_NOT_IMPLEMENTED - /* Note: You better have GDEF when using this API, or marks won't do much. */ --hb_bool_t -+HB_EXTERN hb_bool_t - Xhb_ot_layout_lookup_substitute (hb_font_t *font, - unsigned int lookup_index, - const hb_ot_layout_glyph_sequence_t *sequence, -@@ -274,12 +274,12 @@ - * GPOS - */ - --hb_bool_t -+HB_EXTERN hb_bool_t - hb_ot_layout_has_positioning (hb_face_t *face); - - #ifdef HB_NOT_IMPLEMENTED - /* Note: You better have GDEF when using this API, or marks won't do much. */ --hb_bool_t -+HB_EXTERN hb_bool_t - Xhb_ot_layout_lookup_position (hb_font_t *font, - unsigned int lookup_index, - const hb_ot_layout_glyph_sequence_t *sequence, -@@ -288,7 +288,7 @@ - - /* Optical 'size' feature info. Returns true if found. - * http://www.microsoft.com/typography/otspec/features_pt.htm#size */ --hb_bool_t -+HB_EXTERN hb_bool_t - hb_ot_layout_get_size_params (hb_face_t *face, - unsigned int *design_size, /* OUT. May be NULL */ - unsigned int *subfamily_id, /* OUT. May be NULL */ -diff -uN gfx/harfbuzz/src_old/hb-ot-layout-jstf-table.hh gfx/harfbuzz/src/hb-ot-layout-jstf-table.hh ---- gfx/harfbuzz/src_old/hb-ot-layout-jstf-table.hh 2016-05-10 22:26:56.000000000 +0200 -+++ gfx/harfbuzz/src/hb-ot-layout-jstf-table.hh 2016-06-05 23:49:28.544972286 +0200 -@@ -54,19 +54,20 @@ - - struct JstfPriority - { -- inline bool sanitize (hb_sanitize_context_t *c) { -+ inline bool sanitize (hb_sanitize_context_t *c) const -+ { - TRACE_SANITIZE (this); -- return TRACE_RETURN (c->check_struct (this) && -- shrinkageEnableGSUB.sanitize (c, this) && -- shrinkageDisableGSUB.sanitize (c, this) && -- shrinkageEnableGPOS.sanitize (c, this) && -- shrinkageDisableGPOS.sanitize (c, this) && -- shrinkageJstfMax.sanitize (c, this) && -- extensionEnableGSUB.sanitize (c, this) && -- extensionDisableGSUB.sanitize (c, this) && -- extensionEnableGPOS.sanitize (c, this) && -- extensionDisableGPOS.sanitize (c, this) && -- extensionJstfMax.sanitize (c, this)); -+ return_trace (c->check_struct (this) && -+ shrinkageEnableGSUB.sanitize (c, this) && -+ shrinkageDisableGSUB.sanitize (c, this) && -+ shrinkageEnableGPOS.sanitize (c, this) && -+ shrinkageDisableGPOS.sanitize (c, this) && -+ shrinkageJstfMax.sanitize (c, this) && -+ extensionEnableGSUB.sanitize (c, this) && -+ extensionDisableGSUB.sanitize (c, this) && -+ extensionEnableGPOS.sanitize (c, this) && -+ extensionDisableGPOS.sanitize (c, this) && -+ extensionJstfMax.sanitize (c, this)); - } - - protected: -@@ -123,9 +124,10 @@ - struct JstfLangSys : OffsetListOf<JstfPriority> - { - inline bool sanitize (hb_sanitize_context_t *c, -- const Record<JstfLangSys>::sanitize_closure_t * = NULL) { -+ const Record<JstfLangSys>::sanitize_closure_t * = NULL) const -+ { - TRACE_SANITIZE (this); -- return TRACE_RETURN (OffsetListOf<JstfPriority>::sanitize (c)); -+ return_trace (OffsetListOf<JstfPriority>::sanitize (c)); - } - }; - -@@ -163,11 +165,12 @@ - inline const JstfLangSys& get_default_lang_sys (void) const { return this+defaultLangSys; } - - inline bool sanitize (hb_sanitize_context_t *c, -- const Record<JstfScript>::sanitize_closure_t * = NULL) { -+ const Record<JstfScript>::sanitize_closure_t * = NULL) const -+ { - TRACE_SANITIZE (this); -- return TRACE_RETURN (extenderGlyphs.sanitize (c, this) && -- defaultLangSys.sanitize (c, this) && -- langSys.sanitize (c, this)); -+ return_trace (extenderGlyphs.sanitize (c, this) && -+ defaultLangSys.sanitize (c, this) && -+ langSys.sanitize (c, this)); - } - - protected: -@@ -206,10 +209,12 @@ - inline bool find_script_index (hb_tag_t tag, unsigned int *index) const - { return scriptList.find_index (tag, index); } - -- inline bool sanitize (hb_sanitize_context_t *c) { -+ inline bool sanitize (hb_sanitize_context_t *c) const -+ { - TRACE_SANITIZE (this); -- return TRACE_RETURN (version.sanitize (c) && likely (version.major == 1) && -- scriptList.sanitize (c, this)); -+ return_trace (version.sanitize (c) && -+ likely (version.major == 1) && -+ scriptList.sanitize (c, this)); - } - - protected: -diff -uN gfx/harfbuzz/src_old/hb-ot-layout-private.hh gfx/harfbuzz/src/hb-ot-layout-private.hh ---- gfx/harfbuzz/src_old/hb-ot-layout-private.hh 2016-05-10 22:26:55.000000000 +0200 -+++ gfx/harfbuzz/src/hb-ot-layout-private.hh 2016-06-05 23:49:29.952964753 +0200 -@@ -36,11 +36,20 @@ - #include "hb-set-private.hh" - - -+/* Private API corresponding to hb-ot-layout.h: */ -+ -+HB_INTERNAL hb_bool_t -+hb_ot_layout_table_find_feature (hb_face_t *face, -+ hb_tag_t table_tag, -+ hb_tag_t feature_tag, -+ unsigned int *feature_index); -+ -+ - /* - * GDEF - */ - --typedef enum -+enum hb_ot_layout_glyph_props_flags_t - { - /* The following three match LookupFlags::Ignore* numbers. */ - HB_OT_LAYOUT_GLYPH_PROPS_BASE_GLYPH = 0x02u, -@@ -55,7 +64,8 @@ - HB_OT_LAYOUT_GLYPH_PROPS_PRESERVE = HB_OT_LAYOUT_GLYPH_PROPS_SUBSTITUTED | - HB_OT_LAYOUT_GLYPH_PROPS_LIGATED | - HB_OT_LAYOUT_GLYPH_PROPS_MULTIPLIED --} hb_ot_layout_glyph_class_mask_t; -+}; -+HB_MARK_AS_FLAG_T (hb_ot_layout_glyph_props_flags_t); - - - /* -@@ -126,11 +136,15 @@ - lookup.add_coverage (&digest); - } - -- template <typename TLookup> -- inline void fini (const TLookup &lookup HB_UNUSED) -+ inline void fini (void) - { - } - -+ inline bool may_have (hb_codepoint_t g) const { -+ return digest.may_have (g); -+ } -+ -+ private: - hb_set_digest_t digest; - }; - -@@ -167,82 +181,182 @@ - */ - - /* buffer var allocations, used during the entire shaping process */ --#define unicode_props0() var2.u8[0] --#define unicode_props1() var2.u8[1] -+#define unicode_props() var2.u16[0] - - /* buffer var allocations, used during the GSUB/GPOS processing */ - #define glyph_props() var1.u16[0] /* GDEF glyph properties */ - #define lig_props() var1.u8[2] /* GSUB/GPOS ligature tracking */ - #define syllable() var1.u8[3] /* GSUB/GPOS shaping boundaries */ - -+ -+/* loop over syllables */ -+ -+#define foreach_syllable(buffer, start, end) \ -+ for (unsigned int \ -+ _count = buffer->len, \ -+ start = 0, end = _count ? _next_syllable (buffer, 0) : 0; \ -+ start < _count; \ -+ start = end, end = _next_syllable (buffer, start)) -+ -+static inline unsigned int -+_next_syllable (hb_buffer_t *buffer, unsigned int start) -+{ -+ hb_glyph_info_t *info = buffer->info; -+ unsigned int count = buffer->len; -+ -+ unsigned int syllable = info[start].syllable(); -+ while (++start < count && syllable == info[start].syllable()) -+ ; -+ -+ return start; -+} -+ -+ - /* unicode_props */ - --enum { -- MASK0_ZWJ = 0x20u, -- MASK0_ZWNJ = 0x40u, -- MASK0_IGNORABLE = 0x80u, -- MASK0_GEN_CAT = 0x1Fu -+/* Design: -+ * unicode_props() is a two-byte number. The low byte includes: -+ * - General_Category: 5 bits. -+ * - A bit each for: -+ * * Is it Default_Ignorable(); we have a modified Default_Ignorable(). -+ * * Is it U+200D ZWJ? -+ * * Is it U+200C ZWNJ? -+ * -+ * The high-byte has different meanings, switched by the Gen-Cat: -+ * - For Mn,Mc,Me: the modified Combining_Class. -+ * - For Ws: index of which space character this is, if space fallback -+ * is needed, ie. we don't set this by default, only if asked to. -+ * -+ * If needed, we can use the ZWJ/ZWNJ to use the high byte as well, -+ * freeing two more bits. -+ */ -+ -+enum hb_unicode_props_flags_t { -+ UPROPS_MASK_ZWJ = 0x20u, -+ UPROPS_MASK_ZWNJ = 0x40u, -+ UPROPS_MASK_IGNORABLE = 0x80u, -+ UPROPS_MASK_GEN_CAT = 0x1Fu - }; -+HB_MARK_AS_FLAG_T (hb_unicode_props_flags_t); - - static inline void --_hb_glyph_info_set_unicode_props (hb_glyph_info_t *info, hb_unicode_funcs_t *unicode) -+_hb_glyph_info_set_unicode_props (hb_glyph_info_t *info, hb_buffer_t *buffer) - { -- /* XXX This shouldn't be inlined, or at least not while is_default_ignorable() is inline. */ -- info->unicode_props0() = ((unsigned int) unicode->general_category (info->codepoint)) | -- (unicode->is_default_ignorable (info->codepoint) ? MASK0_IGNORABLE : 0) | -- (info->codepoint == 0x200Cu ? MASK0_ZWNJ : 0) | -- (info->codepoint == 0x200Du ? MASK0_ZWJ : 0); -- info->unicode_props1() = unicode->modified_combining_class (info->codepoint); -+ hb_unicode_funcs_t *unicode = buffer->unicode; -+ unsigned int u = info->codepoint; -+ unsigned int gen_cat = (unsigned int) unicode->general_category (u); -+ unsigned int props = gen_cat; -+ -+ if (u >= 0x80) -+ { -+ buffer->scratch_flags |= HB_BUFFER_SCRATCH_FLAG_HAS_NON_ASCII; -+ if (unlikely (unicode->is_default_ignorable (u))) -+ { -+ buffer->scratch_flags |= HB_BUFFER_SCRATCH_FLAG_HAS_DEFAULT_IGNORABLES; -+ props |= UPROPS_MASK_IGNORABLE; -+ if (u == 0x200Cu) props |= UPROPS_MASK_ZWNJ; -+ if (u == 0x200Du) props |= UPROPS_MASK_ZWJ; -+ } -+ else if (unlikely (HB_UNICODE_GENERAL_CATEGORY_IS_NON_ENCLOSING_MARK (gen_cat))) -+ { -+ /* Only Mn and Mc can have non-zero ccc: -+ * http://www.unicode.org/policies/stability_policy.html#Property_Value -+ * """ -+ * Canonical_Combining_Class, General_Category -+ * All characters other than those with General_Category property values -+ * Spacing_Mark (Mc) and Nonspacing_Mark (Mn) have the Canonical_Combining_Class -+ * property value 0. -+ * 1.1.5+ -+ * """ -+ * -+ * Also, all Mn's that are Default_Ignorable, have ccc=0, hence -+ * the "else if". -+ */ -+ props |= unicode->modified_combining_class (info->codepoint)<<8; -+ } -+ } -+ -+ info->unicode_props() = props; - } - - static inline void - _hb_glyph_info_set_general_category (hb_glyph_info_t *info, - hb_unicode_general_category_t gen_cat) - { -- info->unicode_props0() = (unsigned int) gen_cat | ((info->unicode_props0()) & ~MASK0_GEN_CAT); -+ /* Clears top-byte. */ -+ info->unicode_props() = (unsigned int) gen_cat | (info->unicode_props() & (0xFF & ~UPROPS_MASK_GEN_CAT)); - } - - static inline hb_unicode_general_category_t - _hb_glyph_info_get_general_category (const hb_glyph_info_t *info) - { -- return (hb_unicode_general_category_t) (info->unicode_props0() & MASK0_GEN_CAT); -+ return (hb_unicode_general_category_t) (info->unicode_props() & UPROPS_MASK_GEN_CAT); - } - -+static inline bool -+_hb_glyph_info_is_unicode_mark (const hb_glyph_info_t *info) -+{ -+ return HB_UNICODE_GENERAL_CATEGORY_IS_MARK (info->unicode_props() & UPROPS_MASK_GEN_CAT); -+} - static inline void - _hb_glyph_info_set_modified_combining_class (hb_glyph_info_t *info, - unsigned int modified_class) - { -- info->unicode_props1() = modified_class; -+ if (unlikely (!_hb_glyph_info_is_unicode_mark (info))) -+ return; -+ info->unicode_props() = (modified_class<<8) | (info->unicode_props() & 0xFF); - } -- - static inline unsigned int - _hb_glyph_info_get_modified_combining_class (const hb_glyph_info_t *info) - { -- return info->unicode_props1(); -+ return _hb_glyph_info_is_unicode_mark (info) ? info->unicode_props()>>8 : 0; -+} -+ -+static inline bool -+_hb_glyph_info_is_unicode_space (const hb_glyph_info_t *info) -+{ -+ return _hb_glyph_info_get_general_category (info) == -+ HB_UNICODE_GENERAL_CATEGORY_SPACE_SEPARATOR; -+} -+static inline void -+_hb_glyph_info_set_unicode_space_fallback_type (hb_glyph_info_t *info, hb_unicode_funcs_t::space_t s) -+{ -+ if (unlikely (!_hb_glyph_info_is_unicode_space (info))) -+ return; -+ info->unicode_props() = (((unsigned int) s)<<8) | (info->unicode_props() & 0xFF); -+} -+static inline hb_unicode_funcs_t::space_t -+_hb_glyph_info_get_unicode_space_fallback_type (const hb_glyph_info_t *info) -+{ -+ return _hb_glyph_info_is_unicode_space (info) ? -+ (hb_unicode_funcs_t::space_t) (info->unicode_props()>>8) : -+ hb_unicode_funcs_t::NOT_SPACE; - } - -+static inline bool _hb_glyph_info_ligated (const hb_glyph_info_t *info); -+ - static inline hb_bool_t - _hb_glyph_info_is_default_ignorable (const hb_glyph_info_t *info) - { -- return !!(info->unicode_props0() & MASK0_IGNORABLE); -+ return (info->unicode_props() & UPROPS_MASK_IGNORABLE) && !_hb_glyph_info_ligated (info); - } - - static inline hb_bool_t - _hb_glyph_info_is_zwnj (const hb_glyph_info_t *info) - { -- return !!(info->unicode_props0() & MASK0_ZWNJ); -+ return !!(info->unicode_props() & UPROPS_MASK_ZWNJ); - } - - static inline hb_bool_t - _hb_glyph_info_is_zwj (const hb_glyph_info_t *info) - { -- return !!(info->unicode_props0() & MASK0_ZWJ); -+ return !!(info->unicode_props() & UPROPS_MASK_ZWJ); - } - - static inline void - _hb_glyph_info_flip_joiners (hb_glyph_info_t *info) - { -- info->unicode_props0() ^= MASK0_ZWNJ | MASK0_ZWJ; -+ info->unicode_props() ^= UPROPS_MASK_ZWNJ | UPROPS_MASK_ZWJ; - } - - /* lig_props: aka lig_id / lig_comp -@@ -402,28 +516,31 @@ - HB_OT_LAYOUT_GLYPH_PROPS_MULTIPLIED); - } - -+static inline void -+_hb_glyph_info_clear_substituted (hb_glyph_info_t *info) -+{ -+ info->glyph_props() &= ~(HB_OT_LAYOUT_GLYPH_PROPS_SUBSTITUTED); -+} -+ - - /* Allocation / deallocation. */ - - static inline void - _hb_buffer_allocate_unicode_vars (hb_buffer_t *buffer) - { -- HB_BUFFER_ALLOCATE_VAR (buffer, unicode_props0); -- HB_BUFFER_ALLOCATE_VAR (buffer, unicode_props1); -+ HB_BUFFER_ALLOCATE_VAR (buffer, unicode_props); - } - - static inline void - _hb_buffer_deallocate_unicode_vars (hb_buffer_t *buffer) - { -- HB_BUFFER_DEALLOCATE_VAR (buffer, unicode_props0); -- HB_BUFFER_DEALLOCATE_VAR (buffer, unicode_props1); -+ HB_BUFFER_DEALLOCATE_VAR (buffer, unicode_props); - } - - static inline void - _hb_buffer_assert_unicode_vars (hb_buffer_t *buffer) - { -- HB_BUFFER_ASSERT_VAR (buffer, unicode_props0); -- HB_BUFFER_ASSERT_VAR (buffer, unicode_props1); -+ HB_BUFFER_ASSERT_VAR (buffer, unicode_props); - } - - static inline void -diff -uN gfx/harfbuzz/src_old/hb-ot-map.cc gfx/harfbuzz/src/hb-ot-map.cc ---- gfx/harfbuzz/src_old/hb-ot-map.cc 2016-05-10 22:26:55.000000000 +0200 -+++ gfx/harfbuzz/src/hb-ot-map.cc 2016-06-05 23:49:34.955938050 +0200 -@@ -89,7 +89,7 @@ - - for (unsigned int table_index = 0; table_index < 2; table_index++) { - hb_tag_t table_tag = table_tags[table_index]; -- found_script[table_index] = hb_ot_layout_table_choose_script (face, table_tag, script_tags, &script_index[table_index], &chosen_script[table_index]); -+ found_script[table_index] = (bool) hb_ot_layout_table_choose_script (face, table_tag, script_tags, &script_index[table_index], &chosen_script[table_index]); - hb_ot_layout_script_find_language (face, table_tag, script_index[table_index], language_tag, &language_index[table_index]); - } - } -@@ -216,6 +216,16 @@ - info->tag, - &feature_index[table_index]); - } -+ if (!found && (info->flags & F_GLOBAL_SEARCH)) -+ { -+ for (unsigned int table_index = 0; table_index < 2; table_index++) -+ { -+ found |= hb_ot_layout_table_find_feature (face, -+ table_tags[table_index], -+ info->tag, -+ &feature_index[table_index]); -+ } -+ } - if (!found && !(info->flags & F_HAS_FALLBACK)) - continue; - -diff -uN gfx/harfbuzz/src_old/hb-ot-map-private.hh gfx/harfbuzz/src/hb-ot-map-private.hh ---- gfx/harfbuzz/src_old/hb-ot-map-private.hh 2016-05-10 22:26:56.000000000 +0200 -+++ gfx/harfbuzz/src/hb-ot-map-private.hh 2016-06-05 23:49:33.714944647 +0200 -@@ -154,27 +154,14 @@ - - enum hb_ot_map_feature_flags_t { - F_NONE = 0x0000u, -- F_GLOBAL = 0x0001u, -- F_HAS_FALLBACK = 0x0002u, -- F_MANUAL_ZWJ = 0x0004u -+ F_GLOBAL = 0x0001u, /* Feature applies to all characters; results in no mask allocated for it. */ -+ F_HAS_FALLBACK = 0x0002u, /* Has fallback implementation, so include mask bit even if feature not found. */ -+ F_MANUAL_ZWJ = 0x0004u, /* Don't skip over ZWJ when matching. */ -+ F_GLOBAL_SEARCH = 0x0008u /* If feature not found in LangSys, look for it in global feature list and pick one. */ - }; -+HB_MARK_AS_FLAG_T (hb_ot_map_feature_flags_t); - /* Macro version for where const is desired. */ - #define F_COMBINE(l,r) (hb_ot_map_feature_flags_t ((unsigned int) (l) | (unsigned int) (r))) --static inline hb_ot_map_feature_flags_t --operator | (hb_ot_map_feature_flags_t l, hb_ot_map_feature_flags_t r) --{ return hb_ot_map_feature_flags_t ((unsigned int) l | (unsigned int) r); } --static inline hb_ot_map_feature_flags_t --operator & (hb_ot_map_feature_flags_t l, hb_ot_map_feature_flags_t r) --{ return hb_ot_map_feature_flags_t ((unsigned int) l & (unsigned int) r); } --static inline hb_ot_map_feature_flags_t --operator ~ (hb_ot_map_feature_flags_t r) --{ return hb_ot_map_feature_flags_t (~(unsigned int) r); } --static inline hb_ot_map_feature_flags_t& --operator |= (hb_ot_map_feature_flags_t &l, hb_ot_map_feature_flags_t r) --{ l = l | r; return l; } --static inline hb_ot_map_feature_flags_t& --operator &= (hb_ot_map_feature_flags_t& l, hb_ot_map_feature_flags_t r) --{ l = l & r; return l; } - - - struct hb_ot_map_builder_t -@@ -216,7 +203,8 @@ - unsigned int stage[2]; /* GSUB/GPOS */ - - static int cmp (const feature_info_t *a, const feature_info_t *b) -- { return (a->tag != b->tag) ? (a->tag < b->tag ? -1 : 1) : (a->seq < b->seq ? -1 : 1); } -+ { return (a->tag != b->tag) ? (a->tag < b->tag ? -1 : 1) : -+ (a->seq < b->seq ? -1 : a->seq > b->seq ? 1 : 0); } - }; - - struct stage_info_t { -diff -uN gfx/harfbuzz/src_old/hb-ot-maxp-table.hh gfx/harfbuzz/src/hb-ot-maxp-table.hh ---- gfx/harfbuzz/src_old/hb-ot-maxp-table.hh 2016-05-10 22:26:56.000000000 +0200 -+++ gfx/harfbuzz/src/hb-ot-maxp-table.hh 2016-06-05 23:49:36.145931692 +0200 -@@ -43,14 +43,17 @@ - { - static const hb_tag_t tableTag = HB_OT_TAG_maxp; - -- inline unsigned int get_num_glyphs (void) const { -+ inline unsigned int get_num_glyphs (void) const -+ { - return numGlyphs; - } - -- inline bool sanitize (hb_sanitize_context_t *c) { -+ inline bool sanitize (hb_sanitize_context_t *c) const -+ { - TRACE_SANITIZE (this); -- return TRACE_RETURN (c->check_struct (this) && -- likely (version.major == 1 || (version.major == 0 && version.minor == 0x5000u))); -+ return_trace (c->check_struct (this) && -+ likely (version.major == 1 || -+ (version.major == 0 && version.minor == 0x5000u))); - } - - /* We only implement version 0.5 as none of the extra fields in version 1.0 are useful. */ -diff -uN gfx/harfbuzz/src_old/hb-ot-name-table.hh gfx/harfbuzz/src/hb-ot-name-table.hh ---- gfx/harfbuzz/src_old/hb-ot-name-table.hh 2016-05-10 22:26:56.000000000 +0200 -+++ gfx/harfbuzz/src/hb-ot-name-table.hh 2016-06-05 23:49:37.289925602 +0200 -@@ -56,10 +56,11 @@ - return 0; - } - -- inline bool sanitize (hb_sanitize_context_t *c, void *base) { -+ inline bool sanitize (hb_sanitize_context_t *c, const void *base) const -+ { - TRACE_SANITIZE (this); - /* We can check from base all the way up to the end of string... */ -- return TRACE_RETURN (c->check_struct (this) && c->check_range ((char *) base, (unsigned int) length + offset)); -+ return_trace (c->check_struct (this) && c->check_range ((char *) base, (unsigned int) length + offset)); - } - - USHORT platformID; /* Platform ID. */ -@@ -101,21 +102,22 @@ - inline unsigned int get_size (void) const - { return min_size + count * nameRecord[0].min_size; } - -- inline bool sanitize_records (hb_sanitize_context_t *c) { -+ inline bool sanitize_records (hb_sanitize_context_t *c) const { - TRACE_SANITIZE (this); - char *string_pool = (char *) this + stringOffset; - unsigned int _count = count; - for (unsigned int i = 0; i < _count; i++) -- if (!nameRecord[i].sanitize (c, string_pool)) return TRACE_RETURN (false); -- return TRACE_RETURN (true); -+ if (!nameRecord[i].sanitize (c, string_pool)) return_trace (false); -+ return_trace (true); - } - -- inline bool sanitize (hb_sanitize_context_t *c) { -+ inline bool sanitize (hb_sanitize_context_t *c) const -+ { - TRACE_SANITIZE (this); -- return TRACE_RETURN (c->check_struct (this) && -- likely (format == 0 || format == 1) && -- c->check_array (nameRecord, nameRecord[0].static_size, count) && -- sanitize_records (c)); -+ return_trace (c->check_struct (this) && -+ likely (format == 0 || format == 1) && -+ c->check_array (nameRecord, nameRecord[0].static_size, count) && -+ sanitize_records (c)); - } - - /* We only implement format 0 for now. */ -diff -uN gfx/harfbuzz/src_old/hb-ot-os2-table.hh gfx/harfbuzz/src/hb-ot-os2-table.hh ---- gfx/harfbuzz/src_old/hb-ot-os2-table.hh 1970-01-01 01:00:00.000000000 +0100 -+++ gfx/harfbuzz/src/hb-ot-os2-table.hh 2016-06-05 23:49:38.776917678 +0200 -@@ -0,0 +1,105 @@ -+/* -+ * 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_OS2_TABLE_HH -+#define HB_OT_OS2_TABLE_HH -+ -+#include "hb-open-type-private.hh" -+ -+ -+namespace OT { -+ -+/* -+ * OS/2 and Windows Metrics -+ * http://www.microsoft.com/typography/otspec/os2.htm -+ */ -+ -+#define HB_OT_TAG_os2 HB_TAG('O','S','/','2') -+ -+struct os2 -+{ -+ static const hb_tag_t tableTag = HB_OT_TAG_os2; -+ -+ inline bool sanitize (hb_sanitize_context_t *c) const -+ { -+ TRACE_SANITIZE (this); -+ return_trace (c->check_struct (this)); -+ } -+ -+ public: -+ USHORT version; -+ -+ /* Version 0 */ -+ SHORT xAvgCharWidth; -+ USHORT usWeightClass; -+ USHORT usWidthClass; -+ USHORT fsType; -+ SHORT ySubscriptXSize; -+ SHORT ySubscriptYSize; -+ SHORT ySubscriptXOffset; -+ SHORT ySubscriptYOffset; -+ SHORT ySuperscriptXSize; -+ SHORT ySuperscriptYSize; -+ SHORT ySuperscriptXOffset; -+ SHORT ySuperscriptYOffset; -+ SHORT yStrikeoutSize; -+ SHORT yStrikeoutPosition; -+ SHORT sFamilyClass; -+ BYTE panose[10]; -+ ULONG ulUnicodeRange[4]; -+ Tag achVendID; -+ USHORT fsSelection; -+ USHORT usFirstCharIndex; -+ USHORT usLastCharIndex; -+ SHORT sTypoAscender; -+ SHORT sTypoDescender; -+ SHORT sTypoLineGap; -+ USHORT usWinAscent; -+ USHORT usWinDescent; -+ -+ /* Version 1 */ -+ //ULONG ulCodePageRange1; -+ //ULONG ulCodePageRange2; -+ -+ /* Version 2 */ -+ //SHORT sxHeight; -+ //SHORT sCapHeight; -+ //USHORT usDefaultChar; -+ //USHORT usBreakChar; -+ //USHORT usMaxContext; -+ -+ /* Version 5 */ -+ //USHORT usLowerOpticalPointSize; -+ //USHORT usUpperOpticalPointSize; -+ -+ public: -+ DEFINE_SIZE_STATIC (78); -+}; -+ -+} /* namespace OT */ -+ -+ -+#endif /* HB_OT_OS2_TABLE_HH */ -diff -uN gfx/harfbuzz/src_old/hb-ot-shape.cc gfx/harfbuzz/src/hb-ot-shape.cc ---- gfx/harfbuzz/src_old/hb-ot-shape.cc 2016-05-10 22:26:56.000000000 +0200 -+++ gfx/harfbuzz/src/hb-ot-shape.cc 2016-06-05 23:50:19.596703497 +0200 -@@ -59,10 +59,6 @@ - HB_TAG('r','c','l','t'), - }; - --static hb_tag_t vertical_features[] = { -- HB_TAG('v','e','r','t'), --}; -- - - - static void -@@ -105,10 +101,13 @@ - (horizontal_features[i] == HB_TAG('k','e','r','n') ? - F_HAS_FALLBACK : F_NONE)); - else -- for (unsigned int i = 0; i < ARRAY_LENGTH (vertical_features); i++) -- map->add_feature (vertical_features[i], 1, F_GLOBAL | -- (vertical_features[i] == HB_TAG('v','k','r','n') ? -- F_HAS_FALLBACK : F_NONE)); -+ { -+ /* We really want to find a 'vert' feature if there's any in the font, no -+ * matter which script/langsys it is listed (or not) under. -+ * See various bugs referenced from: -+ * https://github.com/behdad/harfbuzz/issues/63 */ -+ map->add_feature (HB_TAG ('v','e','r','t'), 1, F_GLOBAL | F_GLOBAL_SEARCH); -+ } - - if (planner->shaper->override_features) - planner->shaper->override_features (planner); -@@ -229,7 +228,7 @@ - unsigned int count = buffer->len; - hb_glyph_info_t *info = buffer->info; - for (unsigned int i = 0; i < count; i++) -- _hb_glyph_info_set_unicode_props (&info[i], buffer->unicode); -+ _hb_glyph_info_set_unicode_props (&info[i], buffer); - } - - static void -@@ -246,7 +245,7 @@ - - hb_glyph_info_t dottedcircle = {0}; - dottedcircle.codepoint = 0x25CCu; -- _hb_glyph_info_set_unicode_props (&dottedcircle, buffer->unicode); -+ _hb_glyph_info_set_unicode_props (&dottedcircle, buffer); - - buffer->clear_output (); - -@@ -255,7 +254,7 @@ - info.cluster = buffer->cur().cluster; - info.mask = buffer->cur().mask; - buffer->output_info (info); -- while (buffer->idx < buffer->len) -+ while (buffer->idx < buffer->len && !buffer->in_error) - buffer->next_glyph (); - - buffer->swap_buffers (); -@@ -264,11 +263,23 @@ - static void - hb_form_clusters (hb_buffer_t *buffer) - { -+ if (!(buffer->scratch_flags & HB_BUFFER_SCRATCH_FLAG_HAS_NON_ASCII) || -+ buffer->cluster_level != HB_BUFFER_CLUSTER_LEVEL_MONOTONE_GRAPHEMES) -+ return; -+ -+ /* Loop duplicated in hb_ensure_native_direction(). */ -+ unsigned int base = 0; - unsigned int count = buffer->len; - hb_glyph_info_t *info = buffer->info; - for (unsigned int i = 1; i < count; i++) -- if (HB_UNICODE_GENERAL_CATEGORY_IS_MARK (_hb_glyph_info_get_general_category (&info[i]))) -- buffer->merge_clusters (i - 1, i + 1); -+ { -+ if (likely (!HB_UNICODE_GENERAL_CATEGORY_IS_MARK (_hb_glyph_info_get_general_category (&info[i])))) -+ { -+ buffer->merge_clusters (base, i); -+ base = i; -+ } -+ } -+ buffer->merge_clusters (base, count); - } - - static void -@@ -283,7 +294,28 @@ - if ((HB_DIRECTION_IS_HORIZONTAL (direction) && direction != hb_script_get_horizontal_direction (buffer->props.script)) || - (HB_DIRECTION_IS_VERTICAL (direction) && direction != HB_DIRECTION_TTB)) - { -- hb_buffer_reverse_clusters (buffer); -+ /* Same loop as hb_form_clusters(). -+ * Since form_clusters() merged clusters already, we don't merge. */ -+ unsigned int base = 0; -+ unsigned int count = buffer->len; -+ hb_glyph_info_t *info = buffer->info; -+ for (unsigned int i = 1; i < count; i++) -+ { -+ if (likely (!HB_UNICODE_GENERAL_CATEGORY_IS_MARK (_hb_glyph_info_get_general_category (&info[i])))) -+ { -+ if (buffer->cluster_level == HB_BUFFER_CLUSTER_LEVEL_MONOTONE_CHARACTERS) -+ buffer->merge_clusters (base, i); -+ buffer->reverse_range (base, i); -+ -+ base = i; -+ } -+ } -+ if (buffer->cluster_level == HB_BUFFER_CLUSTER_LEVEL_MONOTONE_CHARACTERS) -+ buffer->merge_clusters (base, count); -+ buffer->reverse_range (base, count); -+ -+ buffer->reverse (); -+ - buffer->props.direction = HB_DIRECTION_REVERSE (buffer->props.direction); - } - } -@@ -305,7 +337,7 @@ - hb_glyph_info_t *info = buffer->info; - for (unsigned int i = 0; i < count; i++) { - hb_codepoint_t codepoint = unicode->mirroring (info[i].codepoint); -- if (likely (codepoint == info[i].codepoint)) -+ if (likely (codepoint == info[i].codepoint || !c->font->has_glyph (codepoint))) - info[i].mask |= rtlm_mask; - else - info[i].codepoint = codepoint; -@@ -315,7 +347,8 @@ - static inline void - hb_ot_shape_setup_masks_fraction (hb_ot_shape_context_t *c) - { -- if (!c->plan->has_frac) -+ if (!(c->buffer->scratch_flags & HB_BUFFER_SCRATCH_FLAG_HAS_NON_ASCII) || -+ !c->plan->has_frac) - return; - - hb_buffer_t *buffer = c->buffer; -@@ -380,6 +413,103 @@ - } - } - -+static void -+hb_ot_zero_width_default_ignorables (hb_ot_shape_context_t *c) -+{ -+ hb_buffer_t *buffer = c->buffer; -+ -+ if (!(buffer->scratch_flags & HB_BUFFER_SCRATCH_FLAG_HAS_DEFAULT_IGNORABLES) || -+ (buffer->flags & HB_BUFFER_FLAG_PRESERVE_DEFAULT_IGNORABLES)) -+ return; -+ -+ unsigned int count = buffer->len; -+ hb_glyph_info_t *info = buffer->info; -+ hb_glyph_position_t *pos = buffer->pos; -+ unsigned int i = 0; -+ for (i = 0; i < count; i++) -+ if (unlikely (_hb_glyph_info_is_default_ignorable (&info[i]))) -+ pos[i].x_advance = pos[i].y_advance = pos[i].x_offset = pos[i].y_offset = 0; -+} -+ -+static void -+hb_ot_hide_default_ignorables (hb_ot_shape_context_t *c) -+{ -+ hb_buffer_t *buffer = c->buffer; -+ -+ if (!(buffer->scratch_flags & HB_BUFFER_SCRATCH_FLAG_HAS_DEFAULT_IGNORABLES) || -+ (buffer->flags & HB_BUFFER_FLAG_PRESERVE_DEFAULT_IGNORABLES)) -+ return; -+ -+ unsigned int count = buffer->len; -+ hb_glyph_info_t *info = buffer->info; -+ hb_glyph_position_t *pos = buffer->pos; -+ unsigned int i = 0; -+ for (i = 0; i < count; i++) -+ { -+ if (unlikely (_hb_glyph_info_is_default_ignorable (&info[i]))) -+ break; -+ } -+ -+ /* No default-ignorables found; return. */ -+ if (i == count) -+ return; -+ -+ hb_codepoint_t space; -+ if (c->font->get_glyph (' ', 0, &space)) -+ { -+ /* Replace default-ignorables with a zero-advance space glyph. */ -+ for (/*continue*/; i < count; i++) -+ { -+ if (_hb_glyph_info_is_default_ignorable (&info[i])) -+ info[i].codepoint = space; -+ } -+ } -+ else -+ { -+ /* Merge clusters and delete default-ignorables. -+ * NOTE! We can't use out-buffer as we have positioning data. */ -+ unsigned int j = i; -+ for (; i < count; i++) -+ { -+ if (_hb_glyph_info_is_default_ignorable (&info[i])) -+ { -+ /* Merge clusters. -+ * Same logic as buffer->delete_glyph(), but for in-place removal. */ -+ -+ unsigned int cluster = info[i].cluster; -+ if (i + 1 < count && cluster == info[i + 1].cluster) -+ continue; /* Cluster survives; do nothing. */ -+ -+ if (j) -+ { -+ /* Merge cluster backward. */ -+ if (cluster < info[j - 1].cluster) -+ { -+ unsigned int old_cluster = info[j - 1].cluster; -+ for (unsigned k = j; k && info[k - 1].cluster == old_cluster; k--) -+ info[k - 1].cluster = cluster; -+ } -+ continue; -+ } -+ -+ if (i + 1 < count) -+ buffer->merge_clusters (i, i + 2); /* Merge cluster forward. */ -+ -+ continue; -+ } -+ -+ if (j != i) -+ { -+ info[j] = info[i]; -+ pos[j] = pos[i]; -+ } -+ j++; -+ } -+ buffer->len = j; -+ } -+} -+ -+ - static inline void - hb_ot_map_glyphs_fast (hb_buffer_t *buffer) - { -@@ -388,6 +518,8 @@ - hb_glyph_info_t *info = buffer->info; - for (unsigned int i = 0; i < count; i++) - info[i].codepoint = info[i].glyph_index(); -+ -+ buffer->content_type = HB_BUFFER_CONTENT_TYPE_GLYPHS; - } - - static inline void -@@ -397,7 +529,7 @@ - hb_glyph_info_t *info = c->buffer->info; - for (unsigned int i = 0; i < count; i++) - { -- hb_ot_layout_glyph_class_mask_t klass; -+ hb_ot_layout_glyph_props_flags_t klass; - - /* Never mark default-ignorables as marks. - * They won't get in the way of lookups anyway, -@@ -421,9 +553,6 @@ - { - hb_buffer_t *buffer = c->buffer; - -- if (c->plan->shaper->preprocess_text) -- c->plan->shaper->preprocess_text (c->plan, buffer, c->font); -- - hb_ot_shape_initialize_masks (c); - - hb_ot_mirror_chars (c); -@@ -448,7 +577,6 @@ - { - hb_buffer_t *buffer = c->buffer; - -- _hb_buffer_allocate_gsubgpos_vars (buffer); - hb_ot_layout_substitute_start (c->font, buffer); - - if (!hb_ot_layout_has_glyph_classes (c->face)) -@@ -465,6 +593,9 @@ - hb_ot_substitute (hb_ot_shape_context_t *c) - { - hb_ot_substitute_default (c); -+ -+ _hb_buffer_allocate_gsubgpos_vars (c->buffer); -+ - hb_ot_substitute_complex (c); - } - -@@ -487,6 +618,9 @@ - static inline void - zero_mark_widths_by_unicode (hb_buffer_t *buffer, bool adjust_offsets) - { -+ if (!(buffer->scratch_flags & HB_BUFFER_SCRATCH_FLAG_HAS_NON_ASCII)) -+ return; -+ - unsigned int count = buffer->len; - hb_glyph_info_t *info = buffer->info; - for (unsigned int i = 0; i < count; i++) -@@ -501,6 +635,10 @@ - static inline void - zero_mark_widths_by_gdef (hb_buffer_t *buffer, bool adjust_offsets) - { -+ /* This one is a hack; Technically GDEF can mark ASCII glyphs as marks, but we don't listen. */ -+ if (!(buffer->scratch_flags & HB_BUFFER_SCRATCH_FLAG_HAS_NON_ASCII)) -+ return; -+ - unsigned int count = buffer->len; - hb_glyph_info_t *info = buffer->info; - for (unsigned int i = 0; i < count; i++) -@@ -519,18 +657,30 @@ - unsigned int count = c->buffer->len; - hb_glyph_info_t *info = c->buffer->info; - hb_glyph_position_t *pos = c->buffer->pos; -- for (unsigned int i = 0; i < count; i++) -- { -- c->font->get_glyph_advance_for_direction (info[i].codepoint, -- direction, -- &pos[i].x_advance, -- &pos[i].y_advance); -- c->font->subtract_glyph_origin_for_direction (info[i].codepoint, -- direction, -- &pos[i].x_offset, -- &pos[i].y_offset); - -+ if (HB_DIRECTION_IS_HORIZONTAL (direction)) -+ { -+ for (unsigned int i = 0; i < count; i++) -+ pos[i].x_advance = c->font->get_glyph_h_advance (info[i].codepoint); -+ /* The nil glyph_h_origin() func returns 0, so no need to apply it. */ -+ if (c->font->has_glyph_h_origin_func ()) -+ for (unsigned int i = 0; i < count; i++) -+ c->font->subtract_glyph_h_origin (info[i].codepoint, -+ &pos[i].x_offset, -+ &pos[i].y_offset); -+ } -+ else -+ { -+ for (unsigned int i = 0; i < count; i++) -+ { -+ pos[i].y_advance = c->font->get_glyph_v_advance (info[i].codepoint); -+ c->font->subtract_glyph_v_origin (info[i].codepoint, -+ &pos[i].x_offset, -+ &pos[i].y_offset); -+ } - } -+ if (c->buffer->scratch_flags & HB_BUFFER_SCRATCH_FLAG_HAS_SPACE_FALLBACK) -+ _hb_ot_shape_fallback_spaces (c->plan, c->font, c->buffer); - } - - static inline bool -@@ -538,7 +688,7 @@ - { - bool ret = false; - unsigned int count = c->buffer->len; -- bool has_positioning = hb_ot_layout_has_positioning (c->face); -+ bool has_positioning = (bool) hb_ot_layout_has_positioning (c->face); - /* If the font has no GPOS, AND, no fallback positioning will - * happen, AND, direction is forward, then when zeroing mark - * widths, we shift the mark with it, such that the mark -@@ -575,23 +725,23 @@ - hb_glyph_info_t *info = c->buffer->info; - hb_glyph_position_t *pos = c->buffer->pos; - -- /* Change glyph origin to what GPOS expects, apply GPOS, change it back. */ -+ /* Change glyph origin to what GPOS expects (horizontal), apply GPOS, change it back. */ - -- for (unsigned int i = 0; i < count; i++) { -- c->font->add_glyph_origin_for_direction (info[i].codepoint, -- HB_DIRECTION_LTR, -- &pos[i].x_offset, -- &pos[i].y_offset); -- } -+ /* The nil glyph_h_origin() func returns 0, so no need to apply it. */ -+ if (c->font->has_glyph_h_origin_func ()) -+ for (unsigned int i = 0; i < count; i++) -+ c->font->add_glyph_h_origin (info[i].codepoint, -+ &pos[i].x_offset, -+ &pos[i].y_offset); - - c->plan->position (c->font, c->buffer); - -- for (unsigned int i = 0; i < count; i++) { -- c->font->subtract_glyph_origin_for_direction (info[i].codepoint, -- HB_DIRECTION_LTR, -- &pos[i].x_offset, -- &pos[i].y_offset); -- } -+ /* The nil glyph_h_origin() func returns 0, so no need to apply it. */ -+ if (c->font->has_glyph_h_origin_func ()) -+ for (unsigned int i = 0; i < count; i++) -+ c->font->subtract_glyph_h_origin (info[i].codepoint, -+ &pos[i].x_offset, -+ &pos[i].y_offset); - - ret = true; - } -@@ -625,6 +775,8 @@ - - hb_bool_t fallback = !hb_ot_position_complex (c); - -+ hb_ot_zero_width_default_ignorables (c); -+ - hb_ot_layout_position_finish (c->font, c->buffer); - - if (fallback && c->plan->shaper->fallback_position) -@@ -642,59 +794,18 @@ - } - - --/* Post-process */ -- --static void --hb_ot_hide_default_ignorables (hb_ot_shape_context_t *c) --{ -- if (c->buffer->flags & HB_BUFFER_FLAG_PRESERVE_DEFAULT_IGNORABLES) -- return; -- -- hb_codepoint_t space; -- enum { -- SPACE_DONT_KNOW, -- SPACE_AVAILABLE, -- SPACE_UNAVAILABLE -- } space_status = SPACE_DONT_KNOW; -- -- unsigned int count = c->buffer->len; -- hb_glyph_info_t *info = c->buffer->info; -- hb_glyph_position_t *pos = c->buffer->pos; -- unsigned int j = 0; -- for (unsigned int i = 0; i < count; i++) -- { -- if (unlikely (!_hb_glyph_info_ligated (&info[i]) && -- _hb_glyph_info_is_default_ignorable (&info[i]))) -- { -- if (space_status == SPACE_DONT_KNOW) -- space_status = c->font->get_glyph (' ', 0, &space) ? SPACE_AVAILABLE : SPACE_UNAVAILABLE; -- -- if (space_status == SPACE_AVAILABLE) -- { -- info[i].codepoint = space; -- pos[i].x_advance = 0; -- pos[i].y_advance = 0; -- } -- else -- continue; /* Delete it. */ -- } -- if (j != i) -- { -- info[j] = info[i]; -- pos[j] = pos[i]; -- } -- j++; -- } -- c->buffer->len = j; --} -- -- - /* Pull it all together! */ - - static void - hb_ot_shape_internal (hb_ot_shape_context_t *c) - { - c->buffer->deallocate_var_all (); -+ c->buffer->scratch_flags = HB_BUFFER_SCRATCH_FLAG_DEFAULT; -+ if (likely (!_hb_unsigned_int_mul_overflows (c->buffer->len, HB_BUFFER_MAX_EXPANSION_FACTOR))) -+ { -+ c->buffer->max_len = MAX (c->buffer->len * HB_BUFFER_MAX_EXPANSION_FACTOR, -+ (unsigned) HB_BUFFER_MAX_LEN_MIN); -+ } - - /* Save the original direction, we use it later. */ - c->target_direction = c->buffer->props.direction; -@@ -709,15 +820,22 @@ - - hb_ensure_native_direction (c->buffer); - -+ if (c->plan->shaper->preprocess_text) -+ c->plan->shaper->preprocess_text (c->plan, c->buffer, c->font); -+ - hb_ot_substitute (c); - hb_ot_position (c); - - hb_ot_hide_default_ignorables (c); - -+ if (c->plan->shaper->postprocess_glyphs) -+ c->plan->shaper->postprocess_glyphs (c->plan, c->buffer, c->font); -+ - _hb_buffer_deallocate_unicode_vars (c->buffer); - - c->buffer->props.direction = c->target_direction; - -+ c->buffer->max_len = HB_BUFFER_MAX_LEN_DEFAULT; - c->buffer->deallocate_var_all (); - } - -@@ -736,6 +854,11 @@ - } - - -+/** -+ * hb_ot_shape_plan_collect_lookups: -+ * -+ * Since: 0.9.7 -+ **/ - void - hb_ot_shape_plan_collect_lookups (hb_shape_plan_t *shape_plan, - hb_tag_t table_tag, -@@ -766,6 +889,11 @@ - } - - -+/** -+ * hb_ot_shape_glyphs_closure: -+ * -+ * Since: 0.9.2 -+ **/ - void - hb_ot_shape_glyphs_closure (hb_font_t *font, - hb_buffer_t *buffer, -diff -uN gfx/harfbuzz/src_old/hb-ot-shape-complex-arabic.cc gfx/harfbuzz/src/hb-ot-shape-complex-arabic.cc ---- gfx/harfbuzz/src_old/hb-ot-shape-complex-arabic.cc 2016-05-10 22:26:55.000000000 +0200 -+++ gfx/harfbuzz/src/hb-ot-shape-complex-arabic.cc 2016-06-05 23:49:45.590881534 +0200 -@@ -24,18 +24,51 @@ - * Google Author(s): Behdad Esfahbod - */ - --#include "hb-ot-shape-complex-private.hh" -+#include "hb-ot-shape-complex-arabic-private.hh" - #include "hb-ot-shape-private.hh" - - -+#ifndef HB_DEBUG_ARABIC -+#define HB_DEBUG_ARABIC (HB_DEBUG+0) -+#endif -+ -+ - /* buffer var allocations */ - #define arabic_shaping_action() complex_var_u8_0() /* arabic shaping action */ - -+#define HB_BUFFER_SCRATCH_FLAG_ARABIC_HAS_STCH HB_BUFFER_SCRATCH_FLAG_COMPLEX0 -+ -+/* See: -+ * https://github.com/behdad/harfbuzz/commit/6e6f82b6f3dde0fc6c3c7d991d9ec6cfff57823d#commitcomment-14248516 */ -+#define HB_ARABIC_GENERAL_CATEGORY_IS_WORD(gen_cat) \ -+ (FLAG_SAFE (gen_cat) & \ -+ (FLAG (HB_UNICODE_GENERAL_CATEGORY_UNASSIGNED) | \ -+ FLAG (HB_UNICODE_GENERAL_CATEGORY_PRIVATE_USE) | \ -+ /*FLAG (HB_UNICODE_GENERAL_CATEGORY_LOWERCASE_LETTER) |*/ \ -+ FLAG (HB_UNICODE_GENERAL_CATEGORY_MODIFIER_LETTER) | \ -+ FLAG (HB_UNICODE_GENERAL_CATEGORY_OTHER_LETTER) | \ -+ /*FLAG (HB_UNICODE_GENERAL_CATEGORY_TITLECASE_LETTER) |*/ \ -+ /*FLAG (HB_UNICODE_GENERAL_CATEGORY_UPPERCASE_LETTER) |*/ \ -+ FLAG (HB_UNICODE_GENERAL_CATEGORY_SPACING_MARK) | \ -+ FLAG (HB_UNICODE_GENERAL_CATEGORY_ENCLOSING_MARK) | \ -+ FLAG (HB_UNICODE_GENERAL_CATEGORY_NON_SPACING_MARK) | \ -+ FLAG (HB_UNICODE_GENERAL_CATEGORY_DECIMAL_NUMBER) | \ -+ FLAG (HB_UNICODE_GENERAL_CATEGORY_LETTER_NUMBER) | \ -+ FLAG (HB_UNICODE_GENERAL_CATEGORY_OTHER_NUMBER) | \ -+ FLAG (HB_UNICODE_GENERAL_CATEGORY_CURRENCY_SYMBOL) | \ -+ FLAG (HB_UNICODE_GENERAL_CATEGORY_MODIFIER_SYMBOL) | \ -+ FLAG (HB_UNICODE_GENERAL_CATEGORY_MATH_SYMBOL) | \ -+ FLAG (HB_UNICODE_GENERAL_CATEGORY_OTHER_SYMBOL))) -+ -+ -+/* -+ * Joining types: -+ */ - - /* - * Bits used in the joining tables - */ --enum { -+enum hb_arabic_joining_type_t { - JOINING_TYPE_U = 0, - JOINING_TYPE_L = 1, - JOINING_TYPE_R = 2, -@@ -49,10 +82,6 @@ - JOINING_TYPE_X = 8 /* means: use general-category to choose between U or T. */ - }; - --/* -- * Joining types: -- */ -- - #include "hb-ot-shape-complex-arabic-table.hh" - - static unsigned int get_joining_type (hb_codepoint_t u, hb_unicode_general_category_t gen_cat) -@@ -61,7 +90,7 @@ - if (likely (j_type != JOINING_TYPE_X)) - return j_type; - -- return (FLAG(gen_cat) & -+ return (FLAG_SAFE(gen_cat) & - (FLAG(HB_UNICODE_GENERAL_CATEGORY_NON_SPACING_MARK) | - FLAG(HB_UNICODE_GENERAL_CATEGORY_ENCLOSING_MARK) | - FLAG(HB_UNICODE_GENERAL_CATEGORY_FORMAT)) -@@ -84,7 +113,7 @@ - - - /* Same order as the feature array */ --enum { -+enum arabic_action_t { - ISOL, - FINA, - FIN2, -@@ -95,7 +124,11 @@ - - NONE, - -- ARABIC_NUM_FEATURES = NONE -+ ARABIC_NUM_FEATURES = NONE, -+ -+ /* We abuse the same byte for other things... */ -+ STCH_FIXED, -+ STCH_REPEATING, - }; - - static const struct arabic_state_table_entry { -@@ -140,6 +173,11 @@ - hb_buffer_t *buffer); - - static void -+record_stch (const hb_ot_shape_plan_t *plan, -+ hb_font_t *font, -+ hb_buffer_t *buffer); -+ -+static void - collect_features_arabic (hb_ot_shape_planner_t *plan) - { - hb_ot_map_builder_t *map = &plan->map; -@@ -165,6 +203,9 @@ - - map->add_gsub_pause (nuke_joiners); - -+ map->add_global_bool_feature (HB_TAG('s','t','c','h')); -+ map->add_gsub_pause (record_stch); -+ - map->add_global_bool_feature (HB_TAG('c','c','m','p')); - map->add_global_bool_feature (HB_TAG('l','o','c','l')); - -@@ -182,7 +223,6 @@ - map->add_gsub_pause (arabic_fallback_shape); - - map->add_global_bool_feature (HB_TAG('c','a','l','t')); -- map->add_gsub_pause (NULL); - - /* The spec includes 'cswh'. Earlier versions of Windows - * used to enable this by default, but testing suggests -@@ -192,6 +232,7 @@ - * Note that IranNastaliq uses this feature extensively - * to fixup broken glyph sequences. Oh well... - * Test case: U+0643,U+0640,U+0631. */ -+ //map->add_gsub_pause (NULL); - //map->add_global_bool_feature (HB_TAG('c','s','w','h')); - map->add_global_bool_feature (HB_TAG('m','s','e','t')); - } -@@ -208,11 +249,13 @@ - * mask_array[NONE] == 0. */ - hb_mask_t mask_array[ARABIC_NUM_FEATURES + 1]; - -- bool do_fallback; - arabic_fallback_plan_t *fallback_plan; -+ -+ unsigned int do_fallback : 1; -+ unsigned int has_stch : 1; - }; - --static void * -+void * - data_create_arabic (const hb_ot_shape_plan_t *plan) - { - arabic_shape_plan_t *arabic_plan = (arabic_shape_plan_t *) calloc (1, sizeof (arabic_shape_plan_t)); -@@ -220,6 +263,7 @@ - return NULL; - - arabic_plan->do_fallback = plan->props.script == HB_SCRIPT_ARABIC; -+ arabic_plan->has_stch = !!plan->map.get_1_mask (HB_TAG ('s','t','c','h')); - for (unsigned int i = 0; i < ARABIC_NUM_FEATURES; i++) { - arabic_plan->mask_array[i] = plan->map.get_1_mask (arabic_features[i]); - arabic_plan->do_fallback = arabic_plan->do_fallback && -@@ -230,7 +274,7 @@ - return arabic_plan; - } - --static void -+void - data_destroy_arabic (void *data) - { - arabic_shape_plan_t *arabic_plan = (arabic_shape_plan_t *) data; -@@ -305,25 +349,30 @@ - info[i].arabic_shaping_action() = info[i - 1].arabic_shaping_action(); - } - --static void --setup_masks_arabic (const hb_ot_shape_plan_t *plan, -- hb_buffer_t *buffer, -- hb_font_t *font HB_UNUSED) -+void -+setup_masks_arabic_plan (const arabic_shape_plan_t *arabic_plan, -+ hb_buffer_t *buffer, -+ hb_script_t script) - { - HB_BUFFER_ALLOCATE_VAR (buffer, arabic_shaping_action); - -- const arabic_shape_plan_t *arabic_plan = (const arabic_shape_plan_t *) plan->data; -- - arabic_joining (buffer); -- if (plan->props.script == HB_SCRIPT_MONGOLIAN) -+ if (script == HB_SCRIPT_MONGOLIAN) - mongolian_variation_selectors (buffer); - - unsigned int count = buffer->len; - hb_glyph_info_t *info = buffer->info; - for (unsigned int i = 0; i < count; i++) - info[i].mask |= arabic_plan->mask_array[info[i].arabic_shaping_action()]; -+} - -- HB_BUFFER_DEALLOCATE_VAR (buffer, arabic_shaping_action); -+static void -+setup_masks_arabic (const hb_ot_shape_plan_t *plan, -+ hb_buffer_t *buffer, -+ hb_font_t *font HB_UNUSED) -+{ -+ const arabic_shape_plan_t *arabic_plan = (const arabic_shape_plan_t *) plan->data; -+ setup_masks_arabic_plan (arabic_plan, buffer, plan->props.script); - } - - -@@ -364,6 +413,197 @@ - arabic_fallback_plan_shape (fallback_plan, font, buffer); - } - -+/* -+ * Stretch feature: "stch". -+ * See example here: -+ * https://www.microsoft.com/typography/OpenTypeDev/syriac/intro.htm -+ * We implement this in a generic way, such that the Arabic subtending -+ * marks can use it as well. -+ */ -+ -+static void -+record_stch (const hb_ot_shape_plan_t *plan, -+ hb_font_t *font, -+ hb_buffer_t *buffer) -+{ -+ const arabic_shape_plan_t *arabic_plan = (const arabic_shape_plan_t *) plan->data; -+ if (!arabic_plan->has_stch) -+ return; -+ -+ /* 'stch' feature was just applied. Look for anything that multiplied, -+ * and record it for stch treatment later. Note that rtlm, frac, etc -+ * are applied before stch, but we assume that they didn't result in -+ * anything multiplying into 5 pieces, so it's safe-ish... */ -+ -+ unsigned int count = buffer->len; -+ hb_glyph_info_t *info = buffer->info; -+ for (unsigned int i = 0; i < count; i++) -+ if (unlikely (_hb_glyph_info_multiplied (&info[i]))) -+ { -+ unsigned int comp = _hb_glyph_info_get_lig_comp (&info[i]); -+ info[i].arabic_shaping_action() = comp % 2 ? STCH_REPEATING : STCH_FIXED; -+ buffer->scratch_flags |= HB_BUFFER_SCRATCH_FLAG_ARABIC_HAS_STCH; -+ } -+} -+ -+static void -+apply_stch (const hb_ot_shape_plan_t *plan, -+ hb_buffer_t *buffer, -+ hb_font_t *font) -+{ -+ if (likely (!(buffer->scratch_flags & HB_BUFFER_SCRATCH_FLAG_ARABIC_HAS_STCH))) -+ return; -+ -+ /* The Arabic shaper currently always processes in RTL mode, so we should -+ * stretch / position the stretched pieces to the left / preceding glyphs. */ -+ -+ /* We do a two pass implementation: -+ * First pass calculates the exact number of extra glyphs we need, -+ * We then enlarge buffer to have that much room, -+ * Second pass applies the stretch, copying things to the end of buffer. -+ */ -+ -+ int sign = font->x_scale < 0 ? -1 : +1; -+ unsigned int extra_glyphs_needed = 0; // Set during MEASURE, used during CUT -+ typedef enum { MEASURE, CUT } step_t; -+ -+ for (step_t step = MEASURE; step <= CUT; step = (step_t) (step + 1)) -+ { -+ unsigned int count = buffer->len; -+ hb_glyph_info_t *info = buffer->info; -+ hb_glyph_position_t *pos = buffer->pos; -+ unsigned int new_len = count + extra_glyphs_needed; // write head during CUT -+ unsigned int j = new_len; -+ for (unsigned int i = count; i; i--) -+ { -+ if (!hb_in_range<unsigned> (info[i - 1].arabic_shaping_action(), STCH_FIXED, STCH_REPEATING)) -+ { -+ if (step == CUT) -+ { -+ --j; -+ info[j] = info[i - 1]; -+ pos[j] = pos[i - 1]; -+ } -+ continue; -+ } -+ -+ /* Yay, justification! */ -+ -+ hb_position_t w_total = 0; // Total to be filled -+ hb_position_t w_fixed = 0; // Sum of fixed tiles -+ hb_position_t w_repeating = 0; // Sum of repeating tiles -+ int n_fixed = 0; -+ int n_repeating = 0; -+ -+ unsigned int end = i; -+ while (i && -+ hb_in_range<unsigned> (info[i - 1].arabic_shaping_action(), STCH_FIXED, STCH_REPEATING)) -+ { -+ i--; -+ hb_position_t width = font->get_glyph_h_advance (info[i].codepoint); -+ if (info[i].arabic_shaping_action() == STCH_FIXED) -+ { -+ w_fixed += width; -+ n_fixed++; -+ } -+ else -+ { -+ w_repeating += width; -+ n_repeating++; -+ } -+ } -+ unsigned int start = i; -+ unsigned int context = i; -+ while (context && -+ !hb_in_range<unsigned> (info[context - 1].arabic_shaping_action(), STCH_FIXED, STCH_REPEATING) && -+ (_hb_glyph_info_is_default_ignorable (&info[context - 1]) || -+ HB_ARABIC_GENERAL_CATEGORY_IS_WORD (_hb_glyph_info_get_general_category (&info[context - 1])))) -+ { -+ context--; -+ w_total += pos[context].x_advance; -+ } -+ i++; // Don't touch i again. -+ -+ DEBUG_MSG (ARABIC, NULL, "%s stretch at (%d,%d,%d)", -+ step == MEASURE ? "measuring" : "cutting", context, start, end); -+ DEBUG_MSG (ARABIC, NULL, "rest of word: count=%d width %d", start - context, w_total); -+ DEBUG_MSG (ARABIC, NULL, "fixed tiles: count=%d width=%d", n_fixed, w_fixed); -+ DEBUG_MSG (ARABIC, NULL, "repeating tiles: count=%d width=%d", n_repeating, w_repeating); -+ -+ /* Number of additional times to repeat each repeating tile. */ -+ int n_copies = 0; -+ -+ hb_position_t w_remaining = w_total - w_fixed; -+ if (sign * w_remaining > sign * w_repeating && sign * w_repeating > 0) -+ n_copies = (sign * w_remaining) / (sign * w_repeating) - 1; -+ -+ /* See if we can improve the fit by adding an extra repeat and squeezing them together a bit. */ -+ hb_position_t extra_repeat_overlap = 0; -+ hb_position_t shortfall = sign * w_remaining - sign * w_repeating * (n_copies + 1); -+ if (shortfall > 0) -+ { -+ ++n_copies; -+ hb_position_t excess = (n_copies + 1) * sign * w_repeating - sign * w_remaining; -+ if (excess > 0) -+ extra_repeat_overlap = excess / (n_copies * n_repeating); -+ } -+ -+ if (step == MEASURE) -+ { -+ extra_glyphs_needed += n_copies * n_repeating; -+ DEBUG_MSG (ARABIC, NULL, "will add extra %d copies of repeating tiles", n_copies); -+ } -+ else -+ { -+ hb_position_t x_offset = 0; -+ for (unsigned int k = end; k > start; k--) -+ { -+ hb_position_t width = font->get_glyph_h_advance (info[k - 1].codepoint); -+ -+ unsigned int repeat = 1; -+ if (info[k - 1].arabic_shaping_action() == STCH_REPEATING) -+ repeat += n_copies; -+ -+ DEBUG_MSG (ARABIC, NULL, "appending %d copies of glyph %d; j=%d", -+ repeat, info[k - 1].codepoint, j); -+ for (unsigned int n = 0; n < repeat; n++) -+ { -+ x_offset -= width; -+ if (n > 0) -+ x_offset += extra_repeat_overlap; -+ pos[k - 1].x_offset = x_offset; -+ /* Append copy. */ -+ --j; -+ info[j] = info[k - 1]; -+ pos[j] = pos[k - 1]; -+ } -+ } -+ } -+ } -+ -+ if (step == MEASURE) -+ { -+ if (unlikely (!buffer->ensure (count + extra_glyphs_needed))) -+ break; -+ } -+ else -+ { -+ assert (j == 0); -+ buffer->len = new_len; -+ } -+ } -+} -+ -+ -+static void -+postprocess_glyphs_arabic (const hb_ot_shape_plan_t *plan, -+ hb_buffer_t *buffer, -+ hb_font_t *font) -+{ -+ apply_stch (plan, buffer, font); -+ -+ HB_BUFFER_DEALLOCATE_VAR (buffer, arabic_shaping_action); -+} - - const hb_ot_complex_shaper_t _hb_ot_complex_shaper_arabic = - { -@@ -372,7 +612,8 @@ - NULL, /* override_features */ - data_create_arabic, - data_destroy_arabic, -- NULL, /* preprocess_text_arabic */ -+ NULL, /* preprocess_text */ -+ postprocess_glyphs_arabic, - HB_OT_SHAPE_NORMALIZATION_MODE_DEFAULT, - NULL, /* decompose */ - NULL, /* compose */ -diff -uN gfx/harfbuzz/src_old/hb-ot-shape-complex-arabic-fallback.hh gfx/harfbuzz/src/hb-ot-shape-complex-arabic-fallback.hh ---- gfx/harfbuzz/src_old/hb-ot-shape-complex-arabic-fallback.hh 2016-05-10 22:26:56.000000000 +0200 -+++ gfx/harfbuzz/src/hb-ot-shape-complex-arabic-fallback.hh 2016-06-05 23:49:40.225909984 +0200 -@@ -75,9 +75,9 @@ - if (!num_glyphs) - return NULL; - -- /* Bubble-sort! -+ /* Bubble-sort or something equally good! - * May not be good-enough for presidential candidate interviews, but good-enough for us... */ -- hb_bubble_sort (&glyphs[0], num_glyphs, OT::GlyphID::cmp, &substitutes[0]); -+ hb_stable_sort (&glyphs[0], num_glyphs, OT::GlyphID::cmp, &substitutes[0]); - - OT::Supplier<OT::GlyphID> glyphs_supplier (glyphs, num_glyphs); - OT::Supplier<OT::GlyphID> substitutes_supplier (substitutes, num_glyphs); -@@ -126,7 +126,7 @@ - first_glyphs_indirection[num_first_glyphs] = first_glyph_idx; - num_first_glyphs++; - } -- hb_bubble_sort (&first_glyphs[0], num_first_glyphs, OT::GlyphID::cmp, &first_glyphs_indirection[0]); -+ hb_stable_sort (&first_glyphs[0], num_first_glyphs, OT::GlyphID::cmp, &first_glyphs_indirection[0]); - - /* Now that the first-glyphs are sorted, walk again, populate ligatures. */ - for (unsigned int i = 0; i < num_first_glyphs; i++) -@@ -327,7 +327,7 @@ - for (unsigned int i = 0; i < fallback_plan->num_lookups; i++) - if (fallback_plan->lookup_array[i]) - { -- fallback_plan->accel_array[i].fini (fallback_plan->lookup_array[i]); -+ fallback_plan->accel_array[i].fini (); - if (fallback_plan->free_lookups) - free (fallback_plan->lookup_array[i]); - } -diff -uN gfx/harfbuzz/src_old/hb-ot-shape-complex-arabic-private.hh gfx/harfbuzz/src/hb-ot-shape-complex-arabic-private.hh ---- gfx/harfbuzz/src_old/hb-ot-shape-complex-arabic-private.hh 1970-01-01 01:00:00.000000000 +0100 -+++ gfx/harfbuzz/src/hb-ot-shape-complex-arabic-private.hh 2016-06-05 23:49:41.475903336 +0200 -@@ -0,0 +1,50 @@ -+/* -+ * 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_ARABIC_PRIVATE_HH -+#define HB_OT_SHAPE_COMPLEX_ARABIC_PRIVATE_HH -+ -+#include "hb-private.hh" -+ -+#include "hb-ot-shape-complex-private.hh" -+ -+ -+struct arabic_shape_plan_t; -+ -+HB_INTERNAL void * -+data_create_arabic (const hb_ot_shape_plan_t *plan); -+ -+HB_INTERNAL void -+data_destroy_arabic (void *data); -+ -+HB_INTERNAL void -+setup_masks_arabic_plan (const arabic_shape_plan_t *arabic_plan, -+ hb_buffer_t *buffer, -+ hb_script_t script); -+ -+#endif /* HB_OT_SHAPE_COMPLEX_ARABIC_PRIVATE_HH */ -diff -uN gfx/harfbuzz/src_old/hb-ot-shape-complex-arabic-table.hh gfx/harfbuzz/src/hb-ot-shape-complex-arabic-table.hh ---- gfx/harfbuzz/src_old/hb-ot-shape-complex-arabic-table.hh 2016-05-10 22:26:55.000000000 +0200 -+++ gfx/harfbuzz/src/hb-ot-shape-complex-arabic-table.hh 2016-06-05 23:49:42.902895782 +0200 -@@ -6,10 +6,10 @@ - * - * on files with these headers: - * -- * # ArabicShaping-7.0.0.txt -- * # Date: 2014-02-14, 21:00:00 GMT [RP, KW, LI] -- * # Blocks-7.0.0.txt -- * # Date: 2014-04-03, 23:23:00 GMT [RP, KW] -+ * # ArabicShaping-8.0.0.txt -+ * # Date: 2015-02-17, 23:33:00 GMT [RP] -+ * # Blocks-8.0.0.txt -+ * # Date: 2014-11-10, 23:04:00 GMT [KW] - * UnicodeData.txt does not have a header. - */ - -@@ -76,9 +76,9 @@ - - /* Arabic Extended-A */ - -- /* 08A0 */ D,D,D,D,D,D,D,D,D,D,R,R,R,U,R,D,D,R,R, -+ /* 08A0 */ D,D,D,D,D,D,D,D,D,D,R,R,R,U,R,D,D,R,R,D,D, - --#define joining_offset_0x1806u 691 -+#define joining_offset_0x1806u 693 - - /* Mongolian */ - -@@ -89,40 +89,40 @@ - /* 1880 */ U,U,U,U,U,U,U,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D, - /* 18A0 */ D,D,D,D,D,D,D,D,D,X,D, - --#define joining_offset_0x200cu 856 -+#define joining_offset_0x200cu 858 - - /* General Punctuation */ - - /* 2000 */ U,C, - --#define joining_offset_0x2066u 858 -+#define joining_offset_0x2066u 860 - - /* General Punctuation */ - - /* 2060 */ U,U,U,U, - --#define joining_offset_0xa840u 862 -+#define joining_offset_0xa840u 864 - - /* Phags-pa */ - - /* A840 */ D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D, - /* A860 */ D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,L,U, - --#define joining_offset_0x10ac0u 914 -+#define joining_offset_0x10ac0u 916 - - /* Manichaean */ - - /* 10AC0 */ D,D,D,D,D,R,U,R,U,R,R,U,U,L,R,R,R,R,R,D,D,D,D,L,D,D,D,D,D,R,D,D, - /* 10AE0 */ D,R,U,U,R,X,X,X,X,X,X,D,D,D,D,R, - --#define joining_offset_0x10b80u 962 -+#define joining_offset_0x10b80u 964 - - /* Psalter Pahlavi */ - - /* 10B80 */ D,R,D,R,R,R,D,D,D,R,D,D,R,D,R,R,D,R,X,X,X,X,X,X,X,X,X,X,X,X,X,X, - /* 10BA0 */ X,X,X,X,X,X,X,X,X,R,R,R,R,D,D,U, - --}; /* Table items: 1010; occupancy: 57% */ -+}; /* Table items: 1012; occupancy: 57% */ - - - static unsigned int -@@ -131,7 +131,7 @@ - switch (u >> 12) - { - case 0x0u: -- if (hb_in_range (u, 0x0600u, 0x08B2u)) return joining_table[u - 0x0600u + joining_offset_0x0600u]; -+ if (hb_in_range (u, 0x0600u, 0x08B4u)) return joining_table[u - 0x0600u + joining_offset_0x0600u]; - break; - - case 0x1u: -diff -uN gfx/harfbuzz/src_old/hb-ot-shape-complex-arabic-win1256.hh gfx/harfbuzz/src/hb-ot-shape-complex-arabic-win1256.hh ---- gfx/harfbuzz/src_old/hb-ot-shape-complex-arabic-win1256.hh 2016-05-10 22:26:56.000000000 +0200 -+++ gfx/harfbuzz/src/hb-ot-shape-complex-arabic-win1256.hh 2016-06-05 23:49:44.102889415 +0200 -@@ -133,7 +133,6 @@ - */ - - #define OT_LOOKUP_TYPE_SUBST_SINGLE 1u --#define OT_LOOKUP_TYPE_SUBST_MULTIPLE 2u - #define OT_LOOKUP_TYPE_SUBST_LIGATURE 4u - - #define OT_SUBLOOKUP_SINGLE_SUBST_FORMAT2(Name, FromGlyphs, ToGlyphs) \ -@@ -143,7 +142,7 @@ - OT_UARRAY(Name##Substitute, OT_LIST(ToGlyphs)) \ - ) \ - OT_COVERAGE1(Name##Coverage, OT_LIST(FromGlyphs)) \ -- /* ASSERT_STATIC_EXPR len(FromGlyphs) == len(ToGlyphs) */ -+ /* ASSERT_STATIC_EXPR_ZERO (len(FromGlyphs) == len(ToGlyphs)) */ - - #define OT_SUBLOOKUP_LIGATURE_SUBST_FORMAT1(Name, FirstGlyphs, LigatureSetOffsets) \ - OT_SUBLOOKUP(Name, 1, \ -@@ -152,7 +151,7 @@ - OT_UARRAY(Name##LigatureSetOffsetsArray, OT_LIST(LigatureSetOffsets)) \ - ) \ - OT_COVERAGE1(Name##Coverage, OT_LIST(FirstGlyphs)) \ -- /* ASSERT_STATIC_EXPR len(FirstGlyphs) == len(LigatureSetOffsets) */ -+ /* ASSERT_STATIC_EXPR_ZERO (len(FirstGlyphs) == len(LigatureSetOffsets)) */ - - #define OT_LIGATURE_SET(Name, LigatureSetOffsets) \ - OT_UARRAY(Name, OT_LIST(LigatureSetOffsets)) -diff -uN gfx/harfbuzz/src_old/hb-ot-shape-complex-default.cc gfx/harfbuzz/src/hb-ot-shape-complex-default.cc ---- gfx/harfbuzz/src_old/hb-ot-shape-complex-default.cc 2016-05-10 22:26:56.000000000 +0200 -+++ gfx/harfbuzz/src/hb-ot-shape-complex-default.cc 2016-06-05 23:49:46.803875109 +0200 -@@ -35,10 +35,11 @@ - NULL, /* data_create */ - NULL, /* data_destroy */ - NULL, /* preprocess_text */ -+ NULL, /* postprocess_glyphs */ - HB_OT_SHAPE_NORMALIZATION_MODE_DEFAULT, - NULL, /* decompose */ - NULL, /* compose */ - NULL, /* setup_masks */ -- HB_OT_SHAPE_ZERO_WIDTH_MARKS_DEFAULT, -+ HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_UNICODE_LATE, - true, /* fallback_position */ - }; -diff -uN gfx/harfbuzz/src_old/hb-ot-shape-complex-hangul.cc gfx/harfbuzz/src/hb-ot-shape-complex-hangul.cc ---- gfx/harfbuzz/src_old/hb-ot-shape-complex-hangul.cc 2016-05-10 22:26:55.000000000 +0200 -+++ gfx/harfbuzz/src/hb-ot-shape-complex-hangul.cc 2016-06-05 23:49:47.978868903 +0200 -@@ -188,7 +188,7 @@ - */ - unsigned int count = buffer->len; - -- for (buffer->idx = 0; buffer->idx < count;) -+ for (buffer->idx = 0; buffer->idx < count && !buffer->in_error;) - { - hb_codepoint_t u = buffer->cur().codepoint; - -@@ -205,17 +205,12 @@ - buffer->next_glyph (); - if (!is_zero_width_char (font, u)) - { -+ buffer->merge_out_clusters (start, end + 1); - hb_glyph_info_t *info = buffer->out_info; - hb_glyph_info_t tone = info[end]; - memmove (&info[start + 1], &info[start], (end - start) * sizeof (hb_glyph_info_t)); - info[start] = tone; - } -- /* Merge clusters across the (possibly reordered) syllable+tone. -- * We want to merge even in the zero-width tone mark case here, -- * so that clustering behavior isn't dependent on how the tone mark -- * is handled by the font. -- */ -- buffer->merge_out_clusters (start, end + 1); - } - else - { -@@ -296,7 +291,8 @@ - } - else - end = start + 2; -- buffer->merge_out_clusters (start, end); -+ if (buffer->cluster_level == HB_BUFFER_CLUSTER_LEVEL_MONOTONE_GRAPHEMES) -+ buffer->merge_out_clusters (start, end); - continue; - } - } -@@ -368,7 +364,8 @@ - info[i++].hangul_shaping_feature() = VJMO; - if (i < end) - info[i++].hangul_shaping_feature() = TJMO; -- buffer->merge_out_clusters (start, end); -+ if (buffer->cluster_level == HB_BUFFER_CLUSTER_LEVEL_MONOTONE_GRAPHEMES) -+ buffer->merge_out_clusters (start, end); - continue; - } - } -@@ -414,13 +411,14 @@ - "hangul", - collect_features_hangul, - override_features_hangul, -- data_create_hangul, /* data_create */ -- data_destroy_hangul, /* data_destroy */ -+ data_create_hangul, -+ data_destroy_hangul, - preprocess_text_hangul, -+ NULL, /* postprocess_glyphs */ - HB_OT_SHAPE_NORMALIZATION_MODE_NONE, - NULL, /* decompose */ - NULL, /* compose */ -- setup_masks_hangul, /* setup_masks */ -+ setup_masks_hangul, - HB_OT_SHAPE_ZERO_WIDTH_MARKS_NONE, - false, /* fallback_position */ - }; -diff -uN gfx/harfbuzz/src_old/hb-ot-shape-complex-hebrew.cc gfx/harfbuzz/src/hb-ot-shape-complex-hebrew.cc ---- gfx/harfbuzz/src_old/hb-ot-shape-complex-hebrew.cc 2016-05-10 22:26:55.000000000 +0200 -+++ gfx/harfbuzz/src/hb-ot-shape-complex-hebrew.cc 2016-06-05 23:49:49.094863009 +0200 -@@ -68,7 +68,7 @@ - 0xFB4Au /* TAV */ - }; - -- bool found = c->unicode->compose (a, b, ab); -+ bool found = (bool) c->unicode->compose (a, b, ab); - - if (!found && !c->plan->has_mark) - { -@@ -163,6 +163,7 @@ - NULL, /* data_create */ - NULL, /* data_destroy */ - NULL, /* preprocess_text */ -+ NULL, /* postprocess_glyphs */ - HB_OT_SHAPE_NORMALIZATION_MODE_DEFAULT, - NULL, /* decompose */ - compose_hebrew, -diff -uN gfx/harfbuzz/src_old/hb-ot-shape-complex-indic.cc gfx/harfbuzz/src/hb-ot-shape-complex-indic.cc ---- gfx/harfbuzz/src_old/hb-ot-shape-complex-indic.cc 2016-05-10 22:26:55.000000000 +0200 -+++ gfx/harfbuzz/src/hb-ot-shape-complex-indic.cc 2016-06-05 23:49:56.649823205 +0200 -@@ -142,7 +142,7 @@ - { - /* If it ligated, all bets are off. */ - if (_hb_glyph_info_ligated (&info)) return false; -- return !!(FLAG (info.indic_category()) & flags); -+ return !!(FLAG_SAFE (info.indic_category()) & flags); - } - - static inline bool -@@ -176,24 +176,8 @@ - * Re-assign category - */ - -- -- /* The spec says U+0952 is OT_A. However, testing shows that Uniscribe -- * treats a whole bunch of characters similarly. -- * TESTS: For example, for U+0951: -- * U+092E,U+0947,U+0952 -- * U+092E,U+0952,U+0947 -- * U+092E,U+0947,U+0951 -- * U+092E,U+0951,U+0947 -- * U+092E,U+0951,U+0952 -- * U+092E,U+0952,U+0951 -- */ -- if (unlikely (hb_in_ranges (u, 0x0951u, 0x0952u, -- 0x1CD0u, 0x1CD2u, -- 0x1CD4u, 0x1CE1u) || -- u == 0x1CF4u)) -- cat = OT_A; - /* The following act more like the Bindus. */ -- else if (unlikely (hb_in_range (u, 0x0953u, 0x0954u))) -+ if (unlikely (hb_in_range (u, 0x0953u, 0x0954u))) - cat = OT_SM; - /* The following act like consonants. */ - else if (unlikely (hb_in_ranges (u, 0x0A72u, 0x0A73u, -@@ -216,15 +200,12 @@ - cat = OT_Symbol; - ASSERT_STATIC ((int) INDIC_SYLLABIC_CATEGORY_AVAGRAHA == OT_Symbol); - } -- else if (unlikely (hb_in_range (u, 0x17CDu, 0x17D1u) || -- u == 0x17CBu || u == 0x17D3u || u == 0x17DDu)) /* Khmer Various signs */ -+ else if (unlikely (u == 0x17DDu)) /* https://github.com/roozbehp/unicode-data/issues/2 */ - { -- /* These are like Top Matras. */ - cat = OT_M; - pos = POS_ABOVE_C; - } - else if (unlikely (u == 0x17C6u)) cat = OT_N; /* Khmer Bindu doesn't like to be repositioned. */ -- else if (unlikely (u == 0x17D2u)) cat = OT_Coeng; /* Khmer coeng */ - else if (unlikely (hb_in_range (u, 0x2010u, 0x2011u))) - cat = OT_PLACEHOLDER; - else if (unlikely (u == 0x25CCu)) cat = OT_DOTTEDCIRCLE; -@@ -237,7 +218,7 @@ - * Re-assign position. - */ - -- if ((FLAG (cat) & CONSONANT_FLAGS)) -+ if ((FLAG_SAFE (cat) & CONSONANT_FLAGS)) - { - pos = POS_BASE_C; - if (is_ra (u)) -@@ -247,7 +228,7 @@ - { - pos = matra_position (u, pos); - } -- else if ((FLAG (cat) & (FLAG (OT_SM) | FLAG (OT_VD) | FLAG (OT_A) | FLAG (OT_Symbol)))) -+ else if ((FLAG_SAFE (cat) & (FLAG (OT_SM) | FLAG (OT_VD) | FLAG (OT_A) | FLAG (OT_Symbol)))) - { - pos = POS_SMVD; - } -@@ -557,8 +538,15 @@ - indic_plan->virama_glyph = (hb_codepoint_t) -1; - - /* Use zero-context would_substitute() matching for new-spec of the main -- * Indic scripts, and scripts with one spec only, but not for old-specs. */ -- bool zero_context = !indic_plan->is_old_spec; -+ * Indic scripts, and scripts with one spec only, but not for old-specs. -+ * The new-spec for all dual-spec scripts says zero-context matching happens. -+ * -+ * However, testing with Malayalam shows that old and new spec both allow -+ * context. Testing with Bengali new-spec however shows that it doesn't. -+ * So, the heuristic here is the way it is. It should *only* be changed, -+ * as we discover more cases of what Windows does. DON'T TOUCH OTHERWISE. -+ */ -+ bool zero_context = !indic_plan->is_old_spec && plan->props.script != HB_SCRIPT_MALAYALAM; - indic_plan->rphf.init (&plan->map, HB_TAG('r','p','h','f'), zero_context); - indic_plan->pref.init (&plan->map, HB_TAG('p','r','e','f'), zero_context); - indic_plan->blwf.init (&plan->map, HB_TAG('b','l','w','f'), zero_context); -@@ -756,7 +744,7 @@ - { - default: - assert (false); -- /* fallthrough */ -+ HB_FALLTHROUGH; - - case BASE_POS_LAST: - { -@@ -963,7 +951,7 @@ - indic_position_t last_pos = POS_START; - for (unsigned int i = start; i < end; i++) - { -- if ((FLAG (info[i].indic_category()) & (JOINER_FLAGS | FLAG (OT_N) | FLAG (OT_RS) | MEDIAL_FLAGS | HALANT_OR_COENG_FLAGS))) -+ if ((FLAG_SAFE (info[i].indic_category()) & (JOINER_FLAGS | FLAG (OT_N) | FLAG (OT_RS) | MEDIAL_FLAGS | HALANT_OR_COENG_FLAGS))) - { - info[i].indic_position() = last_pos; - if (unlikely (info[i].indic_category() == OT_H && -@@ -1012,7 +1000,7 @@ - info[i].syllable() = i - start; - - /* Sit tight, rock 'n roll! */ -- hb_bubble_sort (info + start, end - start, compare_indic_order); -+ hb_stable_sort (info + start, end - start, compare_indic_order); - /* Find base again */ - base = end; - for (unsigned int i = start; i < end; i++) -@@ -1025,7 +1013,11 @@ - * around like crazy. In old-spec mode, we move halants around, so in - * that case merge all clusters after base. Otherwise, check the sort - * order and merge as needed. -- * For pre-base stuff, we handle cluster issues in final reordering. */ -+ * For pre-base stuff, we handle cluster issues in final reordering. -+ * -+ * We could use buffer->sort() for this, if there was no special -+ * reordering of pre-base stuff happening later... -+ */ - if (indic_plan->is_old_spec || end - base > 127) - buffer->merge_clusters (base, end); - else -@@ -1161,17 +1153,6 @@ - } - } - -- --static void --initial_reordering_vowel_syllable (const hb_ot_shape_plan_t *plan, -- hb_face_t *face, -- hb_buffer_t *buffer, -- unsigned int start, unsigned int end) --{ -- /* We made the vowels look like consonants. So let's call the consonant logic! */ -- initial_reordering_consonant_syllable (plan, face, buffer, start, end); --} -- - static void - initial_reordering_standalone_cluster (const hb_ot_shape_plan_t *plan, - hb_face_t *face, -@@ -1194,50 +1175,27 @@ - } - - static void --initial_reordering_broken_cluster (const hb_ot_shape_plan_t *plan, -- hb_face_t *face, -- hb_buffer_t *buffer, -- unsigned int start, unsigned int end) --{ -- /* We already inserted dotted-circles, so just call the standalone_cluster. */ -- initial_reordering_standalone_cluster (plan, face, buffer, start, end); --} -- --static void --initial_reordering_symbol_cluster (const hb_ot_shape_plan_t *plan HB_UNUSED, -- hb_face_t *face HB_UNUSED, -- hb_buffer_t *buffer HB_UNUSED, -- unsigned int start HB_UNUSED, unsigned int end HB_UNUSED) --{ -- /* Nothing to do right now. If we ever switch to using the output -- * buffer in the reordering process, we'd need to next_glyph() here. */ --} -- --static void --initial_reordering_non_indic_cluster (const hb_ot_shape_plan_t *plan HB_UNUSED, -- hb_face_t *face HB_UNUSED, -- hb_buffer_t *buffer HB_UNUSED, -- unsigned int start HB_UNUSED, unsigned int end HB_UNUSED) --{ -- /* Nothing to do right now. If we ever switch to using the output -- * buffer in the reordering process, we'd need to next_glyph() here. */ --} -- -- --static void - initial_reordering_syllable (const hb_ot_shape_plan_t *plan, - hb_face_t *face, - hb_buffer_t *buffer, - unsigned int start, unsigned int end) - { - syllable_type_t syllable_type = (syllable_type_t) (buffer->info[start].syllable() & 0x0F); -- switch (syllable_type) { -- case consonant_syllable: initial_reordering_consonant_syllable (plan, face, buffer, start, end); return; -- case vowel_syllable: initial_reordering_vowel_syllable (plan, face, buffer, start, end); return; -- case standalone_cluster: initial_reordering_standalone_cluster (plan, face, buffer, start, end); return; -- case symbol_cluster: initial_reordering_symbol_cluster (plan, face, buffer, start, end); return; -- case broken_cluster: initial_reordering_broken_cluster (plan, face, buffer, start, end); return; -- case non_indic_cluster: initial_reordering_non_indic_cluster (plan, face, buffer, start, end); return; -+ switch (syllable_type) -+ { -+ case vowel_syllable: /* We made the vowels look like consonants. So let's call the consonant logic! */ -+ case consonant_syllable: -+ initial_reordering_consonant_syllable (plan, face, buffer, start, end); -+ break; -+ -+ case broken_cluster: /* We already inserted dotted-circles, so just call the standalone_cluster. */ -+ case standalone_cluster: -+ initial_reordering_standalone_cluster (plan, face, buffer, start, end); -+ break; -+ -+ case symbol_cluster: -+ case non_indic_cluster: -+ break; - } - } - -@@ -1273,7 +1231,7 @@ - - buffer->idx = 0; - unsigned int last_syllable = 0; -- while (buffer->idx < buffer->len) -+ while (buffer->idx < buffer->len && !buffer->in_error) - { - unsigned int syllable = buffer->cur().syllable(); - syllable_type_t syllable_type = (syllable_type_t) (syllable & 0x0F); -@@ -1281,10 +1239,10 @@ - { - last_syllable = syllable; - -- hb_glyph_info_t info = dottedcircle; -- info.cluster = buffer->cur().cluster; -- info.mask = buffer->cur().mask; -- info.syllable() = buffer->cur().syllable(); -+ hb_glyph_info_t ginfo = dottedcircle; -+ ginfo.cluster = buffer->cur().cluster; -+ ginfo.mask = buffer->cur().mask; -+ ginfo.syllable() = buffer->cur().syllable(); - /* TODO Set glyph_props? */ - - /* Insert dottedcircle after possible Repha. */ -@@ -1293,7 +1251,7 @@ - buffer->cur().indic_category() == OT_Repha) - buffer->next_glyph (); - -- buffer->output_info (info); -+ buffer->output_info (ginfo); - } - else - buffer->next_glyph (); -@@ -1310,18 +1268,8 @@ - update_consonant_positions (plan, font, buffer); - insert_dotted_circles (plan, font, buffer); - -- hb_glyph_info_t *info = buffer->info; -- unsigned int count = buffer->len; -- if (unlikely (!count)) return; -- unsigned int last = 0; -- unsigned int last_syllable = info[0].syllable(); -- for (unsigned int i = 1; i < count; i++) -- if (last_syllable != info[i].syllable()) { -- initial_reordering_syllable (plan, font->face, buffer, last, i); -- last = i; -- last_syllable = info[last].syllable(); -- } -- initial_reordering_syllable (plan, font->face, buffer, last, count); -+ foreach_syllable (buffer, start, end) -+ initial_reordering_syllable (plan, font->face, buffer, start, end); - } - - static void -@@ -1388,6 +1336,25 @@ - break; - } - } -+ /* For Malayalam, skip over unformed below- (but NOT post-) forms. */ -+ if (buffer->props.script == HB_SCRIPT_MALAYALAM) -+ { -+ for (unsigned int i = base + 1; i < end; i++) -+ { -+ while (i < end && is_joiner (info[i])) -+ i++; -+ if (i == end || !is_halant_or_coeng (info[i])) -+ break; -+ i++; /* Skip halant. */ -+ while (i < end && is_joiner (info[i])) -+ i++; -+ if (i < end && is_consonant (info[i]) && info[i].indic_position() == POS_BELOW_C) -+ { -+ base = i; -+ info[base].indic_position() = POS_BASE_C; -+ } -+ } -+ } - - if (start < base && info[base].indic_position() > POS_BASE_C) - base--; -@@ -1448,12 +1415,17 @@ - if (info[i - 1].indic_position () == POS_PRE_M) - { - unsigned int old_pos = i - 1; -+ if (old_pos < base && base <= new_pos) /* Shouldn't actually happen. */ -+ base--; -+ - hb_glyph_info_t tmp = info[old_pos]; - memmove (&info[old_pos], &info[old_pos + 1], (new_pos - old_pos) * sizeof (info[0])); - info[new_pos] = tmp; -- if (old_pos < base && base <= new_pos) /* Shouldn't actually happen. */ -- base--; -+ -+ /* Note: this merge_clusters() is intentionally *after* the reordering. -+ * Indic matra reordering is special and tricky... */ - buffer->merge_clusters (new_pos, MIN (end, base + 1)); -+ - new_pos--; - } - } else { -@@ -1550,7 +1522,7 @@ - { - new_reph_pos = base; - while (new_reph_pos < end && -- !( FLAG (info[new_reph_pos + 1].indic_position()) & (FLAG (POS_POST_C) | FLAG (POS_AFTER_POST) | FLAG (POS_SMVD)))) -+ !( FLAG_SAFE (info[new_reph_pos + 1].indic_position()) & (FLAG (POS_POST_C) | FLAG (POS_AFTER_POST) | FLAG (POS_SMVD)))) - new_reph_pos++; - if (new_reph_pos < end) - goto reph_move; -@@ -1606,12 +1578,12 @@ - - reph_move: - { -- buffer->merge_clusters (start, new_reph_pos + 1); -- - /* Move */ -+ buffer->merge_clusters (start, new_reph_pos + 1); - hb_glyph_info_t reph = info[start]; - memmove (&info[start], &info[start + 1], (new_reph_pos - start) * sizeof (info[0])); - info[new_reph_pos] = reph; -+ - if (start < base && base <= new_reph_pos) - base--; - } -@@ -1666,8 +1638,8 @@ - if (new_pos > start && info[new_pos - 1].indic_category() == OT_M) - { - unsigned int old_pos = i; -- for (unsigned int i = base + 1; i < old_pos; i++) -- if (info[i].indic_category() == OT_M) -+ for (unsigned int j = base + 1; j < old_pos; j++) -+ if (info[j].indic_category() == OT_M) - { - new_pos--; - break; -@@ -1684,10 +1656,12 @@ - - { - unsigned int old_pos = i; -+ - buffer->merge_clusters (new_pos, old_pos + 1); - hb_glyph_info_t tmp = info[old_pos]; - memmove (&info[new_pos + 1], &info[new_pos], (old_pos - new_pos) * sizeof (info[0])); - info[new_pos] = tmp; -+ - if (new_pos <= base && base < old_pos) - base++; - } -@@ -1701,7 +1675,7 @@ - /* Apply 'init' to the Left Matra if it's a word start. */ - if (info[start].indic_position () == POS_PRE_M && - (!start || -- !(FLAG (_hb_glyph_info_get_general_category (&info[start - 1])) & -+ !(FLAG_SAFE (_hb_glyph_info_get_general_category (&info[start - 1])) & - FLAG_RANGE (HB_UNICODE_GENERAL_CATEGORY_FORMAT, HB_UNICODE_GENERAL_CATEGORY_NON_SPACING_MARK)))) - info[start].mask |= indic_plan->mask_array[INIT]; - -@@ -1737,16 +1711,8 @@ - unsigned int count = buffer->len; - if (unlikely (!count)) return; - -- hb_glyph_info_t *info = buffer->info; -- unsigned int last = 0; -- unsigned int last_syllable = info[0].syllable(); -- for (unsigned int i = 1; i < count; i++) -- if (last_syllable != info[i].syllable()) { -- final_reordering_syllable (plan, buffer, last, i); -- last = i; -- last_syllable = info[last].syllable(); -- } -- final_reordering_syllable (plan, buffer, last, count); -+ foreach_syllable (buffer, start, end) -+ final_reordering_syllable (plan, buffer, start, end); - - HB_BUFFER_DEALLOCATE_VAR (buffer, indic_category); - HB_BUFFER_DEALLOCATE_VAR (buffer, indic_position); -@@ -1847,7 +1813,7 @@ - } - } - -- return c->unicode->decompose (ab, a, b); -+ return (bool) c->unicode->decompose (ab, a, b); - } - - static bool -@@ -1863,7 +1829,7 @@ - /* Composition-exclusion exceptions that we want to recompose. */ - if (a == 0x09AFu && b == 0x09BCu) { *ab = 0x09DFu; return true; } - -- return c->unicode->compose (a, b, ab); -+ return (bool) c->unicode->compose (a, b, ab); - } - - -@@ -1875,6 +1841,7 @@ - data_create_indic, - data_destroy_indic, - NULL, /* preprocess_text */ -+ NULL, /* postprocess_glyphs */ - HB_OT_SHAPE_NORMALIZATION_MODE_COMPOSED_DIACRITICS_NO_SHORT_CIRCUIT, - decompose_indic, - compose_indic, -diff -uN gfx/harfbuzz/src_old/hb-ot-shape-complex-indic-machine.hh gfx/harfbuzz/src/hb-ot-shape-complex-indic-machine.hh ---- gfx/harfbuzz/src_old/hb-ot-shape-complex-indic-machine.hh 2016-05-10 22:26:55.000000000 +0200 -+++ gfx/harfbuzz/src/hb-ot-shape-complex-indic-machine.hh 2016-06-05 23:49:50.772854137 +0200 -@@ -1,5 +1,5 @@ - --#line 1 "../../src/hb-ot-shape-complex-indic-machine.rl" -+#line 1 "hb-ot-shape-complex-indic-machine.rl" - /* - * Copyright © 2011,2012 Google, Inc. - * -@@ -32,1281 +32,1304 @@ - #include "hb-private.hh" - - --#line 36 "hb-ot-shape-complex-indic-machine.hh.tmp" -+#line 36 "hb-ot-shape-complex-indic-machine.hh" - static const unsigned char _indic_syllable_machine_trans_keys[] = { -- 1u, 16u, 13u, 13u, 5u, 7u, 5u, 7u, 7u, 7u, 5u, 7u, 5u, 7u, 7u, 7u, -- 5u, 7u, 5u, 7u, 7u, 7u, 5u, 7u, 5u, 7u, 7u, 7u, 4u, 4u, 6u, 6u, -- 16u, 16u, 4u, 7u, 6u, 6u, 16u, 16u, 4u, 7u, 6u, 6u, 16u, 16u, 4u, 7u, -- 6u, 6u, 16u, 16u, 4u, 14u, 4u, 14u, 4u, 14u, 4u, 14u, 4u, 14u, 4u, 14u, -- 4u, 14u, 4u, 14u, 4u, 14u, 4u, 14u, 1u, 16u, 13u, 13u, 5u, 7u, 5u, 7u, -- 7u, 7u, 5u, 7u, 5u, 7u, 7u, 7u, 5u, 7u, 5u, 7u, 7u, 7u, 5u, 7u, -- 5u, 7u, 7u, 7u, 4u, 4u, 6u, 6u, 16u, 16u, 4u, 7u, 6u, 6u, 16u, 16u, -- 4u, 7u, 6u, 6u, 16u, 16u, 4u, 7u, 6u, 6u, 16u, 16u, 4u, 14u, 4u, 14u, -+ 8u, 8u, 1u, 16u, 8u, 13u, 5u, 8u, 5u, 7u, 7u, 7u, 5u, 8u, 5u, 7u, -+ 7u, 7u, 5u, 8u, 5u, 7u, 7u, 7u, 5u, 8u, 5u, 7u, 7u, 7u, 4u, 8u, -+ 6u, 6u, 16u, 16u, 4u, 8u, 6u, 6u, 16u, 16u, 4u, 8u, 6u, 6u, 16u, 16u, -+ 4u, 8u, 6u, 6u, 16u, 16u, 4u, 14u, 4u, 14u, 4u, 14u, 4u, 14u, 4u, 14u, -+ 4u, 14u, 4u, 14u, 4u, 14u, 4u, 14u, 4u, 14u, 8u, 8u, 1u, 16u, 8u, 13u, -+ 5u, 8u, 5u, 7u, 7u, 7u, 5u, 8u, 5u, 7u, 7u, 7u, 5u, 8u, 5u, 7u, -+ 7u, 7u, 5u, 8u, 5u, 7u, 7u, 7u, 4u, 8u, 6u, 6u, 16u, 16u, 4u, 8u, -+ 6u, 6u, 16u, 16u, 4u, 8u, 6u, 6u, 16u, 16u, 4u, 8u, 6u, 6u, 16u, 16u, - 4u, 14u, 4u, 14u, 4u, 14u, 4u, 14u, 4u, 14u, 4u, 14u, 4u, 14u, 4u, 14u, -- 1u, 16u, 13u, 13u, 5u, 7u, 5u, 7u, 7u, 7u, 5u, 7u, 5u, 7u, 7u, 7u, -- 5u, 7u, 5u, 7u, 7u, 7u, 5u, 7u, 5u, 7u, 7u, 7u, 4u, 4u, 6u, 6u, -- 16u, 16u, 4u, 7u, 6u, 6u, 16u, 16u, 4u, 7u, 6u, 6u, 16u, 16u, 4u, 7u, -- 6u, 6u, 16u, 16u, 4u, 14u, 4u, 14u, 4u, 14u, 4u, 14u, 4u, 14u, 4u, 14u, -- 4u, 14u, 4u, 14u, 4u, 14u, 1u, 16u, 13u, 13u, 5u, 7u, 5u, 7u, 7u, 7u, -- 5u, 7u, 5u, 7u, 7u, 7u, 5u, 7u, 5u, 7u, 7u, 7u, 5u, 7u, 5u, 7u, -- 7u, 7u, 4u, 4u, 6u, 6u, 16u, 16u, 4u, 7u, 6u, 6u, 16u, 16u, 4u, 7u, -- 6u, 6u, 16u, 16u, 4u, 7u, 6u, 6u, 16u, 16u, 4u, 14u, 4u, 14u, 4u, 14u, -- 4u, 14u, 4u, 14u, 4u, 14u, 4u, 14u, 4u, 14u, 4u, 14u, 4u, 14u, 4u, 14u, -- 4u, 14u, 5u, 7u, 5u, 7u, 5u, 7u, 5u, 7u, 7u, 7u, 5u, 7u, 5u, 7u, -- 7u, 7u, 5u, 7u, 5u, 7u, 7u, 7u, 1u, 16u, 13u, 13u, 4u, 4u, 6u, 6u, -- 16u, 16u, 4u, 7u, 6u, 6u, 16u, 16u, 4u, 7u, 6u, 6u, 16u, 16u, 4u, 7u, -- 6u, 6u, 16u, 16u, 1u, 31u, 3u, 31u, 3u, 31u, 4u, 31u, 1u, 16u, 3u, 31u, -+ 4u, 14u, 4u, 14u, 8u, 8u, 1u, 16u, 8u, 13u, 5u, 8u, 5u, 7u, 7u, 7u, -+ 5u, 8u, 5u, 7u, 7u, 7u, 5u, 8u, 5u, 7u, 7u, 7u, 5u, 8u, 5u, 7u, -+ 7u, 7u, 4u, 8u, 6u, 6u, 16u, 16u, 4u, 8u, 6u, 6u, 16u, 16u, 4u, 8u, -+ 6u, 6u, 16u, 16u, 4u, 8u, 6u, 6u, 16u, 16u, 4u, 14u, 4u, 14u, 4u, 14u, -+ 4u, 14u, 4u, 14u, 4u, 14u, 4u, 14u, 4u, 14u, 4u, 14u, 8u, 8u, 1u, 16u, -+ 8u, 13u, 5u, 8u, 5u, 7u, 7u, 7u, 5u, 8u, 5u, 7u, 7u, 7u, 5u, 8u, -+ 5u, 7u, 7u, 7u, 5u, 8u, 5u, 7u, 7u, 7u, 4u, 8u, 6u, 6u, 16u, 16u, -+ 4u, 8u, 6u, 6u, 16u, 16u, 4u, 8u, 6u, 6u, 16u, 16u, 4u, 8u, 6u, 6u, -+ 16u, 16u, 4u, 14u, 4u, 14u, 4u, 14u, 4u, 14u, 4u, 14u, 4u, 14u, 4u, 14u, -+ 4u, 14u, 4u, 14u, 4u, 14u, 4u, 14u, 5u, 8u, 4u, 14u, 4u, 14u, 5u, 8u, -+ 5u, 7u, 5u, 8u, 5u, 7u, 7u, 7u, 5u, 8u, 5u, 7u, 7u, 7u, 5u, 8u, -+ 5u, 7u, 7u, 7u, 8u, 8u, 1u, 16u, 8u, 13u, 4u, 8u, 6u, 6u, 16u, 16u, -+ 4u, 8u, 6u, 6u, 16u, 16u, 4u, 8u, 6u, 6u, 16u, 16u, 4u, 8u, 6u, 6u, -+ 16u, 16u, 8u, 8u, 1u, 31u, 3u, 31u, 3u, 31u, 4u, 31u, 1u, 16u, 3u, 31u, - 3u, 31u, 4u, 31u, 1u, 16u, 3u, 31u, 3u, 31u, 4u, 31u, 1u, 16u, 3u, 31u, -- 3u, 31u, 4u, 31u, 1u, 16u, 3u, 31u, 3u, 31u, 4u, 31u, 5u, 14u, 8u, 14u, -+ 3u, 31u, 4u, 31u, 1u, 16u, 3u, 31u, 3u, 31u, 4u, 31u, 5u, 14u, 5u, 14u, - 5u, 10u, 9u, 10u, 9u, 9u, 9u, 10u, 9u, 10u, 9u, 9u, 5u, 10u, 3u, 13u, -- 3u, 10u, 8u, 10u, 3u, 10u, 3u, 13u, 3u, 14u, 3u, 14u, 4u, 14u, 5u, 14u, -+ 3u, 10u, 5u, 10u, 3u, 10u, 3u, 13u, 3u, 14u, 3u, 14u, 4u, 14u, 5u, 14u, - 3u, 14u, 4u, 14u, 5u, 14u, 3u, 14u, 4u, 14u, 5u, 14u, 3u, 14u, 4u, 14u, -- 6u, 14u, 3u, 14u, 1u, 16u, 4u, 31u, 4u, 14u, 3u, 31u, 3u, 31u, 1u, 16u, -+ 5u, 14u, 3u, 14u, 1u, 16u, 4u, 31u, 4u, 14u, 3u, 31u, 3u, 31u, 1u, 16u, - 1u, 16u, 1u, 16u, 1u, 16u, 1u, 16u, 3u, 31u, 3u, 31u, 1u, 16u, 1u, 16u, - 1u, 16u, 1u, 16u, 1u, 16u, 3u, 31u, 3u, 31u, 1u, 16u, 1u, 16u, 1u, 16u, - 1u, 16u, 1u, 16u, 3u, 31u, 3u, 31u, 1u, 16u, 1u, 16u, 1u, 16u, 1u, 16u, - 1u, 16u, 3u, 31u, 3u, 31u, 3u, 31u, 3u, 31u, 4u, 31u, 1u, 16u, 3u, 31u, - 3u, 31u, 4u, 31u, 1u, 16u, 3u, 31u, 3u, 31u, 4u, 31u, 1u, 16u, 3u, 31u, -- 3u, 31u, 4u, 31u, 1u, 16u, 3u, 31u, 3u, 31u, 4u, 31u, 5u, 14u, 8u, 14u, -+ 3u, 31u, 4u, 31u, 1u, 16u, 3u, 31u, 3u, 31u, 4u, 31u, 5u, 14u, 5u, 14u, - 5u, 10u, 9u, 10u, 9u, 9u, 9u, 10u, 9u, 10u, 9u, 9u, 5u, 10u, 3u, 13u, -- 3u, 10u, 8u, 10u, 3u, 10u, 3u, 13u, 3u, 14u, 3u, 14u, 4u, 14u, 5u, 14u, -+ 3u, 10u, 5u, 10u, 3u, 10u, 3u, 13u, 3u, 14u, 3u, 14u, 4u, 14u, 5u, 14u, - 3u, 14u, 4u, 14u, 5u, 14u, 3u, 14u, 4u, 14u, 5u, 14u, 3u, 14u, 4u, 14u, -- 6u, 14u, 3u, 14u, 1u, 16u, 4u, 31u, 4u, 14u, 3u, 31u, 3u, 31u, 1u, 16u, -+ 5u, 14u, 3u, 14u, 1u, 16u, 4u, 31u, 4u, 14u, 3u, 31u, 3u, 31u, 1u, 16u, - 1u, 16u, 1u, 16u, 1u, 16u, 1u, 16u, 3u, 31u, 3u, 31u, 1u, 16u, 1u, 16u, - 1u, 16u, 1u, 16u, 1u, 16u, 3u, 31u, 3u, 31u, 1u, 16u, 1u, 16u, 1u, 16u, - 1u, 16u, 1u, 16u, 3u, 31u, 3u, 31u, 1u, 16u, 1u, 16u, 1u, 16u, 1u, 16u, - 4u, 14u, 1u, 16u, 3u, 31u, 3u, 31u, 4u, 31u, 1u, 16u, 3u, 31u, 3u, 31u, - 4u, 31u, 1u, 16u, 3u, 31u, 3u, 31u, 4u, 31u, 1u, 16u, 3u, 31u, 3u, 31u, -- 4u, 31u, 1u, 16u, 3u, 31u, 3u, 31u, 4u, 31u, 5u, 14u, 8u, 14u, 5u, 10u, -+ 4u, 31u, 1u, 16u, 3u, 31u, 3u, 31u, 4u, 31u, 5u, 14u, 5u, 14u, 5u, 10u, - 9u, 10u, 9u, 9u, 9u, 10u, 9u, 10u, 9u, 9u, 5u, 10u, 3u, 13u, 3u, 10u, -- 8u, 10u, 3u, 10u, 3u, 13u, 3u, 14u, 3u, 14u, 4u, 14u, 5u, 14u, 3u, 14u, -- 4u, 14u, 5u, 14u, 3u, 14u, 4u, 14u, 5u, 14u, 3u, 14u, 4u, 14u, 6u, 14u, -+ 5u, 10u, 3u, 10u, 3u, 13u, 3u, 14u, 3u, 14u, 4u, 14u, 5u, 14u, 3u, 14u, -+ 4u, 14u, 5u, 14u, 3u, 14u, 4u, 14u, 5u, 14u, 3u, 14u, 4u, 14u, 5u, 14u, - 3u, 14u, 1u, 16u, 4u, 31u, 4u, 14u, 3u, 31u, 3u, 31u, 1u, 16u, 1u, 16u, - 1u, 16u, 1u, 16u, 1u, 16u, 3u, 31u, 3u, 31u, 1u, 16u, 1u, 16u, 1u, 16u, - 1u, 16u, 1u, 16u, 3u, 31u, 3u, 31u, 1u, 16u, 1u, 16u, 1u, 16u, 1u, 16u, - 1u, 16u, 3u, 31u, 3u, 31u, 1u, 16u, 1u, 16u, 1u, 16u, 1u, 16u, 1u, 16u, - 4u, 14u, 3u, 31u, 4u, 14u, 3u, 31u, 3u, 31u, 4u, 31u, 1u, 16u, 3u, 31u, - 3u, 31u, 4u, 31u, 1u, 16u, 3u, 31u, 3u, 31u, 4u, 31u, 1u, 16u, 3u, 31u, -- 3u, 31u, 4u, 31u, 1u, 16u, 3u, 31u, 3u, 31u, 4u, 31u, 5u, 14u, 8u, 14u, -+ 3u, 31u, 4u, 31u, 1u, 16u, 3u, 31u, 3u, 31u, 4u, 31u, 5u, 14u, 5u, 14u, - 5u, 10u, 9u, 10u, 9u, 9u, 9u, 10u, 9u, 10u, 9u, 9u, 5u, 10u, 3u, 13u, -- 3u, 10u, 8u, 10u, 3u, 10u, 3u, 13u, 3u, 14u, 3u, 14u, 4u, 14u, 5u, 14u, -+ 3u, 10u, 5u, 10u, 3u, 10u, 3u, 13u, 3u, 14u, 3u, 14u, 4u, 14u, 5u, 14u, - 3u, 14u, 4u, 14u, 5u, 14u, 3u, 14u, 4u, 14u, 5u, 14u, 3u, 14u, 4u, 14u, -- 6u, 14u, 3u, 14u, 1u, 16u, 4u, 31u, 4u, 14u, 3u, 31u, 3u, 31u, 1u, 16u, -+ 5u, 14u, 3u, 14u, 1u, 16u, 4u, 31u, 4u, 14u, 3u, 31u, 3u, 31u, 1u, 16u, - 1u, 16u, 1u, 16u, 1u, 16u, 1u, 16u, 3u, 31u, 3u, 31u, 1u, 16u, 1u, 16u, - 1u, 16u, 1u, 16u, 1u, 16u, 3u, 31u, 3u, 31u, 1u, 16u, 1u, 16u, 1u, 16u, - 1u, 16u, 1u, 16u, 3u, 31u, 3u, 31u, 1u, 16u, 1u, 16u, 1u, 16u, 1u, 16u, -- 1u, 16u, 3u, 31u, 1u, 31u, 3u, 31u, 1u, 31u, 4u, 14u, 1u, 16u, 3u, 31u, -- 3u, 31u, 4u, 31u, 5u, 10u, 9u, 10u, 9u, 9u, 9u, 10u, 9u, 10u, 9u, 9u, -- 5u, 10u, 3u, 31u, 3u, 31u, 1u, 16u, 3u, 14u, 4u, 14u, 5u, 14u, 3u, 14u, -- 4u, 14u, 5u, 14u, 3u, 14u, 4u, 14u, 5u, 14u, 3u, 14u, 4u, 14u, 8u, 14u, -- 3u, 13u, 3u, 10u, 8u, 10u, 3u, 10u, 3u, 13u, 1u, 16u, 3u, 10u, 8u, 10u, -+ 1u, 16u, 3u, 31u, 1u, 31u, 3u, 31u, 1u, 31u, 4u, 14u, 5u, 10u, 9u, 10u, -+ 9u, 9u, 9u, 10u, 9u, 10u, 9u, 9u, 5u, 10u, 1u, 16u, 3u, 31u, 3u, 31u, -+ 4u, 31u, 3u, 31u, 3u, 31u, 1u, 16u, 3u, 14u, 4u, 14u, 5u, 14u, 3u, 14u, -+ 4u, 14u, 5u, 14u, 3u, 14u, 4u, 14u, 5u, 14u, 3u, 14u, 4u, 14u, 5u, 14u, -+ 3u, 13u, 3u, 10u, 5u, 10u, 3u, 10u, 3u, 13u, 1u, 16u, 3u, 10u, 5u, 10u, - 5u, 10u, 9u, 10u, 9u, 9u, 9u, 10u, 9u, 10u, 9u, 9u, 5u, 10u, 0 - }; - - static const char _indic_syllable_machine_key_spans[] = { -- 16, 1, 3, 3, 1, 3, 3, 1, -- 3, 3, 1, 3, 3, 1, 1, 1, -- 1, 4, 1, 1, 4, 1, 1, 4, -- 1, 1, 11, 11, 11, 11, 11, 11, -- 11, 11, 11, 11, 16, 1, 3, 3, -- 1, 3, 3, 1, 3, 3, 1, 3, -- 3, 1, 1, 1, 1, 4, 1, 1, -- 4, 1, 1, 4, 1, 1, 11, 11, -- 11, 11, 11, 11, 11, 11, 11, 11, -- 16, 1, 3, 3, 1, 3, 3, 1, -- 3, 3, 1, 3, 3, 1, 1, 1, -- 1, 4, 1, 1, 4, 1, 1, 4, -- 1, 1, 11, 11, 11, 11, 11, 11, -- 11, 11, 11, 16, 1, 3, 3, 1, -- 3, 3, 1, 3, 3, 1, 3, 3, -- 1, 1, 1, 1, 4, 1, 1, 4, -- 1, 1, 4, 1, 1, 11, 11, 11, -+ 1, 16, 6, 4, 3, 1, 4, 3, -+ 1, 4, 3, 1, 4, 3, 1, 5, -+ 1, 1, 5, 1, 1, 5, 1, 1, -+ 5, 1, 1, 11, 11, 11, 11, 11, -+ 11, 11, 11, 11, 11, 1, 16, 6, -+ 4, 3, 1, 4, 3, 1, 4, 3, -+ 1, 4, 3, 1, 5, 1, 1, 5, -+ 1, 1, 5, 1, 1, 5, 1, 1, - 11, 11, 11, 11, 11, 11, 11, 11, -- 11, 3, 3, 3, 3, 1, 3, 3, -- 1, 3, 3, 1, 16, 1, 1, 1, -- 1, 4, 1, 1, 4, 1, 1, 4, -+ 11, 11, 1, 16, 6, 4, 3, 1, -+ 4, 3, 1, 4, 3, 1, 4, 3, -+ 1, 5, 1, 1, 5, 1, 1, 5, -+ 1, 1, 5, 1, 1, 11, 11, 11, -+ 11, 11, 11, 11, 11, 11, 1, 16, -+ 6, 4, 3, 1, 4, 3, 1, 4, -+ 3, 1, 4, 3, 1, 5, 1, 1, -+ 5, 1, 1, 5, 1, 1, 5, 1, -+ 1, 11, 11, 11, 11, 11, 11, 11, -+ 11, 11, 11, 11, 4, 11, 11, 4, -+ 3, 4, 3, 1, 4, 3, 1, 4, -+ 3, 1, 1, 16, 6, 5, 1, 1, -+ 5, 1, 1, 5, 1, 1, 5, 1, - 1, 1, 31, 29, 29, 28, 16, 29, - 29, 28, 16, 29, 29, 28, 16, 29, -- 29, 28, 16, 29, 29, 28, 10, 7, -+ 29, 28, 16, 29, 29, 28, 10, 10, - 6, 2, 1, 2, 2, 1, 6, 11, -- 8, 3, 8, 11, 12, 12, 11, 10, -+ 8, 6, 8, 11, 12, 12, 11, 10, - 12, 11, 10, 12, 11, 10, 12, 11, -- 9, 12, 16, 28, 11, 29, 29, 16, -+ 10, 12, 16, 28, 11, 29, 29, 16, - 16, 16, 16, 16, 29, 29, 16, 16, - 16, 16, 16, 29, 29, 16, 16, 16, - 16, 16, 29, 29, 16, 16, 16, 16, - 16, 29, 29, 29, 29, 28, 16, 29, - 29, 28, 16, 29, 29, 28, 16, 29, -- 29, 28, 16, 29, 29, 28, 10, 7, -+ 29, 28, 16, 29, 29, 28, 10, 10, - 6, 2, 1, 2, 2, 1, 6, 11, -- 8, 3, 8, 11, 12, 12, 11, 10, -+ 8, 6, 8, 11, 12, 12, 11, 10, - 12, 11, 10, 12, 11, 10, 12, 11, -- 9, 12, 16, 28, 11, 29, 29, 16, -+ 10, 12, 16, 28, 11, 29, 29, 16, - 16, 16, 16, 16, 29, 29, 16, 16, - 16, 16, 16, 29, 29, 16, 16, 16, - 16, 16, 29, 29, 16, 16, 16, 16, - 11, 16, 29, 29, 28, 16, 29, 29, - 28, 16, 29, 29, 28, 16, 29, 29, -- 28, 16, 29, 29, 28, 10, 7, 6, -+ 28, 16, 29, 29, 28, 10, 10, 6, - 2, 1, 2, 2, 1, 6, 11, 8, -- 3, 8, 11, 12, 12, 11, 10, 12, -- 11, 10, 12, 11, 10, 12, 11, 9, -+ 6, 8, 11, 12, 12, 11, 10, 12, -+ 11, 10, 12, 11, 10, 12, 11, 10, - 12, 16, 28, 11, 29, 29, 16, 16, - 16, 16, 16, 29, 29, 16, 16, 16, - 16, 16, 29, 29, 16, 16, 16, 16, - 16, 29, 29, 16, 16, 16, 16, 16, - 11, 29, 11, 29, 29, 28, 16, 29, - 29, 28, 16, 29, 29, 28, 16, 29, -- 29, 28, 16, 29, 29, 28, 10, 7, -+ 29, 28, 16, 29, 29, 28, 10, 10, - 6, 2, 1, 2, 2, 1, 6, 11, -- 8, 3, 8, 11, 12, 12, 11, 10, -+ 8, 6, 8, 11, 12, 12, 11, 10, - 12, 11, 10, 12, 11, 10, 12, 11, -- 9, 12, 16, 28, 11, 29, 29, 16, -+ 10, 12, 16, 28, 11, 29, 29, 16, - 16, 16, 16, 16, 29, 29, 16, 16, - 16, 16, 16, 29, 29, 16, 16, 16, - 16, 16, 29, 29, 16, 16, 16, 16, -- 16, 29, 31, 29, 31, 11, 16, 29, -- 29, 28, 6, 2, 1, 2, 2, 1, -- 6, 29, 29, 16, 12, 11, 10, 12, -- 11, 10, 12, 11, 10, 12, 11, 7, -- 11, 8, 3, 8, 11, 16, 8, 3, -+ 16, 29, 31, 29, 31, 11, 6, 2, -+ 1, 2, 2, 1, 6, 16, 29, 29, -+ 28, 29, 29, 16, 12, 11, 10, 12, -+ 11, 10, 12, 11, 10, 12, 11, 10, -+ 11, 8, 6, 8, 11, 16, 8, 6, - 6, 2, 1, 2, 2, 1, 6 - }; - - static const short _indic_syllable_machine_index_offsets[] = { -- 0, 17, 19, 23, 27, 29, 33, 37, -- 39, 43, 47, 49, 53, 57, 59, 61, -- 63, 65, 70, 72, 74, 79, 81, 83, -- 88, 90, 92, 104, 116, 128, 140, 152, -- 164, 176, 188, 200, 212, 229, 231, 235, -- 239, 241, 245, 249, 251, 255, 259, 261, -- 265, 269, 271, 273, 275, 277, 282, 284, -- 286, 291, 293, 295, 300, 302, 304, 316, -- 328, 340, 352, 364, 376, 388, 400, 412, -- 424, 441, 443, 447, 451, 453, 457, 461, -- 463, 467, 471, 473, 477, 481, 483, 485, -- 487, 489, 494, 496, 498, 503, 505, 507, -- 512, 514, 516, 528, 540, 552, 564, 576, -- 588, 600, 612, 624, 641, 643, 647, 651, -- 653, 657, 661, 663, 667, 671, 673, 677, -- 681, 683, 685, 687, 689, 694, 696, 698, -- 703, 705, 707, 712, 714, 716, 728, 740, -- 752, 764, 776, 788, 800, 812, 824, 836, -- 848, 860, 864, 868, 872, 876, 878, 882, -- 886, 888, 892, 896, 898, 915, 917, 919, -- 921, 923, 928, 930, 932, 937, 939, 941, -- 946, 948, 950, 982, 1012, 1042, 1071, 1088, -- 1118, 1148, 1177, 1194, 1224, 1254, 1283, 1300, -- 1330, 1360, 1389, 1406, 1436, 1466, 1495, 1506, -- 1514, 1521, 1524, 1526, 1529, 1532, 1534, 1541, -- 1553, 1562, 1566, 1575, 1587, 1600, 1613, 1625, -- 1636, 1649, 1661, 1672, 1685, 1697, 1708, 1721, -- 1733, 1743, 1756, 1773, 1802, 1814, 1844, 1874, -- 1891, 1908, 1925, 1942, 1959, 1989, 2019, 2036, -- 2053, 2070, 2087, 2104, 2134, 2164, 2181, 2198, -- 2215, 2232, 2249, 2279, 2309, 2326, 2343, 2360, -- 2377, 2394, 2424, 2454, 2484, 2514, 2543, 2560, -- 2590, 2620, 2649, 2666, 2696, 2726, 2755, 2772, -- 2802, 2832, 2861, 2878, 2908, 2938, 2967, 2978, -- 2986, 2993, 2996, 2998, 3001, 3004, 3006, 3013, -- 3025, 3034, 3038, 3047, 3059, 3072, 3085, 3097, -- 3108, 3121, 3133, 3144, 3157, 3169, 3180, 3193, -- 3205, 3215, 3228, 3245, 3274, 3286, 3316, 3346, -- 3363, 3380, 3397, 3414, 3431, 3461, 3491, 3508, -- 3525, 3542, 3559, 3576, 3606, 3636, 3653, 3670, -- 3687, 3704, 3721, 3751, 3781, 3798, 3815, 3832, -- 3849, 3861, 3878, 3908, 3938, 3967, 3984, 4014, -- 4044, 4073, 4090, 4120, 4150, 4179, 4196, 4226, -- 4256, 4285, 4302, 4332, 4362, 4391, 4402, 4410, -- 4417, 4420, 4422, 4425, 4428, 4430, 4437, 4449, -- 4458, 4462, 4471, 4483, 4496, 4509, 4521, 4532, -- 4545, 4557, 4568, 4581, 4593, 4604, 4617, 4629, -- 4639, 4652, 4669, 4698, 4710, 4740, 4770, 4787, -- 4804, 4821, 4838, 4855, 4885, 4915, 4932, 4949, -- 4966, 4983, 5000, 5030, 5060, 5077, 5094, 5111, -- 5128, 5145, 5175, 5205, 5222, 5239, 5256, 5273, -- 5290, 5302, 5332, 5344, 5374, 5404, 5433, 5450, -- 5480, 5510, 5539, 5556, 5586, 5616, 5645, 5662, -- 5692, 5722, 5751, 5768, 5798, 5828, 5857, 5868, -- 5876, 5883, 5886, 5888, 5891, 5894, 5896, 5903, -- 5915, 5924, 5928, 5937, 5949, 5962, 5975, 5987, -- 5998, 6011, 6023, 6034, 6047, 6059, 6070, 6083, -- 6095, 6105, 6118, 6135, 6164, 6176, 6206, 6236, -- 6253, 6270, 6287, 6304, 6321, 6351, 6381, 6398, -- 6415, 6432, 6449, 6466, 6496, 6526, 6543, 6560, -- 6577, 6594, 6611, 6641, 6671, 6688, 6705, 6722, -- 6739, 6756, 6786, 6818, 6848, 6880, 6892, 6909, -- 6939, 6969, 6998, 7005, 7008, 7010, 7013, 7016, -- 7018, 7025, 7055, 7085, 7102, 7115, 7127, 7138, -- 7151, 7163, 7174, 7187, 7199, 7210, 7223, 7235, -- 7243, 7255, 7264, 7268, 7277, 7289, 7306, 7315, -- 7319, 7326, 7329, 7331, 7334, 7337, 7339 -+ 0, 2, 19, 26, 31, 35, 37, 42, -+ 46, 48, 53, 57, 59, 64, 68, 70, -+ 76, 78, 80, 86, 88, 90, 96, 98, -+ 100, 106, 108, 110, 122, 134, 146, 158, -+ 170, 182, 194, 206, 218, 230, 232, 249, -+ 256, 261, 265, 267, 272, 276, 278, 283, -+ 287, 289, 294, 298, 300, 306, 308, 310, -+ 316, 318, 320, 326, 328, 330, 336, 338, -+ 340, 352, 364, 376, 388, 400, 412, 424, -+ 436, 448, 460, 462, 479, 486, 491, 495, -+ 497, 502, 506, 508, 513, 517, 519, 524, -+ 528, 530, 536, 538, 540, 546, 548, 550, -+ 556, 558, 560, 566, 568, 570, 582, 594, -+ 606, 618, 630, 642, 654, 666, 678, 680, -+ 697, 704, 709, 713, 715, 720, 724, 726, -+ 731, 735, 737, 742, 746, 748, 754, 756, -+ 758, 764, 766, 768, 774, 776, 778, 784, -+ 786, 788, 800, 812, 824, 836, 848, 860, -+ 872, 884, 896, 908, 920, 925, 937, 949, -+ 954, 958, 963, 967, 969, 974, 978, 980, -+ 985, 989, 991, 993, 1010, 1017, 1023, 1025, -+ 1027, 1033, 1035, 1037, 1043, 1045, 1047, 1053, -+ 1055, 1057, 1059, 1091, 1121, 1151, 1180, 1197, -+ 1227, 1257, 1286, 1303, 1333, 1363, 1392, 1409, -+ 1439, 1469, 1498, 1515, 1545, 1575, 1604, 1615, -+ 1626, 1633, 1636, 1638, 1641, 1644, 1646, 1653, -+ 1665, 1674, 1681, 1690, 1702, 1715, 1728, 1740, -+ 1751, 1764, 1776, 1787, 1800, 1812, 1823, 1836, -+ 1848, 1859, 1872, 1889, 1918, 1930, 1960, 1990, -+ 2007, 2024, 2041, 2058, 2075, 2105, 2135, 2152, -+ 2169, 2186, 2203, 2220, 2250, 2280, 2297, 2314, -+ 2331, 2348, 2365, 2395, 2425, 2442, 2459, 2476, -+ 2493, 2510, 2540, 2570, 2600, 2630, 2659, 2676, -+ 2706, 2736, 2765, 2782, 2812, 2842, 2871, 2888, -+ 2918, 2948, 2977, 2994, 3024, 3054, 3083, 3094, -+ 3105, 3112, 3115, 3117, 3120, 3123, 3125, 3132, -+ 3144, 3153, 3160, 3169, 3181, 3194, 3207, 3219, -+ 3230, 3243, 3255, 3266, 3279, 3291, 3302, 3315, -+ 3327, 3338, 3351, 3368, 3397, 3409, 3439, 3469, -+ 3486, 3503, 3520, 3537, 3554, 3584, 3614, 3631, -+ 3648, 3665, 3682, 3699, 3729, 3759, 3776, 3793, -+ 3810, 3827, 3844, 3874, 3904, 3921, 3938, 3955, -+ 3972, 3984, 4001, 4031, 4061, 4090, 4107, 4137, -+ 4167, 4196, 4213, 4243, 4273, 4302, 4319, 4349, -+ 4379, 4408, 4425, 4455, 4485, 4514, 4525, 4536, -+ 4543, 4546, 4548, 4551, 4554, 4556, 4563, 4575, -+ 4584, 4591, 4600, 4612, 4625, 4638, 4650, 4661, -+ 4674, 4686, 4697, 4710, 4722, 4733, 4746, 4758, -+ 4769, 4782, 4799, 4828, 4840, 4870, 4900, 4917, -+ 4934, 4951, 4968, 4985, 5015, 5045, 5062, 5079, -+ 5096, 5113, 5130, 5160, 5190, 5207, 5224, 5241, -+ 5258, 5275, 5305, 5335, 5352, 5369, 5386, 5403, -+ 5420, 5432, 5462, 5474, 5504, 5534, 5563, 5580, -+ 5610, 5640, 5669, 5686, 5716, 5746, 5775, 5792, -+ 5822, 5852, 5881, 5898, 5928, 5958, 5987, 5998, -+ 6009, 6016, 6019, 6021, 6024, 6027, 6029, 6036, -+ 6048, 6057, 6064, 6073, 6085, 6098, 6111, 6123, -+ 6134, 6147, 6159, 6170, 6183, 6195, 6206, 6219, -+ 6231, 6242, 6255, 6272, 6301, 6313, 6343, 6373, -+ 6390, 6407, 6424, 6441, 6458, 6488, 6518, 6535, -+ 6552, 6569, 6586, 6603, 6633, 6663, 6680, 6697, -+ 6714, 6731, 6748, 6778, 6808, 6825, 6842, 6859, -+ 6876, 6893, 6923, 6955, 6985, 7017, 7029, 7036, -+ 7039, 7041, 7044, 7047, 7049, 7056, 7073, 7103, -+ 7133, 7162, 7192, 7222, 7239, 7252, 7264, 7275, -+ 7288, 7300, 7311, 7324, 7336, 7347, 7360, 7372, -+ 7383, 7395, 7404, 7411, 7420, 7432, 7449, 7458, -+ 7465, 7472, 7475, 7477, 7480, 7483, 7485 - }; - - static const short _indic_syllable_machine_indicies[] = { -- 1, 2, 0, 0, 0, 0, 0, 0, -- 0, 0, 0, 0, 0, 0, 0, 1, -- 0, 3, 0, 4, 4, 5, 0, 6, -- 6, 5, 0, 5, 0, 7, 7, 8, -- 0, 9, 9, 8, 0, 8, 0, 10, -- 10, 11, 0, 12, 12, 11, 0, 11, -- 0, 13, 13, 14, 0, 15, 15, 14, -- 0, 14, 0, 16, 0, 17, 0, 18, -- 0, 19, 13, 13, 14, 0, 20, 0, -- 21, 0, 22, 10, 10, 11, 0, 23, -- 0, 24, 0, 25, 7, 7, 8, 0, -- 26, 0, 27, 0, 28, 4, 4, 5, -- 0, 0, 0, 0, 0, 0, 28, 0, -- 28, 4, 4, 5, 0, 0, 0, 0, -- 0, 29, 28, 0, 30, 4, 4, 5, -- 0, 0, 0, 0, 0, 0, 30, 0, -- 30, 4, 4, 5, 0, 0, 0, 0, -- 0, 31, 30, 0, 32, 4, 4, 5, -- 0, 0, 0, 0, 0, 0, 32, 0, -- 32, 4, 4, 5, 0, 0, 0, 0, -- 0, 33, 32, 0, 34, 4, 4, 5, -- 0, 0, 0, 0, 0, 0, 34, 0, -- 34, 4, 4, 5, 0, 0, 0, 0, -- 0, 35, 34, 0, 36, 4, 4, 5, -- 0, 0, 0, 0, 0, 0, 36, 0, -- 36, 4, 4, 5, 0, 0, 0, 0, -- 0, 37, 36, 0, 39, 40, 38, 38, -- 38, 38, 38, 38, 38, 38, 38, 38, -- 38, 38, 38, 39, 38, 41, 38, 42, -- 42, 43, 38, 44, 44, 43, 38, 43, -- 38, 45, 45, 46, 38, 47, 47, 46, -- 38, 46, 38, 48, 48, 49, 38, 50, -- 50, 49, 38, 49, 38, 51, 51, 52, -- 38, 53, 53, 52, 38, 52, 38, 54, -- 38, 55, 38, 56, 38, 57, 51, 51, -- 52, 38, 58, 38, 59, 38, 60, 48, -- 48, 49, 38, 61, 38, 62, 38, 63, -- 45, 45, 46, 38, 64, 38, 65, 38, -- 66, 42, 42, 43, 38, 38, 38, 38, -- 38, 38, 66, 38, 66, 42, 42, 43, -- 38, 38, 38, 38, 38, 67, 66, 38, -- 68, 42, 42, 43, 38, 38, 38, 38, -- 38, 38, 68, 38, 68, 42, 42, 43, -- 38, 38, 38, 38, 38, 69, 68, 38, -- 70, 42, 42, 43, 38, 38, 38, 38, -- 38, 38, 70, 38, 70, 42, 42, 43, -- 38, 38, 38, 38, 38, 71, 70, 38, -- 72, 42, 42, 43, 38, 38, 38, 38, -- 38, 38, 72, 38, 72, 42, 42, 43, -- 38, 38, 38, 38, 38, 73, 72, 38, -- 74, 42, 42, 43, 38, 38, 38, 38, -- 38, 38, 74, 38, 74, 42, 42, 43, -- 38, 38, 38, 38, 38, 75, 74, 38, -- 77, 78, 76, 76, 76, 76, 76, 76, -- 76, 76, 76, 76, 76, 76, 76, 77, -- 76, 79, 76, 80, 80, 81, 76, 83, -- 83, 81, 82, 81, 82, 84, 84, 85, -- 76, 86, 86, 85, 76, 85, 76, 87, -- 87, 88, 76, 89, 89, 88, 76, 88, -- 76, 90, 90, 91, 76, 92, 92, 91, -- 76, 91, 76, 93, 76, 94, 76, 95, -- 76, 96, 90, 90, 91, 76, 97, 76, -- 98, 76, 99, 87, 87, 88, 76, 100, -- 76, 101, 76, 102, 84, 84, 85, 76, -- 103, 76, 104, 76, 105, 80, 80, 81, -- 76, 76, 76, 76, 76, 76, 105, 76, -- 105, 80, 80, 81, 76, 76, 76, 76, -- 76, 106, 105, 76, 107, 80, 80, 81, -- 76, 76, 76, 76, 76, 76, 107, 76, -- 107, 80, 80, 81, 76, 76, 76, 76, -- 76, 108, 107, 76, 109, 80, 80, 81, -- 76, 76, 76, 76, 76, 76, 109, 76, -- 109, 80, 80, 81, 76, 76, 76, 76, -- 76, 110, 109, 76, 111, 80, 80, 81, -- 82, 82, 82, 82, 82, 82, 111, 82, -- 111, 80, 80, 81, 76, 76, 76, 76, -- 76, 112, 111, 76, 113, 80, 80, 81, -- 76, 76, 76, 76, 76, 76, 113, 76, -- 115, 116, 114, 114, 114, 114, 114, 114, -- 114, 114, 114, 114, 114, 114, 114, 115, -- 114, 117, 114, 118, 118, 119, 114, 120, -- 120, 119, 114, 119, 114, 121, 121, 122, -- 114, 123, 123, 122, 114, 122, 114, 124, -- 124, 125, 114, 126, 126, 125, 114, 125, -- 114, 127, 127, 128, 114, 129, 129, 128, -- 114, 128, 114, 130, 114, 131, 114, 132, -- 114, 133, 127, 127, 128, 114, 134, 114, -- 135, 114, 136, 124, 124, 125, 114, 137, -- 114, 138, 114, 139, 121, 121, 122, 114, -- 140, 114, 141, 114, 142, 118, 118, 119, -- 114, 114, 114, 114, 114, 114, 142, 114, -- 142, 118, 118, 119, 114, 114, 114, 114, -- 114, 143, 142, 114, 144, 118, 118, 119, -- 114, 114, 114, 114, 114, 114, 144, 114, -- 144, 118, 118, 119, 114, 114, 114, 114, -- 114, 145, 144, 114, 146, 118, 118, 119, -- 114, 114, 114, 114, 114, 114, 146, 114, -- 146, 118, 118, 119, 114, 114, 114, 114, -- 114, 147, 146, 114, 148, 118, 118, 119, -- 114, 114, 114, 114, 114, 114, 148, 114, -- 148, 118, 118, 119, 114, 114, 114, 114, -- 114, 149, 148, 114, 150, 118, 118, 119, -- 114, 114, 114, 114, 114, 114, 150, 114, -- 150, 118, 118, 119, 114, 114, 114, 114, -- 114, 151, 150, 114, 113, 80, 80, 81, -- 76, 76, 76, 76, 76, 152, 113, 76, -- 111, 80, 80, 81, 0, 0, 0, 0, -- 0, 153, 111, 0, 154, 154, 155, 0, -- 6, 6, 155, 0, 156, 156, 157, 0, -- 158, 158, 157, 0, 157, 0, 159, 159, -- 160, 0, 161, 161, 160, 0, 160, 0, -- 162, 162, 163, 0, 164, 164, 163, 0, -- 163, 0, 165, 166, 0, 0, 0, 0, -- 0, 0, 0, 0, 0, 0, 0, 0, -- 0, 165, 0, 167, 0, 168, 0, 169, -- 0, 170, 0, 171, 162, 162, 163, 0, -- 172, 0, 173, 0, 174, 159, 159, 160, -- 0, 175, 0, 176, 0, 177, 156, 156, -- 157, 0, 178, 0, 179, 0, 181, 182, -- 183, 184, 185, 186, 81, 187, 188, 189, -- 190, 190, 152, 191, 192, 193, 194, 195, -- 180, 180, 180, 180, 180, 180, 180, 180, -- 180, 180, 180, 180, 196, 180, 198, 199, -- 200, 201, 5, 202, 203, 204, 197, 197, -- 37, 205, 197, 197, 206, 197, 197, 197, -- 197, 197, 197, 197, 197, 197, 197, 197, -- 197, 197, 207, 197, 208, 199, 209, 209, -- 5, 202, 203, 204, 197, 197, 197, 205, -- 197, 197, 206, 197, 197, 197, 197, 197, -- 197, 197, 197, 197, 197, 197, 197, 197, -- 207, 197, 199, 209, 209, 5, 202, 203, -- 204, 197, 197, 197, 205, 197, 197, 206, -- 197, 197, 197, 197, 197, 197, 197, 197, -- 197, 197, 197, 197, 197, 207, 197, 210, -- 197, 197, 197, 18, 211, 197, 202, 203, -- 204, 197, 197, 197, 212, 197, 210, 197, -- 213, 214, 215, 216, 5, 202, 203, 204, -- 197, 197, 35, 217, 197, 197, 206, 197, -- 197, 197, 197, 197, 197, 197, 197, 197, -- 197, 197, 197, 197, 207, 197, 218, 214, -- 219, 219, 5, 202, 203, 204, 197, 197, -- 197, 217, 197, 197, 206, 197, 197, 197, -- 197, 197, 197, 197, 197, 197, 197, 197, -- 197, 197, 207, 197, 214, 219, 219, 5, -- 202, 203, 204, 197, 197, 197, 217, 197, -- 197, 206, 197, 197, 197, 197, 197, 197, -- 197, 197, 197, 197, 197, 197, 197, 207, -- 197, 220, 197, 197, 197, 18, 221, 197, -- 202, 203, 204, 197, 197, 197, 212, 197, -- 220, 197, 222, 223, 224, 225, 5, 202, -- 203, 204, 197, 197, 33, 226, 197, 197, -- 206, 197, 197, 197, 197, 197, 197, 197, -- 197, 197, 197, 197, 197, 197, 207, 197, -- 227, 223, 228, 228, 5, 202, 203, 204, -- 197, 197, 197, 226, 197, 197, 206, 197, -- 197, 197, 197, 197, 197, 197, 197, 197, -- 197, 197, 197, 197, 207, 197, 223, 228, -- 228, 5, 202, 203, 204, 197, 197, 197, -- 226, 197, 197, 206, 197, 197, 197, 197, -- 197, 197, 197, 197, 197, 197, 197, 197, -- 197, 207, 197, 229, 197, 197, 197, 18, -- 230, 197, 202, 203, 204, 197, 197, 197, -- 212, 197, 229, 197, 231, 232, 233, 234, -- 5, 202, 203, 204, 197, 197, 31, 235, -- 197, 197, 206, 197, 197, 197, 197, 197, -- 197, 197, 197, 197, 197, 197, 197, 197, -- 207, 197, 236, 232, 237, 237, 5, 202, -- 203, 204, 197, 197, 197, 235, 197, 197, -- 206, 197, 197, 197, 197, 197, 197, 197, -- 197, 197, 197, 197, 197, 197, 207, 197, -- 232, 237, 237, 5, 202, 203, 204, 197, -- 197, 197, 235, 197, 197, 206, 197, 197, -- 197, 197, 197, 197, 197, 197, 197, 197, -- 197, 197, 197, 207, 197, 238, 197, 197, -- 197, 18, 239, 197, 202, 203, 204, 197, -- 197, 197, 212, 197, 238, 197, 240, 241, -- 242, 243, 5, 202, 203, 204, 197, 197, -- 29, 244, 197, 197, 206, 197, 197, 197, -- 197, 197, 197, 197, 197, 197, 197, 197, -- 197, 197, 207, 197, 245, 241, 246, 246, -- 5, 202, 203, 204, 197, 197, 197, 244, -- 197, 197, 206, 197, 197, 197, 197, 197, -- 197, 197, 197, 197, 197, 197, 197, 197, -- 207, 197, 241, 246, 246, 5, 202, 203, -- 204, 197, 197, 197, 244, 197, 197, 206, -- 197, 197, 197, 197, 197, 197, 197, 197, -- 197, 197, 197, 197, 197, 207, 197, 18, -- 247, 197, 202, 203, 204, 197, 197, 197, -- 212, 197, 202, 203, 204, 197, 197, 197, -- 212, 197, 248, 197, 197, 249, 203, 204, -- 197, 203, 204, 197, 250, 197, 203, 251, -- 197, 203, 252, 197, 203, 197, 248, 197, -- 197, 197, 203, 204, 197, 253, 197, 254, -- 255, 197, 202, 203, 204, 197, 197, 3, -- 197, 2, 197, 197, 197, 197, 202, 203, -- 204, 197, 202, 203, 204, 197, 253, 197, -- 197, 197, 197, 202, 203, 204, 197, 253, -- 197, 254, 197, 197, 202, 203, 204, 197, -- 197, 3, 197, 18, 197, 256, 256, 5, -- 202, 203, 204, 197, 197, 197, 212, 197, -- 257, 27, 258, 259, 8, 202, 203, 204, -- 197, 197, 197, 212, 197, 27, 258, 259, -- 8, 202, 203, 204, 197, 197, 197, 212, -- 197, 258, 258, 8, 202, 203, 204, 197, -- 197, 197, 212, 197, 260, 24, 261, 262, -- 11, 202, 203, 204, 197, 197, 197, 212, -- 197, 24, 261, 262, 11, 202, 203, 204, -- 197, 197, 197, 212, 197, 261, 261, 11, -- 202, 203, 204, 197, 197, 197, 212, 197, -- 263, 21, 264, 265, 14, 202, 203, 204, -- 197, 197, 197, 212, 197, 21, 264, 265, -- 14, 202, 203, 204, 197, 197, 197, 212, -- 197, 264, 264, 14, 202, 203, 204, 197, -- 197, 197, 212, 197, 266, 18, 197, 267, -- 197, 202, 203, 204, 197, 197, 197, 212, -- 197, 18, 197, 267, 197, 202, 203, 204, -- 197, 197, 197, 212, 197, 268, 197, 202, -- 203, 204, 197, 197, 197, 212, 197, 18, -- 197, 197, 197, 197, 202, 203, 204, 197, -- 197, 197, 212, 197, 1, 2, 197, 197, -- 18, 247, 197, 202, 203, 204, 197, 197, -- 197, 212, 197, 1, 197, 241, 246, 246, -- 5, 202, 203, 204, 197, 197, 197, 244, -- 197, 197, 197, 197, 197, 197, 197, 197, -- 197, 197, 197, 197, 197, 197, 197, 197, -- 207, 197, 241, 246, 246, 5, 202, 203, -- 204, 197, 197, 197, 244, 197, 240, 241, -- 246, 246, 5, 202, 203, 204, 197, 197, -- 197, 244, 197, 197, 206, 197, 197, 197, -- 197, 197, 197, 197, 197, 197, 197, 197, -- 197, 197, 207, 197, 240, 241, 242, 246, -- 5, 202, 203, 204, 197, 197, 29, 244, -- 197, 197, 206, 197, 197, 197, 197, 197, -- 197, 197, 197, 197, 197, 197, 197, 197, -- 207, 197, 238, 197, 269, 197, 256, 256, -- 5, 202, 203, 204, 197, 197, 197, 212, -- 197, 238, 197, 238, 197, 197, 197, 197, -- 197, 197, 202, 203, 204, 197, 197, 197, -- 212, 197, 238, 197, 238, 197, 197, 197, -- 197, 270, 197, 202, 203, 204, 197, 197, -- 197, 212, 197, 238, 197, 238, 197, 269, -- 197, 197, 197, 197, 202, 203, 204, 197, -- 197, 197, 212, 197, 238, 197, 238, 2, -- 197, 197, 18, 239, 197, 202, 203, 204, -- 197, 197, 197, 212, 197, 238, 197, 231, -- 232, 237, 237, 5, 202, 203, 204, 197, -- 197, 197, 235, 197, 197, 206, 197, 197, -- 197, 197, 197, 197, 197, 197, 197, 197, -- 197, 197, 197, 207, 197, 231, 232, 233, -- 237, 5, 202, 203, 204, 197, 197, 31, -- 235, 197, 197, 206, 197, 197, 197, 197, -- 197, 197, 197, 197, 197, 197, 197, 197, -- 197, 207, 197, 229, 197, 271, 197, 256, -- 256, 5, 202, 203, 204, 197, 197, 197, -- 212, 197, 229, 197, 229, 197, 197, 197, -- 197, 197, 197, 202, 203, 204, 197, 197, -- 197, 212, 197, 229, 197, 229, 197, 197, -- 197, 197, 272, 197, 202, 203, 204, 197, -- 197, 197, 212, 197, 229, 197, 229, 197, -- 271, 197, 197, 197, 197, 202, 203, 204, -- 197, 197, 197, 212, 197, 229, 197, 229, -- 2, 197, 197, 18, 230, 197, 202, 203, -- 204, 197, 197, 197, 212, 197, 229, 197, -- 222, 223, 228, 228, 5, 202, 203, 204, -- 197, 197, 197, 226, 197, 197, 206, 197, -- 197, 197, 197, 197, 197, 197, 197, 197, -- 197, 197, 197, 197, 207, 197, 222, 223, -- 224, 228, 5, 202, 203, 204, 197, 197, -- 33, 226, 197, 197, 206, 197, 197, 197, -- 197, 197, 197, 197, 197, 197, 197, 197, -- 197, 197, 207, 197, 220, 197, 273, 197, -- 256, 256, 5, 202, 203, 204, 197, 197, -- 197, 212, 197, 220, 197, 220, 197, 197, -- 197, 197, 197, 197, 202, 203, 204, 197, -- 197, 197, 212, 197, 220, 197, 220, 197, -- 197, 197, 197, 274, 197, 202, 203, 204, -- 197, 197, 197, 212, 197, 220, 197, 220, -- 197, 273, 197, 197, 197, 197, 202, 203, -- 204, 197, 197, 197, 212, 197, 220, 197, -- 220, 2, 197, 197, 18, 221, 197, 202, -- 203, 204, 197, 197, 197, 212, 197, 220, -- 197, 213, 214, 219, 219, 5, 202, 203, -- 204, 197, 197, 197, 217, 197, 197, 206, -- 197, 197, 197, 197, 197, 197, 197, 197, -- 197, 197, 197, 197, 197, 207, 197, 213, -- 214, 215, 219, 5, 202, 203, 204, 197, -- 197, 35, 217, 197, 197, 206, 197, 197, -- 197, 197, 197, 197, 197, 197, 197, 197, -- 197, 197, 197, 207, 197, 210, 197, 275, -- 197, 256, 256, 5, 202, 203, 204, 197, -- 197, 197, 212, 197, 210, 197, 210, 197, -- 197, 197, 197, 197, 197, 202, 203, 204, -- 197, 197, 197, 212, 197, 210, 197, 210, -- 197, 197, 197, 197, 276, 197, 202, 203, -- 204, 197, 197, 197, 212, 197, 210, 197, -- 210, 197, 275, 197, 197, 197, 197, 202, -- 203, 204, 197, 197, 197, 212, 197, 210, -- 197, 210, 2, 197, 197, 18, 211, 197, -- 202, 203, 204, 197, 197, 197, 212, 197, -- 210, 197, 198, 199, 209, 209, 5, 202, -- 203, 204, 197, 197, 197, 205, 197, 197, -- 206, 197, 197, 197, 197, 197, 197, 197, -- 197, 197, 197, 197, 197, 197, 207, 197, -- 198, 199, 200, 209, 5, 202, 203, 204, -- 197, 197, 37, 205, 197, 197, 206, 197, -- 197, 197, 197, 197, 197, 197, 197, 197, -- 197, 197, 197, 197, 207, 197, 278, 279, -- 280, 281, 43, 282, 283, 284, 277, 277, -- 75, 285, 277, 277, 286, 277, 277, 277, -- 277, 277, 277, 277, 277, 277, 277, 277, -- 277, 277, 287, 277, 288, 279, 289, 281, -- 43, 282, 283, 284, 277, 277, 277, 285, -- 277, 277, 286, 277, 277, 277, 277, 277, -- 277, 277, 277, 277, 277, 277, 277, 277, -- 287, 277, 279, 289, 281, 43, 282, 283, -- 284, 277, 277, 277, 285, 277, 277, 286, -- 277, 277, 277, 277, 277, 277, 277, 277, -- 277, 277, 277, 277, 277, 287, 277, 290, -- 277, 277, 277, 56, 291, 277, 282, 283, -- 284, 277, 277, 277, 292, 277, 290, 277, -- 293, 294, 295, 296, 43, 282, 283, 284, -- 277, 277, 73, 297, 277, 277, 286, 277, -- 277, 277, 277, 277, 277, 277, 277, 277, -- 277, 277, 277, 277, 287, 277, 298, 294, -- 299, 299, 43, 282, 283, 284, 277, 277, -- 277, 297, 277, 277, 286, 277, 277, 277, -- 277, 277, 277, 277, 277, 277, 277, 277, -- 277, 277, 287, 277, 294, 299, 299, 43, -- 282, 283, 284, 277, 277, 277, 297, 277, -- 277, 286, 277, 277, 277, 277, 277, 277, -- 277, 277, 277, 277, 277, 277, 277, 287, -- 277, 300, 277, 277, 277, 56, 301, 277, -- 282, 283, 284, 277, 277, 277, 292, 277, -- 300, 277, 302, 303, 304, 305, 43, 282, -- 283, 284, 277, 277, 71, 306, 277, 277, -- 286, 277, 277, 277, 277, 277, 277, 277, -- 277, 277, 277, 277, 277, 277, 287, 277, -- 307, 303, 308, 308, 43, 282, 283, 284, -- 277, 277, 277, 306, 277, 277, 286, 277, -- 277, 277, 277, 277, 277, 277, 277, 277, -- 277, 277, 277, 277, 287, 277, 303, 308, -- 308, 43, 282, 283, 284, 277, 277, 277, -- 306, 277, 277, 286, 277, 277, 277, 277, -- 277, 277, 277, 277, 277, 277, 277, 277, -- 277, 287, 277, 309, 277, 277, 277, 56, -- 310, 277, 282, 283, 284, 277, 277, 277, -- 292, 277, 309, 277, 311, 312, 313, 314, -- 43, 282, 283, 284, 277, 277, 69, 315, -- 277, 277, 286, 277, 277, 277, 277, 277, -- 277, 277, 277, 277, 277, 277, 277, 277, -- 287, 277, 316, 312, 317, 317, 43, 282, -- 283, 284, 277, 277, 277, 315, 277, 277, -- 286, 277, 277, 277, 277, 277, 277, 277, -- 277, 277, 277, 277, 277, 277, 287, 277, -- 312, 317, 317, 43, 282, 283, 284, 277, -- 277, 277, 315, 277, 277, 286, 277, 277, -- 277, 277, 277, 277, 277, 277, 277, 277, -- 277, 277, 277, 287, 277, 318, 277, 277, -- 277, 56, 319, 277, 282, 283, 284, 277, -- 277, 277, 292, 277, 318, 277, 320, 321, -- 322, 323, 43, 282, 283, 284, 277, 277, -- 67, 324, 277, 277, 286, 277, 277, 277, -- 277, 277, 277, 277, 277, 277, 277, 277, -- 277, 277, 287, 277, 325, 321, 326, 326, -- 43, 282, 283, 284, 277, 277, 277, 324, -- 277, 277, 286, 277, 277, 277, 277, 277, -- 277, 277, 277, 277, 277, 277, 277, 277, -- 287, 277, 321, 326, 326, 43, 282, 283, -- 284, 277, 277, 277, 324, 277, 277, 286, -- 277, 277, 277, 277, 277, 277, 277, 277, -- 277, 277, 277, 277, 277, 287, 277, 56, -- 327, 277, 282, 283, 284, 277, 277, 277, -- 292, 277, 282, 283, 284, 277, 277, 277, -- 292, 277, 328, 277, 277, 329, 283, 284, -- 277, 283, 284, 277, 330, 277, 283, 331, -- 277, 283, 332, 277, 283, 277, 328, 277, -- 277, 277, 283, 284, 277, 333, 277, 334, -- 335, 277, 282, 283, 284, 277, 277, 41, -- 277, 40, 277, 277, 277, 277, 282, 283, -- 284, 277, 282, 283, 284, 277, 333, 277, -- 277, 277, 277, 282, 283, 284, 277, 333, -- 277, 334, 277, 277, 282, 283, 284, 277, -- 277, 41, 277, 56, 277, 336, 336, 43, -- 282, 283, 284, 277, 277, 277, 292, 277, -- 337, 65, 338, 339, 46, 282, 283, 284, -- 277, 277, 277, 292, 277, 65, 338, 339, -- 46, 282, 283, 284, 277, 277, 277, 292, -- 277, 338, 338, 46, 282, 283, 284, 277, -- 277, 277, 292, 277, 340, 62, 341, 342, -- 49, 282, 283, 284, 277, 277, 277, 292, -- 277, 62, 341, 342, 49, 282, 283, 284, -- 277, 277, 277, 292, 277, 341, 341, 49, -- 282, 283, 284, 277, 277, 277, 292, 277, -- 343, 59, 344, 345, 52, 282, 283, 284, -- 277, 277, 277, 292, 277, 59, 344, 345, -- 52, 282, 283, 284, 277, 277, 277, 292, -- 277, 344, 344, 52, 282, 283, 284, 277, -- 277, 277, 292, 277, 346, 56, 277, 347, -- 277, 282, 283, 284, 277, 277, 277, 292, -- 277, 56, 277, 347, 277, 282, 283, 284, -- 277, 277, 277, 292, 277, 348, 277, 282, -- 283, 284, 277, 277, 277, 292, 277, 56, -- 277, 277, 277, 277, 282, 283, 284, 277, -- 277, 277, 292, 277, 39, 40, 277, 277, -- 56, 327, 277, 282, 283, 284, 277, 277, -- 277, 292, 277, 39, 277, 321, 326, 326, -- 43, 282, 283, 284, 277, 277, 277, 324, -- 277, 277, 277, 277, 277, 277, 277, 277, -- 277, 277, 277, 277, 277, 277, 277, 277, -- 287, 277, 321, 326, 326, 43, 282, 283, -- 284, 277, 277, 277, 324, 277, 320, 321, -- 326, 326, 43, 282, 283, 284, 277, 277, -- 277, 324, 277, 277, 286, 277, 277, 277, -- 277, 277, 277, 277, 277, 277, 277, 277, -- 277, 277, 287, 277, 320, 321, 322, 326, -- 43, 282, 283, 284, 277, 277, 67, 324, -- 277, 277, 286, 277, 277, 277, 277, 277, -- 277, 277, 277, 277, 277, 277, 277, 277, -- 287, 277, 318, 277, 349, 277, 336, 336, -- 43, 282, 283, 284, 277, 277, 277, 292, -- 277, 318, 277, 318, 277, 277, 277, 277, -- 277, 277, 282, 283, 284, 277, 277, 277, -- 292, 277, 318, 277, 318, 277, 277, 277, -- 277, 350, 277, 282, 283, 284, 277, 277, -- 277, 292, 277, 318, 277, 318, 277, 349, -- 277, 277, 277, 277, 282, 283, 284, 277, -- 277, 277, 292, 277, 318, 277, 318, 40, -- 277, 277, 56, 319, 277, 282, 283, 284, -- 277, 277, 277, 292, 277, 318, 277, 311, -- 312, 317, 317, 43, 282, 283, 284, 277, -- 277, 277, 315, 277, 277, 286, 277, 277, -- 277, 277, 277, 277, 277, 277, 277, 277, -- 277, 277, 277, 287, 277, 311, 312, 313, -- 317, 43, 282, 283, 284, 277, 277, 69, -- 315, 277, 277, 286, 277, 277, 277, 277, -- 277, 277, 277, 277, 277, 277, 277, 277, -- 277, 287, 277, 309, 277, 351, 277, 336, -- 336, 43, 282, 283, 284, 277, 277, 277, -- 292, 277, 309, 277, 309, 277, 277, 277, -- 277, 277, 277, 282, 283, 284, 277, 277, -- 277, 292, 277, 309, 277, 309, 277, 277, -- 277, 277, 352, 277, 282, 283, 284, 277, -- 277, 277, 292, 277, 309, 277, 309, 277, -- 351, 277, 277, 277, 277, 282, 283, 284, -- 277, 277, 277, 292, 277, 309, 277, 309, -- 40, 277, 277, 56, 310, 277, 282, 283, -- 284, 277, 277, 277, 292, 277, 309, 277, -- 302, 303, 308, 308, 43, 282, 283, 284, -- 277, 277, 277, 306, 277, 277, 286, 277, -- 277, 277, 277, 277, 277, 277, 277, 277, -- 277, 277, 277, 277, 287, 277, 302, 303, -- 304, 308, 43, 282, 283, 284, 277, 277, -- 71, 306, 277, 277, 286, 277, 277, 277, -- 277, 277, 277, 277, 277, 277, 277, 277, -- 277, 277, 287, 277, 300, 277, 353, 277, -- 336, 336, 43, 282, 283, 284, 277, 277, -- 277, 292, 277, 300, 277, 300, 277, 277, -- 277, 277, 277, 277, 282, 283, 284, 277, -- 277, 277, 292, 277, 300, 277, 300, 277, -- 277, 277, 277, 354, 277, 282, 283, 284, -- 277, 277, 277, 292, 277, 300, 277, 300, -- 277, 353, 277, 277, 277, 277, 282, 283, -- 284, 277, 277, 277, 292, 277, 300, 277, -- 300, 40, 277, 277, 56, 301, 277, 282, -- 283, 284, 277, 277, 277, 292, 277, 300, -- 277, 293, 294, 299, 299, 43, 282, 283, -- 284, 277, 277, 277, 297, 277, 277, 286, -- 277, 277, 277, 277, 277, 277, 277, 277, -- 277, 277, 277, 277, 277, 287, 277, 293, -- 294, 295, 299, 43, 282, 283, 284, 277, -- 277, 73, 297, 277, 277, 286, 277, 277, -- 277, 277, 277, 277, 277, 277, 277, 277, -- 277, 277, 277, 287, 277, 290, 277, 355, -- 277, 336, 336, 43, 282, 283, 284, 277, -- 277, 277, 292, 277, 290, 277, 290, 277, -- 277, 277, 277, 277, 277, 282, 283, 284, -- 277, 277, 277, 292, 277, 290, 277, 290, -- 277, 277, 277, 277, 356, 277, 282, 283, -- 284, 277, 277, 277, 292, 277, 290, 277, -- 290, 277, 355, 277, 277, 277, 277, 282, -- 283, 284, 277, 277, 277, 292, 277, 290, -- 277, 74, 42, 42, 43, 277, 277, 277, -- 277, 277, 277, 74, 277, 290, 40, 277, -- 277, 56, 291, 277, 282, 283, 284, 277, -- 277, 277, 292, 277, 290, 277, 278, 279, -- 289, 281, 43, 282, 283, 284, 277, 277, -- 277, 285, 277, 277, 286, 277, 277, 277, -- 277, 277, 277, 277, 277, 277, 277, 277, -- 277, 277, 287, 277, 358, 184, 359, 359, -- 81, 187, 188, 189, 357, 357, 357, 191, -- 357, 357, 194, 357, 357, 357, 357, 357, -- 357, 357, 357, 357, 357, 357, 357, 357, -- 196, 357, 184, 359, 359, 81, 187, 188, -- 189, 357, 357, 357, 191, 357, 357, 194, -- 357, 357, 357, 357, 357, 357, 357, 357, -- 357, 357, 357, 357, 357, 196, 357, 360, -- 357, 357, 357, 95, 361, 357, 187, 188, -- 189, 357, 357, 357, 362, 357, 360, 357, -- 363, 364, 365, 366, 81, 187, 188, 189, -- 357, 357, 112, 367, 357, 357, 194, 357, -- 357, 357, 357, 357, 357, 357, 357, 357, -- 357, 357, 357, 357, 196, 357, 368, 364, -- 369, 369, 81, 187, 188, 189, 357, 357, -- 357, 367, 357, 357, 194, 357, 357, 357, -- 357, 357, 357, 357, 357, 357, 357, 357, -- 357, 357, 196, 357, 364, 369, 369, 81, -- 187, 188, 189, 357, 357, 357, 367, 357, -- 357, 194, 357, 357, 357, 357, 357, 357, -- 357, 357, 357, 357, 357, 357, 357, 196, -- 357, 370, 357, 357, 357, 95, 371, 357, -- 187, 188, 189, 357, 357, 357, 362, 357, -- 370, 357, 372, 373, 374, 375, 81, 187, -- 188, 189, 357, 357, 110, 376, 357, 357, -- 194, 357, 357, 357, 357, 357, 357, 357, -- 357, 357, 357, 357, 357, 357, 196, 357, -- 377, 373, 378, 378, 81, 187, 188, 189, -- 357, 357, 357, 376, 357, 357, 194, 357, -- 357, 357, 357, 357, 357, 357, 357, 357, -- 357, 357, 357, 357, 196, 357, 373, 378, -- 378, 81, 187, 188, 189, 357, 357, 357, -- 376, 357, 357, 194, 357, 357, 357, 357, -- 357, 357, 357, 357, 357, 357, 357, 357, -- 357, 196, 357, 379, 357, 357, 357, 95, -- 380, 357, 187, 188, 189, 357, 357, 357, -- 362, 357, 379, 357, 381, 382, 383, 384, -- 81, 187, 188, 189, 357, 357, 108, 385, -- 357, 357, 194, 357, 357, 357, 357, 357, -- 357, 357, 357, 357, 357, 357, 357, 357, -- 196, 357, 386, 382, 387, 387, 81, 187, -- 188, 189, 357, 357, 357, 385, 357, 357, -- 194, 357, 357, 357, 357, 357, 357, 357, -- 357, 357, 357, 357, 357, 357, 196, 357, -- 382, 387, 387, 81, 187, 188, 189, 357, -- 357, 357, 385, 357, 357, 194, 357, 357, -- 357, 357, 357, 357, 357, 357, 357, 357, -- 357, 357, 357, 196, 357, 388, 357, 357, -- 357, 95, 389, 357, 187, 188, 189, 357, -- 357, 357, 362, 357, 388, 357, 390, 391, -- 392, 393, 81, 187, 188, 189, 357, 357, -- 106, 394, 357, 357, 194, 357, 357, 357, -- 357, 357, 357, 357, 357, 357, 357, 357, -- 357, 357, 196, 357, 395, 391, 396, 396, -- 81, 187, 188, 189, 357, 357, 357, 394, -- 357, 357, 194, 357, 357, 357, 357, 357, -- 357, 357, 357, 357, 357, 357, 357, 357, -- 196, 357, 391, 396, 396, 81, 187, 188, -- 189, 357, 357, 357, 394, 357, 357, 194, -- 357, 357, 357, 357, 357, 357, 357, 357, -- 357, 357, 357, 357, 357, 196, 357, 95, -- 397, 357, 187, 188, 189, 357, 357, 357, -- 362, 357, 187, 188, 189, 357, 357, 357, -- 362, 357, 398, 357, 357, 399, 188, 189, -- 357, 188, 189, 357, 400, 357, 188, 401, -- 357, 188, 402, 357, 188, 357, 398, 357, -- 357, 357, 188, 189, 357, 403, 357, 404, -- 405, 357, 187, 188, 189, 357, 357, 79, -- 357, 78, 357, 357, 357, 357, 187, 188, -- 189, 357, 187, 188, 189, 357, 403, 357, -- 357, 357, 357, 187, 188, 189, 357, 403, -- 357, 404, 357, 357, 187, 188, 189, 357, -- 357, 79, 357, 95, 357, 406, 406, 81, -- 187, 188, 189, 357, 357, 357, 362, 357, -- 407, 104, 408, 409, 85, 187, 188, 189, -- 357, 357, 357, 362, 357, 104, 408, 409, -- 85, 187, 188, 189, 357, 357, 357, 362, -- 357, 408, 408, 85, 187, 188, 189, 357, -- 357, 357, 362, 357, 410, 101, 411, 412, -- 88, 187, 188, 189, 357, 357, 357, 362, -- 357, 101, 411, 412, 88, 187, 188, 189, -- 357, 357, 357, 362, 357, 411, 411, 88, -- 187, 188, 189, 357, 357, 357, 362, 357, -- 413, 98, 414, 415, 91, 187, 188, 189, -- 357, 357, 357, 362, 357, 98, 414, 415, -- 91, 187, 188, 189, 357, 357, 357, 362, -- 357, 414, 414, 91, 187, 188, 189, 357, -- 357, 357, 362, 357, 416, 95, 357, 417, -- 357, 187, 188, 189, 357, 357, 357, 362, -- 357, 95, 357, 417, 357, 187, 188, 189, -- 357, 357, 357, 362, 357, 418, 357, 187, -- 188, 189, 357, 357, 357, 362, 357, 95, -- 357, 357, 357, 357, 187, 188, 189, 357, -- 357, 357, 362, 357, 77, 78, 357, 357, -- 95, 397, 357, 187, 188, 189, 357, 357, -- 357, 362, 357, 77, 357, 391, 396, 396, -- 81, 187, 188, 189, 357, 357, 357, 394, -- 357, 357, 357, 357, 357, 357, 357, 357, -- 357, 357, 357, 357, 357, 357, 357, 357, -- 196, 357, 391, 396, 396, 81, 187, 188, -- 189, 357, 357, 357, 394, 357, 390, 391, -- 396, 396, 81, 187, 188, 189, 357, 357, -- 357, 394, 357, 357, 194, 357, 357, 357, -- 357, 357, 357, 357, 357, 357, 357, 357, -- 357, 357, 196, 357, 390, 391, 392, 396, -- 81, 187, 188, 189, 357, 357, 106, 394, -- 357, 357, 194, 357, 357, 357, 357, 357, -- 357, 357, 357, 357, 357, 357, 357, 357, -- 196, 357, 388, 357, 419, 357, 406, 406, -- 81, 187, 188, 189, 357, 357, 357, 362, -- 357, 388, 357, 388, 357, 357, 357, 357, -- 357, 357, 187, 188, 189, 357, 357, 357, -- 362, 357, 388, 357, 388, 357, 357, 357, -- 357, 420, 357, 187, 188, 189, 357, 357, -- 357, 362, 357, 388, 357, 388, 357, 419, -- 357, 357, 357, 357, 187, 188, 189, 357, -- 357, 357, 362, 357, 388, 357, 388, 78, -- 357, 357, 95, 389, 357, 187, 188, 189, -- 357, 357, 357, 362, 357, 388, 357, 381, -- 382, 387, 387, 81, 187, 188, 189, 357, -- 357, 357, 385, 357, 357, 194, 357, 357, -- 357, 357, 357, 357, 357, 357, 357, 357, -- 357, 357, 357, 196, 357, 381, 382, 383, -- 387, 81, 187, 188, 189, 357, 357, 108, -- 385, 357, 357, 194, 357, 357, 357, 357, -- 357, 357, 357, 357, 357, 357, 357, 357, -- 357, 196, 357, 379, 357, 421, 357, 406, -- 406, 81, 187, 188, 189, 357, 357, 357, -- 362, 357, 379, 357, 379, 357, 357, 357, -- 357, 357, 357, 187, 188, 189, 357, 357, -- 357, 362, 357, 379, 357, 379, 357, 357, -- 357, 357, 422, 357, 187, 188, 189, 357, -- 357, 357, 362, 357, 379, 357, 379, 357, -- 421, 357, 357, 357, 357, 187, 188, 189, -- 357, 357, 357, 362, 357, 379, 357, 379, -- 78, 357, 357, 95, 380, 357, 187, 188, -- 189, 357, 357, 357, 362, 357, 379, 357, -- 372, 373, 378, 378, 81, 187, 188, 189, -- 357, 357, 357, 376, 357, 357, 194, 357, -- 357, 357, 357, 357, 357, 357, 357, 357, -- 357, 357, 357, 357, 196, 357, 372, 373, -- 374, 378, 81, 187, 188, 189, 357, 357, -- 110, 376, 357, 357, 194, 357, 357, 357, -- 357, 357, 357, 357, 357, 357, 357, 357, -- 357, 357, 196, 357, 370, 357, 423, 357, -- 406, 406, 81, 187, 188, 189, 357, 357, -- 357, 362, 357, 370, 357, 370, 357, 357, -- 357, 357, 357, 357, 187, 188, 189, 357, -- 357, 357, 362, 357, 370, 357, 370, 357, -- 357, 357, 357, 424, 357, 187, 188, 189, -- 357, 357, 357, 362, 357, 370, 357, 370, -- 357, 423, 357, 357, 357, 357, 187, 188, -- 189, 357, 357, 357, 362, 357, 370, 357, -- 370, 78, 357, 357, 95, 371, 357, 187, -- 188, 189, 357, 357, 357, 362, 357, 370, -- 357, 363, 364, 369, 369, 81, 187, 188, -- 189, 357, 357, 357, 367, 357, 357, 194, -- 357, 357, 357, 357, 357, 357, 357, 357, -- 357, 357, 357, 357, 357, 196, 357, 363, -- 364, 365, 369, 81, 187, 188, 189, 357, -- 357, 112, 367, 357, 357, 194, 357, 357, -- 357, 357, 357, 357, 357, 357, 357, 357, -- 357, 357, 357, 196, 357, 360, 357, 425, -- 357, 406, 406, 81, 187, 188, 189, 357, -- 357, 357, 362, 357, 360, 357, 360, 357, -- 357, 357, 357, 357, 357, 187, 188, 189, -- 357, 357, 357, 362, 357, 360, 357, 360, -- 357, 357, 357, 357, 426, 357, 187, 188, -- 189, 357, 357, 357, 362, 357, 360, 357, -- 360, 357, 425, 357, 357, 357, 357, 187, -- 188, 189, 357, 357, 357, 362, 357, 360, -- 357, 360, 78, 357, 357, 95, 361, 357, -- 187, 188, 189, 357, 357, 357, 362, 357, -- 360, 357, 113, 80, 80, 81, 427, 427, -- 427, 427, 427, 152, 113, 427, 183, 184, -- 359, 359, 81, 187, 188, 189, 357, 357, -- 357, 191, 357, 357, 194, 357, 357, 357, -- 357, 357, 357, 357, 357, 357, 357, 357, -- 357, 357, 196, 357, 113, 80, 80, 81, -- 427, 427, 427, 427, 427, 427, 113, 427, -- 429, 430, 431, 432, 119, 433, 434, 435, -- 428, 428, 151, 436, 428, 428, 437, 428, -- 428, 428, 428, 428, 428, 428, 428, 428, -- 428, 428, 428, 428, 438, 428, 439, 430, -- 432, 432, 119, 433, 434, 435, 428, 428, -- 428, 436, 428, 428, 437, 428, 428, 428, -- 428, 428, 428, 428, 428, 428, 428, 428, -- 428, 428, 438, 428, 430, 432, 432, 119, -- 433, 434, 435, 428, 428, 428, 436, 428, -- 428, 437, 428, 428, 428, 428, 428, 428, -- 428, 428, 428, 428, 428, 428, 428, 438, -- 428, 440, 428, 428, 428, 132, 441, 428, -- 433, 434, 435, 428, 428, 428, 442, 428, -- 440, 428, 443, 444, 445, 446, 119, 433, -- 434, 435, 428, 428, 149, 447, 428, 428, -- 437, 428, 428, 428, 428, 428, 428, 428, -- 428, 428, 428, 428, 428, 428, 438, 428, -- 448, 444, 449, 449, 119, 433, 434, 435, -- 428, 428, 428, 447, 428, 428, 437, 428, -- 428, 428, 428, 428, 428, 428, 428, 428, -- 428, 428, 428, 428, 438, 428, 444, 449, -- 449, 119, 433, 434, 435, 428, 428, 428, -- 447, 428, 428, 437, 428, 428, 428, 428, -- 428, 428, 428, 428, 428, 428, 428, 428, -- 428, 438, 428, 450, 428, 428, 428, 132, -- 451, 428, 433, 434, 435, 428, 428, 428, -- 442, 428, 450, 428, 452, 453, 454, 455, -- 119, 433, 434, 435, 428, 428, 147, 456, -- 428, 428, 437, 428, 428, 428, 428, 428, -- 428, 428, 428, 428, 428, 428, 428, 428, -- 438, 428, 457, 453, 458, 458, 119, 433, -- 434, 435, 428, 428, 428, 456, 428, 428, -- 437, 428, 428, 428, 428, 428, 428, 428, -- 428, 428, 428, 428, 428, 428, 438, 428, -- 453, 458, 458, 119, 433, 434, 435, 428, -- 428, 428, 456, 428, 428, 437, 428, 428, -- 428, 428, 428, 428, 428, 428, 428, 428, -- 428, 428, 428, 438, 428, 459, 428, 428, -- 428, 132, 460, 428, 433, 434, 435, 428, -- 428, 428, 442, 428, 459, 428, 461, 462, -- 463, 464, 119, 433, 434, 435, 428, 428, -- 145, 465, 428, 428, 437, 428, 428, 428, -- 428, 428, 428, 428, 428, 428, 428, 428, -- 428, 428, 438, 428, 466, 462, 467, 467, -- 119, 433, 434, 435, 428, 428, 428, 465, -- 428, 428, 437, 428, 428, 428, 428, 428, -- 428, 428, 428, 428, 428, 428, 428, 428, -- 438, 428, 462, 467, 467, 119, 433, 434, -- 435, 428, 428, 428, 465, 428, 428, 437, -- 428, 428, 428, 428, 428, 428, 428, 428, -- 428, 428, 428, 428, 428, 438, 428, 468, -- 428, 428, 428, 132, 469, 428, 433, 434, -- 435, 428, 428, 428, 442, 428, 468, 428, -- 470, 471, 472, 473, 119, 433, 434, 435, -- 428, 428, 143, 474, 428, 428, 437, 428, -- 428, 428, 428, 428, 428, 428, 428, 428, -- 428, 428, 428, 428, 438, 428, 475, 471, -- 476, 476, 119, 433, 434, 435, 428, 428, -- 428, 474, 428, 428, 437, 428, 428, 428, -- 428, 428, 428, 428, 428, 428, 428, 428, -- 428, 428, 438, 428, 471, 476, 476, 119, -- 433, 434, 435, 428, 428, 428, 474, 428, -- 428, 437, 428, 428, 428, 428, 428, 428, -- 428, 428, 428, 428, 428, 428, 428, 438, -- 428, 132, 477, 428, 433, 434, 435, 428, -- 428, 428, 442, 428, 433, 434, 435, 428, -- 428, 428, 442, 428, 478, 428, 428, 479, -- 434, 435, 428, 434, 435, 428, 480, 428, -- 434, 481, 428, 434, 482, 428, 434, 428, -- 478, 428, 428, 428, 434, 435, 428, 483, -- 428, 484, 485, 428, 433, 434, 435, 428, -- 428, 117, 428, 116, 428, 428, 428, 428, -- 433, 434, 435, 428, 433, 434, 435, 428, -- 483, 428, 428, 428, 428, 433, 434, 435, -- 428, 483, 428, 484, 428, 428, 433, 434, -- 435, 428, 428, 117, 428, 132, 428, 486, -- 486, 119, 433, 434, 435, 428, 428, 428, -- 442, 428, 487, 141, 488, 489, 122, 433, -- 434, 435, 428, 428, 428, 442, 428, 141, -- 488, 489, 122, 433, 434, 435, 428, 428, -- 428, 442, 428, 488, 488, 122, 433, 434, -- 435, 428, 428, 428, 442, 428, 490, 138, -- 491, 492, 125, 433, 434, 435, 428, 428, -- 428, 442, 428, 138, 491, 492, 125, 433, -- 434, 435, 428, 428, 428, 442, 428, 491, -- 491, 125, 433, 434, 435, 428, 428, 428, -- 442, 428, 493, 135, 494, 495, 128, 433, -- 434, 435, 428, 428, 428, 442, 428, 135, -- 494, 495, 128, 433, 434, 435, 428, 428, -- 428, 442, 428, 494, 494, 128, 433, 434, -- 435, 428, 428, 428, 442, 428, 496, 132, -- 428, 497, 428, 433, 434, 435, 428, 428, -- 428, 442, 428, 132, 428, 497, 428, 433, -- 434, 435, 428, 428, 428, 442, 428, 498, -- 428, 433, 434, 435, 428, 428, 428, 442, -- 428, 132, 428, 428, 428, 428, 433, 434, -- 435, 428, 428, 428, 442, 428, 115, 116, -- 428, 428, 132, 477, 428, 433, 434, 435, -- 428, 428, 428, 442, 428, 115, 428, 471, -- 476, 476, 119, 433, 434, 435, 428, 428, -- 428, 474, 428, 428, 428, 428, 428, 428, -- 428, 428, 428, 428, 428, 428, 428, 428, -- 428, 428, 438, 428, 471, 476, 476, 119, -- 433, 434, 435, 428, 428, 428, 474, 428, -- 470, 471, 476, 476, 119, 433, 434, 435, -- 428, 428, 428, 474, 428, 428, 437, 428, -- 428, 428, 428, 428, 428, 428, 428, 428, -- 428, 428, 428, 428, 438, 428, 470, 471, -- 472, 476, 119, 433, 434, 435, 428, 428, -- 143, 474, 428, 428, 437, 428, 428, 428, -- 428, 428, 428, 428, 428, 428, 428, 428, -- 428, 428, 438, 428, 468, 428, 499, 428, -- 486, 486, 119, 433, 434, 435, 428, 428, -- 428, 442, 428, 468, 428, 468, 428, 428, -- 428, 428, 428, 428, 433, 434, 435, 428, -- 428, 428, 442, 428, 468, 428, 468, 428, -- 428, 428, 428, 500, 428, 433, 434, 435, -- 428, 428, 428, 442, 428, 468, 428, 468, -- 428, 499, 428, 428, 428, 428, 433, 434, -- 435, 428, 428, 428, 442, 428, 468, 428, -- 468, 116, 428, 428, 132, 469, 428, 433, -- 434, 435, 428, 428, 428, 442, 428, 468, -- 428, 461, 462, 467, 467, 119, 433, 434, -- 435, 428, 428, 428, 465, 428, 428, 437, -- 428, 428, 428, 428, 428, 428, 428, 428, -- 428, 428, 428, 428, 428, 438, 428, 461, -- 462, 463, 467, 119, 433, 434, 435, 428, -- 428, 145, 465, 428, 428, 437, 428, 428, -- 428, 428, 428, 428, 428, 428, 428, 428, -- 428, 428, 428, 438, 428, 459, 428, 501, -- 428, 486, 486, 119, 433, 434, 435, 428, -- 428, 428, 442, 428, 459, 428, 459, 428, -- 428, 428, 428, 428, 428, 433, 434, 435, -- 428, 428, 428, 442, 428, 459, 428, 459, -- 428, 428, 428, 428, 502, 428, 433, 434, -- 435, 428, 428, 428, 442, 428, 459, 428, -- 459, 428, 501, 428, 428, 428, 428, 433, -- 434, 435, 428, 428, 428, 442, 428, 459, -- 428, 459, 116, 428, 428, 132, 460, 428, -- 433, 434, 435, 428, 428, 428, 442, 428, -- 459, 428, 452, 453, 458, 458, 119, 433, -- 434, 435, 428, 428, 428, 456, 428, 428, -- 437, 428, 428, 428, 428, 428, 428, 428, -- 428, 428, 428, 428, 428, 428, 438, 428, -- 452, 453, 454, 458, 119, 433, 434, 435, -- 428, 428, 147, 456, 428, 428, 437, 428, -- 428, 428, 428, 428, 428, 428, 428, 428, -- 428, 428, 428, 428, 438, 428, 450, 428, -- 503, 428, 486, 486, 119, 433, 434, 435, -- 428, 428, 428, 442, 428, 450, 428, 450, -- 428, 428, 428, 428, 428, 428, 433, 434, -- 435, 428, 428, 428, 442, 428, 450, 428, -- 450, 428, 428, 428, 428, 504, 428, 433, -- 434, 435, 428, 428, 428, 442, 428, 450, -- 428, 450, 428, 503, 428, 428, 428, 428, -- 433, 434, 435, 428, 428, 428, 442, 428, -- 450, 428, 450, 116, 428, 428, 132, 451, -- 428, 433, 434, 435, 428, 428, 428, 442, -- 428, 450, 428, 443, 444, 449, 449, 119, -- 433, 434, 435, 428, 428, 428, 447, 428, -- 428, 437, 428, 428, 428, 428, 428, 428, -- 428, 428, 428, 428, 428, 428, 428, 438, -- 428, 443, 444, 445, 449, 119, 433, 434, -- 435, 428, 428, 149, 447, 428, 428, 437, -- 428, 428, 428, 428, 428, 428, 428, 428, -- 428, 428, 428, 428, 428, 438, 428, 440, -- 428, 505, 428, 486, 486, 119, 433, 434, -- 435, 428, 428, 428, 442, 428, 440, 428, -- 440, 428, 428, 428, 428, 428, 428, 433, -- 434, 435, 428, 428, 428, 442, 428, 440, -- 428, 440, 428, 428, 428, 428, 506, 428, -- 433, 434, 435, 428, 428, 428, 442, 428, -- 440, 428, 440, 428, 505, 428, 428, 428, -- 428, 433, 434, 435, 428, 428, 428, 442, -- 428, 440, 428, 440, 116, 428, 428, 132, -- 441, 428, 433, 434, 435, 428, 428, 428, -- 442, 428, 440, 428, 429, 430, 432, 432, -- 119, 433, 434, 435, 428, 428, 428, 436, -- 428, 428, 437, 428, 428, 428, 428, 428, -- 428, 428, 428, 428, 428, 428, 428, 428, -- 438, 428, 181, 182, 183, 184, 507, 359, -- 81, 187, 188, 189, 190, 190, 152, 191, -- 357, 181, 194, 357, 357, 357, 357, 357, -- 357, 357, 357, 357, 357, 357, 357, 357, -- 196, 357, 198, 508, 200, 201, 5, 202, -- 203, 204, 197, 197, 37, 205, 197, 197, -- 206, 197, 197, 197, 197, 197, 197, 197, -- 197, 197, 197, 197, 197, 197, 207, 197, -- 210, 182, 183, 184, 509, 510, 81, 511, -- 512, 513, 197, 190, 152, 514, 197, 210, -- 194, 197, 197, 197, 197, 197, 197, 197, -- 197, 197, 197, 197, 197, 197, 196, 197, -- 113, 80, 80, 81, 202, 203, 204, 197, -- 197, 152, 515, 197, 516, 2, 357, 357, -- 357, 426, 357, 187, 188, 189, 357, 357, -- 357, 362, 357, 516, 357, 517, 364, 518, -- 519, 81, 511, 512, 513, 197, 197, 153, -- 367, 197, 197, 194, 197, 197, 197, 197, -- 197, 197, 197, 197, 197, 197, 197, 197, -- 197, 196, 197, 520, 364, 369, 369, 81, -- 511, 512, 513, 197, 197, 197, 367, 197, -- 197, 194, 197, 197, 197, 197, 197, 197, -- 197, 197, 197, 197, 197, 197, 197, 196, -- 197, 364, 369, 369, 81, 511, 512, 513, -- 197, 197, 197, 367, 197, 197, 194, 197, -- 197, 197, 197, 197, 197, 197, 197, 197, -- 197, 197, 197, 197, 196, 197, 521, 197, -- 197, 522, 512, 513, 197, 512, 513, 197, -- 250, 197, 512, 523, 197, 512, 524, 197, -- 512, 197, 521, 197, 197, 197, 512, 513, -- 197, 517, 364, 369, 369, 81, 511, 512, -- 513, 197, 197, 197, 367, 197, 197, 194, -- 197, 197, 197, 197, 197, 197, 197, 197, |