summaryrefslogtreecommitdiffstats
path: root/src/3rdparty/harfbuzz
diff options
context:
space:
mode:
authorLars Knoll <lars.knoll@qt.io>2020-03-14 16:40:20 +0100
committerLars Knoll <lars.knoll@qt.io>2020-03-17 01:43:29 +0100
commit47b1e883e4d177729108ba71bf581957885fe46a (patch)
tree39d0383a0e2515257cc4d3b428c9511e4b3a77e3 /src/3rdparty/harfbuzz
parent8863bfa603491c8ba5d1384a88a5d800268b4820 (diff)
Remove the old harfbuzz library and integration code
It's not used anymore. harfbuzz-ng is a requirement in Qt 6 if you want any open type shaping. Fixes: QTBUG-82881 Change-Id: If7100aebdcfa078a999608bb8f07a2ef3a79d282 Reviewed-by: Konstantin Ritt <ritt.ks@gmail.com>
Diffstat (limited to 'src/3rdparty/harfbuzz')
-rw-r--r--src/3rdparty/harfbuzz/.gitignore20
-rw-r--r--src/3rdparty/harfbuzz/AUTHORS6
-rw-r--r--src/3rdparty/harfbuzz/COPYING24
-rw-r--r--src/3rdparty/harfbuzz/ChangeLog0
-rw-r--r--src/3rdparty/harfbuzz/Makefile.am2
-rw-r--r--src/3rdparty/harfbuzz/NEWS0
-rw-r--r--src/3rdparty/harfbuzz/README7
-rwxr-xr-xsrc/3rdparty/harfbuzz/autogen.sh116
-rw-r--r--src/3rdparty/harfbuzz/configure.ac54
-rw-r--r--src/3rdparty/harfbuzz/qt_attribution.json15
-rw-r--r--src/3rdparty/harfbuzz/src/.gitignore7
-rw-r--r--src/3rdparty/harfbuzz/src/Makefile.am69
-rw-r--r--src/3rdparty/harfbuzz/src/harfbuzz-arabic.c1153
-rw-r--r--src/3rdparty/harfbuzz/src/harfbuzz-buffer-private.h107
-rw-r--r--src/3rdparty/harfbuzz/src/harfbuzz-buffer.c383
-rw-r--r--src/3rdparty/harfbuzz/src/harfbuzz-buffer.h94
-rw-r--r--src/3rdparty/harfbuzz/src/harfbuzz-dump-main.c97
-rw-r--r--src/3rdparty/harfbuzz/src/harfbuzz-dump.c767
-rw-r--r--src/3rdparty/harfbuzz/src/harfbuzz-dump.h41
-rw-r--r--src/3rdparty/harfbuzz/src/harfbuzz-external.h86
-rw-r--r--src/3rdparty/harfbuzz/src/harfbuzz-gdef-private.h126
-rw-r--r--src/3rdparty/harfbuzz/src/harfbuzz-gdef.c1163
-rw-r--r--src/3rdparty/harfbuzz/src/harfbuzz-gdef.h132
-rw-r--r--src/3rdparty/harfbuzz/src/harfbuzz-global.h118
-rw-r--r--src/3rdparty/harfbuzz/src/harfbuzz-gpos-private.h733
-rw-r--r--src/3rdparty/harfbuzz/src/harfbuzz-gpos.c6275
-rw-r--r--src/3rdparty/harfbuzz/src/harfbuzz-gpos.h155
-rw-r--r--src/3rdparty/harfbuzz/src/harfbuzz-greek.c451
-rw-r--r--src/3rdparty/harfbuzz/src/harfbuzz-gsub-private.h475
-rw-r--r--src/3rdparty/harfbuzz/src/harfbuzz-gsub.c4329
-rw-r--r--src/3rdparty/harfbuzz/src/harfbuzz-gsub.h139
-rw-r--r--src/3rdparty/harfbuzz/src/harfbuzz-hangul.c268
-rw-r--r--src/3rdparty/harfbuzz/src/harfbuzz-hebrew.c187
-rw-r--r--src/3rdparty/harfbuzz/src/harfbuzz-impl.c84
-rw-r--r--src/3rdparty/harfbuzz/src/harfbuzz-impl.h131
-rw-r--r--src/3rdparty/harfbuzz/src/harfbuzz-indic.cpp1899
-rw-r--r--src/3rdparty/harfbuzz/src/harfbuzz-khmer.c667
-rw-r--r--src/3rdparty/harfbuzz/src/harfbuzz-myanmar.c538
-rw-r--r--src/3rdparty/harfbuzz/src/harfbuzz-open-private.h102
-rw-r--r--src/3rdparty/harfbuzz/src/harfbuzz-open.c1433
-rw-r--r--src/3rdparty/harfbuzz/src/harfbuzz-open.h280
-rw-r--r--src/3rdparty/harfbuzz/src/harfbuzz-shape.h199
-rw-r--r--src/3rdparty/harfbuzz/src/harfbuzz-shaper-all.cpp37
-rw-r--r--src/3rdparty/harfbuzz/src/harfbuzz-shaper-private.h174
-rw-r--r--src/3rdparty/harfbuzz/src/harfbuzz-shaper.cpp1111
-rw-r--r--src/3rdparty/harfbuzz/src/harfbuzz-shaper.h277
-rw-r--r--src/3rdparty/harfbuzz/src/harfbuzz-stream-private.h81
-rw-r--r--src/3rdparty/harfbuzz/src/harfbuzz-stream.c114
-rw-r--r--src/3rdparty/harfbuzz/src/harfbuzz-stream.h43
-rw-r--r--src/3rdparty/harfbuzz/src/harfbuzz-thai.c460
-rw-r--r--src/3rdparty/harfbuzz/src/harfbuzz-tibetan.c277
-rw-r--r--src/3rdparty/harfbuzz/src/harfbuzz.c32
-rw-r--r--src/3rdparty/harfbuzz/src/harfbuzz.h38
-rw-r--r--src/3rdparty/harfbuzz/tests/Makefile.am7
-rw-r--r--src/3rdparty/harfbuzz/tests/fuzzing/fuzz.cc124
-rw-r--r--src/3rdparty/harfbuzz/tests/shaping/.gitignore2
-rw-r--r--src/3rdparty/harfbuzz/tests/shaping/Makefile.am14
-rw-r--r--src/3rdparty/harfbuzz/tests/shaping/README9
-rw-r--r--src/3rdparty/harfbuzz/tests/shaping/harfbuzz-qt.cpp57
-rw-r--r--src/3rdparty/harfbuzz/tests/shaping/main.cpp1317
60 files changed, 0 insertions, 27106 deletions
diff --git a/src/3rdparty/harfbuzz/.gitignore b/src/3rdparty/harfbuzz/.gitignore
deleted file mode 100644
index 572243facd..0000000000
--- a/src/3rdparty/harfbuzz/.gitignore
+++ /dev/null
@@ -1,20 +0,0 @@
-INSTALL
-Makefile.in
-aclocal.m4
-autom4te.cache
-config.guess
-config.h.in
-config.sub
-config.h
-configure
-depcomp
-install-sh
-ltmain.sh
-missing
-Makefile
-config.status
-config.log
-libtool
-stamp-h1
-compile
-build
diff --git a/src/3rdparty/harfbuzz/AUTHORS b/src/3rdparty/harfbuzz/AUTHORS
deleted file mode 100644
index 023488a5b9..0000000000
--- a/src/3rdparty/harfbuzz/AUTHORS
+++ /dev/null
@@ -1,6 +0,0 @@
-David Turner
-Werner Lemberg
-Owen Taylor
-Behdad Esfahbod
-Lars Knoll
-Simon Hausmann
diff --git a/src/3rdparty/harfbuzz/COPYING b/src/3rdparty/harfbuzz/COPYING
deleted file mode 100644
index 820a9e6808..0000000000
--- a/src/3rdparty/harfbuzz/COPYING
+++ /dev/null
@@ -1,24 +0,0 @@
-HarfBuzz was previously licensed under different licenses. This was
-changed in January 2008. If you need to relicense your old copies,
-consult the announcement of the license change on the internet.
-Other than that, each copy of HarfBuzz is licensed under the COPYING
-file included with it. The actual license follows:
-
-
-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.
diff --git a/src/3rdparty/harfbuzz/ChangeLog b/src/3rdparty/harfbuzz/ChangeLog
deleted file mode 100644
index e69de29bb2..0000000000
--- a/src/3rdparty/harfbuzz/ChangeLog
+++ /dev/null
diff --git a/src/3rdparty/harfbuzz/Makefile.am b/src/3rdparty/harfbuzz/Makefile.am
deleted file mode 100644
index 776b947eee..0000000000
--- a/src/3rdparty/harfbuzz/Makefile.am
+++ /dev/null
@@ -1,2 +0,0 @@
-
-SUBDIRS = src tests
diff --git a/src/3rdparty/harfbuzz/NEWS b/src/3rdparty/harfbuzz/NEWS
deleted file mode 100644
index e69de29bb2..0000000000
--- a/src/3rdparty/harfbuzz/NEWS
+++ /dev/null
diff --git a/src/3rdparty/harfbuzz/README b/src/3rdparty/harfbuzz/README
deleted file mode 100644
index ca2546ae02..0000000000
--- a/src/3rdparty/harfbuzz/README
+++ /dev/null
@@ -1,7 +0,0 @@
-This is HarfBuzz, an OpenType Layout engine library.
-
-To report bugs or post to discussion mailing list, see:
-
- http://freedesktop.org/wiki/Software/HarfBuzz
-
-For license information, see the file COPYING.
diff --git a/src/3rdparty/harfbuzz/autogen.sh b/src/3rdparty/harfbuzz/autogen.sh
deleted file mode 100755
index 7fa1c3df61..0000000000
--- a/src/3rdparty/harfbuzz/autogen.sh
+++ /dev/null
@@ -1,116 +0,0 @@
-#!/bin/sh
-# Run this to generate all the initial makefiles, etc.
-
-set -e
-
-srcdir=`dirname $0`
-test -z "$srcdir" && srcdir=.
-
-ORIGDIR=`pwd`
-cd $srcdir
-PROJECT=harfbuzz
-TEST_TYPE=-f
-FILE=src/harfbuzz.h
-ACLOCAL=${ACLOCAL-aclocal}
-LIBTOOLIZE=${LIBTOOLIZE-libtoolize}
-AUTOMAKE=${AUTOMAKE-automake}
-AUTOHEADER=${AUTOHEADER-autoheader}
-AUTOCONF=${AUTOCONF-autoconf}
-LIBTOOLIZE_FLAGS="--copy --force"
-
-DIE=0
-
-have_libtool=false
-if $LIBTOOLIZE --version < /dev/null > /dev/null 2>&1 ; then
- libtool_version=`$LIBTOOLIZE --version | sed 's/^[^0-9]*\([0-9].[0-9.]*\).*/\1/'`
- case $libtool_version in
- 1.4*|1.5*|1.6*|1.7*|2*)
- have_libtool=true
- ;;
- esac
-fi
-if $have_libtool ; then : ; else
- echo
- echo "You must have libtool 1.4 installed to compile $PROJECT."
- echo "Install the appropriate package for your distribution,"
- echo "or get the source tarball at ftp://ftp.gnu.org/pub/gnu/"
- DIE=1
-fi
-
-($AUTOCONF --version) < /dev/null > /dev/null 2>&1 || {
- echo
- echo "You must have autoconf installed to compile $PROJECT."
- echo "libtool the appropriate package for your distribution,"
- echo "or get the source tarball at ftp://ftp.gnu.org/pub/gnu/"
- DIE=1
-}
-
-have_automake=false
-need_libtoolize=true
-if $AUTOMAKE --version < /dev/null > /dev/null 2>&1 ; then
- automake_version=`$AUTOMAKE --version | grep 'automake (GNU automake)' | sed 's/^[^0-9]*\(.*\)/\1/'`
- case $automake_version in
- 1.2*|1.3*|1.4)
- ;;
- 1.4*)
- have_automake=true
- need_libtoolize=false
- ;;
- *)
- have_automake=true
- ;;
- esac
-fi
-if $have_automake ; then : ; else
- echo
- echo "You must have automake 1.4-p1 installed to compile $PROJECT."
- echo "Get ftp://ftp.gnu.org/pub/gnu/automake/automake-1.4-p1.tar.gz"
- echo "(or a newer version if it is available)"
- DIE=1
-fi
-
-if test "$DIE" -eq 1; then
- exit 1
-fi
-
-test $TEST_TYPE $FILE || {
- echo "You must run this script in the top-level $PROJECT directory"
- exit 1
-}
-
-if test -z "$AUTOGEN_SUBDIR_MODE"; then
- if test -z "$*"; then
- echo "I am going to run ./configure with no arguments - if you wish "
- echo "to pass any to it, please specify them on the $0 command line."
- fi
-fi
-
-echo Running $ACLOCAL $ACLOCAL_FLAGS
-$ACLOCAL $ACLOCAL_FLAGS
-
-# optionally run autoheader
-if $AUTOHEADER --version < /dev/null > /dev/null 2>&1; then
- echo Running $AUTOHEADER
- $AUTOHEADER
-fi
-
-case $need_libtoolize in
- true)
- echo Running $LIBTOOLIZE $LIBTOOLIZE_FLAGS
- $LIBTOOLIZE $LIBTOOLIZE_FLAGS
- ;;
-esac
-
-echo Running $AUTOMAKE -a $am_opt
-$AUTOMAKE -a $am_opt
-echo Running $AUTOCONF
-$AUTOCONF
-cd $ORIGDIR
-
-if test -z "$AUTOGEN_SUBDIR_MODE"; then
- echo Running $srcdir/configure "$@"
- $srcdir/configure "$@"
-
- echo
- echo "Now type 'make' to compile $PROJECT."
-fi
diff --git a/src/3rdparty/harfbuzz/configure.ac b/src/3rdparty/harfbuzz/configure.ac
deleted file mode 100644
index 8519279738..0000000000
--- a/src/3rdparty/harfbuzz/configure.ac
+++ /dev/null
@@ -1,54 +0,0 @@
-AC_INIT(README)
-AM_INIT_AUTOMAKE(harfbuzz, 0.1)
-AC_PROG_CC
-AC_PROG_CXX
-AM_PROG_LIBTOOL
-PKG_PROG_PKG_CONFIG
-AM_CONFIG_HEADER(config.h)
-
-if test "x$ac_compiler_gnu" = xyes; then
- CFLAGS="$CFLAGS -Wall -W -pedantic -ansi"
- CXXFLAGS="$CXXFLAGS -Wall -W"
-fi
-
-AC_PATH_PROG(ft_config,freetype-config,no)
-if test "$ft_config" = "no"; then
- AC_MSG_ERROR([You must have freetype installed; see http://www.freetype.org/])
-fi
-
-FREETYPE_CFLAGS="`$ft_config --cflags`"
-FREETYPE_LIBS="`$ft_config --libs`"
-
-AC_SUBST(FREETYPE_LIBS)
-AC_SUBST(FREETYPE_CFLAGS)
-
-AC_ARG_ENABLE(qt, AS_HELP_STRING([--disable-qt], [Build Qt support (default: auto)]), [QT=$enableval], [QT=auto])
-
-if test "x$QT" = xauto; then
- PKG_CHECK_MODULES(QT, [QtGui >= 4.3], [QT=yes], [QT=no])
-fi
-if test "x$QT" = xyes; then
- PKG_CHECK_MODULES(QT_GUI, [QtGui >= 4.3])
- PKG_CHECK_MODULES(QT_QTEST, [QtTest >= 4.3])
-
- _PKG_CONFIG(QT_INCDIR, [variable=includedir], [QtGui >= 4.3])
- QT_GUI_CFLAGS="$QT_GUI_CFLAGS -I$pkg_cv_QT_INCDIR/../Qt"
-
- AC_SUBST(QT_GUI_CFLAGS)
- AC_SUBST(QT_GUI_LIBS)
- AC_SUBST(QT_QTEST_CFLAGS)
- AC_SUBST(QT_QTEST_LIBS)
-
- _PKG_CONFIG(QT_MOC, [variable=moc_location], [QtGui >= 4.3])
- QT_MOC=$pkg_cv_QT_MOC
- AC_SUBST(QT_MOC)
-fi
-AM_CONDITIONAL(QT, [test "x$QT" = xyes])
-
-AC_OUTPUT([
-Makefile
-src/Makefile
-tests/Makefile
-tests/linebreaking/Makefile
-tests/shaping/Makefile
-])
diff --git a/src/3rdparty/harfbuzz/qt_attribution.json b/src/3rdparty/harfbuzz/qt_attribution.json
deleted file mode 100644
index 986171fb7b..0000000000
--- a/src/3rdparty/harfbuzz/qt_attribution.json
+++ /dev/null
@@ -1,15 +0,0 @@
-{
- "Id": "harfbuzz",
- "Name": "HarfBuzz",
- "QDocModule": "qtgui",
- "QtUsage": "Optionally used in Qt GUI. Configure with -system-harfbuzz to force the use of the system library, or -no-harfbuzz to disable the use of HarfBuzz entirely.",
-
- "License": "MIT License",
- "LicenseId": "MIT",
- "LicenseFile": "COPYING",
- "Copyright": "Copyright © 2008,2010 Nokia Corporation and/or its subsidiary(-ies)
-Copyright © 2006 Behdad Esfahbod
-Copyright © 2005 David Turner
-Copyright © 2004,2007,2008,2009,2010 Red Hat, Inc.
-Copyright © 1998-2004 David Turner and Werner Lemberg"
-}
diff --git a/src/3rdparty/harfbuzz/src/.gitignore b/src/3rdparty/harfbuzz/src/.gitignore
deleted file mode 100644
index 74de98b140..0000000000
--- a/src/3rdparty/harfbuzz/src/.gitignore
+++ /dev/null
@@ -1,7 +0,0 @@
-*.o
-*.lo
-Makefile
-*.la
-.deps
-.libs
-*~
diff --git a/src/3rdparty/harfbuzz/src/Makefile.am b/src/3rdparty/harfbuzz/src/Makefile.am
deleted file mode 100644
index 51d06525da..0000000000
--- a/src/3rdparty/harfbuzz/src/Makefile.am
+++ /dev/null
@@ -1,69 +0,0 @@
-## Process this file with automake to produce Makefile.in
-
-noinst_LTLIBRARIES = libharfbuzz-1.la
-
-MAINSOURCES = \
- harfbuzz-buffer.c \
- harfbuzz-stream.c \
- harfbuzz-dump.c \
- harfbuzz-gdef.c \
- harfbuzz-gpos.c \
- harfbuzz-gsub.c \
- harfbuzz-impl.c \
- harfbuzz-open.c \
- harfbuzz-shaper.cpp \
- harfbuzz-greek.c \
- harfbuzz-tibetan.c \
- harfbuzz-khmer.c \
- harfbuzz-indic.cpp \
- harfbuzz-hebrew.c \
- harfbuzz-arabic.c \
- harfbuzz-hangul.c \
- harfbuzz-myanmar.c \
- harfbuzz-thai.c
-
-EXTRA_SOURCES = harfbuzz.c
-
-PUBLICHEADERS = \
- harfbuzz.h \
- harfbuzz-buffer.h \
- harfbuzz-dump.h \
- harfbuzz-gdef.h \
- harfbuzz-gpos.h \
- harfbuzz-gsub.h \
- harfbuzz-open.h \
- harfbuzz-global.h \
- harfbuzz-external.h \
- harfbuzz-shaper.h \
- harfbuzz-stream.h
-
-PRIVATEHEADERS = \
- harfbuzz-impl.h \
- harfbuzz-buffer-private.h \
- harfbuzz-stream-private.h \
- harfbuzz-gdef-private.h \
- harfbuzz-gpos-private.h \
- harfbuzz-gsub-private.h \
- harfbuzz-open-private.h \
- harfbuzz-shaper-private.h
-
-libharfbuzz_1_la_SOURCES = \
- $(MAINSOURCES) \
- $(PUBLICHEADERS) \
- $(PRIVATEHEADERS)
-
-#noinst_PROGRAMS = harfbuzz-dump
-#
-#harfbuzz_dump_SOURCES = \
-# harfbuzz-dump-main.c
-#
-#harfbuzz_dump_LDADD = \
-# libharfbuzz-1.la
-
-EXTRA_DIST = \
- README \
- COPYING.FTL \
- COPYING.GPL \
- COPYING \
- $(EXTRA_SOURCES)
-
diff --git a/src/3rdparty/harfbuzz/src/harfbuzz-arabic.c b/src/3rdparty/harfbuzz/src/harfbuzz-arabic.c
deleted file mode 100644
index 966537ffa0..0000000000
--- a/src/3rdparty/harfbuzz/src/harfbuzz-arabic.c
+++ /dev/null
@@ -1,1153 +0,0 @@
-/*
- * Copyright (C) 2015 The Qt Company Ltd
- *
- * This is part of HarfBuzz, an OpenType Layout engine library.
- *
- * Permission is hereby granted, without written agreement and without
- * license or royalty fees, to use, copy, modify, and distribute this
- * software and its documentation for any purpose, provided that the
- * above copyright notice and the following two paragraphs appear in
- * all copies of this software.
- *
- * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
- * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
- * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
- * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
- * DAMAGE.
- *
- * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
- * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
- * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
- * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
- * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
- */
-
-#include "harfbuzz-shaper.h"
-#include "harfbuzz-shaper-private.h"
-
-#include <assert.h>
-
-static const HB_UChar16 ReplacementCharacter = 0xfffd;
-
-typedef struct {
- unsigned char shape;
- unsigned char justification;
-} HB_ArabicProperties;
-
-typedef enum {
- XIsolated,
- XFinal,
- XInitial,
- XMedial,
- /* intermediate state */
- XCausing
-} ArabicShape;
-
-/*
-// these groups correspond to the groups defined in the Unicode standard.
-// Some of these groups are equal with regards to both joining and line breaking behaviour,
-// and thus have the same enum value
-//
-// I'm not sure the mapping of syriac to arabic enums is correct with regards to justification, but as
-// I couldn't find any better document I'll hope for the best.
-*/
-typedef enum {
- /* NonJoining */
- ArabicNone,
- ArabicSpace,
- /* Transparent */
- Transparent,
- /* Causing */
- Center,
- Kashida,
-
- /* Arabic */
- /* Dual */
- Beh,
- Noon,
- Nya = Noon,
- Meem = Noon,
- Heh = Noon,
- KnottedHeh = Noon,
- HehGoal = Noon,
- SwashKaf = Noon,
- Yeh,
- FarsiYeh = Yeh,
- Hah,
- Seen,
- Sad = Seen,
- Tah,
- Kaf = Tah,
- Gaf = Tah,
- Lam = Tah,
- Ain,
- Feh = Ain,
- Qaf = Ain,
- /* Right */
- Alef,
- Waw,
- Dal,
- TehMarbuta = Dal,
- Reh,
- TehMarbutaGoal,
- HamzaOnHehGoal = TehMarbutaGoal, /* has been retained as a property value alias */
- YehWithTail = TehMarbutaGoal,
- YehBarree = TehMarbutaGoal,
-
- /* Syriac */
- /* Dual */
- Beth = Beh,
- Gamal = Ain,
- Heth = Noon,
- Teth = Hah,
- Yudh = Noon,
- Khaph = Noon,
- Lamadh = Lam,
- Mim = Noon,
- Nun = Noon,
- Semkath = Noon,
- FinalSemkath = Noon,
- SyriacE = Ain,
- Pe = Ain,
- ReversedPe = Hah,
- Qaph = Noon,
- Shin = Noon,
- Fe = Ain,
-
- /* Right */
- Alaph = Alef,
- DalathRish = Dal,
- He = Dal,
- SyriacWaw = Waw,
- Zhain = Alef,
- YudhHe = Waw,
- Sadhe = TehMarbutaGoal,
- Taw = Dal,
-
- /* Compiler bug? Otherwise ArabicGroupsEnd would be equal to Dal + 1. */
- Dummy = TehMarbutaGoal,
- ArabicGroupsEnd
-} ArabicGroup;
-
-static const unsigned char arabic_group[0x150] = {
- ArabicNone, ArabicNone, ArabicNone, ArabicNone,
- ArabicNone, ArabicNone, ArabicNone, ArabicNone,
- ArabicNone, ArabicNone, ArabicNone, ArabicNone,
- ArabicNone, ArabicNone, ArabicNone, ArabicNone,
-
- Transparent, Transparent, Transparent, Transparent,
- Transparent, Transparent, Transparent, Transparent,
- Transparent, Transparent, Transparent, ArabicNone,
- ArabicNone, ArabicNone, ArabicNone, ArabicNone,
-
- Yeh, ArabicNone, Alef, Alef,
- Waw, Alef, Yeh, Alef,
- Beh, TehMarbuta, Beh, Beh,
- Hah, Hah, Hah, Dal,
-
- Dal, Reh, Reh, Seen,
- Seen, Sad, Sad, Tah,
- Tah, Ain, Ain, Gaf,
- Gaf, FarsiYeh, FarsiYeh, FarsiYeh,
-
- /* 0x640 */
- Kashida, Feh, Qaf, Kaf,
- Lam, Meem, Noon, Heh,
- Waw, Yeh, Yeh, Transparent,
- Transparent, Transparent, Transparent, Transparent,
-
- Transparent, Transparent, Transparent, Transparent,
- Transparent, Transparent, Transparent, Transparent,
- Transparent, Transparent, Transparent, Transparent,
- Transparent, Transparent, Transparent, Transparent,
-
- ArabicNone, ArabicNone, ArabicNone, ArabicNone,
- ArabicNone, ArabicNone, ArabicNone, ArabicNone,
- ArabicNone, ArabicNone, ArabicNone, ArabicNone,
- ArabicNone, ArabicNone, Beh, Qaf,
-
- Transparent, Alef, Alef, Alef,
- ArabicNone, Alef, Waw, Waw,
- Yeh, Beh, Beh, Beh,
- Beh, Beh, Beh, Beh,
-
- /* 0x680 */
- Beh, Hah, Hah, Hah,
- Hah, Hah, Hah, Hah,
- Dal, Dal, Dal, Dal,
- Dal, Dal, Dal, Dal,
-
- Dal, Reh, Reh, Reh,
- Reh, Reh, Reh, Reh,
- Reh, Reh, Seen, Seen,
- Seen, Sad, Sad, Tah,
-
- Ain, Feh, Feh, Feh,
- Feh, Feh, Feh, Qaf,
- Qaf, Gaf, SwashKaf, Gaf,
- Kaf, Kaf, Kaf, Gaf,
-
- Gaf, Gaf, Gaf, Gaf,
- Gaf, Lam, Lam, Lam,
- Lam, Noon, Noon, Noon,
- Noon, Nya, KnottedHeh, Hah,
-
- /* 0x6c0 */
- TehMarbuta, HehGoal, HehGoal, TehMarbutaGoal,
- Waw, Waw, Waw, Waw,
- Waw, Waw, Waw, Waw,
- FarsiYeh, YehWithTail, FarsiYeh, Waw,
-
- Yeh, Yeh, YehBarree, YehBarree,
- ArabicNone, TehMarbuta, Transparent, Transparent,
- Transparent, Transparent, Transparent, Transparent,
- Transparent, ArabicNone, ArabicNone, Transparent,
-
- Transparent, Transparent, Transparent, Transparent,
- Transparent, ArabicNone, ArabicNone, Transparent,
- Transparent, ArabicNone, Transparent, Transparent,
- Transparent, Transparent, Dal, Reh,
-
- ArabicNone, ArabicNone, ArabicNone, ArabicNone,
- ArabicNone, ArabicNone, ArabicNone, ArabicNone,
- ArabicNone, ArabicNone, Seen, Sad,
- Ain, ArabicNone, ArabicNone, KnottedHeh,
-
- /* 0x700 */
- ArabicNone, ArabicNone, ArabicNone, ArabicNone,
- ArabicNone, ArabicNone, ArabicNone, ArabicNone,
- ArabicNone, ArabicNone, ArabicNone, ArabicNone,
- ArabicNone, ArabicNone, ArabicNone, Transparent,
-
- Alaph, Transparent, Beth, Gamal,
- Gamal, DalathRish, DalathRish, He,
- SyriacWaw, Zhain, Heth, Teth,
- Teth, Yudh, YudhHe, Khaph,
-
- Lamadh, Mim, Nun, Semkath,
- FinalSemkath, SyriacE, Pe, ReversedPe,
- Sadhe, Qaph, DalathRish, Shin,
- Taw, Beth, Gamal, DalathRish,
-
- Transparent, Transparent, Transparent, Transparent,
- Transparent, Transparent, Transparent, Transparent,
- Transparent, Transparent, Transparent, Transparent,
- Transparent, Transparent, Transparent, Transparent,
-
- Transparent, Transparent, Transparent, Transparent,
- Transparent, Transparent, Transparent, Transparent,
- Transparent, Transparent, Transparent, ArabicNone,
- ArabicNone, Zhain, Khaph, Fe,
-};
-
-static ArabicGroup arabicGroup(unsigned short uc)
-{
- if (uc >= 0x0600 && uc < 0x750)
- return (ArabicGroup) arabic_group[uc-0x600];
- else if (uc == 0x200d)
- return Center;
- else if (HB_GetUnicodeCharCategory(uc) == HB_Separator_Space)
- return ArabicSpace;
- else
- return ArabicNone;
-}
-
-
-/*
- Arabic shaping obeys a number of rules according to the joining classes (see Unicode book, section on
- arabic).
-
- Each unicode char has a joining class (right, dual (left&right), center (joincausing) or transparent).
- transparent joining is not encoded in HB_UChar16::joining(), but applies to all combining marks and format marks.
-
- Right join-causing: dual + center
- Left join-causing: dual + right + center
-
- Rules are as follows (for a string already in visual order, as we have it here):
-
- R1 Transparent characters do not affect joining behaviour.
- R2 A right joining character, that has a right join-causing char on the right will get form XRight
- (R3 A left joining character, that has a left join-causing char on the left will get form XLeft)
- Note: the above rule is meaningless, as there are no pure left joining characters defined in Unicode
- R4 A dual joining character, that has a left join-causing char on the left and a right join-causing char on
- the right will get form XMedial
- R5 A dual joining character, that has a right join causing char on the right, and no left join causing char on the left
- will get form XRight
- R6 A dual joining character, that has a left join causing char on the left, and no right join causing char on the right
- will get form XLeft
- R7 Otherwise the character will get form XIsolated
-
- Additionally we have to do the minimal ligature support for lam-alef ligatures:
-
- L1 Transparent characters do not affect ligature behaviour.
- L2 Any sequence of Alef(XRight) + Lam(XMedial) will form the ligature Alef.Lam(XLeft)
- L3 Any sequence of Alef(XRight) + Lam(XLeft) will form the ligature Alef.Lam(XIsolated)
-
- The state table below handles rules R1-R7.
-*/
-
-typedef enum {
- JNone,
- JCausing,
- JDual,
- JRight,
- JTransparent
-} Joining;
-
-static const Joining joining_for_group[ArabicGroupsEnd] = {
- /* NonJoining */
- JNone, /* ArabicNone */
- JNone, /* ArabicSpace */
- /* Transparent */
- JTransparent, /* Transparent */
- /* Causing */
- JCausing, /* Center */
- JCausing, /* Kashida */
- /* Dual */
- JDual, /* Beh */
- JDual, /* Noon */
- JDual, /* Yeh */
- JDual, /* Hah */
- JDual, /* Seen */
- JDual, /* Tah */
- JDual, /* Ain */
- /* Right */
- JRight, /* Alef */
- JRight, /* Waw */
- JRight, /* Dal */
- JRight, /* Reh */
- JRight /* TehMarbutaGoal */
-};
-
-
-typedef struct {
- ArabicShape form1;
- ArabicShape form2;
-} JoiningPair;
-
-static const JoiningPair joining_table[5][4] =
-/* None, Causing, Dual, Right */
-{
- { { XIsolated, XIsolated }, { XIsolated, XCausing }, { XIsolated, XInitial }, { XIsolated, XIsolated } }, /* XIsolated */
- { { XFinal, XIsolated }, { XFinal, XCausing }, { XFinal, XInitial }, { XFinal, XIsolated } }, /* XFinal */
- { { XIsolated, XIsolated }, { XInitial, XCausing }, { XInitial, XMedial }, { XInitial, XFinal } }, /* XInitial */
- { { XFinal, XIsolated }, { XMedial, XCausing }, { XMedial, XMedial }, { XMedial, XFinal } }, /* XMedial */
- { { XIsolated, XIsolated }, { XIsolated, XCausing }, { XIsolated, XMedial }, { XIsolated, XFinal } }, /* XCausing */
-};
-
-
-/*
-According to http://www.microsoft.com/middleeast/Arabicdev/IE6/KBase.asp
-
-1. Find the priority of the connecting opportunities in each word
-2. Add expansion at the highest priority connection opportunity
-3. If more than one connection opportunity have the same highest value,
- use the opportunity closest to the end of the word.
-
-Following is a chart that provides the priority for connection
-opportunities and where expansion occurs. The character group names
-are those in table 6.6 of the UNICODE 2.0 book.
-
-
-PrioritY Glyph Condition Kashida Location
-
-Arabic_Kashida User inserted Kashida The user entered a Kashida in a position. After the user
- (Shift+j or Shift+[E with hat]) Thus, it is the highest priority to insert an inserted kashida
- automatic kashida.
-
-Arabic_Seen Seen, Sad Connecting to the next character. After the character.
- (Initial or medial form).
-
-Arabic_HaaDal Teh Marbutah, Haa, Dal Connecting to previous character. Before the final form
- of these characters.
-
-Arabic_Alef Alef, Tah, Lam, Connecting to previous character. Before the final form
- Kaf and Gaf of these characters.
-
-Arabic_BaRa Reh, Yeh Connected to medial Beh Before preceding medial Baa
-
-Arabic_Waw Waw, Ain, Qaf, Feh Connecting to previous character. Before the final form of
- these characters.
-
-Arabic_Normal Other connecting Connecting to previous character. Before the final form
- characters of these characters.
-
-
-
-This seems to imply that we have at most one kashida point per arabic word.
-
-*/
-
-static void getArabicProperties(const unsigned short *chars, int len, HB_ArabicProperties *properties)
-{
-/* qDebug("arabicSyriacOpenTypeShape: properties:"); */
- int lastPos = 0;
- int lastGroup = ArabicNone;
- int i = 0;
-
- ArabicGroup group = arabicGroup(chars[0]);
- Joining j = joining_for_group[group];
- ArabicShape shape = joining_table[XIsolated][j].form2;
- properties[0].justification = HB_NoJustification;
-
- for (i = 1; i < len; ++i) {
- /* #### fix handling for spaces and punktuation */
- properties[i].justification = HB_NoJustification;
-
- group = arabicGroup(chars[i]);
- j = joining_for_group[group];
-
- if (j == JTransparent) {
- properties[i].shape = XIsolated;
- continue;
- }
-
- properties[lastPos].shape = joining_table[shape][j].form1;
- shape = joining_table[shape][j].form2;
-
- switch(lastGroup) {
- case Seen:
- if (properties[lastPos].shape == XInitial || properties[lastPos].shape == XMedial)
- properties[i-1].justification = HB_Arabic_Seen;
- break;
- case Hah:
- if (properties[lastPos].shape == XFinal)
- properties[lastPos-1].justification = HB_Arabic_HaaDal;
- break;
- case Alef:
- if (properties[lastPos].shape == XFinal)
- properties[lastPos-1].justification = HB_Arabic_Alef;
- break;
- case Ain:
- if (properties[lastPos].shape == XFinal)
- properties[lastPos-1].justification = HB_Arabic_Waw;
- break;
- case Noon:
- if (properties[lastPos].shape == XFinal)
- properties[lastPos-1].justification = HB_Arabic_Normal;
- break;
- case ArabicNone:
- break;
-
- default:
- assert(FALSE);
- }
-
- lastGroup = ArabicNone;
-
- switch(group) {
- case ArabicNone:
- case Transparent:
- /* ### Center should probably be treated as transparent when it comes to justification. */
- case Center:
- break;
- case ArabicSpace:
- properties[i].justification = HB_Arabic_Space;
- break;
- case Kashida:
- properties[i].justification = HB_Arabic_Kashida;
- break;
- case Seen:
- lastGroup = Seen;
- break;
-
- case Hah:
- case Dal:
- lastGroup = Hah;
- break;
-
- case Alef:
- case Tah:
- lastGroup = Alef;
- break;
-
- case Yeh:
- case Reh:
- if (properties[lastPos].shape == XMedial && arabicGroup(chars[lastPos]) == Beh)
- properties[lastPos-1].justification = HB_Arabic_BaRa;
- break;
-
- case Ain:
- case Waw:
- lastGroup = Ain;
- break;
-
- case Noon:
- case Beh:
- case TehMarbutaGoal:
- lastGroup = Noon;
- break;
- case ArabicGroupsEnd:
- assert(FALSE);
- }
-
- lastPos = i;
- }
- properties[lastPos].shape = joining_table[shape][JNone].form1;
-
-
- /*
- for (int i = 0; i < len; ++i)
- qDebug("arabic properties(%d): uc=%x shape=%d, justification=%d", i, chars[i], properties[i].shape, properties[i].justification);
- */
-}
-
-static Joining getNkoJoining(unsigned short uc)
-{
- if (uc < 0x7ca)
- return JNone;
- if (uc <= 0x7ea)
- return JDual;
- if (uc <= 0x7f3)
- return JTransparent;
- if (uc <= 0x7f9)
- return JNone;
- if (uc == 0x7fa)
- return JCausing;
- return JNone;
-}
-
-static void getNkoProperties(const unsigned short *chars, int len, HB_ArabicProperties *properties)
-{
- int lastPos = 0;
- int i = 0;
-
- Joining j = getNkoJoining(chars[0]);
- ArabicShape shape = joining_table[XIsolated][j].form2;
- properties[0].justification = HB_NoJustification;
-
- for (i = 1; i < len; ++i) {
- properties[i].justification = (HB_GetUnicodeCharCategory(chars[i]) == HB_Separator_Space) ?
- ArabicSpace : ArabicNone;
-
- j = getNkoJoining(chars[i]);
-
- if (j == JTransparent) {
- properties[i].shape = XIsolated;
- continue;
- }
-
- properties[lastPos].shape = joining_table[shape][j].form1;
- shape = joining_table[shape][j].form2;
-
-
- lastPos = i;
- }
- properties[lastPos].shape = joining_table[shape][JNone].form1;
-
-
- /*
- for (int i = 0; i < len; ++i)
- qDebug("nko properties(%d): uc=%x shape=%d, justification=%d", i, chars[i], properties[i].shape, properties[i].justification);
- */
-}
-
-/*
-// The unicode to unicode shaping codec.
-// does only presentation forms B at the moment, but that should be enough for
-// simple display
-*/
-static const hb_uint16 arabicUnicodeMapping[256][2] = {
- /* base of shaped forms, and number-1 of them (0 for non shaping,
- 1 for right binding and 3 for dual binding */
-
- /* These are just the glyphs available in Unicode,
- some characters are in R class, but have no glyphs in Unicode. */
-
- { 0x0600, 0 }, /* 0x0600 */
- { 0x0601, 0 }, /* 0x0601 */
- { 0x0602, 0 }, /* 0x0602 */
- { 0x0603, 0 }, /* 0x0603 */
- { 0x0604, 0 }, /* 0x0604 */
- { 0x0605, 0 }, /* 0x0605 */
- { 0x0606, 0 }, /* 0x0606 */
- { 0x0607, 0 }, /* 0x0607 */
- { 0x0608, 0 }, /* 0x0608 */
- { 0x0609, 0 }, /* 0x0609 */
- { 0x060A, 0 }, /* 0x060A */
- { 0x060B, 0 }, /* 0x060B */
- { 0x060C, 0 }, /* 0x060C */
- { 0x060D, 0 }, /* 0x060D */
- { 0x060E, 0 }, /* 0x060E */
- { 0x060F, 0 }, /* 0x060F */
-
- { 0x0610, 0 }, /* 0x0610 */
- { 0x0611, 0 }, /* 0x0611 */
- { 0x0612, 0 }, /* 0x0612 */
- { 0x0613, 0 }, /* 0x0613 */
- { 0x0614, 0 }, /* 0x0614 */
- { 0x0615, 0 }, /* 0x0615 */
- { 0x0616, 0 }, /* 0x0616 */
- { 0x0617, 0 }, /* 0x0617 */
- { 0x0618, 0 }, /* 0x0618 */
- { 0x0619, 0 }, /* 0x0619 */
- { 0x061A, 0 }, /* 0x061A */
- { 0x061B, 0 }, /* 0x061B */
- { 0x061C, 0 }, /* 0x061C */
- { 0x061D, 0 }, /* 0x061D */
- { 0x061E, 0 }, /* 0x061E */
- { 0x061F, 0 }, /* 0x061F */
-
- { 0x0620, 0 }, /* 0x0620 */
- { 0xFE80, 0 }, /* 0x0621 HAMZA */
- { 0xFE81, 1 }, /* 0x0622 R ALEF WITH MADDA ABOVE */
- { 0xFE83, 1 }, /* 0x0623 R ALEF WITH HAMZA ABOVE */
- { 0xFE85, 1 }, /* 0x0624 R WAW WITH HAMZA ABOVE */
- { 0xFE87, 1 }, /* 0x0625 R ALEF WITH HAMZA BELOW */
- { 0xFE89, 3 }, /* 0x0626 D YEH WITH HAMZA ABOVE */
- { 0xFE8D, 1 }, /* 0x0627 R ALEF */
- { 0xFE8F, 3 }, /* 0x0628 D BEH */
- { 0xFE93, 1 }, /* 0x0629 R TEH MARBUTA */
- { 0xFE95, 3 }, /* 0x062A D TEH */
- { 0xFE99, 3 }, /* 0x062B D THEH */
- { 0xFE9D, 3 }, /* 0x062C D JEEM */
- { 0xFEA1, 3 }, /* 0x062D D HAH */
- { 0xFEA5, 3 }, /* 0x062E D KHAH */
- { 0xFEA9, 1 }, /* 0x062F R DAL */
-
- { 0xFEAB, 1 }, /* 0x0630 R THAL */
- { 0xFEAD, 1 }, /* 0x0631 R REH */
- { 0xFEAF, 1 }, /* 0x0632 R ZHAIN */
- { 0xFEB1, 3 }, /* 0x0633 D SEEN */
- { 0xFEB5, 3 }, /* 0x0634 D SHEEN */
- { 0xFEB9, 3 }, /* 0x0635 D SAD */
- { 0xFEBD, 3 }, /* 0x0636 D DAD */
- { 0xFEC1, 3 }, /* 0x0637 D TAH */
- { 0xFEC5, 3 }, /* 0x0638 D ZAH */
- { 0xFEC9, 3 }, /* 0x0639 D AIN */
- { 0xFECD, 3 }, /* 0x063A D GHAIN */
- { 0x063B, 0 }, /* 0x063B */
- { 0x063C, 0 }, /* 0x063C */
- { 0x063D, 0 }, /* 0x063D */
- { 0x063E, 0 }, /* 0x063E */
- { 0x063F, 0 }, /* 0x063F */
-
- { 0x0640, 0 }, /* 0x0640 C TATWEEL // ### Join Causing, only one glyph */
- { 0xFED1, 3 }, /* 0x0641 D FEH */
- { 0xFED5, 3 }, /* 0x0642 D QAF */
- { 0xFED9, 3 }, /* 0x0643 D KAF */
- { 0xFEDD, 3 }, /* 0x0644 D LAM */
- { 0xFEE1, 3 }, /* 0x0645 D MEEM */
- { 0xFEE5, 3 }, /* 0x0646 D NOON */
- { 0xFEE9, 3 }, /* 0x0647 D HEH */
- { 0xFEED, 1 }, /* 0x0648 R WAW */
- { 0x0649, 3 }, /* 0x0649 ALEF MAKSURA // ### Dual, glyphs not consecutive, handle in code. */
- { 0xFEF1, 3 }, /* 0x064A D YEH */
- { 0x064B, 0 }, /* 0x064B */
- { 0x064C, 0 }, /* 0x064C */
- { 0x064D, 0 }, /* 0x064D */
- { 0x064E, 0 }, /* 0x064E */
- { 0x064F, 0 }, /* 0x064F */
-
- { 0x0650, 0 }, /* 0x0650 */
- { 0x0651, 0 }, /* 0x0651 */
- { 0x0652, 0 }, /* 0x0652 */
- { 0x0653, 0 }, /* 0x0653 */
- { 0x0654, 0 }, /* 0x0654 */
- { 0x0655, 0 }, /* 0x0655 */
- { 0x0656, 0 }, /* 0x0656 */
- { 0x0657, 0 }, /* 0x0657 */
- { 0x0658, 0 }, /* 0x0658 */
- { 0x0659, 0 }, /* 0x0659 */
- { 0x065A, 0 }, /* 0x065A */
- { 0x065B, 0 }, /* 0x065B */
- { 0x065C, 0 }, /* 0x065C */
- { 0x065D, 0 }, /* 0x065D */
- { 0x065E, 0 }, /* 0x065E */
- { 0x065F, 0 }, /* 0x065F */
-
- { 0x0660, 0 }, /* 0x0660 */
- { 0x0661, 0 }, /* 0x0661 */
- { 0x0662, 0 }, /* 0x0662 */
- { 0x0663, 0 }, /* 0x0663 */
- { 0x0664, 0 }, /* 0x0664 */
- { 0x0665, 0 }, /* 0x0665 */
- { 0x0666, 0 }, /* 0x0666 */
- { 0x0667, 0 }, /* 0x0667 */
- { 0x0668, 0 }, /* 0x0668 */
- { 0x0669, 0 }, /* 0x0669 */
- { 0x066A, 0 }, /* 0x066A */
- { 0x066B, 0 }, /* 0x066B */
- { 0x066C, 0 }, /* 0x066C */
- { 0x066D, 0 }, /* 0x066D */
- { 0x066E, 0 }, /* 0x066E */
- { 0x066F, 0 }, /* 0x066F */
-
- { 0x0670, 0 }, /* 0x0670 */
- { 0xFB50, 1 }, /* 0x0671 R ALEF WASLA */
- { 0x0672, 0 }, /* 0x0672 */
- { 0x0673, 0 }, /* 0x0673 */
- { 0x0674, 0 }, /* 0x0674 */
- { 0x0675, 0 }, /* 0x0675 */
- { 0x0676, 0 }, /* 0x0676 */
- { 0x0677, 0 }, /* 0x0677 */
- { 0x0678, 0 }, /* 0x0678 */
- { 0xFB66, 3 }, /* 0x0679 D TTEH */
- { 0xFB5E, 3 }, /* 0x067A D TTEHEH */
- { 0xFB52, 3 }, /* 0x067B D BEEH */
- { 0x067C, 0 }, /* 0x067C */
- { 0x067D, 0 }, /* 0x067D */
- { 0xFB56, 3 }, /* 0x067E D PEH */
- { 0xFB62, 3 }, /* 0x067F D TEHEH */
-
- { 0xFB5A, 3 }, /* 0x0680 D BEHEH */
- { 0x0681, 0 }, /* 0x0681 */
- { 0x0682, 0 }, /* 0x0682 */
- { 0xFB76, 3 }, /* 0x0683 D NYEH */
- { 0xFB72, 3 }, /* 0x0684 D DYEH */
- { 0x0685, 0 }, /* 0x0685 */
- { 0xFB7A, 3 }, /* 0x0686 D TCHEH */
- { 0xFB7E, 3 }, /* 0x0687 D TCHEHEH */
- { 0xFB88, 1 }, /* 0x0688 R DDAL */
- { 0x0689, 0 }, /* 0x0689 */
- { 0x068A, 0 }, /* 0x068A */
- { 0x068B, 0 }, /* 0x068B */
- { 0xFB84, 1 }, /* 0x068C R DAHAL */
- { 0xFB82, 1 }, /* 0x068D R DDAHAL */
- { 0xFB86, 1 }, /* 0x068E R DUL */
- { 0x068F, 0 }, /* 0x068F */
-
- { 0x0690, 0 }, /* 0x0690 */
- { 0xFB8C, 1 }, /* 0x0691 R RREH */
- { 0x0692, 0 }, /* 0x0692 */
- { 0x0693, 0 }, /* 0x0693 */
- { 0x0694, 0 }, /* 0x0694 */
- { 0x0695, 0 }, /* 0x0695 */
- { 0x0696, 0 }, /* 0x0696 */
- { 0x0697, 0 }, /* 0x0697 */
- { 0xFB8A, 1 }, /* 0x0698 R JEH */
- { 0x0699, 0 }, /* 0x0699 */
- { 0x069A, 0 }, /* 0x069A */
- { 0x069B, 0 }, /* 0x069B */
- { 0x069C, 0 }, /* 0x069C */
- { 0x069D, 0 }, /* 0x069D */
- { 0x069E, 0 }, /* 0x069E */
- { 0x069F, 0 }, /* 0x069F */
-
- { 0x06A0, 0 }, /* 0x06A0 */
- { 0x06A1, 0 }, /* 0x06A1 */
- { 0x06A2, 0 }, /* 0x06A2 */
- { 0x06A3, 0 }, /* 0x06A3 */
- { 0xFB6A, 3 }, /* 0x06A4 D VEH */
- { 0x06A5, 0 }, /* 0x06A5 */
- { 0xFB6E, 3 }, /* 0x06A6 D PEHEH */
- { 0x06A7, 0 }, /* 0x06A7 */
- { 0x06A8, 0 }, /* 0x06A8 */
- { 0xFB8E, 3 }, /* 0x06A9 D KEHEH */
- { 0x06AA, 0 }, /* 0x06AA */
- { 0x06AB, 0 }, /* 0x06AB */
- { 0x06AC, 0 }, /* 0x06AC */
- { 0xFBD3, 3 }, /* 0x06AD D NG */
- { 0x06AE, 0 }, /* 0x06AE */
- { 0xFB92, 3 }, /* 0x06AF D GAF */
-
- { 0x06B0, 0 }, /* 0x06B0 */
- { 0xFB9A, 3 }, /* 0x06B1 D NGOEH */
- { 0x06B2, 0 }, /* 0x06B2 */
- { 0xFB96, 3 }, /* 0x06B3 D GUEH */
- { 0x06B4, 0 }, /* 0x06B4 */
- { 0x06B5, 0 }, /* 0x06B5 */
- { 0x06B6, 0 }, /* 0x06B6 */
- { 0x06B7, 0 }, /* 0x06B7 */
- { 0x06B8, 0 }, /* 0x06B8 */
- { 0x06B9, 0 }, /* 0x06B9 */
- { 0xFB9E, 1 }, /* 0x06BA R NOON GHUNNA */
- { 0xFBA0, 3 }, /* 0x06BB D RNOON */
- { 0x06BC, 0 }, /* 0x06BC */
- { 0x06BD, 0 }, /* 0x06BD */
- { 0xFBAA, 3 }, /* 0x06BE D HEH DOACHASHMEE */
- { 0x06BF, 0 }, /* 0x06BF */
-
- { 0xFBA4, 1 }, /* 0x06C0 R HEH WITH YEH ABOVE */
- { 0xFBA6, 3 }, /* 0x06C1 D HEH GOAL */
- { 0x06C2, 0 }, /* 0x06C2 */
- { 0x06C3, 0 }, /* 0x06C3 */
- { 0x06C4, 0 }, /* 0x06C4 */
- { 0xFBE0, 1 }, /* 0x06C5 R KIRGHIZ OE */
- { 0xFBD9, 1 }, /* 0x06C6 R OE */
- { 0xFBD7, 1 }, /* 0x06C7 R U */
- { 0xFBDB, 1 }, /* 0x06C8 R YU */
- { 0xFBE2, 1 }, /* 0x06C9 R KIRGHIZ YU */
- { 0x06CA, 0 }, /* 0x06CA */
- { 0xFBDE, 1 }, /* 0x06CB R VE */
- { 0xFBFC, 3 }, /* 0x06CC D FARSI YEH */
- { 0x06CD, 0 }, /* 0x06CD */
- { 0x06CE, 0 }, /* 0x06CE */
- { 0x06CF, 0 }, /* 0x06CF */
-
- { 0xFBE4, 3 }, /* 0x06D0 D E */
- { 0x06D1, 0 }, /* 0x06D1 */
- { 0xFBAE, 1 }, /* 0x06D2 R YEH BARREE */
- { 0xFBB0, 1 }, /* 0x06D3 R YEH BARREE WITH HAMZA ABOVE */
- { 0x06D4, 0 }, /* 0x06D4 */
- { 0x06D5, 0 }, /* 0x06D5 */
- { 0x06D6, 0 }, /* 0x06D6 */
- { 0x06D7, 0 }, /* 0x06D7 */
- { 0x06D8, 0 }, /* 0x06D8 */
- { 0x06D9, 0 }, /* 0x06D9 */
- { 0x06DA, 0 }, /* 0x06DA */
- { 0x06DB, 0 }, /* 0x06DB */
- { 0x06DC, 0 }, /* 0x06DC */
- { 0x06DD, 0 }, /* 0x06DD */
- { 0x06DE, 0 }, /* 0x06DE */
- { 0x06DF, 0 }, /* 0x06DF */
-
- { 0x06E0, 0 }, /* 0x06E0 */
- { 0x06E1, 0 }, /* 0x06E1 */
- { 0x06E2, 0 }, /* 0x06E2 */
- { 0x06E3, 0 }, /* 0x06E3 */
- { 0x06E4, 0 }, /* 0x06E4 */
- { 0x06E5, 0 }, /* 0x06E5 */
- { 0x06E6, 0 }, /* 0x06E6 */
- { 0x06E7, 0 }, /* 0x06E7 */
- { 0x06E8, 0 }, /* 0x06E8 */
- { 0x06E9, 0 }, /* 0x06E9 */
- { 0x06EA, 0 }, /* 0x06EA */
- { 0x06EB, 0 }, /* 0x06EB */
- { 0x06EC, 0 }, /* 0x06EC */
- { 0x06ED, 0 }, /* 0x06ED */
- { 0x06EE, 0 }, /* 0x06EE */
- { 0x06EF, 0 }, /* 0x06EF */
-
- { 0x06F0, 0 }, /* 0x06F0 */
- { 0x06F1, 0 }, /* 0x06F1 */
- { 0x06F2, 0 }, /* 0x06F2 */
- { 0x06F3, 0 }, /* 0x06F3 */
- { 0x06F4, 0 }, /* 0x06F4 */
- { 0x06F5, 0 }, /* 0x06F5 */
- { 0x06F6, 0 }, /* 0x06F6 */
- { 0x06F7, 0 }, /* 0x06F7 */
- { 0x06F8, 0 }, /* 0x06F8 */
- { 0x06F9, 0 }, /* 0x06F9 */
- { 0x06FA, 0 }, /* 0x06FA */
- { 0x06FB, 0 }, /* 0x06FB */
- { 0x06FC, 0 }, /* 0x06FC */
- { 0x06FD, 0 }, /* 0x06FD */
- { 0x06FE, 0 }, /* 0x06FE */
- { 0x06FF, 0 } /* 0x06FF */
-};
-
-/* the arabicUnicodeMapping does not work for U+0649 ALEF MAKSURA, this table does */
-static const hb_uint16 alefMaksura[4] = {0xFEEF, 0xFEF0, 0xFBE8, 0xFBE9};
-
-/*
-// this is a bit tricky. Alef always binds to the right, so the second parameter descibing the shape
-// of the lam can be either initial of medial. So initial maps to the isolated form of the ligature,
-// medial to the final form
-*/
-static const hb_uint16 arabicUnicodeLamAlefMapping[6][4] = {
- { 0xfffd, 0xfffd, 0xfef5, 0xfef6 }, /* 0x622 R Alef with Madda above */
- { 0xfffd, 0xfffd, 0xfef7, 0xfef8 }, /* 0x623 R Alef with Hamza above */
- { 0xfffd, 0xfffd, 0xfffd, 0xfffd }, /* 0x624 // Just to fill the table ;-) */
- { 0xfffd, 0xfffd, 0xfef9, 0xfefa }, /* 0x625 R Alef with Hamza below */
- { 0xfffd, 0xfffd, 0xfffd, 0xfffd }, /* 0x626 // Just to fill the table ;-) */
- { 0xfffd, 0xfffd, 0xfefb, 0xfefc } /* 0x627 R Alef */
-};
-
-static int getShape(hb_uint8 cell, int shape)
-{
- /* the arabicUnicodeMapping does not work for U+0649 ALEF MAKSURA, handle this here */
- int ch = (cell != 0x49)
- ? (shape ? arabicUnicodeMapping[cell][0] + shape : 0x600+cell)
- : alefMaksura[shape] ;
- return ch;
-}
-
-
-/*
- Two small helper functions for arabic shaping.
-*/
-static HB_UChar16 prevChar(const HB_UChar16 *str, int pos)
-{
- /*qDebug("leftChar: pos=%d", pos); */
- const HB_UChar16 *ch = str + pos - 1;
- pos--;
- while(pos > -1) {
- if(HB_GetUnicodeCharCategory(*ch) != HB_Mark_NonSpacing)
- return *ch;
- pos--;
- ch--;
- }
- return ReplacementCharacter;
-}
-
-static HB_UChar16 nextChar(const HB_UChar16 *str, hb_uint32 len, hb_uint32 pos)
-{
- const HB_UChar16 *ch = str + pos + 1;
- pos++;
- while(pos < len) {
- /*qDebug("rightChar: %d isLetter=%d, joining=%d", pos, ch.isLetter(), ch.joining()); */
- if(HB_GetUnicodeCharCategory(*ch) != HB_Mark_NonSpacing)
- return *ch;
- /* assume it's a transparent char, this might not be 100% correct */
- pos++;
- ch++;
- }
- return ReplacementCharacter;
-}
-
-static void shapedString(const HB_UChar16 *uc, hb_uint32 stringLength, hb_uint32 from, hb_uint32 len, HB_UChar16 *shapeBuffer, int *shapedLength,
- HB_Bool reverse, HB_GlyphAttributes *attributes, unsigned short *logClusters)
-{
- HB_ArabicProperties *properties;
- hb_int32 f = from;
- hb_uint32 l = len;
- const HB_UChar16 *ch;
- HB_UChar16 *data;
- int clusterStart;
- hb_uint32 i;
- HB_STACKARRAY(HB_ArabicProperties, props, len + 2);
- properties = props;
-
- assert(stringLength >= from + len);
-
- if(len == 0) {
- *shapedLength = 0;
- return;
- }
-
- if (from > 0) {
- --f;
- ++l;
- ++properties;
- }
- if (f + l < stringLength)
- ++l;
- getArabicProperties(uc+f, l, props);
-
- ch = uc + from;
- data = shapeBuffer;
- clusterStart = 0;
-
- for (i = 0; i < len; i++) {
- hb_uint8 r = *ch >> 8;
- const int gpos = int(data - shapeBuffer);
-
- if (r != 0x06) {
- if (r == 0x20) {
- if (*ch == 0x200c || *ch == 0x200d)
- /* remove ZWJ and ZWNJ */
- goto skip;
- }
- if (reverse)
- *data = HB_GetMirroredChar(*ch);
- else
- *data = *ch;
- } else {
- hb_uint8 c = *ch & 0xff;
- int pos = i + from;
- int shape = properties[i].shape;
-/* qDebug("mapping U+%x to shape %d glyph=0x%x", ch->unicode(), shape, getShape(c, shape)); */
- /* take care of lam-alef ligatures (lam right of alef) */
- hb_uint16 map;
- switch (c) {
- case 0x44: { /* lam */
- const HB_UChar16 pch = nextChar(uc, stringLength, pos);
- if ((pch >> 8) == 0x06) {
- switch (pch & 0xff) {
- case 0x22:
- case 0x23:
- case 0x25:
- case 0x27:
-/* qDebug(" lam of lam-alef ligature"); */
- map = arabicUnicodeLamAlefMapping[(pch & 0xff) - 0x22][shape];
- goto next;
- default:
- break;
- }
- }
- break;
- }
- case 0x22: /* alef with madda */
- case 0x23: /* alef with hamza above */
- case 0x25: /* alef with hamza below */
- case 0x27: /* alef */
- if (prevChar(uc, pos) == 0x0644) {
- /* have a lam alef ligature */
- /*qDebug(" alef of lam-alef ligature"); */
- goto skip;
- }
- default:
- break;
- }
- map = getShape(c, shape);
- next:
- *data = map;
- }
- /* ##### Fixme */
- /*glyphs[gpos].attributes.zeroWidth = zeroWidth; */
- if (HB_GetUnicodeCharCategory(*ch) == HB_Mark_NonSpacing) {
- attributes[gpos].mark = TRUE;
-/* qDebug("glyph %d (char %d) is mark!", gpos, i); */
- } else {
- attributes[gpos].mark = FALSE;
- clusterStart = int(data - shapeBuffer);
- }
- attributes[gpos].clusterStart = !attributes[gpos].mark;
- attributes[gpos].combiningClass = HB_GetUnicodeCharCombiningClass(*ch);
- attributes[gpos].justification = properties[i].justification;
-/* qDebug("data[%d] = %x (from %x)", gpos, (uint)data->unicode(), ch->unicode());*/
- data++;
- skip:
- ch++;
- logClusters[i] = clusterStart;
- }
- *shapedLength = int(data - shapeBuffer);
-
- HB_FREE_STACKARRAY(props);
-}
-
-#ifndef NO_OPENTYPE
-
-static const HB_OpenTypeFeature arabic_features[] = {
- { HB_MAKE_TAG('c', 'c', 'm', 'p'), CcmpProperty },
- { HB_MAKE_TAG('i', 's', 'o', 'l'), IsolProperty },
- { HB_MAKE_TAG('f', 'i', 'n', 'a'), FinaProperty },
- { HB_MAKE_TAG('m', 'e', 'd', 'i'), MediProperty },
- { HB_MAKE_TAG('i', 'n', 'i', 't'), InitProperty },
- { HB_MAKE_TAG('r', 'l', 'i', 'g'), RligProperty },
- { HB_MAKE_TAG('c', 'a', 'l', 't'), CaltProperty },
- { HB_MAKE_TAG('l', 'i', 'g', 'a'), LigaProperty },
- { HB_MAKE_TAG('d', 'l', 'i', 'g'), DligProperty },
- { HB_MAKE_TAG('c', 's', 'w', 'h'), CswhProperty },
- /* mset is used in old Win95 fonts that don't have a 'mark' positioning table. */
- { HB_MAKE_TAG('m', 's', 'e', 't'), MsetProperty },
- {0, 0}
-};
-
-static const HB_OpenTypeFeature syriac_features[] = {
- { HB_MAKE_TAG('c', 'c', 'm', 'p'), CcmpProperty },
- { HB_MAKE_TAG('i', 's', 'o', 'l'), IsolProperty },
- { HB_MAKE_TAG('f', 'i', 'n', 'a'), FinaProperty },
- { HB_MAKE_TAG('f', 'i', 'n', '2'), FinaProperty },
- { HB_MAKE_TAG('f', 'i', 'n', '3'), FinaProperty },
- { HB_MAKE_TAG('m', 'e', 'd', 'i'), MediProperty },
- { HB_MAKE_TAG('m', 'e', 'd', '2'), MediProperty },
- { HB_MAKE_TAG('i', 'n', 'i', 't'), InitProperty },
- { HB_MAKE_TAG('r', 'l', 'i', 'g'), RligProperty },
- { HB_MAKE_TAG('c', 'a', 'l', 't'), CaltProperty },
- { HB_MAKE_TAG('l', 'i', 'g', 'a'), LigaProperty },
- { HB_MAKE_TAG('d', 'l', 'i', 'g'), DligProperty },
- {0, 0}
-};
-
-static HB_Bool arabicSyriacOpenTypeShape(HB_ShaperItem *item, HB_Bool *ot_ok)
-{
- const HB_UChar16 *uc;
- const int nglyphs = item->num_glyphs;
- hb_int32 f;
- hb_uint32 l;
- HB_ArabicProperties *properties;
- HB_DECLARE_STACKARRAY(HB_ArabicProperties, props)
- HB_DECLARE_STACKARRAY(hb_uint32, apply)
- HB_Bool shaped;
- int i = 0;
-
- *ot_ok = TRUE;
-
- if (!HB_ConvertStringToGlyphIndices(item))
- return FALSE;
- HB_HeuristicSetGlyphAttributes(item);
-
- HB_INIT_STACKARRAY(HB_ArabicProperties, props, item->item.length + 2);
- HB_INIT_STACKARRAY(hb_uint32, apply, item->num_glyphs);
-
- uc = item->string + item->item.pos;
-
- properties = props;
- f = 0;
- l = item->item.length;
- if (item->item.pos > 0) {
- --f;
- ++l;
- ++properties;
- }
- if (f + l + item->item.pos < item->stringLength) {
- ++l;
- }
- if (item->item.script == HB_Script_Nko)
- getNkoProperties(uc+f, l, props);
- else
- getArabicProperties(uc+f, l, props);
-
- for (i = 0; i < (int)item->num_glyphs; i++) {
- apply[i] = 0;
-
- if (properties[i].shape == XIsolated)
- apply[i] |= MediProperty|FinaProperty|InitProperty;
- else if (properties[i].shape == XMedial)
- apply[i] |= IsolProperty|FinaProperty|InitProperty;
- else if (properties[i].shape == XFinal)
- apply[i] |= IsolProperty|MediProperty|InitProperty;
- else if (properties[i].shape == XInitial)
- apply[i] |= IsolProperty|MediProperty|FinaProperty;
-
- item->attributes[i].justification = properties[i].justification;
- }
-
- HB_FREE_STACKARRAY(props);
-
- shaped = HB_OpenTypeShape(item, apply);
-
- HB_FREE_STACKARRAY(apply);
-
- if (!shaped) {
- *ot_ok = FALSE;
- return FALSE;
- }
- return HB_OpenTypePosition(item, nglyphs, /*doLogClusters*/TRUE);
-}
-
-#endif
-
-/* #### stil missing: identify invalid character combinations */
-HB_Bool HB_ArabicShape(HB_ShaperItem *item)
-{
- int slen;
- HB_Bool haveGlyphs;
- HB_STACKARRAY(HB_UChar16, shapedChars, item->item.length);
-
- assert(item->item.script == HB_Script_Arabic || item->item.script == HB_Script_Syriac
- || item->item.script == HB_Script_Nko);
-
-#ifndef NO_OPENTYPE
-
- if (HB_SelectScript(item, item->item.script == HB_Script_Arabic ? arabic_features : syriac_features)) {
- HB_Bool ot_ok;
- if (arabicSyriacOpenTypeShape(item, &ot_ok)) {
- HB_FREE_STACKARRAY(shapedChars);
- return TRUE;
- }
- if (ot_ok) {
- HB_FREE_STACKARRAY(shapedChars);
- return FALSE;
- /* fall through to the non OT code*/
- }
- }
-#endif
-
- if (item->item.script != HB_Script_Arabic) {
- HB_FREE_STACKARRAY(shapedChars);
- return HB_BasicShape(item);
- }
-
- shapedString(item->string, item->stringLength, item->item.pos, item->item.length, shapedChars, &slen,
- item->item.bidiLevel % 2,
- item->attributes, item->log_clusters);
-
- haveGlyphs = item->font->klass
- ->convertStringToGlyphIndices(item->font,
- shapedChars, slen,
- item->glyphs, &item->num_glyphs,
- item->item.bidiLevel % 2);
-
- HB_FREE_STACKARRAY(shapedChars);
-
- if (!haveGlyphs)
- return FALSE;
-
- HB_HeuristicPosition(item);
- return TRUE;
-}
-
-
diff --git a/src/3rdparty/harfbuzz/src/harfbuzz-buffer-private.h b/src/3rdparty/harfbuzz/src/harfbuzz-buffer-private.h
deleted file mode 100644
index 5065f2e031..0000000000
--- a/src/3rdparty/harfbuzz/src/harfbuzz-buffer-private.h
+++ /dev/null
@@ -1,107 +0,0 @@
-/*
- * Copyright (C) 1998-2004 David Turner and Werner Lemberg
- * Copyright (C) 2004,2007 Red Hat, Inc.
- *
- * This is part of HarfBuzz, an OpenType Layout engine library.
- *
- * Permission is hereby granted, without written agreement and without
- * license or royalty fees, to use, copy, modify, and distribute this
- * software and its documentation for any purpose, provided that the
- * above copyright notice and the following two paragraphs appear in
- * all copies of this software.
- *
- * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
- * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
- * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
- * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
- * DAMAGE.
- *
- * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
- * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
- * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
- * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
- * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
- *
- * Red Hat Author(s): Owen Taylor, Behdad Esfahbod
- */
-
-#ifndef HARFBUZZ_BUFFER_PRIVATE_H
-#define HARFBUZZ_BUFFER_PRIVATE_H
-
-#include "harfbuzz-impl.h"
-#include "harfbuzz-buffer.h"
-
-HB_BEGIN_HEADER
-
-#define HB_GLYPH_PROPERTIES_UNKNOWN 0xFFFF
-
-HB_INTERNAL void
-_hb_buffer_swap( HB_Buffer buffer );
-
-HB_INTERNAL void
-_hb_buffer_clear_output( HB_Buffer buffer );
-
-HB_INTERNAL HB_Error
-_hb_buffer_clear_positions( HB_Buffer buffer );
-
-HB_INTERNAL HB_Error
-_hb_buffer_add_output_glyphs( HB_Buffer buffer,
- HB_UShort num_in,
- HB_UShort num_out,
- HB_UShort *glyph_data,
- HB_UShort component,
- HB_UShort ligID );
-
-HB_INTERNAL HB_Error
-_hb_buffer_add_output_glyph ( HB_Buffer buffer,
- HB_UInt glyph_index,
- HB_UShort component,
- HB_UShort ligID );
-
-HB_INTERNAL HB_Error
-_hb_buffer_copy_output_glyph ( HB_Buffer buffer );
-
-HB_INTERNAL HB_Error
-_hb_buffer_replace_output_glyph ( HB_Buffer buffer,
- HB_UInt glyph_index,
- HB_Bool inplace );
-
-HB_INTERNAL HB_UShort
-_hb_buffer_allocate_ligid( HB_Buffer buffer );
-
-
-/* convenience macros */
-
-#define IN_GLYPH( pos ) (buffer->in_string[(pos)].gindex)
-#define IN_ITEM( pos ) (&buffer->in_string[(pos)])
-#define IN_CURGLYPH() (buffer->in_string[buffer->in_pos].gindex)
-#define IN_CURITEM() (&buffer->in_string[buffer->in_pos])
-#define IN_PROPERTIES( pos ) (buffer->in_string[(pos)].properties)
-#define IN_LIGID( pos ) (buffer->in_string[(pos)].ligID)
-#define IN_COMPONENT( pos ) (buffer->in_string[(pos)].component)
-#define POSITION( pos ) (&buffer->positions[(pos)])
-#define OUT_GLYPH( pos ) (buffer->out_string[(pos)].gindex)
-#define OUT_ITEM( pos ) (&buffer->out_string[(pos)])
-
-#define CHECK_Property( gdef, index, flags, property ) \
- ( ( error = _HB_GDEF_Check_Property( (gdef), (index), (flags), \
- (property) ) ) != HB_Err_Ok )
-
-#define ADD_String( buffer, num_in, num_out, glyph_data, component, ligID ) \
- ( ( error = _hb_buffer_add_output_glyphs( (buffer), \
- (num_in), (num_out), \
- (glyph_data), (component), (ligID) \
- ) ) != HB_Err_Ok )
-#define ADD_Glyph( buffer, glyph_index, component, ligID ) \
- ( ( error = _hb_buffer_add_output_glyph( (buffer), \
- (glyph_index), (component), (ligID) \
- ) ) != HB_Err_Ok )
-#define REPLACE_Glyph( buffer, glyph_index, nesting_level ) \
- ( ( error = _hb_buffer_replace_output_glyph( (buffer), (glyph_index), \
- (nesting_level) == 1 ) ) != HB_Err_Ok )
-#define COPY_Glyph( buffer ) \
- ( (error = _hb_buffer_copy_output_glyph ( buffer ) ) != HB_Err_Ok )
-
-HB_END_HEADER
-
-#endif /* HARFBUZZ_BUFFER_PRIVATE_H */
diff --git a/src/3rdparty/harfbuzz/src/harfbuzz-buffer.c b/src/3rdparty/harfbuzz/src/harfbuzz-buffer.c
deleted file mode 100644
index 4d4c16717f..0000000000
--- a/src/3rdparty/harfbuzz/src/harfbuzz-buffer.c
+++ /dev/null
@@ -1,383 +0,0 @@
-/*
- * Copyright (C) 1998-2004 David Turner and Werner Lemberg
- * Copyright (C) 2004,2007 Red Hat, Inc.
- *
- * This is part of HarfBuzz, an OpenType Layout engine library.
- *
- * Permission is hereby granted, without written agreement and without
- * license or royalty fees, to use, copy, modify, and distribute this
- * software and its documentation for any purpose, provided that the
- * above copyright notice and the following two paragraphs appear in
- * all copies of this software.
- *
- * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
- * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
- * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
- * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
- * DAMAGE.
- *
- * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
- * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
- * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
- * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
- * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
- *
- * Red Hat Author(s): Owen Taylor, Behdad Esfahbod
- */
-
-#include "harfbuzz-impl.h"
-#include "harfbuzz-buffer-private.h"
-#include "harfbuzz-gsub-private.h"
-#include "harfbuzz-gpos-private.h"
-
-/* Here is how the buffer works internally:
- *
- * There are two string pointers: in_string and out_string. They
- * always have same allocated size, but different length and positions.
- *
- * As an optimization, both in_string and out_string may point to the
- * same piece of memory, which is owned by in_string. This remains the
- * case as long as:
- *
- * - copy_glyph() is called
- * - replace_glyph() is called with inplace=TRUE
- * - add_output_glyph() and add_output_glyphs() are not called
- *
- * In that case swap(), and copy_glyph(), and replace_glyph() are all
- * mostly no-op.
- *
- * As soon an add_output_glyph[s]() or replace_glyph() with inplace=FALSE is
- * called, out_string is moved over to an alternate buffer (alt_string), and
- * its current contents (out_length entries) are copied to the alt buffer.
- * This should all remain transparent to the user. swap() then switches
- * in_string and alt_string. alt_string is not allocated until its needed,
- * but after that it's grown with in_string unconditionally.
- *
- * The buffer->separate_out boolean keeps status of whether out_string points
- * to in_string (FALSE) or alt_string (TRUE).
- */
-
-/* Internal API */
-
-static HB_Error
-hb_buffer_ensure( HB_Buffer buffer,
- HB_UInt size )
-{
- HB_UInt new_allocated = buffer->allocated;
-
- if (size > new_allocated)
- {
- HB_Error error;
-
- while (size > new_allocated)
- new_allocated += (new_allocated >> 1) + 8;
-
- if ( buffer->positions )
- {
- if ( REALLOC_ARRAY( buffer->positions, new_allocated, HB_PositionRec ) )
- return error;
- }
-
- if ( REALLOC_ARRAY( buffer->in_string, new_allocated, HB_GlyphItemRec ) )
- return error;
-
- if ( buffer->separate_out )
- {
- if ( REALLOC_ARRAY( buffer->alt_string, new_allocated, HB_GlyphItemRec ) )
- return error;
-
- buffer->out_string = buffer->alt_string;
- }
- else
- {
- buffer->out_string = buffer->in_string;
-
- if ( buffer->alt_string )
- {
- if ( REALLOC_ARRAY( buffer->alt_string, new_allocated, HB_GlyphItemRec ) )
- return error;
- }
- }
-
- buffer->allocated = new_allocated;
- }
-
- return HB_Err_Ok;
-}
-
-static HB_Error
-hb_buffer_duplicate_out_buffer( HB_Buffer buffer )
-{
- if ( !buffer->alt_string )
- {
- HB_Error error;
-
- if ( ALLOC_ARRAY( buffer->alt_string, buffer->allocated, HB_GlyphItemRec ) )
- return error;
- }
-
- buffer->out_string = buffer->alt_string;
- memcpy( buffer->out_string, buffer->in_string, buffer->out_length * sizeof (buffer->out_string[0]) );
- buffer->separate_out = TRUE;
-
- return HB_Err_Ok;
-}
-
-/* Public API */
-
-HB_Error
-hb_buffer_new( HB_Buffer *pbuffer )
-{
- HB_Buffer buffer;
- HB_Error error;
-
- if ( ALLOC( buffer, sizeof( HB_BufferRec ) ) )
- return error;
-
- buffer->allocated = 0;
- buffer->in_string = NULL;
- buffer->alt_string = NULL;
- buffer->positions = NULL;
-
- hb_buffer_clear( buffer );
-
- *pbuffer = buffer;
-
- return HB_Err_Ok;
-}
-
-void
-hb_buffer_free( HB_Buffer buffer )
-{
- FREE( buffer->in_string );
- FREE( buffer->alt_string );
- buffer->out_string = NULL;
- FREE( buffer->positions );
- FREE( buffer );
-}
-
-void
-hb_buffer_clear( HB_Buffer buffer )
-{
- buffer->in_length = 0;
- buffer->out_length = 0;
- buffer->in_pos = 0;
- buffer->out_pos = 0;
- buffer->out_string = buffer->in_string;
- buffer->separate_out = FALSE;
- buffer->max_ligID = 0;
-}
-
-HB_Error
-hb_buffer_add_glyph( HB_Buffer buffer,
- HB_UInt glyph_index,
- HB_UInt properties,
- HB_UInt cluster )
-{
- HB_Error error;
- HB_GlyphItem glyph;
-
- error = hb_buffer_ensure( buffer, buffer->in_length + 1 );
- if ( error )
- return error;
-
- glyph = &buffer->in_string[buffer->in_length];
- glyph->gindex = glyph_index;
- glyph->properties = properties;
- glyph->cluster = cluster;
- glyph->component = 0;
- glyph->ligID = 0;
- glyph->gproperties = HB_GLYPH_PROPERTIES_UNKNOWN;
-
- buffer->in_length++;
-
- return HB_Err_Ok;
-}
-
-/* HarfBuzz-Internal API */
-
-HB_INTERNAL void
-_hb_buffer_clear_output( HB_Buffer buffer )
-{
- buffer->out_length = 0;
- buffer->out_pos = 0;
- buffer->out_string = buffer->in_string;
- buffer->separate_out = FALSE;
-}
-
-HB_INTERNAL HB_Error
-_hb_buffer_clear_positions( HB_Buffer buffer )
-{
- if ( !buffer->positions )
- {
- HB_Error error;
-
- if ( ALLOC_ARRAY( buffer->positions, buffer->allocated, HB_PositionRec ) )
- return error;
- }
-
- memset (buffer->positions, 0, sizeof (buffer->positions[0]) * buffer->in_length);
-
- return HB_Err_Ok;
-}
-
-HB_INTERNAL void
-_hb_buffer_swap( HB_Buffer buffer )
-{
- HB_GlyphItem tmp_string;
- int tmp_length;
- int tmp_pos;
-
- if ( buffer->separate_out )
- {
- tmp_string = buffer->in_string;
- buffer->in_string = buffer->out_string;
- buffer->out_string = tmp_string;
- buffer->alt_string = buffer->out_string;
- }
-
- tmp_length = buffer->in_length;
- buffer->in_length = buffer->out_length;
- buffer->out_length = tmp_length;
-
- tmp_pos = buffer->in_pos;
- buffer->in_pos = buffer->out_pos;
- buffer->out_pos = tmp_pos;
-}
-
-/* The following function copies `num_out' elements from `glyph_data'
- to `buffer->out_string', advancing the in array pointer in the structure
- by `num_in' elements, and the out array pointer by `num_out' elements.
- Finally, it sets the `length' field of `out' equal to
- `pos' of the `out' structure.
-
- If `component' is 0xFFFF, the component value from buffer->in_pos
- will copied `num_out' times, otherwise `component' itself will
- be used to fill the `component' fields.
-
- If `ligID' is 0xFFFF, the ligID value from buffer->in_pos
- will copied `num_out' times, otherwise `ligID' itself will
- be used to fill the `ligID' fields.
-
- The properties for all replacement glyphs are taken
- from the glyph at position `buffer->in_pos'.
-
- The cluster value for the glyph at position buffer->in_pos is used
- for all replacement glyphs */
-HB_INTERNAL HB_Error
-_hb_buffer_add_output_glyphs( HB_Buffer buffer,
- HB_UShort num_in,
- HB_UShort num_out,
- HB_UShort *glyph_data,
- HB_UShort component,
- HB_UShort ligID )
-{
- HB_Error error;
- HB_UShort i;
- HB_UInt properties;
- HB_UInt cluster;
-
- error = hb_buffer_ensure( buffer, buffer->out_pos + num_out );
- if ( error )
- return error;
-
- if ( !buffer->separate_out )
- {
- error = hb_buffer_duplicate_out_buffer( buffer );
- if ( error )
- return error;
- }
-
- properties = buffer->in_string[buffer->in_pos].properties;
- cluster = buffer->in_string[buffer->in_pos].cluster;
- if ( component == 0xFFFF )
- component = buffer->in_string[buffer->in_pos].component;
- if ( ligID == 0xFFFF )
- ligID = buffer->in_string[buffer->in_pos].ligID;
-
- for ( i = 0; i < num_out; i++ )
- {
- HB_GlyphItem item = &buffer->out_string[buffer->out_pos + i];
-
- item->gindex = glyph_data[i];
- item->properties = properties;
- item->cluster = cluster;
- item->component = component;
- item->ligID = ligID;
- item->gproperties = HB_GLYPH_PROPERTIES_UNKNOWN;
- }
-
- buffer->in_pos += num_in;
- buffer->out_pos += num_out;
-
- buffer->out_length = buffer->out_pos;
-
- return HB_Err_Ok;
-}
-
-HB_INTERNAL HB_Error
-_hb_buffer_add_output_glyph( HB_Buffer buffer,
- HB_UInt glyph_index,
- HB_UShort component,
- HB_UShort ligID )
-{
- HB_UShort glyph_data = glyph_index;
-
- return _hb_buffer_add_output_glyphs ( buffer, 1, 1,
- &glyph_data, component, ligID );
-}
-
-HB_INTERNAL HB_Error
-_hb_buffer_copy_output_glyph ( HB_Buffer buffer )
-{
- HB_Error error;
-
- error = hb_buffer_ensure( buffer, buffer->out_pos + 1 );
- if ( error )
- return error;
-
- if ( buffer->separate_out )
- {
- buffer->out_string[buffer->out_pos] = buffer->in_string[buffer->in_pos];
- }
-
- buffer->in_pos++;
- buffer->out_pos++;
- buffer->out_length = buffer->out_pos;
-
- return HB_Err_Ok;
-}
-
-HB_INTERNAL HB_Error
-_hb_buffer_replace_output_glyph( HB_Buffer buffer,
- HB_UInt glyph_index,
- HB_Bool inplace )
-{
-
- HB_Error error;
-
- if ( inplace )
- {
- error = _hb_buffer_copy_output_glyph ( buffer );
- if ( error )
- return error;
-
- buffer->out_string[buffer->out_pos-1].gindex = glyph_index;
- }
- else
- {
- return _hb_buffer_add_output_glyph( buffer, glyph_index, 0xFFFF, 0xFFFF );
- }
-
- return HB_Err_Ok;
-}
-
-HB_INTERNAL HB_UShort
-_hb_buffer_allocate_ligid( HB_Buffer buffer )
-{
- buffer->max_ligID++;
- if (HB_UNLIKELY (buffer->max_ligID == 0))
- buffer->max_ligID++;
-
- return buffer->max_ligID;
-}
diff --git a/src/3rdparty/harfbuzz/src/harfbuzz-buffer.h b/src/3rdparty/harfbuzz/src/harfbuzz-buffer.h
deleted file mode 100644
index 0d631b20a6..0000000000
--- a/src/3rdparty/harfbuzz/src/harfbuzz-buffer.h
+++ /dev/null
@@ -1,94 +0,0 @@
-/*
- * Copyright (C) 1998-2004 David Turner and Werner Lemberg
- * Copyright (C) 2004,2007 Red Hat, Inc.
- *
- * This is part of HarfBuzz, an OpenType Layout engine library.
- *
- * Permission is hereby granted, without written agreement and without
- * license or royalty fees, to use, copy, modify, and distribute this
- * software and its documentation for any purpose, provided that the
- * above copyright notice and the following two paragraphs appear in
- * all copies of this software.
- *
- * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
- * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
- * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
- * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
- * DAMAGE.
- *
- * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
- * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
- * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
- * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
- * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
- *
- * Red Hat Author(s): Owen Taylor, Behdad Esfahbod
- */
-
-#ifndef HARFBUZZ_BUFFER_H
-#define HARFBUZZ_BUFFER_H
-
-#include "harfbuzz-global.h"
-
-HB_BEGIN_HEADER
-
-typedef struct HB_GlyphItemRec_ {
- HB_UInt gindex;
- HB_UInt properties;
- HB_UInt cluster;
- HB_UShort component;
- HB_UShort ligID;
- HB_UShort gproperties;
-} HB_GlyphItemRec, *HB_GlyphItem;
-
-typedef struct HB_PositionRec_ {
- HB_Fixed x_pos;
- HB_Fixed y_pos;
- HB_Fixed x_advance;
- HB_Fixed y_advance;
- HB_UShort back; /* number of glyphs to go back
- for drawing current glyph */
- HB_Short cursive_chain; /* character to which this connects,
- may be positive or negative; used
- only internally */
- HB_Bool new_advance; /* if set, the advance width values are
- absolute, i.e., they won't be
- added to the original glyph's value
- but rather replace them. */
-} HB_PositionRec, *HB_Position;
-
-
-typedef struct HB_BufferRec_{
- HB_UInt allocated;
-
- HB_UInt in_length;
- HB_UInt out_length;
- HB_UInt in_pos;
- HB_UInt out_pos;
-
- HB_GlyphItem in_string;
- HB_GlyphItem out_string;
- HB_GlyphItem alt_string;
- HB_Position positions;
- HB_UShort max_ligID;
- HB_Bool separate_out;
-} HB_BufferRec, *HB_Buffer;
-
-HB_Error
-hb_buffer_new( HB_Buffer *buffer );
-
-void
-hb_buffer_free( HB_Buffer buffer );
-
-void
-hb_buffer_clear( HB_Buffer buffer );
-
-HB_Error
-hb_buffer_add_glyph( HB_Buffer buffer,
- HB_UInt glyph_index,
- HB_UInt properties,
- HB_UInt cluster );
-
-HB_END_HEADER
-
-#endif /* HARFBUZZ_BUFFER_H */
diff --git a/src/3rdparty/harfbuzz/src/harfbuzz-dump-main.c b/src/3rdparty/harfbuzz/src/harfbuzz-dump-main.c
deleted file mode 100644
index dfb35fbaaf..0000000000
--- a/src/3rdparty/harfbuzz/src/harfbuzz-dump-main.c
+++ /dev/null
@@ -1,97 +0,0 @@
-/*
- * Copyright (C) 2000 Red Hat, Inc.
- *
- * This is part of HarfBuzz, an OpenType Layout engine library.
- *
- * Permission is hereby granted, without written agreement and without
- * license or royalty fees, to use, copy, modify, and distribute this
- * software and its documentation for any purpose, provided that the
- * above copyright notice and the following two paragraphs appear in
- * all copies of this software.
- *
- * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
- * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
- * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
- * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
- * DAMAGE.
- *
- * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
- * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
- * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
- * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
- * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
- *
- * Red Hat Author(s): Owen Taylor
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-
-#include "harfbuzz.h"
-#include "harfbuzz-dump.h"
-
-#define N_ELEMENTS(arr) (sizeof(arr)/ sizeof((arr)[0]))
-
-static int
-croak (const char *situation, HB_Error error)
-{
- fprintf (stderr, "%s: Error %d\n", situation, error);
-
- exit (1);
-}
-
-int
-main (int argc, char **argv)
-{
- HB_Error error;
- FT_Library library;
- HB_Font font;
- HB_GSUB gsub;
- HB_GPOS gpos;
-
- if (argc != 2)
- {
- fprintf (stderr, "Usage: harfbuzz-dump MYFONT.TTF\n");
- exit(1);
- }
-
- if ((error = FT_Init_FreeType (&library)))
- croak ("FT_Init_FreeType", error);
-
- if ((error = FT_New_Face (library, argv[1], 0, &font)))
- croak ("FT_New_Face", error);
-
- printf ("<?xml version=\"1.0\"?>\n");
- printf ("<OpenType>\n");
-
- if (!(error = HB_Load_GSUB_Table (font, &gsub, NULL)))
- {
- HB_Dump_GSUB_Table (gsub, stdout);
-
- if ((error = HB_Done_GSUB_Table (gsub)))
- croak ("HB_Done_GSUB_Table", error);
- }
- else if (error != HB_Err_Not_Covered)
- fprintf (stderr, "HB_Load_GSUB_Table: error 0x%x\n", error);
-
- if (!(error = HB_Load_GPOS_Table (font, &gpos, NULL)))
- {
- HB_Dump_GPOS_Table (gpos, stdout);
-
- if ((error = HB_Done_GPOS_Table (gpos)))
- croak ("HB_Done_GPOS_Table", error);
- }
- else if (error != HB_Err_Not_Covered)
- fprintf (stderr, "HB_Load_GPOS_Table: error 0x%x\n", error);
-
- printf ("</OpenType>\n");
-
- if ((error = FT_Done_Face (font)))
- croak ("FT_Done_Face", error);
-
- if ((error = FT_Done_FreeType (library)))
- croak ("FT_Done_FreeType", error);
-
- return 0;
-}
-
diff --git a/src/3rdparty/harfbuzz/src/harfbuzz-dump.c b/src/3rdparty/harfbuzz/src/harfbuzz-dump.c
deleted file mode 100644
index 54d42e93d4..0000000000
--- a/src/3rdparty/harfbuzz/src/harfbuzz-dump.c
+++ /dev/null
@@ -1,767 +0,0 @@
-/*
- * Copyright (C) 2000, 2007 Red Hat, Inc.
- *
- * This is part of HarfBuzz, an OpenType Layout engine library.
- *
- * Permission is hereby granted, without written agreement and without
- * license or royalty fees, to use, copy, modify, and distribute this
- * software and its documentation for any purpose, provided that the
- * above copyright notice and the following two paragraphs appear in
- * all copies of this software.
- *
- * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
- * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
- * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
- * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
- * DAMAGE.
- *
- * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
- * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
- * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
- * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
- * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
- *
- * Red Hat Author(s): Owen Taylor, Behdad Esfahbod
- */
-
-#include "harfbuzz-impl.h"
-#include "harfbuzz-dump.h"
-#include "harfbuzz-gdef-private.h"
-#include "harfbuzz-gsub-private.h"
-#include "harfbuzz-gpos-private.h"
-#include "harfbuzz-open-private.h"
-#include <stdarg.h>
-
-#define DUMP(format) dump (stream, indent, format)
-#define DUMP1(format, arg1) dump (stream, indent, format, arg1)
-#define DUMP2(format, arg1, arg2) dump (stream, indent, format, arg1, arg2)
-#define DUMP3(format, arg1, arg2, arg3) dump (stream, indent, format, arg1, arg2, arg3)
-
-#define DUMP_FINT(strct,fld) dump (stream, indent, "<" #fld ">%d</" #fld ">\n", (strct)->fld)
-#define DUMP_FUINT(strct,fld) dump (stream, indent, "<" #fld ">%u</" #fld ">\n", (strct)->fld)
-#define DUMP_FGLYPH(strct,fld) dump (stream, indent, "<" #fld ">%#06x</" #fld ">\n", (strct)->fld)
-#define DUMP_FGLYPH(strct,fld) dump (stream, indent, "<" #fld ">%#06x</" #fld ">\n", (strct)->fld)
-#define DUMP_USHORT_ARRAY(strct,fld,cnt) Dump_UShort_Array ((strct)->fld, cnt, #fld, stream, indent);
-
-#define DEF_DUMP(type) static void Dump_ ## type (HB_ ## type *type, FILE *stream, int indent, HB_Type hb_type)
-#define RECURSE(name, type, val) do { DUMP ("<" #name ">\n"); Dump_ ## type (val, stream, indent + 1, hb_type); DUMP ("</" #name ">\n"); } while (0)
-#define RECURSE_NUM(name, i, type, val) do { DUMP1 ("<" #name "> <!-- %d -->\n", i); Dump_ ## type (val, stream, indent + 1, hb_type); DUMP ("</" #name ">\n"); } while (0)
-#define DUMP_VALUE_RECORD(val, frmt) do { DUMP ("<ValueRecord>\n"); Dump_ValueRecord (val, stream, indent + 1, hb_type, frmt); DUMP ("</ValueRecord>\n"); } while (0)
-
-static void
-do_indent (FILE *stream, int indent)
-{
- fprintf (stream, "%*s", indent * 3, "");
-}
-
-static void
-dump (FILE *stream, int indent, const char *format, ...)
-{
- va_list list;
-
- do_indent (stream, indent);
-
- va_start (list, format);
- vfprintf (stream, format, list);
- va_end (list);
-}
-
-static void
-Dump_UShort_Array (HB_UShort *array, int count, const char *name, FILE *stream, int indent)
-{
- int i;
-
- do_indent (stream, indent);
-
- fprintf (stream, "<%s>", name);
- for (i = 0; i < count; i++)
- fprintf (stream, "%d%s", array[i], i == 0 ? "" : " ");
- fprintf (stream, "</%s>\n", name);
-}
-
-static void
-Print_Tag (HB_UInt tag, FILE *stream)
-{
- fprintf (stream, "%c%c%c%c",
- (unsigned char)(tag >> 24),
- (unsigned char)((tag >> 16) & 0xff),
- (unsigned char)((tag >> 8) & 0xff),
- (unsigned char)(tag & 0xff));
-}
-
-DEF_DUMP (LangSys)
-{
- int i;
-
- HB_UNUSED(hb_type);
-
- DUMP_FUINT (LangSys, LookupOrderOffset);
- DUMP_FUINT (LangSys, ReqFeatureIndex);
- DUMP_FUINT (LangSys, FeatureCount);
-
- for (i=0; i < LangSys->FeatureCount; i++)
- DUMP1("<FeatureIndex>%d</FeatureIndex>\n", LangSys->FeatureIndex[i]);
-}
-
-DEF_DUMP (ScriptTable)
-{
- int i;
-
- RECURSE (DefaultLangSys, LangSys, &ScriptTable->DefaultLangSys);
-
- DUMP_FUINT (ScriptTable, LangSysCount);
-
- for (i=0; i < ScriptTable->LangSysCount; i++)
- {
- do_indent (stream, indent);
- fprintf (stream, "<LangSysTag>");
- Print_Tag (ScriptTable->LangSysRecord[i].LangSysTag, stream);
- fprintf (stream, "</LangSysTag>\n");
- RECURSE_NUM (LangSys, i, LangSys, &ScriptTable->LangSysRecord[i].LangSys);
- }
-}
-
-DEF_DUMP (ScriptList)
-{
- int i;
-
- DUMP_FUINT (ScriptList, ScriptCount);
-
- for (i=0; i < ScriptList->ScriptCount; i++)
- {
- do_indent (stream, indent);
- fprintf (stream, "<ScriptTag>");
- Print_Tag (ScriptList->ScriptRecord[i].ScriptTag, stream);
- fprintf (stream, "</ScriptTag>\n");
- RECURSE_NUM (Script, i, ScriptTable, &ScriptList->ScriptRecord[i].Script);
- }
-}
-
-DEF_DUMP (Feature)
-{
- int i;
-
- HB_UNUSED(hb_type);
-
- DUMP_FUINT (Feature, FeatureParams);
- DUMP_FUINT (Feature, LookupListCount);
-
- for (i=0; i < Feature->LookupListCount; i++)
- DUMP1("<LookupIndex>%d</LookupIndex>\n", Feature->LookupListIndex[i]);
-}
-
-DEF_DUMP (MarkRecord)
-{
- HB_UNUSED(hb_type);
-
- DUMP_FUINT (MarkRecord, Class);
- DUMP1("<Anchor>%d</Anchor>\n", MarkRecord->MarkAnchor.PosFormat );
-}
-
-DEF_DUMP (MarkArray)
-{
- int i;
-
- DUMP_FUINT (MarkArray, MarkCount);
-
- for (i=0; i < MarkArray->MarkCount; i++)
- RECURSE_NUM (MarkRecord, i, MarkRecord, &MarkArray->MarkRecord[i]);
-}
-
-DEF_DUMP (FeatureList)
-{
- int i;
-
- DUMP_FUINT (FeatureList, FeatureCount);
-
- for (i=0; i < FeatureList->FeatureCount; i++)
- {
- do_indent (stream, indent);
- fprintf (stream, "<FeatureTag>");
- Print_Tag (FeatureList->FeatureRecord[i].FeatureTag, stream);
- fprintf (stream, "</FeatureTag> <!-- %d -->\n", i);
- RECURSE_NUM (Feature, i, Feature, &FeatureList->FeatureRecord[i].Feature);
- }
-}
-
-DEF_DUMP (Coverage)
-{
- HB_UNUSED(hb_type);
-
- DUMP_FUINT (Coverage, CoverageFormat);
-
- if (Coverage->CoverageFormat == 1)
- {
- int i;
- DUMP_FUINT (&Coverage->cf.cf1, GlyphCount);
-
- for (i = 0; i < Coverage->cf.cf1.GlyphCount; i++)
- DUMP2("<Glyph>%#06x</Glyph> <!-- %d -->\n",
- Coverage->cf.cf1.GlyphArray[i], i);
- }
- else
- {
- int i;
- DUMP_FUINT (&Coverage->cf.cf2, RangeCount);
-
- for ( i = 0; i < Coverage->cf.cf2.RangeCount; i++ )
- DUMP3("<Glyph>%#06x - %#06x</Glyph> <!-- %d -->\n",
- Coverage->cf.cf2.RangeRecord[i].Start,
- Coverage->cf.cf2.RangeRecord[i].End, i);
- }
-}
-
-DEF_DUMP (ClassRangeRecord)
-{
- HB_UNUSED(hb_type);
-
- DUMP_FGLYPH (ClassRangeRecord, Start);
- DUMP_FGLYPH (ClassRangeRecord, End);
- DUMP_FUINT (ClassRangeRecord, Class);
-}
-
-DEF_DUMP (ClassDefinition)
-{
- HB_UNUSED(hb_type);
-
- DUMP_FUINT( ClassDefinition, ClassFormat);
- DUMP_FUINT( ClassDefinition, loaded);
-
- if (ClassDefinition->ClassFormat == 1)
- {
- int i;
- HB_ClassDefFormat1 *ClassDefFormat1 = &ClassDefinition->cd.cd1;
- DUMP("<ClassDefinition>\n");
- DUMP_FUINT (ClassDefFormat1, StartGlyph );
- DUMP_FUINT (ClassDefFormat1, GlyphCount );
- for (i = 0; i < ClassDefFormat1->GlyphCount; i++)
- DUMP2(" <Class>%d</Class> <!-- %#06x -->", ClassDefFormat1->ClassValueArray[i],
- ClassDefFormat1->StartGlyph+i );
- }
- else if (ClassDefinition->ClassFormat == 2)
- {
- int i;
- HB_ClassDefFormat2 *ClassDefFormat2 = &ClassDefinition->cd.cd2;
- DUMP_FUINT (ClassDefFormat2, ClassRangeCount);
-
- for (i = 0; i < ClassDefFormat2->ClassRangeCount; i++)
- RECURSE_NUM (ClassRangeRecord, i, ClassRangeRecord, &ClassDefFormat2->ClassRangeRecord[i]);
- }
- else
- fprintf(stderr, "invalid class def table!!!\n");
-}
-
-DEF_DUMP (SubstLookupRecord)
-{
- HB_UNUSED(hb_type);
-
- DUMP_FUINT (SubstLookupRecord, SequenceIndex);
- DUMP_FUINT (SubstLookupRecord, LookupListIndex);
-}
-
-DEF_DUMP (ChainSubClassRule)
-{
- int i;
-
- DUMP_USHORT_ARRAY (ChainSubClassRule, Backtrack, ChainSubClassRule->BacktrackGlyphCount);
- DUMP_USHORT_ARRAY (ChainSubClassRule, Input, ChainSubClassRule->InputGlyphCount - 1);
- DUMP_USHORT_ARRAY (ChainSubClassRule, Lookahead, ChainSubClassRule->LookaheadGlyphCount);
-
- for (i = 0; i < ChainSubClassRule->SubstCount; i++)
- RECURSE_NUM (SubstLookupRecord, i, SubstLookupRecord, &ChainSubClassRule->SubstLookupRecord[i]);
-
- indent--;
-}
-
-DEF_DUMP (ChainSubClassSet)
-{
- int i;
-
- DUMP_FUINT( ChainSubClassSet, ChainSubClassRuleCount );
- for (i = 0; i < ChainSubClassSet->ChainSubClassRuleCount; i++)
- RECURSE_NUM (ChainSubClassRule, i, ChainSubClassRule, &ChainSubClassSet->ChainSubClassRule[i]);
-}
-
-static void
-Dump_GSUB_Lookup_Single (HB_SubTable *subtable, FILE *stream, int indent, HB_Type hb_type)
-{
- HB_SingleSubst *SingleSubst = &subtable->st.gsub.single;
-
- DUMP_FUINT (SingleSubst, SubstFormat);
- RECURSE (Coverage, Coverage, &SingleSubst->Coverage);
-
- if (SingleSubst->SubstFormat == 1)
- {
- DUMP_FINT (&SingleSubst->ssf.ssf1, DeltaGlyphID);
- }
- else
- {
- int i;
-
- DUMP_FINT (&SingleSubst->ssf.ssf2, GlyphCount);
- for (i=0; i < SingleSubst->ssf.ssf2.GlyphCount; i++)
- DUMP2("<Substitute>%#06x</Substitute> <!-- %d -->\n", SingleSubst->ssf.ssf2.Substitute[i], i);
- }
-}
-
-DEF_DUMP (Ligature)
-{
- int i;
-
- HB_UNUSED(hb_type);
-
- DUMP_FGLYPH (Ligature, LigGlyph);
- DUMP_FUINT (Ligature, ComponentCount);
-
- for (i=0; i < Ligature->ComponentCount - 1; i++)
- DUMP1("<Component>%#06x</Component>\n", Ligature->Component[i]);
-}
-
-DEF_DUMP (LigatureSet)
-{
- int i;
-
- DUMP_FUINT (LigatureSet, LigatureCount);
-
- for (i=0; i < LigatureSet->LigatureCount; i++)
- RECURSE_NUM (Ligature, i, Ligature, &LigatureSet->Ligature[i]);
-}
-
-static void
-Dump_GSUB_Lookup_Ligature (HB_SubTable *subtable, FILE *stream, int indent, HB_Type hb_type)
-{
- int i;
- HB_LigatureSubst *LigatureSubst = &subtable->st.gsub.ligature;
-
- DUMP_FUINT (LigatureSubst, SubstFormat);
- RECURSE (Coverage, Coverage, &LigatureSubst->Coverage);
-
- DUMP_FUINT (LigatureSubst, LigatureSetCount);
-
- for (i=0; i < LigatureSubst->LigatureSetCount; i++)
- RECURSE_NUM (LigatureSet, i, LigatureSet, &LigatureSubst->LigatureSet[i]);
-}
-
-DEF_DUMP (ContextSubstFormat1)
-{
- HB_UNUSED(hb_type);
- HB_UNUSED(ContextSubstFormat1);
-
-
- DUMP("<!-- Not implemented!!! -->\n");
-}
-
-DEF_DUMP (ContextSubstFormat2)
-{
- DUMP_FUINT (ContextSubstFormat2, MaxContextLength);
- RECURSE (Coverage, Coverage, &ContextSubstFormat2->Coverage);
- RECURSE (ClassDefinition, ClassDefinition, &ContextSubstFormat2->ClassDef);
-}
-
-DEF_DUMP (ContextSubstFormat3)
-{
- HB_UNUSED(hb_type);
- HB_UNUSED(ContextSubstFormat3);
-
- DUMP("<!-- Not implemented!!! -->\n");
-}
-
-static void
-Dump_GSUB_Lookup_Context (HB_SubTable *subtable, FILE *stream, int indent, HB_Type hb_type)
-{
- HB_ContextSubst *ContextSubst = &subtable->st.gsub.context;
-
- DUMP_FUINT (ContextSubst, SubstFormat);
- switch( ContextSubst->SubstFormat )
- {
- case 1:
- Dump_ContextSubstFormat1 (&ContextSubst->csf.csf1, stream, indent+2, hb_type);
- break;
- case 2:
- Dump_ContextSubstFormat2 (&ContextSubst->csf.csf2, stream, indent+2, hb_type);
- break;
- case 3:
- Dump_ContextSubstFormat3 (&ContextSubst->csf.csf3, stream, indent+2, hb_type);
- break;
- default:
- fprintf(stderr, "invalid subformat!!!!!\n");
- }
-}
-
-DEF_DUMP (ChainContextSubstFormat1)
-{
- HB_UNUSED(hb_type);
- HB_UNUSED(ChainContextSubstFormat1);
-
- DUMP("<!-- Not implemented!!! -->\n");
-}
-
-DEF_DUMP (ChainContextSubstFormat2)
-{
- int i;
-
- RECURSE (Coverage, Coverage, &ChainContextSubstFormat2->Coverage);
- DUMP_FUINT (ChainContextSubstFormat2, MaxBacktrackLength);
- RECURSE (ClassDefinition, ClassDefinition, &ChainContextSubstFormat2->BacktrackClassDef);
- DUMP_FUINT (ChainContextSubstFormat2, MaxInputLength);
- RECURSE (ClassDefinition, ClassDefinition, &ChainContextSubstFormat2->InputClassDef);
- DUMP_FUINT (ChainContextSubstFormat2, MaxLookaheadLength);
- RECURSE (ClassDefinition, ClassDefinition, &ChainContextSubstFormat2->LookaheadClassDef);
-
- DUMP_FUINT (ChainContextSubstFormat2, ChainSubClassSetCount);
- for (i = 0; i < ChainContextSubstFormat2->ChainSubClassSetCount; i++)
- RECURSE (ChainSubClassSet, ChainSubClassSet, &ChainContextSubstFormat2->ChainSubClassSet[i]);
-}
-
-DEF_DUMP (ChainContextSubstFormat3)
-{
- int i;
-
- DUMP_FUINT (ChainContextSubstFormat3, BacktrackGlyphCount);
- for (i = 0; i < ChainContextSubstFormat3->BacktrackGlyphCount; i++)
- RECURSE (BacktrackCoverage, Coverage, &ChainContextSubstFormat3->BacktrackCoverage[i]);
- DUMP_FUINT (ChainContextSubstFormat3, InputGlyphCount);
- for (i = 0; i < ChainContextSubstFormat3->InputGlyphCount; i++)
- RECURSE (InputCoverage, Coverage, &ChainContextSubstFormat3->InputCoverage[i]);
- DUMP_FUINT (ChainContextSubstFormat3, LookaheadGlyphCount);
- for (i = 0; i < ChainContextSubstFormat3->LookaheadGlyphCount; i++)
- RECURSE (LookaheadCoverage, Coverage, &ChainContextSubstFormat3->LookaheadCoverage[i]);
-
- for (i = 0; i < ChainContextSubstFormat3->SubstCount; i++)
- RECURSE_NUM (SubstLookupRecord, i, SubstLookupRecord, &ChainContextSubstFormat3->SubstLookupRecord[i]);
-
-}
-
-static void
-Dump_GSUB_Lookup_Chain (HB_SubTable *subtable, FILE *stream, int indent, HB_Type hb_type)
-{
- HB_ChainContextSubst *chain = &subtable->st.gsub.chain;
-
- DUMP_FUINT (chain, SubstFormat);
- switch (chain->SubstFormat)
- {
- case 1:
- Dump_ChainContextSubstFormat1 (&chain->ccsf.ccsf1, stream, indent+2, hb_type);
- break;
- case 2:
- Dump_ChainContextSubstFormat2 (&chain->ccsf.ccsf2, stream, indent+2, hb_type);
- break;
- case 3:
- Dump_ChainContextSubstFormat3 (&chain->ccsf.ccsf3, stream, indent+2, hb_type);
- break;
- default:
- fprintf(stderr, "invalid subformat!!!!!\n");
- }
-}
-
-static void
-Dump_Device (HB_Device *Device, FILE *stream, int indent, HB_Type hb_type)
-{
- int i;
- int bits;
- int n_per;
- unsigned int mask;
-
- HB_UNUSED(hb_type);
-
- DUMP_FUINT (Device, StartSize);
- DUMP_FUINT (Device, EndSize);
- DUMP_FUINT (Device, DeltaFormat);
- switch (Device->DeltaFormat)
- {
- case 1:
- bits = 2;
- break;
- case 2:
- bits = 4;
- break;
- case 3:
- bits = 8;
- break;
- default:
- bits = 0;
- break;
- }
-
- DUMP ("<DeltaValue>");
- if (!bits)
- {
-
- fprintf(stderr, "invalid DeltaFormat!!!!!\n");
- }
- else
- {
- n_per = 16 / bits;
- mask = (1 << bits) - 1;
- mask = mask << (16 - bits);
-
- for (i = Device->StartSize; i <= Device->EndSize ; i++)
- {
- HB_UShort val = Device->DeltaValue[i / n_per];
- HB_Short signed_val = ((val << ((i % n_per) * bits)) & mask);
- dump (stream, indent, "%d", signed_val >> (16 - bits));
- if (i != Device->EndSize)
- DUMP (", ");
- }
- }
- DUMP ("</DeltaValue>\n");
-}
-
-static void
-Dump_ValueRecord (HB_ValueRecord *ValueRecord, FILE *stream, int indent, HB_Type hb_type, HB_UShort value_format)
-{
- if (value_format & HB_GPOS_FORMAT_HAVE_X_PLACEMENT)
- DUMP_FINT (ValueRecord, XPlacement);
- if (value_format & HB_GPOS_FORMAT_HAVE_Y_PLACEMENT)
- DUMP_FINT (ValueRecord, YPlacement);
- if (value_format & HB_GPOS_FORMAT_HAVE_X_ADVANCE)
- DUMP_FINT (ValueRecord, XAdvance);
- if (value_format & HB_GPOS_FORMAT_HAVE_Y_ADVANCE)
- DUMP_FINT (ValueRecord, XAdvance);
- if (value_format & HB_GPOS_FORMAT_HAVE_X_PLACEMENT_DEVICE)
- RECURSE (Device, Device, &*ValueRecord->DeviceTables[VR_X_PLACEMENT_DEVICE]);
- if (value_format & HB_GPOS_FORMAT_HAVE_Y_PLACEMENT_DEVICE)
- RECURSE (Device, Device, &*ValueRecord->DeviceTables[VR_Y_PLACEMENT_DEVICE]);
- if (value_format & HB_GPOS_FORMAT_HAVE_X_ADVANCE_DEVICE)
- RECURSE (Device, Device, &*ValueRecord->DeviceTables[VR_X_ADVANCE_DEVICE]);
- if (value_format & HB_GPOS_FORMAT_HAVE_Y_ADVANCE_DEVICE)
- RECURSE (Device, Device, &*ValueRecord->DeviceTables[VR_Y_ADVANCE_DEVICE]);
-#ifdef HB_SUPPORT_MULTIPLE_MASTER
- if (value_format & HB_GPOS_FORMAT_HAVE_X_ID_PLACEMENT)
- DUMP_FUINT (ValueRecord, XIdPlacement);
- if (value_format & HB_GPOS_FORMAT_HAVE_Y_ID_PLACEMENT)
- DUMP_FUINT (ValueRecord, YIdPlacement);
- if (value_format & HB_GPOS_FORMAT_HAVE_X_ID_ADVANCE)
- DUMP_FUINT (ValueRecord, XIdAdvance);
- if (value_format & HB_GPOS_FORMAT_HAVE_Y_ID_ADVANCE)
- DUMP_FUINT (ValueRecord, XIdAdvance);
-#endif
-}
-
-static void
-Dump_GPOS_Lookup_Single (HB_SubTable *subtable, FILE *stream, int indent, HB_Type hb_type)
-{
- HB_SinglePos *SinglePos = &subtable->st.gpos.single;
-
- DUMP_FUINT (SinglePos, PosFormat);
- RECURSE (Coverage, Coverage, &SinglePos->Coverage);
-
- DUMP_FUINT (SinglePos, ValueFormat);
-
- if (SinglePos->PosFormat == 1)
- {
- DUMP_VALUE_RECORD (&SinglePos->spf.spf1.Value, SinglePos->ValueFormat);
- }
- else
- {
- int i;
-
- DUMP_FUINT (&SinglePos->spf.spf2, ValueCount);
- for (i = 0; i < SinglePos->spf.spf2.ValueCount; i++)
- DUMP_VALUE_RECORD (&SinglePos->spf.spf2.Value[i], SinglePos->ValueFormat);
- }
-}
-
-static void
-Dump_PairValueRecord (HB_PairValueRecord *PairValueRecord, FILE *stream, int indent, HB_Type hb_type, HB_UShort ValueFormat1, HB_UShort ValueFormat2)
-{
- DUMP_FUINT (PairValueRecord, SecondGlyph);
- DUMP_VALUE_RECORD (&PairValueRecord->Value1, ValueFormat1);
- DUMP_VALUE_RECORD (&PairValueRecord->Value2, ValueFormat2);
-}
-
-static void
-Dump_PairSet (HB_PairSet *PairSet, FILE *stream, int indent, HB_Type hb_type, HB_UShort ValueFormat1, HB_UShort ValueFormat2)
-{
- int i;
- DUMP_FUINT (PairSet, PairValueCount);
-
- for (i = 0; i < PairSet->PairValueCount; i++)
- {
- DUMP ("<PairValueRecord>\n");
- Dump_PairValueRecord (&PairSet->PairValueRecord[i], stream, indent + 1, hb_type, ValueFormat1, ValueFormat2);
- DUMP ("</PairValueRecord>\n");
- }
-}
-
-static void
-Dump_GPOS_Lookup_Pair (HB_SubTable *subtable, FILE *stream, int indent, HB_Type hb_type)
-{
- HB_PairPos *PairPos = &subtable->st.gpos.pair;
-
- DUMP_FUINT (PairPos, PosFormat);
- RECURSE (Coverage, Coverage, &PairPos->Coverage);
-
- DUMP_FUINT (PairPos, ValueFormat1);
- DUMP_FUINT (PairPos, ValueFormat2);
-
- if (PairPos->PosFormat == 1)
- {
- int i;
-
- DUMP_FUINT (&PairPos->ppf.ppf1, PairSetCount);
- for (i = 0; i < PairPos->ppf.ppf1.PairSetCount; i++)
- {
- DUMP ("<PairSet>\n");
- Dump_PairSet (&PairPos->ppf.ppf1.PairSet[i], stream, indent + 1, hb_type, PairPos->ValueFormat1, PairPos->ValueFormat2);
- DUMP ("</PairSet>\n");
- }
- }
- else
- {
- }
-}
-
-static void
-Dump_GPOS_Lookup_Markbase (HB_SubTable *subtable, FILE *stream, int indent, HB_Type hb_type)
-{
- int i;
- HB_MarkBasePos *markbase = &subtable->st.gpos.markbase;
-
- DUMP_FUINT (markbase, PosFormat);
- RECURSE (Coverage, Coverage, &markbase->MarkCoverage);
- RECURSE (Coverage, Coverage, &markbase->BaseCoverage);
- DUMP_FUINT (markbase, ClassCount);
- RECURSE (MarkArray, MarkArray, &markbase->MarkArray);
-
- DUMP ("<BaseArray>\n");
- indent++;
-
- DUMP_FUINT (&markbase->BaseArray, BaseCount);
- for (i = 0; i < markbase->BaseArray.BaseCount; i++)
- {
- int j;
- HB_BaseRecord *r = &markbase->BaseArray.BaseRecord[i];
- DUMP1 ("<BaseRecord> <!-- %d -->\n", i);
- for (j = 0; j < markbase->ClassCount; j++)
- DUMP1 (" <Anchor>%d</Anchor>\n", r->BaseAnchor->PosFormat);
- DUMP ("<BaseRecord>\n");
- }
-
- indent--;
- DUMP ("</BaseArray>\n");
-}
-
-DEF_DUMP (Lookup)
-{
- int i;
- const char *lookup_name;
- void (*lookup_func) (HB_SubTable *subtable, FILE *stream, int indent, HB_Type hb_type) = NULL;
-
- if (hb_type == HB_Type_GSUB)
- {
- switch (Lookup->LookupType)
- {
- case HB_GSUB_LOOKUP_SINGLE:
- lookup_name = "SINGLE";
- lookup_func = Dump_GSUB_Lookup_Single;
- break;
- case HB_GSUB_LOOKUP_MULTIPLE:
- lookup_name = "MULTIPLE";
- break;
- case HB_GSUB_LOOKUP_ALTERNATE:
- lookup_name = "ALTERNATE";
- break;
- case HB_GSUB_LOOKUP_LIGATURE:
- lookup_name = "LIGATURE";
- lookup_func = Dump_GSUB_Lookup_Ligature;
- break;
- case HB_GSUB_LOOKUP_CONTEXT:
- lookup_name = "CONTEXT";
- lookup_func = Dump_GSUB_Lookup_Context;
- break;
- case HB_GSUB_LOOKUP_CHAIN:
- lookup_name = "CHAIN";
- lookup_func = Dump_GSUB_Lookup_Chain;
- break;
- default:
- lookup_name = "(unknown)";
- lookup_func = NULL;
- break;
- }
- }
- else
- {
- switch (Lookup->LookupType)
- {
- case HB_GPOS_LOOKUP_SINGLE:
- lookup_name = "SINGLE";
- lookup_func = Dump_GPOS_Lookup_Single;
- break;
- case HB_GPOS_LOOKUP_PAIR:
- lookup_name = "PAIR";
- lookup_func = Dump_GPOS_Lookup_Pair;
- break;
- case HB_GPOS_LOOKUP_CURSIVE:
- lookup_name = "CURSIVE";
- break;
- case HB_GPOS_LOOKUP_MARKBASE:
- lookup_name = "MARKBASE";
- lookup_func = Dump_GPOS_Lookup_Markbase;
- break;
- case HB_GPOS_LOOKUP_MARKLIG:
- lookup_name = "MARKLIG";
- break;
- case HB_GPOS_LOOKUP_MARKMARK:
- lookup_name = "MARKMARK";
- break;
- case HB_GPOS_LOOKUP_CONTEXT:
- lookup_name = "CONTEXT";
- break;
- case HB_GPOS_LOOKUP_CHAIN:
- lookup_name = "CHAIN";
- break;
- default:
- lookup_name = "(unknown)";
- lookup_func = NULL;
- break;
- }
- }
-
- DUMP2("<LookupType>%s</LookupType> <!-- %d -->\n", lookup_name, Lookup->LookupType);
- DUMP1("<LookupFlag>%#06x</LookupFlag>\n", Lookup->LookupFlag);
-
- for (i=0; i < Lookup->SubTableCount; i++)
- {
- DUMP ("<Subtable>\n");
- if (lookup_func)
- (*lookup_func) (&Lookup->SubTable[i], stream, indent + 1, hb_type);
- DUMP ("</Subtable>\n");
- }
-}
-
-DEF_DUMP (LookupList)
-{
- int i;
-
- DUMP_FUINT (LookupList, LookupCount);
-
- for (i=0; i < LookupList->LookupCount; i++)
- RECURSE_NUM (Lookup, i, Lookup, &LookupList->Lookup[i]);
-}
-
-void
-HB_Dump_GSUB_Table (HB_GSUB gsub, FILE *stream)
-{
- int indent = 1;
- HB_Type hb_type = HB_Type_GSUB;
-
- do_indent (stream, indent);
- fprintf(stream, "<!-- GSUB -->\n");
- RECURSE (ScriptList, ScriptList, &gsub->ScriptList);
- RECURSE (FeatureList, FeatureList, &gsub->FeatureList);
- RECURSE (LookupList, LookupList, &gsub->LookupList);
-}
-
-void
-HB_Dump_GPOS_Table (HB_GPOS gpos, FILE *stream)
-{
- int indent = 1;
- HB_Type hb_type = HB_Type_GPOS;
-
- do_indent (stream, indent);
- fprintf(stream, "<!-- GPOS -->\n");
- RECURSE (ScriptList, ScriptList, &gpos->ScriptList);
- RECURSE (FeatureList, FeatureList, &gpos->FeatureList);
- RECURSE (LookupList, LookupList, &gpos->LookupList);
-}
diff --git a/src/3rdparty/harfbuzz/src/harfbuzz-dump.h b/src/3rdparty/harfbuzz/src/harfbuzz-dump.h
deleted file mode 100644
index ea4a62b2e1..0000000000
--- a/src/3rdparty/harfbuzz/src/harfbuzz-dump.h
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * Copyright (C) 2000, 2007 Red Hat, Inc.
- *
- * This is part of HarfBuzz, an OpenType Layout engine library.
- *
- * Permission is hereby granted, without written agreement and without
- * license or royalty fees, to use, copy, modify, and distribute this
- * software and its documentation for any purpose, provided that the
- * above copyright notice and the following two paragraphs appear in
- * all copies of this software.
- *
- * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
- * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
- * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
- * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
- * DAMAGE.
- *
- * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
- * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
- * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
- * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
- * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
- *
- * Red Hat Author(s): Owen Taylor, Behdad Esfahbod
- */
-
-#ifndef HARFBUZZ_DUMP_H
-#define HARFBUZZ_DUMP_H
-
-#include <stdio.h>
-#include "harfbuzz-gsub.h"
-#include "harfbuzz-gpos.h"
-
-HB_BEGIN_HEADER
-
-void HB_Dump_GSUB_Table (HB_GSUB gsub, FILE *stream);
-void HB_Dump_GPOS_Table (HB_GPOS gpos, FILE *stream);
-
-HB_END_HEADER
-
-#endif /* HARFBUZZ_DUMP_H */
diff --git a/src/3rdparty/harfbuzz/src/harfbuzz-external.h b/src/3rdparty/harfbuzz/src/harfbuzz-external.h
deleted file mode 100644
index 53592c3c46..0000000000
--- a/src/3rdparty/harfbuzz/src/harfbuzz-external.h
+++ /dev/null
@@ -1,86 +0,0 @@
-/*
- * Copyright (C) 2015 The Qt Company Ltd
- *
- * This is part of HarfBuzz, an OpenType Layout engine 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 HARFBUZZ_EXTERNAL_H
-#define HARFBUZZ_EXTERNAL_H
-
-#include "harfbuzz-global.h"
-
-HB_BEGIN_HEADER
-
-/* This header contains some methods that are not part of
- Harfbuzz itself, but referenced by it.
- They need to be provided by the application/library
-*/
-
-typedef enum
-{
- HB_Mark_NonSpacing, /* Mn */
- HB_Mark_SpacingCombining, /* Mc */
- HB_Mark_Enclosing, /* Me */
-
- HB_Number_DecimalDigit, /* Nd */
- HB_Number_Letter, /* Nl */
- HB_Number_Other, /* No */
-
- HB_Separator_Space, /* Zs */
- HB_Separator_Line, /* Zl */
- HB_Separator_Paragraph, /* Zp */
-
- HB_Other_Control, /* Cc */
- HB_Other_Format, /* Cf */
- HB_Other_Surrogate, /* Cs */
- HB_Other_PrivateUse, /* Co */
- HB_Other_NotAssigned, /* Cn */
-
- HB_Letter_Uppercase, /* Lu */
- HB_Letter_Lowercase, /* Ll */
- HB_Letter_Titlecase, /* Lt */
- HB_Letter_Modifier, /* Lm */
- HB_Letter_Other, /* Lo */
-
- HB_Punctuation_Connector, /* Pc */
- HB_Punctuation_Dash, /* Pd */
- HB_Punctuation_Open, /* Ps */
- HB_Punctuation_Close, /* Pe */
- HB_Punctuation_InitialQuote, /* Pi */
- HB_Punctuation_FinalQuote, /* Pf */
- HB_Punctuation_Other, /* Po */
-
- HB_Symbol_Math, /* Sm */
- HB_Symbol_Currency, /* Sc */
- HB_Symbol_Modifier, /* Sk */
- HB_Symbol_Other /* So */
-} HB_CharCategory;
-
-void HB_GetUnicodeCharProperties(HB_UChar32 ch, HB_CharCategory *category, int *combiningClass);
-HB_CharCategory HB_GetUnicodeCharCategory(HB_UChar32 ch);
-int HB_GetUnicodeCharCombiningClass(HB_UChar32 ch);
-HB_UChar16 HB_GetMirroredChar(HB_UChar16 ch);
-
-void (*HB_Library_Resolve(const char *library, int version, const char *symbol))();
-
-HB_END_HEADER
-
-#endif
diff --git a/src/3rdparty/harfbuzz/src/harfbuzz-gdef-private.h b/src/3rdparty/harfbuzz/src/harfbuzz-gdef-private.h
deleted file mode 100644
index 94e9b43e61..0000000000
--- a/src/3rdparty/harfbuzz/src/harfbuzz-gdef-private.h
+++ /dev/null
@@ -1,126 +0,0 @@
-/*
- * Copyright (C) 1998-2004 David Turner and Werner Lemberg
- * Copyright (C) 2006 Behdad Esfahbod
- *
- * This is part of HarfBuzz, an OpenType Layout engine 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 HARFBUZZ_GDEF_PRIVATE_H
-#define HARFBUZZ_GDEF_PRIVATE_H
-
-#include "harfbuzz-impl.h"
-#include "harfbuzz-stream-private.h"
-#include "harfbuzz-buffer-private.h"
-#include "harfbuzz-gdef.h"
-
-HB_BEGIN_HEADER
-
-/* Attachment related structures */
-
-struct HB_AttachPoint_
-{
- HB_UShort* PointIndex; /* array of contour points */
- HB_UShort PointCount; /* size of the PointIndex array */
-};
-
-/* Ligature Caret related structures */
-
-struct HB_CaretValueFormat1_
-{
- HB_Short Coordinate; /* x or y value (in design units) */
-};
-
-typedef struct HB_CaretValueFormat1_ HB_CaretValueFormat1;
-
-
-struct HB_CaretValueFormat2_
-{
- HB_UShort CaretValuePoint; /* contour point index on glyph */
-};
-
-typedef struct HB_CaretValueFormat2_ HB_CaretValueFormat2;
-
-
-struct HB_CaretValueFormat3_
-{
- HB_Device* Device; /* Device table for x or y value */
- HB_Short Coordinate; /* x or y value (in design units) */
-};
-
-typedef struct HB_CaretValueFormat3_ HB_CaretValueFormat3;
-
-
-#ifdef HB_SUPPORT_MULTIPLE_MASTER
-struct HB_CaretValueFormat4_
-{
- HB_UShort IdCaretValue; /* metric ID */
-};
-
-typedef struct HB_CaretValueFormat4_ HB_CaretValueFormat4;
-#endif
-
-
-struct HB_CaretValue_
-{
- union
- {
- HB_CaretValueFormat1 cvf1;
- HB_CaretValueFormat2 cvf2;
- HB_CaretValueFormat3 cvf3;
-#ifdef HB_SUPPORT_MULTIPLE_MASTER
- HB_CaretValueFormat4 cvf4;
-#endif
- } cvf;
-
- HB_Byte CaretValueFormat; /* 1, 2, 3, or 4 */
-};
-
-typedef struct HB_CaretValue_ HB_CaretValue;
-
-
-struct HB_LigGlyph_
-{
- HB_CaretValue* CaretValue; /* array of caret values */
- HB_UShort CaretCount; /* number of caret values */
- HB_Bool loaded;
-};
-
-
-HB_INTERNAL HB_Error
-_HB_GDEF_Add_Glyph_Property( HB_GDEFHeader* gdef,
- HB_UShort glyphID,
- HB_UShort property );
-
-HB_INTERNAL HB_Error
-_HB_GDEF_Check_Property( HB_GDEFHeader* gdef,
- HB_GlyphItem item,
- HB_UShort flags,
- HB_UShort* property );
-
-HB_INTERNAL HB_Error
-_HB_GDEF_LoadMarkAttachClassDef_From_LookupFlags( HB_GDEFHeader* gdef,
- HB_Stream input,
- HB_Lookup* lo,
- HB_UShort num_lookups );
-
-HB_END_HEADER
-
-#endif /* HARFBUZZ_GDEF_PRIVATE_H */
diff --git a/src/3rdparty/harfbuzz/src/harfbuzz-gdef.c b/src/3rdparty/harfbuzz/src/harfbuzz-gdef.c
deleted file mode 100644
index a4bf9352c7..0000000000
--- a/src/3rdparty/harfbuzz/src/harfbuzz-gdef.c
+++ /dev/null
@@ -1,1163 +0,0 @@
-/*
- * Copyright (C) 1998-2004 David Turner and Werner Lemberg
- * Copyright (C) 2006 Behdad Esfahbod
- *
- * This is part of HarfBuzz, an OpenType Layout engine library.
- *
- * Permission is hereby granted, without written agreement and without
- * license or royalty fees, to use, copy, modify, and distribute this
- * software and its documentation for any purpose, provided that the
- * above copyright notice and the following two paragraphs appear in
- * all copies of this software.
- *
- * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
- * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
- * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
- * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
- * DAMAGE.
- *
- * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
- * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
- * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
- * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
- * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
- */
-
-#include "harfbuzz-impl.h"
-#include "harfbuzz-gdef-private.h"
-#include "harfbuzz-open-private.h"
-
-static HB_Error Load_AttachList( HB_AttachList* al,
- HB_Stream stream );
-static HB_Error Load_LigCaretList( HB_LigCaretList* lcl,
- HB_Stream stream );
-
-static void Free_AttachList( HB_AttachList* al);
-static void Free_LigCaretList( HB_LigCaretList* lcl);
-
-static void Free_NewGlyphClasses( HB_GDEFHeader* gdef);
-
-
-
-/* GDEF glyph classes */
-
-#define UNCLASSIFIED_GLYPH 0
-#define SIMPLE_GLYPH 1
-#define LIGATURE_GLYPH 2
-#define MARK_GLYPH 3
-#define COMPONENT_GLYPH 4
-
-
-
-
-
-
-HB_Error HB_New_GDEF_Table( HB_GDEFHeader** retptr )
-{
- HB_Error error;
-
- HB_GDEFHeader* gdef;
-
- if ( !retptr )
- return ERR(HB_Err_Invalid_Argument);
-
- if ( ALLOC( gdef, sizeof( *gdef ) ) )
- return error;
-
- gdef->GlyphClassDef.loaded = FALSE;
- gdef->AttachList.loaded = FALSE;
- gdef->LigCaretList.loaded = FALSE;
- gdef->MarkAttachClassDef_offset = 0;
- gdef->MarkAttachClassDef.loaded = FALSE;
-
- gdef->LastGlyph = 0;
- gdef->NewGlyphClasses = NULL;
-
- *retptr = gdef;
-
- return HB_Err_Ok;
-}
-
-
-HB_Error HB_Load_GDEF_Table( HB_Stream stream,
- HB_GDEFHeader** retptr )
-{
- HB_Error error = HB_Err_Ok;
- HB_UInt cur_offset, new_offset, base_offset;
-
- HB_GDEFHeader* gdef;
-
-
- if ( !retptr )
- return ERR(HB_Err_Invalid_Argument);
-
- if ( GOTO_Table( TTAG_GDEF ) )
- return error;
-
- if (( error = HB_New_GDEF_Table ( &gdef ) ))
- return error;
-
- base_offset = FILE_Pos();
-
- /* skip version */
-
- if ( FILE_Seek( base_offset + 4L ) ||
- ACCESS_Frame( 2L ) )
- goto Fail0;
-
- new_offset = GET_UShort();
-
- FORGET_Frame();
-
- /* all GDEF subtables are optional */
-
- if ( new_offset )
- {
- new_offset += base_offset;
-
- /* only classes 1-4 are allowed here */
-
- cur_offset = FILE_Pos();
- if ( FILE_Seek( new_offset ) ||
- ( error = _HB_OPEN_Load_ClassDefinition( &gdef->GlyphClassDef, 5,
- stream ) ) != HB_Err_Ok )
- goto Fail0;
- (void)FILE_Seek( cur_offset );
- }
-
- if ( ACCESS_Frame( 2L ) )
- goto Fail1;
-
- new_offset = GET_UShort();
-
- FORGET_Frame();
-
- if ( new_offset )
- {
- new_offset += base_offset;
-
- cur_offset = FILE_Pos();
- if ( FILE_Seek( new_offset ) ||
- ( error = Load_AttachList( &gdef->AttachList,
- stream ) ) != HB_Err_Ok )
- goto Fail1;
- (void)FILE_Seek( cur_offset );
- }
-
- if ( ACCESS_Frame( 2L ) )
- goto Fail2;
-
- new_offset = GET_UShort();
-
- FORGET_Frame();
-
- if ( new_offset )
- {
- new_offset += base_offset;
-
- cur_offset = FILE_Pos();
- if ( FILE_Seek( new_offset ) ||
- ( error = Load_LigCaretList( &gdef->LigCaretList,
- stream ) ) != HB_Err_Ok )
- goto Fail2;
- (void)FILE_Seek( cur_offset );
- }
-
- /* OpenType 1.2 has introduced the `MarkAttachClassDef' field. We
- first have to scan the LookupFlag values to find out whether we
- must load it or not. Here we only store the offset of the table. */
-
- if ( ACCESS_Frame( 2L ) )
- goto Fail3;
-
- new_offset = GET_UShort();
-
- FORGET_Frame();
-
- if ( new_offset )
- gdef->MarkAttachClassDef_offset = new_offset + base_offset;
- else
- gdef->MarkAttachClassDef_offset = 0;
-
- *retptr = gdef;
-
- return HB_Err_Ok;
-
-Fail3:
- Free_LigCaretList( &gdef->LigCaretList );
-
-Fail2:
- Free_AttachList( &gdef->AttachList );
-
-Fail1:
- _HB_OPEN_Free_ClassDefinition( &gdef->GlyphClassDef );
-
-Fail0:
- FREE( gdef );
-
- return error;
-}
-
-
-HB_Error HB_Done_GDEF_Table ( HB_GDEFHeader* gdef )
-{
- Free_LigCaretList( &gdef->LigCaretList );
- Free_AttachList( &gdef->AttachList );
- _HB_OPEN_Free_ClassDefinition( &gdef->GlyphClassDef );
- _HB_OPEN_Free_ClassDefinition( &gdef->MarkAttachClassDef );
-
- Free_NewGlyphClasses( gdef );
-
- FREE( gdef );
-
- return HB_Err_Ok;
-}
-
-
-
-
-/*******************************
- * AttachList related functions
- *******************************/
-
-
-/* AttachPoint */
-
-static HB_Error Load_AttachPoint( HB_AttachPoint* ap,
- HB_Stream stream )
-{
- HB_Error error;
-
- HB_UShort n, count;
- HB_UShort* pi;
-
-
- if ( ACCESS_Frame( 2L ) )
- return error;
-
- count = ap->PointCount = GET_UShort();
-
- FORGET_Frame();
-
- ap->PointIndex = NULL;
-
- if ( count )
- {
- if ( ALLOC_ARRAY( ap->PointIndex, count, HB_UShort ) )
- return error;
-
- pi = ap->PointIndex;
-
- if ( ACCESS_Frame( count * 2L ) )
- {
- FREE( pi );
- return error;
- }
-
- for ( n = 0; n < count; n++ )
- pi[n] = GET_UShort();
-
- FORGET_Frame();
- }
-
- return HB_Err_Ok;
-}
-
-
-static void Free_AttachPoint( HB_AttachPoint* ap )
-{
- FREE( ap->PointIndex );
-}
-
-
-/* AttachList */
-
-static HB_Error Load_AttachList( HB_AttachList* al,
- HB_Stream stream )
-{
- HB_Error error;
-
- HB_UShort n, m, count;
- HB_UInt cur_offset, new_offset, base_offset;
-
- HB_AttachPoint* ap;
-
-
- base_offset = FILE_Pos();
-
- if ( ACCESS_Frame( 2L ) )
- return error;
-
- new_offset = GET_UShort() + base_offset;
-
- FORGET_Frame();
-
- cur_offset = FILE_Pos();
- if ( FILE_Seek( new_offset ) ||
- ( error = _HB_OPEN_Load_Coverage( &al->Coverage, stream ) ) != HB_Err_Ok )
- return error;
- (void)FILE_Seek( cur_offset );
-
- if ( ACCESS_Frame( 2L ) )
- goto Fail2;
-
- count = al->GlyphCount = GET_UShort();
-
- FORGET_Frame();
-
- al->AttachPoint = NULL;
-
- if ( ALLOC_ARRAY( al->AttachPoint, count, HB_AttachPoint ) )
- goto Fail2;
-
- ap = al->AttachPoint;
-
- for ( n = 0; n < count; n++ )
- {
- if ( ACCESS_Frame( 2L ) )
- goto Fail1;
-
- new_offset = GET_UShort() + base_offset;
-
- FORGET_Frame();
-
- cur_offset = FILE_Pos();
- if ( FILE_Seek( new_offset ) ||
- ( error = Load_AttachPoint( &ap[n], stream ) ) != HB_Err_Ok )
- goto Fail1;
- (void)FILE_Seek( cur_offset );
- }
-
- al->loaded = TRUE;
-
- return HB_Err_Ok;
-
-Fail1:
- for ( m = 0; m < n; m++ )
- Free_AttachPoint( &ap[m] );
-
- FREE( ap );
-
-Fail2:
- _HB_OPEN_Free_Coverage( &al->Coverage );
- return error;
-}
-
-
-static void Free_AttachList( HB_AttachList* al)
-{
- HB_UShort n, count;
-
- HB_AttachPoint* ap;
-
-
- if ( !al->loaded )
- return;
-
- if ( al->AttachPoint )
- {
- count = al->GlyphCount;
- ap = al->AttachPoint;
-
- for ( n = 0; n < count; n++ )
- Free_AttachPoint( &ap[n] );
-
- FREE( ap );
- }
-
- _HB_OPEN_Free_Coverage( &al->Coverage );
-}
-
-
-
-/*********************************
- * LigCaretList related functions
- *********************************/
-
-
-/* CaretValueFormat1 */
-/* CaretValueFormat2 */
-/* CaretValueFormat3 */
-/* CaretValueFormat4 */
-
-static HB_Error Load_CaretValue( HB_CaretValue* cv,
- HB_Stream stream )
-{
- HB_Error error;
-
- HB_UInt cur_offset, new_offset, base_offset;
-
-
- base_offset = FILE_Pos();
-
- if ( ACCESS_Frame( 2L ) )
- return error;
-
- cv->CaretValueFormat = GET_UShort();
-
- FORGET_Frame();
-
- switch ( cv->CaretValueFormat )
- {
- case 1:
- if ( ACCESS_Frame( 2L ) )
- return error;
-
- cv->cvf.cvf1.Coordinate = GET_Short();
-
- FORGET_Frame();
-
- break;
-
- case 2:
- if ( ACCESS_Frame( 2L ) )
- return error;
-
- cv->cvf.cvf2.CaretValuePoint = GET_UShort();
-
- FORGET_Frame();
-
- break;
-
- case 3:
- if ( ACCESS_Frame( 4L ) )
- return error;
-
- cv->cvf.cvf3.Coordinate = GET_Short();
-
- new_offset = GET_UShort() + base_offset;
-
- FORGET_Frame();
-
- cur_offset = FILE_Pos();
- if ( FILE_Seek( new_offset ) ||
- ( error = _HB_OPEN_Load_Device( &cv->cvf.cvf3.Device,
- stream ) ) != HB_Err_Ok )
- return error;
- (void)FILE_Seek( cur_offset );
-
- break;
-
- case 4:
- if ( ACCESS_Frame( 2L ) )
- return error;
-
-#ifdef HB_SUPPORT_MULTIPLE_MASTER
- cv->cvf.cvf4.IdCaretValue = GET_UShort();
-#else
- (void) GET_UShort();
-#endif
-
- FORGET_Frame();
- break;
-
- default:
- return ERR(HB_Err_Invalid_SubTable_Format);
- }
-
- return HB_Err_Ok;
-}
-
-
-static void Free_CaretValue( HB_CaretValue* cv)
-{
- if ( cv->CaretValueFormat == 3 )
- _HB_OPEN_Free_Device( cv->cvf.cvf3.Device );
-}
-
-
-/* LigGlyph */
-
-static HB_Error Load_LigGlyph( HB_LigGlyph* lg,
- HB_Stream stream )
-{
- HB_Error error;
-
- HB_UShort n, m, count;
- HB_UInt cur_offset, new_offset, base_offset;
-
- HB_CaretValue* cv;
-
-
- base_offset = FILE_Pos();
-
- if ( ACCESS_Frame( 2L ) )
- return error;
-
- count = lg->CaretCount = GET_UShort();
-
- FORGET_Frame();
-
- lg->CaretValue = NULL;
-
- if ( ALLOC_ARRAY( lg->CaretValue, count, HB_CaretValue ) )
- return error;
-
- cv = lg->CaretValue;
-
- for ( n = 0; n < count; n++ )
- {
- if ( ACCESS_Frame( 2L ) )
- goto Fail;
-
- new_offset = GET_UShort() + base_offset;
-
- FORGET_Frame();
-
- cur_offset = FILE_Pos();
- if ( FILE_Seek( new_offset ) ||
- ( error = Load_CaretValue( &cv[n], stream ) ) != HB_Err_Ok )
- goto Fail;
- (void)FILE_Seek( cur_offset );
- }
-
- return HB_Err_Ok;
-
-Fail:
- for ( m = 0; m < n; m++ )
- Free_CaretValue( &cv[m] );
-
- FREE( cv );
- return error;
-}
-
-
-static void Free_LigGlyph( HB_LigGlyph* lg)
-{
- HB_UShort n, count;
-
- HB_CaretValue* cv;
-
-
- if ( lg->CaretValue )
- {
- count = lg->CaretCount;
- cv = lg->CaretValue;
-
- for ( n = 0; n < count; n++ )
- Free_CaretValue( &cv[n] );
-
- FREE( cv );
- }
-}
-
-
-/* LigCaretList */
-
-static HB_Error Load_LigCaretList( HB_LigCaretList* lcl,
- HB_Stream stream )
-{
- HB_Error error;
-
- HB_UShort m, n, count;
- HB_UInt cur_offset, new_offset, base_offset;
-
- HB_LigGlyph* lg;
-
-
- base_offset = FILE_Pos();
-
- if ( ACCESS_Frame( 2L ) )
- return error;
-
- new_offset = GET_UShort() + base_offset;
-
- FORGET_Frame();
-
- cur_offset = FILE_Pos();
- if ( FILE_Seek( new_offset ) ||
- ( error = _HB_OPEN_Load_Coverage( &lcl->Coverage, stream ) ) != HB_Err_Ok )
- return error;
- (void)FILE_Seek( cur_offset );
-
- if ( ACCESS_Frame( 2L ) )
- goto Fail2;
-
- count = lcl->LigGlyphCount = GET_UShort();
-
- FORGET_Frame();
-
- lcl->LigGlyph = NULL;
-
- if ( ALLOC_ARRAY( lcl->LigGlyph, count, HB_LigGlyph ) )
- goto Fail2;
-
- lg = lcl->LigGlyph;
-
- for ( n = 0; n < count; n++ )
- {
- if ( ACCESS_Frame( 2L ) )
- goto Fail1;
-
- new_offset = GET_UShort() + base_offset;
-
- FORGET_Frame();
-
- cur_offset = FILE_Pos();
- if ( FILE_Seek( new_offset ) ||
- ( error = Load_LigGlyph( &lg[n], stream ) ) != HB_Err_Ok )
- goto Fail1;
- (void)FILE_Seek( cur_offset );
- }
-
- lcl->loaded = TRUE;
-
- return HB_Err_Ok;
-
-Fail1:
- for ( m = 0; m < n; m++ )
- Free_LigGlyph( &lg[m] );
-
- FREE( lg );
-
-Fail2:
- _HB_OPEN_Free_Coverage( &lcl->Coverage );
- return error;
-}
-
-
-static void Free_LigCaretList( HB_LigCaretList* lcl )
-{
- HB_UShort n, count;
-
- HB_LigGlyph* lg;
-
-
- if ( !lcl->loaded )
- return;
-
- if ( lcl->LigGlyph )
- {
- count = lcl->LigGlyphCount;
- lg = lcl->LigGlyph;
-
- for ( n = 0; n < count; n++ )
- Free_LigGlyph( &lg[n] );
-
- FREE( lg );
- }
-
- _HB_OPEN_Free_Coverage( &lcl->Coverage );
-}
-
-
-
-/***********
- * GDEF API
- ***********/
-
-
-static HB_UShort Get_New_Class( HB_GDEFHeader* gdef,
- HB_UShort glyphID,
- HB_UShort index )
-{
- HB_UShort glyph_index, array_index, count;
- HB_UShort byte, bits;
-
- HB_ClassRangeRecord* gcrr;
- HB_UShort** ngc;
-
-
- if ( glyphID >= gdef->LastGlyph )
- return 0;
-
- count = gdef->GlyphClassDef.cd.cd2.ClassRangeCount;
- gcrr = gdef->GlyphClassDef.cd.cd2.ClassRangeRecord;
- ngc = gdef->NewGlyphClasses;
-
- if ( index < count && glyphID < gcrr[index].Start )
- {
- array_index = index;
- if ( index == 0 )
- glyph_index = glyphID;
- else
- glyph_index = glyphID - gcrr[index - 1].End - 1;
- }
- else
- {
- array_index = index + 1;
- glyph_index = glyphID - gcrr[index].End - 1;
- }
-
- byte = ngc[array_index][glyph_index / 4];
- bits = byte >> ( 16 - ( glyph_index % 4 + 1 ) * 4 );
-
- return bits & 0x000F;
-}
-
-
-
-HB_Error HB_GDEF_Get_Glyph_Property( HB_GDEFHeader* gdef,
- HB_UShort glyphID,
- HB_UShort* property )
-{
- HB_UShort class = 0, index = 0; /* shut compiler up */
-
- HB_Error error;
-
-
- if ( !gdef || !property )
- return ERR(HB_Err_Invalid_Argument);
-
- /* first, we check for mark attach classes */
-
- if ( gdef->MarkAttachClassDef.loaded )
- {
- error = _HB_OPEN_Get_Class( &gdef->MarkAttachClassDef, glyphID, &class, &index );
- if ( error && error != HB_Err_Not_Covered )
- return error;
- if ( !error )
- {
- *property = class << 8;
- return HB_Err_Ok;
- }
- }
-
- error = _HB_OPEN_Get_Class( &gdef->GlyphClassDef, glyphID, &class, &index );
- if ( error && error != HB_Err_Not_Covered )
- return error;
-
- /* if we have a constructed class table, check whether additional
- values have been assigned */
-
- if ( error == HB_Err_Not_Covered && gdef->NewGlyphClasses )
- class = Get_New_Class( gdef, glyphID, index );
-
- switch ( class )
- {
- default:
- case UNCLASSIFIED_GLYPH:
- *property = 0;
- break;
-
- case SIMPLE_GLYPH:
- *property = HB_GDEF_BASE_GLYPH;
- break;
-
- case LIGATURE_GLYPH:
- *property = HB_GDEF_LIGATURE;
- break;
-
- case MARK_GLYPH:
- *property = HB_GDEF_MARK;
- break;
-
- case COMPONENT_GLYPH:
- *property = HB_GDEF_COMPONENT;
- break;
- }
-
- return HB_Err_Ok;
-}
-
-
-static HB_Error Make_ClassRange( HB_ClassDefinition* cd,
- HB_UShort start,
- HB_UShort end,
- HB_UShort class )
-{
- HB_Error error;
- HB_UShort index;
-
- HB_ClassDefFormat2* cdf2;
- HB_ClassRangeRecord* crr;
-
-
- cdf2 = &cd->cd.cd2;
-
- if ( REALLOC_ARRAY( cdf2->ClassRangeRecord,
- cdf2->ClassRangeCount + 1 ,
- HB_ClassRangeRecord ) )
- return error;
-
- cdf2->ClassRangeCount++;
-
- crr = cdf2->ClassRangeRecord;
- index = cdf2->ClassRangeCount - 1;
-
- crr[index].Start = start;
- crr[index].End = end;
- crr[index].Class = class;
-
- return HB_Err_Ok;
-}
-
-
-
-HB_Error HB_GDEF_Build_ClassDefinition( HB_GDEFHeader* gdef,
- HB_UShort num_glyphs,
- HB_UShort glyph_count,
- HB_UShort* glyph_array,
- HB_UShort* class_array )
-{
- HB_UShort start, curr_glyph, curr_class;
- HB_UShort n, m, count;
- HB_Error error;
-
- HB_ClassDefinition* gcd;
- HB_ClassRangeRecord* gcrr;
- HB_UShort** ngc;
-
-
- if ( !gdef || !glyph_array || !class_array )
- return ERR(HB_Err_Invalid_Argument);
-
- gcd = &gdef->GlyphClassDef;
-
- /* We build a format 2 table */
-
- gcd->ClassFormat = 2;
-
- gcd->cd.cd2.ClassRangeCount = 0;
- gcd->cd.cd2.ClassRangeRecord = NULL;
-
- start = glyph_array[0];
- curr_class = class_array[0];
- curr_glyph = start;
-
- if ( curr_class >= 5 )
- {
- error = ERR(HB_Err_Invalid_Argument);
- goto Fail4;
- }
-
- glyph_count--;
-
- for ( n = 0; n < glyph_count + 1; n++ )
- {
- if ( curr_glyph == glyph_array[n] && curr_class == class_array[n] )
- {
- if ( n == glyph_count )
- {
- if ( ( error = Make_ClassRange( gcd, start,
- curr_glyph,
- curr_class) ) != HB_Err_Ok )
- goto Fail3;
- }
- else
- {
- if ( curr_glyph == 0xFFFF )
- {
- error = ERR(HB_Err_Invalid_Argument);
- goto Fail3;
- }
- else
- curr_glyph++;
- }
- }
- else
- {
- if ( ( error = Make_ClassRange( gcd, start,
- curr_glyph - 1,
- curr_class) ) != HB_Err_Ok )
- goto Fail3;
-
- if ( curr_glyph > glyph_array[n] )
- {
- error = ERR(HB_Err_Invalid_Argument);
- goto Fail3;
- }
-
- start = glyph_array[n];
- curr_class = class_array[n];
- curr_glyph = start;
-
- if ( curr_class >= 5 )
- {
- error = ERR(HB_Err_Invalid_Argument);
- goto Fail3;
- }
-
- if ( n == glyph_count )
- {
- if ( ( error = Make_ClassRange( gcd, start,
- curr_glyph,
- curr_class) ) != HB_Err_Ok )
- goto Fail3;
- }
- else
- {
- if ( curr_glyph == 0xFFFF )
- {
- error = ERR(HB_Err_Invalid_Argument);
- goto Fail3;
- }
- else
- curr_glyph++;
- }
- }
- }
-
- /* now prepare the arrays for class values assigned during the lookup
- process */
-
- if ( ALLOC_ARRAY( gdef->NewGlyphClasses,
- gcd->cd.cd2.ClassRangeCount + 1, HB_UShort* ) )
- goto Fail3;
-
- count = gcd->cd.cd2.ClassRangeCount;
- gcrr = gcd->cd.cd2.ClassRangeRecord;
- ngc = gdef->NewGlyphClasses;
-
- /* We allocate arrays for all glyphs not covered by the class range
- records. Each element holds four class values. */
-
- if ( count > 0 )
- {
- if ( gcrr[0].Start )
- {
- if ( ALLOC_ARRAY( ngc[0], ( gcrr[0].Start + 3 ) / 4, HB_UShort ) )
- goto Fail2;
- }
-
- for ( n = 1; n < count; n++ )
- {
- if ( gcrr[n].Start - gcrr[n - 1].End > 1 )
- if ( ALLOC_ARRAY( ngc[n],
- ( gcrr[n].Start - gcrr[n - 1].End + 2 ) / 4,
- HB_UShort ) )
- goto Fail1;
- }
-
- if ( gcrr[count - 1].End != num_glyphs - 1 )
- {
- if ( ALLOC_ARRAY( ngc[count],
- ( num_glyphs - gcrr[count - 1].End + 2 ) / 4,
- HB_UShort ) )
- goto Fail1;
- }
- }
- else if ( num_glyphs > 0 )
- {
- if ( ALLOC_ARRAY( ngc[count],
- ( num_glyphs + 3 ) / 4,
- HB_UShort ) )
- goto Fail2;
- }
-
- gdef->LastGlyph = num_glyphs - 1;
-
- gdef->MarkAttachClassDef_offset = 0L;
- gdef->MarkAttachClassDef.loaded = FALSE;
-
- gcd->loaded = TRUE;
-
- return HB_Err_Ok;
-
-Fail1:
- for ( m = 0; m < n; m++ )
- FREE( ngc[m] );
-
-Fail2:
- FREE( gdef->NewGlyphClasses );
-
-Fail3:
- FREE( gcd->cd.cd2.ClassRangeRecord );
-
-Fail4:
- return error;
-}
-
-
-static void Free_NewGlyphClasses( HB_GDEFHeader* gdef )
-{
- HB_UShort** ngc;
- HB_UShort n, count;
-
-
- if ( gdef->NewGlyphClasses )
- {
- count = gdef->GlyphClassDef.cd.cd2.ClassRangeCount + 1;
- ngc = gdef->NewGlyphClasses;
-
- for ( n = 0; n < count; n++ )
- FREE( ngc[n] );
-
- FREE( ngc );
- }
-}
-
-
-HB_INTERNAL HB_Error
-_HB_GDEF_Add_Glyph_Property( HB_GDEFHeader* gdef,
- HB_UShort glyphID,
- HB_UShort property )
-{
- HB_Error error;
- HB_UShort class, new_class, index = 0; /* shut compiler up */
- HB_UShort byte, bits, mask;
- HB_UShort array_index, glyph_index, count;
-
- HB_ClassRangeRecord* gcrr;
- HB_UShort** ngc;
-
-
- error = _HB_OPEN_Get_Class( &gdef->GlyphClassDef, glyphID, &class, &index );
- if ( error && error != HB_Err_Not_Covered )
- return error;
-
- /* we don't accept glyphs covered in `GlyphClassDef' */
-
- if ( !error )
- return HB_Err_Not_Covered;
-
- switch ( property )
- {
- case 0:
- new_class = UNCLASSIFIED_GLYPH;
- break;
-
- case HB_GDEF_BASE_GLYPH:
- new_class = SIMPLE_GLYPH;
- break;
-
- case HB_GDEF_LIGATURE:
- new_class = LIGATURE_GLYPH;
- break;
-
- case HB_GDEF_MARK:
- new_class = MARK_GLYPH;
- break;
-
- case HB_GDEF_COMPONENT:
- new_class = COMPONENT_GLYPH;
- break;
-
- default:
- return ERR(HB_Err_Invalid_Argument);
- }
-
- count = gdef->GlyphClassDef.cd.cd2.ClassRangeCount;
- gcrr = gdef->GlyphClassDef.cd.cd2.ClassRangeRecord;
- ngc = gdef->NewGlyphClasses;
-
- if ( index < count && glyphID < gcrr[index].Start )
- {
- array_index = index;
- if ( index == 0 )
- glyph_index = glyphID;
- else
- glyph_index = glyphID - gcrr[index - 1].End - 1;
- }
- else
- {
- array_index = index + 1;
- glyph_index = glyphID - gcrr[index].End - 1;
- }
-
- byte = ngc[array_index][glyph_index / 4];
- bits = byte >> ( 16 - ( glyph_index % 4 + 1 ) * 4 );
- class = bits & 0x000F;
-
- /* we don't overwrite existing entries */
-
- if ( !class )
- {
- bits = new_class << ( 16 - ( glyph_index % 4 + 1 ) * 4 );
- mask = ~( 0x000F << ( 16 - ( glyph_index % 4 + 1 ) * 4 ) );
-
- ngc[array_index][glyph_index / 4] &= mask;
- ngc[array_index][glyph_index / 4] |= bits;
- }
-
- return HB_Err_Ok;
-}
-
-
-HB_INTERNAL HB_Error
-_HB_GDEF_Check_Property( HB_GDEFHeader* gdef,
- HB_GlyphItem gitem,
- HB_UShort flags,
- HB_UShort* property )
-{
- HB_Error error;
-
- if ( gdef )
- {
- HB_UShort basic_glyph_class;
- HB_UShort desired_attachment_class;
-
- if ( gitem->gproperties == HB_GLYPH_PROPERTIES_UNKNOWN )
- {
- error = HB_GDEF_Get_Glyph_Property( gdef, gitem->gindex, &gitem->gproperties );
- if ( error )
- return error;
- }
-
- *property = gitem->gproperties;
-
- /* If the glyph was found in the MarkAttachmentClass table,
- * then that class value is the high byte of the result,
- * otherwise the low byte contains the basic type of the glyph
- * as defined by the GlyphClassDef table.
- */
- if ( *property & HB_LOOKUP_FLAG_IGNORE_SPECIAL_MARKS )
- basic_glyph_class = HB_GDEF_MARK;
- else
- basic_glyph_class = *property;
-
- /* Return Not_Covered, if, for example, basic_glyph_class
- * is HB_GDEF_LIGATURE and LookFlags includes HB_LOOKUP_FLAG_IGNORE_LIGATURES
- */
- if ( flags & basic_glyph_class )
- return HB_Err_Not_Covered;
-
- /* The high byte of LookupFlags has the meaning
- * "ignore marks of attachment type different than
- * the attachment type specified."
- */
- desired_attachment_class = flags & HB_LOOKUP_FLAG_IGNORE_SPECIAL_MARKS;
- if ( desired_attachment_class )
- {
- if ( basic_glyph_class == HB_GDEF_MARK &&
- *property != desired_attachment_class )
- return HB_Err_Not_Covered;
- }
- } else {
- *property = 0;
- }
-
- return HB_Err_Ok;
-}
-
-HB_INTERNAL HB_Error
-_HB_GDEF_LoadMarkAttachClassDef_From_LookupFlags( HB_GDEFHeader* gdef,
- HB_Stream stream,
- HB_Lookup* lo,
- HB_UShort num_lookups)
-{
- HB_Error error = HB_Err_Ok;
- HB_UShort i;
-
- /* We now check the LookupFlags for values larger than 0xFF to find
- out whether we need to load the `MarkAttachClassDef' field of the
- GDEF table -- this hack is necessary for OpenType 1.2 tables since
- the version field of the GDEF table hasn't been incremented.
-
- For constructed GDEF tables, we only load it if
- `MarkAttachClassDef_offset' is not zero (nevertheless, a build of
- a constructed mark attach table is not supported currently). */
-
- if ( gdef &&
- gdef->MarkAttachClassDef_offset && !gdef->MarkAttachClassDef.loaded )
- {
- for ( i = 0; i < num_lookups; i++ )
- {
-
- if ( lo[i].LookupFlag & HB_LOOKUP_FLAG_IGNORE_SPECIAL_MARKS )
- {
- if ( FILE_Seek( gdef->MarkAttachClassDef_offset ) ||
- ( error = _HB_OPEN_Load_ClassDefinition( &gdef->MarkAttachClassDef,
- 256, stream ) ) != HB_Err_Ok )
- goto Done;
-
- break;
- }
- }
- }
-
-Done:
- return error;
-}
-
-/* END */
diff --git a/src/3rdparty/harfbuzz/src/harfbuzz-gdef.h b/src/3rdparty/harfbuzz/src/harfbuzz-gdef.h
deleted file mode 100644
index ccb6bf9734..0000000000
--- a/src/3rdparty/harfbuzz/src/harfbuzz-gdef.h
+++ /dev/null
@@ -1,132 +0,0 @@
-/*
- * Copyright (C) 1998-2004 David Turner and Werner Lemberg
- * Copyright (C) 2006 Behdad Esfahbod
- *
- * This is part of HarfBuzz, an OpenType Layout engine 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 HARFBUZZ_GDEF_H
-#define HARFBUZZ_GDEF_H
-
-#include "harfbuzz-open.h"
-#include "harfbuzz-stream.h"
-
-HB_BEGIN_HEADER
-
-/* GDEF glyph properties. Note that HB_GDEF_COMPONENT has no corresponding
- * flag in the LookupFlag field. */
-#define HB_GDEF_BASE_GLYPH 0x0002
-#define HB_GDEF_LIGATURE 0x0004
-#define HB_GDEF_MARK 0x0008
-#define HB_GDEF_COMPONENT 0x0010
-
-
-typedef struct HB_AttachPoint_ HB_AttachPoint;
-
-
-struct HB_AttachList_
-{
- HB_AttachPoint* AttachPoint; /* array of AttachPoint tables */
- HB_Coverage Coverage; /* Coverage table */
- HB_UShort GlyphCount; /* number of glyphs with
- attachments */
- HB_Bool loaded;
-};
-
-typedef struct HB_AttachList_ HB_AttachList;
-
-typedef struct HB_LigGlyph_ HB_LigGlyph;
-
-struct HB_LigCaretList_
-{
- HB_LigGlyph* LigGlyph; /* array of LigGlyph tables */
- HB_Coverage Coverage; /* Coverage table */
- HB_UShort LigGlyphCount; /* number of ligature glyphs */
- HB_Bool loaded;
-};
-
-typedef struct HB_LigCaretList_ HB_LigCaretList;
-
-
-
-/* The `NewGlyphClasses' field is not defined in the TTO specification.
- We use it for fonts with a constructed `GlyphClassDef' structure
- (i.e., which don't have a GDEF table) to collect glyph classes
- assigned during the lookup process. The number of arrays in this
- pointer array is GlyphClassDef->cd.cd2.ClassRangeCount+1; the nth
- array then contains the glyph class values of the glyphs not covered
- by the ClassRangeRecords structures with index n-1 and n. We store
- glyph class values for four glyphs in a single array element.
-
- `LastGlyph' is identical to the number of glyphs minus one in the
- font; we need it only if `NewGlyphClasses' is not NULL (to have an
- upper bound for the last array).
-
- Note that we first store the file offset to the `MarkAttachClassDef'
- field (which has been introduced in OpenType 1.2) -- since the
- `Version' field value hasn't been increased to indicate that we have
- one more field for some obscure reason, we must parse the GSUB table
- to find out whether class values refer to this table. Only then we
- can finally load the MarkAttachClassDef structure if necessary. */
-
-struct HB_GDEFHeader_
-{
- HB_UShort** NewGlyphClasses;
- HB_UInt offset;
- HB_UInt MarkAttachClassDef_offset;
-
- HB_16Dot16 Version;
-
- HB_ClassDefinition GlyphClassDef;
- HB_AttachList AttachList;
- HB_LigCaretList LigCaretList;
- HB_ClassDefinition MarkAttachClassDef; /* new in OT 1.2 */
-
- HB_UShort LastGlyph;
-};
-
-typedef struct HB_GDEFHeader_ HB_GDEFHeader;
-typedef struct HB_GDEFHeader_* HB_GDEF;
-
-
-HB_Error HB_New_GDEF_Table( HB_GDEFHeader** retptr );
-
-
-HB_Error HB_Load_GDEF_Table( HB_Stream stream,
- HB_GDEFHeader** gdef );
-
-
-HB_Error HB_Done_GDEF_Table ( HB_GDEFHeader* gdef );
-
-
-HB_Error HB_GDEF_Get_Glyph_Property( HB_GDEFHeader* gdef,
- HB_UShort glyphID,
- HB_UShort* property );
-
-HB_Error HB_GDEF_Build_ClassDefinition( HB_GDEFHeader* gdef,
- HB_UShort num_glyphs,
- HB_UShort glyph_count,
- HB_UShort* glyph_array,
- HB_UShort* class_array );
-
-HB_END_HEADER
-
-#endif /* HARFBUZZ_GDEF_H */
diff --git a/src/3rdparty/harfbuzz/src/harfbuzz-global.h b/src/3rdparty/harfbuzz/src/harfbuzz-global.h
deleted file mode 100644
index 69e0666b8a..0000000000
--- a/src/3rdparty/harfbuzz/src/harfbuzz-global.h
+++ /dev/null
@@ -1,118 +0,0 @@
-/*
- * Copyright (C) 2015 The Qt Company Ltd
- * Copyright (C) 2007 Red Hat, Inc.
- *
- * This is part of HarfBuzz, an OpenType Layout engine library.
- *
- * Permission is hereby granted, without written agreement and without
- * license or royalty fees, to use, copy, modify, and distribute this
- * software and its documentation for any purpose, provided that the
- * above copyright notice and the following two paragraphs appear in
- * all copies of this software.
- *
- * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
- * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
- * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
- * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
- * DAMAGE.
- *
- * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
- * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
- * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
- * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
- * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
- *
- * Red Hat Author(s): Behdad Esfahbod
- */
-
-#ifndef HARFBUZZ_GLOBAL_H
-#define HARFBUZZ_GLOBAL_H
-
-#include <stdlib.h>
-#include <string.h>
-
-#ifdef __cplusplus
-#define HB_BEGIN_HEADER extern "C" {
-#define HB_END_HEADER }
-#else
-#define HB_BEGIN_HEADER /* nothing */
-#define HB_END_HEADER /* nothing */
-#endif
-
-HB_BEGIN_HEADER
-
-#ifndef FALSE
-#define FALSE 0
-#endif
-
-#ifndef TRUE
-#define TRUE (!FALSE)
-#endif
-
-#define HB_MAKE_TAG( _x1, _x2, _x3, _x4 ) \
- ( ( (HB_UInt)_x1 << 24 ) | \
- ( (HB_UInt)_x2 << 16 ) | \
- ( (HB_UInt)_x3 << 8 ) | \
- (HB_UInt)_x4 )
-
-typedef char hb_int8;
-typedef unsigned char hb_uint8;
-typedef short hb_int16;
-typedef unsigned short hb_uint16;
-typedef int hb_int32;
-typedef unsigned int hb_uint32;
-
-typedef hb_uint8 HB_Bool;
-
-typedef hb_uint8 HB_Byte;
-typedef hb_uint16 HB_UShort;
-typedef hb_uint32 HB_UInt;
-typedef hb_int8 HB_Char;
-typedef hb_int16 HB_Short;
-typedef hb_int32 HB_Int;
-
-typedef hb_uint16 HB_UChar16;
-typedef hb_uint32 HB_UChar32;
-typedef hb_uint32 HB_Glyph;
-typedef hb_int32 HB_Fixed; /* 26.6 */
-
-#define HB_FIXED_CONSTANT(v) ((v) * 64)
-#define HB_FIXED_ROUND(v) (((v)+32) & -64)
-
-typedef hb_int32 HB_16Dot16; /* 16.16 */
-
-typedef void * HB_Pointer;
-typedef hb_uint32 HB_Tag;
-
-typedef enum {
- /* no error */
- HB_Err_Ok = 0x0000,
- HB_Err_Not_Covered = 0xFFFF,
-
- /* _hb_err() is called whenever returning the following errors,
- * and in a couple places for HB_Err_Not_Covered too. */
-
- /* programmer error */
- HB_Err_Invalid_Argument = 0x1A66,
-
- /* font error */
- HB_Err_Invalid_SubTable_Format = 0x157F,
- HB_Err_Invalid_SubTable = 0x1570,
- HB_Err_Read_Error = 0x6EAD,
-
- /* system error */
- HB_Err_Out_Of_Memory = 0xDEAD
-} HB_Error;
-
-typedef struct {
- HB_Fixed x;
- HB_Fixed y;
-} HB_FixedPoint;
-
-typedef struct HB_Font_ *HB_Font;
-typedef struct HB_StreamRec_ *HB_Stream;
-typedef struct HB_FaceRec_ *HB_Face;
-
-HB_END_HEADER
-
-#endif
diff --git a/src/3rdparty/harfbuzz/src/harfbuzz-gpos-private.h b/src/3rdparty/harfbuzz/src/harfbuzz-gpos-private.h
deleted file mode 100644
index 9f0fecd61e..0000000000
--- a/src/3rdparty/harfbuzz/src/harfbuzz-gpos-private.h
+++ /dev/null
@@ -1,733 +0,0 @@
-/*
- * Copyright (C) 1998-2004 David Turner and Werner Lemberg
- * Copyright (C) 2006 Behdad Esfahbod
- *
- * This is part of HarfBuzz, an OpenType Layout engine 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 HARFBUZZ_GPOS_PRIVATE_H
-#define HARFBUZZ_GPOS_PRIVATE_H
-
-#include "harfbuzz-impl.h"
-#include "harfbuzz-stream-private.h"
-#include "harfbuzz-gpos.h"
-
-HB_BEGIN_HEADER
-
-/* shared tables */
-
-#define VR_X_PLACEMENT_DEVICE 0
-#define VR_Y_PLACEMENT_DEVICE 1
-#define VR_X_ADVANCE_DEVICE 2
-#define VR_Y_ADVANCE_DEVICE 3
-
-#ifndef HB_SUPPORT_MULTIPLE_MASTER
-# define HB_USE_FLEXIBLE_VALUE_RECORD
-#endif
-
-struct HB_ValueRecord_
-{
- HB_Short XPlacement; /* horizontal adjustment for
- placement */
- HB_Short YPlacement; /* vertical adjustment for
- placement */
- HB_Short XAdvance; /* horizontal adjustment for
- advance */
- HB_Short YAdvance; /* vertical adjustment for
- advance */
-
- HB_Device** DeviceTables; /* device tables for placement
- and advance */
-
-#ifdef HB_SUPPORT_MULTIPLE_MASTER
- HB_UShort XIdPlacement; /* horizontal placement metric ID */
- HB_UShort YIdPlacement; /* vertical placement metric ID */
- HB_UShort XIdAdvance; /* horizontal advance metric ID */
- HB_UShort YIdAdvance; /* vertical advance metric ID */
-#endif
-};
-
-typedef struct HB_ValueRecord_ HB_ValueRecord;
-
-
-/* Mask values to scan the value format of the ValueRecord structure.
- We always expand compressed ValueRecords of the font. */
-
-#define HB_GPOS_FORMAT_HAVE_DEVICE_TABLES 0x00F0
-
-#define HB_GPOS_FORMAT_HAVE_X_PLACEMENT 0x0001
-#define HB_GPOS_FORMAT_HAVE_Y_PLACEMENT 0x0002
-#define HB_GPOS_FORMAT_HAVE_X_ADVANCE 0x0004
-#define HB_GPOS_FORMAT_HAVE_Y_ADVANCE 0x0008
-#define HB_GPOS_FORMAT_HAVE_X_PLACEMENT_DEVICE 0x0010
-#define HB_GPOS_FORMAT_HAVE_Y_PLACEMENT_DEVICE 0x0020
-#define HB_GPOS_FORMAT_HAVE_X_ADVANCE_DEVICE 0x0040
-#define HB_GPOS_FORMAT_HAVE_Y_ADVANCE_DEVICE 0x0080
-#define HB_GPOS_FORMAT_HAVE_X_ID_PLACEMENT 0x0100
-#define HB_GPOS_FORMAT_HAVE_Y_ID_PLACEMENT 0x0200
-#define HB_GPOS_FORMAT_HAVE_X_ID_ADVANCE 0x0400
-#define HB_GPOS_FORMAT_HAVE_Y_ID_ADVANCE 0x0800
-
-
-struct HB_AnchorFormat1_
-{
- HB_Short XCoordinate; /* horizontal value */
- HB_Short YCoordinate; /* vertical value */
-};
-
-typedef struct HB_AnchorFormat1_ HB_AnchorFormat1;
-
-
-struct HB_AnchorFormat2_
-{
- HB_Short XCoordinate; /* horizontal value */
- HB_Short YCoordinate; /* vertical value */
- HB_UShort AnchorPoint; /* index to glyph contour point */
-};
-
-typedef struct HB_AnchorFormat2_ HB_AnchorFormat2;
-
-#define AF3_X_DEVICE_TABLE 0
-#define AF3_Y_DEVICE_TABLE 1
-
-struct HB_AnchorFormat3_
-{
- HB_Short XCoordinate; /* horizontal value */
- HB_Short YCoordinate; /* vertical value */
- HB_Device** DeviceTables; /* device tables for coordinates */
-};
-
-typedef struct HB_AnchorFormat3_ HB_AnchorFormat3;
-
-
-#ifdef HB_SUPPORT_MULTIPLE_MASTER
-struct HB_AnchorFormat4_
-{
- HB_UShort XIdAnchor; /* horizontal metric ID */
- HB_UShort YIdAnchor; /* vertical metric ID */
-};
-
-typedef struct HB_AnchorFormat4_ HB_AnchorFormat4;
-#endif
-
-
-struct HB_Anchor_
-{
- HB_Byte PosFormat; /* 1, 2, 3, or 4 -- 0 indicates
- that there is no Anchor table */
-
- union
- {
- HB_AnchorFormat1 af1;
- HB_AnchorFormat2 af2;
- HB_AnchorFormat3 af3;
-#ifdef HB_SUPPORT_MULTIPLE_MASTER
- HB_AnchorFormat4 af4;
-#endif
- } af;
-};
-
-typedef struct HB_Anchor_ HB_Anchor;
-
-
-struct HB_MarkRecord_
-{
- HB_UShort Class; /* mark class */
- HB_Anchor MarkAnchor; /* anchor table */
-};
-
-typedef struct HB_MarkRecord_ HB_MarkRecord;
-
-
-struct HB_MarkArray_
-{
- HB_UShort MarkCount; /* number of MarkRecord tables */
- HB_MarkRecord* MarkRecord; /* array of MarkRecord tables */
-};
-
-typedef struct HB_MarkArray_ HB_MarkArray;
-
-
-/* LookupType 1 */
-
-struct HB_SinglePosFormat1_
-{
- HB_ValueRecord Value; /* ValueRecord for all covered
- glyphs */
-};
-
-typedef struct HB_SinglePosFormat1_ HB_SinglePosFormat1;
-
-
-struct HB_SinglePosFormat2_
-{
- HB_UShort ValueCount; /* number of ValueRecord tables */
- HB_ValueRecord* Value; /* array of ValueRecord tables */
-};
-
-typedef struct HB_SinglePosFormat2_ HB_SinglePosFormat2;
-
-
-struct HB_SinglePos_
-{
- HB_Byte PosFormat; /* 1 or 2 */
- HB_Coverage Coverage; /* Coverage table */
-
- HB_UShort ValueFormat; /* format of ValueRecord table */
-
- union
- {
- HB_SinglePosFormat1 spf1;
- HB_SinglePosFormat2 spf2;
- } spf;
-};
-
-typedef struct HB_SinglePos_ HB_SinglePos;
-
-
-/* LookupType 2 */
-
-struct HB_PairValueRecord_
-{
- HB_UShort SecondGlyph; /* glyph ID for second glyph */
- HB_ValueRecord Value1; /* pos. data for first glyph */
- HB_ValueRecord Value2; /* pos. data for second glyph */
-};
-
-typedef struct HB_PairValueRecord_ HB_PairValueRecord;
-
-
-struct HB_PairSet_
-{
- HB_UShort PairValueCount;
- /* number of PairValueRecord tables */
-#ifndef HB_USE_FLEXIBLE_VALUE_RECORD
- HB_PairValueRecord* PairValueRecord;
- /* array of PairValueRecord tables */
-#else
- HB_Short* ValueRecords;
-#endif
-};
-
-typedef struct HB_PairSet_ HB_PairSet;
-
-
-struct HB_PairPosFormat1_
-{
- HB_UShort PairSetCount; /* number of PairSet tables */
- HB_PairSet* PairSet; /* array of PairSet tables */
-};
-
-typedef struct HB_PairPosFormat1_ HB_PairPosFormat1;
-
-
-struct HB_Class2Record_
-{
- HB_ValueRecord Value1; /* pos. data for first glyph */
- HB_ValueRecord Value2; /* pos. data for second glyph */
-};
-
-typedef struct HB_Class2Record_ HB_Class2Record;
-
-
-struct HB_Class1Record_
-{
- hb_uint8 IsFlexible;
- union {
- HB_Class2Record* Class2Record; /* array of Class2Record tables */
- HB_Short* ValueRecords;
- } c2r;
-};
-
-typedef struct HB_Class1Record_ HB_Class1Record;
-
-
-struct HB_PairPosFormat2_
-{
- HB_ClassDefinition ClassDef1; /* class def. for first glyph */
- HB_ClassDefinition ClassDef2; /* class def. for second glyph */
- HB_UShort Class1Count; /* number of classes in ClassDef1
- table */
- HB_UShort Class2Count; /* number of classes in ClassDef2
- table */
- HB_Class1Record* Class1Record; /* array of Class1Record tables */
-};
-
-typedef struct HB_PairPosFormat2_ HB_PairPosFormat2;
-
-
-struct HB_PairPos_
-{
- HB_Byte PosFormat; /* 1 or 2 */
- HB_Coverage Coverage; /* Coverage table */
- HB_UShort ValueFormat1; /* format of ValueRecord table
- for first glyph */
- HB_UShort ValueFormat2; /* format of ValueRecord table
- for second glyph */
-
- union
- {
- HB_PairPosFormat1 ppf1;
- HB_PairPosFormat2 ppf2;
- } ppf;
-};
-
-typedef struct HB_PairPos_ HB_PairPos;
-
-
-/* LookupType 3 */
-
-struct HB_EntryExitRecord_
-{
- HB_Anchor EntryAnchor; /* entry Anchor table */
- HB_Anchor ExitAnchor; /* exit Anchor table */
-};
-
-
-typedef struct HB_EntryExitRecord_ HB_EntryExitRecord;
-
-struct HB_CursivePos_
-{
- HB_UShort PosFormat; /* always 1 */
- HB_Coverage Coverage; /* Coverage table */
- HB_UShort EntryExitCount;
- /* number of EntryExitRecord tables */
- HB_EntryExitRecord* EntryExitRecord;
- /* array of EntryExitRecord tables */
-};
-
-typedef struct HB_CursivePos_ HB_CursivePos;
-
-
-/* LookupType 4 */
-
-struct HB_BaseRecord_
-{
- HB_Anchor* BaseAnchor; /* array of base glyph anchor
- tables */
-};
-
-typedef struct HB_BaseRecord_ HB_BaseRecord;
-
-
-struct HB_BaseArray_
-{
- HB_UShort BaseCount; /* number of BaseRecord tables */
- HB_BaseRecord* BaseRecord; /* array of BaseRecord tables */
-};
-
-typedef struct HB_BaseArray_ HB_BaseArray;
-
-
-struct HB_MarkBasePos_
-{
- HB_UShort PosFormat; /* always 1 */
- HB_Coverage MarkCoverage; /* mark glyph coverage table */
- HB_Coverage BaseCoverage; /* base glyph coverage table */
- HB_UShort ClassCount; /* number of mark classes */
- HB_MarkArray MarkArray; /* mark array table */
- HB_BaseArray BaseArray; /* base array table */
-};
-
-typedef struct HB_MarkBasePos_ HB_MarkBasePos;
-
-
-/* LookupType 5 */
-
-struct HB_ComponentRecord_
-{
- HB_Anchor* LigatureAnchor; /* array of ligature glyph anchor
- tables */
-};
-
-typedef struct HB_ComponentRecord_ HB_ComponentRecord;
-
-
-struct HB_LigatureAttach_
-{
- HB_UShort ComponentCount;
- /* number of ComponentRecord tables */
- HB_ComponentRecord* ComponentRecord;
- /* array of ComponentRecord tables */
-};
-
-typedef struct HB_LigatureAttach_ HB_LigatureAttach;
-
-
-struct HB_LigatureArray_
-{
- HB_UShort LigatureCount; /* number of LigatureAttach tables */
- HB_LigatureAttach* LigatureAttach;
- /* array of LigatureAttach tables */
-};
-
-typedef struct HB_LigatureArray_ HB_LigatureArray;
-
-
-struct HB_MarkLigPos_
-{
- HB_UShort PosFormat; /* always 1 */
- HB_Coverage MarkCoverage; /* mark glyph coverage table */
- HB_Coverage LigatureCoverage;
- /* ligature glyph coverage table */
- HB_UShort ClassCount; /* number of mark classes */
- HB_MarkArray MarkArray; /* mark array table */
- HB_LigatureArray LigatureArray; /* ligature array table */
-};
-
-typedef struct HB_MarkLigPos_ HB_MarkLigPos;
-
-
-/* LookupType 6 */
-
-struct HB_Mark2Record_
-{
- HB_Anchor* Mark2Anchor; /* array of mark glyph anchor
- tables */
-};
-
-typedef struct HB_Mark2Record_ HB_Mark2Record;
-
-
-struct HB_Mark2Array_
-{
- HB_UShort Mark2Count; /* number of Mark2Record tables */
- HB_Mark2Record* Mark2Record; /* array of Mark2Record tables */
-};
-
-typedef struct HB_Mark2Array_ HB_Mark2Array;
-
-
-struct HB_MarkMarkPos_
-{
- HB_UShort PosFormat; /* always 1 */
- HB_Coverage Mark1Coverage; /* first mark glyph coverage table */
- HB_Coverage Mark2Coverage; /* second mark glyph coverave table */
- HB_UShort ClassCount; /* number of combining mark classes */
- HB_MarkArray Mark1Array; /* MarkArray table for first mark */
- HB_Mark2Array Mark2Array; /* MarkArray table for second mark */
-};
-
-typedef struct HB_MarkMarkPos_ HB_MarkMarkPos;
-
-
-/* needed by both lookup type 7 and 8 */
-
-struct HB_PosLookupRecord_
-{
- HB_UShort SequenceIndex; /* index into current
- glyph sequence */
- HB_UShort LookupListIndex; /* Lookup to apply to that pos. */
-};
-
-typedef struct HB_PosLookupRecord_ HB_PosLookupRecord;
-
-
-/* LookupType 7 */
-
-struct HB_PosRule_
-{
- HB_UShort GlyphCount; /* total number of input glyphs */
- HB_UShort PosCount; /* number of PosLookupRecord tables */
- HB_UShort* Input; /* array of input glyph IDs */
- HB_PosLookupRecord* PosLookupRecord;
- /* array of PosLookupRecord tables */
-};
-
-typedef struct HB_PosRule_ HB_PosRule;
-
-
-struct HB_PosRuleSet_
-{
- HB_UShort PosRuleCount; /* number of PosRule tables */
- HB_PosRule* PosRule; /* array of PosRule tables */
-};
-
-typedef struct HB_PosRuleSet_ HB_PosRuleSet;
-
-
-struct HB_ContextPosFormat1_
-{
- HB_Coverage Coverage; /* Coverage table */
- HB_UShort PosRuleSetCount; /* number of PosRuleSet tables */
- HB_PosRuleSet* PosRuleSet; /* array of PosRuleSet tables */
-};
-
-typedef struct HB_ContextPosFormat1_ HB_ContextPosFormat1;
-
-
-struct HB_PosClassRule_
-{
- HB_UShort GlyphCount; /* total number of context classes */
- HB_UShort PosCount; /* number of PosLookupRecord tables */
- HB_UShort* Class; /* array of classes */
- HB_PosLookupRecord* PosLookupRecord;
- /* array of PosLookupRecord tables */
-};
-
-typedef struct HB_PosClassRule_ HB_PosClassRule;
-
-
-struct HB_PosClassSet_
-{
- HB_UShort PosClassRuleCount;
- /* number of PosClassRule tables */
- HB_PosClassRule* PosClassRule; /* array of PosClassRule tables */
-};
-
-typedef struct HB_PosClassSet_ HB_PosClassSet;
-
-
-/* The `MaxContextLength' field is not defined in the TTO specification
- but simplifies the implementation of this format. It holds the
- maximal context length used in the context rules. */
-
-struct HB_ContextPosFormat2_
-{
- HB_UShort MaxContextLength;
- /* maximal context length */
- HB_Coverage Coverage; /* Coverage table */
- HB_ClassDefinition ClassDef; /* ClassDef table */
- HB_UShort PosClassSetCount;
- /* number of PosClassSet tables */
- HB_PosClassSet* PosClassSet; /* array of PosClassSet tables */
-};
-
-typedef struct HB_ContextPosFormat2_ HB_ContextPosFormat2;
-
-
-struct HB_ContextPosFormat3_
-{
- HB_UShort GlyphCount; /* number of input glyphs */
- HB_UShort PosCount; /* number of PosLookupRecord tables */
- HB_Coverage* Coverage; /* array of Coverage tables */
- HB_PosLookupRecord* PosLookupRecord;
- /* array of PosLookupRecord tables */
-};
-
-typedef struct HB_ContextPosFormat3_ HB_ContextPosFormat3;
-
-
-struct HB_ContextPos_
-{
- HB_Byte PosFormat; /* 1, 2, or 3 */
-
- union
- {
- HB_ContextPosFormat1 cpf1;
- HB_ContextPosFormat2 cpf2;
- HB_ContextPosFormat3 cpf3;
- } cpf;
-};
-
-typedef struct HB_ContextPos_ HB_ContextPos;
-
-
-/* LookupType 8 */
-
-struct HB_ChainPosRule_
-{
- HB_UShort* Backtrack; /* array of backtrack glyph IDs */
- HB_UShort* Input; /* array of input glyph IDs */
- HB_UShort* Lookahead; /* array of lookahead glyph IDs */
- HB_PosLookupRecord* PosLookupRecord;
- /* array of PosLookupRecords */
- HB_UShort BacktrackGlyphCount;
- /* total number of backtrack glyphs */
- HB_UShort InputGlyphCount;
- /* total number of input glyphs */
- HB_UShort LookaheadGlyphCount;
- /* total number of lookahead glyphs */
- HB_UShort PosCount; /* number of PosLookupRecords */
-};
-
-typedef struct HB_ChainPosRule_ HB_ChainPosRule;
-
-
-struct HB_ChainPosRuleSet_
-{
- HB_UShort ChainPosRuleCount;
- /* number of ChainPosRule tables */
- HB_ChainPosRule* ChainPosRule; /* array of ChainPosRule tables */
-};
-
-typedef struct HB_ChainPosRuleSet_ HB_ChainPosRuleSet;
-
-
-struct HB_ChainContextPosFormat1_
-{
- HB_Coverage Coverage; /* Coverage table */
- HB_UShort ChainPosRuleSetCount;
- /* number of ChainPosRuleSet tables */
- HB_ChainPosRuleSet* ChainPosRuleSet;
- /* array of ChainPosRuleSet tables */
-};
-
-typedef struct HB_ChainContextPosFormat1_ HB_ChainContextPosFormat1;
-
-
-struct HB_ChainPosClassRule_
-{
- HB_UShort* Backtrack; /* array of backtrack classes */
- HB_UShort* Input; /* array of context classes */
- HB_UShort* Lookahead; /* array of lookahead classes */
- HB_PosLookupRecord* PosLookupRecord;
- /* array of substitution lookups */
- HB_UShort BacktrackGlyphCount;
- /* total number of backtrack
- classes */
- HB_UShort InputGlyphCount;
- /* total number of context classes */
- HB_UShort LookaheadGlyphCount;
- /* total number of lookahead
- classes */
- HB_UShort PosCount; /* number of PosLookupRecords */
-};
-
-typedef struct HB_ChainPosClassRule_ HB_ChainPosClassRule;
-
-
-struct HB_ChainPosClassSet_
-{
- HB_UShort ChainPosClassRuleCount;
- /* number of ChainPosClassRule
- tables */
- HB_ChainPosClassRule* ChainPosClassRule;
- /* array of ChainPosClassRule
- tables */
-};
-
-typedef struct HB_ChainPosClassSet_ HB_ChainPosClassSet;
-
-
-/* The `MaxXXXLength' fields are not defined in the TTO specification
- but simplifies the implementation of this format. It holds the
- maximal context length used in the specific context rules. */
-
-struct HB_ChainContextPosFormat2_
-{
- HB_Coverage Coverage; /* Coverage table */
-
- HB_UShort MaxBacktrackLength;
- /* maximal backtrack length */
- HB_ClassDefinition BacktrackClassDef;
- /* BacktrackClassDef table */
- HB_UShort MaxInputLength;
- /* maximal input length */
- HB_ClassDefinition InputClassDef;
- /* InputClassDef table */
- HB_UShort MaxLookaheadLength;
- /* maximal lookahead length */
- HB_ClassDefinition LookaheadClassDef;
- /* LookaheadClassDef table */
-
- HB_UShort ChainPosClassSetCount;
- /* number of ChainPosClassSet
- tables */
- HB_ChainPosClassSet* ChainPosClassSet;
- /* array of ChainPosClassSet
- tables */
-};
-
-typedef struct HB_ChainContextPosFormat2_ HB_ChainContextPosFormat2;
-
-
-struct HB_ChainContextPosFormat3_
-{
- HB_UShort BacktrackGlyphCount;
- /* number of backtrack glyphs */
- HB_Coverage* BacktrackCoverage;
- /* array of backtrack Coverage
- tables */
- HB_UShort InputGlyphCount;
- /* number of input glyphs */
- HB_Coverage* InputCoverage;
- /* array of input coverage
- tables */
- HB_UShort LookaheadGlyphCount;
- /* number of lookahead glyphs */
- HB_Coverage* LookaheadCoverage;
- /* array of lookahead coverage
- tables */
- HB_UShort PosCount; /* number of PosLookupRecords */
- HB_PosLookupRecord* PosLookupRecord;
- /* array of substitution lookups */
-};
-
-typedef struct HB_ChainContextPosFormat3_ HB_ChainContextPosFormat3;
-
-
-struct HB_ChainContextPos_
-{
- HB_Byte PosFormat; /* 1, 2, or 3 */
-
- union
- {
- HB_ChainContextPosFormat1 ccpf1;
- HB_ChainContextPosFormat2 ccpf2;
- HB_ChainContextPosFormat3 ccpf3;
- } ccpf;
-};
-
-typedef struct HB_ChainContextPos_ HB_ChainContextPos;
-
-
-#if 0
-/* LookupType 10 */
-struct HB_ExtensionPos_
-{
- HB_UShort PosFormat; /* always 1 */
- HB_UShort LookuptType; /* lookup-type of referenced subtable */
- HB_GPOS_SubTable *subtable; /* referenced subtable */
-};
-
-typedef struct HB_ExtensionPos_ HB_ExtensionPos;
-#endif
-
-
-union HB_GPOS_SubTable_
-{
- HB_SinglePos single;
- HB_PairPos pair;
- HB_CursivePos cursive;
- HB_MarkBasePos markbase;
- HB_MarkLigPos marklig;
- HB_MarkMarkPos markmark;
- HB_ContextPos context;
- HB_ChainContextPos chain;
-};
-
-typedef union HB_GPOS_SubTable_ HB_GPOS_SubTable;
-
-
-
-HB_INTERNAL HB_Error
-_HB_GPOS_Load_SubTable( HB_GPOS_SubTable* st,
- HB_Stream stream,
- HB_UShort lookup_type );
-
-HB_INTERNAL void
-_HB_GPOS_Free_SubTable( HB_GPOS_SubTable* st,
- HB_UShort lookup_type );
-
-HB_END_HEADER
-
-#endif /* HARFBUZZ_GPOS_PRIVATE_H */
diff --git a/src/3rdparty/harfbuzz/src/harfbuzz-gpos.c b/src/3rdparty/harfbuzz/src/harfbuzz-gpos.c
deleted file mode 100644
index 90e31a589c..0000000000
--- a/src/3rdparty/harfbuzz/src/harfbuzz-gpos.c
+++ /dev/null
@@ -1,6275 +0,0 @@
-/*
- * Copyright (C) 1998-2004 David Turner and Werner Lemberg
- * Copyright (C) 2006 Behdad Esfahbod
- * Copyright (C) 2007 Red Hat, Inc.
- *
- * This is part of HarfBuzz, an OpenType Layout engine library.
- *
- * Permission is hereby granted, without written agreement and without
- * license or royalty fees, to use, copy, modify, and distribute this
- * software and its documentation for any purpose, provided that the
- * above copyright notice and the following two paragraphs appear in
- * all copies of this software.
- *
- * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
- * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
- * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
- * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
- * DAMAGE.
- *
- * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
- * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
- * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
- * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
- * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
- *
- * Red Hat Author(s): Behdad Esfahbod
- */
-
-#include "harfbuzz-impl.h"
-#include "harfbuzz-gpos-private.h"
-#include "harfbuzz-open-private.h"
-#include "harfbuzz-gdef-private.h"
-#include "harfbuzz-shaper.h"
-
-struct GPOS_Instance_
-{
- HB_GPOSHeader* gpos;
- HB_Font font;
- HB_Bool dvi;
- HB_UShort load_flags; /* how the glyph should be loaded */
- HB_Bool r2l;
-
- HB_UShort last; /* the last valid glyph -- used
- with cursive positioning */
- HB_Fixed anchor_x; /* the coordinates of the anchor point */
- HB_Fixed anchor_y; /* of the last valid glyph */
-};
-
-typedef struct GPOS_Instance_ GPOS_Instance;
-
-
-static HB_Error GPOS_Do_Glyph_Lookup( GPOS_Instance* gpi,
- HB_UShort lookup_index,
- HB_Buffer buffer,
- HB_UShort context_length,
- int nesting_level );
-
-
-
-#ifdef HB_SUPPORT_MULTIPLE_MASTER
-/* the client application must replace this with something more
- meaningful if multiple master fonts are to be supported. */
-
-static HB_Error default_mmfunc( HB_Font font,
- HB_UShort metric_id,
- HB_Fixed* metric_value,
- void* data )
-{
- HB_UNUSED(font);
- HB_UNUSED(metric_id);
- HB_UNUSED(metric_value);
- HB_UNUSED(data);
- return ERR(HB_Err_Not_Covered); /* ERR() call intended */
-}
-#endif
-
-
-
-HB_Error HB_Load_GPOS_Table( HB_Stream stream,
- HB_GPOSHeader** retptr,
- HB_GDEFHeader* gdef,
- HB_Stream gdefStream )
-{
- HB_UInt cur_offset, new_offset, base_offset;
-
- HB_GPOSHeader* gpos;
-
- HB_Error error = HB_Err_Ok;
-
-
- if ( !retptr )
- return ERR(HB_Err_Invalid_Argument);
-
- if ( GOTO_Table( TTAG_GPOS ) )
- return error;
-
- base_offset = FILE_Pos();
-
- if ( ALLOC ( gpos, sizeof( *gpos ) ) )
- return error;
-
-#ifdef HB_SUPPORT_MULTIPLE_MASTER
- gpos->mmfunc = default_mmfunc;
-#endif
-
- /* skip version */
-
- if ( FILE_Seek( base_offset + 4L ) ||
- ACCESS_Frame( 2L ) )
- goto Fail4;
-
- new_offset = GET_UShort() + base_offset;
-
- FORGET_Frame();
-
- cur_offset = FILE_Pos();
- if ( FILE_Seek( new_offset ) ||
- ( error = _HB_OPEN_Load_ScriptList( &gpos->ScriptList,
- stream ) ) != HB_Err_Ok )
- goto Fail4;
- (void)FILE_Seek( cur_offset );
-
- if ( ACCESS_Frame( 2L ) )
- goto Fail3;
-
- new_offset = GET_UShort() + base_offset;
-
- FORGET_Frame();
-
- cur_offset = FILE_Pos();
- if ( FILE_Seek( new_offset ) ||
- ( error = _HB_OPEN_Load_FeatureList( &gpos->FeatureList,
- stream ) ) != HB_Err_Ok )
- goto Fail3;
- (void)FILE_Seek( cur_offset );
-
- if ( ACCESS_Frame( 2L ) )
- goto Fail2;
-
- new_offset = GET_UShort() + base_offset;
-
- FORGET_Frame();
-
- cur_offset = FILE_Pos();
- if ( FILE_Seek( new_offset ) ||
- ( error = _HB_OPEN_Load_LookupList( &gpos->LookupList,
- stream, HB_Type_GPOS ) ) != HB_Err_Ok )
- goto Fail2;
-
- gpos->gdef = gdef; /* can be NULL */
-
- if ( ( error = _HB_GDEF_LoadMarkAttachClassDef_From_LookupFlags( gdef, gdefStream,
- gpos->LookupList.Lookup,
- gpos->LookupList.LookupCount ) ) )
- goto Fail1;
-
- *retptr = gpos;
-
- return HB_Err_Ok;
-
-Fail1:
- _HB_OPEN_Free_LookupList( &gpos->LookupList, HB_Type_GPOS );
-
-Fail2:
- _HB_OPEN_Free_FeatureList( &gpos->FeatureList );
-
-Fail3:
- _HB_OPEN_Free_ScriptList( &gpos->ScriptList );
-
-Fail4:
- FREE( gpos );
-
- return error;
-}
-
-
-HB_Error HB_Done_GPOS_Table( HB_GPOSHeader* gpos )
-{
- _HB_OPEN_Free_LookupList( &gpos->LookupList, HB_Type_GPOS );
- _HB_OPEN_Free_FeatureList( &gpos->FeatureList );
- _HB_OPEN_Free_ScriptList( &gpos->ScriptList );
-
- FREE( gpos );
-
- return HB_Err_Ok;
-}
-
-static HB_UInt Calculate_Class2RecordSize(HB_UShort format1, HB_UShort format2)
-{
- // Return number of 16 bit values in two value records with given formats
- return (format1 & 0x01) + (format2 & 0x01)
- + ((format1 & 0x02) >> 1) + ((format2 & 0x02) >> 1)
- + ((format1 & 0x04) >> 2) + ((format2 & 0x04) >> 2)
- + ((format1 & 0x08) >> 3) + ((format2 & 0x08) >> 3)
- + ((format1 & 0x10) >> 4) + ((format2 & 0x10) >> 4)
- + ((format1 & 0x20) >> 5) + ((format2 & 0x20) >> 5)
- + ((format1 & 0x40) >> 6) + ((format2 & 0x40) >> 6)
- + ((format1 & 0x80) >> 7) + ((format2 & 0x80) >> 7);
-}
-
-/*****************************
- * SubTable related functions
- *****************************/
-
-/* shared tables */
-
-/* ValueRecord */
-
-static HB_Error Get_FlexibleValueRecord( GPOS_Instance* gpi,
- HB_Short* vr,
- HB_UShort format,
- HB_Position gd )
-{
- HB_Error error = HB_Err_Ok;
-
- HB_16Dot16 x_scale, y_scale;
-
- if ( !format )
- return HB_Err_Ok;
-
- x_scale = gpi->font->x_scale;
- y_scale = gpi->font->y_scale;
-
- /* design units -> fractional pixel */
-
- if ( format & HB_GPOS_FORMAT_HAVE_X_PLACEMENT ) {
- gd->x_pos += *vr * x_scale / 0x10000;
- vr++;
- }
- if ( format & HB_GPOS_FORMAT_HAVE_Y_PLACEMENT ) {
- gd->y_pos += *vr * y_scale / 0x10000;
- vr++;
- }
- if ( format & HB_GPOS_FORMAT_HAVE_X_ADVANCE ) {
- gd->x_advance += *vr * x_scale / 0x10000;
- vr++;
- }
- if ( format & HB_GPOS_FORMAT_HAVE_Y_ADVANCE ) {
- gd->y_advance += *vr * y_scale / 0x10000;
- vr++;
- }
-
- return error;
-}
-
-/* There is a subtle difference in the specs between a `table' and a
- `record' -- offsets for device tables in ValueRecords are taken from
- the parent table and not the parent record. */
-
-static HB_Error Load_ValueRecord( HB_ValueRecord* vr,
- HB_UShort format,
- HB_UInt base_offset,
- HB_Stream stream )
-{
- HB_Error error;
-
- HB_UInt cur_offset, new_offset;
-
-
- if ( format & HB_GPOS_FORMAT_HAVE_X_PLACEMENT )
- {
- if ( ACCESS_Frame( 2L ) )
- return error;
-
- vr->XPlacement = GET_Short();
-
- FORGET_Frame();
- }
- else
- vr->XPlacement = 0;
-
- if ( format & HB_GPOS_FORMAT_HAVE_Y_PLACEMENT )
- {
- if ( ACCESS_Frame( 2L ) )
- return error;
-
- vr->YPlacement = GET_Short();
-
- FORGET_Frame();
- }
- else
- vr->YPlacement = 0;
-
- if ( format & HB_GPOS_FORMAT_HAVE_X_ADVANCE )
- {
- if ( ACCESS_Frame( 2L ) )
- return error;
-
- vr->XAdvance = GET_Short();
-
- FORGET_Frame();
- }
- else
- vr->XAdvance = 0;
-
- if ( format & HB_GPOS_FORMAT_HAVE_Y_ADVANCE )
- {
- if ( ACCESS_Frame( 2L ) )
- return error;
-
- vr->YAdvance = GET_Short();
-
- FORGET_Frame();
- }
- else
- vr->YAdvance = 0;
-
- if ( format & HB_GPOS_FORMAT_HAVE_DEVICE_TABLES )
- {
- if ( ALLOC_ARRAY( vr->DeviceTables, 4, HB_Device ) )
- return error;
- vr->DeviceTables[VR_X_ADVANCE_DEVICE] = 0;
- vr->DeviceTables[VR_Y_ADVANCE_DEVICE] = 0;
- vr->DeviceTables[VR_X_PLACEMENT_DEVICE] = 0;
- vr->DeviceTables[VR_Y_PLACEMENT_DEVICE] = 0;
- }
- else
- {
- vr->DeviceTables = 0;
- }
-
- if ( format & HB_GPOS_FORMAT_HAVE_X_PLACEMENT_DEVICE )
- {
- if ( ACCESS_Frame( 2L ) )
- goto Fail4;
-
- new_offset = GET_UShort();
-
- FORGET_Frame();
-
- if ( new_offset )
- {
- new_offset += base_offset;
-
- cur_offset = FILE_Pos();
- if ( FILE_Seek( new_offset ) ||
- ( error = _HB_OPEN_Load_Device( &vr->DeviceTables[VR_X_PLACEMENT_DEVICE],
- stream ) ) != HB_Err_Ok )
- goto Fail4;
- (void)FILE_Seek( cur_offset );
- }
- }
-
- if ( format & HB_GPOS_FORMAT_HAVE_Y_PLACEMENT_DEVICE )
- {
- if ( ACCESS_Frame( 2L ) )
- goto Fail3;
-
- new_offset = GET_UShort();
-
- FORGET_Frame();
-
- if ( new_offset )
- {
- new_offset += base_offset;
-
- cur_offset = FILE_Pos();
- if ( FILE_Seek( new_offset ) ||
- ( error = _HB_OPEN_Load_Device( &vr->DeviceTables[VR_Y_PLACEMENT_DEVICE],
- stream ) ) != HB_Err_Ok )
- goto Fail3;
- (void)FILE_Seek( cur_offset );
- }
- }
-
- if ( format & HB_GPOS_FORMAT_HAVE_X_ADVANCE_DEVICE )
- {
- if ( ACCESS_Frame( 2L ) )
- goto Fail2;
-
- new_offset = GET_UShort();
-
- FORGET_Frame();
-
- if ( new_offset )
- {
- new_offset += base_offset;
-
- cur_offset = FILE_Pos();
- if ( FILE_Seek( new_offset ) ||
- ( error = _HB_OPEN_Load_Device( &vr->DeviceTables[VR_X_ADVANCE_DEVICE],
- stream ) ) != HB_Err_Ok )
- goto Fail2;
- (void)FILE_Seek( cur_offset );
- }
- }
-
- if ( format & HB_GPOS_FORMAT_HAVE_Y_ADVANCE_DEVICE )
- {
- if ( ACCESS_Frame( 2L ) )
- goto Fail1;
-
- new_offset = GET_UShort();
-
- FORGET_Frame();
-
- if ( new_offset )
- {
- new_offset += base_offset;
-
- cur_offset = FILE_Pos();
- if ( FILE_Seek( new_offset ) ||
- ( error = _HB_OPEN_Load_Device( &vr->DeviceTables[VR_Y_ADVANCE_DEVICE],
- stream ) ) != HB_Err_Ok )
- goto Fail1;
- (void)FILE_Seek( cur_offset );
- }
- }
-
- if ( format & HB_GPOS_FORMAT_HAVE_X_ID_PLACEMENT )
- {
- if ( ACCESS_Frame( 2L ) )
- goto Fail1;
-
-#ifdef HB_SUPPORT_MULTIPLE_MASTER
- vr->XIdPlacement = GET_UShort();
-#else
- (void) GET_UShort();
-#endif
-
- FORGET_Frame();
- }
-#ifdef HB_SUPPORT_MULTIPLE_MASTER
- else
- vr->XIdPlacement = 0;
-#endif
-
- if ( format & HB_GPOS_FORMAT_HAVE_Y_ID_PLACEMENT )
- {
- if ( ACCESS_Frame( 2L ) )
- goto Fail1;
-
-#ifdef HB_SUPPORT_MULTIPLE_MASTER
- vr->YIdPlacement = GET_UShort();
-#else
- (void) GET_UShort();
-#endif
-
- FORGET_Frame();
- }
-#ifdef HB_SUPPORT_MULTIPLE_MASTER
- else
- vr->YIdPlacement = 0;
-#endif
-
- if ( format & HB_GPOS_FORMAT_HAVE_X_ID_ADVANCE )
- {
- if ( ACCESS_Frame( 2L ) )
- goto Fail1;
-
-#ifdef HB_SUPPORT_MULTIPLE_MASTER
- vr->XIdAdvance = GET_UShort();
-#else
- (void) GET_UShort();
-#endif
-
- FORGET_Frame();
- }
-#ifdef HB_SUPPORT_MULTIPLE_MASTER
- else
- vr->XIdAdvance = 0;
-#endif
-
- if ( format & HB_GPOS_FORMAT_HAVE_Y_ID_ADVANCE )
- {
- if ( ACCESS_Frame( 2L ) )
- goto Fail1;
-
-#ifdef HB_SUPPORT_MULTIPLE_MASTER
- vr->YIdAdvance = GET_UShort();
-#else
- (void) GET_UShort();
-#endif
-
- FORGET_Frame();
- }
-#ifdef HB_SUPPORT_MULTIPLE_MASTER
- else
- vr->YIdAdvance = 0;
-#endif
-
- return HB_Err_Ok;
-
-Fail1:
- if ( vr->DeviceTables )
- _HB_OPEN_Free_Device( vr->DeviceTables[VR_Y_ADVANCE_DEVICE] );
-
-Fail2:
- if ( vr->DeviceTables )
- _HB_OPEN_Free_Device( vr->DeviceTables[VR_X_ADVANCE_DEVICE] );
-
-Fail3:
- if ( vr->DeviceTables )
- _HB_OPEN_Free_Device( vr->DeviceTables[VR_Y_PLACEMENT_DEVICE] );
-
-Fail4:
- FREE( vr->DeviceTables );
- return error;
-}
-
-
-static void Free_ValueRecord( HB_ValueRecord* vr,
- HB_UShort format )
-{
- if ( format & HB_GPOS_FORMAT_HAVE_Y_ADVANCE_DEVICE )
- _HB_OPEN_Free_Device( vr->DeviceTables[VR_Y_ADVANCE_DEVICE] );
- if ( format & HB_GPOS_FORMAT_HAVE_X_ADVANCE_DEVICE )
- _HB_OPEN_Free_Device( vr->DeviceTables[VR_X_ADVANCE_DEVICE] );
- if ( format & HB_GPOS_FORMAT_HAVE_Y_PLACEMENT_DEVICE )
- _HB_OPEN_Free_Device( vr->DeviceTables[VR_Y_PLACEMENT_DEVICE] );
- if ( format & HB_GPOS_FORMAT_HAVE_X_PLACEMENT_DEVICE )
- _HB_OPEN_Free_Device( vr->DeviceTables[VR_X_PLACEMENT_DEVICE] );
- FREE( vr->DeviceTables );
-}
-
-
-static HB_Error Get_ValueRecord( GPOS_Instance* gpi,
- HB_ValueRecord* vr,
- HB_UShort format,
- HB_Position gd )
-{
- HB_Short pixel_value;
- HB_Error error = HB_Err_Ok;
-#ifdef HB_SUPPORT_MULTIPLE_MASTER
- HB_GPOSHeader* gpos = gpi->gpos;
- HB_Fixed value;
-#endif
-
- HB_UShort x_ppem, y_ppem;
- HB_16Dot16 x_scale, y_scale;
-
-
- if ( !format )
- return HB_Err_Ok;
-
- x_ppem = gpi->font->x_ppem;
- y_ppem = gpi->font->y_ppem;
- x_scale = gpi->font->x_scale;
- y_scale = gpi->font->y_scale;
-
- /* design units -> fractional pixel */
-
- if ( format & HB_GPOS_FORMAT_HAVE_X_PLACEMENT )
- gd->x_pos += x_scale * vr->XPlacement / 0x10000;
- if ( format & HB_GPOS_FORMAT_HAVE_Y_PLACEMENT )
- gd->y_pos += y_scale * vr->YPlacement / 0x10000;
- if ( format & HB_GPOS_FORMAT_HAVE_X_ADVANCE )
- gd->x_advance += x_scale * vr->XAdvance / 0x10000;
- if ( format & HB_GPOS_FORMAT_HAVE_Y_ADVANCE )
- gd->y_advance += y_scale * vr->YAdvance / 0x10000;
-
- if ( !gpi->dvi )
- {
- /* pixel -> fractional pixel */
-
- if ( format & HB_GPOS_FORMAT_HAVE_X_PLACEMENT_DEVICE )
- {
- _HB_OPEN_Get_Device( vr->DeviceTables[VR_X_PLACEMENT_DEVICE], x_ppem, &pixel_value );
- gd->x_pos += pixel_value << 6;
- }
- if ( format & HB_GPOS_FORMAT_HAVE_Y_PLACEMENT_DEVICE )
- {
- _HB_OPEN_Get_Device( vr->DeviceTables[VR_Y_PLACEMENT_DEVICE], y_ppem, &pixel_value );
- gd->y_pos += pixel_value << 6;
- }
- if ( format & HB_GPOS_FORMAT_HAVE_X_ADVANCE_DEVICE )
- {
- _HB_OPEN_Get_Device( vr->DeviceTables[VR_X_ADVANCE_DEVICE], x_ppem, &pixel_value );
- gd->x_advance += pixel_value << 6;
- }
- if ( format & HB_GPOS_FORMAT_HAVE_Y_ADVANCE_DEVICE )
- {
- _HB_OPEN_Get_Device( vr->DeviceTables[VR_Y_ADVANCE_DEVICE], y_ppem, &pixel_value );
- gd->y_advance += pixel_value << 6;
- }
- }
-
-#ifdef HB_SUPPORT_MULTIPLE_MASTER
- /* values returned from mmfunc() are already in fractional pixels */
-
- if ( format & HB_GPOS_FORMAT_HAVE_X_ID_PLACEMENT )
- {
- error = (gpos->mmfunc)( gpi->font, vr->XIdPlacement,
- &value, gpos->data );
- if ( error )
- return error;
- gd->x_pos += value;
- }
- if ( format & HB_GPOS_FORMAT_HAVE_Y_ID_PLACEMENT )
- {
- error = (gpos->mmfunc)( gpi->font, vr->YIdPlacement,
- &value, gpos->data );
- if ( error )
- return error;
- gd->y_pos += value;
- }
- if ( format & HB_GPOS_FORMAT_HAVE_X_ID_ADVANCE )
- {
- error = (gpos->mmfunc)( gpi->font, vr->XIdAdvance,
- &value, gpos->data );
- if ( error )
- return error;
- gd->x_advance += value;
- }
- if ( format & HB_GPOS_FORMAT_HAVE_Y_ID_ADVANCE )
- {
- error = (gpos->mmfunc)( gpi->font, vr->YIdAdvance,
- &value, gpos->data );
- if ( error )
- return error;
- gd->y_advance += value;
- }
-#endif
-
- return error;
-}
-
-
-/* AnchorFormat1 */
-/* AnchorFormat2 */
-/* AnchorFormat3 */
-/* AnchorFormat4 */
-
-static HB_Error Load_Anchor( HB_Anchor* an,
- HB_Stream stream )
-{
- HB_Error error;
-
- HB_UInt cur_offset, new_offset, base_offset;
-
-
- base_offset = FILE_Pos();
-
- if ( ACCESS_Frame( 2L ) )
- return error;
-
- an->PosFormat = GET_UShort();
-
- FORGET_Frame();
-
- switch ( an->PosFormat )
- {
- case 1:
- if ( ACCESS_Frame( 4L ) )
- return error;
-
- an->af.af1.XCoordinate = GET_Short();
- an->af.af1.YCoordinate = GET_Short();
-
- FORGET_Frame();
- break;
-
- case 2:
- if ( ACCESS_Frame( 6L ) )
- return error;
-
- an->af.af2.XCoordinate = GET_Short();
- an->af.af2.YCoordinate = GET_Short();
- an->af.af2.AnchorPoint = GET_UShort();
-
- FORGET_Frame();
- break;
-
- case 3:
- if ( ACCESS_Frame( 6L ) )
- return error;
-
- an->af.af3.XCoordinate = GET_Short();
- an->af.af3.YCoordinate = GET_Short();
-
- new_offset = GET_UShort();
-
- FORGET_Frame();
-
- if ( new_offset )
- {
- if ( ALLOC_ARRAY( an->af.af3.DeviceTables, 2, HB_Device ) )
- return error;
-
- an->af.af3.DeviceTables[AF3_X_DEVICE_TABLE] = 0;
- an->af.af3.DeviceTables[AF3_Y_DEVICE_TABLE] = 0;
-
- new_offset += base_offset;
-
- cur_offset = FILE_Pos();
- if ( FILE_Seek( new_offset ) ||
- ( error = _HB_OPEN_Load_Device( &an->af.af3.DeviceTables[AF3_X_DEVICE_TABLE],
- stream ) ) != HB_Err_Ok )
- goto Fail2;
- (void)FILE_Seek( cur_offset );
- }
-
- if ( ACCESS_Frame( 2L ) )
- goto Fail;
-
- new_offset = GET_UShort();
-
- FORGET_Frame();
-
- if ( new_offset )
- {
- if ( !an->af.af3.DeviceTables )
- {
- if ( ALLOC_ARRAY( an->af.af3.DeviceTables, 2, HB_Device ) )
- return error;
-
- an->af.af3.DeviceTables[AF3_X_DEVICE_TABLE] = 0;
- an->af.af3.DeviceTables[AF3_Y_DEVICE_TABLE] = 0;
- }
-
- new_offset += base_offset;
-
- cur_offset = FILE_Pos();
- if ( FILE_Seek( new_offset ) ||
- ( error = _HB_OPEN_Load_Device( &an->af.af3.DeviceTables[AF3_Y_DEVICE_TABLE],
- stream ) ) != HB_Err_Ok )
- goto Fail;
- (void)FILE_Seek( cur_offset );
- }
- break;
-
- case 4:
- if ( ACCESS_Frame( 4L ) )
- return error;
-
-#ifdef HB_SUPPORT_MULTIPLE_MASTER
- an->af.af4.XIdAnchor = GET_UShort();
- an->af.af4.YIdAnchor = GET_UShort();
-#else
- (void) GET_UShort();
- (void) GET_UShort();
-#endif
-
- FORGET_Frame();
- break;
-
- default:
- return ERR(HB_Err_Invalid_SubTable_Format);
- }
-
- return HB_Err_Ok;
-
-Fail:
- if ( an->af.af3.DeviceTables )
- _HB_OPEN_Free_Device( an->af.af3.DeviceTables[AF3_X_DEVICE_TABLE] );
-
-Fail2:
- FREE( an->af.af3.DeviceTables );
- return error;
-}
-
-
-static void Free_Anchor( HB_Anchor* an)
-{
- if ( an->PosFormat == 3 && an->af.af3.DeviceTables )
- {
- _HB_OPEN_Free_Device( an->af.af3.DeviceTables[AF3_X_DEVICE_TABLE] );
- _HB_OPEN_Free_Device( an->af.af3.DeviceTables[AF3_Y_DEVICE_TABLE] );
- FREE( an->af.af3.DeviceTables );
- }
-}
-
-
-static HB_Error Get_Anchor( GPOS_Instance* gpi,
- HB_Anchor* an,
- HB_UShort glyph_index,
- HB_Fixed* x_value,
- HB_Fixed* y_value )
-{
- HB_Error error = HB_Err_Ok;
-
-#ifdef HB_SUPPORT_MULTIPLE_MASTER
- HB_GPOSHeader* gpos = gpi->gpos;
-#endif
- HB_UShort ap;
-
- HB_Short pixel_value;
-
- HB_UShort x_ppem, y_ppem;
- HB_16Dot16 x_scale, y_scale;
-
-
- x_ppem = gpi->font->x_ppem;
- y_ppem = gpi->font->y_ppem;
- x_scale = gpi->font->x_scale;
- y_scale = gpi->font->y_scale;
-
- switch ( an->PosFormat )
- {
- case 0:
- /* The special case of an empty AnchorTable */
- default:
-
- return HB_Err_Not_Covered;
-
- case 1:
- *x_value = x_scale * an->af.af1.XCoordinate / 0x10000;
- *y_value = y_scale * an->af.af1.YCoordinate / 0x10000;
- break;
-
- case 2:
- if ( !gpi->dvi )
- {
- hb_uint32 n_points = 0;
- ap = an->af.af2.AnchorPoint;
- if (!gpi->font->klass->getPointInOutline)
- goto no_contour_point;
- error = gpi->font->klass->getPointInOutline(gpi->font, glyph_index, gpi->load_flags, ap, x_value, y_value, &n_points);
- if (error)
- return error;
- /* if n_points is set to zero, we use the design coordinate value pair.
- * This can happen e.g. for sbit glyphs. */
- if (!n_points)
- goto no_contour_point;
- }
- else
- {
- no_contour_point:
- *x_value = x_scale * an->af.af3.XCoordinate / 0x10000;
- *y_value = y_scale * an->af.af3.YCoordinate / 0x10000;
- }
- break;
-
- case 3:
- if ( !gpi->dvi )
- {
- _HB_OPEN_Get_Device( an->af.af3.DeviceTables[AF3_X_DEVICE_TABLE], x_ppem, &pixel_value );
- *x_value = pixel_value << 6;
- _HB_OPEN_Get_Device( an->af.af3.DeviceTables[AF3_Y_DEVICE_TABLE], y_ppem, &pixel_value );
- *y_value = pixel_value << 6;
- }
- else
- *x_value = *y_value = 0;
-
- *x_value += x_scale * an->af.af3.XCoordinate / 0x10000;
- *y_value += y_scale * an->af.af3.YCoordinate / 0x10000;
- break;
-
- case 4:
-#ifdef HB_SUPPORT_MULTIPLE_MASTER
- error = (gpos->mmfunc)( gpi->font, an->af.af4.XIdAnchor,
- x_value, gpos->data );
- if ( error )
- return error;
-
- error = (gpos->mmfunc)( gpi->font, an->af.af4.YIdAnchor,
- y_value, gpos->data );
- if ( error )
- return error;
- break;
-#else
- return ERR(HB_Err_Not_Covered);
-#endif
- }
-
- return error;
-}
-
-
-/* MarkArray */
-
-static HB_Error Load_MarkArray ( HB_MarkArray* ma,
- HB_Stream stream )
-{
- HB_Error error;
-
- HB_UShort n, m, count;
- HB_UInt cur_offset, new_offset, base_offset;
-
- HB_MarkRecord* mr;
-
-
- base_offset = FILE_Pos();
-
- if ( ACCESS_Frame( 2L ) )
- return error;
-
- count = ma->MarkCount = GET_UShort();
-
- FORGET_Frame();
-
- ma->MarkRecord = NULL;
-
- if ( ALLOC_ARRAY( ma->MarkRecord, count, HB_MarkRecord ) )
- return error;
-
- mr = ma->MarkRecord;
-
- for ( n = 0; n < count; n++ )
- {
- if ( ACCESS_Frame( 4L ) )
- goto Fail;
-
- mr[n].Class = GET_UShort();
- new_offset = GET_UShort() + base_offset;
-
- FORGET_Frame();
-
- cur_offset = FILE_Pos();
- if ( FILE_Seek( new_offset ) ||
- ( error = Load_Anchor( &mr[n].MarkAnchor, stream ) ) != HB_Err_Ok )
- goto Fail;
- (void)FILE_Seek( cur_offset );
- }
-
- return HB_Err_Ok;
-
-Fail:
- for ( m = 0; m < n; m++ )
- Free_Anchor( &mr[m].MarkAnchor );
-
- FREE( mr );
- return error;
-}
-
-
-static void Free_MarkArray( HB_MarkArray* ma )
-{
- HB_UShort n, count;
-
- HB_MarkRecord* mr;
-
-
- if ( ma->MarkRecord )
- {
- count = ma->MarkCount;
- mr = ma->MarkRecord;
-
- for ( n = 0; n < count; n++ )
- Free_Anchor( &mr[n].MarkAnchor );
-
- FREE( mr );
- }
-}
-
-
-/* LookupType 1 */
-
-/* SinglePosFormat1 */
-/* SinglePosFormat2 */
-
-static HB_Error Load_SinglePos( HB_GPOS_SubTable* st,
- HB_Stream stream )
-{
- HB_Error error;
- HB_SinglePos* sp = &st->single;
-
- HB_UShort n, m, count, format;
- HB_UInt cur_offset, new_offset, base_offset;
-
- HB_ValueRecord* vr;
-
-
- base_offset = FILE_Pos();
-
- if ( ACCESS_Frame( 6L ) )
- return error;
-
- sp->PosFormat = GET_UShort();
- new_offset = GET_UShort() + base_offset;
-
- format = sp->ValueFormat = GET_UShort();
-
- FORGET_Frame();
-
- if ( !format )
- return ERR(HB_Err_Invalid_SubTable);
-
- cur_offset = FILE_Pos();
- if ( FILE_Seek( new_offset ) ||
- ( error = _HB_OPEN_Load_Coverage( &sp->Coverage, stream ) ) != HB_Err_Ok )
- return error;
- (void)FILE_Seek( cur_offset );
-
- switch ( sp->PosFormat )
- {
- case 1:
- error = Load_ValueRecord( &sp->spf.spf1.Value, format,
- base_offset, stream );
- if ( error )
- goto Fail2;
- break;
-
- case 2:
- if ( ACCESS_Frame( 2L ) )
- goto Fail2;
-
- count = sp->spf.spf2.ValueCount = GET_UShort();
-
- FORGET_Frame();
-
- sp->spf.spf2.Value = NULL;
-
- if ( ALLOC_ARRAY( sp->spf.spf2.Value, count, HB_ValueRecord ) )
- goto Fail2;
-
- vr = sp->spf.spf2.Value;
-
- for ( n = 0; n < count; n++ )
- {
- error = Load_ValueRecord( &vr[n], format, base_offset, stream );
- if ( error )
- goto Fail1;
- }
- break;
-
- default:
- return ERR(HB_Err_Invalid_SubTable_Format);
- }
-
- return HB_Err_Ok;
-
-Fail1:
- for ( m = 0; m < n; m++ )
- Free_ValueRecord( &vr[m], format );
-
- FREE( vr );
-
-Fail2:
- _HB_OPEN_Free_Coverage( &sp->Coverage );
- return error;
-}
-
-
-static void Free_SinglePos( HB_GPOS_SubTable* st )
-{
- HB_UShort n, count, format;
- HB_SinglePos* sp = &st->single;
-
- HB_ValueRecord* v;
-
-
- format = sp->ValueFormat;
-
- switch ( sp->PosFormat )
- {
- case 1:
- Free_ValueRecord( &sp->spf.spf1.Value, format );
- break;
-
- case 2:
- if ( sp->spf.spf2.Value )
- {
- count = sp->spf.spf2.ValueCount;
- v = sp->spf.spf2.Value;
-
- for ( n = 0; n < count; n++ )
- Free_ValueRecord( &v[n], format );
-
- FREE( v );
- }
- break;
- default:
- break;
- }
-
- _HB_OPEN_Free_Coverage( &sp->Coverage );
-}
-
-static HB_Error Lookup_SinglePos( GPOS_Instance* gpi,
- HB_GPOS_SubTable* st,
- HB_Buffer buffer,
- HB_UShort flags,
- HB_UShort context_length,
- int nesting_level )
-{
- HB_UShort index, property;
- HB_Error error;
- HB_GPOSHeader* gpos = gpi->gpos;
- HB_SinglePos* sp = &st->single;
-
- HB_UNUSED(nesting_level);
-
- if ( context_length != 0xFFFF && context_length < 1 )
- return HB_Err_Not_Covered;
-
- if ( CHECK_Property( gpos->gdef, IN_CURITEM(), flags, &property ) )
- return error;
-
- error = _HB_OPEN_Coverage_Index( &sp->Coverage, IN_CURGLYPH(), &index );
- if ( error )
- return error;
-
- switch ( sp->PosFormat )
- {
- case 1:
- error = Get_ValueRecord( gpi, &sp->spf.spf1.Value,
- sp->ValueFormat, POSITION( buffer->in_pos ) );
- if ( error )
- return error;
- break;
-
- case 2:
- if ( index >= sp->spf.spf2.ValueCount )
- return ERR(HB_Err_Invalid_SubTable);
- error = Get_ValueRecord( gpi, &sp->spf.spf2.Value[index],
- sp->ValueFormat, POSITION( buffer->in_pos ) );
- if ( error )
- return error;
- break;
-
- default:
- return ERR(HB_Err_Invalid_SubTable);
- }
-
- (buffer->in_pos)++;
-
- return HB_Err_Ok;
-}
-
-/* LookupType 2 */
-
-/* PairSet */
-
-static HB_Error Load_PairSet ( HB_PairSet* ps,
- HB_UShort format1,
- HB_UShort format2,
- HB_Stream stream )
-{
- HB_Error error;
-
- HB_UShort n, m, count;
-
-#ifdef HB_USE_FLEXIBLE_VALUE_RECORD
- HB_UInt record_size = 0;
- HB_Short *vr;
-#else
- HB_UInt base_offset;
- HB_PairValueRecord* pvr;
-
- base_offset = FILE_Pos();
-#endif
-
- if ( ACCESS_Frame( 2L ) )
- return error;
-
- count = ps->PairValueCount = GET_UShort();
-
- FORGET_Frame();
-
-#ifndef HB_USE_FLEXIBLE_VALUE_RECORD
- ps->PairValueRecord = NULL;
-
- if ( ALLOC_ARRAY( ps->PairValueRecord, count, HB_PairValueRecord ) )
- return error;
-
- pvr = ps->PairValueRecord;
-
- for ( n = 0; n < count; n++ )
- {
- if ( ACCESS_Frame( 2L ) )
- goto Fail;
-
- pvr[n].SecondGlyph = GET_UShort();
-
- FORGET_Frame();
-
- if ( format1 )
- {
- error = Load_ValueRecord( &pvr[n].Value1, format1,
- base_offset, stream );
- if ( error )
- goto Fail;
- }
- if ( format2 )
- {
- error = Load_ValueRecord( &pvr[n].Value2, format2,
- base_offset, stream );
- if ( error )
- {
- if ( format1 )
- Free_ValueRecord( &pvr[n].Value1, format1 );
- goto Fail;
- }
- }
- }
-#else
- ps->ValueRecords = 0;
-
- // Add one for the SecondGlyph part of each record
- record_size = Calculate_Class2RecordSize( format1, format2 ) + 1;
-
- if ( ALLOC_ARRAY( ps->ValueRecords, record_size * count, HB_Short ) )
- return error;
-
- vr = ps->ValueRecords;
-
- for ( n = 0; n < count; n++ )
- {
- for ( m = 0; m < record_size; m++ ) {
- if ( ACCESS_Frame( 2L ) )
- goto Fail;
-
- *(vr++) = GET_Short();
-
- FORGET_Frame();
- }
- }
-#endif
-
-
- return HB_Err_Ok;
-
-Fail:
-#ifndef HB_USE_FLEXIBLE_VALUE_RECORD
- for ( m = 0; m < n; m++ )
- {
- if ( format1 )
- Free_ValueRecord( &pvr[m].Value1, format1 );
- if ( format2 )
- Free_ValueRecord( &pvr[m].Value2, format2 );
- }
-
- FREE( pvr );
-#else
- FREE ( ps->ValueRecords );
-#endif
-
- return error;
-}
-
-
-static void Free_PairSet( HB_PairSet* ps,
- HB_UShort format1,
- HB_UShort format2)
-{
-#ifndef HB_USE_FLEXIBLE_VALUE_RECORD
- HB_UShort n, count;
-
- HB_PairValueRecord* pvr;
-
- if ( ps->PairValueRecord )
- {
- count = ps->PairValueCount;
- pvr = ps->PairValueRecord;
-
- for ( n = 0; n < count; n++ )
- {
- if ( format1 )
- Free_ValueRecord( &pvr[n].Value1, format1 );
- if ( format2 )
- Free_ValueRecord( &pvr[n].Value2, format2 );
- }
-
- FREE( pvr );
- }
-#else
- (void)format1; // unused
- (void)format2; // unused
-
- if ( ps->ValueRecords )
- {
- FREE( ps->ValueRecords );
- }
-#endif
-}
-
-
-/* PairPosFormat1 */
-
-static HB_Error Load_PairPos1( HB_PairPosFormat1* ppf1,
- HB_UShort format1,
- HB_UShort format2,
- HB_Stream stream )
-{
- HB_Error error;
-
- HB_UShort n, m, count;
- HB_UInt cur_offset, new_offset, base_offset;
-
- HB_PairSet* ps;
-
-
- base_offset = FILE_Pos() - 8L;
-
- if ( ACCESS_Frame( 2L ) )
- return error;
-
- count = ppf1->PairSetCount = GET_UShort();
-
- FORGET_Frame();
-
- ppf1->PairSet = NULL;
-
- if ( ALLOC_ARRAY( ppf1->PairSet, count, HB_PairSet ) )
- return error;
-
- ps = ppf1->PairSet;
-
- for ( n = 0; n < count; n++ )
- {
- if ( ACCESS_Frame( 2L ) )
- goto Fail;
-
- new_offset = GET_UShort() + base_offset;
-
- FORGET_Frame();
-
- cur_offset = FILE_Pos();
- if ( FILE_Seek( new_offset ) ||
- ( error = Load_PairSet( &ps[n], format1,
- format2, stream ) ) != HB_Err_Ok )
- goto Fail;
- (void)FILE_Seek( cur_offset );
- }
-
- return HB_Err_Ok;
-
-Fail:
- for ( m = 0; m < n; m++ )
- Free_PairSet( &ps[m], format1, format2 );
-
- FREE( ps );
- return error;
-}
-
-
-static void Free_PairPos1( HB_PairPosFormat1* ppf1,
- HB_UShort format1,
- HB_UShort format2 )
-{
- HB_UShort n, count;
-
- HB_PairSet* ps;
-
-
- if ( ppf1->PairSet )
- {
- count = ppf1->PairSetCount;
- ps = ppf1->PairSet;
-
- for ( n = 0; n < count; n++ )
- Free_PairSet( &ps[n], format1, format2 );
-
- FREE( ps );
- }
-}
-
-
-/* PairPosFormat2 */
-
-static HB_Error Load_PairPos2( HB_PairPosFormat2* ppf2,
- HB_UShort format1,
- HB_UShort format2,
- HB_Stream stream )
-{
- HB_Error error;
-
- HB_UShort m, n, k, count1, count2;
- HB_UInt cur_offset, new_offset1, new_offset2, base_offset, cls2_record_size = 0;
-
- HB_Class1Record* c1r;
- HB_Class2Record* c2r;
-
- HB_Short* vr;
-
- hb_uint8 use_flexible_value_records;
-
- base_offset = FILE_Pos() - 8L;
-
- if ( ACCESS_Frame( 8L ) )
- return error;
-
- new_offset1 = GET_UShort() + base_offset;
- new_offset2 = GET_UShort() + base_offset;
-
- /* `Class1Count' and `Class2Count' are the upper limits for class
- values, thus we read it now to make additional safety checks. */
-
- count1 = ppf2->Class1Count = GET_UShort();
- count2 = ppf2->Class2Count = GET_UShort();
-
-#ifndef HB_USE_FLEXIBLE_VALUE_RECORD
- use_flexible_value_records = 0;
-#else
- use_flexible_value_records = !((format1 & HB_GPOS_FORMAT_HAVE_DEVICE_TABLES) ||
- (format2 & HB_GPOS_FORMAT_HAVE_DEVICE_TABLES));
-#endif
-
- FORGET_Frame();
-
- cur_offset = FILE_Pos();
- if ( FILE_Seek( new_offset1 ) ||
- ( error = _HB_OPEN_Load_ClassDefinition( &ppf2->ClassDef1, count1,
- stream ) ) != HB_Err_Ok )
- return error;
- if ( FILE_Seek( new_offset2 ) ||
- ( error = _HB_OPEN_Load_ClassDefinition( &ppf2->ClassDef2, count2,
- stream ) ) != HB_Err_Ok )
- goto Fail3;
- (void)FILE_Seek( cur_offset );
-
- ppf2->Class1Record = NULL;
-
- if ( ALLOC_ARRAY( ppf2->Class1Record, count1, HB_Class1Record ) )
- goto Fail2;
-
- c1r = ppf2->Class1Record;
-
- if ( use_flexible_value_records )
- cls2_record_size = Calculate_Class2RecordSize(format1, format2);
-
- for ( m = 0; m < count1; m++ )
- {
- c1r[m].IsFlexible = use_flexible_value_records;
- if ( use_flexible_value_records ) {
- c1r[m].c2r.ValueRecords = NULL;
-
- if ( ALLOC_ARRAY( c1r[m].c2r.ValueRecords, count2 * cls2_record_size, HB_UShort ) )
- goto Fail1;
-
- vr = c1r[m].c2r.ValueRecords;
-
- if ( ACCESS_Frame( count2 * cls2_record_size * 2L ))
- goto Fail1;
-
- for ( n = 0; n < count2 * cls2_record_size; n++ )
- vr[n] = GET_Short();
-
- FORGET_Frame();
- } else {
- c1r[m].c2r.Class2Record = NULL;
-
- if ( ALLOC_ARRAY( c1r[m].c2r.Class2Record, count2, HB_Class2Record ) )
- goto Fail1;
-
- c2r = c1r[m].c2r.Class2Record;
- for ( n = 0; n < count2; n++ )
- {
- if ( format1 )
- {
- error = Load_ValueRecord( &c2r[n].Value1, format1,
- base_offset, stream );
- if ( error )
- goto Fail0;
- }
- if ( format2 )
- {
- error = Load_ValueRecord( &c2r[n].Value2, format2,
- base_offset, stream );
- if ( error )
- {
- if ( format1 )
- Free_ValueRecord( &c2r[n].Value1, format1 );
- goto Fail0;
- }
- }
- }
- }
-
- continue;
-
- Fail0:
- for ( k = 0; k < n; k++ )
- {
- if ( format1 )
- Free_ValueRecord( &c2r[k].Value1, format1 );
- if ( format2 )
- Free_ValueRecord( &c2r[k].Value2, format2 );
- }
- goto Fail1;
- }
-
- return HB_Err_Ok;
-
-Fail1:
- for ( k = 0; k < m; k++ )
- {
- if ( !use_flexible_value_records ) {
- c2r = c1r[k].c2r.Class2Record;
-
- for ( n = 0; n < count2; n++ )
- {
- if ( format1 )
- Free_ValueRecord( &c2r[n].Value1, format1 );
- if ( format2 )
- Free_ValueRecord( &c2r[n].Value2, format2 );
- }
-
- FREE( c2r );
- } else {
- FREE( c1r[k].c2r.ValueRecords );
- }
- }
-
- FREE( c1r );
-Fail2:
-
- _HB_OPEN_Free_ClassDefinition( &ppf2->ClassDef2 );
-
-Fail3:
- _HB_OPEN_Free_ClassDefinition( &ppf2->ClassDef1 );
- return error;
-}
-
-
-static void Free_PairPos2( HB_PairPosFormat2* ppf2,
- HB_UShort format1,
- HB_UShort format2)
-{
- HB_UShort m, n, count1, count2;
-
- HB_Class1Record* c1r;
- HB_Class2Record* c2r;
-
-
- if ( ppf2->Class1Record )
- {
- c1r = ppf2->Class1Record;
- count1 = ppf2->Class1Count;
- count2 = ppf2->Class2Count;
-
- for ( m = 0; m < count1; m++ )
- {
- if ( !c1r[m].IsFlexible ) {
- c2r = c1r[m].c2r.Class2Record;
-
- for ( n = 0; n < count2; n++ )
- {
- if ( format1 )
- Free_ValueRecord( &c2r[n].Value1, format1 );
- if ( format2 )
- Free_ValueRecord( &c2r[n].Value2, format2 );
- }
-
- FREE( c2r );
- } else {
- FREE( c1r[m].c2r.ValueRecords );
- }
- }
-
- FREE( c1r );
-
- _HB_OPEN_Free_ClassDefinition( &ppf2->ClassDef2 );
- _HB_OPEN_Free_ClassDefinition( &ppf2->ClassDef1 );
- }
-}
-
-
-static HB_Error Load_PairPos( HB_GPOS_SubTable* st,
- HB_Stream stream )
-{
- HB_Error error;
- HB_PairPos* pp = &st->pair;
-
- HB_UShort format1, format2;
- HB_UInt cur_offset, new_offset, base_offset;
-
-
- base_offset = FILE_Pos();
-
- if ( ACCESS_Frame( 8L ) )
- return error;
-
- pp->PosFormat = GET_UShort();
- new_offset = GET_UShort() + base_offset;
-
- format1 = pp->ValueFormat1 = GET_UShort();
- format2 = pp->ValueFormat2 = GET_UShort();
-
- FORGET_Frame();
-
- cur_offset = FILE_Pos();
- if ( FILE_Seek( new_offset ) ||
- ( error = _HB_OPEN_Load_Coverage( &pp->Coverage, stream ) ) != HB_Err_Ok )
- return error;
- (void)FILE_Seek( cur_offset );
-
- switch ( pp->PosFormat )
- {
- case 1:
- error = Load_PairPos1( &pp->ppf.ppf1, format1, format2, stream );
- if ( error )
- goto Fail;
- break;
-
- case 2:
- error = Load_PairPos2( &pp->ppf.ppf2, format1, format2, stream );
- if ( error )
- goto Fail;
- break;
-
- default:
- return ERR(HB_Err_Invalid_SubTable_Format);
- }
-
- return HB_Err_Ok;
-
-Fail:
- _HB_OPEN_Free_Coverage( &pp->Coverage );
- return error;
-}
-
-
-static void Free_PairPos( HB_GPOS_SubTable* st )
-{
- HB_UShort format1, format2;
- HB_PairPos* pp = &st->pair;
-
-
- format1 = pp->ValueFormat1;
- format2 = pp->ValueFormat2;
-
- switch ( pp->PosFormat )
- {
- case 1:
- Free_PairPos1( &pp->ppf.ppf1, format1, format2 );
- break;
-
- case 2:
- Free_PairPos2( &pp->ppf.ppf2, format1, format2 );
- break;
-
- default:
- break;
- }
-
- _HB_OPEN_Free_Coverage( &pp->Coverage );
-}
-
-static HB_Error Lookup_PairPos1( GPOS_Instance* gpi,
- HB_PairPosFormat1* ppf1,
- HB_Buffer buffer,
- HB_UInt first_pos,
- HB_UShort index,
- HB_UShort format1,
- HB_UShort format2 )
-{
- HB_Error error;
- HB_UShort numpvr, glyph2;
-
-#ifndef HB_USE_FLEXIBLE_VALUE_RECORD
- HB_PairValueRecord* pvr;
-#else
- HB_Short *vr;
- HB_UShort second_glyph;
- HB_UInt record_size1, record_size2;
-#endif
-
- if ( index >= ppf1->PairSetCount )
- return ERR(HB_Err_Invalid_SubTable);
-
- if (!ppf1->PairSet[index].PairValueCount)
- return HB_Err_Not_Covered;
-
- glyph2 = IN_CURGLYPH();
-
-#ifndef HB_USE_FLEXIBLE_VALUE_RECORD
- pvr = ppf1->PairSet[index].PairValueRecord;
- if ( !pvr )
- return ERR(HB_Err_Invalid_SubTable);
-
- for ( numpvr = ppf1->PairSet[index].PairValueCount;
- numpvr;
- numpvr--, pvr++ )
- {
- if ( glyph2 == pvr->SecondGlyph )
- {
- error = Get_ValueRecord( gpi, &pvr->Value1, format1,
- POSITION( first_pos ) );
- if ( error )
- return error;
- return Get_ValueRecord( gpi, &pvr->Value2, format2,
- POSITION( buffer->in_pos ) );
- }
- }
-#else
- vr = ppf1->PairSet[index].ValueRecords;
- if ( !vr )
- return ERR(HB_Err_Invalid_SubTable);
-
- record_size1 = Calculate_Class2RecordSize( format1, 0 );
- record_size2 = Calculate_Class2RecordSize( format2, 0 );
-
- for ( numpvr = ppf1->PairSet[index].PairValueCount; numpvr; numpvr-- )
- {
- second_glyph = *((HB_UShort *)vr);
- vr++;
- if ( glyph2 == second_glyph )
- {
- error = Get_FlexibleValueRecord( gpi, vr, format1, POSITION( first_pos ) );
- if ( error )
- return error;
- vr += record_size1;
-
- return Get_FlexibleValueRecord( gpi, vr, format2, POSITION( buffer->in_pos ) );
- }
- else
- {
- vr += record_size1 + record_size2;
- }
- }
-#endif
-
- return HB_Err_Not_Covered;
-}
-
-
-static HB_Error Lookup_PairPos2( GPOS_Instance* gpi,
- HB_PairPosFormat2* ppf2,
- HB_Buffer buffer,
- HB_UInt first_pos,
- HB_UShort format1,
- HB_UShort format2 )
-{
- HB_Error error;
- HB_UShort cl1 = 0, cl2 = 0; /* shut compiler up */
-
- HB_Class1Record* c1r;
- HB_Class2Record* c2r;
- HB_Short* vr;
-
- HB_UShort vr1_size;
- HB_UShort vr2_size;
-
-
- error = _HB_OPEN_Get_Class( &ppf2->ClassDef1, IN_GLYPH( first_pos ),
- &cl1, NULL );
- if ( error && error != HB_Err_Not_Covered )
- return error;
- error = _HB_OPEN_Get_Class( &ppf2->ClassDef2, IN_CURGLYPH(),
- &cl2, NULL );
- if ( error && error != HB_Err_Not_Covered )
- return error;
-
- c1r = &ppf2->Class1Record[cl1];
- if ( !c1r )
- return ERR(HB_Err_Invalid_SubTable);
-
- if ( !c1r->IsFlexible ) {
- c2r = &c1r->c2r.Class2Record[cl2];
-
- error = Get_ValueRecord( gpi, &c2r->Value1, format1, POSITION( first_pos ) );
- if ( error )
- return error;
- return Get_ValueRecord( gpi, &c2r->Value2, format2, POSITION( buffer->in_pos ) );
- } else {
- vr1_size = Calculate_Class2RecordSize( format1, 0 );
- vr2_size = Calculate_Class2RecordSize( format2, 0 );
-
- vr = c1r->c2r.ValueRecords + (cl2 * ( vr1_size + vr2_size ));
-
- error = Get_FlexibleValueRecord( gpi, vr, format1, POSITION( first_pos ) );
- if ( error )
- return error;
- vr += vr1_size; // Skip to second record
- return Get_FlexibleValueRecord( gpi, vr, format2, POSITION( buffer->in_pos ) );
- }
-}
-
-static HB_Error Lookup_PairPos( GPOS_Instance* gpi,
- HB_GPOS_SubTable* st,
- HB_Buffer buffer,
- HB_UShort flags,
- HB_UShort context_length,
- int nesting_level )
-{
- HB_Error error;
- HB_UShort index, property;
- HB_UInt first_pos;
- HB_GPOSHeader* gpos = gpi->gpos;
- HB_PairPos* pp = &st->pair;
-
- HB_UNUSED(nesting_level);
-
- if ( buffer->in_pos >= buffer->in_length - 1 )
- return HB_Err_Not_Covered; /* Not enough glyphs in stream */
-
- if ( context_length != 0xFFFF && context_length < 2 )
- return HB_Err_Not_Covered;
-
- if ( CHECK_Property( gpos->gdef, IN_CURITEM(), flags, &property ) )
- return error;
-
- error = _HB_OPEN_Coverage_Index( &pp->Coverage, IN_CURGLYPH(), &index );
- if ( error )
- return error;
-
- /* second glyph */
-
- first_pos = buffer->in_pos;
- (buffer->in_pos)++;
-
- while ( CHECK_Property( gpos->gdef, IN_CURITEM(),
- flags, &property ) )
- {
- if ( error && error != HB_Err_Not_Covered )
- return error;
-
- if ( buffer->in_pos == buffer->in_length )
- {
- buffer->in_pos = first_pos;
- return HB_Err_Not_Covered;
- }
- (buffer->in_pos)++;
-
- }
-
- switch ( pp->PosFormat )
- {
- case 1:
- error = Lookup_PairPos1( gpi, &pp->ppf.ppf1, buffer,
- first_pos, index,
- pp->ValueFormat1, pp->ValueFormat2 );
- break;
-
- case 2:
- error = Lookup_PairPos2( gpi, &pp->ppf.ppf2, buffer, first_pos,
- pp->ValueFormat1, pp->ValueFormat2 );
- break;
-
- default:
- return ERR(HB_Err_Invalid_SubTable_Format);
- }
-
- /* if we don't have coverage for the second glyph don't skip it for
- further lookups but reset in_pos back to the first_glyph and let
- the caller in Do_String_Lookup increment in_pos */
- if ( error == HB_Err_Not_Covered )
- buffer->in_pos = first_pos;
-
- /* adjusting the `next' glyph */
-
- if ( pp->ValueFormat2 )
- (buffer->in_pos)++;
-
- return error;
-}
-
-
-/* LookupType 3 */
-
-/* CursivePosFormat1 */
-
-static HB_Error Load_CursivePos( HB_GPOS_SubTable* st,
- HB_Stream stream )
-{
- HB_Error error;
- HB_CursivePos* cp = &st->cursive;
-
- HB_UShort n, m, count;
- HB_UInt cur_offset, new_offset, base_offset;
-
- HB_EntryExitRecord* eer;
-
-
- base_offset = FILE_Pos();
-
- if ( ACCESS_Frame( 4L ) )
- return error;
-
- cp->PosFormat = GET_UShort();
- new_offset = GET_UShort() + base_offset;
-
- FORGET_Frame();
-
- cur_offset = FILE_Pos();
- if ( FILE_Seek( new_offset ) ||
- ( error = _HB_OPEN_Load_Coverage( &cp->Coverage, stream ) ) != HB_Err_Ok )
- return error;
- (void)FILE_Seek( cur_offset );
-
- if ( ACCESS_Frame( 2L ) )
- goto Fail2;
-
- count = cp->EntryExitCount = GET_UShort();
-
- FORGET_Frame();
-
- cp->EntryExitRecord = NULL;
-
- if ( ALLOC_ARRAY( cp->EntryExitRecord, count, HB_EntryExitRecord ) )
- goto Fail2;
-
- eer = cp->EntryExitRecord;
-
- for ( n = 0; n < count; n++ )
- {
- HB_UInt entry_offset;
-
- if ( ACCESS_Frame( 2L ) )
- return error;
-
- entry_offset = new_offset = GET_UShort();
-
- FORGET_Frame();
-
- if ( new_offset )
- {
- new_offset += base_offset;
-
- cur_offset = FILE_Pos();
- if ( FILE_Seek( new_offset ) ||
- ( error = Load_Anchor( &eer[n].EntryAnchor,
- stream ) ) != HB_Err_Ok )
- goto Fail1;
- (void)FILE_Seek( cur_offset );
- }
- else
- eer[n].EntryAnchor.PosFormat = 0;
-
- if ( ACCESS_Frame( 2L ) )
- return error;
-
- new_offset = GET_UShort();
-
- FORGET_Frame();
-
- if ( new_offset )
- {
- new_offset += base_offset;
-
- cur_offset = FILE_Pos();
- if ( FILE_Seek( new_offset ) ||
- ( error = Load_Anchor( &eer[n].ExitAnchor,
- stream ) ) != HB_Err_Ok )
- {
- if ( entry_offset )
- Free_Anchor( &eer[n].EntryAnchor );
- goto Fail1;
- }
- (void)FILE_Seek( cur_offset );
- }
- else
- eer[n].ExitAnchor.PosFormat = 0;
- }
-
- return HB_Err_Ok;
-
-Fail1:
- for ( m = 0; m < n; m++ )
- {
- Free_Anchor( &eer[m].EntryAnchor );
- Free_Anchor( &eer[m].ExitAnchor );
- }
-
- FREE( eer );
-
-Fail2:
- _HB_OPEN_Free_Coverage( &cp->Coverage );
- return error;
-}
-
-
-static void Free_CursivePos( HB_GPOS_SubTable* st )
-{
- HB_UShort n, count;
- HB_CursivePos* cp = &st->cursive;
-
- HB_EntryExitRecord* eer;
-
-
- if ( cp->EntryExitRecord )
- {
- count = cp->EntryExitCount;
- eer = cp->EntryExitRecord;
-
- for ( n = 0; n < count; n++ )
- {
- Free_Anchor( &eer[n].EntryAnchor );
- Free_Anchor( &eer[n].ExitAnchor );
- }
-
- FREE( eer );
- }
-
- _HB_OPEN_Free_Coverage( &cp->Coverage );
-}
-
-
-static HB_Error Lookup_CursivePos( GPOS_Instance* gpi,
- HB_GPOS_SubTable* st,
- HB_Buffer buffer,
- HB_UShort flags,
- HB_UShort context_length,
- int nesting_level )
-{
- HB_UShort index, property;
- HB_Error error;
- HB_GPOSHeader* gpos = gpi->gpos;
- HB_CursivePos* cp = &st->cursive;
-
- HB_EntryExitRecord* eer;
- HB_Fixed entry_x, entry_y;
- HB_Fixed exit_x, exit_y;
-
- HB_UNUSED(nesting_level);
-
- if ( context_length != 0xFFFF && context_length < 1 )
- {
- gpi->last = 0xFFFF;
- return HB_Err_Not_Covered;
- }
-
- /* Glyphs not having the right GDEF properties will be ignored, i.e.,
- gpi->last won't be reset (contrary to user defined properties). */
-
- if ( CHECK_Property( gpos->gdef, IN_CURITEM(), flags, &property ) )
- return error;
-
- /* We don't handle mark glyphs here. According to Andrei, this isn't
- possible, but who knows... */
-
- if ( property == HB_GDEF_MARK )
- {
- gpi->last = 0xFFFF;
- return HB_Err_Not_Covered;
- }
-
- error = _HB_OPEN_Coverage_Index( &cp->Coverage, IN_CURGLYPH(), &index );
- if ( error )
- {
- gpi->last = 0xFFFF;
- return error;
- }
-
- if ( index >= cp->EntryExitCount )
- return ERR(HB_Err_Invalid_SubTable);
-
- eer = &cp->EntryExitRecord[index];
-
- /* Now comes the messiest part of the whole OpenType
- specification. At first glance, cursive connections seem easy
- to understand, but there are pitfalls! The reason is that
- the specs don't mention how to compute the advance values
- resp. glyph offsets. I was told it would be an omission, to
- be fixed in the next OpenType version... Again many thanks to
- Andrei Burago <andreib@microsoft.com> for clarifications.
-
- Consider the following example:
-
- | xadv1 |
- +---------+
- | |
- +-----+--+ 1 |
- | | .| |
- | 0+--+------+
- | 2 |
- | |
- 0+--------+
- | xadv2 |
-
- glyph1: advance width = 12
- anchor point = (3,1)
-
- glyph2: advance width = 11
- anchor point = (9,4)
-
- LSB is 1 for both glyphs (so the boxes drawn above are glyph
- bboxes). Writing direction is R2L; `0' denotes the glyph's
- coordinate origin.
-
- Now the surprising part: The advance width of the *left* glyph
- (resp. of the *bottom* glyph) will be modified, no matter
- whether the writing direction is L2R or R2L (resp. T2B or
- B2T)! This assymetry is caused by the fact that the glyph's
- coordinate origin is always the lower left corner for all
- writing directions.
-
- Continuing the above example, we can compute the new
- (horizontal) advance width of glyph2 as
-
- 9 - 3 = 6 ,
-
- and the new vertical offset of glyph2 as
-
- 1 - 4 = -3 .
-
-
- Vertical writing direction is far more complicated:
-
- a) Assuming that we recompute the advance height of the lower glyph:
-
- --
- +---------+
- -- | |
- +-----+--+ 1 | yadv1
- | | .| |
- yadv2 | 0+--+------+ -- BSB1 --
- | 2 | -- -- y_offset
- | |
- BSB2 -- 0+--------+ --
- -- --
-
- glyph1: advance height = 6
- anchor point = (3,1)
-
- glyph2: advance height = 7
- anchor point = (9,4)
-
- TSB is 1 for both glyphs; writing direction is T2B.
-
-
- BSB1 = yadv1 - (TSB1 + ymax1)
- BSB2 = yadv2 - (TSB2 + ymax2)
- y_offset = y2 - y1
-
- vertical advance width of glyph2
- = y_offset + BSB2 - BSB1
- = (y2 - y1) + (yadv2 - (TSB2 + ymax2)) - (yadv1 - (TSB1 + ymax1))
- = y2 - y1 + yadv2 - TSB2 - ymax2 - (yadv1 - TSB1 - ymax1)
- = y2 - y1 + yadv2 - TSB2 - ymax2 - yadv1 + TSB1 + ymax1
-
-
- b) Assuming that we recompute the advance height of the upper glyph:
-
- -- --
- +---------+ -- TSB1
- -- -- | |
- TSB2 -- +-----+--+ 1 | yadv1 ymax1
- | | .| |
- yadv2 | 0+--+------+ -- --
- ymax2 | 2 | -- y_offset
- | |
- -- 0+--------+ --
- --
-
- glyph1: advance height = 6
- anchor point = (3,1)
-
- glyph2: advance height = 7
- anchor point = (9,4)
-
- TSB is 1 for both glyphs; writing direction is T2B.
-
- y_offset = y2 - y1
-
- vertical advance width of glyph2
- = TSB1 + ymax1 + y_offset - (TSB2 + ymax2)
- = TSB1 + ymax1 + y2 - y1 - TSB2 - ymax2
-
-
- Comparing a) with b) shows that b) is easier to compute. I'll wait
- for a reply from Andrei to see what should really be implemented...
-
- Since horizontal advance widths or vertical advance heights
- can be used alone but not together, no ambiguity occurs. */
-
- if ( gpi->last == 0xFFFF )
- goto end;
-
- /* Get_Anchor() returns HB_Err_Not_Covered if there is no anchor
- table. */
-
- error = Get_Anchor( gpi, &eer->EntryAnchor, IN_CURGLYPH(),
- &entry_x, &entry_y );
- if ( error == HB_Err_Not_Covered )
- goto end;
- if ( error )
- return error;
-
- if ( gpi->r2l )
- {
- POSITION( buffer->in_pos )->x_advance = entry_x - gpi->anchor_x;
- POSITION( buffer->in_pos )->new_advance = TRUE;
- }
- else
- {
- POSITION( gpi->last )->x_advance = gpi->anchor_x - entry_x;
- POSITION( gpi->last )->new_advance = TRUE;
- }
-
- if ( flags & HB_LOOKUP_FLAG_RIGHT_TO_LEFT )
- {
- POSITION( gpi->last )->cursive_chain = gpi->last - buffer->in_pos;
- POSITION( gpi->last )->y_pos = entry_y - gpi->anchor_y;
- }
- else
- {
- POSITION( buffer->in_pos )->cursive_chain = buffer->in_pos - gpi->last;
- POSITION( buffer->in_pos )->y_pos = gpi->anchor_y - entry_y;
- }
-
-end:
- error = Get_Anchor( gpi, &eer->ExitAnchor, IN_CURGLYPH(),
- &exit_x, &exit_y );
- if ( error == HB_Err_Not_Covered )
- gpi->last = 0xFFFF;
- else
- {
- gpi->last = buffer->in_pos;
- gpi->anchor_x = exit_x;
- gpi->anchor_y = exit_y;
- }
- if ( error )
- return error;
-
- (buffer->in_pos)++;
-
- return HB_Err_Ok;
-}
-
-
-/* LookupType 4 */
-
-/* BaseArray */
-
-static HB_Error Load_BaseArray( HB_BaseArray* ba,
- HB_UShort num_classes,
- HB_Stream stream )
-{
- HB_Error error;
-
- HB_UShort m, n, count;
- HB_UInt cur_offset, new_offset, base_offset;
-
- HB_BaseRecord *br;
- HB_Anchor *ban, *bans;
-
-
- base_offset = FILE_Pos();
-
- if ( ACCESS_Frame( 2L ) )
- return error;
-
- count = ba->BaseCount = GET_UShort();
-
- FORGET_Frame();
-
- ba->BaseRecord = NULL;
-
- if ( ALLOC_ARRAY( ba->BaseRecord, count, HB_BaseRecord ) )
- return error;
-
- br = ba->BaseRecord;
-
- bans = NULL;
-
- if ( ALLOC_ARRAY( bans, count * num_classes, HB_Anchor ) )
- goto Fail;
-
- for ( m = 0; m < count; m++ )
- {
- br[m].BaseAnchor = NULL;
-
- ban = br[m].BaseAnchor = bans + m * num_classes;
-
- for ( n = 0; n < num_classes; n++ )
- {
- if ( ACCESS_Frame( 2L ) )
- goto Fail;
-
- new_offset = GET_UShort() + base_offset;
-
- FORGET_Frame();
-
- if (new_offset == base_offset) {
- /* XXX
- * Doulos SIL Regular is buggy and has zero offsets here.
- * Skip it
- */
- ban[n].PosFormat = 0;
- continue;
- }
-
- cur_offset = FILE_Pos();
- if ( FILE_Seek( new_offset ) ||
- ( error = Load_Anchor( &ban[n], stream ) ) != HB_Err_Ok )
- goto Fail;
- (void)FILE_Seek( cur_offset );
- }
- }
-
- return HB_Err_Ok;
-
-Fail:
- FREE( bans );
- FREE( br );
- return error;
-}
-
-
-static void Free_BaseArray( HB_BaseArray* ba,
- HB_UShort num_classes )
-{
- HB_BaseRecord *br;
- HB_Anchor *bans;
-
- if ( ba->BaseRecord )
- {
- br = ba->BaseRecord;
-
- if ( ba->BaseCount )
- {
- HB_UShort i, count;
- count = num_classes * ba->BaseCount;
- bans = br[0].BaseAnchor;
- for (i = 0; i < count; i++)
- Free_Anchor (&bans[i]);
- FREE( bans );
- }
-
- FREE( br );
- }
-}
-
-
-/* MarkBasePosFormat1 */
-
-static HB_Error Load_MarkBasePos( HB_GPOS_SubTable* st,
- HB_Stream stream )
-{
- HB_Error error;
- HB_MarkBasePos* mbp = &st->markbase;
-
- HB_UInt cur_offset, new_offset, base_offset;
-
-
- base_offset = FILE_Pos();
-
- if ( ACCESS_Frame( 4L ) )
- return error;
-
- mbp->PosFormat = GET_UShort();
- new_offset = GET_UShort() + base_offset;
-
- FORGET_Frame();
-
- if (mbp->PosFormat != 1)
- return ERR(HB_Err_Invalid_SubTable_Format);
-
- cur_offset = FILE_Pos();
- if ( FILE_Seek( new_offset ) ||
- ( error = _HB_OPEN_Load_Coverage( &mbp->MarkCoverage, stream ) ) != HB_Err_Ok )
- return error;
- (void)FILE_Seek( cur_offset );
-
- if ( ACCESS_Frame( 2L ) )
- goto Fail3;
-
- new_offset = GET_UShort() + base_offset;
-
- FORGET_Frame();
-
- cur_offset = FILE_Pos();
- if ( FILE_Seek( new_offset ) ||
- ( error = _HB_OPEN_Load_Coverage( &mbp->BaseCoverage, stream ) ) != HB_Err_Ok )
- goto Fail3;
- (void)FILE_Seek( cur_offset );
-
- if ( ACCESS_Frame( 4L ) )
- goto Fail2;
-
- mbp->ClassCount = GET_UShort();
- new_offset = GET_UShort() + base_offset;
-
- FORGET_Frame();
-
- cur_offset = FILE_Pos();
- if ( FILE_Seek( new_offset ) ||
- ( error = Load_MarkArray( &mbp->MarkArray, stream ) ) != HB_Err_Ok )
- goto Fail2;
- (void)FILE_Seek( cur_offset );
-
- if ( ACCESS_Frame( 2L ) )
- goto Fail1;
-
- new_offset = GET_UShort() + base_offset;
-
- FORGET_Frame();
-
- cur_offset = FILE_Pos();
- if ( FILE_Seek( new_offset ) ||
- ( error = Load_BaseArray( &mbp->BaseArray, mbp->ClassCount,
- stream ) ) != HB_Err_Ok )
- goto Fail1;
-
- return HB_Err_Ok;
-
-Fail1:
- Free_MarkArray( &mbp->MarkArray );
-
-Fail2:
- _HB_OPEN_Free_Coverage( &mbp->BaseCoverage );
-
-Fail3:
- _HB_OPEN_Free_Coverage( &mbp->MarkCoverage );
- return error;
-}
-
-
-static void Free_MarkBasePos( HB_GPOS_SubTable* st )
-{
- HB_MarkBasePos* mbp = &st->markbase;
-
- Free_BaseArray( &mbp->BaseArray, mbp->ClassCount );
- Free_MarkArray( &mbp->MarkArray );
- _HB_OPEN_Free_Coverage( &mbp->BaseCoverage );
- _HB_OPEN_Free_Coverage( &mbp->MarkCoverage );
-}
-
-
-static HB_Error Lookup_MarkBasePos( GPOS_Instance* gpi,
- HB_GPOS_SubTable* st,
- HB_Buffer buffer,
- HB_UShort flags,
- HB_UShort context_length,
- int nesting_level )
-{
- HB_UShort i, j, mark_index, base_index, property, class;
- HB_Fixed x_mark_value, y_mark_value, x_base_value, y_base_value;
- HB_Error error;
- HB_GPOSHeader* gpos = gpi->gpos;
- HB_MarkBasePos* mbp = &st->markbase;
-
- HB_MarkArray* ma;
- HB_BaseArray* ba;
- HB_BaseRecord* br;
- HB_Anchor* mark_anchor;
- HB_Anchor* base_anchor;
-
- HB_Position o;
-
- HB_UNUSED(nesting_level);
-
- if ( context_length != 0xFFFF && context_length < 1 )
- return HB_Err_Not_Covered;
-
- if ( flags & HB_LOOKUP_FLAG_IGNORE_BASE_GLYPHS )
- return HB_Err_Not_Covered;
-
- if ( CHECK_Property( gpos->gdef, IN_CURITEM(),
- flags, &property ) )
- return error;
-
- error = _HB_OPEN_Coverage_Index( &mbp->MarkCoverage, IN_CURGLYPH(),
- &mark_index );
- if ( error )
- return error;
-
- /* now we search backwards for a non-mark glyph */
-
- i = 1;
- j = buffer->in_pos - 1;
-
- while ( i <= buffer->in_pos )
- {
- error = HB_GDEF_Get_Glyph_Property( gpos->gdef, IN_GLYPH( j ),
- &property );
- if ( error )
- return error;
-
- if ( !( property == HB_GDEF_MARK || property & HB_LOOKUP_FLAG_IGNORE_SPECIAL_MARKS ) )
- break;
-
- i++;
- j--;
- }
-
- /* The following assertion is too strong -- at least for mangal.ttf. */
-#if 0
- if ( property != HB_GDEF_BASE_GLYPH )
- return HB_Err_Not_Covered;
-#endif
-
- if ( i > buffer->in_pos )
- return HB_Err_Not_Covered;
-
- error = _HB_OPEN_Coverage_Index( &mbp->BaseCoverage, IN_GLYPH( j ),
- &base_index );
- if ( error )
- return error;
-
- ma = &mbp->MarkArray;
-
- if ( mark_index >= ma->MarkCount )
- return ERR(HB_Err_Invalid_SubTable);
-
- class = ma->MarkRecord[mark_index].Class;
- mark_anchor = &ma->MarkRecord[mark_index].MarkAnchor;
-
- if ( class >= mbp->ClassCount )
- return ERR(HB_Err_Invalid_SubTable);
-
- ba = &mbp->BaseArray;
-
- if ( base_index >= ba->BaseCount )
- return ERR(HB_Err_Invalid_SubTable);
-
- br = &ba->BaseRecord[base_index];
- base_anchor = &br->BaseAnchor[class];
-
- error = Get_Anchor( gpi, mark_anchor, IN_CURGLYPH(),
- &x_mark_value, &y_mark_value );
- if ( error )
- return error;
-
- error = Get_Anchor( gpi, base_anchor, IN_GLYPH( j ),
- &x_base_value, &y_base_value );
- if ( error )
- return error;
-
- /* anchor points are not cumulative */
-
- o = POSITION( buffer->in_pos );
-
- o->x_pos = x_base_value - x_mark_value;
- o->y_pos = y_base_value - y_mark_value;
- o->x_advance = 0;
- o->y_advance = 0;
- o->back = i;
-
- (buffer->in_pos)++;
-
- return HB_Err_Ok;
-}
-
-
-/* LookupType 5 */
-
-/* LigatureAttach */
-
-static HB_Error Load_LigatureAttach( HB_LigatureAttach* lat,
- HB_UShort num_classes,
- HB_Stream stream )
-{
- HB_Error error;
-
- HB_UShort m, n, k, count;
- HB_UInt cur_offset, new_offset, base_offset;
-
- HB_ComponentRecord* cr;
- HB_Anchor* lan;
-
-
- base_offset = FILE_Pos();
-
- if ( ACCESS_Frame( 2L ) )
- return error;
-
- count = lat->ComponentCount = GET_UShort();
-
- FORGET_Frame();
-
- lat->ComponentRecord = NULL;
-
- if ( ALLOC_ARRAY( lat->ComponentRecord, count, HB_ComponentRecord ) )
- return error;
-
- cr = lat->ComponentRecord;
-
- for ( m = 0; m < count; m++ )
- {
- cr[m].LigatureAnchor = NULL;
-
- if ( ALLOC_ARRAY( cr[m].LigatureAnchor, num_classes, HB_Anchor ) )
- goto Fail;
-
- lan = cr[m].LigatureAnchor;
-
- for ( n = 0; n < num_classes; n++ )
- {
- if ( ACCESS_Frame( 2L ) )
- goto Fail0;
-
- new_offset = GET_UShort();
-
- FORGET_Frame();
-
- if ( new_offset )
- {
- new_offset += base_offset;
-
- cur_offset = FILE_Pos();
- if ( FILE_Seek( new_offset ) ||
- ( error = Load_Anchor( &lan[n], stream ) ) != HB_Err_Ok )
- goto Fail0;
- (void)FILE_Seek( cur_offset );
- }
- else
- lan[n].PosFormat = 0;
- }
-
- continue;
- Fail0:
- for ( k = 0; k < n; k++ )
- Free_Anchor( &lan[k] );
- goto Fail;
- }
-
- return HB_Err_Ok;
-
-Fail:
- for ( k = 0; k < m; k++ )
- {
- lan = cr[k].LigatureAnchor;
-
- for ( n = 0; n < num_classes; n++ )
- Free_Anchor( &lan[n] );
-
- FREE( lan );
- }
-
- FREE( cr );
- return error;
-}
-
-
-static void Free_LigatureAttach( HB_LigatureAttach* lat,
- HB_UShort num_classes )
-{
- HB_UShort m, n, count;
-
- HB_ComponentRecord* cr;
- HB_Anchor* lan;
-
-
- if ( lat->ComponentRecord )
- {
- count = lat->ComponentCount;
- cr = lat->ComponentRecord;
-
- for ( m = 0; m < count; m++ )
- {
- lan = cr[m].LigatureAnchor;
-
- for ( n = 0; n < num_classes; n++ )
- Free_Anchor( &lan[n] );
-
- FREE( lan );
- }
-
- FREE( cr );
- }
-}
-
-
-/* LigatureArray */
-
-static HB_Error Load_LigatureArray( HB_LigatureArray* la,
- HB_UShort num_classes,
- HB_Stream stream )
-{
- HB_Error error;
-
- HB_UShort n, m, count;
- HB_UInt cur_offset, new_offset, base_offset;
-
- HB_LigatureAttach* lat;
-
-
- base_offset = FILE_Pos();
-
- if ( ACCESS_Frame( 2L ) )
- return error;
-
- count = la->LigatureCount = GET_UShort();
-
- FORGET_Frame();
-
- la->LigatureAttach = NULL;
-
- if ( ALLOC_ARRAY( la->LigatureAttach, count, HB_LigatureAttach ) )
- return error;
-
- lat = la->LigatureAttach;
-
- for ( n = 0; n < count; n++ )
- {
- if ( ACCESS_Frame( 2L ) )
- goto Fail;
-
- new_offset = GET_UShort() + base_offset;
-
- FORGET_Frame();
-
- cur_offset = FILE_Pos();
- if ( FILE_Seek( new_offset ) ||
- ( error = Load_LigatureAttach( &lat[n], num_classes,
- stream ) ) != HB_Err_Ok )
- goto Fail;
- (void)FILE_Seek( cur_offset );
- }
-
- return HB_Err_Ok;
-
-Fail:
- for ( m = 0; m < n; m++ )
- Free_LigatureAttach( &lat[m], num_classes );
-
- FREE( lat );
- return error;
-}
-
-
-static void Free_LigatureArray( HB_LigatureArray* la,
- HB_UShort num_classes )
-{
- HB_UShort n, count;
-
- HB_LigatureAttach* lat;
-
-
- if ( la->LigatureAttach )
- {
- count = la->LigatureCount;
- lat = la->LigatureAttach;
-
- for ( n = 0; n < count; n++ )
- Free_LigatureAttach( &lat[n], num_classes );
-
- FREE( lat );
- }
-}
-
-
-/* MarkLigPosFormat1 */
-
-static HB_Error Load_MarkLigPos( HB_GPOS_SubTable* st,
- HB_Stream stream )
-{
- HB_Error error;
- HB_MarkLigPos* mlp = &st->marklig;
-
- HB_UInt cur_offset, new_offset, base_offset;
-
-
- base_offset = FILE_Pos();
-
- if ( ACCESS_Frame( 4L ) )
- return error;
-
- mlp->PosFormat = GET_UShort();
- new_offset = GET_UShort() + base_offset;
-
- FORGET_Frame();
-
- cur_offset = FILE_Pos();
- if ( FILE_Seek( new_offset ) ||
- ( error = _HB_OPEN_Load_Coverage( &mlp->MarkCoverage, stream ) ) != HB_Err_Ok )
- return error;
- (void)FILE_Seek( cur_offset );
-
- if ( ACCESS_Frame( 2L ) )
- goto Fail3;
-
- new_offset = GET_UShort() + base_offset;
-
- FORGET_Frame();
-
- cur_offset = FILE_Pos();
- if ( FILE_Seek( new_offset ) ||
- ( error = _HB_OPEN_Load_Coverage( &mlp->LigatureCoverage,
- stream ) ) != HB_Err_Ok )
- goto Fail3;
- (void)FILE_Seek( cur_offset );
-
- if ( ACCESS_Frame( 4L ) )
- goto Fail2;
-
- mlp->ClassCount = GET_UShort();
- new_offset = GET_UShort() + base_offset;
-
- FORGET_Frame();
-
- cur_offset = FILE_Pos();
- if ( FILE_Seek( new_offset ) ||
- ( error = Load_MarkArray( &mlp->MarkArray, stream ) ) != HB_Err_Ok )
- goto Fail2;
- (void)FILE_Seek( cur_offset );
-
- if ( ACCESS_Frame( 2L ) )
- goto Fail1;
-
- new_offset = GET_UShort() + base_offset;
-
- FORGET_Frame();
-
- cur_offset = FILE_Pos();
- if ( FILE_Seek( new_offset ) ||
- ( error = Load_LigatureArray( &mlp->LigatureArray, mlp->ClassCount,
- stream ) ) != HB_Err_Ok )
- goto Fail1;
-
- return HB_Err_Ok;
-
-Fail1:
- Free_MarkArray( &mlp->MarkArray );
-
-Fail2:
- _HB_OPEN_Free_Coverage( &mlp->LigatureCoverage );
-
-Fail3:
- _HB_OPEN_Free_Coverage( &mlp->MarkCoverage );
- return error;
-}
-
-
-static void Free_MarkLigPos( HB_GPOS_SubTable* st)
-{
- HB_MarkLigPos* mlp = &st->marklig;
-
- Free_LigatureArray( &mlp->LigatureArray, mlp->ClassCount );
- Free_MarkArray( &mlp->MarkArray );
- _HB_OPEN_Free_Coverage( &mlp->LigatureCoverage );
- _HB_OPEN_Free_Coverage( &mlp->MarkCoverage );
-}
-
-
-static HB_Error Lookup_MarkLigPos( GPOS_Instance* gpi,
- HB_GPOS_SubTable* st,
- HB_Buffer buffer,
- HB_UShort flags,
- HB_UShort context_length,
- int nesting_level )
-{
- HB_UShort i, j, mark_index, lig_index, property, class;
- HB_UShort mark_glyph;
- HB_Fixed x_mark_value, y_mark_value, x_lig_value, y_lig_value;
- HB_Error error;
- HB_GPOSHeader* gpos = gpi->gpos;
- HB_MarkLigPos* mlp = &st->marklig;
-
- HB_MarkArray* ma;
- HB_LigatureArray* la;
- HB_LigatureAttach* lat;
- HB_ComponentRecord* cr;
- HB_UShort comp_index;
- HB_Anchor* mark_anchor;
- HB_Anchor* lig_anchor;
-
- HB_Position o;
-
- HB_UNUSED(nesting_level);
-
- if ( context_length != 0xFFFF && context_length < 1 )
- return HB_Err_Not_Covered;
-
- if ( flags & HB_LOOKUP_FLAG_IGNORE_LIGATURES )
- return HB_Err_Not_Covered;
-
- mark_glyph = IN_CURGLYPH();
-
- if ( CHECK_Property( gpos->gdef, IN_CURITEM(), flags, &property ) )
- return error;
-
- error = _HB_OPEN_Coverage_Index( &mlp->MarkCoverage, mark_glyph, &mark_index );
- if ( error )
- return error;
-
- /* now we search backwards for a non-mark glyph */
-
- i = 1;
- j = buffer->in_pos - 1;
-
- while ( i <= buffer->in_pos )
- {
- error = HB_GDEF_Get_Glyph_Property( gpos->gdef, IN_GLYPH( j ),
- &property );
- if ( error )
- return error;
-
- if ( !( property == HB_GDEF_MARK || property & HB_LOOKUP_FLAG_IGNORE_SPECIAL_MARKS ) )
- break;
-
- i++;
- j--;
- }
-
- /* Similar to Lookup_MarkBasePos(), I suspect that this assertion is
- too strong, thus it is commented out. */
-#if 0
- if ( property != HB_GDEF_LIGATURE )
- return HB_Err_Not_Covered;
-#endif
-
- if ( i > buffer->in_pos )
- return HB_Err_Not_Covered;
-
- error = _HB_OPEN_Coverage_Index( &mlp->LigatureCoverage, IN_GLYPH( j ),
- &lig_index );
- if ( error )
- return error;
-
- ma = &mlp->MarkArray;
-
- if ( mark_index >= ma->MarkCount )
- return ERR(HB_Err_Invalid_SubTable);
-
- class = ma->MarkRecord[mark_index].Class;
- mark_anchor = &ma->MarkRecord[mark_index].MarkAnchor;
-
- if ( class >= mlp->ClassCount )
- return ERR(HB_Err_Invalid_SubTable);
-
- la = &mlp->LigatureArray;
-
- if ( lig_index >= la->LigatureCount )
- return ERR(HB_Err_Invalid_SubTable);
-
- lat = &la->LigatureAttach[lig_index];
-
- /* 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
- can directly use the component index. If not, we attach the mark
- glyph to the last component of the ligature. */
-
- if ( IN_LIGID( j ) == IN_LIGID( buffer->in_pos) )
- {
- comp_index = IN_COMPONENT( buffer->in_pos );
- if ( comp_index >= lat->ComponentCount )
- return HB_Err_Not_Covered;
- }
- else
- comp_index = lat->ComponentCount - 1;
-
- cr = &lat->ComponentRecord[comp_index];
- lig_anchor = &cr->LigatureAnchor[class];
-
- error = Get_Anchor( gpi, mark_anchor, IN_CURGLYPH(),
- &x_mark_value, &y_mark_value );
- if ( error )
- return error;
- error = Get_Anchor( gpi, lig_anchor, IN_GLYPH( j ),
- &x_lig_value, &y_lig_value );
- if ( error )
- return error;
-
- /* anchor points are not cumulative */
-
- o = POSITION( buffer->in_pos );
-
- o->x_pos = x_lig_value - x_mark_value;
- o->y_pos = y_lig_value - y_mark_value;
- o->x_advance = 0;
- o->y_advance = 0;
- o->back = i;
-
- (buffer->in_pos)++;
-
- return HB_Err_Ok;
-}
-
-
-/* LookupType 6 */
-
-/* Mark2Array */
-
-static HB_Error Load_Mark2Array( HB_Mark2Array* m2a,
- HB_UShort num_classes,
- HB_Stream stream )
-{
- HB_Error error;
-
- HB_UShort m, n, count;
- HB_UInt cur_offset, new_offset, base_offset;
-
- HB_Mark2Record *m2r;
- HB_Anchor *m2an, *m2ans;
-
-
- base_offset = FILE_Pos();
-
- if ( ACCESS_Frame( 2L ) )
- return error;
-
- count = m2a->Mark2Count = GET_UShort();
-
- FORGET_Frame();
-
- m2a->Mark2Record = NULL;
-
- if ( ALLOC_ARRAY( m2a->Mark2Record, count, HB_Mark2Record ) )
- return error;
-
- m2r = m2a->Mark2Record;
-
- m2ans = NULL;
-
- if ( ALLOC_ARRAY( m2ans, count * num_classes, HB_Anchor ) )
- goto Fail;
-
- for ( m = 0; m < count; m++ )
- {
- m2an = m2r[m].Mark2Anchor = m2ans + m * num_classes;
-
- for ( n = 0; n < num_classes; n++ )
- {
- if ( ACCESS_Frame( 2L ) )
- goto Fail;
-
- new_offset = GET_UShort() + base_offset;
-
- FORGET_Frame();
-
- if (new_offset == base_offset) {
- /* Anchor table not provided. Skip loading.
- * Some versions of FreeSans hit this. */
- m2an[n].PosFormat = 0;
- continue;
- }
-
- cur_offset = FILE_Pos();
- if ( FILE_Seek( new_offset ) ||
- ( error = Load_Anchor( &m2an[n], stream ) ) != HB_Err_Ok )
- goto Fail;
- (void)FILE_Seek( cur_offset );
- }
- }
-
- return HB_Err_Ok;
-
-Fail:
- FREE( m2ans );
- FREE( m2r );
- return error;
-}
-
-
-static void Free_Mark2Array( HB_Mark2Array* m2a,
- HB_UShort num_classes )
-{
- HB_Mark2Record *m2r;
- HB_Anchor *m2ans;
-
- HB_UNUSED(num_classes);
-
- if ( m2a->Mark2Record )
- {
- m2r = m2a->Mark2Record;
-
- if ( m2a->Mark2Count )
- {
- m2ans = m2r[0].Mark2Anchor;
- FREE( m2ans );
- }
-
- FREE( m2r );
- }
-}
-
-
-/* MarkMarkPosFormat1 */
-
-static HB_Error Load_MarkMarkPos( HB_GPOS_SubTable* st,
- HB_Stream stream )
-{
- HB_Error error;
- HB_MarkMarkPos* mmp = &st->markmark;
-
- HB_UInt cur_offset, new_offset, base_offset;
-
-
- base_offset = FILE_Pos();
-
- if ( ACCESS_Frame( 4L ) )
- return error;
-
- mmp->PosFormat = GET_UShort();
- new_offset = GET_UShort() + base_offset;
-
- FORGET_Frame();
-
- cur_offset = FILE_Pos();
- if ( FILE_Seek( new_offset ) ||
- ( error = _HB_OPEN_Load_Coverage( &mmp->Mark1Coverage,
- stream ) ) != HB_Err_Ok )
- return error;
- (void)FILE_Seek( cur_offset );
-
- if ( ACCESS_Frame( 2L ) )
- goto Fail3;
-
- new_offset = GET_UShort() + base_offset;
-
- FORGET_Frame();
-
- cur_offset = FILE_Pos();
- if ( FILE_Seek( new_offset ) ||
- ( error = _HB_OPEN_Load_Coverage( &mmp->Mark2Coverage,
- stream ) ) != HB_Err_Ok )
- goto Fail3;
- (void)FILE_Seek( cur_offset );
-
- if ( ACCESS_Frame( 4L ) )
- goto Fail2;
-
- mmp->ClassCount = GET_UShort();
- new_offset = GET_UShort() + base_offset;
-
- FORGET_Frame();
-
- cur_offset = FILE_Pos();
- if ( FILE_Seek( new_offset ) ||
- ( error = Load_MarkArray( &mmp->Mark1Array, stream ) ) != HB_Err_Ok )
- goto Fail2;
- (void)FILE_Seek( cur_offset );
-
- if ( ACCESS_Frame( 2L ) )
- goto Fail1;
-
- new_offset = GET_UShort() + base_offset;
-
- FORGET_Frame();
-
- cur_offset = FILE_Pos();
- if ( FILE_Seek( new_offset ) ||
- ( error = Load_Mark2Array( &mmp->Mark2Array, mmp->ClassCount,
- stream ) ) != HB_Err_Ok )
- goto Fail1;
-
- return HB_Err_Ok;
-
-Fail1:
- Free_MarkArray( &mmp->Mark1Array );
-
-Fail2:
- _HB_OPEN_Free_Coverage( &mmp->Mark2Coverage );
-
-Fail3:
- _HB_OPEN_Free_Coverage( &mmp->Mark1Coverage );
- return error;
-}
-
-
-static void Free_MarkMarkPos( HB_GPOS_SubTable* st)
-{
- HB_MarkMarkPos* mmp = &st->markmark;
-
- Free_Mark2Array( &mmp->Mark2Array, mmp->ClassCount );
- Free_MarkArray( &mmp->Mark1Array );
- _HB_OPEN_Free_Coverage( &mmp->Mark2Coverage );
- _HB_OPEN_Free_Coverage( &mmp->Mark1Coverage );
-}
-
-
-static HB_Error Lookup_MarkMarkPos( GPOS_Instance* gpi,
- HB_GPOS_SubTable* st,
- HB_Buffer buffer,
- HB_UShort flags,
- HB_UShort context_length,
- int nesting_level )
-{
- HB_UShort i, j, mark1_index, mark2_index, property, class;
- HB_Fixed x_mark1_value, y_mark1_value,
- x_mark2_value, y_mark2_value;
- HB_Error error;
- HB_GPOSHeader* gpos = gpi->gpos;
- HB_MarkMarkPos* mmp = &st->markmark;
-
- HB_MarkArray* ma1;
- HB_Mark2Array* ma2;
- HB_Mark2Record* m2r;
- HB_Anchor* mark1_anchor;
- HB_Anchor* mark2_anchor;
-
- HB_Position o;
-
- HB_UNUSED(nesting_level);
-
- if ( context_length != 0xFFFF && context_length < 1 )
- return HB_Err_Not_Covered;
-
- if ( flags & HB_LOOKUP_FLAG_IGNORE_MARKS )
- return HB_Err_Not_Covered;
-
- if ( CHECK_Property( gpos->gdef, IN_CURITEM(),
- flags, &property ) )
- return error;
-
- error = _HB_OPEN_Coverage_Index( &mmp->Mark1Coverage, IN_CURGLYPH(),
- &mark1_index );
- if ( error )
- return error;
-
- /* now we search backwards for a suitable mark glyph until a non-mark
- glyph */
-
- if ( buffer->in_pos == 0 )
- return HB_Err_Not_Covered;
-
- i = 1;
- j = buffer->in_pos - 1;
- while ( i <= buffer->in_pos )
- {
- error = HB_GDEF_Get_Glyph_Property( gpos->gdef, IN_GLYPH( j ),
- &property );
- if ( error )
- return error;
-
- if ( !( property == HB_GDEF_MARK || property & HB_LOOKUP_FLAG_IGNORE_SPECIAL_MARKS ) )
- return HB_Err_Not_Covered;
-
- if ( flags & HB_LOOKUP_FLAG_IGNORE_SPECIAL_MARKS )
- {
- if ( property == (flags & 0xFF00) )
- break;
- }
- else
- break;
-
- i++;
- j--;
- }
-
- if ( i > buffer->in_pos )
- return HB_Err_Not_Covered;
-
- error = _HB_OPEN_Coverage_Index( &mmp->Mark2Coverage, IN_GLYPH( j ),
- &mark2_index );
- if ( error )
- return error;
-
- ma1 = &mmp->Mark1Array;
-
- if ( mark1_index >= ma1->MarkCount )
- return ERR(HB_Err_Invalid_SubTable);
-
- class = ma1->MarkRecord[mark1_index].Class;
- mark1_anchor = &ma1->MarkRecord[mark1_index].MarkAnchor;
-
- if ( class >= mmp->ClassCount )
- return ERR(HB_Err_Invalid_SubTable);
-
- ma2 = &mmp->Mark2Array;
-
- if ( mark2_index >= ma2->Mark2Count )
- return ERR(HB_Err_Invalid_SubTable);
-
- m2r = &ma2->Mark2Record[mark2_index];
- mark2_anchor = &m2r->Mark2Anchor[class];
-
- error = Get_Anchor( gpi, mark1_anchor, IN_CURGLYPH(),
- &x_mark1_value, &y_mark1_value );
- if ( error )
- return error;
- error = Get_Anchor( gpi, mark2_anchor, IN_GLYPH( j ),
- &x_mark2_value, &y_mark2_value );
- if ( error )
- return error;
-
- /* anchor points are not cumulative */
-
- o = POSITION( buffer->in_pos );
-
- o->x_pos = x_mark2_value - x_mark1_value;
- o->y_pos = y_mark2_value - y_mark1_value;
- o->x_advance = 0;
- o->y_advance = 0;
- o->back = 1;
-
- (buffer->in_pos)++;
-
- return HB_Err_Ok;
-}
-
-
-/* Do the actual positioning for a context positioning (either format
- 7 or 8). This is only called after we've determined that the stream
- matches the subrule. */
-
-static HB_Error Do_ContextPos( GPOS_Instance* gpi,
- HB_UShort GlyphCount,
- HB_UShort PosCount,
- HB_PosLookupRecord* pos,
- HB_Buffer buffer,
- int nesting_level )
-{
- HB_Error error;
- HB_UInt i, old_pos;
-
-
- i = 0;
-
- while ( i < GlyphCount )
- {
- if ( PosCount && i == pos->SequenceIndex )
- {
- old_pos = buffer->in_pos;
-
- /* Do a positioning */
-
- error = GPOS_Do_Glyph_Lookup( gpi, pos->LookupListIndex, buffer,
- GlyphCount, nesting_level );
-
- if ( error )
- return error;
-
- pos++;
- PosCount--;
- i += buffer->in_pos - old_pos;
- }
- else
- {
- i++;
- (buffer->in_pos)++;
- }
- }
-
- return HB_Err_Ok;
-}
-
-
-/* LookupType 7 */
-
-/* PosRule */
-
-static HB_Error Load_PosRule( HB_PosRule* pr,
- HB_Stream stream )
-{
- HB_Error error;
-
- HB_UShort n, count;
- HB_UShort* i;
-
- HB_PosLookupRecord* plr;
-
-
- if ( ACCESS_Frame( 4L ) )
- return error;
-
- pr->GlyphCount = GET_UShort();
- pr->PosCount = GET_UShort();
-
- FORGET_Frame();
-
- pr->Input = NULL;
-
- count = pr->GlyphCount - 1; /* only GlyphCount - 1 elements */
-
- if ( ALLOC_ARRAY( pr->Input, count, HB_UShort ) )
- return error;
-
- i = pr->Input;
-
- if ( ACCESS_Frame( count * 2L ) )
- goto Fail2;
-
- for ( n = 0; n < count; n++ )
- i[n] = GET_UShort();
-
- FORGET_Frame();
-
- pr->PosLookupRecord = NULL;
-
- count = pr->PosCount;
-
- if ( ALLOC_ARRAY( pr->PosLookupRecord, count, HB_PosLookupRecord ) )
- goto Fail2;
-
- plr = pr->PosLookupRecord;
-
- if ( ACCESS_Frame( count * 4L ) )
- goto Fail1;
-
- for ( n = 0; n < count; n++ )
- {
- plr[n].SequenceIndex = GET_UShort();
- plr[n].LookupListIndex = GET_UShort();
- }
-
- FORGET_Frame();
-
- return HB_Err_Ok;
-
-Fail1:
- FREE( plr );
-
-Fail2:
- FREE( i );
- return error;
-}
-
-
-static void Free_PosRule( HB_PosRule* pr )
-{
- FREE( pr->PosLookupRecord );
- FREE( pr->Input );
-}
-
-
-/* PosRuleSet */
-
-static HB_Error Load_PosRuleSet( HB_PosRuleSet* prs,
- HB_Stream stream )
-{
- HB_Error error;
-
- HB_UShort n, m, count;
- HB_UInt cur_offset, new_offset, base_offset;
-
- HB_PosRule* pr;
-
-
- base_offset = FILE_Pos();
-
- if ( ACCESS_Frame( 2L ) )
- return error;
-
- count = prs->PosRuleCount = GET_UShort();
-
- FORGET_Frame();
-
- prs->PosRule = NULL;
-
- if ( ALLOC_ARRAY( prs->PosRule, count, HB_PosRule ) )
- return error;
-
- pr = prs->PosRule;
-
- for ( n = 0; n < count; n++ )
- {
- if ( ACCESS_Frame( 2L ) )
- goto Fail;
-
- new_offset = GET_UShort() + base_offset;
-
- FORGET_Frame();
-
- cur_offset = FILE_Pos();
- if ( FILE_Seek( new_offset ) ||
- ( error = Load_PosRule( &pr[n], stream ) ) != HB_Err_Ok )
- goto Fail;
- (void)FILE_Seek( cur_offset );
- }
-
- return HB_Err_Ok;
-
-Fail:
- for ( m = 0; m < n; m++ )
- Free_PosRule( &pr[m] );
-
- FREE( pr );
- return error;
-}
-
-
-static void Free_PosRuleSet( HB_PosRuleSet* prs )
-{
- HB_UShort n, count;
-
- HB_PosRule* pr;
-
-
- if ( prs->PosRule )
- {
- count = prs->PosRuleCount;
- pr = prs->PosRule;
-
- for ( n = 0; n < count; n++ )
- Free_PosRule( &pr[n] );
-
- FREE( pr );
- }
-}
-
-
-/* ContextPosFormat1 */
-
-static HB_Error Load_ContextPos1( HB_ContextPosFormat1* cpf1,
- HB_Stream stream )
-{
- HB_Error error;
-
- HB_UShort n, m, count;
- HB_UInt cur_offset, new_offset, base_offset;
-
- HB_PosRuleSet* prs;
-
-
- base_offset = FILE_Pos() - 2L;
-
- if ( ACCESS_Frame( 2L ) )
- return error;
-
- new_offset = GET_UShort() + base_offset;
-
- FORGET_Frame();
-
- cur_offset = FILE_Pos();
- if ( FILE_Seek( new_offset ) ||
- ( error = _HB_OPEN_Load_Coverage( &cpf1->Coverage, stream ) ) != HB_Err_Ok )
- return error;
- (void)FILE_Seek( cur_offset );
-
- if ( ACCESS_Frame( 2L ) )
- goto Fail2;
-
- count = cpf1->PosRuleSetCount = GET_UShort();
-
- FORGET_Frame();
-
- cpf1->PosRuleSet = NULL;
-
- if ( ALLOC_ARRAY( cpf1->PosRuleSet, count, HB_PosRuleSet ) )
- goto Fail2;
-
- prs = cpf1->PosRuleSet;
-
- for ( n = 0; n < count; n++ )
- {
- if ( ACCESS_Frame( 2L ) )
- goto Fail1;
-
- new_offset = GET_UShort() + base_offset;
-
- FORGET_Frame();
-
- cur_offset = FILE_Pos();
- if ( FILE_Seek( new_offset ) ||
- ( error = Load_PosRuleSet( &prs[n], stream ) ) != HB_Err_Ok )
- goto Fail1;
- (void)FILE_Seek( cur_offset );
- }
-
- return HB_Err_Ok;
-
-Fail1:
- for ( m = 0; m < n; m++ )
- Free_PosRuleSet( &prs[m] );
-
- FREE( prs );
-
-Fail2:
- _HB_OPEN_Free_Coverage( &cpf1->Coverage );
- return error;
-}
-
-
-static void Free_ContextPos1( HB_ContextPosFormat1* cpf1 )
-{
- HB_UShort n, count;
-
- HB_PosRuleSet* prs;
-
-
- if ( cpf1->PosRuleSet )
- {
- count = cpf1->PosRuleSetCount;
- prs = cpf1->PosRuleSet;
-
- for ( n = 0; n < count; n++ )
- Free_PosRuleSet( &prs[n] );
-
- FREE( prs );
- }
-
- _HB_OPEN_Free_Coverage( &cpf1->Coverage );
-}
-
-
-/* PosClassRule */
-
-static HB_Error Load_PosClassRule( HB_ContextPosFormat2* cpf2,
- HB_PosClassRule* pcr,
- HB_Stream stream )
-{
- HB_Error error;
-
- HB_UShort n, count;
-
- HB_UShort* c;
- HB_PosLookupRecord* plr;
-
-
- if ( ACCESS_Frame( 4L ) )
- return error;
-
- pcr->GlyphCount = GET_UShort();
- pcr->PosCount = GET_UShort();
-
- FORGET_Frame();
-
- if ( pcr->GlyphCount > cpf2->MaxContextLength )
- cpf2->MaxContextLength = pcr->GlyphCount;
-
- pcr->Class = NULL;
-
- count = pcr->GlyphCount - 1; /* only GlyphCount - 1 elements */
-
- if ( ALLOC_ARRAY( pcr->Class, count, HB_UShort ) )
- return error;
-
- c = pcr->Class;
-
- if ( ACCESS_Frame( count * 2L ) )
- goto Fail2;
-
- for ( n = 0; n < count; n++ )
- c[n] = GET_UShort();
-
- FORGET_Frame();
-
- pcr->PosLookupRecord = NULL;
-
- count = pcr->PosCount;
-
- if ( ALLOC_ARRAY( pcr->PosLookupRecord, count, HB_PosLookupRecord ) )
- goto Fail2;
-
- plr = pcr->PosLookupRecord;
-
- if ( ACCESS_Frame( count * 4L ) )
- goto Fail1;
-
- for ( n = 0; n < count; n++ )
- {
- plr[n].SequenceIndex = GET_UShort();
- plr[n].LookupListIndex = GET_UShort();
- }
-
- FORGET_Frame();
-
- return HB_Err_Ok;
-
-Fail1:
- FREE( plr );
-
-Fail2:
- FREE( c );
- return error;
-}
-
-
-static void Free_PosClassRule( HB_PosClassRule* pcr )
-{
- FREE( pcr->PosLookupRecord );
- FREE( pcr->Class );
-}
-
-
-/* PosClassSet */
-
-static HB_Error Load_PosClassSet( HB_ContextPosFormat2* cpf2,
- HB_PosClassSet* pcs,
- HB_Stream stream )
-{
- HB_Error error;
-
- HB_UShort n, m, count;
- HB_UInt cur_offset, new_offset, base_offset;
-
- HB_PosClassRule* pcr;
-
-
- base_offset = FILE_Pos();
-
- if ( ACCESS_Frame( 2L ) )
- return error;
-
- count = pcs->PosClassRuleCount = GET_UShort();
-
- FORGET_Frame();
-
- pcs->PosClassRule = NULL;
-
- if ( ALLOC_ARRAY( pcs->PosClassRule, count, HB_PosClassRule ) )
- return error;
-
- pcr = pcs->PosClassRule;
-
- for ( n = 0; n < count; n++ )
- {
- if ( ACCESS_Frame( 2L ) )
- goto Fail;
-
- new_offset = GET_UShort() + base_offset;
-
- FORGET_Frame();
-
- cur_offset = FILE_Pos();
- if ( FILE_Seek( new_offset ) ||
- ( error = Load_PosClassRule( cpf2, &pcr[n],
- stream ) ) != HB_Err_Ok )
- goto Fail;
- (void)FILE_Seek( cur_offset );
- }
-
- return HB_Err_Ok;
-
-Fail:
- for ( m = 0; m < n; m++ )
- Free_PosClassRule( &pcr[m] );
-
- FREE( pcr );
- return error;
-}
-
-
-static void Free_PosClassSet( HB_PosClassSet* pcs )
-{
- HB_UShort n, count;
-
- HB_PosClassRule* pcr;
-
-
- if ( pcs->PosClassRule )
- {
- count = pcs->PosClassRuleCount;
- pcr = pcs->PosClassRule;
-
- for ( n = 0; n < count; n++ )
- Free_PosClassRule( &pcr[n] );
-
- FREE( pcr );
- }
-}
-
-
-/* ContextPosFormat2 */
-
-static HB_Error Load_ContextPos2( HB_ContextPosFormat2* cpf2,
- HB_Stream stream )
-{
- HB_Error error;
-
- HB_UShort n, m, count;
- HB_UInt cur_offset, new_offset, base_offset;
-
- HB_PosClassSet* pcs;
-
-
- base_offset = FILE_Pos() - 2;
-
- if ( ACCESS_Frame( 2L ) )
- return error;
-
- new_offset = GET_UShort() + base_offset;
-
- FORGET_Frame();
-
- cur_offset = FILE_Pos();
- if ( FILE_Seek( new_offset ) ||
- ( error = _HB_OPEN_Load_Coverage( &cpf2->Coverage, stream ) ) != HB_Err_Ok )
- return error;
- (void)FILE_Seek( cur_offset );
-
- if ( ACCESS_Frame( 4L ) )
- goto Fail3;
-
- new_offset = GET_UShort() + base_offset;
-
- /* `PosClassSetCount' is the upper limit for class values, thus we
- read it now to make an additional safety check. */
-
- count = cpf2->PosClassSetCount = GET_UShort();
-
- FORGET_Frame();
-
- cur_offset = FILE_Pos();
- if ( FILE_Seek( new_offset ) ||
- ( error = _HB_OPEN_Load_ClassDefinition( &cpf2->ClassDef, count,
- stream ) ) != HB_Err_Ok )
- goto Fail3;
- (void)FILE_Seek( cur_offset );
-
- cpf2->PosClassSet = NULL;
- cpf2->MaxContextLength = 0;
-
- if ( ALLOC_ARRAY( cpf2->PosClassSet, count, HB_PosClassSet ) )
- goto Fail2;
-
- pcs = cpf2->PosClassSet;
-
- for ( n = 0; n < count; n++ )
- {
- if ( ACCESS_Frame( 2L ) )
- goto Fail1;
-
- new_offset = GET_UShort() + base_offset;
-
- FORGET_Frame();
-
- if ( new_offset != base_offset ) /* not a NULL offset */
- {
- cur_offset = FILE_Pos();
- if ( FILE_Seek( new_offset ) ||
- ( error = Load_PosClassSet( cpf2, &pcs[n],
- stream ) ) != HB_Err_Ok )
- goto Fail1;
- (void)FILE_Seek( cur_offset );
- }
- else
- {
- /* we create a PosClassSet table with no entries */
-
- cpf2->PosClassSet[n].PosClassRuleCount = 0;
- cpf2->PosClassSet[n].PosClassRule = NULL;
- }
- }
-
- return HB_Err_Ok;
-
-Fail1:
- for ( m = 0; m < n; m++ )
- Free_PosClassSet( &pcs[m] );
-
- FREE( pcs );
-
-Fail2:
- _HB_OPEN_Free_ClassDefinition( &cpf2->ClassDef );
-
-Fail3:
- _HB_OPEN_Free_Coverage( &cpf2->Coverage );
- return error;
-}
-
-
-static void Free_ContextPos2( HB_ContextPosFormat2* cpf2 )
-{
- HB_UShort n, count;
-
- HB_PosClassSet* pcs;
-
-
- if ( cpf2->PosClassSet )
- {
- count = cpf2->PosClassSetCount;
- pcs = cpf2->PosClassSet;
-
- for ( n = 0; n < count; n++ )
- Free_PosClassSet( &pcs[n] );
-
- FREE( pcs );
- }
-
- _HB_OPEN_Free_ClassDefinition( &cpf2->ClassDef );
- _HB_OPEN_Free_Coverage( &cpf2->Coverage );
-}
-
-
-/* ContextPosFormat3 */
-
-static HB_Error Load_ContextPos3( HB_ContextPosFormat3* cpf3,
- HB_Stream stream )
-{
- HB_Error error;
-
- HB_UShort n, count;
- HB_UInt cur_offset, new_offset, base_offset;
-
- HB_Coverage* c;
- HB_PosLookupRecord* plr;
-
-
- base_offset = FILE_Pos() - 2L;
-
- if ( ACCESS_Frame( 4L ) )
- return error;
-
- cpf3->GlyphCount = GET_UShort();
- cpf3->PosCount = GET_UShort();
-
- FORGET_Frame();
-
- cpf3->Coverage = NULL;
-
- count = cpf3->GlyphCount;
-
- if ( ALLOC_ARRAY( cpf3->Coverage, count, HB_Coverage ) )
- return error;
-
- c = cpf3->Coverage;
-
- for ( n = 0; n < count; n++ )
- {
- if ( ACCESS_Frame( 2L ) )
- goto Fail2;
-
- new_offset = GET_UShort() + base_offset;
-
- FORGET_Frame();
-
- cur_offset = FILE_Pos();
- if ( FILE_Seek( new_offset ) ||
- ( error = _HB_OPEN_Load_Coverage( &c[n], stream ) ) != HB_Err_Ok )
- goto Fail2;
- (void)FILE_Seek( cur_offset );
- }
-
- cpf3->PosLookupRecord = NULL;
-
- count = cpf3->PosCount;
-
- if ( ALLOC_ARRAY( cpf3->PosLookupRecord, count, HB_PosLookupRecord ) )
- goto Fail2;
-
- plr = cpf3->PosLookupRecord;
-
- if ( ACCESS_Frame( count * 4L ) )
- goto Fail1;
-
- for ( n = 0; n < count; n++ )
- {
- plr[n].SequenceIndex = GET_UShort();
- plr[n].LookupListIndex = GET_UShort();
- }
-
- FORGET_Frame();
-
- return HB_Err_Ok;
-
-Fail1:
- FREE( plr );
-
-Fail2:
- for ( n = 0; n < count; n++ )
- _HB_OPEN_Free_Coverage( &c[n] );
-
- FREE( c );
- return error;
-}
-
-
-static void Free_ContextPos3( HB_ContextPosFormat3* cpf3 )
-{
- HB_UShort n, count;
-
- HB_Coverage* c;
-
-
- FREE( cpf3->PosLookupRecord );
-
- if ( cpf3->Coverage )
- {
- count = cpf3->GlyphCount;
- c = cpf3->Coverage;
-
- for ( n = 0; n < count; n++ )
- _HB_OPEN_Free_Coverage( &c[n] );
-
- FREE( c );
- }
-}
-
-
-/* ContextPos */
-
-static HB_Error Load_ContextPos( HB_GPOS_SubTable* st,
- HB_Stream stream )
-{
- HB_Error error;
- HB_ContextPos* cp = &st->context;
-
-
- if ( ACCESS_Frame( 2L ) )
- return error;
-
- cp->PosFormat = GET_UShort();
-
- FORGET_Frame();
-
- switch ( cp->PosFormat )
- {
- case 1:
- return Load_ContextPos1( &cp->cpf.cpf1, stream );
-
- case 2:
- return Load_ContextPos2( &cp->cpf.cpf2, stream );
-
- case 3:
- return Load_ContextPos3( &cp->cpf.cpf3, stream );
-
- default:
- return ERR(HB_Err_Invalid_SubTable_Format);
- }
-
- return HB_Err_Ok; /* never reached */
-}
-
-
-static void Free_ContextPos( HB_GPOS_SubTable* st )
-{
- HB_ContextPos* cp = &st->context;
-
- switch ( cp->PosFormat )
- {
- case 1: Free_ContextPos1( &cp->cpf.cpf1 ); break;
- case 2: Free_ContextPos2( &cp->cpf.cpf2 ); break;
- case 3: Free_ContextPos3( &cp->cpf.cpf3 ); break;
- default: break;
- }
-}
-
-
-static HB_Error Lookup_ContextPos1( GPOS_Instance* gpi,
- HB_ContextPosFormat1* cpf1,
- HB_Buffer buffer,
- HB_UShort flags,
- HB_UShort context_length,
- int nesting_level )
-{
- HB_UShort index, property;
- HB_UShort i, j, k, numpr;
- HB_Error error;
- HB_GPOSHeader* gpos = gpi->gpos;
-
- HB_PosRule* pr;
- HB_GDEFHeader* gdef;
-
-
- gdef = gpos->gdef;
-
- if ( CHECK_Property( gdef, IN_CURITEM(), flags, &property ) )
- return error;
-
- error = _HB_OPEN_Coverage_Index( &cpf1->Coverage, IN_CURGLYPH(), &index );
- if ( error )
- return error;
-
- pr = cpf1->PosRuleSet[index].PosRule;
- numpr = cpf1->PosRuleSet[index].PosRuleCount;
-
- for ( k = 0; k < numpr; k++ )
- {
- if ( context_length != 0xFFFF && context_length < pr[k].GlyphCount )
- goto next_posrule;
-
- if ( buffer->in_pos + pr[k].GlyphCount > buffer->in_length )
- goto next_posrule; /* context is too long */
-
- for ( i = 1, j = buffer->in_pos + 1; i < pr[k].GlyphCount; i++, j++ )
- {
- while ( CHECK_Property( gdef, IN_ITEM( j ), flags, &property ) )
- {
- if ( error && error != HB_Err_Not_Covered )
- return error;
-
- if ( j + pr[k].GlyphCount - i == (HB_Int)buffer->in_length )
- goto next_posrule;
- j++;
- }
-
- if ( IN_GLYPH( j ) != pr[k].Input[i - 1] )
- goto next_posrule;
- }
-
- return Do_ContextPos( gpi, pr[k].GlyphCount,
- pr[k].PosCount, pr[k].PosLookupRecord,
- buffer,
- nesting_level );
-
- next_posrule:
- ;
- }
-
- return HB_Err_Not_Covered;
-}
-
-
-static HB_Error Lookup_ContextPos2( GPOS_Instance* gpi,
- HB_ContextPosFormat2* cpf2,
- HB_Buffer buffer,
- HB_UShort flags,
- HB_UShort context_length,
- int nesting_level )
-{
- HB_UShort index, property;
- HB_Error error;
- HB_UShort i, j, k, known_classes;
-
- HB_UShort* classes;
- HB_UShort* cl;
- HB_GPOSHeader* gpos = gpi->gpos;
-
- HB_PosClassSet* pcs;
- HB_PosClassRule* pr;
- HB_GDEFHeader* gdef;
-
-
- gdef = gpos->gdef;
-
- if ( CHECK_Property( gdef, IN_CURITEM(), flags, &property ) )
- return error;
-
- /* Note: The coverage table in format 2 doesn't give an index into
- anything. It just lets us know whether or not we need to
- do any lookup at all. */
-
- error = _HB_OPEN_Coverage_Index( &cpf2->Coverage, IN_CURGLYPH(), &index );
- if ( error )
- return error;
-
- if (cpf2->MaxContextLength < 1)
- return HB_Err_Not_Covered;
-
- if ( ALLOC_ARRAY( classes, cpf2->MaxContextLength, HB_UShort ) )
- return error;
-
- error = _HB_OPEN_Get_Class( &cpf2->ClassDef, IN_CURGLYPH(),
- &classes[0], NULL );
- if ( error && error != HB_Err_Not_Covered )
- goto End;
- known_classes = 0;
-
- pcs = &cpf2->PosClassSet[classes[0]];
- if ( !pcs )
- {
- error = ERR(HB_Err_Invalid_SubTable);
- goto End;
- }
-
- for ( k = 0; k < pcs->PosClassRuleCount; k++ )
- {
- pr = &pcs->PosClassRule[k];
-
- if ( context_length != 0xFFFF && context_length < pr->GlyphCount )
- goto next_posclassrule;
-
- if ( buffer->in_pos + pr->GlyphCount > buffer->in_length )
- goto next_posclassrule; /* context is too long */
-
- cl = pr->Class;
-
- /* Start at 1 because [0] is implied */
-
- for ( i = 1, j = buffer->in_pos + 1; i < pr->GlyphCount; i++, j++ )
- {
- while ( CHECK_Property( gdef, IN_ITEM( j ), flags, &property ) )
- {
- if ( error && error != HB_Err_Not_Covered )
- goto End;
-
- if ( j + pr->GlyphCount - i == (HB_Int)buffer->in_length )
- goto next_posclassrule;
- j++;
- }
-
- if ( i > known_classes )
- {
- /* Keeps us from having to do this for each rule */
-
- error = _HB_OPEN_Get_Class( &cpf2->ClassDef, IN_GLYPH( j ), &classes[i], NULL );
- if ( error && error != HB_Err_Not_Covered )
- goto End;
- known_classes = i;
- }
-
- if ( cl[i - 1] != classes[i] )
- goto next_posclassrule;
- }
-
- error = Do_ContextPos( gpi, pr->GlyphCount,
- pr->PosCount, pr->PosLookupRecord,
- buffer,
- nesting_level );
- goto End;
-
- next_posclassrule:
- ;
- }
-
- error = HB_Err_Not_Covered;
-
-End:
- FREE( classes );
- return error;
-}
-
-
-static HB_Error Lookup_ContextPos3( GPOS_Instance* gpi,
- HB_ContextPosFormat3* cpf3,
- HB_Buffer buffer,
- HB_UShort flags,
- HB_UShort context_length,
- int nesting_level )
-{
- HB_Error error;
- HB_UShort index, i, j, property;
- HB_GPOSHeader* gpos = gpi->gpos;
-
- HB_Coverage* c;
- HB_GDEFHeader* gdef;
-
-
- gdef = gpos->gdef;
-
- if ( CHECK_Property( gdef, IN_CURITEM(), flags, &property ) )
- return error;
-
- if ( context_length != 0xFFFF && context_length < cpf3->GlyphCount )
- return HB_Err_Not_Covered;
-
- if ( buffer->in_pos + cpf3->GlyphCount > buffer->in_length )
- return HB_Err_Not_Covered; /* context is too long */
-
- c = cpf3->Coverage;
-
- for ( i = 1, j = 1; i < cpf3->GlyphCount; i++, j++ )
- {
- while ( CHECK_Property( gdef, IN_ITEM( j ), flags, &property ) )
- {
- if ( error && error != HB_Err_Not_Covered )
- return error;
-
- if ( j + cpf3->GlyphCount - i == (HB_Int)buffer->in_length )
- return HB_Err_Not_Covered;
- j++;
- }
-
- error = _HB_OPEN_Coverage_Index( &c[i], IN_GLYPH( j ), &index );
- if ( error )
- return error;
- }
-
- return Do_ContextPos( gpi, cpf3->GlyphCount,
- cpf3->PosCount, cpf3->PosLookupRecord,
- buffer,
- nesting_level );
-}
-
-
-static HB_Error Lookup_ContextPos( GPOS_Instance* gpi,
- HB_GPOS_SubTable* st,
- HB_Buffer buffer,
- HB_UShort flags,
- HB_UShort context_length,
- int nesting_level )
-{
- HB_ContextPos* cp = &st->context;
-
- switch ( cp->PosFormat )
- {
- case 1:
- return Lookup_ContextPos1( gpi, &cp->cpf.cpf1, buffer,
- flags, context_length, nesting_level );
-
- case 2:
- return Lookup_ContextPos2( gpi, &cp->cpf.cpf2, buffer,
- flags, context_length, nesting_level );
-
- case 3:
- return Lookup_ContextPos3( gpi, &cp->cpf.cpf3, buffer,
- flags, context_length, nesting_level );
-
- default:
- return ERR(HB_Err_Invalid_SubTable_Format);
- }
-
- return HB_Err_Ok; /* never reached */
-}
-
-
-/* LookupType 8 */
-
-/* ChainPosRule */
-
-static HB_Error Load_ChainPosRule( HB_ChainPosRule* cpr,
- HB_Stream stream )
-{
- HB_Error error;
-
- HB_UShort n, count;
- HB_UShort* b;
- HB_UShort* i;
- HB_UShort* l;
-
- HB_PosLookupRecord* plr;
-
-
- if ( ACCESS_Frame( 2L ) )
- return error;
-
- cpr->BacktrackGlyphCount = GET_UShort();
-
- FORGET_Frame();
-
- cpr->Backtrack = NULL;
-
- count = cpr->BacktrackGlyphCount;
-
- if ( ALLOC_ARRAY( cpr->Backtrack, count, HB_UShort ) )
- return error;
-
- b = cpr->Backtrack;
-
- if ( ACCESS_Frame( count * 2L ) )
- goto Fail4;
-
- for ( n = 0; n < count; n++ )
- b[n] = GET_UShort();
-
- FORGET_Frame();
-
- if ( ACCESS_Frame( 2L ) )
- goto Fail4;
-
- cpr->InputGlyphCount = GET_UShort();
-
- FORGET_Frame();
-
- cpr->Input = NULL;
-
- count = cpr->InputGlyphCount - 1; /* only InputGlyphCount - 1 elements */
-
- if ( ALLOC_ARRAY( cpr->Input, count, HB_UShort ) )
- goto Fail4;
-
- i = cpr->Input;
-
- if ( ACCESS_Frame( count * 2L ) )
- goto Fail3;
-
- for ( n = 0; n < count; n++ )
- i[n] = GET_UShort();
-
- FORGET_Frame();
-
- if ( ACCESS_Frame( 2L ) )
- goto Fail3;
-
- cpr->LookaheadGlyphCount = GET_UShort();
-
- FORGET_Frame();
-
- cpr->Lookahead = NULL;
-
- count = cpr->LookaheadGlyphCount;
-
- if ( ALLOC_ARRAY( cpr->Lookahead, count, HB_UShort ) )
- goto Fail3;
-
- l = cpr->Lookahead;
-
- if ( ACCESS_Frame( count * 2L ) )
- goto Fail2;
-
- for ( n = 0; n < count; n++ )
- l[n] = GET_UShort();
-
- FORGET_Frame();
-
- if ( ACCESS_Frame( 2L ) )
- goto Fail2;
-
- cpr->PosCount = GET_UShort();
-
- FORGET_Frame();
-
- cpr->PosLookupRecord = NULL;
-
- count = cpr->PosCount;
-
- if ( ALLOC_ARRAY( cpr->PosLookupRecord, count, HB_PosLookupRecord ) )
- goto Fail2;
-
- plr = cpr->PosLookupRecord;
-
- if ( ACCESS_Frame( count * 4L ) )
- goto Fail1;
-
- for ( n = 0; n < count; n++ )
- {
- plr[n].SequenceIndex = GET_UShort();
- plr[n].LookupListIndex = GET_UShort();
- }
-
- FORGET_Frame();
-
- return HB_Err_Ok;
-
-Fail1:
- FREE( plr );
-
-Fail2:
- FREE( l );
-
-Fail3:
- FREE( i );
-
-Fail4:
- FREE( b );
- return error;
-}
-
-
-static void Free_ChainPosRule( HB_ChainPosRule* cpr )
-{
- FREE( cpr->PosLookupRecord );
- FREE( cpr->Lookahead );
- FREE( cpr->Input );
- FREE( cpr->Backtrack );
-}
-
-
-/* ChainPosRuleSet */
-
-static HB_Error Load_ChainPosRuleSet( HB_ChainPosRuleSet* cprs,
- HB_Stream stream )
-{
- HB_Error error;
-
- HB_UShort n, m, count;
- HB_UInt cur_offset, new_offset, base_offset;
-
- HB_ChainPosRule* cpr;
-
-
- base_offset = FILE_Pos();
-
- if ( ACCESS_Frame( 2L ) )
- return error;
-
- count = cprs->ChainPosRuleCount = GET_UShort();
-
- FORGET_Frame();
-
- cprs->ChainPosRule = NULL;
-
- if ( ALLOC_ARRAY( cprs->ChainPosRule, count, HB_ChainPosRule ) )
- return error;
-
- cpr = cprs->ChainPosRule;
-
- for ( n = 0; n < count; n++ )
- {
- if ( ACCESS_Frame( 2L ) )
- goto Fail;
-
- new_offset = GET_UShort() + base_offset;
-
- FORGET_Frame();
-
- cur_offset = FILE_Pos();
- if ( FILE_Seek( new_offset ) ||
- ( error = Load_ChainPosRule( &cpr[n], stream ) ) != HB_Err_Ok )
- goto Fail;
- (void)FILE_Seek( cur_offset );
- }
-
- return HB_Err_Ok;
-
-Fail:
- for ( m = 0; m < n; m++ )
- Free_ChainPosRule( &cpr[m] );
-
- FREE( cpr );
- return error;
-}
-
-
-static void Free_ChainPosRuleSet( HB_ChainPosRuleSet* cprs )
-{
- HB_UShort n, count;
-
- HB_ChainPosRule* cpr;
-
-
- if ( cprs->ChainPosRule )
- {
- count = cprs->ChainPosRuleCount;
- cpr = cprs->ChainPosRule;
-
- for ( n = 0; n < count; n++ )
- Free_ChainPosRule( &cpr[n] );
-
- FREE( cpr );
- }
-}
-
-
-/* ChainContextPosFormat1 */
-
-static HB_Error Load_ChainContextPos1( HB_ChainContextPosFormat1* ccpf1,
- HB_Stream stream )
-{
- HB_Error error;
-
- HB_UShort n, m, count;
- HB_UInt cur_offset, new_offset, base_offset;
-
- HB_ChainPosRuleSet* cprs;
-
-
- base_offset = FILE_Pos() - 2L;
-
- if ( ACCESS_Frame( 2L ) )
- return error;
-
- new_offset = GET_UShort() + base_offset;
-
- FORGET_Frame();
-
- cur_offset = FILE_Pos();
- if ( FILE_Seek( new_offset ) ||
- ( error = _HB_OPEN_Load_Coverage( &ccpf1->Coverage, stream ) ) != HB_Err_Ok )
- return error;
- (void)FILE_Seek( cur_offset );
-
- if ( ACCESS_Frame( 2L ) )
- goto Fail2;
-
- count = ccpf1->ChainPosRuleSetCount = GET_UShort();
-
- FORGET_Frame();
-
- ccpf1->ChainPosRuleSet = NULL;
-
- if ( ALLOC_ARRAY( ccpf1->ChainPosRuleSet, count, HB_ChainPosRuleSet ) )
- goto Fail2;
-
- cprs = ccpf1->ChainPosRuleSet;
-
- for ( n = 0; n < count; n++ )
- {
- if ( ACCESS_Frame( 2L ) )
- goto Fail1;
-
- new_offset = GET_UShort() + base_offset;
-
- FORGET_Frame();
-
- cur_offset = FILE_Pos();
- if ( FILE_Seek( new_offset ) ||
- ( error = Load_ChainPosRuleSet( &cprs[n], stream ) ) != HB_Err_Ok )
- goto Fail1;
- (void)FILE_Seek( cur_offset );
- }
-
- return HB_Err_Ok;
-
-Fail1:
- for ( m = 0; m < n; m++ )
- Free_ChainPosRuleSet( &cprs[m] );
-
- FREE( cprs );
-
-Fail2:
- _HB_OPEN_Free_Coverage( &ccpf1->Coverage );
- return error;
-}
-
-
-static void Free_ChainContextPos1( HB_ChainContextPosFormat1* ccpf1 )
-{
- HB_UShort n, count;
-
- HB_ChainPosRuleSet* cprs;
-
-
- if ( ccpf1->ChainPosRuleSet )
- {
- count = ccpf1->ChainPosRuleSetCount;
- cprs = ccpf1->ChainPosRuleSet;
-
- for ( n = 0; n < count; n++ )
- Free_ChainPosRuleSet( &cprs[n] );
-
- FREE( cprs );
- }
-
- _HB_OPEN_Free_Coverage( &ccpf1->Coverage );
-}
-
-
-/* ChainPosClassRule */
-
-static HB_Error Load_ChainPosClassRule(
- HB_ChainContextPosFormat2* ccpf2,
- HB_ChainPosClassRule* cpcr,
- HB_Stream stream )
-{
- HB_Error error;
-
- HB_UShort n, count;
-
- HB_UShort* b;
- HB_UShort* i;
- HB_UShort* l;
- HB_PosLookupRecord* plr;
-
-
- if ( ACCESS_Frame( 2L ) )
- return error;
-
- cpcr->BacktrackGlyphCount = GET_UShort();
-
- FORGET_Frame();
-
- if ( cpcr->BacktrackGlyphCount > ccpf2->MaxBacktrackLength )
- ccpf2->MaxBacktrackLength = cpcr->BacktrackGlyphCount;
-
- cpcr->Backtrack = NULL;
-
- count = cpcr->BacktrackGlyphCount;
-
- if ( ALLOC_ARRAY( cpcr->Backtrack, count, HB_UShort ) )
- return error;
-
- b = cpcr->Backtrack;
-
- if ( ACCESS_Frame( count * 2L ) )
- goto Fail4;
-
- for ( n = 0; n < count; n++ )
- b[n] = GET_UShort();
-
- FORGET_Frame();
-
- if ( ACCESS_Frame( 2L ) )
- goto Fail4;
-
- cpcr->InputGlyphCount = GET_UShort();
-
- if ( cpcr->InputGlyphCount > ccpf2->MaxInputLength )
- ccpf2->MaxInputLength = cpcr->InputGlyphCount;
-
- FORGET_Frame();
-
- cpcr->Input = NULL;
-
- count = cpcr->InputGlyphCount - 1; /* only InputGlyphCount - 1 elements */
-
- if ( ALLOC_ARRAY( cpcr->Input, count, HB_UShort ) )
- goto Fail4;
-
- i = cpcr->Input;
-
- if ( ACCESS_Frame( count * 2L ) )
- goto Fail3;
-
- for ( n = 0; n < count; n++ )
- i[n] = GET_UShort();
-
- FORGET_Frame();
-
- if ( ACCESS_Frame( 2L ) )
- goto Fail3;
-
- cpcr->LookaheadGlyphCount = GET_UShort();
-
- FORGET_Frame();
-
- if ( cpcr->LookaheadGlyphCount > ccpf2->MaxLookaheadLength )
- ccpf2->MaxLookaheadLength = cpcr->LookaheadGlyphCount;
-
- cpcr->Lookahead = NULL;
-
- count = cpcr->LookaheadGlyphCount;
-
- if ( ALLOC_ARRAY( cpcr->Lookahead, count, HB_UShort ) )
- goto Fail3;
-
- l = cpcr->Lookahead;
-
- if ( ACCESS_Frame( count * 2L ) )
- goto Fail2;
-
- for ( n = 0; n < count; n++ )
- l[n] = GET_UShort();
-
- FORGET_Frame();
-
- if ( ACCESS_Frame( 2L ) )
- goto Fail2;
-
- cpcr->PosCount = GET_UShort();
-
- FORGET_Frame();
-
- cpcr->PosLookupRecord = NULL;
-
- count = cpcr->PosCount;
-
- if ( ALLOC_ARRAY( cpcr->PosLookupRecord, count, HB_PosLookupRecord ) )
- goto Fail2;
-
- plr = cpcr->PosLookupRecord;
-
- if ( ACCESS_Frame( count * 4L ) )
- goto Fail1;
-
- for ( n = 0; n < count; n++ )
- {
- plr[n].SequenceIndex = GET_UShort();
- plr[n].LookupListIndex = GET_UShort();
- }
-
- FORGET_Frame();
-
- return HB_Err_Ok;
-
-Fail1:
- FREE( plr );
-
-Fail2:
- FREE( l );
-
-Fail3:
- FREE( i );
-
-Fail4:
- FREE( b );
- return error;
-}
-
-
-static void Free_ChainPosClassRule( HB_ChainPosClassRule* cpcr )
-{
- FREE( cpcr->PosLookupRecord );
- FREE( cpcr->Lookahead );
- FREE( cpcr->Input );
- FREE( cpcr->Backtrack );
-}
-
-
-/* PosClassSet */
-
-static HB_Error Load_ChainPosClassSet(
- HB_ChainContextPosFormat2* ccpf2,
- HB_ChainPosClassSet* cpcs,
- HB_Stream stream )
-{
- HB_Error error;
-
- HB_UShort n, m, count;
- HB_UInt cur_offset, new_offset, base_offset;
-
- HB_ChainPosClassRule* cpcr;
-
-
- base_offset = FILE_Pos();
-
- if ( ACCESS_Frame( 2L ) )
- return error;
-
- count = cpcs->ChainPosClassRuleCount = GET_UShort();
-
- FORGET_Frame();
-
- cpcs->ChainPosClassRule = NULL;
-
- if ( ALLOC_ARRAY( cpcs->ChainPosClassRule, count,
- HB_ChainPosClassRule ) )
- return error;
-
- cpcr = cpcs->ChainPosClassRule;
-
- for ( n = 0; n < count; n++ )
- {
- if ( ACCESS_Frame( 2L ) )
- goto Fail;
-
- new_offset = GET_UShort() + base_offset;
-
- FORGET_Frame();
-
- cur_offset = FILE_Pos();
- if ( FILE_Seek( new_offset ) ||
- ( error = Load_ChainPosClassRule( ccpf2, &cpcr[n],
- stream ) ) != HB_Err_Ok )
- goto Fail;
- (void)FILE_Seek( cur_offset );
- }
-
- return HB_Err_Ok;
-
-Fail:
- for ( m = 0; m < n; m++ )
- Free_ChainPosClassRule( &cpcr[m] );
-
- FREE( cpcr );
- return error;
-}
-
-
-static void Free_ChainPosClassSet( HB_ChainPosClassSet* cpcs )
-{
- HB_UShort n, count;
-
- HB_ChainPosClassRule* cpcr;
-
-
- if ( cpcs->ChainPosClassRule )
- {
- count = cpcs->ChainPosClassRuleCount;
- cpcr = cpcs->ChainPosClassRule;
-
- for ( n = 0; n < count; n++ )
- Free_ChainPosClassRule( &cpcr[n] );
-
- FREE( cpcr );
- }
-}
-
-
-/* ChainContextPosFormat2 */
-
-static HB_Error Load_ChainContextPos2( HB_ChainContextPosFormat2* ccpf2,
- HB_Stream stream )
-{
- HB_Error error;
-
- HB_UShort n, m, count;
- HB_UInt cur_offset, new_offset, base_offset;
- HB_UInt backtrack_offset, input_offset, lookahead_offset;
-
- HB_ChainPosClassSet* cpcs;
-
-
- base_offset = FILE_Pos() - 2;
-
- if ( ACCESS_Frame( 2L ) )
- return error;
-
- new_offset = GET_UShort() + base_offset;
-
- FORGET_Frame();
-
- cur_offset = FILE_Pos();
- if ( FILE_Seek( new_offset ) ||
- ( error = _HB_OPEN_Load_Coverage( &ccpf2->Coverage, stream ) ) != HB_Err_Ok )
- return error;
- (void)FILE_Seek( cur_offset );
-
- if ( ACCESS_Frame( 8L ) )
- goto Fail5;
-
- backtrack_offset = GET_UShort();
- input_offset = GET_UShort();
- lookahead_offset = GET_UShort();
-
- /* `ChainPosClassSetCount' is the upper limit for input class values,
- thus we read it now to make an additional safety check. No limit
- is known or needed for the other two class definitions */
-
- count = ccpf2->ChainPosClassSetCount = GET_UShort();
-
- FORGET_Frame();
-
- if ( ( error = _HB_OPEN_Load_EmptyOrClassDefinition( &ccpf2->BacktrackClassDef, 65535,
- backtrack_offset, base_offset,
- stream ) ) != HB_Err_Ok )
- goto Fail5;
- if ( ( error = _HB_OPEN_Load_EmptyOrClassDefinition( &ccpf2->InputClassDef, count,
- input_offset, base_offset,
- stream ) ) != HB_Err_Ok )
- goto Fail4;
- if ( ( error = _HB_OPEN_Load_EmptyOrClassDefinition( &ccpf2->LookaheadClassDef, 65535,
- lookahead_offset, base_offset,
- stream ) ) != HB_Err_Ok )
- goto Fail3;
-
- ccpf2->ChainPosClassSet = NULL;
- ccpf2->MaxBacktrackLength = 0;
- ccpf2->MaxInputLength = 0;
- ccpf2->MaxLookaheadLength = 0;
-
- if ( ALLOC_ARRAY( ccpf2->ChainPosClassSet, count, HB_ChainPosClassSet ) )
- goto Fail2;
-
- cpcs = ccpf2->ChainPosClassSet;
-
- for ( n = 0; n < count; n++ )
- {
- if ( ACCESS_Frame( 2L ) )
- goto Fail1;
-
- new_offset = GET_UShort() + base_offset;
-
- FORGET_Frame();
-
- if ( new_offset != base_offset ) /* not a NULL offset */
- {
- cur_offset = FILE_Pos();
- if ( FILE_Seek( new_offset ) ||
- ( error = Load_ChainPosClassSet( ccpf2, &cpcs[n],
- stream ) ) != HB_Err_Ok )
- goto Fail1;
- (void)FILE_Seek( cur_offset );
- }
- else
- {
- /* we create a ChainPosClassSet table with no entries */
-
- ccpf2->ChainPosClassSet[n].ChainPosClassRuleCount = 0;
- ccpf2->ChainPosClassSet[n].ChainPosClassRule = NULL;
- }
- }
-
- return HB_Err_Ok;
-
-Fail1:
- for ( m = 0; m < n; m++ )
- Free_ChainPosClassSet( &cpcs[m] );
-
- FREE( cpcs );
-
-Fail2:
- _HB_OPEN_Free_ClassDefinition( &ccpf2->LookaheadClassDef );
-
-Fail3:
- _HB_OPEN_Free_ClassDefinition( &ccpf2->InputClassDef );
-
-Fail4:
- _HB_OPEN_Free_ClassDefinition( &ccpf2->BacktrackClassDef );
-
-Fail5:
- _HB_OPEN_Free_Coverage( &ccpf2->Coverage );
- return error;
-}
-
-
-static void Free_ChainContextPos2( HB_ChainContextPosFormat2* ccpf2 )
-{
- HB_UShort n, count;
-
- HB_ChainPosClassSet* cpcs;
-
-
- if ( ccpf2->ChainPosClassSet )
- {
- count = ccpf2->ChainPosClassSetCount;
- cpcs = ccpf2->ChainPosClassSet;
-
- for ( n = 0; n < count; n++ )
- Free_ChainPosClassSet( &cpcs[n] );
-
- FREE( cpcs );
- }
-
- _HB_OPEN_Free_ClassDefinition( &ccpf2->LookaheadClassDef );
- _HB_OPEN_Free_ClassDefinition( &ccpf2->InputClassDef );
- _HB_OPEN_Free_ClassDefinition( &ccpf2->BacktrackClassDef );
-
- _HB_OPEN_Free_Coverage( &ccpf2->Coverage );
-}
-
-
-/* ChainContextPosFormat3 */
-
-static HB_Error Load_ChainContextPos3( HB_ChainContextPosFormat3* ccpf3,
- HB_Stream stream )
-{
- HB_Error error;
-
- HB_UShort n, nb, ni, nl, m, count;
- HB_UShort backtrack_count, input_count, lookahead_count;
- HB_UInt cur_offset, new_offset, base_offset;
-
- HB_Coverage* b;
- HB_Coverage* i;
- HB_Coverage* l;
- HB_PosLookupRecord* plr;
-
-
- base_offset = FILE_Pos() - 2L;
-
- if ( ACCESS_Frame( 2L ) )
- return error;
-
- ccpf3->BacktrackGlyphCount = GET_UShort();
-
- FORGET_Frame();
-
- ccpf3->BacktrackCoverage = NULL;
-
- backtrack_count = ccpf3->BacktrackGlyphCount;
-
- if ( ALLOC_ARRAY( ccpf3->BacktrackCoverage, backtrack_count,
- HB_Coverage ) )
- return error;
-
- b = ccpf3->BacktrackCoverage;
-
- for ( nb = 0; nb < backtrack_count; nb++ )
- {
- if ( ACCESS_Frame( 2L ) )
- goto Fail4;
-
- new_offset = GET_UShort() + base_offset;
-
- FORGET_Frame();
-
- cur_offset = FILE_Pos();
- if ( FILE_Seek( new_offset ) ||
- ( error = _HB_OPEN_Load_Coverage( &b[nb], stream ) ) != HB_Err_Ok )
- goto Fail4;
- (void)FILE_Seek( cur_offset );
- }
-
- if ( ACCESS_Frame( 2L ) )
- goto Fail4;
-
- ccpf3->InputGlyphCount = GET_UShort();
-
- FORGET_Frame();
-
- ccpf3->InputCoverage = NULL;
-
- input_count = ccpf3->InputGlyphCount;
-
- if ( ALLOC_ARRAY( ccpf3->InputCoverage, input_count, HB_Coverage ) )
- goto Fail4;
-
- i = ccpf3->InputCoverage;
-
- for ( ni = 0; ni < input_count; ni++ )
- {
- if ( ACCESS_Frame( 2L ) )
- goto Fail3;
-
- new_offset = GET_UShort() + base_offset;
-
- FORGET_Frame();
-
- cur_offset = FILE_Pos();
- if ( FILE_Seek( new_offset ) ||
- ( error = _HB_OPEN_Load_Coverage( &i[ni], stream ) ) != HB_Err_Ok )
- goto Fail3;
- (void)FILE_Seek( cur_offset );
- }
-
- if ( ACCESS_Frame( 2L ) )
- goto Fail3;
-
- ccpf3->LookaheadGlyphCount = GET_UShort();
-
- FORGET_Frame();
-
- ccpf3->LookaheadCoverage = NULL;
-
- lookahead_count = ccpf3->LookaheadGlyphCount;
-
- if ( ALLOC_ARRAY( ccpf3->LookaheadCoverage, lookahead_count,
- HB_Coverage ) )
- goto Fail3;
-
- l = ccpf3->LookaheadCoverage;
-
- for ( nl = 0; nl < lookahead_count; nl++ )
- {
- if ( ACCESS_Frame( 2L ) )
- goto Fail2;
-
- new_offset = GET_UShort() + base_offset;
-
- FORGET_Frame();
-
- cur_offset = FILE_Pos();
- if ( FILE_Seek( new_offset ) ||
- ( error = _HB_OPEN_Load_Coverage( &l[nl], stream ) ) != HB_Err_Ok )
- goto Fail2;
- (void)FILE_Seek( cur_offset );
- }
-
- if ( ACCESS_Frame( 2L ) )
- goto Fail2;
-
- ccpf3->PosCount = GET_UShort();
-
- FORGET_Frame();
-
- ccpf3->PosLookupRecord = NULL;
-
- count = ccpf3->PosCount;
-
- if ( ALLOC_ARRAY( ccpf3->PosLookupRecord, count, HB_PosLookupRecord ) )
- goto Fail2;
-
- plr = ccpf3->PosLookupRecord;
-
- if ( ACCESS_Frame( count * 4L ) )
- goto Fail1;
-
- for ( n = 0; n < count; n++ )
- {
- plr[n].SequenceIndex = GET_UShort();
- plr[n].LookupListIndex = GET_UShort();
- }
-
- FORGET_Frame();
-
- return HB_Err_Ok;
-
-Fail1:
- FREE( plr );
-
-Fail2:
- for ( m = 0; m < nl; m++ )
- _HB_OPEN_Free_Coverage( &l[m] );
-
- FREE( l );
-
-Fail3:
- for ( m = 0; m < ni; m++ )
- _HB_OPEN_Free_Coverage( &i[m] );
-
- FREE( i );
-
-Fail4:
- for ( m = 0; m < nb; m++ )
- _HB_OPEN_Free_Coverage( &b[m] );
-
- FREE( b );
- return error;
-}
-
-
-static void Free_ChainContextPos3( HB_ChainContextPosFormat3* ccpf3 )
-{
- HB_UShort n, count;
-
- HB_Coverage* c;
-
-
- FREE( ccpf3->PosLookupRecord );
-
- if ( ccpf3->LookaheadCoverage )
- {
- count = ccpf3->LookaheadGlyphCount;
- c = ccpf3->LookaheadCoverage;
-
- for ( n = 0; n < count; n++ )
- _HB_OPEN_Free_Coverage( &c[n] );
-
- FREE( c );
- }
-
- if ( ccpf3->InputCoverage )
- {
- count = ccpf3->InputGlyphCount;
- c = ccpf3->InputCoverage;
-
- for ( n = 0; n < count; n++ )
- _HB_OPEN_Free_Coverage( &c[n] );
-
- FREE( c );
- }
-
- if ( ccpf3->BacktrackCoverage )
- {
- count = ccpf3->BacktrackGlyphCount;
- c = ccpf3->BacktrackCoverage;
-
- for ( n = 0; n < count; n++ )
- _HB_OPEN_Free_Coverage( &c[n] );
-
- FREE( c );
- }
-}
-
-
-/* ChainContextPos */
-
-static HB_Error Load_ChainContextPos( HB_GPOS_SubTable* st,
- HB_Stream stream )
-{
- HB_Error error;
- HB_ChainContextPos* ccp = &st->chain;
-
-
- if ( ACCESS_Frame( 2L ) )
- return error;
-
- ccp->PosFormat = GET_UShort();
-
- FORGET_Frame();
-
- switch ( ccp->PosFormat )
- {
- case 1:
- return Load_ChainContextPos1( &ccp->ccpf.ccpf1, stream );
-
- case 2:
- return Load_ChainContextPos2( &ccp->ccpf.ccpf2, stream );
-
- case 3:
- return Load_ChainContextPos3( &ccp->ccpf.ccpf3, stream );
-
- default:
- return ERR(HB_Err_Invalid_SubTable_Format);
- }
-
- return HB_Err_Ok; /* never reached */
-}
-
-
-static void Free_ChainContextPos( HB_GPOS_SubTable* st )
-{
- HB_ChainContextPos* ccp = &st->chain;
-
- switch ( ccp->PosFormat )
- {
- case 1: Free_ChainContextPos1( &ccp->ccpf.ccpf1 ); break;
- case 2: Free_ChainContextPos2( &ccp->ccpf.ccpf2 ); break;
- case 3: Free_ChainContextPos3( &ccp->ccpf.ccpf3 ); break;
- default: break;
- }
-}
-
-
-static HB_Error Lookup_ChainContextPos1(
- GPOS_Instance* gpi,
- HB_ChainContextPosFormat1* ccpf1,
- HB_Buffer buffer,
- HB_UShort flags,
- HB_UShort context_length,
- int nesting_level )
-{
- HB_UShort index, property;
- HB_UShort i, j, k, num_cpr;
- HB_UShort bgc, igc, lgc;
- HB_Error error;
- HB_GPOSHeader* gpos = gpi->gpos;
-
- HB_ChainPosRule* cpr;
- HB_ChainPosRule curr_cpr;
- HB_GDEFHeader* gdef;
-
-
- gdef = gpos->gdef;
-
- if ( CHECK_Property( gdef, IN_CURITEM(), flags, &property ) )
- return error;
-
- error = _HB_OPEN_Coverage_Index( &ccpf1->Coverage, IN_CURGLYPH(), &index );
- if ( error )
- return error;
-
- cpr = ccpf1->ChainPosRuleSet[index].ChainPosRule;
- num_cpr = ccpf1->ChainPosRuleSet[index].ChainPosRuleCount;
-
- for ( k = 0; k < num_cpr; k++ )
- {
- curr_cpr = cpr[k];
- bgc = curr_cpr.BacktrackGlyphCount;
- igc = curr_cpr.InputGlyphCount;
- lgc = curr_cpr.LookaheadGlyphCount;
-
- if ( context_length != 0xFFFF && context_length < igc )
- goto next_chainposrule;
-
- /* check whether context is too long; it is a first guess only */
-
- if ( bgc > buffer->in_pos || buffer->in_pos + igc + lgc > buffer->in_length )
- goto next_chainposrule;
-
- if ( bgc )
- {
- /* Since we don't know in advance the number of glyphs to inspect,
- we search backwards for matches in the backtrack glyph array */
-
- for ( i = 0, j = buffer->in_pos - 1; i < bgc; i++, j-- )
- {
- while ( CHECK_Property( gdef, IN_ITEM( j ), flags, &property ) )
- {
- if ( error && error != HB_Err_Not_Covered )
- return error;
-
- if ( j + 1 == bgc - i )
- goto next_chainposrule;
- j--;
- }
-
- /* In OpenType 1.3, it is undefined whether the offsets of
- backtrack glyphs is in logical order or not. Version 1.4
- will clarify this:
-
- Logical order - a b c d e f g h i j
- i
- Input offsets - 0 1
- Backtrack offsets - 3 2 1 0
- Lookahead offsets - 0 1 2 3 */
-
- if ( IN_GLYPH( j ) != curr_cpr.Backtrack[i] )
- goto next_chainposrule;
- }
- }
-
- /* Start at 1 because [0] is implied */
-
- for ( i = 1, j = buffer->in_pos + 1; i < igc; i++, j++ )
- {
- while ( CHECK_Property( gdef, IN_ITEM( j ), flags, &property ) )
- {
- if ( error && error != HB_Err_Not_Covered )
- return error;
-
- if ( j + igc - i + lgc == (HB_Int)buffer->in_length )
- goto next_chainposrule;
- j++;
- }
-
- if ( IN_GLYPH( j ) != curr_cpr.Input[i - 1] )
- goto next_chainposrule;
- }
-
- /* we are starting to check for lookahead glyphs right after the
- last context glyph */
-
- for ( i = 0; i < lgc; i++, j++ )
- {
- while ( CHECK_Property( gdef, IN_ITEM( j ), flags, &property ) )
- {
- if ( error && error != HB_Err_Not_Covered )
- return error;
-
- if ( j + lgc - i == (HB_Int)buffer->in_length )
- goto next_chainposrule;
- j++;
- }
-
- if ( IN_GLYPH( j ) != curr_cpr.Lookahead[i] )
- goto next_chainposrule;
- }
-
- return Do_ContextPos( gpi, igc,
- curr_cpr.PosCount,
- curr_cpr.PosLookupRecord,
- buffer,
- nesting_level );
-
- next_chainposrule:
- ;
- }
-
- return HB_Err_Not_Covered;
-}
-
-
-static HB_Error Lookup_ChainContextPos2(
- GPOS_Instance* gpi,
- HB_ChainContextPosFormat2* ccpf2,
- HB_Buffer buffer,
- HB_UShort flags,
- HB_UShort context_length,
- int nesting_level )
-{
- HB_UShort index, property;
- HB_Error error;
- HB_UShort i, j, k;
- HB_UShort bgc, igc, lgc;
- HB_UShort known_backtrack_classes,
- known_input_classes,
- known_lookahead_classes;
-
- HB_UShort* backtrack_classes;
- HB_UShort* input_classes;
- HB_UShort* lookahead_classes;
-
- HB_UShort* bc;
- HB_UShort* ic;
- HB_UShort* lc;
- HB_GPOSHeader* gpos = gpi->gpos;
-
- HB_ChainPosClassSet* cpcs;
- HB_ChainPosClassRule cpcr;
- HB_GDEFHeader* gdef;
-
-
- gdef = gpos->gdef;
-
- if ( CHECK_Property( gdef, IN_CURITEM(), flags, &property ) )
- return error;
-
- /* Note: The coverage table in format 2 doesn't give an index into
- anything. It just lets us know whether or not we need to
- do any lookup at all. */
-
- error = _HB_OPEN_Coverage_Index( &ccpf2->Coverage, IN_CURGLYPH(), &index );
- if ( error )
- return error;
-
- if (ccpf2->MaxInputLength < 1)
- return HB_Err_Not_Covered;
-
- if ( ALLOC_ARRAY( backtrack_classes, ccpf2->MaxBacktrackLength, HB_UShort ) )
- return error;
- known_backtrack_classes = 0;
-
- if ( ALLOC_ARRAY( input_classes, ccpf2->MaxInputLength, HB_UShort ) )
- goto End3;
- known_input_classes = 1;
-
- if ( ALLOC_ARRAY( lookahead_classes, ccpf2->MaxLookaheadLength, HB_UShort ) )
- goto End2;
- known_lookahead_classes = 0;
-
- error = _HB_OPEN_Get_Class( &ccpf2->InputClassDef, IN_CURGLYPH(),
- &input_classes[0], NULL );
- if ( error && error != HB_Err_Not_Covered )
- goto End1;
-
- cpcs = &ccpf2->ChainPosClassSet[input_classes[0]];
- if ( !cpcs )
- {
- error = ERR(HB_Err_Invalid_SubTable);
- goto End1;
- }
-
- for ( k = 0; k < cpcs->ChainPosClassRuleCount; k++ )
- {
- cpcr = cpcs->ChainPosClassRule[k];
- bgc = cpcr.BacktrackGlyphCount;
- igc = cpcr.InputGlyphCount;
- lgc = cpcr.LookaheadGlyphCount;
-
- if ( context_length != 0xFFFF && context_length < igc )
- goto next_chainposclassrule;
-
- /* check whether context is too long; it is a first guess only */
-
- if ( bgc > buffer->in_pos || buffer->in_pos + igc + lgc > buffer->in_length )
- goto next_chainposclassrule;
-
- if ( bgc )
- {
- /* Since we don't know in advance the number of glyphs to inspect,
- we search backwards for matches in the backtrack glyph array.
- Note that `known_backtrack_classes' starts at index 0. */
-
- bc = cpcr.Backtrack;
-
- for ( i = 0, j = buffer->in_pos - 1; i < bgc; i++, j-- )
- {
- while ( CHECK_Property( gdef, IN_ITEM( j ), flags, &property ) )
- {
- if ( error && error != HB_Err_Not_Covered )
- goto End1;
-
- if ( j + 1 == bgc - i )
- goto next_chainposclassrule;
- j++;
- }
-
- if ( i >= known_backtrack_classes )
- {
- /* Keeps us from having to do this for each rule */
-
- error = _HB_OPEN_Get_Class( &ccpf2->BacktrackClassDef, IN_GLYPH( j ),
- &backtrack_classes[i], NULL );
- if ( error && error != HB_Err_Not_Covered )
- goto End1;
- known_backtrack_classes = i;
- }
-
- if ( bc[i] != backtrack_classes[i] )
- goto next_chainposclassrule;
- }
- }
-
- ic = cpcr.Input;
-
- /* Start at 1 because [0] is implied */
-
- for ( i = 1, j = buffer->in_pos + 1; i < igc; i++, j++ )
- {
- while ( CHECK_Property( gdef, IN_ITEM( j ), flags, &property ) )
- {
- if ( error && error != HB_Err_Not_Covered )
- goto End1;
-
- if ( j + igc - i + lgc == (HB_Int)buffer->in_length )
- goto next_chainposclassrule;
- j++;
- }
-
- if ( i >= known_input_classes )
- {
- error = _HB_OPEN_Get_Class( &ccpf2->InputClassDef, IN_GLYPH( j ),
- &input_classes[i], NULL );
- if ( error && error != HB_Err_Not_Covered )
- goto End1;
- known_input_classes = i;
- }
-
- if ( ic[i - 1] != input_classes[i] )
- goto next_chainposclassrule;
- }
-
- /* we are starting to check for lookahead glyphs right after the
- last context glyph */
-
- lc = cpcr.Lookahead;
-
- for ( i = 0; i < lgc; i++, j++ )
- {
- while ( CHECK_Property( gdef, IN_ITEM( j ), flags, &property ) )
- {
- if ( error && error != HB_Err_Not_Covered )
- goto End1;
-
- if ( j + lgc - i == (HB_Int)buffer->in_length )
- goto next_chainposclassrule;
- j++;
- }
-
- if ( i >= known_lookahead_classes )
- {
- error = _HB_OPEN_Get_Class( &ccpf2->LookaheadClassDef, IN_GLYPH( j ),
- &lookahead_classes[i], NULL );
- if ( error && error != HB_Err_Not_Covered )
- goto End1;
- known_lookahead_classes = i;
- }
-
- if ( lc[i] != lookahead_classes[i] )
- goto next_chainposclassrule;
- }
-
- error = Do_ContextPos( gpi, igc,
- cpcr.PosCount,
- cpcr.PosLookupRecord,
- buffer,
- nesting_level );
- goto End1;
-
- next_chainposclassrule:
- ;
- }
-
- error = HB_Err_Not_Covered;
-
-End1:
- FREE( lookahead_classes );
-
-End2:
- FREE( input_classes );
-
-End3:
- FREE( backtrack_classes );
- return error;
-}
-
-
-static HB_Error Lookup_ChainContextPos3(
- GPOS_Instance* gpi,
- HB_ChainContextPosFormat3* ccpf3,
- HB_Buffer buffer,
- HB_UShort flags,
- HB_UShort context_length,
- int nesting_level )
-{
- HB_UShort index, i, j, property;
- HB_UShort bgc, igc, lgc;
- HB_Error error;
- HB_GPOSHeader* gpos = gpi->gpos;
-
- HB_Coverage* bc;
- HB_Coverage* ic;
- HB_Coverage* lc;
- HB_GDEFHeader* gdef;
-
-
- gdef = gpos->gdef;
-
- if ( CHECK_Property( gdef, IN_CURITEM(), flags, &property ) )
- return error;
-
- bgc = ccpf3->BacktrackGlyphCount;
- igc = ccpf3->InputGlyphCount;
- lgc = ccpf3->LookaheadGlyphCount;
-
- if ( context_length != 0xFFFF && context_length < igc )
- return HB_Err_Not_Covered;
-
- /* check whether context is too long; it is a first guess only */
-
- if ( bgc > buffer->in_pos || buffer->in_pos + igc + lgc > buffer->in_length )
- return HB_Err_Not_Covered;
-
- if ( bgc )
- {
- /* Since we don't know in advance the number of glyphs to inspect,
- we search backwards for matches in the backtrack glyph array */
-
- bc = ccpf3->BacktrackCoverage;
-
- for ( i = 0, j = buffer->in_pos - 1; i < bgc; i++, j-- )
- {
- while ( CHECK_Property( gdef, IN_ITEM( j ), flags, &property ) )
- {
- if ( error && error != HB_Err_Not_Covered )
- return error;
-
- if ( j + 1 == bgc - i )
- return HB_Err_Not_Covered;
- j--;
- }
-
- error = _HB_OPEN_Coverage_Index( &bc[i], IN_GLYPH( j ), &index );
- if ( error )
- return error;
- }
- }
-
- ic = ccpf3->InputCoverage;
-
- for ( i = 0, j = buffer->in_pos; i < igc; i++, j++ )
- {
- /* We already called CHECK_Property for IN_GLYPH ( buffer->in_pos ) */
- while ( j > buffer->in_pos && CHECK_Property( gdef, IN_ITEM( j ), flags, &property ) )
- {
- if ( error && error != HB_Err_Not_Covered )
- return error;
-
- if ( j + igc - i + lgc == (HB_Int)buffer->in_length )
- return HB_Err_Not_Covered;
- j++;
- }
-
- error = _HB_OPEN_Coverage_Index( &ic[i], IN_GLYPH( j ), &index );
- if ( error )
- return error;
- }
-
- /* we are starting to check for lookahead glyphs right after the
- last context glyph */
-
- lc = ccpf3->LookaheadCoverage;
-
- for ( i = 0; i < lgc; i++, j++ )
- {
- while ( CHECK_Property( gdef, IN_ITEM( j ), flags, &property ) )
- {
- if ( error && error != HB_Err_Not_Covered )
- return error;
-
- if ( j + lgc - i == (HB_Int)buffer->in_length )
- return HB_Err_Not_Covered;
- j++;
- }
-
- error = _HB_OPEN_Coverage_Index( &lc[i], IN_GLYPH( j ), &index );
- if ( error )
- return error;
- }
-
- return Do_ContextPos( gpi, igc,
- ccpf3->PosCount,
- ccpf3->PosLookupRecord,
- buffer,
- nesting_level );
-}
-
-
-static HB_Error Lookup_ChainContextPos(
- GPOS_Instance* gpi,
- HB_GPOS_SubTable* st,
- HB_Buffer buffer,
- HB_UShort flags,
- HB_UShort context_length,
- int nesting_level )
-{
- HB_ChainContextPos* ccp = &st->chain;
-
- switch ( ccp->PosFormat )
- {
- case 1:
- return Lookup_ChainContextPos1( gpi, &ccp->ccpf.ccpf1, buffer,
- flags, context_length,
- nesting_level );
-
- case 2:
- return Lookup_ChainContextPos2( gpi, &ccp->ccpf.ccpf2, buffer,
- flags, context_length,
- nesting_level );
-
- case 3:
- return Lookup_ChainContextPos3( gpi, &ccp->ccpf.ccpf3, buffer,
- flags, context_length,
- nesting_level );
-
- default:
- return ERR(HB_Err_Invalid_SubTable_Format);
- }
-
- return HB_Err_Ok; /* never reached */
-}
-
-
-
-/***********
- * GPOS API
- ***********/
-
-
-
-HB_Error HB_GPOS_Select_Script( HB_GPOSHeader* gpos,
- HB_UInt script_tag,
- HB_UShort* script_index )
-{
- HB_UShort n;
-
- HB_ScriptList* sl;
- HB_ScriptRecord* sr;
-
-
- if ( !gpos || !script_index )
- return ERR(HB_Err_Invalid_Argument);
-
- sl = &gpos->ScriptList;
- sr = sl->ScriptRecord;
-
- for ( n = 0; n < sl->ScriptCount; n++ )
- if ( script_tag == sr[n].ScriptTag )
- {
- *script_index = n;
-
- return HB_Err_Ok;
- }
-
- return HB_Err_Not_Covered;
-}
-
-
-
-HB_Error HB_GPOS_Select_Language( HB_GPOSHeader* gpos,
- HB_UInt language_tag,
- HB_UShort script_index,
- HB_UShort* language_index,
- HB_UShort* req_feature_index )
-{
- HB_UShort n;
-
- HB_ScriptList* sl;
- HB_ScriptRecord* sr;
- HB_ScriptTable* s;
- HB_LangSysRecord* lsr;
-
-
- if ( !gpos || !language_index || !req_feature_index )
- return ERR(HB_Err_Invalid_Argument);
-
- sl = &gpos->ScriptList;
- sr = sl->ScriptRecord;
-
- if ( script_index >= sl->ScriptCount )
- return ERR(HB_Err_Invalid_Argument);
-
- s = &sr[script_index].Script;
- lsr = s->LangSysRecord;
-
- for ( n = 0; n < s->LangSysCount; n++ )
- if ( language_tag == lsr[n].LangSysTag )
- {
- *language_index = n;
- *req_feature_index = lsr[n].LangSys.ReqFeatureIndex;
-
- return HB_Err_Ok;
- }
-
- return HB_Err_Not_Covered;
-}
-
-
-/* selecting 0xFFFF for language_index asks for the values of the
- default language (DefaultLangSys) */
-
-
-HB_Error HB_GPOS_Select_Feature( HB_GPOSHeader* gpos,
- HB_UInt feature_tag,
- HB_UShort script_index,
- HB_UShort language_index,
- HB_UShort* feature_index )
-{
- HB_UShort n;
-
- HB_ScriptList* sl;
- HB_ScriptRecord* sr;
- HB_ScriptTable* s;
- HB_LangSysRecord* lsr;
- HB_LangSys* ls;
- HB_UShort* fi;
-
- HB_FeatureList* fl;
- HB_FeatureRecord* fr;
-
-
- if ( !gpos || !feature_index )
- return ERR(HB_Err_Invalid_Argument);
-
- sl = &gpos->ScriptList;
- sr = sl->ScriptRecord;
-
- fl = &gpos->FeatureList;
- fr = fl->FeatureRecord;
-
- if ( script_index >= sl->ScriptCount )
- return ERR(HB_Err_Invalid_Argument);
-
- s = &sr[script_index].Script;
- lsr = s->LangSysRecord;
-
- if ( language_index == 0xFFFF )
- ls = &s->DefaultLangSys;
- else
- {
- if ( language_index >= s->LangSysCount )
- return ERR(HB_Err_Invalid_Argument);
-
- ls = &lsr[language_index].LangSys;
- }
-
- fi = ls->FeatureIndex;
-
- for ( n = 0; n < ls->FeatureCount; n++ )
- {
- if ( fi[n] >= fl->FeatureCount )
- return ERR(HB_Err_Invalid_SubTable_Format);
-
- if ( feature_tag == fr[fi[n]].FeatureTag )
- {
- *feature_index = fi[n];
-
- return HB_Err_Ok;
- }
- }
-
- return HB_Err_Not_Covered;
-}
-
-
-/* The next three functions return a null-terminated list */
-
-
-HB_Error HB_GPOS_Query_Scripts( HB_GPOSHeader* gpos,
- HB_UInt** script_tag_list )
-{
- HB_Error error;
- HB_UShort n;
- HB_UInt* stl;
-
- HB_ScriptList* sl;
- HB_ScriptRecord* sr;
-
-
- if ( !gpos || !script_tag_list )
- return ERR(HB_Err_Invalid_Argument);
-
- sl = &gpos->ScriptList;
- sr = sl->ScriptRecord;
-
- if ( ALLOC_ARRAY( stl, sl->ScriptCount + 1, HB_UInt ) )
- return error;
-
- for ( n = 0; n < sl->ScriptCount; n++ )
- stl[n] = sr[n].ScriptTag;
- stl[n] = 0;
-
- *script_tag_list = stl;
-
- return HB_Err_Ok;
-}
-
-
-
-HB_Error HB_GPOS_Query_Languages( HB_GPOSHeader* gpos,
- HB_UShort script_index,
- HB_UInt** language_tag_list )
-{
- HB_Error error;
- HB_UShort n;
- HB_UInt* ltl;
-
- HB_ScriptList* sl;
- HB_ScriptRecord* sr;
- HB_ScriptTable* s;
- HB_LangSysRecord* lsr;
-
-
- if ( !gpos || !language_tag_list )
- return ERR(HB_Err_Invalid_Argument);
-
- sl = &gpos->ScriptList;
- sr = sl->ScriptRecord;
-
- if ( script_index >= sl->ScriptCount )
- return ERR(HB_Err_Invalid_Argument);
-
- s = &sr[script_index].Script;
- lsr = s->LangSysRecord;
-
- if ( ALLOC_ARRAY( ltl, s->LangSysCount + 1, HB_UInt ) )
- return error;
-
- for ( n = 0; n < s->LangSysCount; n++ )
- ltl[n] = lsr[n].LangSysTag;
- ltl[n] = 0;
-
- *language_tag_list = ltl;
-
- return HB_Err_Ok;
-}
-
-
-/* selecting 0xFFFF for language_index asks for the values of the
- default language (DefaultLangSys) */
-
-
-HB_Error HB_GPOS_Query_Features( HB_GPOSHeader* gpos,
- HB_UShort script_index,
- HB_UShort language_index,
- HB_UInt** feature_tag_list )
-{
- HB_UShort n;
- HB_Error error;
- HB_UInt* ftl;
-
- HB_ScriptList* sl;
- HB_ScriptRecord* sr;
- HB_ScriptTable* s;
- HB_LangSysRecord* lsr;
- HB_LangSys* ls;
- HB_UShort* fi;
-
- HB_FeatureList* fl;
- HB_FeatureRecord* fr;
-
-
- if ( !gpos || !feature_tag_list )
- return ERR(HB_Err_Invalid_Argument);
-
- sl = &gpos->ScriptList;
- sr = sl->ScriptRecord;
-
- fl = &gpos->FeatureList;
- fr = fl->FeatureRecord;
-
- if ( script_index >= sl->ScriptCount )
- return ERR(HB_Err_Invalid_Argument);
-
- s = &sr[script_index].Script;
- lsr = s->LangSysRecord;
-
- if ( language_index == 0xFFFF )
- ls = &s->DefaultLangSys;
- else
- {
- if ( language_index >= s->LangSysCount )
- return ERR(HB_Err_Invalid_Argument);
-
- ls = &lsr[language_index].LangSys;
- }
-
- fi = ls->FeatureIndex;
-
- if ( ALLOC_ARRAY( ftl, ls->FeatureCount + 1, HB_UInt ) )
- return error;
-
- for ( n = 0; n < ls->FeatureCount; n++ )
- {
- if ( fi[n] >= fl->FeatureCount )
- {
- FREE( ftl );
- return ERR(HB_Err_Invalid_SubTable_Format);
- }
- ftl[n] = fr[fi[n]].FeatureTag;
- }
- ftl[n] = 0;
-
- *feature_tag_list = ftl;
-
- return HB_Err_Ok;
-}
-
-
-/* Do an individual subtable lookup. Returns HB_Err_Ok if positioning
- has been done, or HB_Err_Not_Covered if not. */
-static HB_Error GPOS_Do_Glyph_Lookup( GPOS_Instance* gpi,
- HB_UShort lookup_index,
- HB_Buffer buffer,
- HB_UShort context_length,
- int nesting_level )
-{
- HB_Error error = HB_Err_Not_Covered;
- HB_UShort i, flags, lookup_count;
- HB_GPOSHeader* gpos = gpi->gpos;
- HB_Lookup* lo;
- int lookup_type;
-
-
- nesting_level++;
-
- if ( nesting_level > HB_MAX_NESTING_LEVEL )
- return ERR(HB_Err_Not_Covered); /* ERR() call intended */
-
- lookup_count = gpos->LookupList.LookupCount;
- if (lookup_index >= lookup_count)
- return error;
-
- lo = &gpos->LookupList.Lookup[lookup_index];
- flags = lo->LookupFlag;
- lookup_type = lo->LookupType;
-
- for ( i = 0; i < lo->SubTableCount; i++ )
- {
- HB_GPOS_SubTable *st = &lo->SubTable[i].st.gpos;
-
- switch (lookup_type) {
- case HB_GPOS_LOOKUP_SINGLE:
- error = Lookup_SinglePos ( gpi, st, buffer, flags, context_length, nesting_level ); break;
- case HB_GPOS_LOOKUP_PAIR:
- error = Lookup_PairPos ( gpi, st, buffer, flags, context_length, nesting_level ); break;
- case HB_GPOS_LOOKUP_CURSIVE:
- error = Lookup_CursivePos ( gpi, st, buffer, flags, context_length, nesting_level ); break;
- case HB_GPOS_LOOKUP_MARKBASE:
- error = Lookup_MarkBasePos ( gpi, st, buffer, flags, context_length, nesting_level ); break;
- case HB_GPOS_LOOKUP_MARKLIG:
- error = Lookup_MarkLigPos ( gpi, st, buffer, flags, context_length, nesting_level ); break;
- case HB_GPOS_LOOKUP_MARKMARK:
- error = Lookup_MarkMarkPos ( gpi, st, buffer, flags, context_length, nesting_level ); break;
- case HB_GPOS_LOOKUP_CONTEXT:
- error = Lookup_ContextPos ( gpi, st, buffer, flags, context_length, nesting_level ); break;
- case HB_GPOS_LOOKUP_CHAIN:
- error = Lookup_ChainContextPos ( gpi, st, buffer, flags, context_length, nesting_level ); break;
- /*case HB_GPOS_LOOKUP_EXTENSION:
- error = Lookup_ExtensionPos ( gpi, st, buffer, flags, context_length, nesting_level ); break;*/
- default:
- error = HB_Err_Not_Covered;
- }
-
- /* Check whether we have a successful positioning or an error other
- than HB_Err_Not_Covered */
- if ( error != HB_Err_Not_Covered )
- return error;
- }
-
- return HB_Err_Not_Covered;
-}
-
-
-HB_INTERNAL HB_Error
-_HB_GPOS_Load_SubTable( HB_GPOS_SubTable* st,
- HB_Stream stream,
- HB_UShort lookup_type )
-{
- switch ( lookup_type ) {
- case HB_GPOS_LOOKUP_SINGLE: return Load_SinglePos ( st, stream );
- case HB_GPOS_LOOKUP_PAIR: return Load_PairPos ( st, stream );
- case HB_GPOS_LOOKUP_CURSIVE: return Load_CursivePos ( st, stream );
- case HB_GPOS_LOOKUP_MARKBASE: return Load_MarkBasePos ( st, stream );
- case HB_GPOS_LOOKUP_MARKLIG: return Load_MarkLigPos ( st, stream );
- case HB_GPOS_LOOKUP_MARKMARK: return Load_MarkMarkPos ( st, stream );
- case HB_GPOS_LOOKUP_CONTEXT: return Load_ContextPos ( st, stream );
- case HB_GPOS_LOOKUP_CHAIN: return Load_ChainContextPos ( st, stream );
- /*case HB_GPOS_LOOKUP_EXTENSION: return Load_ExtensionPos ( st, stream );*/
- default: return ERR(HB_Err_Invalid_SubTable_Format);
- }
-}
-
-
-HB_INTERNAL void
-_HB_GPOS_Free_SubTable( HB_GPOS_SubTable* st,
- HB_UShort lookup_type )
-{
- switch ( lookup_type ) {
- case HB_GPOS_LOOKUP_SINGLE: Free_SinglePos ( st ); return;
- case HB_GPOS_LOOKUP_PAIR: Free_PairPos ( st ); return;
- case HB_GPOS_LOOKUP_CURSIVE: Free_CursivePos ( st ); return;
- case HB_GPOS_LOOKUP_MARKBASE: Free_MarkBasePos ( st ); return;
- case HB_GPOS_LOOKUP_MARKLIG: Free_MarkLigPos ( st ); return;
- case HB_GPOS_LOOKUP_MARKMARK: Free_MarkMarkPos ( st ); return;
- case HB_GPOS_LOOKUP_CONTEXT: Free_ContextPos ( st ); return;
- case HB_GPOS_LOOKUP_CHAIN: Free_ChainContextPos ( st ); return;
- /*case HB_GPOS_LOOKUP_EXTENSION: Free_ExtensionPos ( st ); return;*/
- default: return;
- }
-}
-
-
-/* apply one lookup to the input string object */
-
-static HB_Error GPOS_Do_String_Lookup( GPOS_Instance* gpi,
- HB_UShort lookup_index,
- HB_Buffer buffer )
-{
- HB_Error error, retError = HB_Err_Not_Covered;
- HB_GPOSHeader* gpos = gpi->gpos;
-
- HB_UInt* properties = gpos->LookupList.Properties;
-
- const int nesting_level = 0;
- /* 0xFFFF indicates that we don't have a context length yet */
- const HB_UShort context_length = 0xFFFF;
-
-
- gpi->last = 0xFFFF; /* no last valid glyph for cursive pos. */
-
- buffer->in_pos = 0;
- while ( buffer->in_pos < buffer->in_length )
- {
- if ( ~IN_PROPERTIES( buffer->in_pos ) & properties[lookup_index] )
- {
- /* Note that the connection between mark and base glyphs hold
- exactly one (string) lookup. For example, it would be possible
- that in the first lookup, mark glyph X is attached to base
- glyph A, and in the next lookup it is attached to base glyph B.
- It is up to the font designer to provide meaningful lookups and
- lookup order. */
-
- error = GPOS_Do_Glyph_Lookup( gpi, lookup_index, buffer, context_length, nesting_level );
- if ( error && error != HB_Err_Not_Covered )
- return error;
- }
- else
- {
- /* Contrary to properties defined in GDEF, user-defined properties
- will always stop a possible cursive positioning. */
- gpi->last = 0xFFFF;
-
- error = HB_Err_Not_Covered;
- }
-
- if ( error == HB_Err_Not_Covered )
- (buffer->in_pos)++;
- else
- retError = error;
- }
-
- return retError;
-}
-
-
-static HB_Error Position_CursiveChain ( HB_Buffer buffer )
-{
- HB_UInt i, j;
- HB_Position positions = buffer->positions;
-
- /* First handle all left-to-right connections */
- for (j = 0; j < buffer->in_length; j++)
- {
- if (positions[j].cursive_chain > 0)
- positions[j].y_pos += positions[j - positions[j].cursive_chain].y_pos;
- }
-
- /* Then handle all right-to-left connections */
- for (i = buffer->in_length; i > 0; i--)
- {
- j = i - 1;
-
- if (positions[j].cursive_chain < 0)
- positions[j].y_pos += positions[j - positions[j].cursive_chain].y_pos;
- }
-
- return HB_Err_Ok;
-}
-
-
-HB_Error HB_GPOS_Add_Feature( HB_GPOSHeader* gpos,
- HB_UShort feature_index,
- HB_UInt property )
-{
- HB_UShort i;
-
- HB_Feature feature;
- HB_UInt* properties;
- HB_UShort* index;
- HB_UShort lookup_count;
-
- /* Each feature can only be added once */
-
- if ( !gpos ||
- feature_index >= gpos->FeatureList.FeatureCount ||
- gpos->FeatureList.ApplyCount == gpos->FeatureList.FeatureCount )
- return ERR(HB_Err_Invalid_Argument);
-
- gpos->FeatureList.ApplyOrder[gpos->FeatureList.ApplyCount++] = feature_index;
-
- properties = gpos->LookupList.Properties;
-
- feature = gpos->FeatureList.FeatureRecord[feature_index].Feature;
- index = feature.LookupListIndex;
- lookup_count = gpos->LookupList.LookupCount;
-
- for ( i = 0; i < feature.LookupListCount; i++ )
- {
- HB_UShort lookup_index = index[i];
- if (lookup_index < lookup_count)
- properties[lookup_index] |= property;
- }
-
- return HB_Err_Ok;
-}
-
-
-
-HB_Error HB_GPOS_Clear_Features( HB_GPOSHeader* gpos )
-{
- HB_UShort i;
-
- HB_UInt* properties;
-
-
- if ( !gpos )
- return ERR(HB_Err_Invalid_Argument);
-
- gpos->FeatureList.ApplyCount = 0;
-
- properties = gpos->LookupList.Properties;
-
- for ( i = 0; i < gpos->LookupList.LookupCount; i++ )
- properties[i] = 0;
-
- return HB_Err_Ok;
-}
-
-#ifdef HB_SUPPORT_MULTIPLE_MASTER
-HB_Error HB_GPOS_Register_MM_Function( HB_GPOSHeader* gpos,
- HB_MMFunction mmfunc,
- void* data )
-{
- if ( !gpos )
- return ERR(HB_Err_Invalid_Argument);
-
- gpos->mmfunc = mmfunc;
- gpos->data = data;
-
- return HB_Err_Ok;
-}
-#endif
-
-/* If `dvi' is TRUE, glyph contour points for anchor points and device
- tables are ignored -- you will get device independent values. */
-
-
-HB_Error HB_GPOS_Apply_String( HB_Font font,
- HB_GPOSHeader* gpos,
- HB_UShort load_flags,
- HB_Buffer buffer,
- HB_Bool dvi,
- HB_Bool r2l )
-{
- HB_Error error, retError = HB_Err_Not_Covered;
- GPOS_Instance gpi;
- int i, j, lookup_count, num_features;
-
- if ( !font || !gpos || !buffer )
- return ERR(HB_Err_Invalid_Argument);
-
- if ( buffer->in_length == 0 )
- return HB_Err_Not_Covered;
-
- gpi.font = font;
- gpi.gpos = gpos;
- gpi.load_flags = load_flags;
- gpi.r2l = r2l;
- gpi.dvi = dvi;
-
- lookup_count = gpos->LookupList.LookupCount;
- num_features = gpos->FeatureList.ApplyCount;
-
- if ( num_features )
- {
- error = _hb_buffer_clear_positions( buffer );
- if ( error )
- return error;
- }
-
- for ( i = 0; i < num_features; i++ )
- {
- HB_UShort feature_index = gpos->FeatureList.ApplyOrder[i];
- HB_Feature feature = gpos->FeatureList.FeatureRecord[feature_index].Feature;
-
- for ( j = 0; j < feature.LookupListCount; j++ )
- {
- HB_UShort lookup_index = feature.LookupListIndex[j];
-
- /* Skip nonexistant lookups */
- if (lookup_index >= lookup_count)
- continue;
-
- error = GPOS_Do_String_Lookup( &gpi, lookup_index, buffer );
- if ( error )
- {
- if ( error != HB_Err_Not_Covered )
- return error;
- }
- else
- retError = error;
- }
- }
-
- if ( num_features )
- {
- error = Position_CursiveChain ( buffer );
- if ( error )
- return error;
- }
-
- return retError;
-}
-
-/* END */
diff --git a/src/3rdparty/harfbuzz/src/harfbuzz-gpos.h b/src/3rdparty/harfbuzz/src/harfbuzz-gpos.h
deleted file mode 100644
index 92bff84a94..0000000000
--- a/src/3rdparty/harfbuzz/src/harfbuzz-gpos.h
+++ /dev/null
@@ -1,155 +0,0 @@
-/*
- * Copyright (C) 1998-2004 David Turner and Werner Lemberg
- * Copyright (C) 2006 Behdad Esfahbod
- *
- * This is part of HarfBuzz, an OpenType Layout engine 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 HARFBUZZ_GPOS_H
-#define HARFBUZZ_GPOS_H
-
-#include "harfbuzz-gdef.h"
-#include "harfbuzz-buffer.h"
-
-HB_BEGIN_HEADER
-
-
-/* Lookup types for glyph positioning */
-
-#define HB_GPOS_LOOKUP_SINGLE 1
-#define HB_GPOS_LOOKUP_PAIR 2
-#define HB_GPOS_LOOKUP_CURSIVE 3
-#define HB_GPOS_LOOKUP_MARKBASE 4
-#define HB_GPOS_LOOKUP_MARKLIG 5
-#define HB_GPOS_LOOKUP_MARKMARK 6
-#define HB_GPOS_LOOKUP_CONTEXT 7
-#define HB_GPOS_LOOKUP_CHAIN 8
-#define HB_GPOS_LOOKUP_EXTENSION 9
-
-#ifdef HB_SUPPORT_MULTIPLE_MASTER
-/* A pointer to a function which accesses the PostScript interpreter.
- Multiple Master fonts need this interface to convert a metric ID
- (as stored in an OpenType font version 1.2 or higher) `metric_id'
- into a metric value (returned in `metric_value').
-
- `data' points to the user-defined structure specified during a
- call to HB_GPOS_Register_MM_Function().
-
- `metric_value' must be returned as a scaled value (but shouldn't
- be rounded). */
-
-typedef HB_Error (*HB_MMFunction)(HB_Font font,
- HB_UShort metric_id,
- HB_Fixed* metric_value,
- void* data );
-#endif
-
-
-struct HB_GPOSHeader_
-{
- HB_16Dot16 Version;
-
- HB_ScriptList ScriptList;
- HB_FeatureList FeatureList;
- HB_LookupList LookupList;
-
- HB_GDEFHeader* gdef;
-
-#ifdef HB_SUPPORT_MULTIPLE_MASTER
- /* this is OpenType 1.2 -- Multiple Master fonts need this
- callback function to get various metric values from the
- PostScript interpreter. */
-
- HB_MMFunction mmfunc;
- void* data;
-#endif
-};
-
-typedef struct HB_GPOSHeader_ HB_GPOSHeader;
-typedef HB_GPOSHeader* HB_GPOS;
-
-
-HB_Error HB_Load_GPOS_Table( HB_Stream stream,
- HB_GPOSHeader** gpos,
- HB_GDEFHeader* gdef,
- HB_Stream gdefStream );
-
-
-HB_Error HB_Done_GPOS_Table( HB_GPOSHeader* gpos );
-
-
-HB_Error HB_GPOS_Select_Script( HB_GPOSHeader* gpos,
- HB_UInt script_tag,
- HB_UShort* script_index );
-
-HB_Error HB_GPOS_Select_Language( HB_GPOSHeader* gpos,
- HB_UInt language_tag,
- HB_UShort script_index,
- HB_UShort* language_index,
- HB_UShort* req_feature_index );
-
-HB_Error HB_GPOS_Select_Feature( HB_GPOSHeader* gpos,
- HB_UInt feature_tag,
- HB_UShort script_index,
- HB_UShort language_index,
- HB_UShort* feature_index );
-
-
-HB_Error HB_GPOS_Query_Scripts( HB_GPOSHeader* gpos,
- HB_UInt** script_tag_list );
-
-HB_Error HB_GPOS_Query_Languages( HB_GPOSHeader* gpos,
- HB_UShort script_index,
- HB_UInt** language_tag_list );
-
-HB_Error HB_GPOS_Query_Features( HB_GPOSHeader* gpos,
- HB_UShort script_index,
- HB_UShort language_index,
- HB_UInt** feature_tag_list );
-
-
-HB_Error HB_GPOS_Add_Feature( HB_GPOSHeader* gpos,
- HB_UShort feature_index,
- HB_UInt property );
-
-HB_Error HB_GPOS_Clear_Features( HB_GPOSHeader* gpos );
-
-
-#ifdef HB_SUPPORT_MULTIPLE_MASTER
-HB_Error HB_GPOS_Register_MM_Function( HB_GPOSHeader* gpos,
- HB_MMFunction mmfunc,
- void* data );
-#endif
-
-/* If `dvi' is TRUE, glyph contour points for anchor points and device
- tables are ignored -- you will get device independent values. */
-
-
-HB_Error HB_GPOS_Apply_String( HB_Font font,
- HB_GPOSHeader* gpos,
- HB_UShort load_flags,
- HB_Buffer buffer,
- HB_Bool dvi,
- HB_Bool r2l );
-
-HB_END_HEADER
-
-#endif /* HARFBUZZ_GPOS_H */
diff --git a/src/3rdparty/harfbuzz/src/harfbuzz-greek.c b/src/3rdparty/harfbuzz/src/harfbuzz-greek.c
deleted file mode 100644
index 05ee06cdeb..0000000000
--- a/src/3rdparty/harfbuzz/src/harfbuzz-greek.c
+++ /dev/null
@@ -1,451 +0,0 @@
-/*
- * Copyright (C) 2015 The Qt Company Ltd
- *
- * This is part of HarfBuzz, an OpenType Layout engine library.
- *
- * Permission is hereby granted, without written agreement and without
- * license or royalty fees, to use, copy, modify, and distribute this
- * software and its documentation for any purpose, provided that the
- * above copyright notice and the following two paragraphs appear in
- * all copies of this software.
- *
- * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
- * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
- * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
- * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
- * DAMAGE.
- *
- * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
- * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
- * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
- * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
- * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
- */
-
-#include "harfbuzz-shaper.h"
-#include "harfbuzz-shaper-private.h"
-#include <assert.h>
-
-#ifndef NO_OPENTYPE
-static const HB_OpenTypeFeature greek_features[] = {
- { HB_MAKE_TAG('c', 'c', 'm', 'p'), CcmpProperty },
- { HB_MAKE_TAG('l', 'i', 'g', 'a'), CcmpProperty },
- { HB_MAKE_TAG('c', 'l', 'i', 'g'), CcmpProperty },
- {0, 0}
-};
-#endif
-
-/*
- Greek decompositions
-*/
-
-
-typedef struct _hb_greek_decomposition {
- HB_UChar16 composed;
- HB_UChar16 base;
-} hb_greek_decomposition;
-
-static const hb_greek_decomposition decompose_0x300[] = {
- { 0x1FBA, 0x0391 },
- { 0x1FC8, 0x0395 },
- { 0x1FCA, 0x0397 },
- { 0x1FDA, 0x0399 },
- { 0x1FF8, 0x039F },
- { 0x1FEA, 0x03A5 },
- { 0x1FFA, 0x03A9 },
- { 0x1F70, 0x03B1 },
- { 0x1F72, 0x03B5 },
- { 0x1F74, 0x03B7 },
- { 0x1F76, 0x03B9 },
- { 0x1F78, 0x03BF },
- { 0x1F7A, 0x03C5 },
- { 0x1F7C, 0x03C9 },
- { 0x1FD2, 0x03CA },
- { 0x1FE2, 0x03CB },
- { 0x1F02, 0x1F00 },
- { 0, 0 }
-};
-
-static HB_UChar16 compose_0x300(HB_UChar16 base)
-{
- if ((base ^ 0x1f00) < 0x100) {
- if (base <= 0x1f69 && !(base & 0x6))
- return base + 2;
- if (base == 0x1fbf)
- return 0x1fcd;
- if (base == 0x1ffe)
- return 0x1fdd;
- return 0;
- }
- {
- const hb_greek_decomposition *d = decompose_0x300;
- while (d->base && d->base != base)
- ++d;
- return d->composed;
- }
-}
-
-static const hb_greek_decomposition decompose_0x301[] = {
- { 0x0386, 0x0391 },
- { 0x0388, 0x0395 },
- { 0x0389, 0x0397 },
- { 0x038A, 0x0399 },
- { 0x038C, 0x039F },
- { 0x038E, 0x03A5 },
- { 0x038F, 0x03A9 },
- { 0x03AC, 0x03B1 },
- { 0x03AD, 0x03B5 },
- { 0x03AE, 0x03B7 },
- { 0x03AF, 0x03B9 },
- { 0x03CC, 0x03BF },
- { 0x03CD, 0x03C5 },
- { 0x03CE, 0x03C9 },
- { 0x0390, 0x03CA },
- { 0x03B0, 0x03CB },
- { 0x03D3, 0x03D2 },
- { 0, 0 }
-};
-
-
-static HB_UChar16 compose_0x301(HB_UChar16 base)
-{
- if ((base ^ 0x1f00) < 0x100) {
- if (base <= 0x1f69 && !(base & 0x6))
- return base + 4;
- if (base == 0x1fbf)
- return 0x1fce;
- if (base == 0x1ffe)
- return 0x1fde;
- }
- {
- const hb_greek_decomposition *d = decompose_0x301;
- while (d->base && d->base != base)
- ++d;
- return d->composed;
- }
-}
-
-static const hb_greek_decomposition decompose_0x304[] = {
- { 0x1FB9, 0x0391 },
- { 0x1FD9, 0x0399 },
- { 0x1FE9, 0x03A5 },
- { 0x1FB1, 0x03B1 },
- { 0x1FD1, 0x03B9 },
- { 0x1FE1, 0x03C5 },
- { 0, 0 }
-};
-
-static HB_UChar16 compose_0x304(HB_UChar16 base)
-{
- const hb_greek_decomposition *d = decompose_0x304;
- while (d->base && d->base != base)
- ++d;
- return d->composed;
-}
-
-static const hb_greek_decomposition decompose_0x306[] = {
- { 0x1FB8, 0x0391 },
- { 0x1FD8, 0x0399 },
- { 0x1FE8, 0x03A5 },
- { 0x1FB0, 0x03B1 },
- { 0x1FD0, 0x03B9 },
- { 0x1FE0, 0x03C5 },
- { 0, 0 }
-};
-
-static HB_UChar16 compose_0x306(HB_UChar16 base)
-{
- const hb_greek_decomposition *d = decompose_0x306;
- while (d->base && d->base != base)
- ++d;
- return d->composed;
-}
-
-static const hb_greek_decomposition decompose_0x308[] = {
- { 0x03AA, 0x0399 },
- { 0x03AB, 0x03A5 },
- { 0x03CA, 0x03B9 },
- { 0x03CB, 0x03C5 },
- { 0x03D4, 0x03D2 },
- { 0, 0 }
-};
-
-static HB_UChar16 compose_0x308(HB_UChar16 base)
-{
- const hb_greek_decomposition *d = decompose_0x308;
- while (d->base && d->base != base)
- ++d;
- return d->composed;
-}
-
-
-static const hb_greek_decomposition decompose_0x313[] = {
- { 0x1F08, 0x0391 },
- { 0x1F18, 0x0395 },
- { 0x1F28, 0x0397 },
- { 0x1F38, 0x0399 },
- { 0x1F48, 0x039F },
- { 0x1F68, 0x03A9 },
- { 0x1F00, 0x03B1 },
- { 0x1F10, 0x03B5 },
- { 0x1F20, 0x03B7 },
- { 0x1F30, 0x03B9 },
- { 0x1F40, 0x03BF },
- { 0x1FE4, 0x03C1 },
- { 0x1F50, 0x03C5 },
- { 0x1F60, 0x03C9 },
- { 0, 0 }
-};
-
-static HB_UChar16 compose_0x313(HB_UChar16 base)
-{
- const hb_greek_decomposition *d = decompose_0x313;
- while (d->base && d->base != base)
- ++d;
- return d->composed;
-}
-
-static const hb_greek_decomposition decompose_0x314[] = {
- { 0x1F09, 0x0391 },
- { 0x1F19, 0x0395 },
- { 0x1F29, 0x0397 },
- { 0x1F39, 0x0399 },
- { 0x1F49, 0x039F },
- { 0x1FEC, 0x03A1 },
- { 0x1F59, 0x03A5 },
- { 0x1F69, 0x03A9 },
- { 0x1F01, 0x03B1 },
- { 0x1F11, 0x03B5 },
- { 0x1F21, 0x03B7 },
- { 0x1F31, 0x03B9 },
- { 0x1F41, 0x03BF },
- { 0x1FE5, 0x03C1 },
- { 0x1F51, 0x03C5 },
- { 0x1F61, 0x03C9 },
- { 0, 0 }
-};
-
-static HB_UChar16 compose_0x314(HB_UChar16 base)
-{
- const hb_greek_decomposition *d = decompose_0x314;
- while (d->base && d->base != base)
- ++d;
- return d->composed;
-}
-
-static const hb_greek_decomposition decompose_0x342[] = {
- { 0x1FB6, 0x03B1 },
- { 0x1FC6, 0x03B7 },
- { 0x1FD6, 0x03B9 },
- { 0x1FE6, 0x03C5 },
- { 0x1FF6, 0x03C9 },
- { 0x1FD7, 0x03CA },
- { 0x1FE7, 0x03CB },
- { 0x1F06, 0x1F00 },
- { 0x1F07, 0x1F01 },
- { 0x1F0E, 0x1F08 },
- { 0x1F0F, 0x1F09 },
- { 0x1F26, 0x1F20 },
- { 0x1F27, 0x1F21 },
- { 0x1F2E, 0x1F28 },
- { 0x1F2F, 0x1F29 },
- { 0x1F36, 0x1F30 },
- { 0x1F37, 0x1F31 },
- { 0x1F3E, 0x1F38 },
- { 0x1F3F, 0x1F39 },
- { 0x1F56, 0x1F50 },
- { 0x1F57, 0x1F51 },
- { 0x1F5F, 0x1F59 },
- { 0x1F66, 0x1F60 },
- { 0x1F67, 0x1F61 },
- { 0x1F6E, 0x1F68 },
- { 0x1F6F, 0x1F69 },
- { 0x1FCF, 0x1FBF },
- { 0x1FDF, 0x1FFE },
- { 0, 0 }
-};
-
-static HB_UChar16 compose_0x342(HB_UChar16 base)
-{
- const hb_greek_decomposition *d = decompose_0x342;
- while (d->base && d->base != base)
- ++d;
- return d->composed;
-}
-
-static const hb_greek_decomposition decompose_0x345[] = {
- { 0x1FBC, 0x0391 },
- { 0x1FCC, 0x0397 },
- { 0x1FFC, 0x03A9 },
- { 0x1FB4, 0x03AC },
- { 0x1FC4, 0x03AE },
- { 0x1FB3, 0x03B1 },
- { 0x1FC3, 0x03B7 },
- { 0x1FF3, 0x03C9 },
- { 0x1FF4, 0x03CE },
- { 0x1F80, 0x1F00 },
- { 0x1F81, 0x1F01 },
- { 0x1F82, 0x1F02 },
- { 0x1F83, 0x1F03 },
- { 0x1F84, 0x1F04 },
- { 0x1F85, 0x1F05 },
- { 0x1F86, 0x1F06 },
- { 0x1F87, 0x1F07 },
- { 0x1F88, 0x1F08 },
- { 0x1F89, 0x1F09 },
- { 0x1F8A, 0x1F0A },
- { 0x1F8B, 0x1F0B },
- { 0x1F8C, 0x1F0C },
- { 0x1F8D, 0x1F0D },
- { 0x1F8E, 0x1F0E },
- { 0x1F8F, 0x1F0F },
- { 0x1F90, 0x1F20 },
- { 0x1F91, 0x1F21 },
- { 0x1F92, 0x1F22 },
- { 0x1F93, 0x1F23 },
- { 0x1F94, 0x1F24 },
- { 0x1F95, 0x1F25 },
- { 0x1F96, 0x1F26 },
- { 0x1F97, 0x1F27 },
- { 0x1F98, 0x1F28 },
- { 0x1F99, 0x1F29 },
- { 0x1F9A, 0x1F2A },
- { 0x1F9B, 0x1F2B },
- { 0x1F9C, 0x1F2C },
- { 0x1F9D, 0x1F2D },
- { 0x1F9E, 0x1F2E },
- { 0x1F9F, 0x1F2F },
- { 0x1FA0, 0x1F60 },
- { 0x1FA1, 0x1F61 },
- { 0x1FA2, 0x1F62 },
- { 0x1FA3, 0x1F63 },
- { 0x1FA4, 0x1F64 },
- { 0x1FA5, 0x1F65 },
- { 0x1FA6, 0x1F66 },
- { 0x1FA7, 0x1F67 },
- { 0x1FA8, 0x1F68 },
- { 0x1FA9, 0x1F69 },
- { 0x1FAA, 0x1F6A },
- { 0x1FAB, 0x1F6B },
- { 0x1FAC, 0x1F6C },
- { 0x1FAD, 0x1F6D },
- { 0x1FAE, 0x1F6E },
- { 0x1FAF, 0x1F6F },
- { 0x1FB2, 0x1F70 },
- { 0x1FC2, 0x1F74 },
- { 0x1FF2, 0x1F7C },
- { 0x1FB7, 0x1FB6 },
- { 0x1FC7, 0x1FC6 },
- { 0x1FF7, 0x1FF6 },
- { 0, 0 }
-};
-
-static HB_UChar16 compose_0x345(HB_UChar16 base)
-{
- const hb_greek_decomposition *d = decompose_0x345;
- while (d->base && d->base != base)
- ++d;
- return d->composed;
-}
-
-/*
- Greek shaping. Heuristic positioning can't render polytonic greek correctly. We're a lot
- better off mapping greek chars with diacritics to the characters in the extended greek
- region in Unicode if possible.
-*/
-HB_Bool HB_GreekShape(HB_ShaperItem *shaper_item)
-{
- const int availableGlyphs = shaper_item->num_glyphs;
- const HB_UChar16 *uc = shaper_item->string + shaper_item->item.pos;
- unsigned short *logClusters = shaper_item->log_clusters;
- HB_GlyphAttributes *attributes = shaper_item->attributes;
-
- HB_Bool haveGlyphs;
- int slen = 1;
- int cluster_start = 0;
- hb_uint32 i;
-
- HB_STACKARRAY(HB_UChar16, shapedChars, 2 * shaper_item->item.length);
-
- assert(shaper_item->item.script == HB_Script_Greek);
-
- *shapedChars = *uc;
- logClusters[0] = 0;
-
- attributes[0].mark = false;
- attributes[0].clusterStart = true;
- attributes[0].dontPrint = false;
-
- for (i = 1; i < shaper_item->item.length; ++i) {
- hb_uint16 base = shapedChars[slen-1];
- hb_uint16 shaped = 0;
- if (uc[i] == 0x300)
- shaped = compose_0x300(base);
- else if (uc[i] == 0x301)
- shaped = compose_0x301(base);
- else if (uc[i] == 0x304)
- shaped = compose_0x304(base);
- else if (uc[i] == 0x306)
- shaped = compose_0x306(base);
- else if (uc[i] == 0x308)
- shaped = compose_0x308(base);
- else if (uc[i] == 0x313)
- shaped = compose_0x313(base);
- else if (uc[i] == 0x314)
- shaped = compose_0x314(base);
- else if (uc[i] == 0x342)
- shaped = compose_0x342(base);
- else if (uc[i] == 0x345)
- shaped = compose_0x345(base);
-
- if (shaped) {
- if (shaper_item->font->klass->canRender(shaper_item->font, (HB_UChar16 *)&shaped, 1)) {
- shapedChars[slen-1] = shaped;
- } else {
- shaped = 0;
- }
- }
-
- if (!shaped) {
- HB_CharCategory category;
- int cmb;
- shapedChars[slen] = uc[i];
- HB_GetUnicodeCharProperties(uc[i], &category, &cmb);
- if (category != HB_Mark_NonSpacing) {
- attributes[slen].clusterStart = TRUE;
- attributes[slen].mark = FALSE;
- attributes[slen].combiningClass = 0;
- attributes[slen].dontPrint = HB_IsControlChar(uc[i]);
- cluster_start = slen;
- } else {
- attributes[slen].clusterStart = FALSE;
- attributes[slen].mark = TRUE;
- attributes[slen].combiningClass = cmb;
- }
- ++slen;
- }
- logClusters[i] = cluster_start;
- }
-
- haveGlyphs = shaper_item->font->klass
- ->convertStringToGlyphIndices(shaper_item->font,
- shapedChars, slen,
- shaper_item->glyphs, &shaper_item->num_glyphs,
- shaper_item->item.bidiLevel % 2);
-
- HB_FREE_STACKARRAY(shapedChars);
-
- if (!haveGlyphs)
- return FALSE;
-
-#ifndef NO_OPENTYPE
- if (HB_SelectScript(shaper_item, greek_features)) {
- HB_OpenTypeShape(shaper_item, /*properties*/0);
- return HB_OpenTypePosition(shaper_item, availableGlyphs, /*doLogClusters*/TRUE);
- }
-#endif
- HB_HeuristicPosition(shaper_item);
-
- return TRUE;
-}
-
diff --git a/src/3rdparty/harfbuzz/src/harfbuzz-gsub-private.h b/src/3rdparty/harfbuzz/src/harfbuzz-gsub-private.h
deleted file mode 100644
index df0c3f639f..0000000000
--- a/src/3rdparty/harfbuzz/src/harfbuzz-gsub-private.h
+++ /dev/null
@@ -1,475 +0,0 @@
-/*
- * Copyright (C) 1998-2004 David Turner and Werner Lemberg
- * Copyright (C) 2006 Behdad Esfahbod
- *
- * This is part of HarfBuzz, an OpenType Layout engine 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 HARFBUZZ_GSUB_PRIVATE_H
-#define HARFBUZZ_GSUB_PRIVATE_H
-
-#include "harfbuzz-impl.h"
-#include "harfbuzz-stream-private.h"
-#include "harfbuzz-gsub.h"
-
-HB_BEGIN_HEADER
-
-typedef union HB_GSUB_SubTable_ HB_GSUB_SubTable;
-
-/* LookupType 1 */
-
-struct HB_SingleSubstFormat1_
-{
- HB_Short DeltaGlyphID; /* constant added to get
- substitution glyph index */
-};
-
-typedef struct HB_SingleSubstFormat1_ HB_SingleSubstFormat1;
-
-
-struct HB_SingleSubstFormat2_
-{
- HB_UShort* Substitute; /* array of substitute glyph IDs */
- HB_UShort GlyphCount; /* number of glyph IDs in
- Substitute array */
-};
-
-typedef struct HB_SingleSubstFormat2_ HB_SingleSubstFormat2;
-
-
-struct HB_SingleSubst_
-{
- union
- {
- HB_SingleSubstFormat1 ssf1;
- HB_SingleSubstFormat2 ssf2;
- } ssf;
-
- HB_Coverage Coverage; /* Coverage table */
- HB_Byte SubstFormat; /* 1 or 2 */
-};
-
-typedef struct HB_SingleSubst_ HB_SingleSubst;
-
-
-/* LookupType 2 */
-
-struct HB_Sequence_
-{
- HB_UShort* Substitute; /* string of glyph IDs to
- substitute */
- HB_UShort GlyphCount; /* number of glyph IDs in the
- Substitute array */
-};
-
-typedef struct HB_Sequence_ HB_Sequence;
-
-
-struct HB_MultipleSubst_
-{
- HB_Sequence* Sequence; /* array of Sequence tables */
- HB_Coverage Coverage; /* Coverage table */
- HB_UShort SubstFormat; /* always 1 */
- HB_UShort SequenceCount; /* number of Sequence tables */
-};
-
-typedef struct HB_MultipleSubst_ HB_MultipleSubst;
-
-
-/* LookupType 3 */
-
-struct HB_AlternateSet_
-{
- HB_UShort* Alternate; /* array of alternate glyph IDs */
- HB_UShort GlyphCount; /* number of glyph IDs in the
- Alternate array */
-};
-
-typedef struct HB_AlternateSet_ HB_AlternateSet;
-
-
-struct HB_AlternateSubst_
-{
- HB_AlternateSet* AlternateSet; /* array of AlternateSet tables */
- HB_Coverage Coverage; /* Coverage table */
- HB_UShort SubstFormat; /* always 1 */
- HB_UShort AlternateSetCount;
- /* number of AlternateSet tables */
-};
-
-typedef struct HB_AlternateSubst_ HB_AlternateSubst;
-
-
-/* LookupType 4 */
-
-struct HB_Ligature_
-{
- HB_UShort* Component; /* array of component glyph IDs */
- HB_UShort LigGlyph; /* glyphID of ligature
- to substitute */
- HB_UShort ComponentCount; /* number of components in ligature */
-};
-
-typedef struct HB_Ligature_ HB_Ligature;
-
-
-struct HB_LigatureSet_
-{
- HB_Ligature* Ligature; /* array of Ligature tables */
- HB_UShort LigatureCount; /* number of Ligature tables */
-};
-
-typedef struct HB_LigatureSet_ HB_LigatureSet;
-
-
-struct HB_LigatureSubst_
-{
- HB_LigatureSet* LigatureSet; /* array of LigatureSet tables */
- HB_Coverage Coverage; /* Coverage table */
- HB_UShort SubstFormat; /* always 1 */
- HB_UShort LigatureSetCount; /* number of LigatureSet tables */
-};
-
-typedef struct HB_LigatureSubst_ HB_LigatureSubst;
-
-
-/* needed by both lookup type 5 and 6 */
-
-struct HB_SubstLookupRecord_
-{
- HB_UShort SequenceIndex; /* index into current
- glyph sequence */
- HB_UShort LookupListIndex; /* Lookup to apply to that pos. */
-};
-
-typedef struct HB_SubstLookupRecord_ HB_SubstLookupRecord;
-
-
-/* LookupType 5 */
-
-struct HB_SubRule_
-{
- HB_UShort* Input; /* array of input glyph IDs */
- HB_SubstLookupRecord* SubstLookupRecord;
- /* array of SubstLookupRecord
- tables */
- HB_UShort GlyphCount; /* total number of input glyphs */
- HB_UShort SubstCount; /* number of SubstLookupRecord
- tables */
-};
-
-typedef struct HB_SubRule_ HB_SubRule;
-
-
-struct HB_SubRuleSet_
-{
- HB_SubRule* SubRule; /* array of SubRule tables */
- HB_UShort SubRuleCount; /* number of SubRule tables */
-};
-
-typedef struct HB_SubRuleSet_ HB_SubRuleSet;
-
-
-struct HB_ContextSubstFormat1_
-{
- HB_SubRuleSet* SubRuleSet; /* array of SubRuleSet tables */
- HB_Coverage Coverage; /* Coverage table */
- HB_UShort SubRuleSetCount; /* number of SubRuleSet tables */
-};
-
-typedef struct HB_ContextSubstFormat1_ HB_ContextSubstFormat1;
-
-
-struct HB_SubClassRule_
-{
- HB_UShort* Class; /* array of classes */
- HB_SubstLookupRecord* SubstLookupRecord;
- /* array of SubstLookupRecord
- tables */
- HB_UShort GlyphCount; /* total number of context classes */
- HB_UShort SubstCount; /* number of SubstLookupRecord
- tables */
-};
-
-typedef struct HB_SubClassRule_ HB_SubClassRule;
-
-
-struct HB_SubClassSet_
-{
- HB_SubClassRule* SubClassRule; /* array of SubClassRule tables */
- HB_UShort SubClassRuleCount;
- /* number of SubClassRule tables */
-};
-
-typedef struct HB_SubClassSet_ HB_SubClassSet;
-
-
-/* The `MaxContextLength' field is not defined in the TTO specification
- but simplifies the implementation of this format. It holds the
- maximal context length used in the context rules. */
-
-struct HB_ContextSubstFormat2_
-{
- HB_SubClassSet* SubClassSet; /* array of SubClassSet tables */
- HB_Coverage Coverage; /* Coverage table */
- HB_ClassDefinition ClassDef; /* ClassDef table */
- HB_UShort SubClassSetCount;
- /* number of SubClassSet tables */
- HB_UShort MaxContextLength;
- /* maximal context length */
-};
-
-typedef struct HB_ContextSubstFormat2_ HB_ContextSubstFormat2;
-
-
-struct HB_ContextSubstFormat3_
-{
- HB_Coverage* Coverage; /* array of Coverage tables */
- HB_SubstLookupRecord* SubstLookupRecord;
- /* array of substitution lookups */
- HB_UShort GlyphCount; /* number of input glyphs */
- HB_UShort SubstCount; /* number of SubstLookupRecords */
-};
-
-typedef struct HB_ContextSubstFormat3_ HB_ContextSubstFormat3;
-
-
-struct HB_ContextSubst_
-{
- union
- {
- HB_ContextSubstFormat1 csf1;
- HB_ContextSubstFormat2 csf2;
- HB_ContextSubstFormat3 csf3;
- } csf;
-
- HB_Byte SubstFormat; /* 1, 2, or 3 */
-};
-
-typedef struct HB_ContextSubst_ HB_ContextSubst;
-
-
-/* LookupType 6 */
-
-struct HB_ChainSubRule_
-{
- HB_UShort* Backtrack; /* array of backtrack glyph IDs */
- HB_UShort* Input; /* array of input glyph IDs */
- HB_UShort* Lookahead; /* array of lookahead glyph IDs */
- HB_SubstLookupRecord* SubstLookupRecord;
- /* array of SubstLookupRecords */
- HB_UShort BacktrackGlyphCount;
- /* total number of backtrack glyphs */
- HB_UShort InputGlyphCount;
- /* total number of input glyphs */
- HB_UShort LookaheadGlyphCount;
- /* total number of lookahead glyphs */
- HB_UShort SubstCount; /* number of SubstLookupRecords */
-};
-
-typedef struct HB_ChainSubRule_ HB_ChainSubRule;
-
-
-struct HB_ChainSubRuleSet_
-{
- HB_ChainSubRule* ChainSubRule; /* array of ChainSubRule tables */
- HB_UShort ChainSubRuleCount;
- /* number of ChainSubRule tables */
-};
-
-typedef struct HB_ChainSubRuleSet_ HB_ChainSubRuleSet;
-
-
-struct HB_ChainContextSubstFormat1_
-{
- HB_ChainSubRuleSet* ChainSubRuleSet;
- /* array of ChainSubRuleSet tables */
- HB_Coverage Coverage; /* Coverage table */
- HB_UShort ChainSubRuleSetCount;
- /* number of ChainSubRuleSet tables */
-};
-
-typedef struct HB_ChainContextSubstFormat1_ HB_ChainContextSubstFormat1;
-
-
-struct HB_ChainSubClassRule_
-{
- HB_UShort* Backtrack; /* array of backtrack classes */
- HB_UShort* Input; /* array of context classes */
- HB_UShort* Lookahead; /* array of lookahead classes */
- HB_SubstLookupRecord* SubstLookupRecord;
- /* array of substitution lookups */
- HB_UShort BacktrackGlyphCount;
- /* total number of backtrack
- classes */
- HB_UShort InputGlyphCount;
- /* total number of context classes */
- HB_UShort LookaheadGlyphCount;
- /* total number of lookahead
- classes */
- HB_UShort SubstCount; /* number of SubstLookupRecords */
-};
-
-typedef struct HB_ChainSubClassRule_ HB_ChainSubClassRule;
-
-
-struct HB_ChainSubClassSet_
-{
- HB_ChainSubClassRule* ChainSubClassRule;
- /* array of ChainSubClassRule
- tables */
- HB_UShort ChainSubClassRuleCount;
- /* number of ChainSubClassRule
- tables */
-};
-
-typedef struct HB_ChainSubClassSet_ HB_ChainSubClassSet;
-
-
-/* The `MaxXXXLength' fields are not defined in the TTO specification
- but simplifies the implementation of this format. It holds the
- maximal context length used in the specific context rules. */
-
-struct HB_ChainContextSubstFormat2_
-{
- HB_ChainSubClassSet* ChainSubClassSet;
- /* array of ChainSubClassSet
- tables */
- HB_Coverage Coverage; /* Coverage table */
-
- HB_ClassDefinition BacktrackClassDef;
- /* BacktrackClassDef table */
- HB_ClassDefinition InputClassDef;
- /* InputClassDef table */
- HB_ClassDefinition LookaheadClassDef;
- /* LookaheadClassDef table */
-
- HB_UShort ChainSubClassSetCount;
- /* number of ChainSubClassSet
- tables */
- HB_UShort MaxBacktrackLength;
- /* maximal backtrack length */
- HB_UShort MaxLookaheadLength;
- /* maximal lookahead length */
- HB_UShort MaxInputLength;
- /* maximal input length */
-};
-
-typedef struct HB_ChainContextSubstFormat2_ HB_ChainContextSubstFormat2;
-
-
-struct HB_ChainContextSubstFormat3_
-{
- HB_Coverage* BacktrackCoverage;
- /* array of backtrack Coverage
- tables */
- HB_Coverage* InputCoverage;
- /* array of input coverage
- tables */
- HB_Coverage* LookaheadCoverage;
- /* array of lookahead coverage
- tables */
- HB_SubstLookupRecord* SubstLookupRecord;
- /* array of substitution lookups */
- HB_UShort BacktrackGlyphCount;
- /* number of backtrack glyphs */
- HB_UShort InputGlyphCount;
- /* number of input glyphs */
- HB_UShort LookaheadGlyphCount;
- /* number of lookahead glyphs */
- HB_UShort SubstCount; /* number of SubstLookupRecords */
-};
-
-typedef struct HB_ChainContextSubstFormat3_ HB_ChainContextSubstFormat3;
-
-
-struct HB_ChainContextSubst_
-{
- union
- {
- HB_ChainContextSubstFormat1 ccsf1;
- HB_ChainContextSubstFormat2 ccsf2;
- HB_ChainContextSubstFormat3 ccsf3;
- } ccsf;
-
- HB_Byte SubstFormat; /* 1, 2, or 3 */
-};
-
-typedef struct HB_ChainContextSubst_ HB_ChainContextSubst;
-
-
-#if 0
-/* LookupType 7 */
-struct HB_ExtensionSubst_
-{
- HB_GSUB_SubTable *subtable; /* referenced subtable */
- HB_UShort SubstFormat; /* always 1 */
- HB_UShort LookuptType; /* lookup-type of referenced subtable */
-};
-
-typedef struct HB_ExtensionSubst_ HB_ExtensionSubst;
-#endif
-
-
-/* LookupType 8 */
-struct HB_ReverseChainContextSubst_
-{
- HB_Coverage* LookaheadCoverage; /* array of lookahead Coverage
- tables */
- HB_UShort* Substitute; /* array of substitute Glyph ID */
- HB_Coverage* BacktrackCoverage; /* array of backtrack Coverage
- tables */
- HB_Coverage Coverage; /* coverage table for input glyphs */
- HB_UShort SubstFormat; /* always 1 */
- HB_UShort BacktrackGlyphCount; /* number of backtrack glyphs */
- HB_UShort LookaheadGlyphCount; /* number of lookahead glyphs */
- HB_UShort GlyphCount; /* number of Glyph IDs */
-};
-
-typedef struct HB_ReverseChainContextSubst_ HB_ReverseChainContextSubst;
-
-
-union HB_GSUB_SubTable_
-{
- HB_SingleSubst single;
- HB_MultipleSubst multiple;
- HB_AlternateSubst alternate;
- HB_LigatureSubst ligature;
- HB_ContextSubst context;
- HB_ChainContextSubst chain;
- HB_ReverseChainContextSubst reverse;
-};
-
-
-
-
-HB_INTERNAL HB_Error
-_HB_GSUB_Load_SubTable( HB_GSUB_SubTable* st,
- HB_Stream stream,
- HB_UShort lookup_type );
-
-HB_INTERNAL void
-_HB_GSUB_Free_SubTable( HB_GSUB_SubTable* st,
- HB_UShort lookup_type );
-
-HB_END_HEADER
-
-#endif /* HARFBUZZ_GSUB_PRIVATE_H */
diff --git a/src/3rdparty/harfbuzz/src/harfbuzz-gsub.c b/src/3rdparty/harfbuzz/src/harfbuzz-gsub.c
deleted file mode 100644
index 89875d1d24..0000000000
--- a/src/3rdparty/harfbuzz/src/harfbuzz-gsub.c
+++ /dev/null
@@ -1,4329 +0,0 @@
-/*
- * Copyright (C) 1998-2004 David Turner and Werner Lemberg
- * Copyright (C) 2006 Behdad Esfahbod
- * Copyright (C) 2007 Red Hat, Inc.
- *
- * This is part of HarfBuzz, an OpenType Layout engine library.
- *
- * Permission is hereby granted, without written agreement and without
- * license or royalty fees, to use, copy, modify, and distribute this
- * software and its documentation for any purpose, provided that the
- * above copyright notice and the following two paragraphs appear in
- * all copies of this software.
- *
- * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
- * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
- * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
- * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
- * DAMAGE.
- *
- * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
- * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
- * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
- * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
- * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
- *
- * Red Hat Author(s): Behdad Esfahbod
- */
-
-#include "harfbuzz-impl.h"
-#include "harfbuzz-gsub-private.h"
-#include "harfbuzz-open-private.h"
-#include "harfbuzz-gdef-private.h"
-
-static HB_Error GSUB_Do_Glyph_Lookup( HB_GSUBHeader* gsub,
- HB_UShort lookup_index,
- HB_Buffer buffer,
- HB_UShort context_length,
- int nesting_level );
-
-
-
-/**********************
- * Auxiliary functions
- **********************/
-
-
-
-HB_Error HB_Load_GSUB_Table( HB_Stream stream,
- HB_GSUBHeader** retptr,
- HB_GDEFHeader* gdef,
- HB_Stream gdefStream )
-{
- HB_Error error = HB_Err_Ok;
- HB_UInt cur_offset, new_offset, base_offset;
-
- HB_GSUBHeader* gsub;
-
- if ( !retptr )
- return ERR(HB_Err_Invalid_Argument);
-
- if ( GOTO_Table( TTAG_GSUB ) )
- return error;
-
- base_offset = FILE_Pos();
-
- if ( ALLOC ( gsub, sizeof( *gsub ) ) )
- return error;
-
-
- /* skip version */
-
- if ( FILE_Seek( base_offset + 4L ) ||
- ACCESS_Frame( 2L ) )
- goto Fail4;
-
- new_offset = GET_UShort() + base_offset;
-
- FORGET_Frame();
-
- cur_offset = FILE_Pos();
- if ( FILE_Seek( new_offset ) ||
- ( error = _HB_OPEN_Load_ScriptList( &gsub->ScriptList,
- stream ) ) != HB_Err_Ok )
- goto Fail4;
- (void)FILE_Seek( cur_offset );
-
- if ( ACCESS_Frame( 2L ) )
- goto Fail3;
-
- new_offset = GET_UShort() + base_offset;
-
- FORGET_Frame();
-
- cur_offset = FILE_Pos();
- if ( FILE_Seek( new_offset ) ||
- ( error = _HB_OPEN_Load_FeatureList( &gsub->FeatureList,
- stream ) ) != HB_Err_Ok )
- goto Fail3;
- (void)FILE_Seek( cur_offset );
-
- if ( ACCESS_Frame( 2L ) )
- goto Fail2;
-
- new_offset = GET_UShort() + base_offset;
-
- FORGET_Frame();
-
- cur_offset = FILE_Pos();
- if ( FILE_Seek( new_offset ) ||
- ( error = _HB_OPEN_Load_LookupList( &gsub->LookupList,
- stream, HB_Type_GSUB ) ) != HB_Err_Ok )
- goto Fail2;
-
- gsub->gdef = gdef; /* can be NULL */
-
- if ( ( error = _HB_GDEF_LoadMarkAttachClassDef_From_LookupFlags( gdef, gdefStream,
- gsub->LookupList.Lookup,
- gsub->LookupList.LookupCount ) ) )
- goto Fail1;
-
- *retptr = gsub;
-
- return HB_Err_Ok;
-
-Fail1:
- _HB_OPEN_Free_LookupList( &gsub->LookupList, HB_Type_GSUB );
-
-Fail2:
- _HB_OPEN_Free_FeatureList( &gsub->FeatureList );
-
-Fail3:
- _HB_OPEN_Free_ScriptList( &gsub->ScriptList );
-
-Fail4:
- FREE ( gsub );
-
-
- return error;
-}
-
-
-HB_Error HB_Done_GSUB_Table( HB_GSUBHeader* gsub )
-{
- _HB_OPEN_Free_LookupList( &gsub->LookupList, HB_Type_GSUB );
- _HB_OPEN_Free_FeatureList( &gsub->FeatureList );
- _HB_OPEN_Free_ScriptList( &gsub->ScriptList );
-
- FREE( gsub );
-
- return HB_Err_Ok;
-}
-
-/*****************************
- * SubTable related functions
- *****************************/
-
-
-/* LookupType 1 */
-
-/* SingleSubstFormat1 */
-/* SingleSubstFormat2 */
-
-static HB_Error Load_SingleSubst( HB_GSUB_SubTable* st,
- HB_Stream stream )
-{
- HB_Error error;
- HB_SingleSubst* ss = &st->single;
-
- HB_UShort n, count;
- HB_UInt cur_offset, new_offset, base_offset;
-
- HB_UShort* s;
-
-
- base_offset = FILE_Pos();
-
- if ( ACCESS_Frame( 4L ) )
- return error;
-
- ss->SubstFormat = GET_UShort();
- new_offset = GET_UShort() + base_offset;
-
- FORGET_Frame();
-
- cur_offset = FILE_Pos();
- if ( FILE_Seek( new_offset ) ||
- ( error = _HB_OPEN_Load_Coverage( &ss->Coverage, stream ) ) != HB_Err_Ok )
- return error;
- (void)FILE_Seek( cur_offset );
-
- switch ( ss->SubstFormat )
- {
- case 1:
- if ( ACCESS_Frame( 2L ) )
- goto Fail2;
-
- ss->ssf.ssf1.DeltaGlyphID = GET_UShort();
-
- FORGET_Frame();
-
- break;
-
- case 2:
- if ( ACCESS_Frame( 2L ) )
- goto Fail2;
-
- count = ss->ssf.ssf2.GlyphCount = GET_UShort();
-
- FORGET_Frame();
-
- ss->ssf.ssf2.Substitute = NULL;
-
- if ( ALLOC_ARRAY( ss->ssf.ssf2.Substitute, count, HB_UShort ) )
- goto Fail2;
-
- s = ss->ssf.ssf2.Substitute;
-
- if ( ACCESS_Frame( count * 2L ) )
- goto Fail1;
-
- for ( n = 0; n < count; n++ )
- s[n] = GET_UShort();
-
- FORGET_Frame();
-
- break;
-
- default:
- return ERR(HB_Err_Invalid_SubTable_Format);
- }
-
- return HB_Err_Ok;
-
-Fail1:
- FREE( s );
-
-Fail2:
- _HB_OPEN_Free_Coverage( &ss->Coverage );
- return error;
-}
-
-
-static void Free_SingleSubst( HB_GSUB_SubTable* st )
-{
- HB_SingleSubst* ss = &st->single;
-
- switch ( ss->SubstFormat )
- {
- case 1:
- break;
-
- case 2:
- FREE( ss->ssf.ssf2.Substitute );
- break;
-
- default:
- break;
- }
-
- _HB_OPEN_Free_Coverage( &ss->Coverage );
-}
-
-
-static HB_Error Lookup_SingleSubst( HB_GSUBHeader* gsub,
- HB_GSUB_SubTable* st,
- HB_Buffer buffer,
- HB_UShort flags,
- HB_UShort context_length,
- int nesting_level )
-{
- HB_UShort index, value, property;
- HB_Error error;
- HB_SingleSubst* ss = &st->single;
- HB_GDEFHeader* gdef = gsub->gdef;
-
- HB_UNUSED(nesting_level);
-
- if ( context_length != 0xFFFF && context_length < 1 )
- return HB_Err_Not_Covered;
-
- if ( CHECK_Property( gdef, IN_CURITEM(), flags, &property ) )
- return error;
-
- error = _HB_OPEN_Coverage_Index( &ss->Coverage, IN_CURGLYPH(), &index );
- if ( error )
- return error;
-
- switch ( ss->SubstFormat )
- {
- case 1:
- value = ( IN_CURGLYPH() + ss->ssf.ssf1.DeltaGlyphID ) & 0xFFFF;
- if ( REPLACE_Glyph( buffer, value, nesting_level ) )
- return error;
- break;
-
- case 2:
- if ( index >= ss->ssf.ssf2.GlyphCount )
- return ERR(HB_Err_Invalid_SubTable);
- value = ss->ssf.ssf2.Substitute[index];
- if ( REPLACE_Glyph( buffer, value, nesting_level ) )
- return error;
- break;
-
- default:
- return ERR(HB_Err_Invalid_SubTable);
- }
-
- if ( gdef && gdef->NewGlyphClasses )
- {
- /* we inherit the old glyph class to the substituted glyph */
-
- error = _HB_GDEF_Add_Glyph_Property( gdef, value, property );
- if ( error && error != HB_Err_Not_Covered )
- return error;
- }
-
- return HB_Err_Ok;
-}
-
-
-/* LookupType 2 */
-
-/* Sequence */
-
-static HB_Error Load_Sequence( HB_Sequence* s,
- HB_Stream stream )
-{
- HB_Error error;
-
- HB_UShort n, count;
- HB_UShort* sub;
-
-
- if ( ACCESS_Frame( 2L ) )
- return error;
-
- count = s->GlyphCount = GET_UShort();
-
- FORGET_Frame();
-
- s->Substitute = NULL;
-
- if ( count )
- {
- if ( ALLOC_ARRAY( s->Substitute, count, HB_UShort ) )
- return error;
-
- sub = s->Substitute;
-
- if ( ACCESS_Frame( count * 2L ) )
- {
- FREE( sub );
- return error;
- }
-
- for ( n = 0; n < count; n++ )
- sub[n] = GET_UShort();
-
- FORGET_Frame();
- }
-
- return HB_Err_Ok;
-}
-
-
-static void Free_Sequence( HB_Sequence* s )
-{
- FREE( s->Substitute );
-}
-
-
-/* MultipleSubstFormat1 */
-
-static HB_Error Load_MultipleSubst( HB_GSUB_SubTable* st,
- HB_Stream stream )
-{
- HB_Error error;
- HB_MultipleSubst* ms = &st->multiple;
-
- HB_UShort n = 0, m, count;
- HB_UInt cur_offset, new_offset, base_offset;
-
- HB_Sequence* s;
-
-
- base_offset = FILE_Pos();
-
- if ( ACCESS_Frame( 4L ) )
- return error;
-
- ms->SubstFormat = GET_UShort(); /* should be 1 */
- new_offset = GET_UShort() + base_offset;
-
- FORGET_Frame();
-
- cur_offset = FILE_Pos();
- if ( FILE_Seek( new_offset ) ||
- ( error = _HB_OPEN_Load_Coverage( &ms->Coverage, stream ) ) != HB_Err_Ok )
- return error;
- (void)FILE_Seek( cur_offset );
-
- if ( ACCESS_Frame( 2L ) )
- goto Fail2;
-
- count = ms->SequenceCount = GET_UShort();
-
- FORGET_Frame();
-
- ms->Sequence = NULL;
-
- if ( ALLOC_ARRAY( ms->Sequence, count, HB_Sequence ) )
- goto Fail2;
-
- s = ms->Sequence;
-
- for ( n = 0; n < count; n++ )
- {
- if ( ACCESS_Frame( 2L ) )
- goto Fail1;
-
- new_offset = GET_UShort() + base_offset;
-
- FORGET_Frame();
-
- cur_offset = FILE_Pos();
- if ( FILE_Seek( new_offset ) ||
- ( error = Load_Sequence( &s[n], stream ) ) != HB_Err_Ok )
- goto Fail1;
- (void)FILE_Seek( cur_offset );
- }
-
- return HB_Err_Ok;
-
-Fail1:
- for ( m = 0; m < n; m++ )
- Free_Sequence( &s[m] );
-
- FREE( s );
-
-Fail2:
- _HB_OPEN_Free_Coverage( &ms->Coverage );
- return error;
-}
-
-
-static void Free_MultipleSubst( HB_GSUB_SubTable* st )
-{
- HB_UShort n, count;
- HB_MultipleSubst* ms = &st->multiple;
-
- HB_Sequence* s;
-
-
- if ( ms->Sequence )
- {
- count = ms->SequenceCount;
- s = ms->Sequence;
-
- for ( n = 0; n < count; n++ )
- Free_Sequence( &s[n] );
-
- FREE( s );
- }
-
- _HB_OPEN_Free_Coverage( &ms->Coverage );
-}
-
-
-static HB_Error Lookup_MultipleSubst( HB_GSUBHeader* gsub,
- HB_GSUB_SubTable* st,
- HB_Buffer buffer,
- HB_UShort flags,
- HB_UShort context_length,
- int nesting_level )
-{
- HB_Error error;
- HB_UShort index, property, n, count;
- HB_UShort*s;
- HB_MultipleSubst* ms = &st->multiple;
- HB_GDEFHeader* gdef = gsub->gdef;
-
- HB_UNUSED(nesting_level);
-
- if ( context_length != 0xFFFF && context_length < 1 )
- return HB_Err_Not_Covered;
-
- if ( CHECK_Property( gdef, IN_CURITEM(), flags, &property ) )
- return error;
-
- error = _HB_OPEN_Coverage_Index( &ms->Coverage, IN_CURGLYPH(), &index );
- if ( error )
- return error;
-
- if ( index >= ms->SequenceCount )
- return ERR(HB_Err_Invalid_SubTable);
-
- count = ms->Sequence[index].GlyphCount;
- s = ms->Sequence[index].Substitute;
-
- if ( ADD_String( buffer, 1, count, s, 0xFFFF, 0xFFFF ) )
- return error;
-
- if ( gdef && gdef->NewGlyphClasses )
- {
- /* this is a guess only ... */
-
- if ( property == HB_GDEF_LIGATURE )
- property = HB_GDEF_BASE_GLYPH;
-
- for ( n = 0; n < count; n++ )
- {
- error = _HB_GDEF_Add_Glyph_Property( gdef, s[n], property );
- if ( error && error != HB_Err_Not_Covered )
- return error;
- }
- }
-
- return HB_Err_Ok;
-}
-
-
-/* LookupType 3 */
-
-/* AlternateSet */
-
-static HB_Error Load_AlternateSet( HB_AlternateSet* as,
- HB_Stream stream )
-{
- HB_Error error;
-
- HB_UShort n, count;
- HB_UShort* a;
-
-
- if ( ACCESS_Frame( 2L ) )
- return error;
-
- count = as->GlyphCount = GET_UShort();
-
- FORGET_Frame();
-
- as->Alternate = NULL;
-
- if ( ALLOC_ARRAY( as->Alternate, count, HB_UShort ) )
- return error;
-
- a = as->Alternate;
-
- if ( ACCESS_Frame( count * 2L ) )
- {
- FREE( a );
- return error;
- }
-
- for ( n = 0; n < count; n++ )
- a[n] = GET_UShort();
-
- FORGET_Frame();
-
- return HB_Err_Ok;
-}
-
-
-static void Free_AlternateSet( HB_AlternateSet* as )
-{
- FREE( as->Alternate );
-}
-
-
-/* AlternateSubstFormat1 */
-
-static HB_Error Load_AlternateSubst( HB_GSUB_SubTable* st,
- HB_Stream stream )
-{
- HB_Error error;
- HB_AlternateSubst* as = &st->alternate;
-
- HB_UShort n = 0, m, count;
- HB_UInt cur_offset, new_offset, base_offset;
-
- HB_AlternateSet* aset;
-
-
- base_offset = FILE_Pos();
-
- if ( ACCESS_Frame( 4L ) )
- return error;
-
- as->SubstFormat = GET_UShort(); /* should be 1 */
- new_offset = GET_UShort() + base_offset;
-
- FORGET_Frame();
-
- cur_offset = FILE_Pos();
- if ( FILE_Seek( new_offset ) ||
- ( error = _HB_OPEN_Load_Coverage( &as->Coverage, stream ) ) != HB_Err_Ok )
- return error;
- (void)FILE_Seek( cur_offset );
-
- if ( ACCESS_Frame( 2L ) )
- goto Fail2;
-
- count = as->AlternateSetCount = GET_UShort();
-
- FORGET_Frame();
-
- as->AlternateSet = NULL;
-
- if ( ALLOC_ARRAY( as->AlternateSet, count, HB_AlternateSet ) )
- goto Fail2;
-
- aset = as->AlternateSet;
-
- for ( n = 0; n < count; n++ )
- {
- if ( ACCESS_Frame( 2L ) )
- goto Fail1;
-
- new_offset = GET_UShort() + base_offset;
-
- FORGET_Frame();
-
- cur_offset = FILE_Pos();
- if ( FILE_Seek( new_offset ) ||
- ( error = Load_AlternateSet( &aset[n], stream ) ) != HB_Err_Ok )
- goto Fail1;
- (void)FILE_Seek( cur_offset );
- }
-
- return HB_Err_Ok;
-
-Fail1:
- for ( m = 0; m < n; m++ )
- Free_AlternateSet( &aset[m] );
-
- FREE( aset );
-
-Fail2:
- _HB_OPEN_Free_Coverage( &as->Coverage );
- return error;
-}
-
-
-static void Free_AlternateSubst( HB_GSUB_SubTable* st )
-{
- HB_UShort n, count;
- HB_AlternateSubst* as = &st->alternate;
-
- HB_AlternateSet* aset;
-
-
- if ( as->AlternateSet )
- {
- count = as->AlternateSetCount;
- aset = as->AlternateSet;
-
- for ( n = 0; n < count; n++ )
- Free_AlternateSet( &aset[n] );
-
- FREE( aset );
- }
-
- _HB_OPEN_Free_Coverage( &as->Coverage );
-}
-
-
-static HB_Error Lookup_AlternateSubst( HB_GSUBHeader* gsub,
- HB_GSUB_SubTable* st,
- HB_Buffer buffer,
- HB_UShort flags,
- HB_UShort context_length,
- int nesting_level )
-{
- HB_Error error;
- HB_UShort index, value, alt_index, property;
- HB_AlternateSubst* as = &st->alternate;
- HB_GDEFHeader* gdef = gsub->gdef;
- HB_AlternateSet aset;
-
- HB_UNUSED(nesting_level);
-
- if ( context_length != 0xFFFF && context_length < 1 )
- return HB_Err_Not_Covered;
-
- if ( CHECK_Property( gdef, IN_CURITEM(), flags, &property ) )
- return error;
-
- error = _HB_OPEN_Coverage_Index( &as->Coverage, IN_CURGLYPH(), &index );
- if ( error )
- return error;
-
- aset = as->AlternateSet[index];
-
- /* we use a user-defined callback function to get the alternate index */
-
- if ( gsub->altfunc )
- alt_index = (gsub->altfunc)( buffer->out_pos, IN_CURGLYPH(),
- aset.GlyphCount, aset.Alternate,
- gsub->data );
- else
- alt_index = 0;
-
- value = aset.Alternate[alt_index];
- if ( REPLACE_Glyph( buffer, value, nesting_level ) )
- return error;
-
- if ( gdef && gdef->NewGlyphClasses )
- {
- /* we inherit the old glyph class to the substituted glyph */
-
- error = _HB_GDEF_Add_Glyph_Property( gdef, value, property );
- if ( error && error != HB_Err_Not_Covered )
- return error;
- }
-
- return HB_Err_Ok;
-}
-
-
-/* LookupType 4 */
-
-/* Ligature */
-
-static HB_Error Load_Ligature( HB_Ligature* l,
- HB_Stream stream )
-{
- HB_Error error;
-
- HB_UShort n, count;
- HB_UShort* c;
-
-
- if ( ACCESS_Frame( 4L ) )
- return error;
-
- l->LigGlyph = GET_UShort();
- l->ComponentCount = GET_UShort();
-
- FORGET_Frame();
-
- l->Component = NULL;
-
- count = l->ComponentCount - 1; /* only ComponentCount - 1 elements */
-
- if ( ALLOC_ARRAY( l->Component, count, HB_UShort ) )
- return error;
-
- c = l->Component;
-
- if ( ACCESS_Frame( count * 2L ) )
- {
- FREE( c );
- return error;
- }
-
- for ( n = 0; n < count; n++ )
- c[n] = GET_UShort();
-
- FORGET_Frame();
-
- return HB_Err_Ok;
-}
-
-
-static void Free_Ligature( HB_Ligature* l )
-{
- FREE( l->Component );
-}
-
-
-/* LigatureSet */
-
-static HB_Error Load_LigatureSet( HB_LigatureSet* ls,
- HB_Stream stream )
-{
- HB_Error error;
-
- HB_UShort n = 0, m, count;
- HB_UInt cur_offset, new_offset, base_offset;
-
- HB_Ligature* l;
-
-
- base_offset = FILE_Pos();
-
- if ( ACCESS_Frame( 2L ) )
- return error;
-
- count = ls->LigatureCount = GET_UShort();
-
- FORGET_Frame();
-
- ls->Ligature = NULL;
-
- if ( ALLOC_ARRAY( ls->Ligature, count, HB_Ligature ) )
- return error;
-
- l = ls->Ligature;
-
- for ( n = 0; n < count; n++ )
- {
- if ( ACCESS_Frame( 2L ) )
- goto Fail;
-
- new_offset = GET_UShort() + base_offset;
-
- FORGET_Frame();
-
- cur_offset = FILE_Pos();
- if ( FILE_Seek( new_offset ) ||
- ( error = Load_Ligature( &l[n], stream ) ) != HB_Err_Ok )
- goto Fail;
- (void)FILE_Seek( cur_offset );
- }
-
- return HB_Err_Ok;
-
-Fail:
- for ( m = 0; m < n; m++ )
- Free_Ligature( &l[m] );
-
- FREE( l );
- return error;
-}
-
-
-static void Free_LigatureSet( HB_LigatureSet* ls )
-{
- HB_UShort n, count;
-
- HB_Ligature* l;
-
-
- if ( ls->Ligature )
- {
- count = ls->LigatureCount;
- l = ls->Ligature;
-
- for ( n = 0; n < count; n++ )
- Free_Ligature( &l[n] );
-
- FREE( l );
- }
-}
-
-
-/* LigatureSubstFormat1 */
-
-static HB_Error Load_LigatureSubst( HB_GSUB_SubTable* st,
- HB_Stream stream )
-{
- HB_Error error;
- HB_LigatureSubst* ls = &st->ligature;
-
- HB_UShort n = 0, m, count;
- HB_UInt cur_offset, new_offset, base_offset;
-
- HB_LigatureSet* lset;
-
-
- base_offset = FILE_Pos();
-
- if ( ACCESS_Frame( 4L ) )
- return error;
-
- ls->SubstFormat = GET_UShort(); /* should be 1 */
- new_offset = GET_UShort() + base_offset;
-
- FORGET_Frame();
-
- cur_offset = FILE_Pos();
- if ( FILE_Seek( new_offset ) ||
- ( error = _HB_OPEN_Load_Coverage( &ls->Coverage, stream ) ) != HB_Err_Ok )
- return error;
- (void)FILE_Seek( cur_offset );
-
- if ( ACCESS_Frame( 2L ) )
- goto Fail2;
-
- count = ls->LigatureSetCount = GET_UShort();
-
- FORGET_Frame();
-
- ls->LigatureSet = NULL;
-
- if ( ALLOC_ARRAY( ls->LigatureSet, count, HB_LigatureSet ) )
- goto Fail2;
-
- lset = ls->LigatureSet;
-
- for ( n = 0; n < count; n++ )
- {
- if ( ACCESS_Frame( 2L ) )
- goto Fail1;
-
- new_offset = GET_UShort() + base_offset;
-
- FORGET_Frame();
-
- cur_offset = FILE_Pos();
- if ( FILE_Seek( new_offset ) ||
- ( error = Load_LigatureSet( &lset[n], stream ) ) != HB_Err_Ok )
- goto Fail1;
- (void)FILE_Seek( cur_offset );
- }
-
- return HB_Err_Ok;
-
-Fail1:
- for ( m = 0; m < n; m++ )
- Free_LigatureSet( &lset[m] );
-
- FREE( lset );
-
-Fail2:
- _HB_OPEN_Free_Coverage( &ls->Coverage );
- return error;
-}
-
-
-static void Free_LigatureSubst( HB_GSUB_SubTable* st )
-{
- HB_UShort n, count;
- HB_LigatureSubst* ls = &st->ligature;
-
- HB_LigatureSet* lset;
-
-
- if ( ls->LigatureSet )
- {
- count = ls->LigatureSetCount;
- lset = ls->LigatureSet;
-
- for ( n = 0; n < count; n++ )
- Free_LigatureSet( &lset[n] );
-
- FREE( lset );
- }
-
- _HB_OPEN_Free_Coverage( &ls->Coverage );
-}
-
-
-static HB_Error Lookup_LigatureSubst( HB_GSUBHeader* gsub,
- HB_GSUB_SubTable* st,
- HB_Buffer buffer,
- HB_UShort flags,
- HB_UShort context_length,
- int nesting_level )
-{
- HB_UShort index, property;
- HB_Error error;
- HB_UShort numlig, i, j, is_mark, first_is_mark = FALSE;
- HB_UShort* c;
- HB_LigatureSubst* ls = &st->ligature;
- HB_GDEFHeader* gdef = gsub->gdef;
-
- HB_Ligature* lig;
-
- HB_UNUSED(nesting_level);
-
- if ( CHECK_Property( gdef, IN_CURITEM(), flags, &property ) )
- return error;
-
- if ( property == HB_GDEF_MARK || property & HB_LOOKUP_FLAG_IGNORE_SPECIAL_MARKS )
- first_is_mark = TRUE;
-
- error = _HB_OPEN_Coverage_Index( &ls->Coverage, IN_CURGLYPH(), &index );
- if ( error )
- return error;
-
- if ( index >= ls->LigatureSetCount )
- return ERR(HB_Err_Invalid_SubTable);
-
- lig = ls->LigatureSet[index].Ligature;
-
- for ( numlig = ls->LigatureSet[index].LigatureCount;
- numlig;
- numlig--, lig++ )
- {
- if ( buffer->in_pos + lig->ComponentCount > buffer->in_length )
- goto next_ligature; /* Not enough glyphs in input */
-
- c = lig->Component;
-
- is_mark = first_is_mark;
-
- if ( context_length != 0xFFFF && context_length < lig->ComponentCount )
- break;
-
- for ( i = 1, j = buffer->in_pos + 1; i < lig->ComponentCount; i++, j++ )
- {
- while ( CHECK_Property( gdef, IN_ITEM( j ), flags, &property ) )
- {
- if ( error && error != HB_Err_Not_Covered )
- return error;
-
- if ( j + lig->ComponentCount - i == (HB_Int)buffer->in_length )
- goto next_ligature;
- j++;
- }
-
- if ( !( property == HB_GDEF_MARK || property & HB_LOOKUP_FLAG_IGNORE_SPECIAL_MARKS ) )
- is_mark = FALSE;
-
- if ( IN_GLYPH( j ) != c[i - 1] )
- goto next_ligature;
- }
-
- if ( gdef && gdef->NewGlyphClasses )
- {
- /* this is just a guess ... */
-
- error = _HB_GDEF_Add_Glyph_Property( gdef, lig->LigGlyph,
- is_mark ? HB_GDEF_MARK : HB_GDEF_LIGATURE );
- if ( error && error != HB_Err_Not_Covered )
- return error;
- }
-
- if ( j == buffer->in_pos + i ) /* No input glyphs skipped */
- {
- /* We don't use a new ligature ID if there are no skipped
- glyphs and the ligature already has an ID. */
-
- if ( IN_LIGID( buffer->in_pos ) )
- {
- if ( ADD_String( buffer, i, 1, &lig->LigGlyph,
- 0xFFFF, 0xFFFF ) )
- return error;
- }
- else
- {
- HB_UShort ligID = _hb_buffer_allocate_ligid( buffer );
- if ( ADD_String( buffer, i, 1, &lig->LigGlyph,
- 0xFFFF, ligID ) )
- return error;
- }
- }
- else
- {
- HB_UShort ligID = _hb_buffer_allocate_ligid( buffer );
- if ( ADD_Glyph( buffer, lig->LigGlyph, 0xFFFF, ligID ) )
- return error;
-
- /* Now we must do a second loop to copy the skipped glyphs to
- `out' and assign component values to it. We start with the
- glyph after the first component. Glyphs between component
- i and i+1 belong to component i. Together with the ligID
- value it is later possible to check whether a specific
- component value really belongs to a given ligature. */
-
- for ( i = 0; i < lig->ComponentCount - 1; i++ )
- {
- while ( CHECK_Property( gdef, IN_CURITEM(),
- flags, &property ) )
- if ( ADD_Glyph( buffer, IN_CURGLYPH(), i, ligID ) )
- return error;
-
- (buffer->in_pos)++;
- }
- }
-
- return HB_Err_Ok;
-
- next_ligature:
- ;
- }
-
- return HB_Err_Not_Covered;
-}
-
-
-/* Do the actual substitution for a context substitution (either format
- 5 or 6). This is only called after we've determined that the input
- matches the subrule. */
-
-static HB_Error Do_ContextSubst( HB_GSUBHeader* gsub,
- HB_UShort GlyphCount,
- HB_UShort SubstCount,
- HB_SubstLookupRecord* subst,
- HB_Buffer buffer,
- int nesting_level )
-{
- HB_Error error;
- HB_UInt i, old_pos;
-
-
- i = 0;
-
- while ( i < GlyphCount )
- {
- if ( SubstCount && i == subst->SequenceIndex )
- {
- old_pos = buffer->in_pos;
-
- /* Do a substitution */
-
- error = GSUB_Do_Glyph_Lookup( gsub, subst->LookupListIndex, buffer,
- GlyphCount, nesting_level );
-
- subst++;
- SubstCount--;
- i += buffer->in_pos - old_pos;
-
- if ( error == HB_Err_Not_Covered )
- {
- if ( COPY_Glyph( buffer ) )
- return error;
- i++;
- }
- else if ( error )
- return error;
- }
- else
- {
- /* No substitution for this index */
-
- if ( COPY_Glyph( buffer ) )
- return error;
- i++;
- }
- }
-
- return HB_Err_Ok;
-}
-
-
-/* LookupType 5 */
-
-/* SubRule */
-
-static HB_Error Load_SubRule( HB_SubRule* sr,
- HB_Stream stream )
-{
- HB_Error error;
-
- HB_UShort n, count;
- HB_UShort* i;
-
- HB_SubstLookupRecord* slr;
-
-
- if ( ACCESS_Frame( 4L ) )
- return error;
-
- sr->GlyphCount = GET_UShort();
- sr->SubstCount = GET_UShort();
-
- FORGET_Frame();
-
- sr->Input = NULL;
-
- count = sr->GlyphCount - 1; /* only GlyphCount - 1 elements */
-
- if ( ALLOC_ARRAY( sr->Input, count, HB_UShort ) )
- return error;
-
- i = sr->Input;
-
- if ( ACCESS_Frame( count * 2L ) )
- goto Fail2;
-
- for ( n = 0; n < count; n++ )
- i[n] = GET_UShort();
-
- FORGET_Frame();
-
- sr->SubstLookupRecord = NULL;
-
- count = sr->SubstCount;
-
- if ( ALLOC_ARRAY( sr->SubstLookupRecord, count, HB_SubstLookupRecord ) )
- goto Fail2;
-
- slr = sr->SubstLookupRecord;
-
- if ( ACCESS_Frame( count * 4L ) )
- goto Fail1;
-
- for ( n = 0; n < count; n++ )
- {
- slr[n].SequenceIndex = GET_UShort();
- slr[n].LookupListIndex = GET_UShort();
- }
-
- FORGET_Frame();
-
- return HB_Err_Ok;
-
-Fail1:
- FREE( slr );
-
-Fail2:
- FREE( i );
- return error;
-}
-
-
-static void Free_SubRule( HB_SubRule* sr )
-{
- FREE( sr->SubstLookupRecord );
- FREE( sr->Input );
-}
-
-
-/* SubRuleSet */
-
-static HB_Error Load_SubRuleSet( HB_SubRuleSet* srs,
- HB_Stream stream )
-{
- HB_Error error;
-
- HB_UShort n = 0, m, count;
- HB_UInt cur_offset, new_offset, base_offset;
-
- HB_SubRule* sr;
-
-
- base_offset = FILE_Pos();
-
- if ( ACCESS_Frame( 2L ) )
- return error;
-
- count = srs->SubRuleCount = GET_UShort();
-
- FORGET_Frame();
-
- srs->SubRule = NULL;
-
- if ( ALLOC_ARRAY( srs->SubRule, count, HB_SubRule ) )
- return error;
-
- sr = srs->SubRule;
-
- for ( n = 0; n < count; n++ )
- {
- if ( ACCESS_Frame( 2L ) )
- goto Fail;
-
- new_offset = GET_UShort() + base_offset;
-
- FORGET_Frame();
-
- cur_offset = FILE_Pos();
- if ( FILE_Seek( new_offset ) ||
- ( error = Load_SubRule( &sr[n], stream ) ) != HB_Err_Ok )
- goto Fail;
- (void)FILE_Seek( cur_offset );
- }
-
- return HB_Err_Ok;
-
-Fail:
- for ( m = 0; m < n; m++ )
- Free_SubRule( &sr[m] );
-
- FREE( sr );
- return error;
-}
-
-
-static void Free_SubRuleSet( HB_SubRuleSet* srs )
-{
- HB_UShort n, count;
-
- HB_SubRule* sr;
-
-
- if ( srs->SubRule )
- {
- count = srs->SubRuleCount;
- sr = srs->SubRule;
-
- for ( n = 0; n < count; n++ )
- Free_SubRule( &sr[n] );
-
- FREE( sr );
- }
-}
-
-
-/* ContextSubstFormat1 */
-
-static HB_Error Load_ContextSubst1( HB_ContextSubstFormat1* csf1,
- HB_Stream stream )
-{
- HB_Error error;
-
- HB_UShort n = 0, m, count;
- HB_UInt cur_offset, new_offset, base_offset;
-
- HB_SubRuleSet* srs;
-
-
- base_offset = FILE_Pos() - 2L;
-
- if ( ACCESS_Frame( 2L ) )
- return error;
-
- new_offset = GET_UShort() + base_offset;
-
- FORGET_Frame();
-
- cur_offset = FILE_Pos();
- if ( FILE_Seek( new_offset ) ||
- ( error = _HB_OPEN_Load_Coverage( &csf1->Coverage, stream ) ) != HB_Err_Ok )
- return error;
- (void)FILE_Seek( cur_offset );
-
- if ( ACCESS_Frame( 2L ) )
- goto Fail2;
-
- count = csf1->SubRuleSetCount = GET_UShort();
-
- FORGET_Frame();
-
- csf1->SubRuleSet = NULL;
-
- if ( ALLOC_ARRAY( csf1->SubRuleSet, count, HB_SubRuleSet ) )
- goto Fail2;
-
- srs = csf1->SubRuleSet;
-
- for ( n = 0; n < count; n++ )
- {
- if ( ACCESS_Frame( 2L ) )
- goto Fail1;
-
- new_offset = GET_UShort() + base_offset;
-
- FORGET_Frame();
-
- cur_offset = FILE_Pos();
- if ( FILE_Seek( new_offset ) ||
- ( error = Load_SubRuleSet( &srs[n], stream ) ) != HB_Err_Ok )
- goto Fail1;
- (void)FILE_Seek( cur_offset );
- }
-
- return HB_Err_Ok;
-
-Fail1:
- for ( m = 0; m < n; m++ )
- Free_SubRuleSet( &srs[m] );
-
- FREE( srs );
-
-Fail2:
- _HB_OPEN_Free_Coverage( &csf1->Coverage );
- return error;
-}
-
-
-static void Free_ContextSubst1( HB_ContextSubstFormat1* csf1 )
-{
- HB_UShort n, count;
-
- HB_SubRuleSet* srs;
-
-
- if ( csf1->SubRuleSet )
- {
- count = csf1->SubRuleSetCount;
- srs = csf1->SubRuleSet;
-
- for ( n = 0; n < count; n++ )
- Free_SubRuleSet( &srs[n] );
-
- FREE( srs );
- }
-
- _HB_OPEN_Free_Coverage( &csf1->Coverage );
-}
-
-
-/* SubClassRule */
-
-static HB_Error Load_SubClassRule( HB_ContextSubstFormat2* csf2,
- HB_SubClassRule* scr,
- HB_Stream stream )
-{
- HB_Error error;
-
- HB_UShort n, count;
-
- HB_UShort* c;
- HB_SubstLookupRecord* slr;
-
-
- if ( ACCESS_Frame( 4L ) )
- return error;
-
- scr->GlyphCount = GET_UShort();
- scr->SubstCount = GET_UShort();
-
- if ( scr->GlyphCount > csf2->MaxContextLength )
- csf2->MaxContextLength = scr->GlyphCount;
-
- FORGET_Frame();
-
- scr->Class = NULL;
-
- count = scr->GlyphCount - 1; /* only GlyphCount - 1 elements */
-
- if ( ALLOC_ARRAY( scr->Class, count, HB_UShort ) )
- return error;
-
- c = scr->Class;
-
- if ( ACCESS_Frame( count * 2L ) )
- goto Fail2;
-
- for ( n = 0; n < count; n++ )
- c[n] = GET_UShort();
-
- FORGET_Frame();
-
- scr->SubstLookupRecord = NULL;
-
- count = scr->SubstCount;
-
- if ( ALLOC_ARRAY( scr->SubstLookupRecord, count, HB_SubstLookupRecord ) )
- goto Fail2;
-
- slr = scr->SubstLookupRecord;
-
- if ( ACCESS_Frame( count * 4L ) )
- goto Fail1;
-
- for ( n = 0; n < count; n++ )
- {
- slr[n].SequenceIndex = GET_UShort();
- slr[n].LookupListIndex = GET_UShort();
- }
-
- FORGET_Frame();
-
- return HB_Err_Ok;
-
-Fail1:
- FREE( slr );
-
-Fail2:
- FREE( c );
- return error;
-}
-
-
-static void Free_SubClassRule( HB_SubClassRule* scr )
-{
- FREE( scr->SubstLookupRecord );
- FREE( scr->Class );
-}
-
-
-/* SubClassSet */
-
-static HB_Error Load_SubClassSet( HB_ContextSubstFormat2* csf2,
- HB_SubClassSet* scs,
- HB_Stream stream )
-{
- HB_Error error;
-
- HB_UShort n = 0, m, count;
- HB_UInt cur_offset, new_offset, base_offset;
-
- HB_SubClassRule* scr;
-
-
- base_offset = FILE_Pos();
-
- if ( ACCESS_Frame( 2L ) )
- return error;
-
- count = scs->SubClassRuleCount = GET_UShort();
-
- FORGET_Frame();
-
- scs->SubClassRule = NULL;
-
- if ( ALLOC_ARRAY( scs->SubClassRule, count, HB_SubClassRule ) )
- return error;
-
- scr = scs->SubClassRule;
-
- for ( n = 0; n < count; n++ )
- {
- if ( ACCESS_Frame( 2L ) )
- goto Fail;
-
- new_offset = GET_UShort() + base_offset;
-
- FORGET_Frame();
-
- cur_offset = FILE_Pos();
- if ( FILE_Seek( new_offset ) ||
- ( error = Load_SubClassRule( csf2, &scr[n],
- stream ) ) != HB_Err_Ok )
- goto Fail;
- (void)FILE_Seek( cur_offset );
- }
-
- return HB_Err_Ok;
-
-Fail:
- for ( m = 0; m < n; m++ )
- Free_SubClassRule( &scr[m] );
-
- FREE( scr );
- return error;
-}
-
-
-static void Free_SubClassSet( HB_SubClassSet* scs )
-{
- HB_UShort n, count;
-
- HB_SubClassRule* scr;
-
-
- if ( scs->SubClassRule )
- {
- count = scs->SubClassRuleCount;
- scr = scs->SubClassRule;
-
- for ( n = 0; n < count; n++ )
- Free_SubClassRule( &scr[n] );
-
- FREE( scr );
- }
-}
-
-
-/* ContextSubstFormat2 */
-
-static HB_Error Load_ContextSubst2( HB_ContextSubstFormat2* csf2,
- HB_Stream stream )
-{
- HB_Error error;
-
- HB_UShort n = 0, m, count;
- HB_UInt cur_offset, new_offset, base_offset;
-
- HB_SubClassSet* scs;
-
-
- base_offset = FILE_Pos() - 2;
-
- if ( ACCESS_Frame( 2L ) )
- return error;
-
- new_offset = GET_UShort() + base_offset;
-
- FORGET_Frame();
-
- cur_offset = FILE_Pos();
- if ( FILE_Seek( new_offset ) ||
- ( error = _HB_OPEN_Load_Coverage( &csf2->Coverage, stream ) ) != HB_Err_Ok )
- return error;
- (void)FILE_Seek( cur_offset );
-
- if ( ACCESS_Frame( 4L ) )
- goto Fail3;
-
- new_offset = GET_UShort() + base_offset;
-
- /* `SubClassSetCount' is the upper limit for class values, thus we
- read it now to make an additional safety check. */
-
- count = csf2->SubClassSetCount = GET_UShort();
-
- FORGET_Frame();
-
- cur_offset = FILE_Pos();
- if ( FILE_Seek( new_offset ) ||
- ( error = _HB_OPEN_Load_ClassDefinition( &csf2->ClassDef, count,
- stream ) ) != HB_Err_Ok )
- goto Fail3;
- (void)FILE_Seek( cur_offset );
-
- csf2->SubClassSet = NULL;
- csf2->MaxContextLength = 0;
-
- if ( ALLOC_ARRAY( csf2->SubClassSet, count, HB_SubClassSet ) )
- goto Fail2;
-
- scs = csf2->SubClassSet;
-
- for ( n = 0; n < count; n++ )
- {
- if ( ACCESS_Frame( 2L ) )
- goto Fail1;
-
- new_offset = GET_UShort() + base_offset;
-
- FORGET_Frame();
-
- if ( new_offset != base_offset ) /* not a NULL offset */
- {
- cur_offset = FILE_Pos();
- if ( FILE_Seek( new_offset ) ||
- ( error = Load_SubClassSet( csf2, &scs[n],
- stream ) ) != HB_Err_Ok )
- goto Fail1;
- (void)FILE_Seek( cur_offset );
- }
- else
- {
- /* we create a SubClassSet table with no entries */
-
- csf2->SubClassSet[n].SubClassRuleCount = 0;
- csf2->SubClassSet[n].SubClassRule = NULL;
- }
- }
-
- return HB_Err_Ok;
-
-Fail1:
- for ( m = 0; m < n; m++ )
- Free_SubClassSet( &scs[m] );
-
- FREE( scs );
-
-Fail2:
- _HB_OPEN_Free_ClassDefinition( &csf2->ClassDef );
-
-Fail3:
- _HB_OPEN_Free_Coverage( &csf2->Coverage );
- return error;
-}
-
-
-static void Free_ContextSubst2( HB_ContextSubstFormat2* csf2 )
-{
- HB_UShort n, count;
-
- HB_SubClassSet* scs;
-
-
- if ( csf2->SubClassSet )
- {
- count = csf2->SubClassSetCount;
- scs = csf2->SubClassSet;
-
- for ( n = 0; n < count; n++ )
- Free_SubClassSet( &scs[n] );
-
- FREE( scs );
- }
-
- _HB_OPEN_Free_ClassDefinition( &csf2->ClassDef );
- _HB_OPEN_Free_Coverage( &csf2->Coverage );
-}
-
-
-/* ContextSubstFormat3 */
-
-static HB_Error Load_ContextSubst3( HB_ContextSubstFormat3* csf3,
- HB_Stream stream )
-{
- HB_Error error;
-
- HB_UShort n = 0, m, count;
- HB_UInt cur_offset, new_offset, base_offset;
-
- HB_Coverage* c;
- HB_SubstLookupRecord* slr;
-
-
- base_offset = FILE_Pos() - 2L;
-
- if ( ACCESS_Frame( 4L ) )
- return error;
-
- csf3->GlyphCount = GET_UShort();
- csf3->SubstCount = GET_UShort();
-
- FORGET_Frame();
-
- csf3->Coverage = NULL;
-
- count = csf3->GlyphCount;
-
- if ( ALLOC_ARRAY( csf3->Coverage, count, HB_Coverage ) )
- return error;
-
- c = csf3->Coverage;
-
- for ( n = 0; n < count; n++ )
- {
- if ( ACCESS_Frame( 2L ) )
- goto Fail2;
-
- new_offset = GET_UShort() + base_offset;
-
- FORGET_Frame();
-
- cur_offset = FILE_Pos();
- if ( FILE_Seek( new_offset ) ||
- ( error = _HB_OPEN_Load_Coverage( &c[n], stream ) ) != HB_Err_Ok )
- goto Fail2;
- (void)FILE_Seek( cur_offset );
- }
-
- csf3->SubstLookupRecord = NULL;
-
- count = csf3->SubstCount;
-
- if ( ALLOC_ARRAY( csf3->SubstLookupRecord, count,
- HB_SubstLookupRecord ) )
- goto Fail2;
-
- slr = csf3->SubstLookupRecord;
-
- if ( ACCESS_Frame( count * 4L ) )
- goto Fail1;
-
- for ( n = 0; n < count; n++ )
- {
- slr[n].SequenceIndex = GET_UShort();
- slr[n].LookupListIndex = GET_UShort();
- }
-
- FORGET_Frame();
-
- return HB_Err_Ok;
-
-Fail1:
- FREE( slr );
-
-Fail2:
- for ( m = 0; m < n; m++ )
- _HB_OPEN_Free_Coverage( &c[m] );
-
- FREE( c );
- return error;
-}
-
-
-static void Free_ContextSubst3( HB_ContextSubstFormat3* csf3 )
-{
- HB_UShort n, count;
-
- HB_Coverage* c;
-
-
- FREE( csf3->SubstLookupRecord );
-
- if ( csf3->Coverage )
- {
- count = csf3->GlyphCount;
- c = csf3->Coverage;
-
- for ( n = 0; n < count; n++ )
- _HB_OPEN_Free_Coverage( &c[n] );
-
- FREE( c );
- }
-}
-
-
-/* ContextSubst */
-
-static HB_Error Load_ContextSubst( HB_GSUB_SubTable* st,
- HB_Stream stream )
-{
- HB_Error error;
- HB_ContextSubst* cs = &st->context;
-
-
- if ( ACCESS_Frame( 2L ) )
- return error;
-
- cs->SubstFormat = GET_UShort();
-
- FORGET_Frame();
-
- switch ( cs->SubstFormat )
- {
- case 1: return Load_ContextSubst1( &cs->csf.csf1, stream );
- case 2: return Load_ContextSubst2( &cs->csf.csf2, stream );
- case 3: return Load_ContextSubst3( &cs->csf.csf3, stream );
- default: return ERR(HB_Err_Invalid_SubTable_Format);
- }
-
- return HB_Err_Ok; /* never reached */
-}
-
-
-static void Free_ContextSubst( HB_GSUB_SubTable* st )
-{
- HB_ContextSubst* cs = &st->context;
-
- switch ( cs->SubstFormat )
- {
- case 1: Free_ContextSubst1( &cs->csf.csf1 ); break;
- case 2: Free_ContextSubst2( &cs->csf.csf2 ); break;
- case 3: Free_ContextSubst3( &cs->csf.csf3 ); break;
- default: break;
- }
-}
-
-
-static HB_Error Lookup_ContextSubst1( HB_GSUBHeader* gsub,
- HB_ContextSubstFormat1* csf1,
- HB_Buffer buffer,
- HB_UShort flags,
- HB_UShort context_length,
- int nesting_level )
-{
- HB_UShort index, property;
- HB_UShort i, j, k, numsr;
- HB_Error error;
-
- HB_SubRule* sr;
- HB_GDEFHeader* gdef;
-
-
- gdef = gsub->gdef;
-
- if ( CHECK_Property( gdef, IN_CURITEM(), flags, &property ) )
- return error;
-
- error = _HB_OPEN_Coverage_Index( &csf1->Coverage, IN_CURGLYPH(), &index );
- if ( error )
- return error;
-
- sr = csf1->SubRuleSet[index].SubRule;
- numsr = csf1->SubRuleSet[index].SubRuleCount;
-
- for ( k = 0; k < numsr; k++ )
- {
- if ( context_length != 0xFFFF && context_length < sr[k].GlyphCount )
- goto next_subrule;
-
- if ( buffer->in_pos + sr[k].GlyphCount > buffer->in_length )
- goto next_subrule; /* context is too long */
-
- for ( i = 1, j = buffer->in_pos + 1; i < sr[k].GlyphCount; i++, j++ )
- {
- while ( CHECK_Property( gdef, IN_ITEM( j ), flags, &property ) )
- {
- if ( error && error != HB_Err_Not_Covered )
- return error;
-
- if ( j + sr[k].GlyphCount - i == (HB_Int)buffer->in_length )
- goto next_subrule;
- j++;
- }
-
- if ( IN_GLYPH( j ) != sr[k].Input[i - 1] )
- goto next_subrule;
- }
-
- return Do_ContextSubst( gsub, sr[k].GlyphCount,
- sr[k].SubstCount, sr[k].SubstLookupRecord,
- buffer,
- nesting_level );
- next_subrule:
- ;
- }
-
- return HB_Err_Not_Covered;
-}
-
-
-static HB_Error Lookup_ContextSubst2( HB_GSUBHeader* gsub,
- HB_ContextSubstFormat2* csf2,
- HB_Buffer buffer,
- HB_UShort flags,
- HB_UShort context_length,
- int nesting_level )
-{
- HB_UShort index, property;
- HB_Error error;
- HB_UShort i, j, k, known_classes;
-
- HB_UShort* classes;
- HB_UShort* cl;
-
- HB_SubClassSet* scs;
- HB_SubClassRule* sr;
- HB_GDEFHeader* gdef;
-
-
- gdef = gsub->gdef;
-
- if ( CHECK_Property( gdef, IN_CURITEM(), flags, &property ) )
- return error;
-
- /* Note: The coverage table in format 2 doesn't give an index into
- anything. It just lets us know whether or not we need to
- do any lookup at all. */
-
- error = _HB_OPEN_Coverage_Index( &csf2->Coverage, IN_CURGLYPH(), &index );
- if ( error )
- return error;
-
- if (csf2->MaxContextLength < 1)
- return HB_Err_Not_Covered;
-
- if ( ALLOC_ARRAY( classes, csf2->MaxContextLength, HB_UShort ) )
- return error;
-
- error = _HB_OPEN_Get_Class( &csf2->ClassDef, IN_CURGLYPH(),
- &classes[0], NULL );
- if ( error && error != HB_Err_Not_Covered )
- goto End;
- known_classes = 0;
-
- scs = &csf2->SubClassSet[classes[0]];
- if ( !scs )
- {
- error = ERR(HB_Err_Invalid_SubTable);
- goto End;
- }
-
- for ( k = 0; k < scs->SubClassRuleCount; k++ )
- {
- sr = &scs->SubClassRule[k];
-
- if ( context_length != 0xFFFF && context_length < sr->GlyphCount )
- goto next_subclassrule;
-
- if ( buffer->in_pos + sr->GlyphCount > buffer->in_length )
- goto next_subclassrule; /* context is too long */
-
- cl = sr->Class;
-
- /* Start at 1 because [0] is implied */
-
- for ( i = 1, j = buffer->in_pos + 1; i < sr->GlyphCount; i++, j++ )
- {
- while ( CHECK_Property( gdef, IN_ITEM( j ), flags, &property ) )
- {
- if ( error && error != HB_Err_Not_Covered )
- goto End;
-
- if ( j + sr->GlyphCount - i < (HB_Int)buffer->in_length )
- goto next_subclassrule;
- j++;
- }
-
- if ( i > known_classes )
- {
- /* Keeps us from having to do this for each rule */
-
- error = _HB_OPEN_Get_Class( &csf2->ClassDef, IN_GLYPH( j ), &classes[i], NULL );
- if ( error && error != HB_Err_Not_Covered )
- goto End;
- known_classes = i;
- }
-
- if ( cl[i - 1] != classes[i] )
- goto next_subclassrule;
- }
-
- error = Do_ContextSubst( gsub, sr->GlyphCount,
- sr->SubstCount, sr->SubstLookupRecord,
- buffer,
- nesting_level );
- goto End;
-
- next_subclassrule:
- ;
- }
-
- error = HB_Err_Not_Covered;
-
-End:
- FREE( classes );
- return error;
-}
-
-
-static HB_Error Lookup_ContextSubst3( HB_GSUBHeader* gsub,
- HB_ContextSubstFormat3* csf3,
- HB_Buffer buffer,
- HB_UShort flags,
- HB_UShort context_length,
- int nesting_level )
-{
- HB_Error error;
- HB_UShort index, i, j, property;
-
- HB_Coverage* c;
- HB_GDEFHeader* gdef;
-
-
- gdef = gsub->gdef;
-
- if ( CHECK_Property( gdef, IN_CURITEM(), flags, &property ) )
- return error;
-
- if ( context_length != 0xFFFF && context_length < csf3->GlyphCount )
- return HB_Err_Not_Covered;
-
- if ( buffer->in_pos + csf3->GlyphCount > buffer->in_length )
- return HB_Err_Not_Covered; /* context is too long */
-
- c = csf3->Coverage;
-
- for ( i = 1, j = buffer->in_pos + 1; i < csf3->GlyphCount; i++, j++ )
- {
- while ( CHECK_Property( gdef, IN_ITEM( j ), flags, &property ) )
- {
- if ( error && error != HB_Err_Not_Covered )
- return error;
-
- if ( j + csf3->GlyphCount - i == (HB_Int)buffer->in_length )
- return HB_Err_Not_Covered;
- j++;
- }
-
- error = _HB_OPEN_Coverage_Index( &c[i], IN_GLYPH( j ), &index );
- if ( error )
- return error;
- }
-
- return Do_ContextSubst( gsub, csf3->GlyphCount,
- csf3->SubstCount, csf3->SubstLookupRecord,
- buffer,
- nesting_level );
-}
-
-
-static HB_Error Lookup_ContextSubst( HB_GSUBHeader* gsub,
- HB_GSUB_SubTable* st,
- HB_Buffer buffer,
- HB_UShort flags,
- HB_UShort context_length,
- int nesting_level )
-{
- HB_ContextSubst* cs = &st->context;
-
- switch ( cs->SubstFormat )
- {
- case 1: return Lookup_ContextSubst1( gsub, &cs->csf.csf1, buffer, flags, context_length, nesting_level );
- case 2: return Lookup_ContextSubst2( gsub, &cs->csf.csf2, buffer, flags, context_length, nesting_level );
- case 3: return Lookup_ContextSubst3( gsub, &cs->csf.csf3, buffer, flags, context_length, nesting_level );
- default: return ERR(HB_Err_Invalid_SubTable_Format);
- }
-
- return HB_Err_Ok; /* never reached */
-}
-
-
-/* LookupType 6 */
-
-/* ChainSubRule */
-
-static HB_Error Load_ChainSubRule( HB_ChainSubRule* csr,
- HB_Stream stream )
-{
- HB_Error error;
-
- HB_UShort n, count;
- HB_UShort* b;
- HB_UShort* i;
- HB_UShort* l;
-
- HB_SubstLookupRecord* slr;
-
-
- if ( ACCESS_Frame( 2L ) )
- return error;
-
- csr->BacktrackGlyphCount = GET_UShort();
-
- FORGET_Frame();
-
- csr->Backtrack = NULL;
-
- count = csr->BacktrackGlyphCount;
-
- if ( ALLOC_ARRAY( csr->Backtrack, count, HB_UShort ) )
- return error;
-
- b = csr->Backtrack;
-
- if ( ACCESS_Frame( count * 2L ) )
- goto Fail4;
-
- for ( n = 0; n < count; n++ )
- b[n] = GET_UShort();
-
- FORGET_Frame();
-
- if ( ACCESS_Frame( 2L ) )
- goto Fail4;
-
- csr->InputGlyphCount = GET_UShort();
-
- FORGET_Frame();
-
- csr->Input = NULL;
-
- count = csr->InputGlyphCount - 1; /* only InputGlyphCount - 1 elements */
-
- if ( ALLOC_ARRAY( csr->Input, count, HB_UShort ) )
- goto Fail4;
-
- i = csr->Input;
-
- if ( ACCESS_Frame( count * 2L ) )
- goto Fail3;
-
- for ( n = 0; n < count; n++ )
- i[n] = GET_UShort();
-
- FORGET_Frame();
-
- if ( ACCESS_Frame( 2L ) )
- goto Fail3;
-
- csr->LookaheadGlyphCount = GET_UShort();
-
- FORGET_Frame();
-
- csr->Lookahead = NULL;
-
- count = csr->LookaheadGlyphCount;
-
- if ( ALLOC_ARRAY( csr->Lookahead, count, HB_UShort ) )
- goto Fail3;
-
- l = csr->Lookahead;
-
- if ( ACCESS_Frame( count * 2L ) )
- goto Fail2;
-
- for ( n = 0; n < count; n++ )
- l[n] = GET_UShort();
-
- FORGET_Frame();
-
- if ( ACCESS_Frame( 2L ) )
- goto Fail2;
-
- csr->SubstCount = GET_UShort();
-
- FORGET_Frame();
-
- csr->SubstLookupRecord = NULL;
-
- count = csr->SubstCount;
-
- if ( ALLOC_ARRAY( csr->SubstLookupRecord, count, HB_SubstLookupRecord ) )
- goto Fail2;
-
- slr = csr->SubstLookupRecord;
-
- if ( ACCESS_Frame( count * 4L ) )
- goto Fail1;
-
- for ( n = 0; n < count; n++ )
- {
- slr[n].SequenceIndex = GET_UShort();
- slr[n].LookupListIndex = GET_UShort();
- }
-
- FORGET_Frame();
-
- return HB_Err_Ok;
-
-Fail1:
- FREE( slr );
-
-Fail2:
- FREE( l );
-
-Fail3:
- FREE( i );
-
-Fail4:
- FREE( b );
- return error;
-}
-
-
-static void Free_ChainSubRule( HB_ChainSubRule* csr )
-{
- FREE( csr->SubstLookupRecord );
- FREE( csr->Lookahead );
- FREE( csr->Input );
- FREE( csr->Backtrack );
-}
-
-
-/* ChainSubRuleSet */
-
-static HB_Error Load_ChainSubRuleSet( HB_ChainSubRuleSet* csrs,
- HB_Stream stream )
-{
- HB_Error error;
-
- HB_UShort n = 0, m, count;
- HB_UInt cur_offset, new_offset, base_offset;
-
- HB_ChainSubRule* csr;
-
-
- base_offset = FILE_Pos();
-
- if ( ACCESS_Frame( 2L ) )
- return error;
-
- count = csrs->ChainSubRuleCount = GET_UShort();
-
- FORGET_Frame();
-
- csrs->ChainSubRule = NULL;
-
- if ( ALLOC_ARRAY( csrs->ChainSubRule, count, HB_ChainSubRule ) )
- return error;
-
- csr = csrs->ChainSubRule;
-
- for ( n = 0; n < count; n++ )
- {
- if ( ACCESS_Frame( 2L ) )
- goto Fail;
-
- new_offset = GET_UShort() + base_offset;
-
- FORGET_Frame();
-
- cur_offset = FILE_Pos();
- if ( FILE_Seek( new_offset ) ||
- ( error = Load_ChainSubRule( &csr[n], stream ) ) != HB_Err_Ok )
- goto Fail;
- (void)FILE_Seek( cur_offset );
- }
-
- return HB_Err_Ok;
-
-Fail:
- for ( m = 0; m < n; m++ )
- Free_ChainSubRule( &csr[m] );
-
- FREE( csr );
- return error;
-}
-
-
-static void Free_ChainSubRuleSet( HB_ChainSubRuleSet* csrs )
-{
- HB_UShort n, count;
-
- HB_ChainSubRule* csr;
-
-
- if ( csrs->ChainSubRule )
- {
- count = csrs->ChainSubRuleCount;
- csr = csrs->ChainSubRule;
-
- for ( n = 0; n < count; n++ )
- Free_ChainSubRule( &csr[n] );
-
- FREE( csr );
- }
-}
-
-
-/* ChainContextSubstFormat1 */
-
-static HB_Error Load_ChainContextSubst1(
- HB_ChainContextSubstFormat1* ccsf1,
- HB_Stream stream )
-{
- HB_Error error;
-
- HB_UShort n = 0, m, count;
- HB_UInt cur_offset, new_offset, base_offset;
-
- HB_ChainSubRuleSet* csrs;
-
-
- base_offset = FILE_Pos() - 2L;
-
- if ( ACCESS_Frame( 2L ) )
- return error;
-
- new_offset = GET_UShort() + base_offset;
-
- FORGET_Frame();
-
- cur_offset = FILE_Pos();
- if ( FILE_Seek( new_offset ) ||
- ( error = _HB_OPEN_Load_Coverage( &ccsf1->Coverage, stream ) ) != HB_Err_Ok )
- return error;
- (void)FILE_Seek( cur_offset );
-
- if ( ACCESS_Frame( 2L ) )
- goto Fail2;
-
- count = ccsf1->ChainSubRuleSetCount = GET_UShort();
-
- FORGET_Frame();
-
- ccsf1->ChainSubRuleSet = NULL;
-
- if ( ALLOC_ARRAY( ccsf1->ChainSubRuleSet, count, HB_ChainSubRuleSet ) )
- goto Fail2;
-
- csrs = ccsf1->ChainSubRuleSet;
-
- for ( n = 0; n < count; n++ )
- {
- if ( ACCESS_Frame( 2L ) )
- goto Fail1;
-
- new_offset = GET_UShort() + base_offset;
-
- FORGET_Frame();
-
- cur_offset = FILE_Pos();
- if ( FILE_Seek( new_offset ) ||
- ( error = Load_ChainSubRuleSet( &csrs[n], stream ) ) != HB_Err_Ok )
- goto Fail1;
- (void)FILE_Seek( cur_offset );
- }
-
- return HB_Err_Ok;
-
-Fail1:
- for ( m = 0; m < n; m++ )
- Free_ChainSubRuleSet( &csrs[m] );
-
- FREE( csrs );
-
-Fail2:
- _HB_OPEN_Free_Coverage( &ccsf1->Coverage );
- return error;
-}
-
-
-static void Free_ChainContextSubst1( HB_ChainContextSubstFormat1* ccsf1 )
-{
- HB_UShort n, count;
-
- HB_ChainSubRuleSet* csrs;
-
-
- if ( ccsf1->ChainSubRuleSet )
- {
- count = ccsf1->ChainSubRuleSetCount;
- csrs = ccsf1->ChainSubRuleSet;
-
- for ( n = 0; n < count; n++ )
- Free_ChainSubRuleSet( &csrs[n] );
-
- FREE( csrs );
- }
-
- _HB_OPEN_Free_Coverage( &ccsf1->Coverage );
-}
-
-
-/* ChainSubClassRule */
-
-static HB_Error Load_ChainSubClassRule(
- HB_ChainContextSubstFormat2* ccsf2,
- HB_ChainSubClassRule* cscr,
- HB_Stream stream )
-{
- HB_Error error;
-
- HB_UShort n, count;
-
- HB_UShort* b;
- HB_UShort* i;
- HB_UShort* l;
- HB_SubstLookupRecord* slr;
-
-
- if ( ACCESS_Frame( 2L ) )
- return error;
-
- cscr->BacktrackGlyphCount = GET_UShort();
-
- FORGET_Frame();
-
- if ( cscr->BacktrackGlyphCount > ccsf2->MaxBacktrackLength )
- ccsf2->MaxBacktrackLength = cscr->BacktrackGlyphCount;
-
- cscr->Backtrack = NULL;
-
- count = cscr->BacktrackGlyphCount;
-
- if ( ALLOC_ARRAY( cscr->Backtrack, count, HB_UShort ) )
- return error;
-
- b = cscr->Backtrack;
-
- if ( ACCESS_Frame( count * 2L ) )
- goto Fail4;
-
- for ( n = 0; n < count; n++ )
- b[n] = GET_UShort();
-
- FORGET_Frame();
-
- if ( ACCESS_Frame( 2L ) )
- goto Fail4;
-
- cscr->InputGlyphCount = GET_UShort();
-
- FORGET_Frame();
-
- if ( cscr->InputGlyphCount > ccsf2->MaxInputLength )
- ccsf2->MaxInputLength = cscr->InputGlyphCount;
-
- cscr->Input = NULL;
-
- count = cscr->InputGlyphCount - 1; /* only InputGlyphCount - 1 elements */
-
- if ( ALLOC_ARRAY( cscr->Input, count, HB_UShort ) )
- goto Fail4;
-
- i = cscr->Input;
-
- if ( ACCESS_Frame( count * 2L ) )
- goto Fail3;
-
- for ( n = 0; n < count; n++ )
- i[n] = GET_UShort();
-
- FORGET_Frame();
-
- if ( ACCESS_Frame( 2L ) )
- goto Fail3;
-
- cscr->LookaheadGlyphCount = GET_UShort();
-
- FORGET_Frame();
-
- if ( cscr->LookaheadGlyphCount > ccsf2->MaxLookaheadLength )
- ccsf2->MaxLookaheadLength = cscr->LookaheadGlyphCount;
-
- cscr->Lookahead = NULL;
-
- count = cscr->LookaheadGlyphCount;
-
- if ( ALLOC_ARRAY( cscr->Lookahead, count, HB_UShort ) )
- goto Fail3;
-
- l = cscr->Lookahead;
-
- if ( ACCESS_Frame( count * 2L ) )
- goto Fail2;
-
- for ( n = 0; n < count; n++ )
- l[n] = GET_UShort();
-
- FORGET_Frame();
-
- if ( ACCESS_Frame( 2L ) )
- goto Fail2;
-
- cscr->SubstCount = GET_UShort();
-
- FORGET_Frame();
-
- cscr->SubstLookupRecord = NULL;
-
- count = cscr->SubstCount;
-
- if ( ALLOC_ARRAY( cscr->SubstLookupRecord, count,
- HB_SubstLookupRecord ) )
- goto Fail2;
-
- slr = cscr->SubstLookupRecord;
-
- if ( ACCESS_Frame( count * 4L ) )
- goto Fail1;
-
- for ( n = 0; n < count; n++ )
- {
- slr[n].SequenceIndex = GET_UShort();
- slr[n].LookupListIndex = GET_UShort();
- }
-
- FORGET_Frame();
-
- return HB_Err_Ok;
-
-Fail1:
- FREE( slr );
-
-Fail2:
- FREE( l );
-
-Fail3:
- FREE( i );
-
-Fail4:
- FREE( b );
- return error;
-}
-
-
-static void Free_ChainSubClassRule( HB_ChainSubClassRule* cscr )
-{
- FREE( cscr->SubstLookupRecord );
- FREE( cscr->Lookahead );
- FREE( cscr->Input );
- FREE( cscr->Backtrack );
-}
-
-
-/* SubClassSet */
-
-static HB_Error Load_ChainSubClassSet(
- HB_ChainContextSubstFormat2* ccsf2,
- HB_ChainSubClassSet* cscs,
- HB_Stream stream )
-{
- HB_Error error;
-
- HB_UShort n = 0, m, count;
- HB_UInt cur_offset, new_offset, base_offset;
-
- HB_ChainSubClassRule* cscr;
-
-
- base_offset = FILE_Pos();
-
- if ( ACCESS_Frame( 2L ) )
- return error;
-
- count = cscs->ChainSubClassRuleCount = GET_UShort();
-
- FORGET_Frame();
-
- cscs->ChainSubClassRule = NULL;
-
- if ( ALLOC_ARRAY( cscs->ChainSubClassRule, count,
- HB_ChainSubClassRule ) )
- return error;
-
- cscr = cscs->ChainSubClassRule;
-
- for ( n = 0; n < count; n++ )
- {
- if ( ACCESS_Frame( 2L ) )
- goto Fail;
-
- new_offset = GET_UShort() + base_offset;
-
- FORGET_Frame();
-
- cur_offset = FILE_Pos();
- if ( FILE_Seek( new_offset ) ||
- ( error = Load_ChainSubClassRule( ccsf2, &cscr[n],
- stream ) ) != HB_Err_Ok )
- goto Fail;
- (void)FILE_Seek( cur_offset );
- }
-
- return HB_Err_Ok;
-
-Fail:
- for ( m = 0; m < n; m++ )
- Free_ChainSubClassRule( &cscr[m] );
-
- FREE( cscr );
- return error;
-}
-
-
-static void Free_ChainSubClassSet( HB_ChainSubClassSet* cscs )
-{
- HB_UShort n, count;
-
- HB_ChainSubClassRule* cscr;
-
-
- if ( cscs->ChainSubClassRule )
- {
- count = cscs->ChainSubClassRuleCount;
- cscr = cscs->ChainSubClassRule;
-
- for ( n = 0; n < count; n++ )
- Free_ChainSubClassRule( &cscr[n] );
-
- FREE( cscr );
- }
-}
-
-
-/* ChainContextSubstFormat2 */
-
-static HB_Error Load_ChainContextSubst2(
- HB_ChainContextSubstFormat2* ccsf2,
- HB_Stream stream )
-{
- HB_Error error;
-
- HB_UShort n = 0, m, count;
- HB_UInt cur_offset, new_offset, base_offset;
- HB_UInt backtrack_offset, input_offset, lookahead_offset;
-
- HB_ChainSubClassSet* cscs;
-
-
- base_offset = FILE_Pos() - 2;
-
- if ( ACCESS_Frame( 2L ) )
- return error;
-
- new_offset = GET_UShort() + base_offset;
-
- FORGET_Frame();
-
- cur_offset = FILE_Pos();
- if ( FILE_Seek( new_offset ) ||
- ( error = _HB_OPEN_Load_Coverage( &ccsf2->Coverage, stream ) ) != HB_Err_Ok )
- return error;
- (void)FILE_Seek( cur_offset );
-
- if ( ACCESS_Frame( 8L ) )
- goto Fail5;
-
- backtrack_offset = GET_UShort();
- input_offset = GET_UShort();
- lookahead_offset = GET_UShort();
-
- /* `ChainSubClassSetCount' is the upper limit for input class values,
- thus we read it now to make an additional safety check. No limit
- is known or needed for the other two class definitions */
-
- count = ccsf2->ChainSubClassSetCount = GET_UShort();
-
- FORGET_Frame();
-
- if ( ( error = _HB_OPEN_Load_EmptyOrClassDefinition( &ccsf2->BacktrackClassDef, 65535,
- backtrack_offset, base_offset,
- stream ) ) != HB_Err_Ok )
- goto Fail5;
-
- if ( ( error = _HB_OPEN_Load_EmptyOrClassDefinition( &ccsf2->InputClassDef, count,
- input_offset, base_offset,
- stream ) ) != HB_Err_Ok )
- goto Fail4;
- if ( ( error = _HB_OPEN_Load_EmptyOrClassDefinition( &ccsf2->LookaheadClassDef, 65535,
- lookahead_offset, base_offset,
- stream ) ) != HB_Err_Ok )
- goto Fail3;
-
- ccsf2->ChainSubClassSet = NULL;
- ccsf2->MaxBacktrackLength = 0;
- ccsf2->MaxInputLength = 0;
- ccsf2->MaxLookaheadLength = 0;
-
- if ( ALLOC_ARRAY( ccsf2->ChainSubClassSet, count, HB_ChainSubClassSet ) )
- goto Fail2;
-
- cscs = ccsf2->ChainSubClassSet;
-
- for ( n = 0; n < count; n++ )
- {
- if ( ACCESS_Frame( 2L ) )
- goto Fail1;
-
- new_offset = GET_UShort() + base_offset;
-
- FORGET_Frame();
-
- if ( new_offset != base_offset ) /* not a NULL offset */
- {
- cur_offset = FILE_Pos();
- if ( FILE_Seek( new_offset ) ||
- ( error = Load_ChainSubClassSet( ccsf2, &cscs[n],
- stream ) ) != HB_Err_Ok )
- goto Fail1;
- (void)FILE_Seek( cur_offset );
- }
- else
- {
- /* we create a ChainSubClassSet table with no entries */
-
- ccsf2->ChainSubClassSet[n].ChainSubClassRuleCount = 0;
- ccsf2->ChainSubClassSet[n].ChainSubClassRule = NULL;
- }
- }
-
- return HB_Err_Ok;
-
-Fail1:
- for ( m = 0; m < n; m++ )
- Free_ChainSubClassSet( &cscs[m] );
-
- FREE( cscs );
-
-Fail2:
- _HB_OPEN_Free_ClassDefinition( &ccsf2->LookaheadClassDef );
-
-Fail3:
- _HB_OPEN_Free_ClassDefinition( &ccsf2->InputClassDef );
-
-Fail4:
- _HB_OPEN_Free_ClassDefinition( &ccsf2->BacktrackClassDef );
-
-Fail5:
- _HB_OPEN_Free_Coverage( &ccsf2->Coverage );
- return error;
-}
-
-
-static void Free_ChainContextSubst2( HB_ChainContextSubstFormat2* ccsf2 )
-{
- HB_UShort n, count;
-
- HB_ChainSubClassSet* cscs;
-
-
- if ( ccsf2->ChainSubClassSet )
- {
- count = ccsf2->ChainSubClassSetCount;
- cscs = ccsf2->ChainSubClassSet;
-
- for ( n = 0; n < count; n++ )
- Free_ChainSubClassSet( &cscs[n] );
-
- FREE( cscs );
- }
-
- _HB_OPEN_Free_ClassDefinition( &ccsf2->LookaheadClassDef );
- _HB_OPEN_Free_ClassDefinition( &ccsf2->InputClassDef );
- _HB_OPEN_Free_ClassDefinition( &ccsf2->BacktrackClassDef );
-
- _HB_OPEN_Free_Coverage( &ccsf2->Coverage );
-}
-
-
-/* ChainContextSubstFormat3 */
-
-static HB_Error Load_ChainContextSubst3(
- HB_ChainContextSubstFormat3* ccsf3,
- HB_Stream stream )
-{
- HB_Error error;
-
- HB_UShort n, nb = 0, ni =0, nl = 0, m, count;
- HB_UShort backtrack_count, input_count, lookahead_count;
- HB_UInt cur_offset, new_offset, base_offset;
-
- HB_Coverage* b;
- HB_Coverage* i;
- HB_Coverage* l;
- HB_SubstLookupRecord* slr;
-
-
- base_offset = FILE_Pos() - 2L;
-
- if ( ACCESS_Frame( 2L ) )
- return error;
-
- ccsf3->BacktrackGlyphCount = GET_UShort();
-
- FORGET_Frame();
-
- ccsf3->BacktrackCoverage = NULL;
-
- backtrack_count = ccsf3->BacktrackGlyphCount;
-
- if ( ALLOC_ARRAY( ccsf3->BacktrackCoverage, backtrack_count,
- HB_Coverage ) )
- return error;
-
- b = ccsf3->BacktrackCoverage;
-
- for ( nb = 0; nb < backtrack_count; nb++ )
- {
- if ( ACCESS_Frame( 2L ) )
- goto Fail4;
-
- new_offset = GET_UShort() + base_offset;
-
- FORGET_Frame();
-
- cur_offset = FILE_Pos();
- if ( FILE_Seek( new_offset ) ||
- ( error = _HB_OPEN_Load_Coverage( &b[nb], stream ) ) != HB_Err_Ok )
- goto Fail4;
- (void)FILE_Seek( cur_offset );
- }
-
- if ( ACCESS_Frame( 2L ) )
- goto Fail4;
-
- ccsf3->InputGlyphCount = GET_UShort();
-
- FORGET_Frame();
-
- ccsf3->InputCoverage = NULL;
-
- input_count = ccsf3->InputGlyphCount;
-
- if ( ALLOC_ARRAY( ccsf3->InputCoverage, input_count, HB_Coverage ) )
- goto Fail4;
-
- i = ccsf3->InputCoverage;
-
- for ( ni = 0; ni < input_count; ni++ )
- {
- if ( ACCESS_Frame( 2L ) )
- goto Fail3;
-
- new_offset = GET_UShort() + base_offset;
-
- FORGET_Frame();
-
- cur_offset = FILE_Pos();
- if ( FILE_Seek( new_offset ) ||
- ( error = _HB_OPEN_Load_Coverage( &i[ni], stream ) ) != HB_Err_Ok )
- goto Fail3;
- (void)FILE_Seek( cur_offset );
- }
-
- if ( ACCESS_Frame( 2L ) )
- goto Fail3;
-
- ccsf3->LookaheadGlyphCount = GET_UShort();
-
- FORGET_Frame();
-
- ccsf3->LookaheadCoverage = NULL;
-
- lookahead_count = ccsf3->LookaheadGlyphCount;
-
- if ( ALLOC_ARRAY( ccsf3->LookaheadCoverage, lookahead_count,
- HB_Coverage ) )
- goto Fail3;
-
- l = ccsf3->LookaheadCoverage;
-
- for ( nl = 0; nl < lookahead_count; nl++ )
- {
- if ( ACCESS_Frame( 2L ) )
- goto Fail2;
-
- new_offset = GET_UShort() + base_offset;
-
- FORGET_Frame();
-
- cur_offset = FILE_Pos();
- if ( FILE_Seek( new_offset ) ||
- ( error = _HB_OPEN_Load_Coverage( &l[nl], stream ) ) != HB_Err_Ok )
- goto Fail2;
- (void)FILE_Seek( cur_offset );
- }
-
- if ( ACCESS_Frame( 2L ) )
- goto Fail2;
-
- ccsf3->SubstCount = GET_UShort();
-
- FORGET_Frame();
-
- ccsf3->SubstLookupRecord = NULL;
-
- count = ccsf3->SubstCount;
-
- if ( ALLOC_ARRAY( ccsf3->SubstLookupRecord, count,
- HB_SubstLookupRecord ) )
- goto Fail2;
-
- slr = ccsf3->SubstLookupRecord;
-
- if ( ACCESS_Frame( count * 4L ) )
- goto Fail1;
-
- for ( n = 0; n < count; n++ )
- {
- slr[n].SequenceIndex = GET_UShort();
- slr[n].LookupListIndex = GET_UShort();
- }
-
- FORGET_Frame();
-
- return HB_Err_Ok;
-
-Fail1:
- FREE( slr );
-
-Fail2:
- for ( m = 0; m < nl; m++ )
- _HB_OPEN_Free_Coverage( &l[m] );
-
- FREE( l );
-
-Fail3:
- for ( m = 0; m < ni; m++ )
- _HB_OPEN_Free_Coverage( &i[m] );
-
- FREE( i );
-
-Fail4:
- for ( m = 0; m < nb; m++ )
- _HB_OPEN_Free_Coverage( &b[m] );
-
- FREE( b );
- return error;
-}
-
-
-static void Free_ChainContextSubst3( HB_ChainContextSubstFormat3* ccsf3 )
-{
- HB_UShort n, count;
-
- HB_Coverage* c;
-
-
- FREE( ccsf3->SubstLookupRecord );
-
- if ( ccsf3->LookaheadCoverage )
- {
- count = ccsf3->LookaheadGlyphCount;
- c = ccsf3->LookaheadCoverage;
-
- for ( n = 0; n < count; n++ )
- _HB_OPEN_Free_Coverage( &c[n] );
-
- FREE( c );
- }
-
- if ( ccsf3->InputCoverage )
- {
- count = ccsf3->InputGlyphCount;
- c = ccsf3->InputCoverage;
-
- for ( n = 0; n < count; n++ )
- _HB_OPEN_Free_Coverage( &c[n] );
-
- FREE( c );
- }
-
- if ( ccsf3->BacktrackCoverage )
- {
- count = ccsf3->BacktrackGlyphCount;
- c = ccsf3->BacktrackCoverage;
-
- for ( n = 0; n < count; n++ )
- _HB_OPEN_Free_Coverage( &c[n] );
-
- FREE( c );
- }
-}
-
-
-/* ChainContextSubst */
-
-static HB_Error Load_ChainContextSubst( HB_GSUB_SubTable* st,
- HB_Stream stream )
-{
- HB_Error error;
- HB_ChainContextSubst* ccs = &st->chain;
-
- if ( ACCESS_Frame( 2L ) )
- return error;
-
- ccs->SubstFormat = GET_UShort();
-
- FORGET_Frame();
-
- switch ( ccs->SubstFormat ) {
- case 1: return Load_ChainContextSubst1( &ccs->ccsf.ccsf1, stream );
- case 2: return Load_ChainContextSubst2( &ccs->ccsf.ccsf2, stream );
- case 3: return Load_ChainContextSubst3( &ccs->ccsf.ccsf3, stream );
- default: return ERR(HB_Err_Invalid_SubTable_Format);
- }
-
- return HB_Err_Ok; /* never reached */
-}
-
-
-static void Free_ChainContextSubst( HB_GSUB_SubTable* st )
-{
- HB_ChainContextSubst* ccs = &st->chain;
-
- switch ( ccs->SubstFormat ) {
- case 1: Free_ChainContextSubst1( &ccs->ccsf.ccsf1 ); break;
- case 2: Free_ChainContextSubst2( &ccs->ccsf.ccsf2 ); break;
- case 3: Free_ChainContextSubst3( &ccs->ccsf.ccsf3 ); break;
- default: break;
- }
-}
-
-
-static HB_Error Lookup_ChainContextSubst1( HB_GSUBHeader* gsub,
- HB_ChainContextSubstFormat1* ccsf1,
- HB_Buffer buffer,
- HB_UShort flags,
- HB_UShort context_length,
- int nesting_level )
-{
- HB_UShort index, property;
- HB_UShort i, j, k, num_csr;
- HB_UShort bgc, igc, lgc;
- HB_Error error;
-
- HB_ChainSubRule* csr;
- HB_ChainSubRule curr_csr;
- HB_GDEFHeader* gdef;
-
-
- gdef = gsub->gdef;
-
- if ( CHECK_Property( gdef, IN_CURITEM(), flags, &property ) )
- return error;
-
- error = _HB_OPEN_Coverage_Index( &ccsf1->Coverage, IN_CURGLYPH(), &index );
- if ( error )
- return error;
-
- csr = ccsf1->ChainSubRuleSet[index].ChainSubRule;
- num_csr = ccsf1->ChainSubRuleSet[index].ChainSubRuleCount;
-
- for ( k = 0; k < num_csr; k++ )
- {
- curr_csr = csr[k];
- bgc = curr_csr.BacktrackGlyphCount;
- igc = curr_csr.InputGlyphCount;
- lgc = curr_csr.LookaheadGlyphCount;
-
- if ( context_length != 0xFFFF && context_length < igc )
- goto next_chainsubrule;
-
- /* check whether context is too long; it is a first guess only */
-
- if ( bgc > buffer->out_pos || buffer->in_pos + igc + lgc > buffer->in_length )
- goto next_chainsubrule;
-
- if ( bgc )
- {
- /* since we don't know in advance the number of glyphs to inspect,
- we search backwards for matches in the backtrack glyph array */
-
- for ( i = 0, j = buffer->out_pos - 1; i < bgc; i++, j-- )
- {
- while ( CHECK_Property( gdef, OUT_ITEM( j ), flags, &property ) )
- {
- if ( error && error != HB_Err_Not_Covered )
- return error;
-
- if ( j + 1 == bgc - i )
- goto next_chainsubrule;
- j--;
- }
-
- /* In OpenType 1.3, it is undefined whether the offsets of
- backtrack glyphs is in logical order or not. Version 1.4
- will clarify this:
-
- Logical order - a b c d e f g h i j
- i
- Input offsets - 0 1
- Backtrack offsets - 3 2 1 0
- Lookahead offsets - 0 1 2 3 */
-
- if ( OUT_GLYPH( j ) != curr_csr.Backtrack[i] )
- goto next_chainsubrule;
- }
- }
-
- /* Start at 1 because [0] is implied */
-
- for ( i = 1, j = buffer->in_pos + 1; i < igc; i++, j++ )
- {
- while ( CHECK_Property( gdef, IN_ITEM( j ), flags, &property ) )
- {
- if ( error && error != HB_Err_Not_Covered )
- return error;
-
- if ( j + igc - i + lgc == (HB_Int)buffer->in_length )
- goto next_chainsubrule;
- j++;
- }
-
- if ( IN_GLYPH( j ) != curr_csr.Input[i - 1] )
- goto next_chainsubrule;
- }
-
- /* we are starting to check for lookahead glyphs right after the
- last context glyph */
-
- for ( i = 0; i < lgc; i++, j++ )
- {
- while ( CHECK_Property( gdef, IN_ITEM( j ), flags, &property ) )
- {
- if ( error && error != HB_Err_Not_Covered )
- return error;
-
- if ( j + lgc - i == (HB_Int)buffer->in_length )
- goto next_chainsubrule;
- j++;
- }
-
- if ( IN_GLYPH( j ) != curr_csr.Lookahead[i] )
- goto next_chainsubrule;
- }
-
- return Do_ContextSubst( gsub, igc,
- curr_csr.SubstCount,
- curr_csr.SubstLookupRecord,
- buffer,
- nesting_level );
-
- next_chainsubrule:
- ;
- }
-
- return HB_Err_Not_Covered;
-}
-
-
-static HB_Error Lookup_ChainContextSubst2( HB_GSUBHeader* gsub,
- HB_ChainContextSubstFormat2* ccsf2,
- HB_Buffer buffer,
- HB_UShort flags,
- HB_UShort context_length,
- int nesting_level )
-{
- HB_UShort index, property;
- HB_Error error;
- HB_UShort i, j, k;
- HB_UShort bgc, igc, lgc;
- HB_UShort known_backtrack_classes,
- known_input_classes,
- known_lookahead_classes;
-
- HB_UShort* backtrack_classes;
- HB_UShort* input_classes;
- HB_UShort* lookahead_classes;
-
- HB_UShort* bc;
- HB_UShort* ic;
- HB_UShort* lc;
-
- HB_ChainSubClassSet* cscs;
- HB_ChainSubClassRule ccsr;
- HB_GDEFHeader* gdef;
-
-
- gdef = gsub->gdef;
-
- if ( CHECK_Property( gdef, IN_CURITEM(), flags, &property ) )
- return error;
-
- /* Note: The coverage table in format 2 doesn't give an index into
- anything. It just lets us know whether or not we need to
- do any lookup at all. */
-
- error = _HB_OPEN_Coverage_Index( &ccsf2->Coverage, IN_CURGLYPH(), &index );
- if ( error )
- return error;
-
- if (ccsf2->MaxInputLength < 1)
- return HB_Err_Not_Covered;
-
- if ( ALLOC_ARRAY( backtrack_classes, ccsf2->MaxBacktrackLength, HB_UShort ) )
- return error;
- known_backtrack_classes = 0;
-
- if ( ALLOC_ARRAY( input_classes, ccsf2->MaxInputLength, HB_UShort ) )
- goto End3;
- known_input_classes = 1;
-
- if ( ALLOC_ARRAY( lookahead_classes, ccsf2->MaxLookaheadLength, HB_UShort ) )
- goto End2;
- known_lookahead_classes = 0;
-
- error = _HB_OPEN_Get_Class( &ccsf2->InputClassDef, IN_CURGLYPH(),
- &input_classes[0], NULL );
- if ( error && error != HB_Err_Not_Covered )
- goto End1;
-
- cscs = &ccsf2->ChainSubClassSet[input_classes[0]];
- if ( !cscs )
- {
- error = ERR(HB_Err_Invalid_SubTable);
- goto End1;
- }
-
- for ( k = 0; k < cscs->ChainSubClassRuleCount; k++ )
- {
- ccsr = cscs->ChainSubClassRule[k];
- bgc = ccsr.BacktrackGlyphCount;
- igc = ccsr.InputGlyphCount;
- lgc = ccsr.LookaheadGlyphCount;
-
- if ( context_length != 0xFFFF && context_length < igc )
- goto next_chainsubclassrule;
-
- /* check whether context is too long; it is a first guess only */
-
- if ( bgc > buffer->out_pos || buffer->in_pos + igc + lgc > buffer->in_length )
- goto next_chainsubclassrule;
-
- if ( bgc )
- {
- /* Since we don't know in advance the number of glyphs to inspect,
- we search backwards for matches in the backtrack glyph array.
- Note that `known_backtrack_classes' starts at index 0. */
-
- bc = ccsr.Backtrack;
-
- for ( i = 0, j = buffer->out_pos - 1; i < bgc; i++, j-- )
- {
- while ( CHECK_Property( gdef, OUT_ITEM( j ), flags, &property ) )
- {
- if ( error && error != HB_Err_Not_Covered )
- goto End1;
-
- if ( j + 1 == bgc - i )
- goto next_chainsubclassrule;
- j--;
- }
-
- if ( i >= known_backtrack_classes )
- {
- /* Keeps us from having to do this for each rule */
-
- error = _HB_OPEN_Get_Class( &ccsf2->BacktrackClassDef, OUT_GLYPH( j ),
- &backtrack_classes[i], NULL );
- if ( error && error != HB_Err_Not_Covered )
- goto End1;
- known_backtrack_classes = i;
- }
-
- if ( bc[i] != backtrack_classes[i] )
- goto next_chainsubclassrule;
- }
- }
-
- ic = ccsr.Input;
-
- /* Start at 1 because [0] is implied */
-
- for ( i = 1, j = buffer->in_pos + 1; i < igc; i++, j++ )
- {
- while ( CHECK_Property( gdef, IN_ITEM( j ), flags, &property ) )
- {
- if ( error && error != HB_Err_Not_Covered )
- goto End1;
-
- if ( j + igc - i + lgc == (HB_Int)buffer->in_length )
- goto next_chainsubclassrule;
- j++;
- }
-
- if ( i >= known_input_classes )
- {
- error = _HB_OPEN_Get_Class( &ccsf2->InputClassDef, IN_GLYPH( j ),
- &input_classes[i], NULL );
- if ( error && error != HB_Err_Not_Covered )
- goto End1;
- known_input_classes = i;
- }
-
- if ( ic[i - 1] != input_classes[i] )
- goto next_chainsubclassrule;
- }
-
- /* we are starting to check for lookahead glyphs right after the
- last context glyph */
-
- lc = ccsr.Lookahead;
-
- for ( i = 0; i < lgc; i++, j++ )
- {
- while ( CHECK_Property( gdef, IN_ITEM( j ), flags, &property ) )
- {
- if ( error && error != HB_Err_Not_Covered )
- goto End1;
-
- if ( j + lgc - i == (HB_Int)buffer->in_length )
- goto next_chainsubclassrule;
- j++;
- }
-
- if ( i >= known_lookahead_classes )
- {
- error = _HB_OPEN_Get_Class( &ccsf2->LookaheadClassDef, IN_GLYPH( j ),
- &lookahead_classes[i], NULL );
- if ( error && error != HB_Err_Not_Covered )
- goto End1;
- known_lookahead_classes = i;
- }
-
- if ( lc[i] != lookahead_classes[i] )
- goto next_chainsubclassrule;
- }
-
- error = Do_ContextSubst( gsub, igc,
- ccsr.SubstCount,
- ccsr.SubstLookupRecord,
- buffer,
- nesting_level );
- goto End1;
-
- next_chainsubclassrule:
- ;
- }
-
- error = HB_Err_Not_Covered;
-
-End1:
- FREE( lookahead_classes );
-
-End2:
- FREE( input_classes );
-
-End3:
- FREE( backtrack_classes );
- return error;
-}
-
-
-static HB_Error Lookup_ChainContextSubst3( HB_GSUBHeader* gsub,
- HB_ChainContextSubstFormat3* ccsf3,
- HB_Buffer buffer,
- HB_UShort flags,
- HB_UShort context_length,
- int nesting_level )
-{
- HB_UShort index, i, j, property;
- HB_UShort bgc, igc, lgc;
- HB_Error error;
-
- HB_Coverage* bc;
- HB_Coverage* ic;
- HB_Coverage* lc;
- HB_GDEFHeader* gdef;
-
-
- gdef = gsub->gdef;
-
- if ( CHECK_Property( gdef, IN_CURITEM(), flags, &property ) )
- return error;
-
- bgc = ccsf3->BacktrackGlyphCount;
- igc = ccsf3->InputGlyphCount;
- lgc = ccsf3->LookaheadGlyphCount;
-
- if ( context_length != 0xFFFF && context_length < igc )
- return HB_Err_Not_Covered;
-
- /* check whether context is too long; it is a first guess only */
-
- if ( bgc > buffer->out_pos || buffer->in_pos + igc + lgc > buffer->in_length )
- return HB_Err_Not_Covered;
-
- if ( bgc )
- {
- /* Since we don't know in advance the number of glyphs to inspect,
- we search backwards for matches in the backtrack glyph array */
-
- bc = ccsf3->BacktrackCoverage;
-
- for ( i = 0, j = buffer->out_pos - 1; i < bgc; i++, j-- )
- {
- while ( CHECK_Property( gdef, OUT_ITEM( j ), flags, &property ) )
- {
- if ( error && error != HB_Err_Not_Covered )
- return error;
-
- if ( j + 1 == bgc - i )
- return HB_Err_Not_Covered;
- j--;
- }
-
- error = _HB_OPEN_Coverage_Index( &bc[i], OUT_GLYPH( j ), &index );
- if ( error )
- return error;
- }
- }
-
- ic = ccsf3->InputCoverage;
-
- for ( i = 0, j = buffer->in_pos; i < igc; i++, j++ )
- {
- /* We already called CHECK_Property for IN_GLYPH( buffer->in_pos ) */
- while ( j > buffer->in_pos && CHECK_Property( gdef, IN_ITEM( j ), flags, &property ) )
- {
- if ( error && error != HB_Err_Not_Covered )
- return error;
-
- if ( j + igc - i + lgc == (HB_Int)buffer->in_length )
- return HB_Err_Not_Covered;
- j++;
- }
-
- error = _HB_OPEN_Coverage_Index( &ic[i], IN_GLYPH( j ), &index );
- if ( error )
- return error;
- }
-
- /* we are starting for lookahead glyphs right after the last context
- glyph */
-
- lc = ccsf3->LookaheadCoverage;
-
- for ( i = 0; i < lgc; i++, j++ )
- {
- while ( CHECK_Property( gdef, IN_ITEM( j ), flags, &property ) )
- {
- if ( error && error != HB_Err_Not_Covered )
- return error;
-
- if ( j + lgc - i == (HB_Int)buffer->in_length )
- return HB_Err_Not_Covered;
- j++;
- }
-
- error = _HB_OPEN_Coverage_Index( &lc[i], IN_GLYPH( j ), &index );
- if ( error )
- return error;
- }
-
- return Do_ContextSubst( gsub, igc,
- ccsf3->SubstCount,
- ccsf3->SubstLookupRecord,
- buffer,
- nesting_level );
-}
-
-
-static HB_Error Lookup_ChainContextSubst( HB_GSUBHeader* gsub,
- HB_GSUB_SubTable* st,
- HB_Buffer buffer,
- HB_UShort flags,
- HB_UShort context_length,
- int nesting_level )
-{
- HB_ChainContextSubst* ccs = &st->chain;
-
- switch ( ccs->SubstFormat ) {
- case 1: return Lookup_ChainContextSubst1( gsub, &ccs->ccsf.ccsf1, buffer, flags, context_length, nesting_level );
- case 2: return Lookup_ChainContextSubst2( gsub, &ccs->ccsf.ccsf2, buffer, flags, context_length, nesting_level );
- case 3: return Lookup_ChainContextSubst3( gsub, &ccs->ccsf.ccsf3, buffer, flags, context_length, nesting_level );
- default: return ERR(HB_Err_Invalid_SubTable_Format);
- }
-}
-
-
-static HB_Error Load_ReverseChainContextSubst( HB_GSUB_SubTable* st,
- HB_Stream stream )
-{
- HB_Error error;
- HB_ReverseChainContextSubst* rccs = &st->reverse;
-
- HB_UShort m, count;
-
- HB_UShort nb = 0, nl = 0, n;
- HB_UShort backtrack_count, lookahead_count;
- HB_UInt cur_offset, new_offset, base_offset;
-
- HB_Coverage* b;
- HB_Coverage* l;
- HB_UShort* sub;
-
- base_offset = FILE_Pos();
-
- if ( ACCESS_Frame( 2L ) )
- return error;
-
- rccs->SubstFormat = GET_UShort();
-
- if ( rccs->SubstFormat != 1 )
- return ERR(HB_Err_Invalid_SubTable_Format);
-
- FORGET_Frame();
-
- if ( ACCESS_Frame( 2L ) )
- return error;
-
- new_offset = GET_UShort() + base_offset;
-
- FORGET_Frame();
-
- cur_offset = FILE_Pos();
- if ( FILE_Seek( new_offset ) ||
- ( error = _HB_OPEN_Load_Coverage( &rccs->Coverage, stream ) ) != HB_Err_Ok )
- return error;
- (void)FILE_Seek( cur_offset );
-
-
- if ( ACCESS_Frame( 2L ) )
- goto Fail4;
-
- rccs->BacktrackGlyphCount = GET_UShort();
-
- FORGET_Frame();
-
- rccs->BacktrackCoverage = NULL;
-
- backtrack_count = rccs->BacktrackGlyphCount;
-
- if ( ALLOC_ARRAY( rccs->BacktrackCoverage, backtrack_count,
- HB_Coverage ) )
- goto Fail4;
-
- b = rccs->BacktrackCoverage;
-
- for ( nb = 0; nb < backtrack_count; nb++ )
- {
- if ( ACCESS_Frame( 2L ) )
- goto Fail3;
-
- new_offset = GET_UShort() + base_offset;
-
- FORGET_Frame();
-
- cur_offset = FILE_Pos();
- if ( FILE_Seek( new_offset ) ||
- ( error = _HB_OPEN_Load_Coverage( &b[nb], stream ) ) != HB_Err_Ok )
- goto Fail3;
- (void)FILE_Seek( cur_offset );
- }
-
-
- if ( ACCESS_Frame( 2L ) )
- goto Fail3;
-
- rccs->LookaheadGlyphCount = GET_UShort();
-
- FORGET_Frame();
-
- rccs->LookaheadCoverage = NULL;
-
- lookahead_count = rccs->LookaheadGlyphCount;
-
- if ( ALLOC_ARRAY( rccs->LookaheadCoverage, lookahead_count,
- HB_Coverage ) )
- goto Fail3;
-
- l = rccs->LookaheadCoverage;
-
- for ( nl = 0; nl < lookahead_count; nl++ )
- {
- if ( ACCESS_Frame( 2L ) )
- goto Fail2;
-
- new_offset = GET_UShort() + base_offset;
-
- FORGET_Frame();
-
- cur_offset = FILE_Pos();
- if ( FILE_Seek( new_offset ) ||
- ( error = _HB_OPEN_Load_Coverage( &l[nl], stream ) ) != HB_Err_Ok )
- goto Fail2;
- (void)FILE_Seek( cur_offset );
- }
-
- if ( ACCESS_Frame( 2L ) )
- goto Fail2;
-
- rccs->GlyphCount = GET_UShort();
-
- FORGET_Frame();
-
- rccs->Substitute = NULL;
-
- count = rccs->GlyphCount;
-
- if ( ALLOC_ARRAY( rccs->Substitute, count,
- HB_UShort ) )
- goto Fail2;
-
- sub = rccs->Substitute;
-
- if ( ACCESS_Frame( count * 2L ) )
- goto Fail1;
-
- for ( n = 0; n < count; n++ )
- sub[n] = GET_UShort();
-
- FORGET_Frame();
-
- return HB_Err_Ok;
-
-Fail1:
- FREE( sub );
-
-Fail2:
- for ( m = 0; m < nl; m++ )
- _HB_OPEN_Free_Coverage( &l[m] );
-
- FREE( l );
-
-Fail3:
- for ( m = 0; m < nb; m++ )
- _HB_OPEN_Free_Coverage( &b[m] );
-
- FREE( b );
-
-Fail4:
- _HB_OPEN_Free_Coverage( &rccs->Coverage );
- return error;
-}
-
-
-static void Free_ReverseChainContextSubst( HB_GSUB_SubTable* st )
-{
- HB_UShort n, count;
- HB_ReverseChainContextSubst* rccs = &st->reverse;
-
- HB_Coverage* c;
-
- _HB_OPEN_Free_Coverage( &rccs->Coverage );
-
- if ( rccs->LookaheadCoverage )
- {
- count = rccs->LookaheadGlyphCount;
- c = rccs->LookaheadCoverage;
-
- for ( n = 0; n < count; n++ )
- _HB_OPEN_Free_Coverage( &c[n] );
-
- FREE( c );
- }
-
- if ( rccs->BacktrackCoverage )
- {
- count = rccs->BacktrackGlyphCount;
- c = rccs->BacktrackCoverage;
-
- for ( n = 0; n < count; n++ )
- _HB_OPEN_Free_Coverage( &c[n] );
-
- FREE( c );
- }
-
- FREE ( rccs->Substitute );
-}
-
-
-static HB_Error Lookup_ReverseChainContextSubst( HB_GSUBHeader* gsub,
- HB_GSUB_SubTable* st,
- HB_Buffer buffer,
- HB_UShort flags,
- HB_UShort context_length,
- int nesting_level )
-{
- HB_UShort index, input_index, i, j, property;
- HB_UShort bgc, lgc;
- HB_Error error;
-
- HB_ReverseChainContextSubst* rccs = &st->reverse;
- HB_Coverage* bc;
- HB_Coverage* lc;
- HB_GDEFHeader* gdef;
-
- if ( nesting_level != 1 || context_length != 0xFFFF )
- return HB_Err_Not_Covered;
-
- gdef = gsub->gdef;
-
- if ( CHECK_Property( gdef, IN_CURITEM(), flags, &property ) )
- return error;
-
- bgc = rccs->BacktrackGlyphCount;
- lgc = rccs->LookaheadGlyphCount;
-
- /* check whether context is too long; it is a first guess only */
-
- if ( bgc > buffer->in_pos || buffer->in_pos + 1 + lgc > buffer->in_length )
- return HB_Err_Not_Covered;
-
- if ( bgc )
- {
- /* Since we don't know in advance the number of glyphs to inspect,
- we search backwards for matches in the backtrack glyph array */
-
- bc = rccs->BacktrackCoverage;
-
- for ( i = 0, j = buffer->in_pos - 1; i < bgc; i++, j-- )
- {
- while ( CHECK_Property( gdef, IN_ITEM( j ), flags, &property ) )
- {
- if ( error && error != HB_Err_Not_Covered )
- return error;
-
- if ( j + 1 == bgc - i )
- return HB_Err_Not_Covered;
- j--;
- }
-
- error = _HB_OPEN_Coverage_Index( &bc[i], IN_GLYPH( j ), &index );
- if ( error )
- return error;
- }
- }
-
- j = buffer->in_pos;
-
- error = _HB_OPEN_Coverage_Index( &rccs->Coverage, IN_GLYPH( j ), &input_index );
- if ( error )
- return error;
-
- lc = rccs->LookaheadCoverage;
-
- for ( i = 0, j = buffer->in_pos + 1; i < lgc; i++, j++ )
- {
- while ( CHECK_Property( gdef, IN_ITEM( j ), flags, &property ) )
- {
- if ( error && error != HB_Err_Not_Covered )
- return error;
-
- if ( j + lgc - i == (HB_Int)buffer->in_length )
- return HB_Err_Not_Covered;
- j++;
- }
-
- error = _HB_OPEN_Coverage_Index( &lc[i], IN_GLYPH( j ), &index );
- if ( error )
- return error;
- }
-
- IN_CURGLYPH() = rccs->Substitute[input_index];
- buffer->in_pos--; /* Reverse! */
-
- return error;
-}
-
-
-
-/***********
- * GSUB API
- ***********/
-
-
-
-HB_Error HB_GSUB_Select_Script( HB_GSUBHeader* gsub,
- HB_UInt script_tag,
- HB_UShort* script_index )
-{
- HB_UShort n;
-
- HB_ScriptList* sl;
- HB_ScriptRecord* sr;
-
-
- if ( !gsub || !script_index )
- return ERR(HB_Err_Invalid_Argument);
-
- sl = &gsub->ScriptList;
- sr = sl->ScriptRecord;
-
- for ( n = 0; n < sl->ScriptCount; n++ )
- if ( script_tag == sr[n].ScriptTag )
- {
- *script_index = n;
-
- return HB_Err_Ok;
- }
-
- return HB_Err_Not_Covered;
-}
-
-
-
-HB_Error HB_GSUB_Select_Language( HB_GSUBHeader* gsub,
- HB_UInt language_tag,
- HB_UShort script_index,
- HB_UShort* language_index,
- HB_UShort* req_feature_index )
-{
- HB_UShort n;
-
- HB_ScriptList* sl;
- HB_ScriptRecord* sr;
- HB_ScriptTable* s;
- HB_LangSysRecord* lsr;
-
-
- if ( !gsub || !language_index || !req_feature_index )
- return ERR(HB_Err_Invalid_Argument);
-
- sl = &gsub->ScriptList;
- sr = sl->ScriptRecord;
-
- if ( script_index >= sl->ScriptCount )
- return ERR(HB_Err_Invalid_Argument);
-
- s = &sr[script_index].Script;
- lsr = s->LangSysRecord;
-
- for ( n = 0; n < s->LangSysCount; n++ )
- if ( language_tag == lsr[n].LangSysTag )
- {
- *language_index = n;
- *req_feature_index = lsr[n].LangSys.ReqFeatureIndex;
-
- return HB_Err_Ok;
- }
-
- return HB_Err_Not_Covered;
-}
-
-
-/* selecting 0xFFFF for language_index asks for the values of the
- default language (DefaultLangSys) */
-
-
-HB_Error HB_GSUB_Select_Feature( HB_GSUBHeader* gsub,
- HB_UInt feature_tag,
- HB_UShort script_index,
- HB_UShort language_index,
- HB_UShort* feature_index )
-{
- HB_UShort n;
-
- HB_ScriptList* sl;
- HB_ScriptRecord* sr;
- HB_ScriptTable* s;
- HB_LangSysRecord* lsr;
- HB_LangSys* ls;
- HB_UShort* fi;
-
- HB_FeatureList* fl;
- HB_FeatureRecord* fr;
-
-
- if ( !gsub || !feature_index )
- return ERR(HB_Err_Invalid_Argument);
-
- sl = &gsub->ScriptList;
- sr = sl->ScriptRecord;
-
- fl = &gsub->FeatureList;
- fr = fl->FeatureRecord;
-
- if ( script_index >= sl->ScriptCount )
- return ERR(HB_Err_Invalid_Argument);
-
- s = &sr[script_index].Script;
- lsr = s->LangSysRecord;
-
- if ( language_index == 0xFFFF )
- ls = &s->DefaultLangSys;
- else
- {
- if ( language_index >= s->LangSysCount )
- return ERR(HB_Err_Invalid_Argument);
-
- ls = &lsr[language_index].LangSys;
- }
-
- fi = ls->FeatureIndex;
-
- for ( n = 0; n < ls->FeatureCount; n++ )
- {
- if ( fi[n] >= fl->FeatureCount )
- return ERR(HB_Err_Invalid_SubTable_Format);
-
- if ( feature_tag == fr[fi[n]].FeatureTag )
- {
- *feature_index = fi[n];
-
- return HB_Err_Ok;
- }
- }
-
- return HB_Err_Not_Covered;
-}
-
-
-/* The next three functions return a null-terminated list */
-
-
-HB_Error HB_GSUB_Query_Scripts( HB_GSUBHeader* gsub,
- HB_UInt** script_tag_list )
-{
- HB_UShort n;
- HB_Error error;
- HB_UInt* stl;
-
- HB_ScriptList* sl;
- HB_ScriptRecord* sr;
-
-
- if ( !gsub || !script_tag_list )
- return ERR(HB_Err_Invalid_Argument);
-
- sl = &gsub->ScriptList;
- sr = sl->ScriptRecord;
-
- if ( ALLOC_ARRAY( stl, sl->ScriptCount + 1, HB_UInt ) )
- return error;
-
- for ( n = 0; n < sl->ScriptCount; n++ )
- stl[n] = sr[n].ScriptTag;
- stl[n] = 0;
-
- *script_tag_list = stl;
-
- return HB_Err_Ok;
-}
-
-
-
-HB_Error HB_GSUB_Query_Languages( HB_GSUBHeader* gsub,
- HB_UShort script_index,
- HB_UInt** language_tag_list )
-{
- HB_UShort n;
- HB_Error error;
- HB_UInt* ltl;
-
- HB_ScriptList* sl;
- HB_ScriptRecord* sr;
- HB_ScriptTable* s;
- HB_LangSysRecord* lsr;
-
-
- if ( !gsub || !language_tag_list )
- return ERR(HB_Err_Invalid_Argument);
-
- sl = &gsub->ScriptList;
- sr = sl->ScriptRecord;
-
- if ( script_index >= sl->ScriptCount )
- return ERR(HB_Err_Invalid_Argument);
-
- s = &sr[script_index].Script;
- lsr = s->LangSysRecord;
-
- if ( ALLOC_ARRAY( ltl, s->LangSysCount + 1, HB_UInt ) )
- return error;
-
- for ( n = 0; n < s->LangSysCount; n++ )
- ltl[n] = lsr[n].LangSysTag;
- ltl[n] = 0;
-
- *language_tag_list = ltl;
-
- return HB_Err_Ok;
-}
-
-
-/* selecting 0xFFFF for language_index asks for the values of the
- default language (DefaultLangSys) */
-
-
-HB_Error HB_GSUB_Query_Features( HB_GSUBHeader* gsub,
- HB_UShort script_index,
- HB_UShort language_index,
- HB_UInt** feature_tag_list )
-{
- HB_UShort n;
- HB_Error error;
- HB_UInt* ftl;
-
- HB_ScriptList* sl;
- HB_ScriptRecord* sr;
- HB_ScriptTable* s;
- HB_LangSysRecord* lsr;
- HB_LangSys* ls;
- HB_UShort* fi;
-
- HB_FeatureList* fl;
- HB_FeatureRecord* fr;
-
-
- if ( !gsub || !feature_tag_list )
- return ERR(HB_Err_Invalid_Argument);
-
- sl = &gsub->ScriptList;
- sr = sl->ScriptRecord;
-
- fl = &gsub->FeatureList;
- fr = fl->FeatureRecord;
-
- if ( script_index >= sl->ScriptCount )
- return ERR(HB_Err_Invalid_Argument);
-
- s = &sr[script_index].Script;
- lsr = s->LangSysRecord;
-
- if ( language_index == 0xFFFF )
- ls = &s->DefaultLangSys;
- else
- {
- if ( language_index >= s->LangSysCount )
- return ERR(HB_Err_Invalid_Argument);
-
- ls = &lsr[language_index].LangSys;
- }
-
- fi = ls->FeatureIndex;
-
- if ( ALLOC_ARRAY( ftl, ls->FeatureCount + 1, HB_UInt ) )
- return error;
-
- for ( n = 0; n < ls->FeatureCount; n++ )
- {
- if ( fi[n] >= fl->FeatureCount )
- {
- FREE( ftl );
- return ERR(HB_Err_Invalid_SubTable_Format);
- }
- ftl[n] = fr[fi[n]].FeatureTag;
- }
- ftl[n] = 0;
-
- *feature_tag_list = ftl;
-
- return HB_Err_Ok;
-}
-
-
-/* Do an individual subtable lookup. Returns HB_Err_Ok if substitution
- has been done, or HB_Err_Not_Covered if not. */
-static HB_Error GSUB_Do_Glyph_Lookup( HB_GSUBHeader* gsub,
- HB_UShort lookup_index,
- HB_Buffer buffer,
- HB_UShort context_length,
- int nesting_level )
-{
- HB_Error error = HB_Err_Not_Covered;
- HB_UShort i, flags, lookup_count;
- HB_Lookup* lo;
- int lookup_type;
-
- nesting_level++;
-
- if ( nesting_level > HB_MAX_NESTING_LEVEL )
- return ERR(HB_Err_Not_Covered); /* ERR() call intended */
-
- lookup_count = gsub->LookupList.LookupCount;
- if (lookup_index >= lookup_count)
- return error;
-
- lo = &gsub->LookupList.Lookup[lookup_index];
- flags = lo->LookupFlag;
- lookup_type = lo->LookupType;
-
- for ( i = 0; i < lo->SubTableCount; i++ )
- {
- HB_GSUB_SubTable *st = &lo->SubTable[i].st.gsub;
-
- switch (lookup_type) {
- case HB_GSUB_LOOKUP_SINGLE:
- error = Lookup_SingleSubst ( gsub, st, buffer, flags, context_length, nesting_level ); break;
- case HB_GSUB_LOOKUP_MULTIPLE:
- error = Lookup_MultipleSubst ( gsub, st, buffer, flags, context_length, nesting_level ); break;
- case HB_GSUB_LOOKUP_ALTERNATE:
- error = Lookup_AlternateSubst ( gsub, st, buffer, flags, context_length, nesting_level ); break;
- case HB_GSUB_LOOKUP_LIGATURE:
- error = Lookup_LigatureSubst ( gsub, st, buffer, flags, context_length, nesting_level ); break;
- case HB_GSUB_LOOKUP_CONTEXT:
- error = Lookup_ContextSubst ( gsub, st, buffer, flags, context_length, nesting_level ); break;
- case HB_GSUB_LOOKUP_CHAIN:
- error = Lookup_ChainContextSubst ( gsub, st, buffer, flags, context_length, nesting_level ); break;
- /*case HB_GSUB_LOOKUP_EXTENSION:
- error = Lookup_ExtensionSubst ( gsub, st, buffer, flags, context_length, nesting_level ); break;*/
- case HB_GSUB_LOOKUP_REVERSE_CHAIN:
- error = Lookup_ReverseChainContextSubst ( gsub, st, buffer, flags, context_length, nesting_level ); break;
- default:
- error = HB_Err_Not_Covered;
- };
-
- /* Check whether we have a successful substitution or an error other
- than HB_Err_Not_Covered */
- if ( error != HB_Err_Not_Covered )
- return error;
- }
-
- return HB_Err_Not_Covered;
-}
-
-
-HB_INTERNAL HB_Error
-_HB_GSUB_Load_SubTable( HB_GSUB_SubTable* st,
- HB_Stream stream,
- HB_UShort lookup_type )
-{
- switch (lookup_type) {
- case HB_GSUB_LOOKUP_SINGLE: return Load_SingleSubst ( st, stream );
- case HB_GSUB_LOOKUP_MULTIPLE: return Load_MultipleSubst ( st, stream );
- case HB_GSUB_LOOKUP_ALTERNATE: return Load_AlternateSubst ( st, stream );
- case HB_GSUB_LOOKUP_LIGATURE: return Load_LigatureSubst ( st, stream );
- case HB_GSUB_LOOKUP_CONTEXT: return Load_ContextSubst ( st, stream );
- case HB_GSUB_LOOKUP_CHAIN: return Load_ChainContextSubst ( st, stream );
- /*case HB_GSUB_LOOKUP_EXTENSION: return Load_ExtensionSubst ( st, stream );*/
- case HB_GSUB_LOOKUP_REVERSE_CHAIN: return Load_ReverseChainContextSubst ( st, stream );
- default: return ERR(HB_Err_Invalid_SubTable_Format);
- };
-}
-
-
-HB_INTERNAL void
-_HB_GSUB_Free_SubTable( HB_GSUB_SubTable* st,
- HB_UShort lookup_type )
-{
- switch ( lookup_type ) {
- case HB_GSUB_LOOKUP_SINGLE: Free_SingleSubst ( st ); return;
- case HB_GSUB_LOOKUP_MULTIPLE: Free_MultipleSubst ( st ); return;
- case HB_GSUB_LOOKUP_ALTERNATE: Free_AlternateSubst ( st ); return;
- case HB_GSUB_LOOKUP_LIGATURE: Free_LigatureSubst ( st ); return;
- case HB_GSUB_LOOKUP_CONTEXT: Free_ContextSubst ( st ); return;
- case HB_GSUB_LOOKUP_CHAIN: Free_ChainContextSubst ( st ); return;
- /*case HB_GSUB_LOOKUP_EXTENSION: Free_ExtensionSubst ( st ); return;*/
- case HB_GSUB_LOOKUP_REVERSE_CHAIN: Free_ReverseChainContextSubst ( st ); return;
- default: return;
- };
-}
-
-
-
-/* apply one lookup to the input string object */
-
-static HB_Error GSUB_Do_String_Lookup( HB_GSUBHeader* gsub,
- HB_UShort lookup_index,
- HB_Buffer buffer )
-{
- HB_Error error, retError = HB_Err_Not_Covered;
-
- HB_UInt* properties = gsub->LookupList.Properties;
- int lookup_type = gsub->LookupList.Lookup[lookup_index].LookupType;
-
- const int nesting_level = 0;
- /* 0xFFFF indicates that we don't have a context length yet */
- const HB_UShort context_length = 0xFFFF;
-
- switch (lookup_type) {
-
- case HB_GSUB_LOOKUP_SINGLE:
- case HB_GSUB_LOOKUP_MULTIPLE:
- case HB_GSUB_LOOKUP_ALTERNATE:
- case HB_GSUB_LOOKUP_LIGATURE:
- case HB_GSUB_LOOKUP_CONTEXT:
- case HB_GSUB_LOOKUP_CHAIN:
- /* in/out forward substitution (implemented lazy) */
-
- _hb_buffer_clear_output ( buffer );
- buffer->in_pos = 0;
- while ( buffer->in_pos < buffer->in_length )
- {
- if ( ~IN_PROPERTIES( buffer->in_pos ) & properties[lookup_index] )
- {
- error = GSUB_Do_Glyph_Lookup( gsub, lookup_index, buffer, context_length, nesting_level );
- if ( error )
- {
- if ( error != HB_Err_Not_Covered )
- return error;
- }
- else
- retError = error;
- }
- else
- error = HB_Err_Not_Covered;
-
- if ( error == HB_Err_Not_Covered )
- if ( COPY_Glyph ( buffer ) )
- return error;
- }
- /* we shouldn't swap if error occurred.
- *
- * also don't swap if nothing changed (ie HB_Err_Not_Covered).
- * shouldn't matter in that case though.
- */
- if ( retError == HB_Err_Ok )
- _hb_buffer_swap( buffer );
-
- return retError;
-
- case HB_GSUB_LOOKUP_REVERSE_CHAIN:
- /* in-place backward substitution */
-
- buffer->in_pos = buffer->in_length - 1;
- do
- {
- if ( ~IN_PROPERTIES( buffer->in_pos ) & properties[lookup_index] )
- {
- error = GSUB_Do_Glyph_Lookup( gsub, lookup_index, buffer, context_length, nesting_level );
- if ( error )
- {
- if ( error != HB_Err_Not_Covered )
- return error;
- }
- else
- retError = error;
- }
- else
- error = HB_Err_Not_Covered;
-
- if ( error == HB_Err_Not_Covered )
- buffer->in_pos--;
- }
- while ((HB_Int) buffer->in_pos >= 0);
-
- return retError;
-
- /*case HB_GSUB_LOOKUP_EXTENSION:*/
- default:
- return retError;
- };
-}
-
-
-HB_Error HB_GSUB_Add_Feature( HB_GSUBHeader* gsub,
- HB_UShort feature_index,
- HB_UInt property )
-{
- HB_UShort i;
-
- HB_Feature feature;
- HB_UInt* properties;
- HB_UShort* index;
- HB_UShort lookup_count;
-
- /* Each feature can only be added once */
-
- if ( !gsub ||
- feature_index >= gsub->FeatureList.FeatureCount ||
- gsub->FeatureList.ApplyCount == gsub->FeatureList.FeatureCount )
- return ERR(HB_Err_Invalid_Argument);
-
- gsub->FeatureList.ApplyOrder[gsub->FeatureList.ApplyCount++] = feature_index;
-
- properties = gsub->LookupList.Properties;
-
- feature = gsub->FeatureList.FeatureRecord[feature_index].Feature;
- index = feature.LookupListIndex;
- lookup_count = gsub->LookupList.LookupCount;
-
- for ( i = 0; i < feature.LookupListCount; i++ )
- {
- HB_UShort lookup_index = index[i];
- if (lookup_index < lookup_count)
- properties[lookup_index] |= property;
- }
-
- return HB_Err_Ok;
-}
-
-
-
-HB_Error HB_GSUB_Clear_Features( HB_GSUBHeader* gsub )
-{
- HB_UShort i;
-
- HB_UInt* properties;
-
-
- if ( !gsub )
- return ERR(HB_Err_Invalid_Argument);
-
- gsub->FeatureList.ApplyCount = 0;
-
- properties = gsub->LookupList.Properties;
-
- for ( i = 0; i < gsub->LookupList.LookupCount; i++ )
- properties[i] = 0;
-
- return HB_Err_Ok;
-}
-
-
-
-HB_Error HB_GSUB_Register_Alternate_Function( HB_GSUBHeader* gsub,
- HB_AltFunction altfunc,
- void* data )
-{
- if ( !gsub )
- return ERR(HB_Err_Invalid_Argument);
-
- gsub->altfunc = altfunc;
- gsub->data = data;
-
- return HB_Err_Ok;
-}
-
-/* returns error if one happened, otherwise returns HB_Err_Not_Covered if no
- * feature were applied, or HB_Err_Ok otherwise.
- */
-HB_Error HB_GSUB_Apply_String( HB_GSUBHeader* gsub,
- HB_Buffer buffer )
-{
- HB_Error error, retError = HB_Err_Not_Covered;
- int i, j, lookup_count, num_features;
-
- if ( !gsub ||
- !buffer)
- return ERR(HB_Err_Invalid_Argument);
-
- if ( buffer->in_length == 0 )
- return retError;
-
- lookup_count = gsub->LookupList.LookupCount;
- num_features = gsub->FeatureList.ApplyCount;
-
- for ( i = 0; i < num_features; i++)
- {
- HB_UShort feature_index = gsub->FeatureList.ApplyOrder[i];
- HB_Feature feature = gsub->FeatureList.FeatureRecord[feature_index].Feature;
-
- for ( j = 0; j < feature.LookupListCount; j++ )
- {
- HB_UShort lookup_index = feature.LookupListIndex[j];
-
- /* Skip nonexistant lookups */
- if (lookup_index >= lookup_count)
- continue;
-
- error = GSUB_Do_String_Lookup( gsub, lookup_index, buffer );
- if ( error )
- {
- if ( error != HB_Err_Not_Covered )
- return error;
- }
- else
- retError = error;
- }
- }
-
- error = retError;
-
- return error;
-}
-
-
-/* END */
diff --git a/src/3rdparty/harfbuzz/src/harfbuzz-gsub.h b/src/3rdparty/harfbuzz/src/harfbuzz-gsub.h
deleted file mode 100644
index 6e452bdb35..0000000000
--- a/src/3rdparty/harfbuzz/src/harfbuzz-gsub.h
+++ /dev/null
@@ -1,139 +0,0 @@
-/*
- * Copyright (C) 1998-2004 David Turner and Werner Lemberg
- * Copyright (C) 2006 Behdad Esfahbod
- *
- * This is part of HarfBuzz, an OpenType Layout engine 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 HARFBUZZ_GSUB_H
-#define HARFBUZZ_GSUB_H
-
-#include "harfbuzz-gdef.h"
-#include "harfbuzz-buffer.h"
-
-HB_BEGIN_HEADER
-
-/* Lookup types for glyph substitution */
-
-#define HB_GSUB_LOOKUP_SINGLE 1
-#define HB_GSUB_LOOKUP_MULTIPLE 2
-#define HB_GSUB_LOOKUP_ALTERNATE 3
-#define HB_GSUB_LOOKUP_LIGATURE 4
-#define HB_GSUB_LOOKUP_CONTEXT 5
-#define HB_GSUB_LOOKUP_CHAIN 6
-#define HB_GSUB_LOOKUP_EXTENSION 7
-#define HB_GSUB_LOOKUP_REVERSE_CHAIN 8
-
-
-/* A pointer to a function which selects the alternate glyph. `pos' is
- the position of the glyph with index `glyphID', `num_alternates'
- gives the number of alternates in the `alternates' array. `data'
- points to the user-defined structure specified during a call to
- HB_GSUB_Register_Alternate_Function(). The function must return an
- index into the `alternates' array. */
-
-typedef HB_UShort (*HB_AltFunction)(HB_UInt pos,
- HB_UShort glyphID,
- HB_UShort num_alternates,
- HB_UShort* alternates,
- void* data );
-
-
-struct HB_GSUBHeader_
-{
- HB_GDEFHeader* gdef;
-
- /* the next two fields are used for an alternate substitution callback
- function to select the proper alternate glyph. */
-
- void* data;
- HB_AltFunction altfunc;
-
- HB_UInt offset;
-
- HB_16Dot16 Version;
-
- HB_ScriptList ScriptList;
- HB_FeatureList FeatureList;
- HB_LookupList LookupList;
-};
-
-typedef struct HB_GSUBHeader_ HB_GSUBHeader;
-typedef HB_GSUBHeader* HB_GSUB;
-
-
-HB_Error HB_Load_GSUB_Table( HB_Stream stream,
- HB_GSUBHeader** gsub,
- HB_GDEFHeader* gdef,
- HB_Stream gdefStream );
-
-
-HB_Error HB_Done_GSUB_Table( HB_GSUBHeader* gsub );
-
-
-HB_Error HB_GSUB_Select_Script( HB_GSUBHeader* gsub,
- HB_UInt script_tag,
- HB_UShort* script_index );
-
-HB_Error HB_GSUB_Select_Language( HB_GSUBHeader* gsub,
- HB_UInt language_tag,
- HB_UShort script_index,
- HB_UShort* language_index,
- HB_UShort* req_feature_index );
-
-HB_Error HB_GSUB_Select_Feature( HB_GSUBHeader* gsub,
- HB_UInt feature_tag,
- HB_UShort script_index,
- HB_UShort language_index,
- HB_UShort* feature_index );
-
-
-HB_Error HB_GSUB_Query_Scripts( HB_GSUBHeader* gsub,
- HB_UInt** script_tag_list );
-
-HB_Error HB_GSUB_Query_Languages( HB_GSUBHeader* gsub,
- HB_UShort script_index,
- HB_UInt** language_tag_list );
-
-HB_Error HB_GSUB_Query_Features( HB_GSUBHeader* gsub,
- HB_UShort script_index,
- HB_UShort language_index,
- HB_UInt** feature_tag_list );
-
-
-HB_Error HB_GSUB_Add_Feature( HB_GSUBHeader* gsub,
- HB_UShort feature_index,
- HB_UInt property );
-
-HB_Error HB_GSUB_Clear_Features( HB_GSUBHeader* gsub );
-
-
-HB_Error HB_GSUB_Register_Alternate_Function( HB_GSUBHeader* gsub,
- HB_AltFunction altfunc,
- void* data );
-
-
-HB_Error HB_GSUB_Apply_String( HB_GSUBHeader* gsub,
- HB_Buffer buffer );
-
-HB_END_HEADER
-
-#endif /* HARFBUZZ_GSUB_H */
diff --git a/src/3rdparty/harfbuzz/src/harfbuzz-hangul.c b/src/3rdparty/harfbuzz/src/harfbuzz-hangul.c
deleted file mode 100644
index 41d5545898..0000000000
--- a/src/3rdparty/harfbuzz/src/harfbuzz-hangul.c
+++ /dev/null
@@ -1,268 +0,0 @@
-/*
- * Copyright (C) 2015 The Qt Company Ltd
- *
- * This is part of HarfBuzz, an OpenType Layout engine library.
- *
- * Permission is hereby granted, without written agreement and without
- * license or royalty fees, to use, copy, modify, and distribute this
- * software and its documentation for any purpose, provided that the
- * above copyright notice and the following two paragraphs appear in
- * all copies of this software.
- *
- * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
- * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
- * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
- * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
- * DAMAGE.
- *
- * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
- * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
- * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
- * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
- * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
- */
-
-#include "harfbuzz-shaper.h"
-#include "harfbuzz-shaper-private.h"
-
-#include <assert.h>
-
-/*
-// Hangul is a syllable based script. Unicode reserves a large range
-// for precomposed hangul, where syllables are already precomposed to
-// their final glyph shape. In addition, a so called jamo range is
-// defined, that can be used to express old Hangul. Modern hangul
-// syllables can also be expressed as jamo, and should be composed
-// into syllables. The operation is rather simple and mathematical.
-
-// Every hangul jamo is classified as being either a Leading consonant
-// (L), and intermediat Vowel (V) or a trailing consonant (T). Modern
-// hangul syllables (the ones in the precomposed area can be of type
-// LV or LVT.
-//
-// Syllable breaks do _not_ occur between:
-//
-// L L, V or precomposed
-// V, LV V, T
-// LVT, T T
-//
-// A standard syllable is of the form L+V+T*. The above rules allow
-// nonstandard syllables L*V*T*. To transform them into standard
-// syllables fill characters L_f and V_f can be inserted.
-*/
-
-enum {
- Hangul_SBase = 0xac00,
- Hangul_LBase = 0x1100,
- Hangul_VBase = 0x1161,
- Hangul_TBase = 0x11a7,
- Hangul_SCount = 11172,
- Hangul_LCount = 19,
- Hangul_VCount = 21,
- Hangul_TCount = 28,
- Hangul_NCount = 21*28
-};
-
-#define hangul_isPrecomposed(uc) \
- (uc >= Hangul_SBase && uc < Hangul_SBase + Hangul_SCount)
-
-#define hangul_isLV(uc) \
- ((uc - Hangul_SBase) % Hangul_TCount == 0)
-
-typedef enum {
- L,
- V,
- T,
- LV,
- LVT,
- X
-} HangulType;
-
-static HangulType hangul_type(unsigned short uc) {
- if (uc > Hangul_SBase && uc < Hangul_SBase + Hangul_SCount)
- return hangul_isLV(uc) ? LV : LVT;
- if (uc < Hangul_LBase || uc > 0x11ff)
- return X;
- if (uc < Hangul_VBase)
- return L;
- if (uc < Hangul_TBase)
- return V;
- return T;
-}
-
-static int hangul_nextSyllableBoundary(const HB_UChar16 *s, int start, int end)
-{
- const HB_UChar16 *uc = s + start;
-
- HangulType state = hangul_type(*uc);
- int pos = 1;
-
- while (pos < end - start) {
- HangulType newState = hangul_type(uc[pos]);
- switch(newState) {
- case X:
- goto finish;
- case L:
- case V:
- case T:
- if (state > newState)
- goto finish;
- state = newState;
- break;
- case LV:
- if (state > L)
- goto finish;
- state = V;
- break;
- case LVT:
- if (state > L)
- goto finish;
- state = T;
- }
- ++pos;
- }
-
- finish:
- return start+pos;
-}
-
-#ifndef NO_OPENTYPE
-static const HB_OpenTypeFeature hangul_features [] = {
- { HB_MAKE_TAG('c', 'c', 'm', 'p'), CcmpProperty },
- { HB_MAKE_TAG('l', 'j', 'm', 'o'), CcmpProperty },
- { HB_MAKE_TAG('v', 'j', 'm', 'o'), CcmpProperty },
- { HB_MAKE_TAG('t', 'j', 'm', 'o'), CcmpProperty },
- { 0, 0 }
-};
-#endif
-
-static HB_Bool hangul_shape_syllable(HB_ShaperItem *item, HB_Bool openType)
-{
- const HB_UChar16 *ch = item->string + item->item.pos;
- int len = item->item.length;
-#ifndef NO_OPENTYPE
- const int availableGlyphs = item->num_glyphs;
-#endif
-
- int i;
- HB_UChar16 composed = 0;
- /* see if we can compose the syllable into a modern hangul */
- if (item->item.length == 2) {
- int LIndex = ch[0] - Hangul_LBase;
- int VIndex = ch[1] - Hangul_VBase;
- if (LIndex >= 0 && LIndex < Hangul_LCount &&
- VIndex >= 0 && VIndex < Hangul_VCount)
- composed = (LIndex * Hangul_VCount + VIndex) * Hangul_TCount + Hangul_SBase;
- } else if (item->item.length == 3) {
- int LIndex = ch[0] - Hangul_LBase;
- int VIndex = ch[1] - Hangul_VBase;
- int TIndex = ch[2] - Hangul_TBase;
- if (LIndex >= 0 && LIndex < Hangul_LCount &&
- VIndex >= 0 && VIndex < Hangul_VCount &&
- TIndex >= 0 && TIndex < Hangul_TCount)
- composed = (LIndex * Hangul_VCount + VIndex) * Hangul_TCount + TIndex + Hangul_SBase;
- }
-
-
-
- /* if we have a modern hangul use the composed form */
- if (composed) {
- ch = &composed;
- len = 1;
- }
-
- if (!item->font->klass->convertStringToGlyphIndices(item->font,
- ch, len,
- item->glyphs, &item->num_glyphs,
- item->item.bidiLevel % 2))
- return FALSE;
- for (i = 0; i < len; i++) {
- item->attributes[i].mark = FALSE;
- item->attributes[i].clusterStart = FALSE;
- item->attributes[i].justification = 0;
- item->attributes[i].zeroWidth = FALSE;
- /*IDEBUG(" %d: %4x", i, ch[i].unicode()); */
- }
-
-#ifndef NO_OPENTYPE
- if (!composed && openType) {
- HB_Bool positioned;
-
- HB_STACKARRAY(unsigned short, logClusters, len);
- for (i = 0; i < len; ++i)
- logClusters[i] = i;
- item->log_clusters = logClusters;
-
- HB_OpenTypeShape(item, /*properties*/0);
-
- positioned = HB_OpenTypePosition(item, availableGlyphs, /*doLogClusters*/FALSE);
-
- HB_FREE_STACKARRAY(logClusters);
-
- if (!positioned)
- return FALSE;
- } else {
- HB_HeuristicPosition(item);
- }
-#endif
-
- item->attributes[0].clusterStart = TRUE;
- return TRUE;
-}
-
-HB_Bool HB_HangulShape(HB_ShaperItem *item)
-{
- const HB_UChar16 *uc = item->string + item->item.pos;
- HB_Bool allPrecomposed = TRUE;
- int i;
-
- assert(item->item.script == HB_Script_Hangul);
-
- for (i = 0; i < (int)item->item.length; ++i) {
- if (!hangul_isPrecomposed(uc[i])) {
- allPrecomposed = FALSE;
- break;
- }
- }
-
- if (!allPrecomposed) {
- HB_Bool openType = FALSE;
- unsigned short *logClusters = item->log_clusters;
- HB_ShaperItem syllable;
- int first_glyph = 0;
- int sstart = item->item.pos;
- int end = sstart + item->item.length;
-
-#ifndef NO_OPENTYPE
- openType = HB_SelectScript(item, hangul_features);
-#endif
- syllable = *item;
-
- while (sstart < end) {
- int send = hangul_nextSyllableBoundary(item->string, sstart, end);
-
- syllable.item.pos = sstart;
- syllable.item.length = send-sstart;
- syllable.glyphs = item->glyphs + first_glyph;
- syllable.attributes = item->attributes + first_glyph;
- syllable.offsets = item->offsets + first_glyph;
- syllable.advances = item->advances + first_glyph;
- syllable.num_glyphs = item->num_glyphs - first_glyph;
- if (!hangul_shape_syllable(&syllable, openType)) {
- item->num_glyphs += syllable.num_glyphs;
- return FALSE;
- }
- /* fix logcluster array */
- for (i = sstart; i < send; ++i)
- logClusters[i-item->item.pos] = first_glyph;
- sstart = send;
- first_glyph += syllable.num_glyphs;
- }
- item->num_glyphs = first_glyph;
- return TRUE;
- }
-
- return HB_BasicShape(item);
-}
-
-
diff --git a/src/3rdparty/harfbuzz/src/harfbuzz-hebrew.c b/src/3rdparty/harfbuzz/src/harfbuzz-hebrew.c
deleted file mode 100644
index a96ab39285..0000000000
--- a/src/3rdparty/harfbuzz/src/harfbuzz-hebrew.c
+++ /dev/null
@@ -1,187 +0,0 @@
-/*
- * Copyright (C) 2015 The Qt Company Ltd
- *
- * This is part of HarfBuzz, an OpenType Layout engine library.
- *
- * Permission is hereby granted, without written agreement and without
- * license or royalty fees, to use, copy, modify, and distribute this
- * software and its documentation for any purpose, provided that the
- * above copyright notice and the following two paragraphs appear in
- * all copies of this software.
- *
- * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
- * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
- * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
- * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
- * DAMAGE.
- *
- * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
- * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
- * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
- * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
- * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
- */
-
-#include "harfbuzz-shaper.h"
-#include "harfbuzz-shaper-private.h"
-#include <assert.h>
-
-/*
-// Uniscribe also defines dlig for Hebrew, but we leave this out for now, as it's mostly
-// ligatures one does not want in modern Hebrew (as lam-alef ligatures).
-*/
-#ifndef NO_OPENTYPE
-static const HB_OpenTypeFeature hebrew_features[] = {
- { HB_MAKE_TAG('c', 'c', 'm', 'p'), CcmpProperty },
- {0, 0}
-};
-#endif
-
-/* Hebrew shaping. In the non opentype case we try to use the
- presentation forms specified for Hebrew. Especially for the
- ligatures with Dagesh this gives much better results than we could
- achieve manually.
-*/
-HB_Bool HB_HebrewShape(HB_ShaperItem *shaper_item)
-{
- enum {
- Dagesh = 0x5bc,
- ShinDot = 0x5c1,
- SinDot = 0x5c2,
- Patah = 0x5b7,
- Qamats = 0x5b8,
- Holam = 0x5b9,
- Rafe = 0x5bf
- };
-
- assert(shaper_item->item.script == HB_Script_Hebrew);
-
-#ifndef NO_OPENTYPE
- if (HB_SelectScript(shaper_item, hebrew_features)) {
-
- const int availableGlyphs = shaper_item->num_glyphs;
- if (!HB_ConvertStringToGlyphIndices(shaper_item))
- return FALSE;
-
- HB_HeuristicSetGlyphAttributes(shaper_item);
- HB_OpenTypeShape(shaper_item, /*properties*/0);
- return HB_OpenTypePosition(shaper_item, availableGlyphs, /*doLogClusters*/TRUE);
- }
-#endif
-
- {
- const HB_UChar16 *uc = shaper_item->string + shaper_item->item.pos;
- unsigned short *logClusters = shaper_item->log_clusters;
- HB_GlyphAttributes *attributes = shaper_item->attributes;
-
- HB_Bool haveGlyphs;
- int slen = 1;
- int cluster_start = 0;
- hb_uint32 i;
-
- HB_STACKARRAY(HB_UChar16, shapedChars, 2 * shaper_item->item.length);
- *shapedChars = *uc;
- logClusters[0] = 0;
-
- for (i = 1; i < shaper_item->item.length; ++i) {
- hb_uint16 base = shapedChars[cluster_start];
- hb_uint16 shaped = 0;
- HB_Bool invalid = FALSE;
- if (uc[i] == Dagesh) {
- if (base >= 0x5d0
- && base <= 0x5ea
- && base != 0x5d7
- && base != 0x5dd
- && base != 0x5df
- && base != 0x5e2
- && base != 0x5e5) {
- shaped = base - 0x5d0 + 0xfb30;
- } else if (base == 0xfb2a || base == 0xfb2b /* Shin with Shin or Sin dot */) {
- shaped = base + 2;
- } else {
- invalid = TRUE;
- }
- } else if (uc[i] == ShinDot) {
- if (base == 0x05e9)
- shaped = 0xfb2a;
- else if (base == 0xfb49)
- shaped = 0xfb2c;
- else
- invalid = TRUE;
- } else if (uc[i] == SinDot) {
- if (base == 0x05e9)
- shaped = 0xfb2b;
- else if (base == 0xfb49)
- shaped = 0xfb2d;
- else
- invalid = TRUE;
- } else if (uc[i] == Patah) {
- if (base == 0x5d0)
- shaped = 0xfb2e;
- } else if (uc[i] == Qamats) {
- if (base == 0x5d0)
- shaped = 0xfb2f;
- } else if (uc[i] == Holam) {
- if (base == 0x5d5)
- shaped = 0xfb4b;
- } else if (uc[i] == Rafe) {
- if (base == 0x5d1)
- shaped = 0xfb4c;
- else if (base == 0x5db)
- shaped = 0xfb4d;
- else if (base == 0x5e4)
- shaped = 0xfb4e;
- }
-
- if (invalid) {
- shapedChars[slen] = 0x25cc;
- attributes[slen].clusterStart = TRUE;
- attributes[slen].mark = FALSE;
- attributes[slen].combiningClass = 0;
- cluster_start = slen;
- ++slen;
- }
- if (shaped) {
- if (shaper_item->font->klass->canRender(shaper_item->font, (HB_UChar16 *)&shaped, 1)) {
- shapedChars[cluster_start] = shaped;
- } else
- shaped = 0;
- }
- if (!shaped) {
- HB_CharCategory category;
- int cmb;
- shapedChars[slen] = uc[i];
- HB_GetUnicodeCharProperties(uc[i], &category, &cmb);
- if (category != HB_Mark_NonSpacing) {
- attributes[slen].clusterStart = TRUE;
- attributes[slen].mark = FALSE;
- attributes[slen].combiningClass = 0;
- attributes[slen].dontPrint = HB_IsControlChar(uc[i]);
- cluster_start = slen;
- } else {
- attributes[slen].clusterStart = FALSE;
- attributes[slen].mark = TRUE;
- attributes[slen].combiningClass = cmb;
- }
- ++slen;
- }
- logClusters[i] = cluster_start;
- }
-
- haveGlyphs = shaper_item->font->klass
- ->convertStringToGlyphIndices(shaper_item->font,
- shapedChars, slen,
- shaper_item->glyphs, &shaper_item->num_glyphs,
- shaper_item->item.bidiLevel % 2);
-
- HB_FREE_STACKARRAY(shapedChars);
-
- if (!haveGlyphs)
- return FALSE;
-
- HB_HeuristicPosition(shaper_item);
- }
-
- return TRUE;
-}
-
diff --git a/src/3rdparty/harfbuzz/src/harfbuzz-impl.c b/src/3rdparty/harfbuzz/src/harfbuzz-impl.c
deleted file mode 100644
index 8f7edcece3..0000000000
--- a/src/3rdparty/harfbuzz/src/harfbuzz-impl.c
+++ /dev/null
@@ -1,84 +0,0 @@
-/*
- * Copyright (C) 1998-2004 David Turner and Werner Lemberg
- * Copyright (C) 2015 The Qt Company Ltd
- * Copyright (C) 2007 Red Hat, Inc.
- *
- * This is part of HarfBuzz, an OpenType Layout engine library.
- *
- * Permission is hereby granted, without written agreement and without
- * license or royalty fees, to use, copy, modify, and distribute this
- * software and its documentation for any purpose, provided that the
- * above copyright notice and the following two paragraphs appear in
- * all copies of this software.
- *
- * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
- * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
- * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
- * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
- * DAMAGE.
- *
- * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
- * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
- * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
- * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
- * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
- *
- * Red Hat Author(s): Behdad Esfahbod
- */
-
-#include "harfbuzz-impl.h"
-
-
-HB_INTERNAL HB_Pointer
-_hb_alloc(size_t size,
- HB_Error *perror )
-{
- HB_Error error = (HB_Error)0;
- HB_Pointer block = NULL;
-
- if ( size > 0 )
- {
- block = calloc( 1, size );
- if ( !block )
- error = ERR(HB_Err_Out_Of_Memory);
- }
-
- *perror = error;
- return block;
-}
-
-
-HB_INTERNAL HB_Pointer
-_hb_realloc(HB_Pointer block,
- size_t new_size,
- HB_Error *perror )
-{
- HB_Pointer block2 = NULL;
- HB_Error error = (HB_Error)0;
-
- block2 = realloc( block, new_size );
- if ( block2 == NULL && new_size != 0 )
- error = ERR(HB_Err_Out_Of_Memory);
-
- if ( !error )
- block = block2;
-
- *perror = error;
- return block;
-}
-
-
-HB_INTERNAL void
-_hb_free( HB_Pointer block )
-{
- if ( block )
- free( block );
-}
-
-
-/* helper func to set a breakpoint on */
-HB_INTERNAL HB_Error
-_hb_err (HB_Error code)
-{
- return code;
-}
diff --git a/src/3rdparty/harfbuzz/src/harfbuzz-impl.h b/src/3rdparty/harfbuzz/src/harfbuzz-impl.h
deleted file mode 100644
index f98594ac91..0000000000
--- a/src/3rdparty/harfbuzz/src/harfbuzz-impl.h
+++ /dev/null
@@ -1,131 +0,0 @@
-/*
- * Copyright (C) 1998-2004 David Turner and Werner Lemberg
- * Copyright (C) 2006 Behdad Esfahbod
- *
- * This is part of HarfBuzz, an OpenType Layout engine 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 HARFBUZZ_IMPL_H
-#define HARFBUZZ_IMPL_H
-
-#include "harfbuzz-global.h"
-
-#include <stdlib.h>
-
-HB_BEGIN_HEADER
-
-#ifndef HB_INTERNAL
-# define HB_INTERNAL
-#endif
-
-#ifndef NULL
-# define NULL ((void *)0)
-#endif
-
-#ifndef FALSE
-# define FALSE 0
-#endif
-
-#ifndef TRUE
-# define TRUE 1
-#endif
-
-#ifndef TTAG_GDEF
-# define TTAG_GDEF HB_MAKE_TAG( 'G', 'D', 'E', 'F' )
-#endif
-#ifndef TTAG_GPOS
-# define TTAG_GPOS HB_MAKE_TAG( 'G', 'P', 'O', 'S' )
-#endif
-#ifndef TTAG_GSUB
-# define TTAG_GSUB HB_MAKE_TAG( 'G', 'S', 'U', 'B' )
-#endif
-
-#ifndef HB_UNUSED
-# define HB_UNUSED(arg) ((void)(arg))
-#endif
-
-#define HB_LIKELY(cond) (cond)
-#define HB_UNLIKELY(cond) (cond)
-
-#define ARRAY_LEN(Array) ((int)(sizeof (Array) / sizeof (Array)[0]))
-
-
-
-#define HB_IsHighSurrogate(ucs) \
- (((ucs) & 0xfc00) == 0xd800)
-
-#define HB_IsLowSurrogate(ucs) \
- (((ucs) & 0xfc00) == 0xdc00)
-
-#define HB_SurrogateToUcs4(high, low) \
- (((HB_UChar32)(high))<<10) + (low) - 0x35fdc00;
-
-
-
-
-
-#define ALLOC(_ptr,_size) \
- ( (_ptr) = _hb_alloc( _size, &error ), error != 0 )
-
-#define REALLOC(_ptr,_newsz) \
- ( (_ptr) = _hb_realloc( (_ptr), (_newsz), &error ), error != 0 )
-
-#define FREE(_ptr) \
- do { \
- if ( (_ptr) ) \
- { \
- _hb_free( _ptr ); \
- _ptr = NULL; \
- } \
- } while (0)
-
-#define ALLOC_ARRAY(_ptr,_count,_type) \
- ALLOC(_ptr,(_count)*sizeof(_type))
-
-#define REALLOC_ARRAY(_ptr,_newcnt,_type) \
- REALLOC(_ptr,(_newcnt)*sizeof(_type))
-
-#define MEM_Copy(dest,source,count) memcpy( (char*)(dest), (const char*)(source), (size_t)(count) )
-
-#define ERR(err) _hb_err (err)
-
-
-HB_INTERNAL HB_Pointer
-_hb_alloc( size_t size,
- HB_Error *perror_ );
-
-HB_INTERNAL HB_Pointer
-_hb_realloc( HB_Pointer block,
- size_t new_size,
- HB_Error *perror_ );
-
-HB_INTERNAL void
-_hb_free( HB_Pointer block );
-
-
-/* helper func to set a breakpoint on */
-HB_INTERNAL HB_Error
-_hb_err (HB_Error code);
-
-
-HB_END_HEADER
-
-#endif /* HARFBUZZ_IMPL_H */
diff --git a/src/3rdparty/harfbuzz/src/harfbuzz-indic.cpp b/src/3rdparty/harfbuzz/src/harfbuzz-indic.cpp
deleted file mode 100644
index de3bcb2bbf..0000000000
--- a/src/3rdparty/harfbuzz/src/harfbuzz-indic.cpp
+++ /dev/null
@@ -1,1899 +0,0 @@
-/*
- * Copyright (C) 2015 The Qt Company Ltd
- *
- * This is part of HarfBuzz, an OpenType Layout engine library.
- *
- * Permission is hereby granted, without written agreement and without
- * license or royalty fees, to use, copy, modify, and distribute this
- * software and its documentation for any purpose, provided that the
- * above copyright notice and the following two paragraphs appear in
- * all copies of this software.
- *
- * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
- * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
- * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
- * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
- * DAMAGE.
- *
- * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
- * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
- * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
- * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
- * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
- */
-
-#include "harfbuzz-shaper.h"
-#include "harfbuzz-shaper-private.h"
-
-#include <assert.h>
-#include <stdio.h>
-
-#define FLAG(x) (1 << (x))
-
-static HB_Bool isLetter(HB_UChar16 ucs)
-{
- const int test = FLAG(HB_Letter_Uppercase) |
- FLAG(HB_Letter_Lowercase) |
- FLAG(HB_Letter_Titlecase) |
- FLAG(HB_Letter_Modifier) |
- FLAG(HB_Letter_Other);
- return !!(FLAG(HB_GetUnicodeCharCategory(ucs)) & test);
-}
-
-static HB_Bool isMark(HB_UChar16 ucs)
-{
- const int test = FLAG(HB_Mark_NonSpacing) |
- FLAG(HB_Mark_SpacingCombining) |
- FLAG(HB_Mark_Enclosing);
- return !!(FLAG(HB_GetUnicodeCharCategory(ucs)) & test);
-}
-
-enum Form {
- Invalid = 0x0,
- UnknownForm = Invalid,
- Consonant,
- Nukta,
- Halant,
- Matra,
- VowelMark,
- StressMark,
- IndependentVowel,
- LengthMark,
- Control,
- Other
-};
-
-static const unsigned char indicForms[0xe00-0x900] = {
- // Devangari
- Invalid, VowelMark, VowelMark, VowelMark,
- IndependentVowel, IndependentVowel, IndependentVowel, IndependentVowel,
- IndependentVowel, IndependentVowel, IndependentVowel, IndependentVowel,
- IndependentVowel, IndependentVowel, IndependentVowel, IndependentVowel,
-
- IndependentVowel, IndependentVowel, IndependentVowel, IndependentVowel,
- IndependentVowel, Consonant, Consonant, Consonant,
- Consonant, Consonant, Consonant, Consonant,
- Consonant, Consonant, Consonant, Consonant,
-
- Consonant, Consonant, Consonant, Consonant,
- Consonant, Consonant, Consonant, Consonant,
- Consonant, Consonant, Consonant, Consonant,
- Consonant, Consonant, Consonant, Consonant,
-
- Consonant, Consonant, Consonant, Consonant,
- Consonant, Consonant, Consonant, Consonant,
- Consonant, Consonant, UnknownForm, UnknownForm,
- Nukta, Other, Matra, Matra,
-
- Matra, Matra, Matra, Matra,
- Matra, Matra, Matra, Matra,
- Matra, Matra, Matra, Matra,
- Matra, Halant, UnknownForm, UnknownForm,
-
- Other, StressMark, StressMark, StressMark,
- StressMark, UnknownForm, UnknownForm, UnknownForm,
- Consonant, Consonant, Consonant, Consonant,
- Consonant, Consonant, Consonant, Consonant,
-
- IndependentVowel, IndependentVowel, VowelMark, VowelMark,
- Other, Other, Other, Other,
- Other, Other, Other, Other,
- Other, Other, Other, Other,
-
- Other, Other, Other, Other,
- Other, Other, Other, Other,
- Other, Other, Other, Consonant,
- Consonant, Consonant /* ??? */, Consonant, Consonant,
-
- // Bengali
- Invalid, VowelMark, VowelMark, VowelMark,
- Invalid, IndependentVowel, IndependentVowel, IndependentVowel,
- IndependentVowel, IndependentVowel, IndependentVowel, IndependentVowel,
- IndependentVowel, Invalid, Invalid, IndependentVowel,
-
- IndependentVowel, Invalid, Invalid, IndependentVowel,
- IndependentVowel, Consonant, Consonant, Consonant,
- Consonant, Consonant, Consonant, Consonant,
- Consonant, Consonant, Consonant, Consonant,
-
- Consonant, Consonant, Consonant, Consonant,
- Consonant, Consonant, Consonant, Consonant,
- Consonant, Invalid, Consonant, Consonant,
- Consonant, Consonant, Consonant, Consonant,
-
- Consonant, Invalid, Consonant, Invalid,
- Invalid, Invalid, Consonant, Consonant,
- Consonant, Consonant, UnknownForm, UnknownForm,
- Nukta, Other, Matra, Matra,
-
- Matra, Matra, Matra, Matra,
- Matra, Invalid, Invalid, Matra,
- Matra, Invalid, Invalid, Matra,
- Matra, Halant, Consonant, UnknownForm,
-
- Invalid, Invalid, Invalid, Invalid,
- Invalid, Invalid, Invalid, VowelMark,
- Invalid, Invalid, Invalid, Invalid,
- Consonant, Consonant, Invalid, Consonant,
-
- IndependentVowel, IndependentVowel, VowelMark, VowelMark,
- Other, Other, Other, Other,
- Other, Other, Other, Other,
- Other, Other, Other, Other,
-
- Consonant, Consonant, Other, Other,
- Other, Other, Other, Other,
- Other, Other, Other, Other,
- Other, Other, Other, Other,
-
- // Gurmukhi
- Invalid, VowelMark, VowelMark, VowelMark,
- Invalid, IndependentVowel, IndependentVowel, IndependentVowel,
- IndependentVowel, IndependentVowel, IndependentVowel, Invalid,
- Invalid, Invalid, Invalid, IndependentVowel,
-
- IndependentVowel, Invalid, Invalid, IndependentVowel,
- IndependentVowel, Consonant, Consonant, Consonant,
- Consonant, Consonant, Consonant, Consonant,
- Consonant, Consonant, Consonant, Consonant,
-
- Consonant, Consonant, Consonant, Consonant,
- Consonant, Consonant, Consonant, Consonant,
- Consonant, Invalid, Consonant, Consonant,
- Consonant, Consonant, Consonant, Consonant,
-
- Consonant, Invalid, Consonant, Consonant,
- Invalid, Consonant, Consonant, Invalid,
- Consonant, Consonant, UnknownForm, UnknownForm,
- Nukta, Other, Matra, Matra,
-
- Matra, Matra, Matra, Invalid,
- Invalid, Invalid, Invalid, Matra,
- Matra, Invalid, Invalid, Matra,
- Matra, Halant, UnknownForm, UnknownForm,
-
- Invalid, Invalid, Invalid, Invalid,
- Invalid, UnknownForm, UnknownForm, UnknownForm,
- Invalid, Consonant, Consonant, Consonant,
- Consonant, Invalid, Consonant, Invalid,
-
- Other, Other, Invalid, Invalid,
- Other, Other, Other, Other,
- Other, Other, Other, Other,
- Other, Other, Other, Other,
-
- StressMark, StressMark, Consonant, Consonant,
- Other, Other, Other, Other,
- Other, Other, Other, Other,
- Other, Other, Other, Other,
-
- // Gujarati
- Invalid, VowelMark, VowelMark, VowelMark,
- Invalid, IndependentVowel, IndependentVowel, IndependentVowel,
- IndependentVowel, IndependentVowel, IndependentVowel, IndependentVowel,
- IndependentVowel, IndependentVowel, Invalid, IndependentVowel,
-
- IndependentVowel, IndependentVowel, Invalid, IndependentVowel,
- IndependentVowel, Consonant, Consonant, Consonant,
- Consonant, Consonant, Consonant, Consonant,
- Consonant, Consonant, Consonant, Consonant,
-
- Consonant, Consonant, Consonant, Consonant,
- Consonant, Consonant, Consonant, Consonant,
- Consonant, Invalid, Consonant, Consonant,
- Consonant, Consonant, Consonant, Consonant,
-
- Consonant, Invalid, Consonant, Consonant,
- Invalid, Consonant, Consonant, Consonant,
- Consonant, Consonant, UnknownForm, UnknownForm,
- Nukta, Other, Matra, Matra,
-
- Matra, Matra, Matra, Matra,
- Matra, Matra, Invalid, Matra,
- Matra, Matra, Invalid, Matra,
- Matra, Halant, UnknownForm, UnknownForm,
-
- Other, UnknownForm, UnknownForm, UnknownForm,
- UnknownForm, UnknownForm, UnknownForm, UnknownForm,
- UnknownForm, UnknownForm, UnknownForm, UnknownForm,
- UnknownForm, UnknownForm, UnknownForm, UnknownForm,
-
- IndependentVowel, IndependentVowel, VowelMark, VowelMark,
- Other, Other, Other, Other,
- Other, Other, Other, Other,
- Other, Other, Other, Other,
-
- Other, Other, Other, Other,
- Other, Other, Other, Other,
- Other, Other, Other, Other,
- Other, Other, Other, Other,
-
- // Oriya
- Invalid, VowelMark, VowelMark, VowelMark,
- Invalid, IndependentVowel, IndependentVowel, IndependentVowel,
- IndependentVowel, IndependentVowel, IndependentVowel, IndependentVowel,
- IndependentVowel, Invalid, Invalid, IndependentVowel,
-
- IndependentVowel, Invalid, Invalid, IndependentVowel,
- IndependentVowel, Consonant, Consonant, Consonant,
- Consonant, Consonant, Consonant, Consonant,
- Consonant, Consonant, Consonant, Consonant,
-
- Consonant, Consonant, Consonant, Consonant,
- Consonant, Consonant, Consonant, Consonant,
- Consonant, Invalid, Consonant, Consonant,
- Consonant, Consonant, Consonant, Consonant,
-
- Consonant, Invalid, Consonant, Consonant,
- Invalid, Consonant, Consonant, Consonant,
- Consonant, Consonant, UnknownForm, UnknownForm,
- Nukta, Other, Matra, Matra,
-
- Matra, Matra, Matra, Matra,
- Invalid, Invalid, Invalid, Matra,
- Matra, Invalid, Invalid, Matra,
- Matra, Halant, UnknownForm, UnknownForm,
-
- Other, Invalid, Invalid, Invalid,
- Invalid, UnknownForm, LengthMark, LengthMark,
- Invalid, Invalid, Invalid, Invalid,
- Consonant, Consonant, Invalid, Consonant,
-
- IndependentVowel, IndependentVowel, Invalid, Invalid,
- Invalid, Invalid, Other, Other,
- Other, Other, Other, Other,
- Other, Other, Other, Other,
-
- Other, Consonant, Other, Other,
- Other, Other, Other, Other,
- Other, Other, Other, Other,
- Other, Other, Other, Other,
-
- //Tamil
- Invalid, Invalid, VowelMark, Other,
- Invalid, IndependentVowel, IndependentVowel, IndependentVowel,
- IndependentVowel, IndependentVowel, IndependentVowel, Invalid,
- Invalid, Invalid, IndependentVowel, IndependentVowel,
-
- IndependentVowel, Invalid, IndependentVowel, IndependentVowel,
- IndependentVowel, Consonant, Invalid, Invalid,
- Invalid, Consonant, Consonant, Invalid,
- Consonant, Invalid, Consonant, Consonant,
-
- Invalid, Invalid, Invalid, Consonant,
- Consonant, Invalid, Invalid, Invalid,
- Consonant, Consonant, Consonant, Invalid,
- Invalid, Invalid, Consonant, Consonant,
-
- Consonant, Consonant, Consonant, Consonant,
- Consonant, Consonant, Consonant, Consonant,
- Consonant, Consonant, UnknownForm, UnknownForm,
- Invalid, Invalid, Matra, Matra,
-
- Matra, Matra, Matra, Invalid,
- Invalid, Invalid, Matra, Matra,
- Matra, Invalid, Matra, Matra,
- Matra, Halant, Invalid, Invalid,
-
- Invalid, Invalid, Invalid, Invalid,
- Invalid, Invalid, Invalid, LengthMark,
- Invalid, Invalid, Invalid, Invalid,
- Invalid, Invalid, Invalid, Invalid,
-
- Invalid, Invalid, Invalid, Invalid,
- Invalid, Invalid, Other, Other,
- Other, Other, Other, Other,
- Other, Other, Other, Other,
-
- Other, Other, Other, Other,
- Other, Other, Other, Other,
- Other, Other, Other, Other,
- Other, Other, Other, Other,
-
- // Telugu
- Invalid, VowelMark, VowelMark, VowelMark,
- Invalid, IndependentVowel, IndependentVowel, IndependentVowel,
- IndependentVowel, IndependentVowel, IndependentVowel, IndependentVowel,
- IndependentVowel, Invalid, IndependentVowel, IndependentVowel,
-
- IndependentVowel, Invalid, IndependentVowel, IndependentVowel,
- IndependentVowel, Consonant, Consonant, Consonant,
- Consonant, Consonant, Consonant, Consonant,
- Consonant, Consonant, Consonant, Consonant,
-
- Consonant, Consonant, Consonant, Consonant,
- Consonant, Consonant, Consonant, Consonant,
- Consonant, Invalid, Consonant, Consonant,
- Consonant, Consonant, Consonant, Consonant,
-
- Consonant, Consonant, Consonant, Consonant,
- Invalid, Consonant, Consonant, Consonant,
- Consonant, Consonant, UnknownForm, UnknownForm,
- Invalid, Invalid, Matra, Matra,
-
- Matra, Matra, Matra, Matra,
- Matra, Invalid, Matra, Matra,
- Matra, Invalid, Matra, Matra,
- Matra, Halant, Invalid, Invalid,
-
- Invalid, Invalid, Invalid, Invalid,
- Invalid, LengthMark, Matra, Invalid,
- Invalid, Invalid, Invalid, Invalid,
- Invalid, Invalid, Invalid, Invalid,
-
- IndependentVowel, IndependentVowel, Invalid, Invalid,
- Invalid, Invalid, Other, Other,
- Other, Other, Other, Other,
- Other, Other, Other, Other,
-
- Other, Other, Other, Other,
- Other, Other, Other, Other,
- Other, Other, Other, Other,
- Other, Other, Other, Other,
-
- // Kannada
- Invalid, Invalid, VowelMark, VowelMark,
- Invalid, IndependentVowel, IndependentVowel, IndependentVowel,
- IndependentVowel, IndependentVowel, IndependentVowel, IndependentVowel,
- IndependentVowel, Invalid, IndependentVowel, IndependentVowel,
-
- IndependentVowel, Invalid, IndependentVowel, IndependentVowel,
- IndependentVowel, Consonant, Consonant, Consonant,
- Consonant, Consonant, Consonant, Consonant,
- Consonant, Consonant, Consonant, Consonant,
-
- Consonant, Consonant, Consonant, Consonant,
- Consonant, Consonant, Consonant, Consonant,
- Consonant, Invalid, Consonant, Consonant,
- Consonant, Consonant, Consonant, Consonant,
-
- Consonant, Consonant, Consonant, Consonant,
- Invalid, Consonant, Consonant, Consonant,
- Consonant, Consonant, UnknownForm, UnknownForm,
- Nukta, Other, Matra, Matra,
-
- Matra, Matra, Matra, Matra,
- Matra, Invalid, Matra, Matra,
- Matra, Invalid, Matra, Matra,
- Matra, Halant, Invalid, Invalid,
-
- Invalid, Invalid, Invalid, Invalid,
- Invalid, LengthMark, LengthMark, Invalid,
- Invalid, Invalid, Invalid, Invalid,
- Invalid, Invalid, Consonant, Invalid,
-
- IndependentVowel, IndependentVowel, VowelMark, VowelMark,
- Invalid, Invalid, Other, Other,
- Other, Other, Other, Other,
- Other, Other, Other, Other,
-
- Other, Other, Other, Other,
- Other, Other, Other, Other,
- Other, Other, Other, Other,
- Other, Other, Other, Other,
-
- // Malayalam
- Invalid, Invalid, VowelMark, VowelMark,
- Invalid, IndependentVowel, IndependentVowel, IndependentVowel,
- IndependentVowel, IndependentVowel, IndependentVowel, IndependentVowel,
- IndependentVowel, Invalid, IndependentVowel, IndependentVowel,
-
- IndependentVowel, Invalid, IndependentVowel, IndependentVowel,
- IndependentVowel, Consonant, Consonant, Consonant,
- Consonant, Consonant, Consonant, Consonant,
- Consonant, Consonant, Consonant, Consonant,
-
- Consonant, Consonant, Consonant, Consonant,
- Consonant, Consonant, Consonant, Consonant,
- Consonant, Invalid, Consonant, Consonant,
- Consonant, Consonant, Consonant, Consonant,
-
- Consonant, Consonant, Consonant, Consonant,
- Consonant, Consonant, Consonant, Consonant,
- Consonant, Consonant, UnknownForm, UnknownForm,
- Invalid, Invalid, Matra, Matra,
-
- Matra, Matra, Matra, Matra,
- Invalid, Invalid, Matra, Matra,
- Matra, Invalid, Matra, Matra,
- Matra, Halant, Invalid, Invalid,
-
- Invalid, Invalid, Invalid, Invalid,
- Invalid, Invalid, Invalid, Matra,
- Invalid, Invalid, Invalid, Invalid,
- Invalid, Invalid, Invalid, Invalid,
-
- IndependentVowel, IndependentVowel, Invalid, Invalid,
- Invalid, Invalid, Other, Other,
- Other, Other, Other, Other,
- Other, Other, Other, Other,
-
- Other, Other, Other, Other,
- Other, Other, Other, Other,
- Other, Other, Other, Other,
- Other, Other, Other, Other,
-
- // Sinhala
- Invalid, Invalid, VowelMark, VowelMark,
- Invalid, IndependentVowel, IndependentVowel, IndependentVowel,
- IndependentVowel, IndependentVowel, IndependentVowel, IndependentVowel,
- IndependentVowel, IndependentVowel, IndependentVowel, IndependentVowel,
-
- IndependentVowel, IndependentVowel, IndependentVowel, IndependentVowel,
- IndependentVowel, IndependentVowel, IndependentVowel, Invalid,
- Invalid, Invalid, Consonant, Consonant,
- Consonant, Consonant, Consonant, Consonant,
-
- Consonant, Consonant, Consonant, Consonant,
- Consonant, Consonant, Consonant, Consonant,
- Consonant, Consonant, Consonant, Consonant,
- Consonant, Consonant, Consonant, Consonant,
-
- Consonant, Consonant, Invalid, Consonant,
- Consonant, Consonant, Consonant, Consonant,
- Consonant, Consonant, Consonant, Consonant,
- Invalid, Consonant, Invalid, Invalid,
-
- Consonant, Consonant, Consonant, Consonant,
- Consonant, Consonant, Consonant, Invalid,
- Invalid, Invalid, Halant, Invalid,
- Invalid, Invalid, Invalid, Matra,
-
- Matra, Matra, Matra, Matra,
- Matra, Invalid, Matra, Invalid,
- Matra, Matra, Matra, Matra,
- Matra, Matra, Matra, Matra,
-
- Invalid, Invalid, Invalid, Invalid,
- Invalid, Invalid, Invalid, Invalid,
- Invalid, Invalid, Invalid, Invalid,
- Invalid, Invalid, Invalid, Invalid,
-
- Invalid, Invalid, Matra, Matra,
- Other, Other, Other, Other,
- Other, Other, Other, Other,
- Other, Other, Other, Other,
-};
-
-enum Position {
- None,
- Pre,
- Above,
- Below,
- Post,
- Split,
- Base,
- Reph,
- Vattu,
- Inherit
-};
-
-static const unsigned char indicPosition[0xe00-0x900] = {
- // Devanagari
- None, Above, Above, Post,
- None, None, None, None,
- None, None, None, None,
- None, None, None, None,
-
- None, None, None, None,
- None, None, None, None,
- None, None, None, None,
- None, None, None, None,
-
- None, None, None, None,
- None, None, None, None,
- None, None, None, None,
- None, None, None, None,
-
- Below, None, None, None,
- None, None, None, None,
- None, None, None, None,
- None, None, Post, Pre,
-
- Post, Below, Below, Below,
- Below, Above, Above, Above,
- Above, Post, Post, Post,
- Post, None, None, None,
-
- None, Above, Below, Above,
- Above, None, None, None,
- None, None, None, None,
- None, None, None, None,
-
- None, None, Below, Below,
- None, None, None, None,
- None, None, None, None,
- None, None, None, None,
-
- None, None, None, None,
- None, None, None, None,
- None, None, None, None,
- None, None, None, None,
-
- // Bengali
- None, Above, Post, Post,
- None, None, None, None,
- None, None, None, None,
- None, None, None, None,
-
- None, None, None, None,
- None, None, None, None,
- None, None, None, None,
- None, None, None, None,
-
- None, None, None, None,
- None, None, None, None,
- None, None, None, None,
- Below, None, None, Post,
-
- Below, None, None, None,
- None, None, None, None,
- None, None, None, None,
- Below, None, Post, Pre,
-
- Post, Below, Below, Below,
- Below, None, None, Pre,
- Pre, None, None, Split,
- Split, Below, None, None,
-
- None, None, None, None,
- None, None, None, Post,
- None, None, None, None,
- None, None, None, None,
-
- None, None, Below, Below,
- None, None, None, None,
- None, None, None, None,
- None, None, None, None,
-
- Below, None, None, None,
- None, None, None, None,
- None, None, None, None,
- None, None, None, None,
-
- // Gurmukhi
- None, Above, Above, Post,
- None, None, None, None,
- None, None, None, None,
- None, None, None, None,
-
- None, None, None, None,
- None, None, None, None,
- None, None, None, None,
- None, None, None, None,
-
- None, None, None, None,
- None, None, None, None,
- None, None, None, None,
- None, None, None, Post,
-
- Below, None, None, None,
- None, Below, None, None,
- None, Below, None, None,
- Below, None, Post, Pre,
-
- Post, Below, Below, None,
- None, None, None, Above,
- Above, None, None, Above,
- Above, None, None, None,
-
- None, None, None, None,
- None, None, None, None,
- None, None, None, None,
- None, None, None, None,
-
- None, None, None, None,
- None, None, None, None,
- None, None, None, None,
- None, None, None, None,
-
- Above, Above, None, None,
- None, None, None, None,
- None, None, None, None,
- None, None, None, None,
-
- // Gujarati
- None, Above, Above, Post,
- None, None, None, None,
- None, None, None, None,
- None, None, None, None,
-
- None, None, None, None,
- None, None, None, None,
- None, None, None, None,
- None, None, None, None,
-
- None, None, None, None,
- None, None, None, None,
- None, None, None, None,
- None, None, None, None,
-
- Below, None, None, None,
- None, None, None, None,
- None, None, None, None,
- None, None, Post, Pre,
-
- Post, Below, Below, Below,
- Below, Above, None, Above,
- Above, Post, None, Post,
- Post, None, None, None,
-
- None, None, None, None,
- None, None, None, None,
- None, None, None, None,
- None, None, None, None,
-
- None, None, Below, Below,
- None, None, None, None,
- None, None, None, None,
- None, None, None, None,
-
- None, None, None, None,
- None, None, None, None,
- None, None, None, None,
- None, None, None, None,
-
- // Oriya
- None, Above, Post, Post,
- None, None, None, None,
- None, None, None, None,
- None, None, None, None,
-
- None, None, None, None,
- None, Below, Below, Below,
- Below, Below, Below, Below,
- Below, Below, None, Below,
-
- Below, Below, Below, Below,
- Below, Below, Below, Below,
- Below, None, Below, Below,
- Below, Below, Below, Post,
-
- Below, None, Below, Below,
- None, Below, Below, Below,
- Below, Below, None, None,
- None, None, Post, Above,
-
- Post, Below, Below, Below,
- None, None, None, Pre,
- Split, None, None, Split,
- Split, None, None, None,
-
- None, None, None, None,
- None, None, Above, Post,
- None, None, None, None,
- None, None, None, Post,
-
- None, None, None, None,
- None, None, None, None,
- None, None, None, None,
- None, None, None, None,
-
- None, Below, None, None,
- None, None, None, None,
- None, None, None, None,
- None, None, None, None,
-
- // Tamil
- None, None, Above, None,
- None, None, None, None,
- None, None, None, None,
- None, None, None, None,
-
- None, None, None, None,
- None, None, None, None,
- None, None, None, None,
- None, None, None, None,
-
- None, None, None, None,
- None, None, None, None,
- None, None, None, None,
- None, None, None, None,
-
- None, None, None, None,
- None, None, None, None,
- None, None, None, None,
- None, None, Post, Post,
-
- Above, Below, Below, None,
- None, None, Pre, Pre,
- Pre, None, Split, Split,
- Split, Halant, None, None,
-
- None, None, None, None,
- None, None, None, Post,
- None, None, None, None,
- None, None, None, None,
-
- None, None, None, None,
- None, None, None, None,
- None, None, None, None,
- None, None, None, None,
-
- None, None, None, None,
- None, None, None, None,
- None, None, None, None,
- None, None, None, None,
-
- // Telugu
- None, Post, Post, Post,
- None, None, None, None,
- None, None, None, None,
- None, None, None, None,
-
- None, None, None, None,
- None, Below, Below, Below,
- Below, Below, Below, Below,
- Below, Below, Below, Below,
-
- Below, Below, Below, Below,
- Below, Below, Below, Below,
- Below, None, Below, Below,
- Below, Below, Below, Below,
-
- Below, None, Below, Below,
- None, Below, Below, Below,
- Below, Below, None, None,
- None, None, Post, Above,
-
- Above, Post, Post, Post,
- Post, None, Above, Above,
- Split, None, Post, Above,
- Above, Halant, None, None,
-
- None, None, None, None,
- None, Above, Below, None,
- None, None, None, None,
- None, None, None, None,
-
- None, None, None, None,
- None, None, None, None,
- None, None, None, None,
- None, None, None, None,
-
- None, None, None, None,
- None, None, None, None,
- None, None, None, None,
- None, None, None, None,
-
- // Kannada
- None, None, Post, Post,
- None, None, None, None,
- None, None, None, None,
- None, None, None, None,
-
- None, None, None, None,
- None, Below, Below, Below,
- Below, Below, Below, Below,
- Below, Below, Below, Below,
-
- Below, Below, Below, Below,
- Below, Below, Below, Below,
- Below, Below, Below, Below,
- Below, Below, Below, Below,
-
- Below, None, Below, Below,
- None, Below, Below, Below,
- Below, Below, None, None,
- None, None, Post, Above,
-
- Split, Post, Post, Post,
- Post, None, Above, Split,
- Split, None, Split, Split,
- Above, Halant, None, None,
-
- None, None, None, None,
- None, Post, Post, None,
- None, None, None, None,
- None, None, Below, None,
-
- None, None, Below, Below,
- None, None, None, None,
- None, None, None, None,
- None, None, None, None,
-
- None, None, None, None,
- None, None, None, None,
- None, None, None, None,
- None, None, None, None,
-
- // Malayalam
- None, None, Post, Post,
- None, None, None, None,
- None, None, None, None,
- None, None, None, None,
-
- None, None, None, None,
- None, None, None, None,
- None, None, None, None,
- None, None, None, None,
-
- None, None, None, None,
- None, None, None, None,
- None, None, None, None,
- None, None, None, Post,
-
- Pre, None, Below, None,
- None, Post, None, None,
- None, None, None, None,
- None, None, Post, Post,
-
- Post, Post, Post, Post,
- None, None, Pre, Pre,
- Pre, None, Split, Split,
- Split, Halant, None, None,
-
- None, None, None, None,
- None, None, None, Post,
- None, None, None, None,
- None, None, None, None,
-
- None, None, None, None,
- None, None, None, None,
- None, None, None, None,
- None, None, None, None,
-
- None, None, None, None,
- None, None, None, None,
- None, None, None, None,
- None, None, None, None,
-
- // Sinhala
- None, None, Post, Post,
- None, None, None, None,
- None, None, None, None,
- None, None, None, None,
-
- None, None, None, None,
- None, None, None, None,
- None, None, None, None,
- None, None, None, None,
-
- None, None, None, None,
- None, None, None, None,
- None, None, None, None,
- None, None, None, None,
-
- None, None, None, None,
- None, None, None, None,
- None, None, None, None,
- None, None, None, None,
-
- None, None, None, None,
- None, None, None, None,
- None, None, None, None,
- None, None, None, Post,
-
- Post, Post, Above, Above,
- Below, None, Below, None,
- Post, Pre, Split, Pre,
- Split, Split, Split, Post,
-
- None, None, None, None,
- None, None, None, None,
- None, None, None, None,
- None, None, None, None,
-
- None, None, Post, Post,
- None, None, None, None,
- None, None, None, None,
- None, None, None, None
-};
-
-static inline Form form(unsigned short uc) {
- if (uc < 0x900 || uc > 0xdff) {
- if (uc == 0x25cc)
- return Consonant;
- if (uc == 0x200c || uc == 0x200d)
- return Control;
- return Other;
- }
- return (Form)indicForms[uc-0x900];
-}
-
-static inline Position indic_position(unsigned short uc) {
- if (uc < 0x900 || uc > 0xdff)
- return None;
- return (Position) indicPosition[uc-0x900];
-}
-
-
-enum IndicScriptProperties {
- HasReph = 0x01,
- HasSplit = 0x02
-};
-
-const hb_uint8 scriptProperties[10] = {
- // Devanagari,
- HasReph,
- // Bengali,
- HasReph|HasSplit,
- // Gurmukhi,
- 0,
- // Gujarati,
- HasReph,
- // Oriya,
- HasReph|HasSplit,
- // Tamil,
- HasSplit,
- // Telugu,
- HasSplit,
- // Kannada,
- HasSplit|HasReph,
- // Malayalam,
- HasSplit,
- // Sinhala,
- HasSplit
-};
-
-struct IndicOrdering {
- Form form;
- Position position;
-};
-
-static const IndicOrdering devanagari_order [] = {
- { Consonant, Below },
- { Matra, Below },
- { VowelMark, Below },
- { StressMark, Below },
- { Matra, Above },
- { Matra, Post },
- { Consonant, Reph },
- { VowelMark, Above },
- { StressMark, Above },
- { VowelMark, Post },
- { (Form)0, None }
-};
-
-static const IndicOrdering bengali_order [] = {
- { Consonant, Below },
- { Matra, Below },
- { Matra, Above },
- { Consonant, Reph },
- { VowelMark, Above },
- { Consonant, Post },
- { Matra, Post },
- { VowelMark, Post },
- { (Form)0, None }
-};
-
-static const IndicOrdering gurmukhi_order [] = {
- { Consonant, Below },
- { Matra, Below },
- { Matra, Above },
- { Consonant, Post },
- { Matra, Post },
- { VowelMark, Above },
- { (Form)0, None }
-};
-
-static const IndicOrdering tamil_order [] = {
- { Matra, Above },
- { Matra, Post },
- { VowelMark, Post },
- { (Form)0, None }
-};
-
-static const IndicOrdering telugu_order [] = {
- { Matra, Above },
- { Matra, Below },
- { Matra, Post },
- { Consonant, Below },
- { Consonant, Post },
- { VowelMark, Post },
- { (Form)0, None }
-};
-
-static const IndicOrdering kannada_order [] = {
- { Matra, Above },
- { Matra, Post },
- { Consonant, Below },
- { Consonant, Post },
- { LengthMark, Post },
- { Consonant, Reph },
- { VowelMark, Post },
- { (Form)0, None }
-};
-
-static const IndicOrdering malayalam_order [] = {
- { Consonant, Below },
- { Matra, Below },
- { Consonant, Reph },
- { Consonant, Post },
- { Matra, Post },
- { VowelMark, Post },
- { (Form)0, None }
-};
-
-static const IndicOrdering sinhala_order [] = {
- { Matra, Below },
- { Matra, Above },
- { Matra, Post },
- { VowelMark, Post },
- { (Form)0, None }
-};
-
-static const IndicOrdering * const indic_order[] = {
- devanagari_order, // Devanagari
- bengali_order, // Bengali
- gurmukhi_order, // Gurmukhi
- devanagari_order, // Gujarati
- bengali_order, // Oriya
- tamil_order, // Tamil
- telugu_order, // Telugu
- kannada_order, // Kannada
- malayalam_order, // Malayalam
- sinhala_order // Sinhala
-};
-
-
-
-// vowel matras that have to be split into two parts.
-static const unsigned short split_matras[] = {
- // matra, split1, split2, split3
-
- // bengalis
- 0x9cb, 0x9c7, 0x9be, 0x0,
- 0x9cc, 0x9c7, 0x9d7, 0x0,
- // oriya
- 0xb48, 0xb47, 0xb56, 0x0,
- 0xb4b, 0xb47, 0xb3e, 0x0,
- 0xb4c, 0xb47, 0xb57, 0x0,
- // tamil
- 0xbca, 0xbc6, 0xbbe, 0x0,
- 0xbcb, 0xbc7, 0xbbe, 0x0,
- 0xbcc, 0xbc6, 0xbd7, 0x0,
- // telugu
- 0xc48, 0xc46, 0xc56, 0x0,
- // kannada
- 0xcc0, 0xcbf, 0xcd5, 0x0,
- 0xcc7, 0xcc6, 0xcd5, 0x0,
- 0xcc8, 0xcc6, 0xcd6, 0x0,
- 0xcca, 0xcc6, 0xcc2, 0x0,
- 0xccb, 0xcc6, 0xcc2, 0xcd5,
- // malayalam
- 0xd4a, 0xd46, 0xd3e, 0x0,
- 0xd4b, 0xd47, 0xd3e, 0x0,
- 0xd4c, 0xd46, 0xd57, 0x0,
- // sinhala
- 0xdda, 0xdd9, 0xdca, 0x0,
- 0xddc, 0xdd9, 0xdcf, 0x0,
- 0xddd, 0xdd9, 0xdcf, 0xdca,
- 0xdde, 0xdd9, 0xddf, 0x0,
- 0xffff
-};
-
-static inline void splitMatra(unsigned short *reordered, int matra, int &len)
-{
- unsigned short matra_uc = reordered[matra];
- //qDebug("matra=%d, reordered[matra]=%x", matra, reordered[matra]);
-
- const unsigned short *split = split_matras;
- while (split[0] < matra_uc)
- split += 4;
-
- assert(*split == matra_uc);
- ++split;
-
- int added_chars = split[2] == 0x0 ? 1 : 2;
-
- memmove(reordered + matra + added_chars, reordered + matra, (len-matra)*sizeof(unsigned short));
- reordered[matra] = split[0];
- reordered[matra+1] = split[1];
- if(added_chars == 2)
- reordered[matra+2] = split[2];
- len += added_chars;
-}
-
-#ifndef NO_OPENTYPE
-static const HB_OpenTypeFeature indic_features[] = {
- { HB_MAKE_TAG('l', 'o', 'c', 'a'), LocaProperty },
- { HB_MAKE_TAG('c', 'c', 'm', 'p'), CcmpProperty },
- { HB_MAKE_TAG('i', 'n', 'i', 't'), InitProperty },
- { HB_MAKE_TAG('n', 'u', 'k', 't'), NuktaProperty },
- { HB_MAKE_TAG('a', 'k', 'h', 'n'), AkhantProperty },
- { HB_MAKE_TAG('r', 'p', 'h', 'f'), RephProperty },
- { HB_MAKE_TAG('b', 'l', 'w', 'f'), BelowFormProperty },
- { HB_MAKE_TAG('h', 'a', 'l', 'f'), HalfFormProperty },
- { HB_MAKE_TAG('p', 's', 't', 'f'), PostFormProperty },
- { HB_MAKE_TAG('c', 'j', 'c', 't'), ConjunctFormProperty },
- { HB_MAKE_TAG('v', 'a', 't', 'u'), VattuProperty },
- { HB_MAKE_TAG('p', 'r', 'e', 's'), PreSubstProperty },
- { HB_MAKE_TAG('b', 'l', 'w', 's'), BelowSubstProperty },
- { HB_MAKE_TAG('a', 'b', 'v', 's'), AboveSubstProperty },
- { HB_MAKE_TAG('p', 's', 't', 's'), PostSubstProperty },
- { HB_MAKE_TAG('h', 'a', 'l', 'n'), HalantProperty },
- { HB_MAKE_TAG('c', 'a', 'l', 't'), IndicCaltProperty },
- { 0, 0 }
-};
-#endif
-
-// #define INDIC_DEBUG
-#ifdef INDIC_DEBUG
-#define IDEBUG hb_debug
-#include <stdarg.h>
-
-static void hb_debug(const char *msg, ...)
-{
- va_list ap;
- va_start(ap, msg); // use variable arg list
- vfprintf(stderr, msg, ap);
- va_end(ap);
- fprintf(stderr, "\n");
-}
-
-#else
-#define IDEBUG if(0) printf
-#endif
-
-#if 0 //def INDIC_DEBUG
-static QString propertiesToString(int properties)
-{
- QString res;
- properties = ~properties;
- if (properties & LocaProperty)
- res += "Loca ";
- if (properties & CcmpProperty)
- res += "Ccmp ";
- if (properties & InitProperty)
- res += "Init ";
- if (properties & NuktaProperty)
- res += "Nukta ";
- if (properties & AkhantProperty)
- res += "Akhant ";
- if (properties & RephProperty)
- res += "Reph ";
- if (properties & PreFormProperty)
- res += "PreForm ";
- if (properties & BelowFormProperty)
- res += "BelowForm ";
- if (properties & AboveFormProperty)
- res += "AboveForm ";
- if (properties & HalfFormProperty)
- res += "HalfForm ";
- if (properties & PostFormProperty)
- res += "PostForm ";
- if (properties & ConjunctFormProperty)
- res += "PostForm ";
- if (properties & VattuProperty)
- res += "Vattu ";
- if (properties & PreSubstProperty)
- res += "PreSubst ";
- if (properties & BelowSubstProperty)
- res += "BelowSubst ";
- if (properties & AboveSubstProperty)
- res += "AboveSubst ";
- if (properties & PostSubstProperty)
- res += "PostSubst ";
- if (properties & HalantProperty)
- res += "Halant ";
- if (properties & CligProperty)
- res += "Clig ";
- if (properties & IndicCaltProperty)
- res += "Calt ";
- return res;
-}
-#endif
-
-static bool indic_shape_syllable(HB_Bool openType, HB_ShaperItem *item, bool invalid)
-{
- HB_Script script = item->item.script;
- assert(script >= HB_Script_Devanagari && script <= HB_Script_Sinhala);
- const unsigned short script_base = 0x0900 + 0x80*(script-HB_Script_Devanagari);
- const unsigned short ra = script_base + 0x30;
- const unsigned short halant = script_base + 0x4d;
- const unsigned short nukta = script_base + 0x3c;
- bool control = false;
-
- int len = (int)item->item.length;
- IDEBUG(">>>>> indic shape: from=%d, len=%d invalid=%d", item->item.pos, item->item.length, invalid);
-
- if ((int)item->num_glyphs < len+4) {
- item->num_glyphs = len+4;
- return false;
- }
-
- HB_STACKARRAY(HB_UChar16, reordered, len + 4);
- HB_STACKARRAY(hb_uint8, position, len + 4);
-
- unsigned char properties = scriptProperties[script-HB_Script_Devanagari];
-
- if (invalid) {
- *reordered = 0x25cc;
- memcpy(reordered+1, item->string + item->item.pos, len*sizeof(HB_UChar16));
- len++;
- } else {
- memcpy(reordered, item->string + item->item.pos, len*sizeof(HB_UChar16));
- }
- if (reordered[len-1] == 0x200c) // zero width non joiner
- len--;
-
- int i;
- int base = 0;
- int reph = -1;
-
-#ifdef INDIC_DEBUG
- IDEBUG("original:");
- for (i = 0; i < len; i++) {
- IDEBUG(" %d: %4x", i, reordered[i]);
- }
-#endif
-
- if (len != 1) {
- HB_UChar16 *uc = reordered;
- bool beginsWithRa = false;
-
- // Rule 1: find base consonant
- //
- // The shaping engine finds the base consonant of the
- // syllable, using the following algorithm: starting from the
- // end of the syllable, move backwards until a consonant is
- // found that does not have a below-base or post-base form
- // (post-base forms have to follow below-base forms), or
- // arrive at the first consonant. The consonant stopped at
- // will be the base.
- //
- // * If the syllable starts with Ra + H (in a script that has
- // 'Reph'), Ra is excluded from candidates for base
- // consonants.
- //
- // * In Kannada and Telugu, the base consonant cannot be
- // farther than 3 consonants from the end of the syllable.
- // #### replace the HasReph property by testing if the feature exists in the font!
- if (form(*uc) == Consonant || (script == HB_Script_Bengali && form(*uc) == IndependentVowel)) {
- if ((properties & HasReph) && (len > 2) &&
- (*uc == ra || *uc == 0x9f0) && *(uc+1) == halant)
- beginsWithRa = true;
-
- if (beginsWithRa && form(*(uc+2)) == Control)
- beginsWithRa = false;
-
- base = (beginsWithRa ? 2 : 0);
- IDEBUG(" length = %d, beginsWithRa = %d, base=%d", len, beginsWithRa, base);
-
- int lastConsonant = 0;
- int matra = -1;
- // we remember:
- // * the last consonant since we need it for rule 2
- // * the matras position for rule 3 and 4
-
- // figure out possible base glyphs
- memset(position, 0, len);
- if (script == HB_Script_Devanagari || script == HB_Script_Gujarati) {
- bool vattu = false;
- for (i = base; i < len; ++i) {
- position[i] = form(uc[i]);
- if (position[i] == Consonant) {
- lastConsonant = i;
- vattu = (!vattu && uc[i] == ra);
- if (vattu) {
- IDEBUG("excluding vattu glyph at %d from base candidates", i);
- position[i] = Vattu;
- }
- } else if (position[i] == Matra) {
- matra = i;
- }
- }
- } else {
- for (i = base; i < len; ++i) {
- position[i] = form(uc[i]);
- if (position[i] == Consonant)
- lastConsonant = i;
- else if (matra < 0 && position[i] == Matra)
- matra = i;
- }
- }
- int skipped = 0;
- Position pos = Post;
- for (i = len-1; i >= base; i--) {
- if (position[i] != Consonant && (position[i] != Control || script == HB_Script_Kannada))
- continue;
-
- if (i < len-1 && position[i] == Control && position[i+1] == Consonant) {
- base = i+1;
- break;
- }
-
- Position charPosition = indic_position(uc[i]);
- if (pos == Post && charPosition == Post) {
- pos = Post;
- } else if ((pos == Post || pos == Below) && charPosition == Below) {
- if (script == HB_Script_Devanagari || script == HB_Script_Gujarati)
- base = i;
- pos = Below;
- } else {
- base = i;
- break;
- }
- if (skipped == 2 && (script == HB_Script_Kannada || script == HB_Script_Telugu)) {
- base = i;
- break;
- }
- ++skipped;
- }
-
- IDEBUG(" base consonant at %d skipped=%d, lastConsonant=%d", base, skipped, lastConsonant);
-
- // Rule 2:
- //
- // If the base consonant is not the last one, Uniscribe
- // moves the halant from the base consonant to the last
- // one.
- if (lastConsonant > base) {
- int halantPos = 0;
- if (uc[base+1] == halant)
- halantPos = base + 1;
- else if (uc[base+1] == nukta && uc[base+2] == halant)
- halantPos = base + 2;
- if (halantPos > 0) {
- IDEBUG(" moving halant from %d to %d!", base+1, lastConsonant);
- for (i = halantPos; i < lastConsonant; i++)
- uc[i] = uc[i+1];
- uc[lastConsonant] = halant;
- }
- }
-
- // Rule 3:
- //
- // If the syllable starts with Ra + H, Uniscribe moves
- // this combination so that it follows either:
-
- // * the post-base 'matra' (if any) or the base consonant
- // (in scripts that show similarity to Devanagari, i.e.,
- // Devanagari, Gujarati, Bengali)
- // * the base consonant (other scripts)
- // * the end of the syllable (Kannada)
-
- Position matra_position = None;
- if (matra > 0)
- matra_position = indic_position(uc[matra]);
- IDEBUG(" matra at %d with form %d, base=%d", matra, matra_position, base);
-
- if (beginsWithRa && base != 0) {
- int toPos = base+1;
- if (toPos < len && uc[toPos] == nukta)
- toPos++;
- if (toPos < len && uc[toPos] == halant)
- toPos++;
- if (toPos < len && uc[toPos] == 0x200d)
- toPos++;
- if (toPos < len-1 && uc[toPos] == ra && uc[toPos+1] == halant)
- toPos += 2;
- if (script == HB_Script_Devanagari || script == HB_Script_Gujarati || script == HB_Script_Bengali) {
- if (matra_position == Post || matra_position == Split) {
- toPos = matra+1;
- matra -= 2;
- }
- } else if (script == HB_Script_Kannada) {
- toPos = len;
- matra -= 2;
- }
-
- IDEBUG("moving leading ra+halant to position %d", toPos);
- for (i = 2; i < toPos; i++)
- uc[i-2] = uc[i];
- uc[toPos-2] = ra;
- uc[toPos-1] = halant;
- base -= 2;
- if (properties & HasReph)
- reph = toPos-2;
- }
-
- // Rule 4:
-
- // Uniscribe splits two- or three-part matras into their
- // parts. This splitting is a character-to-character
- // operation).
- //
- // Uniscribe describes some moving operations for these
- // matras here. For shaping however all pre matras need
- // to be at the beginning of the syllable, so we just move
- // them there now.
- if (matra_position == Split) {
- splitMatra(uc, matra, len);
- // Handle three-part matras (0xccb in Kannada)
- matra_position = indic_position(uc[matra]);
- }
-
- if (matra_position == Pre) {
- unsigned short m = uc[matra];
- while (matra--)
- uc[matra+1] = uc[matra];
- uc[0] = m;
- base++;
- }
- }
-
- // Rule 5:
- //
- // Uniscribe classifies consonants and 'matra' parts as
- // pre-base, above-base (Reph), below-base or post-base. This
- // classification exists on the character code level and is
- // language-dependent, not font-dependent.
- for (i = 0; i < base; ++i)
- position[i] = Pre;
- position[base] = Base;
- for (i = base+1; i < len; ++i) {
- position[i] = indic_position(uc[i]);
- // #### replace by adjusting table
- if (uc[i] == nukta || uc[i] == halant)
- position[i] = Inherit;
- }
- if (reph > 0) {
- // recalculate reph, it might have changed.
- for (i = base+1; i < len; ++i)
- if (uc[i] == ra)
- reph = i;
- position[reph] = Reph;
- position[reph+1] = Inherit;
- }
-
- // all reordering happens now to the chars after the base
- int fixed = base+1;
- if (fixed < len && uc[fixed] == nukta)
- fixed++;
- if (fixed < len && uc[fixed] == halant)
- fixed++;
- if (fixed < len && uc[fixed] == 0x200d)
- fixed++;
-
-#ifdef INDIC_DEBUG
- for (i = fixed; i < len; ++i)
- IDEBUG("position[%d] = %d, form=%d uc=%x", i, position[i], form(uc[i]), uc[i]);
-#endif
- // we continuosly position the matras and vowel marks and increase the fixed
- // until we reached the end.
- const IndicOrdering *finalOrder = indic_order[script-HB_Script_Devanagari];
-
- IDEBUG(" reordering pass:");
- IDEBUG(" base=%d fixed=%d", base, fixed);
- int toMove = 0;
- while (finalOrder[toMove].form && fixed < len-1) {
- IDEBUG(" fixed = %d, toMove=%d, moving form %d with pos %d", fixed, toMove, finalOrder[toMove].form, finalOrder[toMove].position);
- for (i = fixed; i < len; i++) {
-// IDEBUG() << " i=" << i << "uc=" << Qt::hex << uc[i] << "form=" << form(uc[i])
-// << "position=" << position[i];
- if (form(uc[i]) == finalOrder[toMove].form &&
- position[i] == finalOrder[toMove].position) {
- // need to move this glyph
- int to = fixed;
- if (i < len-1 && position[i+1] == Inherit) {
- IDEBUG(" moving two chars from %d to %d", i, to);
- unsigned short ch = uc[i];
- unsigned short ch2 = uc[i+1];
- unsigned char pos = position[i];
- for (int j = i+1; j > to+1; j--) {
- uc[j] = uc[j-2];
- position[j] = position[j-2];
- }
- uc[to] = ch;
- uc[to+1] = ch2;
- position[to] = pos;
- position[to+1] = pos;
- fixed += 2;
- } else {
- IDEBUG(" moving one char from %d to %d", i, to);
- unsigned short ch = uc[i];
- unsigned char pos = position[i];
- for (int j = i; j > to; j--) {
- uc[j] = uc[j-1];
- position[j] = position[j-1];
- }
- uc[to] = ch;
- position[to] = pos;
- fixed++;
- }
- }
- }
- toMove++;
- }
-
- }
-
- if (reph > 0) {
- // recalculate reph, it might have changed.
- for (i = base+1; i < len; ++i)
- if (reordered[i] == ra)
- reph = i;
- }
-
-#ifndef NO_OPENTYPE
- const int availableGlyphs = item->num_glyphs;
-#endif
- if (!item->font->klass->convertStringToGlyphIndices(item->font,
- reordered, len,
- item->glyphs, &item->num_glyphs,
- item->item.bidiLevel % 2))
- goto error;
-
-
- IDEBUG(" base=%d, reph=%d", base, reph);
- IDEBUG("reordered:");
- for (i = 0; i < len; i++) {
- item->attributes[i].mark = false;
- item->attributes[i].clusterStart = false;
- item->attributes[i].justification = 0;
- item->attributes[i].zeroWidth = false;
- IDEBUG(" %d: %4x", i, reordered[i]);
- }
-
- // now we have the syllable in the right order, and can start running it through open type.
-
- for (i = 0; i < len; ++i)
- control |= (form(reordered[i]) == Control);
-
-#ifndef NO_OPENTYPE
- if (openType) {
-
- // we need to keep track of where the base glyph is for some
- // scripts and use the cluster feature for this. This
- // also means we have to correct the logCluster output from
- // the open type engine manually afterwards. for indic this
- // is rather simple, as all chars just point to the first
- // glyph in the syllable.
- HB_STACKARRAY(unsigned short, clusters, len);
- HB_STACKARRAY(unsigned int, properties, len);
-
- for (i = 0; i < len; ++i)
- clusters[i] = i;
-
- // features we should always apply
- for (i = 0; i < len; ++i)
- properties[i] = ~(LocaProperty
- | CcmpProperty
- | NuktaProperty
- | VattuProperty
- | ConjunctFormProperty
- | PreSubstProperty
- | BelowSubstProperty
- | AboveSubstProperty
- | PostSubstProperty
- | HalantProperty
- | IndicCaltProperty
- | PositioningProperties);
-
- // Loca always applies
- // Ccmp always applies
- // Init
- if (item->item.pos == 0
- || !(isLetter(item->string[item->item.pos-1]) || isMark(item->string[item->item.pos-1])))
- properties[0] &= ~InitProperty;
-
- // Nukta always applies
- // Akhant
- for (i = 0; i <= base; ++i)
- properties[i] &= ~AkhantProperty;
- // Reph
- if (reph >= 0) {
- properties[reph] &= ~RephProperty;
- properties[reph+1] &= ~RephProperty;
- }
- // BelowForm
- for (i = base+1; i < len; ++i)
- properties[i] &= ~BelowFormProperty;
-
- if (script == HB_Script_Devanagari || script == HB_Script_Gujarati) {
- // vattu glyphs need this aswell
- bool vattu = false;
- for (i = base-2; i > 1; --i) {
- if (form(reordered[i]) == Consonant) {
- vattu = (!vattu && reordered[i] == ra);
- if (vattu) {
- IDEBUG("forming vattu ligature at %d", i);
- properties[i] &= ~BelowFormProperty;
- properties[i+1] &= ~BelowFormProperty;
- }
- }
- }
- }
- // HalfFormProperty
- for (i = 0; i < base; ++i)
- properties[i] &= ~HalfFormProperty;
- if (control) {
- for (i = 2; i < len; ++i) {
- if (reordered[i] == 0x200d /* ZWJ */) {
- properties[i-1] &= ~HalfFormProperty;
- properties[i-2] &= ~HalfFormProperty;
- } else if (reordered[i] == 0x200c /* ZWNJ */) {
- properties[i-1] &= ~HalfFormProperty;
- properties[i-2] &= ~HalfFormProperty;
- }
- }
- }
- // PostFormProperty
- for (i = base+1; i < len; ++i)
- properties[i] &= ~PostFormProperty;
- // vattu always applies
- // pres always applies
- // blws always applies
- // abvs always applies
- // psts always applies
- // halant always applies
- // calt always applies
-
-#ifdef INDIC_DEBUG
-// {
-// IDEBUG("OT properties:");
-// for (int i = 0; i < len; ++i)
-// qDebug(" i: %s", ::propertiesToString(properties[i]).toLatin1().data());
-// }
-#endif
-
- // initialize
- item->log_clusters = clusters;
- HB_OpenTypeShape(item, properties);
-
- int newLen = item->face->buffer->in_length;
- HB_GlyphItem otl_glyphs = item->face->buffer->in_string;
-
- // move the left matra back to its correct position in malayalam and tamil
- if ((script == HB_Script_Malayalam || script == HB_Script_Tamil) && (form(reordered[0]) == Matra)) {
-// qDebug("reordering matra, len=%d", newLen);
- // need to find the base in the shaped string and move the matra there
- int basePos = 0;
- while (basePos < newLen && (int)otl_glyphs[basePos].cluster <= base)
- basePos++;
- --basePos;
- if (basePos < newLen && basePos > 1) {
-// qDebug("moving prebase matra to position %d in syllable newlen=%d", basePos, newLen);
- HB_GlyphItemRec m = otl_glyphs[0];
- --basePos;
- for (i = 0; i < basePos; ++i)
- otl_glyphs[i] = otl_glyphs[i+1];
- otl_glyphs[basePos] = m;
- }
- }
-
- HB_Bool positioned = HB_OpenTypePosition(item, availableGlyphs, false);
-
- HB_FREE_STACKARRAY(clusters);
- HB_FREE_STACKARRAY(properties);
-
- if (!positioned)
- goto error;
-
- if (control) {
- IDEBUG("found a control char in the syllable");
- hb_uint32 i = 0, j = 0;
- while (i < item->num_glyphs) {
- if (form(reordered[otl_glyphs[i].cluster]) == Control) {
- ++i;
- if (i >= item->num_glyphs)
- break;
- }
- item->glyphs[j] = item->glyphs[i];
- item->attributes[j] = item->attributes[i];
- item->offsets[j] = item->offsets[i];
- item->advances[j] = item->advances[i];
- ++i;
- ++j;
- }
- item->num_glyphs = j;
- }
-
- } else {
- HB_HeuristicPosition(item);
- }
-#endif // NO_OPENTYPE
- item->attributes[0].clusterStart = true;
-
- HB_FREE_STACKARRAY(reordered);
- HB_FREE_STACKARRAY(position);
-
- IDEBUG("<<<<<<");
- return true;
-
-error:
- HB_FREE_STACKARRAY(reordered);
- HB_FREE_STACKARRAY(position);
- return false;
-}
-
-/* syllables are of the form:
-
- (Consonant Nukta? Halant)* Consonant Matra? VowelMark? StressMark?
- (Consonant Nukta? Halant)* Consonant Halant
- IndependentVowel VowelMark? StressMark?
-
- We return syllable boundaries on invalid combinations aswell
-*/
-static int indic_nextSyllableBoundary(HB_Script script, const HB_UChar16 *s, int start, int end, bool *invalid)
-{
- *invalid = false;
- IDEBUG("indic_nextSyllableBoundary: start=%d, end=%d", start, end);
- const HB_UChar16 *uc = s+start;
-
- int pos = 0;
- Form state = form(uc[pos]);
- IDEBUG("state[%d]=%d (uc=%4x)", pos, state, uc[pos]);
- pos++;
-
- if (state != Consonant && state != IndependentVowel) {
- if (state != Other)
- *invalid = true;
- goto finish;
- }
-
- while (pos < end - start) {
- Form newState = form(uc[pos]);
- IDEBUG("state[%d]=%d (uc=%4x)", pos, newState, uc[pos]);
- switch(newState) {
- case Control:
- newState = state;
- if (state == Halant && uc[pos] == 0x200d /* ZWJ */)
- break;
- // the control character should be the last char in the item
- if (state == Consonant && script == HB_Script_Bengali && uc[pos-1] == 0x09B0 && uc[pos] == 0x200d /* ZWJ */)
- break;
- if (state == Consonant && script == HB_Script_Kannada && uc[pos-1] == 0x0CB0 && uc[pos] == 0x200d /* ZWJ */)
- break;
- // Bengali and Kannada has a special exception for rendering yaphala with ra (to avoid reph) see http://www.unicode.org/faq/indic.html#15
- ++pos;
- goto finish;
- case Consonant:
- if (state == Halant && (script != HB_Script_Sinhala || uc[pos-1] == 0x200d /* ZWJ */))
- break;
- goto finish;
- case Halant:
- if (state == Nukta || state == Consonant)
- break;
- // Bengali has a special exception allowing the combination Vowel_A/E + Halant + Ya
- if (script == HB_Script_Bengali && pos == 1 &&
- (uc[0] == 0x0985 || uc[0] == 0x098f))
- break;
- // Sinhala uses the Halant as a component of certain matras. Allow these, but keep the state on Matra.
- if (script == HB_Script_Sinhala && state == Matra) {
- ++pos;
- continue;
- }
- if (script == HB_Script_Malayalam && state == Matra && uc[pos-1] == 0x0d41) {
- ++pos;
- continue;
- }
- goto finish;
- case Nukta:
- if (state == Consonant)
- break;
- goto finish;
- case StressMark:
- if (state == VowelMark)
- break;
- // fall through
- case VowelMark:
- if (state == Matra || state == LengthMark || state == IndependentVowel)
- break;
- // fall through
- case Matra:
- if (state == Consonant || state == Nukta)
- break;
- if (state == Matra) {
- // ### needs proper testing for correct two/three part matras
- break;
- }
- // ### not sure if this is correct. If it is, does it apply only to Bengali or should
- // it work for all Indic languages?
- // the combination Independent_A + Vowel Sign AA is allowed.
- if (script == HB_Script_Bengali && uc[pos] == 0x9be && uc[pos-1] == 0x985)
- break;
- if (script == HB_Script_Tamil && state == Matra) {
- if (uc[pos-1] == 0x0bc6 &&
- (uc[pos] == 0xbbe || uc[pos] == 0xbd7))
- break;
- if (uc[pos-1] == 0x0bc7 && uc[pos] == 0xbbe)
- break;
- }
- goto finish;
-
- case LengthMark:
- if (state == Matra) {
- // ### needs proper testing for correct two/three part matras
- break;
- }
- case IndependentVowel:
- case Invalid:
- case Other:
- goto finish;
- }
- state = newState;
- pos++;
- }
- finish:
- return pos+start;
-}
-
-HB_Bool HB_IndicShape(HB_ShaperItem *item)
-{
- assert(item->item.script >= HB_Script_Devanagari && item->item.script <= HB_Script_Sinhala);
-
- HB_Bool openType = false;
-#ifndef NO_OPENTYPE
- openType = HB_SelectScript(item, indic_features);
-#endif
- unsigned short *logClusters = item->log_clusters;
-
- HB_ShaperItem syllable = *item;
- int first_glyph = 0;
-
- int sstart = item->item.pos;
- int end = sstart + item->item.length;
- IDEBUG("indic_shape: from %d length %d", item->item.pos, item->item.length);
- while (sstart < end) {
- bool invalid;
- int send = indic_nextSyllableBoundary(item->item.script, item->string, sstart, end, &invalid);
- IDEBUG("syllable from %d, length %d, invalid=%s", sstart, send-sstart,
- invalid ? "true" : "false");
- syllable.item.pos = sstart;
- syllable.item.length = send-sstart;
- syllable.glyphs = item->glyphs + first_glyph;
- syllable.attributes = item->attributes + first_glyph;
- syllable.offsets = item->offsets + first_glyph;
- syllable.advances = item->advances + first_glyph;
- syllable.num_glyphs = item->num_glyphs - first_glyph;
- if (!indic_shape_syllable(openType, &syllable, invalid)) {
- IDEBUG("syllable shaping failed, syllable requests %d glyphs", syllable.num_glyphs);
- item->num_glyphs += syllable.num_glyphs;
- return false;
- }
- // fix logcluster array
- IDEBUG("syllable:");
- hb_uint32 g;
- for (g = first_glyph; g < first_glyph + syllable.num_glyphs; ++g)
- IDEBUG(" %d -> glyph %x", g, item->glyphs[g]);
- IDEBUG(" logclusters:");
- int i;
- for (i = sstart; i < send; ++i) {
- IDEBUG(" %d -> glyph %d", i, first_glyph);
- logClusters[i-item->item.pos] = first_glyph;
- }
- sstart = send;
- first_glyph += syllable.num_glyphs;
- }
- item->num_glyphs = first_glyph;
- return true;
-}
-
-void HB_IndicAttributes(HB_Script script, const HB_UChar16 *text, hb_uint32 from, hb_uint32 len, HB_CharAttributes *attributes)
-{
- int end = from + len;
- const HB_UChar16 *uc = text + from;
- attributes += from;
- hb_uint32 i = 0;
- while (i < len) {
- bool invalid;
- hb_uint32 boundary = indic_nextSyllableBoundary(script, text, from+i, end, &invalid) - from;
- attributes[i].graphemeBoundary = true;
-
- if (boundary > len-1) boundary = len;
- i++;
- while (i < boundary) {
- attributes[i].graphemeBoundary = false;
- ++uc;
- ++i;
- }
- assert(i == boundary);
- }
-
-
-}
-
-
diff --git a/src/3rdparty/harfbuzz/src/harfbuzz-khmer.c b/src/3rdparty/harfbuzz/src/harfbuzz-khmer.c
deleted file mode 100644
index 809a55b863..0000000000
--- a/src/3rdparty/harfbuzz/src/harfbuzz-khmer.c
+++ /dev/null
@@ -1,667 +0,0 @@
-/*
- * Copyright (C) 2015 The Qt Company Ltd
- *
- * This is part of HarfBuzz, an OpenType Layout engine library.
- *
- * Permission is hereby granted, without written agreement and without
- * license or royalty fees, to use, copy, modify, and distribute this
- * software and its documentation for any purpose, provided that the
- * above copyright notice and the following two paragraphs appear in
- * all copies of this software.
- *
- * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
- * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
- * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
- * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
- * DAMAGE.
- *
- * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
- * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
- * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
- * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
- * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
- */
-
-#include "harfbuzz-shaper.h"
-#include "harfbuzz-shaper-private.h"
-
-#include <assert.h>
-#include <stdio.h>
-
-/*
-// Vocabulary
-// Base -> A consonant or an independent vowel in its full (not subscript) form. It is the
-// center of the syllable, it can be surrounded by coeng (subscript) consonants, vowels,
-// split vowels, signs... but there is only one base in a syllable, it has to be coded as
-// the first character of the syllable.
-// split vowel --> vowel that has two parts placed separately (e.g. Before and after the consonant).
-// Khmer language has five of them. Khmer split vowels either have one part before the
-// base and one after the base or they have a part before the base and a part above the base.
-// The first part of all Khmer split vowels is the same character, identical to
-// the glyph of Khmer dependent vowel SRA EI
-// coeng --> modifier used in Khmer to construct coeng (subscript) consonants
-// Differently than indian languages, the coeng modifies the consonant that follows it,
-// not the one preceding it Each consonant has two forms, the base form and the subscript form
-// the base form is the normal one (using the consonants code-point), the subscript form is
-// displayed when the combination coeng + consonant is encountered.
-// Consonant of type 1 -> A consonant which has subscript for that only occupies space under a base consonant
-// Consonant of type 2.-> Its subscript form occupies space under and before the base (only one, RO)
-// Consonant of Type 3 -> Its subscript form occupies space under and after the base (KHO, CHHO, THHO, BA, YO, SA)
-// Consonant shifter -> Khmer has to series of consonants. The same dependent vowel has different sounds
-// if it is attached to a consonant of the first series or a consonant of the second series
-// Most consonants have an equivalent in the other series, but some of theme exist only in
-// one series (for example SA). If we want to use the consonant SA with a vowel sound that
-// can only be done with a vowel sound that corresponds to a vowel accompanying a consonant
-// of the other series, then we need to use a consonant shifter: TRIISAP or MUSIKATOAN
-// x17C9 y x17CA. TRIISAP changes a first series consonant to second series sound and
-// MUSIKATOAN a second series consonant to have a first series vowel sound.
-// Consonant shifter are both normally supercript marks, but, when they are followed by a
-// superscript, they change shape and take the form of subscript dependent vowel SRA U.
-// If they are in the same syllable as a coeng consonant, Unicode 3.0 says that they
-// should be typed before the coeng. Unicode 4.0 breaks the standard and says that it should
-// be placed after the coeng consonant.
-// Dependent vowel -> In khmer dependent vowels can be placed above, below, before or after the base
-// Each vowel has its own position. Only one vowel per syllable is allowed.
-// Signs -> Khmer has above signs and post signs. Only one above sign and/or one post sign are
-// Allowed in a syllable.
-//
-//
-// order is important here! This order must be the same that is found in each horizontal
-// line in the statetable for Khmer (see khmerStateTable) .
-*/
-enum KhmerCharClassValues {
- CC_RESERVED = 0,
- CC_CONSONANT = 1, /* Consonant of type 1 or independent vowel */
- CC_CONSONANT2 = 2, /* Consonant of type 2 */
- CC_CONSONANT3 = 3, /* Consonant of type 3 */
- CC_ZERO_WIDTH_NJ_MARK = 4, /* Zero Width non joiner character (0x200C) */
- CC_CONSONANT_SHIFTER = 5,
- CC_ROBAT = 6, /* Khmer special diacritic accent -treated differently in state table */
- CC_COENG = 7, /* Subscript consonant combining character */
- CC_DEPENDENT_VOWEL = 8,
- CC_SIGN_ABOVE = 9,
- CC_SIGN_AFTER = 10,
- CC_ZERO_WIDTH_J_MARK = 11, /* Zero width joiner character */
- CC_COUNT = 12 /* This is the number of character classes */
-};
-
-
-enum KhmerCharClassFlags {
- CF_CLASS_MASK = 0x0000FFFF,
-
- CF_CONSONANT = 0x01000000, /* flag to speed up comparing */
- CF_SPLIT_VOWEL = 0x02000000, /* flag for a split vowel -> the first part is added in front of the syllable */
- CF_DOTTED_CIRCLE = 0x04000000, /* add a dotted circle if a character with this flag is the first in a syllable */
- CF_COENG = 0x08000000, /* flag to speed up comparing */
- CF_SHIFTER = 0x10000000, /* flag to speed up comparing */
- CF_ABOVE_VOWEL = 0x20000000, /* flag to speed up comparing */
-
- /* position flags */
- CF_POS_BEFORE = 0x00080000,
- CF_POS_BELOW = 0x00040000,
- CF_POS_ABOVE = 0x00020000,
- CF_POS_AFTER = 0x00010000,
- CF_POS_MASK = 0x000f0000
-};
-
-
-/* Characters that get referred to by name */
-enum KhmerChar {
- C_SIGN_ZWNJ = 0x200C,
- C_SIGN_ZWJ = 0x200D,
- C_RO = 0x179A,
- C_VOWEL_AA = 0x17B6,
- C_SIGN_NIKAHIT = 0x17C6,
- C_VOWEL_E = 0x17C1,
- C_COENG = 0x17D2
-};
-
-
-/*
-// simple classes, they are used in the statetable (in this file) to control the length of a syllable
-// they are also used to know where a character should be placed (location in reference to the base character)
-// and also to know if a character, when independently displayed, should be displayed with a dotted-circle to
-// indicate error in syllable construction
-*/
-enum {
- _xx = CC_RESERVED,
- _sa = CC_SIGN_ABOVE | CF_DOTTED_CIRCLE | CF_POS_ABOVE,
- _sp = CC_SIGN_AFTER | CF_DOTTED_CIRCLE| CF_POS_AFTER,
- _c1 = CC_CONSONANT | CF_CONSONANT,
- _c2 = CC_CONSONANT2 | CF_CONSONANT,
- _c3 = CC_CONSONANT3 | CF_CONSONANT,
- _rb = CC_ROBAT | CF_POS_ABOVE | CF_DOTTED_CIRCLE,
- _cs = CC_CONSONANT_SHIFTER | CF_DOTTED_CIRCLE | CF_SHIFTER,
- _dl = CC_DEPENDENT_VOWEL | CF_POS_BEFORE | CF_DOTTED_CIRCLE,
- _db = CC_DEPENDENT_VOWEL | CF_POS_BELOW | CF_DOTTED_CIRCLE,
- _da = CC_DEPENDENT_VOWEL | CF_POS_ABOVE | CF_DOTTED_CIRCLE | CF_ABOVE_VOWEL,
- _dr = CC_DEPENDENT_VOWEL | CF_POS_AFTER | CF_DOTTED_CIRCLE,
- _co = CC_COENG | CF_COENG | CF_DOTTED_CIRCLE,
-
- /* split vowel */
- _va = _da | CF_SPLIT_VOWEL,
- _vr = _dr | CF_SPLIT_VOWEL
-};
-
-
-/*
-// Character class: a character class value
-// ORed with character class flags.
-*/
-typedef unsigned long KhmerCharClass;
-
-
-/*
-// Character class tables
-// _xx character does not combine into syllable, such as numbers, puntuation marks, non-Khmer signs...
-// _sa Sign placed above the base
-// _sp Sign placed after the base
-// _c1 Consonant of type 1 or independent vowel (independent vowels behave as type 1 consonants)
-// _c2 Consonant of type 2 (only RO)
-// _c3 Consonant of type 3
-// _rb Khmer sign robat u17CC. combining mark for subscript consonants
-// _cd Consonant-shifter
-// _dl Dependent vowel placed before the base (left of the base)
-// _db Dependent vowel placed below the base
-// _da Dependent vowel placed above the base
-// _dr Dependent vowel placed behind the base (right of the base)
-// _co Khmer combining mark COENG u17D2, combines with the consonant or independent vowel following
-// it to create a subscript consonant or independent vowel
-// _va Khmer split vowel in which the first part is before the base and the second one above the base
-// _vr Khmer split vowel in which the first part is before the base and the second one behind (right of) the base
-*/
-static const KhmerCharClass khmerCharClasses[] = {
- _c1, _c1, _c1, _c3, _c1, _c1, _c1, _c1, _c3, _c1, _c1, _c1, _c1, _c3, _c1, _c1, /* 1780 - 178F */
- _c1, _c1, _c1, _c1, _c3, _c1, _c1, _c1, _c1, _c3, _c2, _c1, _c1, _c1, _c3, _c3, /* 1790 - 179F */
- _c1, _c3, _c1, _c1, _c1, _c1, _c1, _c1, _c1, _c1, _c1, _c1, _c1, _c1, _c1, _c1, /* 17A0 - 17AF */
- _c1, _c1, _c1, _c1, _dr, _dr, _dr, _da, _da, _da, _da, _db, _db, _db, _va, _vr, /* 17B0 - 17BF */
- _vr, _dl, _dl, _dl, _vr, _vr, _sa, _sp, _sp, _cs, _cs, _sa, _rb, _sa, _sa, _sa, /* 17C0 - 17CF */
- _sa, _sa, _co, _sa, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _sa, _xx, _xx /* 17D0 - 17DF */
-};
-
-/* this enum must reflect the range of khmerCharClasses */
-enum KhmerCharClassesRange {
- KhmerFirstChar = 0x1780,
- KhmerLastChar = 0x17df
-};
-
-/*
-// Below we define how a character in the input string is either in the khmerCharClasses table
-// (in which case we get its type back), a ZWJ or ZWNJ (two characters that may appear
-// within the syllable, but are not in the table) we also get their type back, or an unknown object
-// in which case we get _xx (CC_RESERVED) back
-*/
-static KhmerCharClass getKhmerCharClass(HB_UChar16 uc)
-{
- if (uc == C_SIGN_ZWJ) {
- return CC_ZERO_WIDTH_J_MARK;
- }
-
- if (uc == C_SIGN_ZWNJ) {
- return CC_ZERO_WIDTH_NJ_MARK;
- }
-
- if (uc < KhmerFirstChar || uc > KhmerLastChar) {
- return CC_RESERVED;
- }
-
- return khmerCharClasses[uc - KhmerFirstChar];
-}
-
-
-/*
-// The stateTable is used to calculate the end (the length) of a well
-// formed Khmer Syllable.
-//
-// Each horizontal line is ordered exactly the same way as the values in KhmerClassTable
-// CharClassValues. This coincidence of values allows the follow up of the table.
-//
-// Each line corresponds to a state, which does not necessarily need to be a type
-// of component... for example, state 2 is a base, with is always a first character
-// in the syllable, but the state could be produced a consonant of any type when
-// it is the first character that is analysed (in ground state).
-//
-// Differentiating 3 types of consonants is necessary in order to
-// forbid the use of certain combinations, such as having a second
-// coeng after a coeng RO,
-// The inexistent possibility of having a type 3 after another type 3 is permitted,
-// eliminating it would very much complicate the table, and it does not create typing
-// problems, as the case above.
-//
-// The table is quite complex, in order to limit the number of coeng consonants
-// to 2 (by means of the table).
-//
-// There a peculiarity, as far as Unicode is concerned:
-// - The consonant-shifter is considered in two possible different
-// locations, the one considered in Unicode 3.0 and the one considered in
-// Unicode 4.0. (there is a backwards compatibility problem in this standard).
-//
-//
-// xx independent character, such as a number, punctuation sign or non-khmer char
-//
-// c1 Khmer consonant of type 1 or an independent vowel
-// that is, a letter in which the subscript for is only under the
-// base, not taking any space to the right or to the left
-//
-// c2 Khmer consonant of type 2, the coeng form takes space under
-// and to the left of the base (only RO is of this type)
-//
-// c3 Khmer consonant of type 3. Its subscript form takes space under
-// and to the right of the base.
-//
-// cs Khmer consonant shifter
-//
-// rb Khmer robat
-//
-// co coeng character (u17D2)
-//
-// dv dependent vowel (including split vowels, they are treated in the same way).
-// even if dv is not defined above, the component that is really tested for is
-// KhmerClassTable::CC_DEPENDENT_VOWEL, which is common to all dependent vowels
-//
-// zwj Zero Width joiner
-//
-// zwnj Zero width non joiner
-//
-// sa above sign
-//
-// sp post sign
-//
-// there are lines with equal content but for an easier understanding
-// (and maybe change in the future) we did not join them
-*/
-static const signed char khmerStateTable[][CC_COUNT] =
-{
- /* xx c1 c2 c3 zwnj cs rb co dv sa sp zwj */
- { 1, 2, 2, 2, 1, 1, 1, 6, 1, 1, 1, 2}, /* 0 - ground state */
- {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, /* 1 - exit state (or sign to the right of the syllable) */
- {-1, -1, -1, -1, 3, 4, 5, 6, 16, 17, 1, -1}, /* 2 - Base consonant */
- {-1, -1, -1, -1, -1, 4, -1, -1, 16, -1, -1, -1}, /* 3 - First ZWNJ before a register shifter It can only be followed by a shifter or a vowel */
- {-1, -1, -1, -1, 15, -1, -1, 6, 16, 17, 1, 14}, /* 4 - First register shifter */
- {-1, -1, -1, -1, -1, -1, -1, -1, 20, -1, 1, -1}, /* 5 - Robat */
- {-1, 7, 8, 9, -1, -1, -1, -1, -1, -1, -1, -1}, /* 6 - First Coeng */
- {-1, -1, -1, -1, 12, 13, -1, 10, 16, 17, 1, 14}, /* 7 - First consonant of type 1 after coeng */
- {-1, -1, -1, -1, 12, 13, -1, -1, 16, 17, 1, 14}, /* 8 - First consonant of type 2 after coeng */
- {-1, -1, -1, -1, 12, 13, -1, 10, 16, 17, 1, 14}, /* 9 - First consonant or type 3 after ceong */
- {-1, 11, 11, 11, -1, -1, -1, -1, -1, -1, -1, -1}, /* 10 - Second Coeng (no register shifter before) */
- {-1, -1, -1, -1, 15, -1, -1, -1, 16, 17, 1, 14}, /* 11 - Second coeng consonant (or ind. vowel) no register shifter before */
- {-1, -1, -1, -1, -1, 13, -1, -1, 16, -1, -1, -1}, /* 12 - Second ZWNJ before a register shifter */
- {-1, -1, -1, -1, 15, -1, -1, -1, 16, 17, 1, 14}, /* 13 - Second register shifter */
- {-1, -1, -1, -1, -1, -1, -1, -1, 16, -1, -1, -1}, /* 14 - ZWJ before vowel */
- {-1, -1, -1, -1, -1, -1, -1, -1, 16, -1, -1, -1}, /* 15 - ZWNJ before vowel */
- {-1, -1, -1, -1, -1, -1, -1, -1, -1, 17, 1, 18}, /* 16 - dependent vowel */
- {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 1, 18}, /* 17 - sign above */
- {-1, -1, -1, -1, -1, -1, -1, 19, -1, -1, -1, -1}, /* 18 - ZWJ after vowel */
- {-1, 1, -1, 1, -1, -1, -1, -1, -1, -1, -1, -1}, /* 19 - Third coeng */
- {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 1, -1}, /* 20 - dependent vowel after a Robat */
-};
-
-
-/* #define KHMER_DEBUG */
-#ifdef KHMER_DEBUG
-#define KHDEBUG qDebug
-#else
-#define KHDEBUG if(0) printf
-#endif
-
-/*
-// Given an input string of characters and a location in which to start looking
-// calculate, using the state table, which one is the last character of the syllable
-// that starts in the starting position.
-*/
-static int khmer_nextSyllableBoundary(const HB_UChar16 *s, int start, int end, HB_Bool *invalid)
-{
- const HB_UChar16 *uc = s + start;
- int state = 0;
- int pos = start;
- *invalid = FALSE;
-
- while (pos < end) {
- KhmerCharClass charClass = getKhmerCharClass(*uc);
- if (pos == start) {
- *invalid = (charClass > 0) && ! (charClass & CF_CONSONANT);
- }
- state = khmerStateTable[state][charClass & CF_CLASS_MASK];
-
- KHDEBUG("state[%d]=%d class=%8lx (uc=%4x)", pos - start, state,
- charClass, *uc );
-
- if (state < 0) {
- break;
- }
- ++uc;
- ++pos;
- }
- return pos;
-}
-
-#ifndef NO_OPENTYPE
-static const HB_OpenTypeFeature khmer_features[] = {
- { HB_MAKE_TAG( 'p', 'r', 'e', 'f' ), PreFormProperty },
- { HB_MAKE_TAG( 'b', 'l', 'w', 'f' ), BelowFormProperty },
- { HB_MAKE_TAG( 'a', 'b', 'v', 'f' ), AboveFormProperty },
- { HB_MAKE_TAG( 'p', 's', 't', 'f' ), PostFormProperty },
- { HB_MAKE_TAG( 'p', 'r', 'e', 's' ), PreSubstProperty },
- { HB_MAKE_TAG( 'b', 'l', 'w', 's' ), BelowSubstProperty },
- { HB_MAKE_TAG( 'a', 'b', 'v', 's' ), AboveSubstProperty },
- { HB_MAKE_TAG( 'p', 's', 't', 's' ), PostSubstProperty },
- { HB_MAKE_TAG( 'c', 'l', 'i', 'g' ), CligProperty },
- { 0, 0 }
-};
-#endif
-
-
-static HB_Bool khmer_shape_syllable(HB_Bool openType, HB_ShaperItem *item)
-{
-/* KHDEBUG("syllable from %d len %d, str='%s'", item->from, item->length,
- item->string->mid(item->from, item->length).toUtf8().data()); */
-
- int len = 0;
- int syllableEnd = item->item.pos + item->item.length;
- unsigned short reordered[16];
- unsigned char properties[16];
- enum {
- AboveForm = 0x01,
- PreForm = 0x02,
- PostForm = 0x04,
- BelowForm = 0x08
- };
-#ifndef NO_OPENTYPE
- const int availableGlyphs = item->num_glyphs;
-#endif
- int coengRo;
- int i;
-
- /* according to the specs this is the max length one can get
- ### the real value should be smaller */
- assert(item->item.length < 13);
-
- memset(properties, 0, 16*sizeof(unsigned char));
-
-#ifdef KHMER_DEBUG
- qDebug("original:");
- for (int i = from; i < syllableEnd; i++) {
- qDebug(" %d: %4x", i, string[i]);
- }
-#endif
-
- /*
- // write a pre vowel or the pre part of a split vowel first
- // and look out for coeng + ro. RO is the only vowel of type 2, and
- // therefore the only one that requires saving space before the base.
- */
- coengRo = -1; /* There is no Coeng Ro, if found this value will change */
- for (i = item->item.pos; i < syllableEnd; i += 1) {
- KhmerCharClass charClass = getKhmerCharClass(item->string[i]);
-
- /* if a split vowel, write the pre part. In Khmer the pre part
- is the same for all split vowels, same glyph as pre vowel C_VOWEL_E */
- if (charClass & CF_SPLIT_VOWEL) {
- reordered[len] = C_VOWEL_E;
- properties[len] = PreForm;
- ++len;
- break; /* there can be only one vowel */
- }
- /* if a vowel with pos before write it out */
- if (charClass & CF_POS_BEFORE) {
- reordered[len] = item->string[i];
- properties[len] = PreForm;
- ++len;
- break; /* there can be only one vowel */
- }
- /* look for coeng + ro and remember position
- works because coeng + ro is always in front of a vowel (if there is a vowel)
- and because CC_CONSONANT2 is enough to identify it, as it is the only consonant
- with this flag */
- if ( (charClass & CF_COENG) && (i + 1 < syllableEnd) &&
- ( (getKhmerCharClass(item->string[i+1]) & CF_CLASS_MASK) == CC_CONSONANT2) ) {
- coengRo = i;
- }
- }
-
- /* write coeng + ro if found */
- if (coengRo > -1) {
- reordered[len] = C_COENG;
- properties[len] = PreForm;
- ++len;
- reordered[len] = C_RO;
- properties[len] = PreForm;
- ++len;
- }
-
- /*
- shall we add a dotted circle?
- If in the position in which the base should be (first char in the string) there is
- a character that has the Dotted circle flag (a character that cannot be a base)
- then write a dotted circle */
- if (getKhmerCharClass(item->string[item->item.pos]) & CF_DOTTED_CIRCLE) {
- reordered[len] = C_DOTTED_CIRCLE;
- ++len;
- }
-
- /* copy what is left to the output, skipping before vowels and
- coeng Ro if they are present */
- for (i = item->item.pos; i < syllableEnd; i += 1) {
- HB_UChar16 uc = item->string[i];
- KhmerCharClass charClass = getKhmerCharClass(uc);
-
- /* skip a before vowel, it was already processed */
- if (charClass & CF_POS_BEFORE) {
- continue;
- }
-
- /* skip coeng + ro, it was already processed */
- if (i == coengRo) {
- i += 1;
- continue;
- }
-
- switch (charClass & CF_POS_MASK)
- {
- case CF_POS_ABOVE :
- reordered[len] = uc;
- properties[len] = AboveForm;
- ++len;
- break;
-
- case CF_POS_AFTER :
- reordered[len] = uc;
- properties[len] = PostForm;
- ++len;
- break;
-
- case CF_POS_BELOW :
- reordered[len] = uc;
- properties[len] = BelowForm;
-